ActivityManagerService.java revision 734983fff35d9ed2b7a9848bdfbca401887d0dd8
1/* 2 * Copyright (C) 2006-2008 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17package com.android.server.am; 18 19import static android.content.pm.PackageManager.PERMISSION_GRANTED; 20import static com.android.internal.util.XmlUtils.readIntAttribute; 21import static com.android.internal.util.XmlUtils.readLongAttribute; 22import static com.android.internal.util.XmlUtils.writeIntAttribute; 23import static com.android.internal.util.XmlUtils.writeLongAttribute; 24import static com.android.server.Watchdog.NATIVE_STACKS_OF_INTEREST; 25import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT; 26import static org.xmlpull.v1.XmlPullParser.START_TAG; 27 28import static com.android.server.am.ActivityStackSupervisor.HOME_STACK_ID; 29 30import android.app.AppOpsManager; 31import android.app.IActivityContainer; 32import android.app.IActivityContainerCallback; 33import android.appwidget.AppWidgetManager; 34import android.graphics.Rect; 35import android.os.BatteryStats; 36import android.util.ArrayMap; 37import com.android.internal.R; 38import com.android.internal.annotations.GuardedBy; 39import com.android.internal.app.IAppOpsService; 40import com.android.internal.app.ProcessMap; 41import com.android.internal.app.ProcessStats; 42import com.android.internal.os.BackgroundThread; 43import com.android.internal.os.BatteryStatsImpl; 44import com.android.internal.os.ProcessCpuTracker; 45import com.android.internal.os.TransferPipe; 46import com.android.internal.util.FastPrintWriter; 47import com.android.internal.util.FastXmlSerializer; 48import com.android.internal.util.MemInfoReader; 49import com.android.internal.util.Preconditions; 50import com.android.server.AppOpsService; 51import com.android.server.AttributeCache; 52import com.android.server.IntentResolver; 53import com.android.server.ServiceThread; 54import com.android.server.SystemService; 55import com.android.server.Watchdog; 56import com.android.server.am.ActivityStack.ActivityState; 57import com.android.server.firewall.IntentFirewall; 58import com.android.server.pm.UserManagerService; 59import com.android.server.wm.AppTransition; 60import com.android.server.wm.WindowManagerService; 61import com.google.android.collect.Lists; 62import com.google.android.collect.Maps; 63 64import dalvik.system.Zygote; 65 66import libcore.io.IoUtils; 67 68import org.xmlpull.v1.XmlPullParser; 69import org.xmlpull.v1.XmlPullParserException; 70import org.xmlpull.v1.XmlSerializer; 71 72import android.app.Activity; 73import android.app.ActivityManager; 74import android.app.ActivityManager.RunningTaskInfo; 75import android.app.ActivityManager.StackInfo; 76import android.app.ActivityManagerNative; 77import android.app.ActivityOptions; 78import android.app.ActivityThread; 79import android.app.AlertDialog; 80import android.app.AppGlobals; 81import android.app.ApplicationErrorReport; 82import android.app.Dialog; 83import android.app.IActivityController; 84import android.app.IApplicationThread; 85import android.app.IInstrumentationWatcher; 86import android.app.INotificationManager; 87import android.app.IProcessObserver; 88import android.app.IServiceConnection; 89import android.app.IStopUserCallback; 90import android.app.IThumbnailReceiver; 91import android.app.IUiAutomationConnection; 92import android.app.IUserSwitchObserver; 93import android.app.Instrumentation; 94import android.app.Notification; 95import android.app.NotificationManager; 96import android.app.PendingIntent; 97import android.app.backup.IBackupManager; 98import android.content.ActivityNotFoundException; 99import android.content.BroadcastReceiver; 100import android.content.ClipData; 101import android.content.ComponentCallbacks2; 102import android.content.ComponentName; 103import android.content.ContentProvider; 104import android.content.ContentResolver; 105import android.content.Context; 106import android.content.DialogInterface; 107import android.content.IContentProvider; 108import android.content.IIntentReceiver; 109import android.content.IIntentSender; 110import android.content.Intent; 111import android.content.IntentFilter; 112import android.content.IntentSender; 113import android.content.pm.ActivityInfo; 114import android.content.pm.ApplicationInfo; 115import android.content.pm.ConfigurationInfo; 116import android.content.pm.IPackageDataObserver; 117import android.content.pm.IPackageManager; 118import android.content.pm.InstrumentationInfo; 119import android.content.pm.PackageInfo; 120import android.content.pm.PackageManager; 121import android.content.pm.ParceledListSlice; 122import android.content.pm.UserInfo; 123import android.content.pm.PackageManager.NameNotFoundException; 124import android.content.pm.PathPermission; 125import android.content.pm.ProviderInfo; 126import android.content.pm.ResolveInfo; 127import android.content.pm.ServiceInfo; 128import android.content.res.CompatibilityInfo; 129import android.content.res.Configuration; 130import android.graphics.Bitmap; 131import android.net.Proxy; 132import android.net.ProxyProperties; 133import android.net.Uri; 134import android.os.Binder; 135import android.os.Build; 136import android.os.Bundle; 137import android.os.Debug; 138import android.os.DropBoxManager; 139import android.os.Environment; 140import android.os.FactoryTest; 141import android.os.FileObserver; 142import android.os.FileUtils; 143import android.os.Handler; 144import android.os.IBinder; 145import android.os.IPermissionController; 146import android.os.IRemoteCallback; 147import android.os.IUserManager; 148import android.os.Looper; 149import android.os.Message; 150import android.os.Parcel; 151import android.os.ParcelFileDescriptor; 152import android.os.Process; 153import android.os.RemoteCallbackList; 154import android.os.RemoteException; 155import android.os.SELinux; 156import android.os.ServiceManager; 157import android.os.StrictMode; 158import android.os.SystemClock; 159import android.os.SystemProperties; 160import android.os.UpdateLock; 161import android.os.UserHandle; 162import android.provider.Settings; 163import android.text.format.DateUtils; 164import android.text.format.Time; 165import android.util.AtomicFile; 166import android.util.EventLog; 167import android.util.Log; 168import android.util.Pair; 169import android.util.PrintWriterPrinter; 170import android.util.Slog; 171import android.util.SparseArray; 172import android.util.TimeUtils; 173import android.util.Xml; 174import android.view.Gravity; 175import android.view.LayoutInflater; 176import android.view.View; 177import android.view.WindowManager; 178 179import java.io.BufferedInputStream; 180import java.io.BufferedOutputStream; 181import java.io.DataInputStream; 182import java.io.DataOutputStream; 183import java.io.File; 184import java.io.FileDescriptor; 185import java.io.FileInputStream; 186import java.io.FileNotFoundException; 187import java.io.FileOutputStream; 188import java.io.IOException; 189import java.io.InputStreamReader; 190import java.io.PrintWriter; 191import java.io.StringWriter; 192import java.lang.ref.WeakReference; 193import java.util.ArrayList; 194import java.util.Arrays; 195import java.util.Collections; 196import java.util.Comparator; 197import java.util.HashMap; 198import java.util.HashSet; 199import java.util.Iterator; 200import java.util.List; 201import java.util.Locale; 202import java.util.Map; 203import java.util.Set; 204import java.util.concurrent.atomic.AtomicBoolean; 205import java.util.concurrent.atomic.AtomicLong; 206 207public final class ActivityManagerService extends ActivityManagerNative 208 implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback { 209 private static final String USER_DATA_DIR = "/data/user/"; 210 static final String TAG = "ActivityManager"; 211 static final String TAG_MU = "ActivityManagerServiceMU"; 212 static final boolean DEBUG = false; 213 static final boolean localLOGV = DEBUG; 214 static final boolean DEBUG_BACKUP = localLOGV || false; 215 static final boolean DEBUG_BROADCAST = localLOGV || false; 216 static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false; 217 static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false; 218 static final boolean DEBUG_CLEANUP = localLOGV || false; 219 static final boolean DEBUG_CONFIGURATION = localLOGV || false; 220 static final boolean DEBUG_FOCUS = false; 221 static final boolean DEBUG_IMMERSIVE = localLOGV || false; 222 static final boolean DEBUG_MU = localLOGV || false; 223 static final boolean DEBUG_OOM_ADJ = localLOGV || false; 224 static final boolean DEBUG_LRU = localLOGV || false; 225 static final boolean DEBUG_PAUSE = localLOGV || false; 226 static final boolean DEBUG_POWER = localLOGV || false; 227 static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false; 228 static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false; 229 static final boolean DEBUG_PROCESSES = localLOGV || false; 230 static final boolean DEBUG_PROVIDER = localLOGV || false; 231 static final boolean DEBUG_RESULTS = localLOGV || false; 232 static final boolean DEBUG_SERVICE = localLOGV || false; 233 static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false; 234 static final boolean DEBUG_STACK = localLOGV || false; 235 static final boolean DEBUG_SWITCH = localLOGV || false; 236 static final boolean DEBUG_TASKS = localLOGV || false; 237 static final boolean DEBUG_THUMBNAILS = localLOGV || false; 238 static final boolean DEBUG_TRANSITION = localLOGV || false; 239 static final boolean DEBUG_URI_PERMISSION = localLOGV || false; 240 static final boolean DEBUG_USER_LEAVING = localLOGV || false; 241 static final boolean DEBUG_VISBILITY = localLOGV || false; 242 static final boolean DEBUG_PSS = localLOGV || false; 243 static final boolean DEBUG_LOCKSCREEN = localLOGV || false; 244 static final boolean VALIDATE_TOKENS = false; 245 static final boolean SHOW_ACTIVITY_START_TIME = true; 246 247 // Control over CPU and battery monitoring. 248 static final long BATTERY_STATS_TIME = 30*60*1000; // write battery stats every 30 minutes. 249 static final boolean MONITOR_CPU_USAGE = true; 250 static final long MONITOR_CPU_MIN_TIME = 5*1000; // don't sample cpu less than every 5 seconds. 251 static final long MONITOR_CPU_MAX_TIME = 0x0fffffff; // wait possibly forever for next cpu sample. 252 static final boolean MONITOR_THREAD_CPU_USAGE = false; 253 254 // The flags that are set for all calls we make to the package manager. 255 static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES; 256 257 private static final String SYSTEM_DEBUGGABLE = "ro.debuggable"; 258 259 static final boolean IS_USER_BUILD = "user".equals(Build.TYPE); 260 261 // Maximum number of recent tasks that we can remember. 262 static final int MAX_RECENT_TASKS = ActivityManager.isLowRamDeviceStatic() ? 10 : 20; 263 264 // Amount of time after a call to stopAppSwitches() during which we will 265 // prevent further untrusted switches from happening. 266 static final long APP_SWITCH_DELAY_TIME = 5*1000; 267 268 // How long we wait for a launched process to attach to the activity manager 269 // before we decide it's never going to come up for real. 270 static final int PROC_START_TIMEOUT = 10*1000; 271 272 // How long we wait for a launched process to attach to the activity manager 273 // before we decide it's never going to come up for real, when the process was 274 // started with a wrapper for instrumentation (such as Valgrind) because it 275 // could take much longer than usual. 276 static final int PROC_START_TIMEOUT_WITH_WRAPPER = 300*1000; 277 278 // How long to wait after going idle before forcing apps to GC. 279 static final int GC_TIMEOUT = 5*1000; 280 281 // The minimum amount of time between successive GC requests for a process. 282 static final int GC_MIN_INTERVAL = 60*1000; 283 284 // The minimum amount of time between successive PSS requests for a process. 285 static final int FULL_PSS_MIN_INTERVAL = 10*60*1000; 286 287 // The minimum amount of time between successive PSS requests for a process 288 // when the request is due to the memory state being lowered. 289 static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000; 290 291 // The rate at which we check for apps using excessive power -- 15 mins. 292 static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000; 293 294 // The minimum sample duration we will allow before deciding we have 295 // enough data on wake locks to start killing things. 296 static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000; 297 298 // The minimum sample duration we will allow before deciding we have 299 // enough data on CPU usage to start killing things. 300 static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000; 301 302 // How long we allow a receiver to run before giving up on it. 303 static final int BROADCAST_FG_TIMEOUT = 10*1000; 304 static final int BROADCAST_BG_TIMEOUT = 60*1000; 305 306 // How long we wait until we timeout on key dispatching. 307 static final int KEY_DISPATCHING_TIMEOUT = 5*1000; 308 309 // How long we wait until we timeout on key dispatching during instrumentation. 310 static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000; 311 312 // Amount of time we wait for observers to handle a user switch before 313 // giving up on them and unfreezing the screen. 314 static final int USER_SWITCH_TIMEOUT = 2*1000; 315 316 // Maximum number of users we allow to be running at a time. 317 static final int MAX_RUNNING_USERS = 3; 318 319 // How long to wait in getAssistContextExtras for the activity and foreground services 320 // to respond with the result. 321 static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500; 322 323 // Maximum number of persisted Uri grants a package is allowed 324 static final int MAX_PERSISTED_URI_GRANTS = 128; 325 326 static final int MY_PID = Process.myPid(); 327 328 static final String[] EMPTY_STRING_ARRAY = new String[0]; 329 330 // How many bytes to write into the dropbox log before truncating 331 static final int DROPBOX_MAX_SIZE = 256 * 1024; 332 333 /** Run all ActivityStacks through this */ 334 ActivityStackSupervisor mStackSupervisor; 335 336 public IntentFirewall mIntentFirewall; 337 338 // Whether we should show our dialogs (ANR, crash, etc) or just perform their 339 // default actuion automatically. Important for devices without direct input 340 // devices. 341 private boolean mShowDialogs = true; 342 343 /** 344 * Description of a request to start a new activity, which has been held 345 * due to app switches being disabled. 346 */ 347 static class PendingActivityLaunch { 348 final ActivityRecord r; 349 final ActivityRecord sourceRecord; 350 final int startFlags; 351 final ActivityStack stack; 352 353 PendingActivityLaunch(ActivityRecord _r, ActivityRecord _sourceRecord, 354 int _startFlags, ActivityStack _stack) { 355 r = _r; 356 sourceRecord = _sourceRecord; 357 startFlags = _startFlags; 358 stack = _stack; 359 } 360 } 361 362 final ArrayList<PendingActivityLaunch> mPendingActivityLaunches 363 = new ArrayList<PendingActivityLaunch>(); 364 365 BroadcastQueue mFgBroadcastQueue; 366 BroadcastQueue mBgBroadcastQueue; 367 // Convenient for easy iteration over the queues. Foreground is first 368 // so that dispatch of foreground broadcasts gets precedence. 369 final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2]; 370 371 BroadcastQueue broadcastQueueForIntent(Intent intent) { 372 final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0; 373 if (DEBUG_BACKGROUND_BROADCAST) { 374 Slog.i(TAG, "Broadcast intent " + intent + " on " 375 + (isFg ? "foreground" : "background") 376 + " queue"); 377 } 378 return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue; 379 } 380 381 BroadcastRecord broadcastRecordForReceiverLocked(IBinder receiver) { 382 for (BroadcastQueue queue : mBroadcastQueues) { 383 BroadcastRecord r = queue.getMatchingOrderedReceiver(receiver); 384 if (r != null) { 385 return r; 386 } 387 } 388 return null; 389 } 390 391 /** 392 * Activity we have told the window manager to have key focus. 393 */ 394 ActivityRecord mFocusedActivity = null; 395 396 /** 397 * List of intents that were used to start the most recent tasks. 398 */ 399 private final ArrayList<TaskRecord> mRecentTasks = new ArrayList<TaskRecord>(); 400 401 public class PendingAssistExtras extends Binder implements Runnable { 402 public final ActivityRecord activity; 403 public boolean haveResult = false; 404 public Bundle result = null; 405 public PendingAssistExtras(ActivityRecord _activity) { 406 activity = _activity; 407 } 408 @Override 409 public void run() { 410 Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity); 411 synchronized (this) { 412 haveResult = true; 413 notifyAll(); 414 } 415 } 416 } 417 418 final ArrayList<PendingAssistExtras> mPendingAssistExtras 419 = new ArrayList<PendingAssistExtras>(); 420 421 /** 422 * Process management. 423 */ 424 final ProcessList mProcessList = new ProcessList(); 425 426 /** 427 * All of the applications we currently have running organized by name. 428 * The keys are strings of the application package name (as 429 * returned by the package manager), and the keys are ApplicationRecord 430 * objects. 431 */ 432 final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>(); 433 434 /** 435 * Tracking long-term execution of processes to look for abuse and other 436 * bad app behavior. 437 */ 438 final ProcessStatsService mProcessStats; 439 440 /** 441 * The currently running isolated processes. 442 */ 443 final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>(); 444 445 /** 446 * Counter for assigning isolated process uids, to avoid frequently reusing the 447 * same ones. 448 */ 449 int mNextIsolatedProcessUid = 0; 450 451 /** 452 * The currently running heavy-weight process, if any. 453 */ 454 ProcessRecord mHeavyWeightProcess = null; 455 456 /** 457 * The last time that various processes have crashed. 458 */ 459 final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>(); 460 461 /** 462 * Information about a process that is currently marked as bad. 463 */ 464 static final class BadProcessInfo { 465 BadProcessInfo(long time, String shortMsg, String longMsg, String stack) { 466 this.time = time; 467 this.shortMsg = shortMsg; 468 this.longMsg = longMsg; 469 this.stack = stack; 470 } 471 472 final long time; 473 final String shortMsg; 474 final String longMsg; 475 final String stack; 476 } 477 478 /** 479 * Set of applications that we consider to be bad, and will reject 480 * incoming broadcasts from (which the user has no control over). 481 * Processes are added to this set when they have crashed twice within 482 * a minimum amount of time; they are removed from it when they are 483 * later restarted (hopefully due to some user action). The value is the 484 * time it was added to the list. 485 */ 486 final ProcessMap<BadProcessInfo> mBadProcesses = new ProcessMap<BadProcessInfo>(); 487 488 /** 489 * All of the processes we currently have running organized by pid. 490 * The keys are the pid running the application. 491 * 492 * <p>NOTE: This object is protected by its own lock, NOT the global 493 * activity manager lock! 494 */ 495 final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>(); 496 497 /** 498 * All of the processes that have been forced to be foreground. The key 499 * is the pid of the caller who requested it (we hold a death 500 * link on it). 501 */ 502 abstract class ForegroundToken implements IBinder.DeathRecipient { 503 int pid; 504 IBinder token; 505 } 506 final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>(); 507 508 /** 509 * List of records for processes that someone had tried to start before the 510 * system was ready. We don't start them at that point, but ensure they 511 * are started by the time booting is complete. 512 */ 513 final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>(); 514 515 /** 516 * List of persistent applications that are in the process 517 * of being started. 518 */ 519 final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>(); 520 521 /** 522 * Processes that are being forcibly torn down. 523 */ 524 final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>(); 525 526 /** 527 * List of running applications, sorted by recent usage. 528 * The first entry in the list is the least recently used. 529 */ 530 final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>(); 531 532 /** 533 * Where in mLruProcesses that the processes hosting activities start. 534 */ 535 int mLruProcessActivityStart = 0; 536 537 /** 538 * Where in mLruProcesses that the processes hosting services start. 539 * This is after (lower index) than mLruProcessesActivityStart. 540 */ 541 int mLruProcessServiceStart = 0; 542 543 /** 544 * List of processes that should gc as soon as things are idle. 545 */ 546 final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>(); 547 548 /** 549 * Processes we want to collect PSS data from. 550 */ 551 final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>(); 552 553 /** 554 * Last time we requested PSS data of all processes. 555 */ 556 long mLastFullPssTime = SystemClock.uptimeMillis(); 557 558 /** 559 * This is the process holding what we currently consider to be 560 * the "home" activity. 561 */ 562 ProcessRecord mHomeProcess; 563 564 /** 565 * This is the process holding the activity the user last visited that 566 * is in a different process from the one they are currently in. 567 */ 568 ProcessRecord mPreviousProcess; 569 570 /** 571 * The time at which the previous process was last visible. 572 */ 573 long mPreviousProcessVisibleTime; 574 575 /** 576 * Which uses have been started, so are allowed to run code. 577 */ 578 final SparseArray<UserStartedState> mStartedUsers = new SparseArray<UserStartedState>(); 579 580 /** 581 * LRU list of history of current users. Most recently current is at the end. 582 */ 583 final ArrayList<Integer> mUserLru = new ArrayList<Integer>(); 584 585 /** 586 * Constant array of the users that are currently started. 587 */ 588 int[] mStartedUserArray = new int[] { 0 }; 589 590 /** 591 * Registered observers of the user switching mechanics. 592 */ 593 final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers 594 = new RemoteCallbackList<IUserSwitchObserver>(); 595 596 /** 597 * Currently active user switch. 598 */ 599 Object mCurUserSwitchCallback; 600 601 /** 602 * Packages that the user has asked to have run in screen size 603 * compatibility mode instead of filling the screen. 604 */ 605 final CompatModePackages mCompatModePackages; 606 607 /** 608 * Set of IntentSenderRecord objects that are currently active. 609 */ 610 final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords 611 = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>(); 612 613 /** 614 * Fingerprints (hashCode()) of stack traces that we've 615 * already logged DropBox entries for. Guarded by itself. If 616 * something (rogue user app) forces this over 617 * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared. 618 */ 619 private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>(); 620 private static final int MAX_DUP_SUPPRESSED_STACKS = 5000; 621 622 /** 623 * Strict Mode background batched logging state. 624 * 625 * The string buffer is guarded by itself, and its lock is also 626 * used to determine if another batched write is already 627 * in-flight. 628 */ 629 private final StringBuilder mStrictModeBuffer = new StringBuilder(); 630 631 /** 632 * Keeps track of all IIntentReceivers that have been registered for 633 * broadcasts. Hash keys are the receiver IBinder, hash value is 634 * a ReceiverList. 635 */ 636 final HashMap<IBinder, ReceiverList> mRegisteredReceivers = 637 new HashMap<IBinder, ReceiverList>(); 638 639 /** 640 * Resolver for broadcast intents to registered receivers. 641 * Holds BroadcastFilter (subclass of IntentFilter). 642 */ 643 final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver 644 = new IntentResolver<BroadcastFilter, BroadcastFilter>() { 645 @Override 646 protected boolean allowFilterResult( 647 BroadcastFilter filter, List<BroadcastFilter> dest) { 648 IBinder target = filter.receiverList.receiver.asBinder(); 649 for (int i=dest.size()-1; i>=0; i--) { 650 if (dest.get(i).receiverList.receiver.asBinder() == target) { 651 return false; 652 } 653 } 654 return true; 655 } 656 657 @Override 658 protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) { 659 if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL 660 || userId == filter.owningUserId) { 661 return super.newResult(filter, match, userId); 662 } 663 return null; 664 } 665 666 @Override 667 protected BroadcastFilter[] newArray(int size) { 668 return new BroadcastFilter[size]; 669 } 670 671 @Override 672 protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) { 673 return packageName.equals(filter.packageName); 674 } 675 }; 676 677 /** 678 * State of all active sticky broadcasts per user. Keys are the action of the 679 * sticky Intent, values are an ArrayList of all broadcasted intents with 680 * that action (which should usually be one). The SparseArray is keyed 681 * by the user ID the sticky is for, and can include UserHandle.USER_ALL 682 * for stickies that are sent to all users. 683 */ 684 final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts = 685 new SparseArray<ArrayMap<String, ArrayList<Intent>>>(); 686 687 final ActiveServices mServices; 688 689 /** 690 * Backup/restore process management 691 */ 692 String mBackupAppName = null; 693 BackupRecord mBackupTarget = null; 694 695 /** 696 * List of PendingThumbnailsRecord objects of clients who are still 697 * waiting to receive all of the thumbnails for a task. 698 */ 699 final ArrayList<PendingThumbnailsRecord> mPendingThumbnails = 700 new ArrayList<PendingThumbnailsRecord>(); 701 702 final ProviderMap mProviderMap; 703 704 /** 705 * List of content providers who have clients waiting for them. The 706 * application is currently being launched and the provider will be 707 * removed from this list once it is published. 708 */ 709 final ArrayList<ContentProviderRecord> mLaunchingProviders 710 = new ArrayList<ContentProviderRecord>(); 711 712 /** 713 * File storing persisted {@link #mGrantedUriPermissions}. 714 */ 715 private final AtomicFile mGrantFile; 716 717 /** XML constants used in {@link #mGrantFile} */ 718 private static final String TAG_URI_GRANTS = "uri-grants"; 719 private static final String TAG_URI_GRANT = "uri-grant"; 720 private static final String ATTR_USER_HANDLE = "userHandle"; 721 private static final String ATTR_SOURCE_PKG = "sourcePkg"; 722 private static final String ATTR_TARGET_PKG = "targetPkg"; 723 private static final String ATTR_URI = "uri"; 724 private static final String ATTR_MODE_FLAGS = "modeFlags"; 725 private static final String ATTR_CREATED_TIME = "createdTime"; 726 727 /** 728 * Global set of specific {@link Uri} permissions that have been granted. 729 * This optimized lookup structure maps from {@link UriPermission#targetUid} 730 * to {@link UriPermission#uri} to {@link UriPermission}. 731 */ 732 @GuardedBy("this") 733 private final SparseArray<ArrayMap<Uri, UriPermission>> 734 mGrantedUriPermissions = new SparseArray<ArrayMap<Uri, UriPermission>>(); 735 736 CoreSettingsObserver mCoreSettingsObserver; 737 738 /** 739 * Thread-local storage used to carry caller permissions over through 740 * indirect content-provider access. 741 */ 742 private class Identity { 743 public int pid; 744 public int uid; 745 746 Identity(int _pid, int _uid) { 747 pid = _pid; 748 uid = _uid; 749 } 750 } 751 752 private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>(); 753 754 /** 755 * All information we have collected about the runtime performance of 756 * any user id that can impact battery performance. 757 */ 758 final BatteryStatsService mBatteryStatsService; 759 760 /** 761 * Information about component usage 762 */ 763 final UsageStatsService mUsageStatsService; 764 765 /** 766 * Information about and control over application operations 767 */ 768 final AppOpsService mAppOpsService; 769 770 /** 771 * Current configuration information. HistoryRecord objects are given 772 * a reference to this object to indicate which configuration they are 773 * currently running in, so this object must be kept immutable. 774 */ 775 Configuration mConfiguration = new Configuration(); 776 777 /** 778 * Current sequencing integer of the configuration, for skipping old 779 * configurations. 780 */ 781 int mConfigurationSeq = 0; 782 783 /** 784 * Hardware-reported OpenGLES version. 785 */ 786 final int GL_ES_VERSION; 787 788 /** 789 * List of initialization arguments to pass to all processes when binding applications to them. 790 * For example, references to the commonly used services. 791 */ 792 HashMap<String, IBinder> mAppBindArgs; 793 794 /** 795 * Temporary to avoid allocations. Protected by main lock. 796 */ 797 final StringBuilder mStringBuilder = new StringBuilder(256); 798 799 /** 800 * Used to control how we initialize the service. 801 */ 802 boolean mStartRunning = false; 803 ComponentName mTopComponent; 804 String mTopAction; 805 String mTopData; 806 boolean mProcessesReady = false; 807 boolean mSystemReady = false; 808 boolean mBooting = false; 809 boolean mWaitingUpdate = false; 810 boolean mDidUpdate = false; 811 boolean mOnBattery = false; 812 boolean mLaunchWarningShown = false; 813 814 Context mContext; 815 816 int mFactoryTest; 817 818 boolean mCheckedForSetup; 819 820 /** 821 * The time at which we will allow normal application switches again, 822 * after a call to {@link #stopAppSwitches()}. 823 */ 824 long mAppSwitchesAllowedTime; 825 826 /** 827 * This is set to true after the first switch after mAppSwitchesAllowedTime 828 * is set; any switches after that will clear the time. 829 */ 830 boolean mDidAppSwitch; 831 832 /** 833 * Last time (in realtime) at which we checked for power usage. 834 */ 835 long mLastPowerCheckRealtime; 836 837 /** 838 * Last time (in uptime) at which we checked for power usage. 839 */ 840 long mLastPowerCheckUptime; 841 842 /** 843 * Set while we are wanting to sleep, to prevent any 844 * activities from being started/resumed. 845 */ 846 boolean mSleeping = false; 847 848 /** 849 * State of external calls telling us if the device is asleep. 850 */ 851 boolean mWentToSleep = false; 852 853 /** 854 * State of external call telling us if the lock screen is shown. 855 */ 856 boolean mLockScreenShown = false; 857 858 /** 859 * Set if we are shutting down the system, similar to sleeping. 860 */ 861 boolean mShuttingDown = false; 862 863 /** 864 * Current sequence id for oom_adj computation traversal. 865 */ 866 int mAdjSeq = 0; 867 868 /** 869 * Current sequence id for process LRU updating. 870 */ 871 int mLruSeq = 0; 872 873 /** 874 * Keep track of the non-cached/empty process we last found, to help 875 * determine how to distribute cached/empty processes next time. 876 */ 877 int mNumNonCachedProcs = 0; 878 879 /** 880 * Keep track of the number of cached hidden procs, to balance oom adj 881 * distribution between those and empty procs. 882 */ 883 int mNumCachedHiddenProcs = 0; 884 885 /** 886 * Keep track of the number of service processes we last found, to 887 * determine on the next iteration which should be B services. 888 */ 889 int mNumServiceProcs = 0; 890 int mNewNumAServiceProcs = 0; 891 int mNewNumServiceProcs = 0; 892 893 /** 894 * Allow the current computed overall memory level of the system to go down? 895 * This is set to false when we are killing processes for reasons other than 896 * memory management, so that the now smaller process list will not be taken as 897 * an indication that memory is tighter. 898 */ 899 boolean mAllowLowerMemLevel = false; 900 901 /** 902 * The last computed memory level, for holding when we are in a state that 903 * processes are going away for other reasons. 904 */ 905 int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL; 906 907 /** 908 * The last total number of process we have, to determine if changes actually look 909 * like a shrinking number of process due to lower RAM. 910 */ 911 int mLastNumProcesses; 912 913 /** 914 * The uptime of the last time we performed idle maintenance. 915 */ 916 long mLastIdleTime = SystemClock.uptimeMillis(); 917 918 /** 919 * Total time spent with RAM that has been added in the past since the last idle time. 920 */ 921 long mLowRamTimeSinceLastIdle = 0; 922 923 /** 924 * If RAM is currently low, when that horrible situation started. 925 */ 926 long mLowRamStartTime = 0; 927 928 /** 929 * For reporting to battery stats the current top application. 930 */ 931 private String mCurResumedPackage = null; 932 private int mCurResumedUid = -1; 933 934 /** 935 * For reporting to battery stats the apps currently running foreground 936 * service. The ProcessMap is package/uid tuples; each of these contain 937 * an array of the currently foreground processes. 938 */ 939 final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages 940 = new ProcessMap<ArrayList<ProcessRecord>>(); 941 942 /** 943 * This is set if we had to do a delayed dexopt of an app before launching 944 * it, to increasing the ANR timeouts in that case. 945 */ 946 boolean mDidDexOpt; 947 948 String mDebugApp = null; 949 boolean mWaitForDebugger = false; 950 boolean mDebugTransient = false; 951 String mOrigDebugApp = null; 952 boolean mOrigWaitForDebugger = false; 953 boolean mAlwaysFinishActivities = false; 954 IActivityController mController = null; 955 String mProfileApp = null; 956 ProcessRecord mProfileProc = null; 957 String mProfileFile; 958 ParcelFileDescriptor mProfileFd; 959 int mProfileType = 0; 960 boolean mAutoStopProfiler = false; 961 String mOpenGlTraceApp = null; 962 963 static class ProcessChangeItem { 964 static final int CHANGE_ACTIVITIES = 1<<0; 965 static final int CHANGE_IMPORTANCE= 1<<1; 966 int changes; 967 int uid; 968 int pid; 969 int importance; 970 boolean foregroundActivities; 971 } 972 973 final RemoteCallbackList<IProcessObserver> mProcessObservers 974 = new RemoteCallbackList<IProcessObserver>(); 975 ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5]; 976 977 final ArrayList<ProcessChangeItem> mPendingProcessChanges 978 = new ArrayList<ProcessChangeItem>(); 979 final ArrayList<ProcessChangeItem> mAvailProcessChanges 980 = new ArrayList<ProcessChangeItem>(); 981 982 /** 983 * Runtime CPU use collection thread. This object's lock is used to 984 * protect all related state. 985 */ 986 final Thread mProcessCpuThread; 987 988 /** 989 * Used to collect process stats when showing not responding dialog. 990 * Protected by mProcessCpuThread. 991 */ 992 final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker( 993 MONITOR_THREAD_CPU_USAGE); 994 final AtomicLong mLastCpuTime = new AtomicLong(0); 995 final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true); 996 997 long mLastWriteTime = 0; 998 999 /** 1000 * Used to retain an update lock when the foreground activity is in 1001 * immersive mode. 1002 */ 1003 final UpdateLock mUpdateLock = new UpdateLock("immersive"); 1004 1005 /** 1006 * Set to true after the system has finished booting. 1007 */ 1008 boolean mBooted = false; 1009 1010 int mProcessLimit = ProcessList.MAX_CACHED_APPS; 1011 int mProcessLimitOverride = -1; 1012 1013 WindowManagerService mWindowManager; 1014 1015 final ActivityThread mSystemThread; 1016 1017 int mCurrentUserId = 0; 1018 int[] mRelatedUserIds = new int[0]; // Accessed by ActivityStack 1019 private UserManagerService mUserManager; 1020 1021 private final class AppDeathRecipient implements IBinder.DeathRecipient { 1022 final ProcessRecord mApp; 1023 final int mPid; 1024 final IApplicationThread mAppThread; 1025 1026 AppDeathRecipient(ProcessRecord app, int pid, 1027 IApplicationThread thread) { 1028 if (localLOGV) Slog.v( 1029 TAG, "New death recipient " + this 1030 + " for thread " + thread.asBinder()); 1031 mApp = app; 1032 mPid = pid; 1033 mAppThread = thread; 1034 } 1035 1036 @Override 1037 public void binderDied() { 1038 if (localLOGV) Slog.v( 1039 TAG, "Death received in " + this 1040 + " for thread " + mAppThread.asBinder()); 1041 synchronized(ActivityManagerService.this) { 1042 appDiedLocked(mApp, mPid, mAppThread); 1043 } 1044 } 1045 } 1046 1047 static final int SHOW_ERROR_MSG = 1; 1048 static final int SHOW_NOT_RESPONDING_MSG = 2; 1049 static final int SHOW_FACTORY_ERROR_MSG = 3; 1050 static final int UPDATE_CONFIGURATION_MSG = 4; 1051 static final int GC_BACKGROUND_PROCESSES_MSG = 5; 1052 static final int WAIT_FOR_DEBUGGER_MSG = 6; 1053 static final int SERVICE_TIMEOUT_MSG = 12; 1054 static final int UPDATE_TIME_ZONE = 13; 1055 static final int SHOW_UID_ERROR_MSG = 14; 1056 static final int IM_FEELING_LUCKY_MSG = 15; 1057 static final int PROC_START_TIMEOUT_MSG = 20; 1058 static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21; 1059 static final int KILL_APPLICATION_MSG = 22; 1060 static final int FINALIZE_PENDING_INTENT_MSG = 23; 1061 static final int POST_HEAVY_NOTIFICATION_MSG = 24; 1062 static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25; 1063 static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26; 1064 static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27; 1065 static final int CLEAR_DNS_CACHE_MSG = 28; 1066 static final int UPDATE_HTTP_PROXY_MSG = 29; 1067 static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30; 1068 static final int DISPATCH_PROCESSES_CHANGED = 31; 1069 static final int DISPATCH_PROCESS_DIED = 32; 1070 static final int REPORT_MEM_USAGE_MSG = 33; 1071 static final int REPORT_USER_SWITCH_MSG = 34; 1072 static final int CONTINUE_USER_SWITCH_MSG = 35; 1073 static final int USER_SWITCH_TIMEOUT_MSG = 36; 1074 static final int IMMERSIVE_MODE_LOCK_MSG = 37; 1075 static final int PERSIST_URI_GRANTS_MSG = 38; 1076 static final int REQUEST_ALL_PSS_MSG = 39; 1077 static final int START_RELATED_USERS_MSG = 40; 1078 1079 static final int FIRST_ACTIVITY_STACK_MSG = 100; 1080 static final int FIRST_BROADCAST_QUEUE_MSG = 200; 1081 static final int FIRST_COMPAT_MODE_MSG = 300; 1082 static final int FIRST_SUPERVISOR_STACK_MSG = 100; 1083 1084 AlertDialog mUidAlert; 1085 CompatModeDialog mCompatModeDialog; 1086 long mLastMemUsageReportTime = 0; 1087 1088 /** 1089 * Flag whether the current user is a "monkey", i.e. whether 1090 * the UI is driven by a UI automation tool. 1091 */ 1092 private boolean mUserIsMonkey; 1093 1094 final ServiceThread mHandlerThread; 1095 final MainHandler mHandler; 1096 1097 final class MainHandler extends Handler { 1098 public MainHandler(Looper looper) { 1099 super(looper, null, true); 1100 } 1101 1102 @Override 1103 public void handleMessage(Message msg) { 1104 switch (msg.what) { 1105 case SHOW_ERROR_MSG: { 1106 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1107 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), 1108 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; 1109 synchronized (ActivityManagerService.this) { 1110 ProcessRecord proc = (ProcessRecord)data.get("app"); 1111 AppErrorResult res = (AppErrorResult) data.get("result"); 1112 if (proc != null && proc.crashDialog != null) { 1113 Slog.e(TAG, "App already has crash dialog: " + proc); 1114 if (res != null) { 1115 res.set(0); 1116 } 1117 return; 1118 } 1119 if (!showBackground && UserHandle.getAppId(proc.uid) 1120 >= Process.FIRST_APPLICATION_UID && proc.userId != mCurrentUserId 1121 && proc.pid != MY_PID) { 1122 Slog.w(TAG, "Skipping crash dialog of " + proc + ": background"); 1123 if (res != null) { 1124 res.set(0); 1125 } 1126 return; 1127 } 1128 if (mShowDialogs && !mSleeping && !mShuttingDown) { 1129 Dialog d = new AppErrorDialog(mContext, 1130 ActivityManagerService.this, res, proc); 1131 d.show(); 1132 proc.crashDialog = d; 1133 } else { 1134 // The device is asleep, so just pretend that the user 1135 // saw a crash dialog and hit "force quit". 1136 if (res != null) { 1137 res.set(0); 1138 } 1139 } 1140 } 1141 1142 ensureBootCompleted(); 1143 } break; 1144 case SHOW_NOT_RESPONDING_MSG: { 1145 synchronized (ActivityManagerService.this) { 1146 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1147 ProcessRecord proc = (ProcessRecord)data.get("app"); 1148 if (proc != null && proc.anrDialog != null) { 1149 Slog.e(TAG, "App already has anr dialog: " + proc); 1150 return; 1151 } 1152 1153 Intent intent = new Intent("android.intent.action.ANR"); 1154 if (!mProcessesReady) { 1155 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 1156 | Intent.FLAG_RECEIVER_FOREGROUND); 1157 } 1158 broadcastIntentLocked(null, null, intent, 1159 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 1160 false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */); 1161 1162 if (mShowDialogs) { 1163 Dialog d = new AppNotRespondingDialog(ActivityManagerService.this, 1164 mContext, proc, (ActivityRecord)data.get("activity"), 1165 msg.arg1 != 0); 1166 d.show(); 1167 proc.anrDialog = d; 1168 } else { 1169 // Just kill the app if there is no dialog to be shown. 1170 killAppAtUsersRequest(proc, null); 1171 } 1172 } 1173 1174 ensureBootCompleted(); 1175 } break; 1176 case SHOW_STRICT_MODE_VIOLATION_MSG: { 1177 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1178 synchronized (ActivityManagerService.this) { 1179 ProcessRecord proc = (ProcessRecord) data.get("app"); 1180 if (proc == null) { 1181 Slog.e(TAG, "App not found when showing strict mode dialog."); 1182 break; 1183 } 1184 if (proc.crashDialog != null) { 1185 Slog.e(TAG, "App already has strict mode dialog: " + proc); 1186 return; 1187 } 1188 AppErrorResult res = (AppErrorResult) data.get("result"); 1189 if (mShowDialogs && !mSleeping && !mShuttingDown) { 1190 Dialog d = new StrictModeViolationDialog(mContext, 1191 ActivityManagerService.this, res, proc); 1192 d.show(); 1193 proc.crashDialog = d; 1194 } else { 1195 // The device is asleep, so just pretend that the user 1196 // saw a crash dialog and hit "force quit". 1197 res.set(0); 1198 } 1199 } 1200 ensureBootCompleted(); 1201 } break; 1202 case SHOW_FACTORY_ERROR_MSG: { 1203 Dialog d = new FactoryErrorDialog( 1204 mContext, msg.getData().getCharSequence("msg")); 1205 d.show(); 1206 ensureBootCompleted(); 1207 } break; 1208 case UPDATE_CONFIGURATION_MSG: { 1209 final ContentResolver resolver = mContext.getContentResolver(); 1210 Settings.System.putConfiguration(resolver, (Configuration)msg.obj); 1211 } break; 1212 case GC_BACKGROUND_PROCESSES_MSG: { 1213 synchronized (ActivityManagerService.this) { 1214 performAppGcsIfAppropriateLocked(); 1215 } 1216 } break; 1217 case WAIT_FOR_DEBUGGER_MSG: { 1218 synchronized (ActivityManagerService.this) { 1219 ProcessRecord app = (ProcessRecord)msg.obj; 1220 if (msg.arg1 != 0) { 1221 if (!app.waitedForDebugger) { 1222 Dialog d = new AppWaitingForDebuggerDialog( 1223 ActivityManagerService.this, 1224 mContext, app); 1225 app.waitDialog = d; 1226 app.waitedForDebugger = true; 1227 d.show(); 1228 } 1229 } else { 1230 if (app.waitDialog != null) { 1231 app.waitDialog.dismiss(); 1232 app.waitDialog = null; 1233 } 1234 } 1235 } 1236 } break; 1237 case SERVICE_TIMEOUT_MSG: { 1238 if (mDidDexOpt) { 1239 mDidDexOpt = false; 1240 Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG); 1241 nmsg.obj = msg.obj; 1242 mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT); 1243 return; 1244 } 1245 mServices.serviceTimeout((ProcessRecord)msg.obj); 1246 } break; 1247 case UPDATE_TIME_ZONE: { 1248 synchronized (ActivityManagerService.this) { 1249 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1250 ProcessRecord r = mLruProcesses.get(i); 1251 if (r.thread != null) { 1252 try { 1253 r.thread.updateTimeZone(); 1254 } catch (RemoteException ex) { 1255 Slog.w(TAG, "Failed to update time zone for: " + r.info.processName); 1256 } 1257 } 1258 } 1259 } 1260 } break; 1261 case CLEAR_DNS_CACHE_MSG: { 1262 synchronized (ActivityManagerService.this) { 1263 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1264 ProcessRecord r = mLruProcesses.get(i); 1265 if (r.thread != null) { 1266 try { 1267 r.thread.clearDnsCache(); 1268 } catch (RemoteException ex) { 1269 Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName); 1270 } 1271 } 1272 } 1273 } 1274 } break; 1275 case UPDATE_HTTP_PROXY_MSG: { 1276 ProxyProperties proxy = (ProxyProperties)msg.obj; 1277 String host = ""; 1278 String port = ""; 1279 String exclList = ""; 1280 String pacFileUrl = null; 1281 if (proxy != null) { 1282 host = proxy.getHost(); 1283 port = Integer.toString(proxy.getPort()); 1284 exclList = proxy.getExclusionList(); 1285 pacFileUrl = proxy.getPacFileUrl(); 1286 } 1287 synchronized (ActivityManagerService.this) { 1288 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1289 ProcessRecord r = mLruProcesses.get(i); 1290 if (r.thread != null) { 1291 try { 1292 r.thread.setHttpProxy(host, port, exclList, pacFileUrl); 1293 } catch (RemoteException ex) { 1294 Slog.w(TAG, "Failed to update http proxy for: " + 1295 r.info.processName); 1296 } 1297 } 1298 } 1299 } 1300 } break; 1301 case SHOW_UID_ERROR_MSG: { 1302 String title = "System UIDs Inconsistent"; 1303 String text = "UIDs on the system are inconsistent, you need to wipe your" 1304 + " data partition or your device will be unstable."; 1305 Log.e(TAG, title + ": " + text); 1306 if (mShowDialogs) { 1307 // XXX This is a temporary dialog, no need to localize. 1308 AlertDialog d = new BaseErrorDialog(mContext); 1309 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR); 1310 d.setCancelable(false); 1311 d.setTitle(title); 1312 d.setMessage(text); 1313 d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky", 1314 mHandler.obtainMessage(IM_FEELING_LUCKY_MSG)); 1315 mUidAlert = d; 1316 d.show(); 1317 } 1318 } break; 1319 case IM_FEELING_LUCKY_MSG: { 1320 if (mUidAlert != null) { 1321 mUidAlert.dismiss(); 1322 mUidAlert = null; 1323 } 1324 } break; 1325 case PROC_START_TIMEOUT_MSG: { 1326 if (mDidDexOpt) { 1327 mDidDexOpt = false; 1328 Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 1329 nmsg.obj = msg.obj; 1330 mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT); 1331 return; 1332 } 1333 ProcessRecord app = (ProcessRecord)msg.obj; 1334 synchronized (ActivityManagerService.this) { 1335 processStartTimedOutLocked(app); 1336 } 1337 } break; 1338 case DO_PENDING_ACTIVITY_LAUNCHES_MSG: { 1339 synchronized (ActivityManagerService.this) { 1340 doPendingActivityLaunchesLocked(true); 1341 } 1342 } break; 1343 case KILL_APPLICATION_MSG: { 1344 synchronized (ActivityManagerService.this) { 1345 int appid = msg.arg1; 1346 boolean restart = (msg.arg2 == 1); 1347 Bundle bundle = (Bundle)msg.obj; 1348 String pkg = bundle.getString("pkg"); 1349 String reason = bundle.getString("reason"); 1350 forceStopPackageLocked(pkg, appid, restart, false, true, false, 1351 false, UserHandle.USER_ALL, reason); 1352 } 1353 } break; 1354 case FINALIZE_PENDING_INTENT_MSG: { 1355 ((PendingIntentRecord)msg.obj).completeFinalize(); 1356 } break; 1357 case POST_HEAVY_NOTIFICATION_MSG: { 1358 INotificationManager inm = NotificationManager.getService(); 1359 if (inm == null) { 1360 return; 1361 } 1362 1363 ActivityRecord root = (ActivityRecord)msg.obj; 1364 ProcessRecord process = root.app; 1365 if (process == null) { 1366 return; 1367 } 1368 1369 try { 1370 Context context = mContext.createPackageContext(process.info.packageName, 0); 1371 String text = mContext.getString(R.string.heavy_weight_notification, 1372 context.getApplicationInfo().loadLabel(context.getPackageManager())); 1373 Notification notification = new Notification(); 1374 notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon; 1375 notification.when = 0; 1376 notification.flags = Notification.FLAG_ONGOING_EVENT; 1377 notification.tickerText = text; 1378 notification.defaults = 0; // please be quiet 1379 notification.sound = null; 1380 notification.vibrate = null; 1381 notification.setLatestEventInfo(context, text, 1382 mContext.getText(R.string.heavy_weight_notification_detail), 1383 PendingIntent.getActivityAsUser(mContext, 0, root.intent, 1384 PendingIntent.FLAG_CANCEL_CURRENT, null, 1385 new UserHandle(root.userId))); 1386 1387 try { 1388 int[] outId = new int[1]; 1389 inm.enqueueNotificationWithTag("android", "android", null, 1390 R.string.heavy_weight_notification, 1391 notification, outId, root.userId); 1392 } catch (RuntimeException e) { 1393 Slog.w(ActivityManagerService.TAG, 1394 "Error showing notification for heavy-weight app", e); 1395 } catch (RemoteException e) { 1396 } 1397 } catch (NameNotFoundException e) { 1398 Slog.w(TAG, "Unable to create context for heavy notification", e); 1399 } 1400 } break; 1401 case CANCEL_HEAVY_NOTIFICATION_MSG: { 1402 INotificationManager inm = NotificationManager.getService(); 1403 if (inm == null) { 1404 return; 1405 } 1406 try { 1407 inm.cancelNotificationWithTag("android", null, 1408 R.string.heavy_weight_notification, msg.arg1); 1409 } catch (RuntimeException e) { 1410 Slog.w(ActivityManagerService.TAG, 1411 "Error canceling notification for service", e); 1412 } catch (RemoteException e) { 1413 } 1414 } break; 1415 case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: { 1416 synchronized (ActivityManagerService.this) { 1417 checkExcessivePowerUsageLocked(true); 1418 removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1419 Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1420 sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 1421 } 1422 } break; 1423 case SHOW_COMPAT_MODE_DIALOG_MSG: { 1424 synchronized (ActivityManagerService.this) { 1425 ActivityRecord ar = (ActivityRecord)msg.obj; 1426 if (mCompatModeDialog != null) { 1427 if (mCompatModeDialog.mAppInfo.packageName.equals( 1428 ar.info.applicationInfo.packageName)) { 1429 return; 1430 } 1431 mCompatModeDialog.dismiss(); 1432 mCompatModeDialog = null; 1433 } 1434 if (ar != null && false) { 1435 if (mCompatModePackages.getPackageAskCompatModeLocked( 1436 ar.packageName)) { 1437 int mode = mCompatModePackages.computeCompatModeLocked( 1438 ar.info.applicationInfo); 1439 if (mode == ActivityManager.COMPAT_MODE_DISABLED 1440 || mode == ActivityManager.COMPAT_MODE_ENABLED) { 1441 mCompatModeDialog = new CompatModeDialog( 1442 ActivityManagerService.this, mContext, 1443 ar.info.applicationInfo); 1444 mCompatModeDialog.show(); 1445 } 1446 } 1447 } 1448 } 1449 break; 1450 } 1451 case DISPATCH_PROCESSES_CHANGED: { 1452 dispatchProcessesChanged(); 1453 break; 1454 } 1455 case DISPATCH_PROCESS_DIED: { 1456 final int pid = msg.arg1; 1457 final int uid = msg.arg2; 1458 dispatchProcessDied(pid, uid); 1459 break; 1460 } 1461 case REPORT_MEM_USAGE_MSG: { 1462 final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj; 1463 Thread thread = new Thread() { 1464 @Override public void run() { 1465 final SparseArray<ProcessMemInfo> infoMap 1466 = new SparseArray<ProcessMemInfo>(memInfos.size()); 1467 for (int i=0, N=memInfos.size(); i<N; i++) { 1468 ProcessMemInfo mi = memInfos.get(i); 1469 infoMap.put(mi.pid, mi); 1470 } 1471 updateCpuStatsNow(); 1472 synchronized (mProcessCpuThread) { 1473 final int N = mProcessCpuTracker.countStats(); 1474 for (int i=0; i<N; i++) { 1475 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 1476 if (st.vsize > 0) { 1477 long pss = Debug.getPss(st.pid, null); 1478 if (pss > 0) { 1479 if (infoMap.indexOfKey(st.pid) < 0) { 1480 ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid, 1481 ProcessList.NATIVE_ADJ, -1, "native", null); 1482 mi.pss = pss; 1483 memInfos.add(mi); 1484 } 1485 } 1486 } 1487 } 1488 } 1489 1490 long totalPss = 0; 1491 for (int i=0, N=memInfos.size(); i<N; i++) { 1492 ProcessMemInfo mi = memInfos.get(i); 1493 if (mi.pss == 0) { 1494 mi.pss = Debug.getPss(mi.pid, null); 1495 } 1496 totalPss += mi.pss; 1497 } 1498 Collections.sort(memInfos, new Comparator<ProcessMemInfo>() { 1499 @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) { 1500 if (lhs.oomAdj != rhs.oomAdj) { 1501 return lhs.oomAdj < rhs.oomAdj ? -1 : 1; 1502 } 1503 if (lhs.pss != rhs.pss) { 1504 return lhs.pss < rhs.pss ? 1 : -1; 1505 } 1506 return 0; 1507 } 1508 }); 1509 1510 StringBuilder tag = new StringBuilder(128); 1511 StringBuilder stack = new StringBuilder(128); 1512 tag.append("Low on memory -- "); 1513 appendMemBucket(tag, totalPss, "total", false); 1514 appendMemBucket(stack, totalPss, "total", true); 1515 1516 StringBuilder logBuilder = new StringBuilder(1024); 1517 logBuilder.append("Low on memory:\n"); 1518 1519 boolean firstLine = true; 1520 int lastOomAdj = Integer.MIN_VALUE; 1521 for (int i=0, N=memInfos.size(); i<N; i++) { 1522 ProcessMemInfo mi = memInfos.get(i); 1523 1524 if (mi.oomAdj != ProcessList.NATIVE_ADJ 1525 && (mi.oomAdj < ProcessList.SERVICE_ADJ 1526 || mi.oomAdj == ProcessList.HOME_APP_ADJ 1527 || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) { 1528 if (lastOomAdj != mi.oomAdj) { 1529 lastOomAdj = mi.oomAdj; 1530 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) { 1531 tag.append(" / "); 1532 } 1533 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) { 1534 if (firstLine) { 1535 stack.append(":"); 1536 firstLine = false; 1537 } 1538 stack.append("\n\t at "); 1539 } else { 1540 stack.append("$"); 1541 } 1542 } else { 1543 tag.append(" "); 1544 stack.append("$"); 1545 } 1546 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) { 1547 appendMemBucket(tag, mi.pss, mi.name, false); 1548 } 1549 appendMemBucket(stack, mi.pss, mi.name, true); 1550 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ 1551 && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) { 1552 stack.append("("); 1553 for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) { 1554 if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) { 1555 stack.append(DUMP_MEM_OOM_LABEL[k]); 1556 stack.append(":"); 1557 stack.append(DUMP_MEM_OOM_ADJ[k]); 1558 } 1559 } 1560 stack.append(")"); 1561 } 1562 } 1563 1564 logBuilder.append(" "); 1565 logBuilder.append(ProcessList.makeOomAdjString(mi.oomAdj)); 1566 logBuilder.append(' '); 1567 logBuilder.append(ProcessList.makeProcStateString(mi.procState)); 1568 logBuilder.append(' '); 1569 ProcessList.appendRamKb(logBuilder, mi.pss); 1570 logBuilder.append(" kB: "); 1571 logBuilder.append(mi.name); 1572 logBuilder.append(" ("); 1573 logBuilder.append(mi.pid); 1574 logBuilder.append(") "); 1575 logBuilder.append(mi.adjType); 1576 logBuilder.append('\n'); 1577 if (mi.adjReason != null) { 1578 logBuilder.append(" "); 1579 logBuilder.append(mi.adjReason); 1580 logBuilder.append('\n'); 1581 } 1582 } 1583 1584 logBuilder.append(" "); 1585 ProcessList.appendRamKb(logBuilder, totalPss); 1586 logBuilder.append(" kB: TOTAL\n"); 1587 1588 long[] infos = new long[Debug.MEMINFO_COUNT]; 1589 Debug.getMemInfo(infos); 1590 logBuilder.append(" MemInfo: "); 1591 logBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, "); 1592 logBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, "); 1593 logBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, "); 1594 logBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, "); 1595 logBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n"); 1596 if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) { 1597 logBuilder.append(" ZRAM: "); 1598 logBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]); 1599 logBuilder.append(" kB RAM, "); 1600 logBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]); 1601 logBuilder.append(" kB swap total, "); 1602 logBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]); 1603 logBuilder.append(" kB swap free\n"); 1604 } 1605 Slog.i(TAG, logBuilder.toString()); 1606 1607 StringBuilder dropBuilder = new StringBuilder(1024); 1608 /* 1609 StringWriter oomSw = new StringWriter(); 1610 PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256); 1611 StringWriter catSw = new StringWriter(); 1612 PrintWriter catPw = new FastPrintWriter(catSw, false, 256); 1613 String[] emptyArgs = new String[] { }; 1614 dumpApplicationMemoryUsage(null, oomPw, " ", emptyArgs, true, catPw); 1615 oomPw.flush(); 1616 String oomString = oomSw.toString(); 1617 */ 1618 dropBuilder.append(stack); 1619 dropBuilder.append('\n'); 1620 dropBuilder.append('\n'); 1621 dropBuilder.append(logBuilder); 1622 dropBuilder.append('\n'); 1623 /* 1624 dropBuilder.append(oomString); 1625 dropBuilder.append('\n'); 1626 */ 1627 StringWriter catSw = new StringWriter(); 1628 synchronized (ActivityManagerService.this) { 1629 PrintWriter catPw = new FastPrintWriter(catSw, false, 256); 1630 String[] emptyArgs = new String[] { }; 1631 catPw.println(); 1632 dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null); 1633 catPw.println(); 1634 mServices.dumpServicesLocked(null, catPw, emptyArgs, 0, 1635 false, false, null); 1636 catPw.println(); 1637 dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null); 1638 catPw.flush(); 1639 } 1640 dropBuilder.append(catSw.toString()); 1641 addErrorToDropBox("lowmem", null, "system_server", null, 1642 null, tag.toString(), dropBuilder.toString(), null, null); 1643 //Slog.i(TAG, "Sent to dropbox:"); 1644 //Slog.i(TAG, dropBuilder.toString()); 1645 synchronized (ActivityManagerService.this) { 1646 long now = SystemClock.uptimeMillis(); 1647 if (mLastMemUsageReportTime < now) { 1648 mLastMemUsageReportTime = now; 1649 } 1650 } 1651 } 1652 }; 1653 thread.start(); 1654 break; 1655 } 1656 case REPORT_USER_SWITCH_MSG: { 1657 dispatchUserSwitch((UserStartedState)msg.obj, msg.arg1, msg.arg2); 1658 break; 1659 } 1660 case CONTINUE_USER_SWITCH_MSG: { 1661 continueUserSwitch((UserStartedState)msg.obj, msg.arg1, msg.arg2); 1662 break; 1663 } 1664 case USER_SWITCH_TIMEOUT_MSG: { 1665 timeoutUserSwitch((UserStartedState)msg.obj, msg.arg1, msg.arg2); 1666 break; 1667 } 1668 case IMMERSIVE_MODE_LOCK_MSG: { 1669 final boolean nextState = (msg.arg1 != 0); 1670 if (mUpdateLock.isHeld() != nextState) { 1671 if (DEBUG_IMMERSIVE) { 1672 final ActivityRecord r = (ActivityRecord) msg.obj; 1673 Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r); 1674 } 1675 if (nextState) { 1676 mUpdateLock.acquire(); 1677 } else { 1678 mUpdateLock.release(); 1679 } 1680 } 1681 break; 1682 } 1683 case PERSIST_URI_GRANTS_MSG: { 1684 writeGrantedUriPermissions(); 1685 break; 1686 } 1687 case REQUEST_ALL_PSS_MSG: { 1688 requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false); 1689 break; 1690 } 1691 case START_RELATED_USERS_MSG: { 1692 synchronized (ActivityManagerService.this) { 1693 startRelatedUsersLocked(); 1694 } 1695 break; 1696 } 1697 } 1698 } 1699 }; 1700 1701 static final int COLLECT_PSS_BG_MSG = 1; 1702 1703 final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) { 1704 @Override 1705 public void handleMessage(Message msg) { 1706 switch (msg.what) { 1707 case COLLECT_PSS_BG_MSG: { 1708 int i=0, num=0; 1709 long start = SystemClock.uptimeMillis(); 1710 long[] tmp = new long[1]; 1711 do { 1712 ProcessRecord proc; 1713 int procState; 1714 int pid; 1715 synchronized (ActivityManagerService.this) { 1716 if (i >= mPendingPssProcesses.size()) { 1717 if (DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num + " of " + i 1718 + " processes in " + (SystemClock.uptimeMillis()-start) + "ms"); 1719 mPendingPssProcesses.clear(); 1720 return; 1721 } 1722 proc = mPendingPssProcesses.get(i); 1723 procState = proc.pssProcState; 1724 if (proc.thread != null && procState == proc.setProcState) { 1725 pid = proc.pid; 1726 } else { 1727 proc = null; 1728 pid = 0; 1729 } 1730 i++; 1731 } 1732 if (proc != null) { 1733 long pss = Debug.getPss(pid, tmp); 1734 synchronized (ActivityManagerService.this) { 1735 if (proc.thread != null && proc.setProcState == procState 1736 && proc.pid == pid) { 1737 num++; 1738 proc.lastPssTime = SystemClock.uptimeMillis(); 1739 proc.baseProcessTracker.addPss(pss, tmp[0], true, proc.pkgList); 1740 if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString() 1741 + ": " + pss + " lastPss=" + proc.lastPss 1742 + " state=" + ProcessList.makeProcStateString(procState)); 1743 if (proc.initialIdlePss == 0) { 1744 proc.initialIdlePss = pss; 1745 } 1746 proc.lastPss = pss; 1747 if (procState >= ActivityManager.PROCESS_STATE_HOME) { 1748 proc.lastCachedPss = pss; 1749 } 1750 } 1751 } 1752 } 1753 } while (true); 1754 } 1755 } 1756 } 1757 }; 1758 1759 public void setSystemProcess() { 1760 try { 1761 ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true); 1762 ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats); 1763 ServiceManager.addService("meminfo", new MemBinder(this)); 1764 ServiceManager.addService("gfxinfo", new GraphicsBinder(this)); 1765 ServiceManager.addService("dbinfo", new DbBinder(this)); 1766 if (MONITOR_CPU_USAGE) { 1767 ServiceManager.addService("cpuinfo", new CpuBinder(this)); 1768 } 1769 ServiceManager.addService("permission", new PermissionController(this)); 1770 1771 ApplicationInfo info = mContext.getPackageManager().getApplicationInfo( 1772 "android", STOCK_PM_FLAGS); 1773 mSystemThread.installSystemApplicationInfo(info); 1774 1775 synchronized (this) { 1776 ProcessRecord app = newProcessRecordLocked(info, info.processName, false); 1777 app.persistent = true; 1778 app.pid = MY_PID; 1779 app.maxAdj = ProcessList.SYSTEM_ADJ; 1780 app.makeActive(mSystemThread.getApplicationThread(), mProcessStats); 1781 mProcessNames.put(app.processName, app.uid, app); 1782 synchronized (mPidsSelfLocked) { 1783 mPidsSelfLocked.put(app.pid, app); 1784 } 1785 updateLruProcessLocked(app, false, null); 1786 updateOomAdjLocked(); 1787 } 1788 } catch (PackageManager.NameNotFoundException e) { 1789 throw new RuntimeException( 1790 "Unable to find android system package", e); 1791 } 1792 } 1793 1794 public void setWindowManager(WindowManagerService wm) { 1795 mWindowManager = wm; 1796 mStackSupervisor.setWindowManager(wm); 1797 } 1798 1799 public void startObservingNativeCrashes() { 1800 final NativeCrashListener ncl = new NativeCrashListener(this); 1801 ncl.start(); 1802 } 1803 1804 public IAppOpsService getAppOpsService() { 1805 return mAppOpsService; 1806 } 1807 1808 static class MemBinder extends Binder { 1809 ActivityManagerService mActivityManagerService; 1810 MemBinder(ActivityManagerService activityManagerService) { 1811 mActivityManagerService = activityManagerService; 1812 } 1813 1814 @Override 1815 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1816 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1817 != PackageManager.PERMISSION_GRANTED) { 1818 pw.println("Permission Denial: can't dump meminfo from from pid=" 1819 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1820 + " without permission " + android.Manifest.permission.DUMP); 1821 return; 1822 } 1823 1824 mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, " ", args, false, null); 1825 } 1826 } 1827 1828 static class GraphicsBinder extends Binder { 1829 ActivityManagerService mActivityManagerService; 1830 GraphicsBinder(ActivityManagerService activityManagerService) { 1831 mActivityManagerService = activityManagerService; 1832 } 1833 1834 @Override 1835 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1836 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1837 != PackageManager.PERMISSION_GRANTED) { 1838 pw.println("Permission Denial: can't dump gfxinfo from from pid=" 1839 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1840 + " without permission " + android.Manifest.permission.DUMP); 1841 return; 1842 } 1843 1844 mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args); 1845 } 1846 } 1847 1848 static class DbBinder extends Binder { 1849 ActivityManagerService mActivityManagerService; 1850 DbBinder(ActivityManagerService activityManagerService) { 1851 mActivityManagerService = activityManagerService; 1852 } 1853 1854 @Override 1855 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1856 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1857 != PackageManager.PERMISSION_GRANTED) { 1858 pw.println("Permission Denial: can't dump dbinfo from from pid=" 1859 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1860 + " without permission " + android.Manifest.permission.DUMP); 1861 return; 1862 } 1863 1864 mActivityManagerService.dumpDbInfo(fd, pw, args); 1865 } 1866 } 1867 1868 static class CpuBinder extends Binder { 1869 ActivityManagerService mActivityManagerService; 1870 CpuBinder(ActivityManagerService activityManagerService) { 1871 mActivityManagerService = activityManagerService; 1872 } 1873 1874 @Override 1875 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1876 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1877 != PackageManager.PERMISSION_GRANTED) { 1878 pw.println("Permission Denial: can't dump cpuinfo from from pid=" 1879 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1880 + " without permission " + android.Manifest.permission.DUMP); 1881 return; 1882 } 1883 1884 synchronized (mActivityManagerService.mProcessCpuThread) { 1885 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad()); 1886 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState( 1887 SystemClock.uptimeMillis())); 1888 } 1889 } 1890 } 1891 1892 public static final class Lifecycle extends SystemService { 1893 private final ActivityManagerService mService; 1894 1895 public Lifecycle(Context context) { 1896 super(context); 1897 mService = new ActivityManagerService(context); 1898 } 1899 1900 @Override 1901 public void onStart() { 1902 mService.start(); 1903 } 1904 1905 public ActivityManagerService getService() { 1906 return mService; 1907 } 1908 } 1909 1910 // Note: This method is invoked on the main thread but may need to attach various 1911 // handlers to other threads. So take care to be explicit about the looper. 1912 public ActivityManagerService(Context systemContext) { 1913 mContext = systemContext; 1914 mFactoryTest = FactoryTest.getMode(); 1915 mSystemThread = ActivityThread.currentActivityThread(); 1916 1917 Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass()); 1918 1919 mHandlerThread = new ServiceThread(TAG, 1920 android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/); 1921 mHandlerThread.start(); 1922 mHandler = new MainHandler(mHandlerThread.getLooper()); 1923 1924 mFgBroadcastQueue = new BroadcastQueue(this, mHandler, 1925 "foreground", BROADCAST_FG_TIMEOUT, false); 1926 mBgBroadcastQueue = new BroadcastQueue(this, mHandler, 1927 "background", BROADCAST_BG_TIMEOUT, true); 1928 mBroadcastQueues[0] = mFgBroadcastQueue; 1929 mBroadcastQueues[1] = mBgBroadcastQueue; 1930 1931 mServices = new ActiveServices(this); 1932 mProviderMap = new ProviderMap(this); 1933 1934 // TODO: Move creation of battery stats service outside of activity manager service. 1935 File dataDir = Environment.getDataDirectory(); 1936 File systemDir = new File(dataDir, "system"); 1937 systemDir.mkdirs(); 1938 mBatteryStatsService = new BatteryStatsService(new File( 1939 systemDir, "batterystats.bin").toString(), mHandler); 1940 mBatteryStatsService.getActiveStatistics().readLocked(); 1941 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 1942 mOnBattery = DEBUG_POWER ? true 1943 : mBatteryStatsService.getActiveStatistics().getIsOnBattery(); 1944 mBatteryStatsService.getActiveStatistics().setCallback(this); 1945 1946 mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats")); 1947 1948 mUsageStatsService = new UsageStatsService(new File(systemDir, "usagestats").toString()); 1949 mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler); 1950 1951 mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml")); 1952 1953 // User 0 is the first and only user that runs at boot. 1954 mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true)); 1955 mUserLru.add(Integer.valueOf(0)); 1956 updateStartedUserArrayLocked(); 1957 1958 GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version", 1959 ConfigurationInfo.GL_ES_VERSION_UNDEFINED); 1960 1961 mConfiguration.setToDefaults(); 1962 mConfiguration.setLocale(Locale.getDefault()); 1963 1964 mConfigurationSeq = mConfiguration.seq = 1; 1965 mProcessCpuTracker.init(); 1966 1967 mCompatModePackages = new CompatModePackages(this, systemDir, mHandler); 1968 mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler); 1969 mStackSupervisor = new ActivityStackSupervisor(this); 1970 1971 mProcessCpuThread = new Thread("CpuTracker") { 1972 @Override 1973 public void run() { 1974 while (true) { 1975 try { 1976 try { 1977 synchronized(this) { 1978 final long now = SystemClock.uptimeMillis(); 1979 long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now; 1980 long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now; 1981 //Slog.i(TAG, "Cpu delay=" + nextCpuDelay 1982 // + ", write delay=" + nextWriteDelay); 1983 if (nextWriteDelay < nextCpuDelay) { 1984 nextCpuDelay = nextWriteDelay; 1985 } 1986 if (nextCpuDelay > 0) { 1987 mProcessCpuMutexFree.set(true); 1988 this.wait(nextCpuDelay); 1989 } 1990 } 1991 } catch (InterruptedException e) { 1992 } 1993 updateCpuStatsNow(); 1994 } catch (Exception e) { 1995 Slog.e(TAG, "Unexpected exception collecting process stats", e); 1996 } 1997 } 1998 } 1999 }; 2000 2001 Watchdog.getInstance().addMonitor(this); 2002 Watchdog.getInstance().addThread(mHandler); 2003 } 2004 2005 private void start() { 2006 mProcessCpuThread.start(); 2007 2008 mBatteryStatsService.publish(mContext); 2009 mUsageStatsService.publish(mContext); 2010 mAppOpsService.publish(mContext); 2011 startRunning(null, null, null, null); 2012 } 2013 2014 @Override 2015 public boolean onTransact(int code, Parcel data, Parcel reply, int flags) 2016 throws RemoteException { 2017 if (code == SYSPROPS_TRANSACTION) { 2018 // We need to tell all apps about the system property change. 2019 ArrayList<IBinder> procs = new ArrayList<IBinder>(); 2020 synchronized(this) { 2021 final int NP = mProcessNames.getMap().size(); 2022 for (int ip=0; ip<NP; ip++) { 2023 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 2024 final int NA = apps.size(); 2025 for (int ia=0; ia<NA; ia++) { 2026 ProcessRecord app = apps.valueAt(ia); 2027 if (app.thread != null) { 2028 procs.add(app.thread.asBinder()); 2029 } 2030 } 2031 } 2032 } 2033 2034 int N = procs.size(); 2035 for (int i=0; i<N; i++) { 2036 Parcel data2 = Parcel.obtain(); 2037 try { 2038 procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0); 2039 } catch (RemoteException e) { 2040 } 2041 data2.recycle(); 2042 } 2043 } 2044 try { 2045 return super.onTransact(code, data, reply, flags); 2046 } catch (RuntimeException e) { 2047 // The activity manager only throws security exceptions, so let's 2048 // log all others. 2049 if (!(e instanceof SecurityException)) { 2050 Slog.wtf(TAG, "Activity Manager Crash", e); 2051 } 2052 throw e; 2053 } 2054 } 2055 2056 void updateCpuStats() { 2057 final long now = SystemClock.uptimeMillis(); 2058 if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) { 2059 return; 2060 } 2061 if (mProcessCpuMutexFree.compareAndSet(true, false)) { 2062 synchronized (mProcessCpuThread) { 2063 mProcessCpuThread.notify(); 2064 } 2065 } 2066 } 2067 2068 void updateCpuStatsNow() { 2069 synchronized (mProcessCpuThread) { 2070 mProcessCpuMutexFree.set(false); 2071 final long now = SystemClock.uptimeMillis(); 2072 boolean haveNewCpuStats = false; 2073 2074 if (MONITOR_CPU_USAGE && 2075 mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) { 2076 mLastCpuTime.set(now); 2077 haveNewCpuStats = true; 2078 mProcessCpuTracker.update(); 2079 //Slog.i(TAG, mProcessCpu.printCurrentState()); 2080 //Slog.i(TAG, "Total CPU usage: " 2081 // + mProcessCpu.getTotalCpuPercent() + "%"); 2082 2083 // Slog the cpu usage if the property is set. 2084 if ("true".equals(SystemProperties.get("events.cpu"))) { 2085 int user = mProcessCpuTracker.getLastUserTime(); 2086 int system = mProcessCpuTracker.getLastSystemTime(); 2087 int iowait = mProcessCpuTracker.getLastIoWaitTime(); 2088 int irq = mProcessCpuTracker.getLastIrqTime(); 2089 int softIrq = mProcessCpuTracker.getLastSoftIrqTime(); 2090 int idle = mProcessCpuTracker.getLastIdleTime(); 2091 2092 int total = user + system + iowait + irq + softIrq + idle; 2093 if (total == 0) total = 1; 2094 2095 EventLog.writeEvent(EventLogTags.CPU, 2096 ((user+system+iowait+irq+softIrq) * 100) / total, 2097 (user * 100) / total, 2098 (system * 100) / total, 2099 (iowait * 100) / total, 2100 (irq * 100) / total, 2101 (softIrq * 100) / total); 2102 } 2103 } 2104 2105 long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes(); 2106 final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics(); 2107 synchronized(bstats) { 2108 synchronized(mPidsSelfLocked) { 2109 if (haveNewCpuStats) { 2110 if (mOnBattery) { 2111 int perc = bstats.startAddingCpuLocked(); 2112 int totalUTime = 0; 2113 int totalSTime = 0; 2114 final int N = mProcessCpuTracker.countStats(); 2115 for (int i=0; i<N; i++) { 2116 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 2117 if (!st.working) { 2118 continue; 2119 } 2120 ProcessRecord pr = mPidsSelfLocked.get(st.pid); 2121 int otherUTime = (st.rel_utime*perc)/100; 2122 int otherSTime = (st.rel_stime*perc)/100; 2123 totalUTime += otherUTime; 2124 totalSTime += otherSTime; 2125 if (pr != null) { 2126 BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats; 2127 if (ps == null || !ps.isActive()) { 2128 pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked( 2129 pr.info.uid, pr.processName); 2130 } 2131 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 2132 st.rel_stime-otherSTime); 2133 ps.addSpeedStepTimes(cpuSpeedTimes); 2134 pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10; 2135 } else { 2136 BatteryStatsImpl.Uid.Proc ps = st.batteryStats; 2137 if (ps == null || !ps.isActive()) { 2138 st.batteryStats = ps = bstats.getProcessStatsLocked( 2139 bstats.mapUid(st.uid), st.name); 2140 } 2141 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 2142 st.rel_stime-otherSTime); 2143 ps.addSpeedStepTimes(cpuSpeedTimes); 2144 } 2145 } 2146 bstats.finishAddingCpuLocked(perc, totalUTime, 2147 totalSTime, cpuSpeedTimes); 2148 } 2149 } 2150 } 2151 2152 if (mLastWriteTime < (now-BATTERY_STATS_TIME)) { 2153 mLastWriteTime = now; 2154 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 2155 } 2156 } 2157 } 2158 } 2159 2160 @Override 2161 public void batteryNeedsCpuUpdate() { 2162 updateCpuStatsNow(); 2163 } 2164 2165 @Override 2166 public void batteryPowerChanged(boolean onBattery) { 2167 // When plugging in, update the CPU stats first before changing 2168 // the plug state. 2169 updateCpuStatsNow(); 2170 synchronized (this) { 2171 synchronized(mPidsSelfLocked) { 2172 mOnBattery = DEBUG_POWER ? true : onBattery; 2173 } 2174 } 2175 } 2176 2177 /** 2178 * Initialize the application bind args. These are passed to each 2179 * process when the bindApplication() IPC is sent to the process. They're 2180 * lazily setup to make sure the services are running when they're asked for. 2181 */ 2182 private HashMap<String, IBinder> getCommonServicesLocked() { 2183 if (mAppBindArgs == null) { 2184 mAppBindArgs = new HashMap<String, IBinder>(); 2185 2186 // Setup the application init args 2187 mAppBindArgs.put("package", ServiceManager.getService("package")); 2188 mAppBindArgs.put("window", ServiceManager.getService("window")); 2189 mAppBindArgs.put(Context.ALARM_SERVICE, 2190 ServiceManager.getService(Context.ALARM_SERVICE)); 2191 } 2192 return mAppBindArgs; 2193 } 2194 2195 final void setFocusedActivityLocked(ActivityRecord r) { 2196 if (mFocusedActivity != r) { 2197 if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r); 2198 mFocusedActivity = r; 2199 mStackSupervisor.setFocusedStack(r); 2200 if (r != null) { 2201 mWindowManager.setFocusedApp(r.appToken, true); 2202 } 2203 applyUpdateLockStateLocked(r); 2204 } 2205 } 2206 2207 @Override 2208 public void setFocusedStack(int stackId) { 2209 if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId); 2210 synchronized (ActivityManagerService.this) { 2211 ActivityStack stack = mStackSupervisor.getStack(stackId); 2212 if (stack != null) { 2213 ActivityRecord r = stack.topRunningActivityLocked(null); 2214 if (r != null) { 2215 setFocusedActivityLocked(r); 2216 } 2217 } 2218 } 2219 } 2220 2221 @Override 2222 public void notifyActivityDrawn(IBinder token) { 2223 if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token); 2224 synchronized (this) { 2225 ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token); 2226 if (r != null) { 2227 r.task.stack.notifyActivityDrawnLocked(r); 2228 } 2229 } 2230 } 2231 2232 final void applyUpdateLockStateLocked(ActivityRecord r) { 2233 // Modifications to the UpdateLock state are done on our handler, outside 2234 // the activity manager's locks. The new state is determined based on the 2235 // state *now* of the relevant activity record. The object is passed to 2236 // the handler solely for logging detail, not to be consulted/modified. 2237 final boolean nextState = r != null && r.immersive; 2238 mHandler.sendMessage( 2239 mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r)); 2240 } 2241 2242 final void showAskCompatModeDialogLocked(ActivityRecord r) { 2243 Message msg = Message.obtain(); 2244 msg.what = SHOW_COMPAT_MODE_DIALOG_MSG; 2245 msg.obj = r.task.askedCompatMode ? null : r; 2246 mHandler.sendMessage(msg); 2247 } 2248 2249 private final int updateLruProcessInternalLocked(ProcessRecord app, long now, int index, 2250 String what, Object obj, ProcessRecord srcApp) { 2251 app.lastActivityTime = now; 2252 2253 if (app.activities.size() > 0) { 2254 // Don't want to touch dependent processes that are hosting activities. 2255 return index; 2256 } 2257 2258 int lrui = mLruProcesses.lastIndexOf(app); 2259 if (lrui < 0) { 2260 Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: " 2261 + what + " " + obj + " from " + srcApp); 2262 return index; 2263 } 2264 2265 if (lrui >= index) { 2266 // Don't want to cause this to move dependent processes *back* in the 2267 // list as if they were less frequently used. 2268 return index; 2269 } 2270 2271 if (lrui >= mLruProcessActivityStart) { 2272 // Don't want to touch dependent processes that are hosting activities. 2273 return index; 2274 } 2275 2276 mLruProcesses.remove(lrui); 2277 if (index > 0) { 2278 index--; 2279 } 2280 if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index 2281 + " in LRU list: " + app); 2282 mLruProcesses.add(index, app); 2283 return index; 2284 } 2285 2286 final void removeLruProcessLocked(ProcessRecord app) { 2287 int lrui = mLruProcesses.lastIndexOf(app); 2288 if (lrui >= 0) { 2289 if (lrui <= mLruProcessActivityStart) { 2290 mLruProcessActivityStart--; 2291 } 2292 if (lrui <= mLruProcessServiceStart) { 2293 mLruProcessServiceStart--; 2294 } 2295 mLruProcesses.remove(lrui); 2296 } 2297 } 2298 2299 final void updateLruProcessLocked(ProcessRecord app, boolean activityChange, 2300 ProcessRecord client) { 2301 final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities; 2302 final boolean hasService = false; // not impl yet. app.services.size() > 0; 2303 if (!activityChange && hasActivity) { 2304 // The process has activties, so we are only going to allow activity-based 2305 // adjustments move it. It should be kept in the front of the list with other 2306 // processes that have activities, and we don't want those to change their 2307 // order except due to activity operations. 2308 return; 2309 } 2310 2311 mLruSeq++; 2312 final long now = SystemClock.uptimeMillis(); 2313 app.lastActivityTime = now; 2314 2315 // First a quick reject: if the app is already at the position we will 2316 // put it, then there is nothing to do. 2317 if (hasActivity) { 2318 final int N = mLruProcesses.size(); 2319 if (N > 0 && mLruProcesses.get(N-1) == app) { 2320 if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app); 2321 return; 2322 } 2323 } else { 2324 if (mLruProcessServiceStart > 0 2325 && mLruProcesses.get(mLruProcessServiceStart-1) == app) { 2326 if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app); 2327 return; 2328 } 2329 } 2330 2331 int lrui = mLruProcesses.lastIndexOf(app); 2332 2333 if (app.persistent && lrui >= 0) { 2334 // We don't care about the position of persistent processes, as long as 2335 // they are in the list. 2336 if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app); 2337 return; 2338 } 2339 2340 /* In progress: compute new position first, so we can avoid doing work 2341 if the process is not actually going to move. Not yet working. 2342 int addIndex; 2343 int nextIndex; 2344 boolean inActivity = false, inService = false; 2345 if (hasActivity) { 2346 // Process has activities, put it at the very tipsy-top. 2347 addIndex = mLruProcesses.size(); 2348 nextIndex = mLruProcessServiceStart; 2349 inActivity = true; 2350 } else if (hasService) { 2351 // Process has services, put it at the top of the service list. 2352 addIndex = mLruProcessActivityStart; 2353 nextIndex = mLruProcessServiceStart; 2354 inActivity = true; 2355 inService = true; 2356 } else { 2357 // Process not otherwise of interest, it goes to the top of the non-service area. 2358 addIndex = mLruProcessServiceStart; 2359 if (client != null) { 2360 int clientIndex = mLruProcesses.lastIndexOf(client); 2361 if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating " 2362 + app); 2363 if (clientIndex >= 0 && addIndex > clientIndex) { 2364 addIndex = clientIndex; 2365 } 2366 } 2367 nextIndex = addIndex > 0 ? addIndex-1 : addIndex; 2368 } 2369 2370 Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act=" 2371 + mLruProcessActivityStart + "): " + app); 2372 */ 2373 2374 if (lrui >= 0) { 2375 if (lrui < mLruProcessActivityStart) { 2376 mLruProcessActivityStart--; 2377 } 2378 if (lrui < mLruProcessServiceStart) { 2379 mLruProcessServiceStart--; 2380 } 2381 /* 2382 if (addIndex > lrui) { 2383 addIndex--; 2384 } 2385 if (nextIndex > lrui) { 2386 nextIndex--; 2387 } 2388 */ 2389 mLruProcesses.remove(lrui); 2390 } 2391 2392 /* 2393 mLruProcesses.add(addIndex, app); 2394 if (inActivity) { 2395 mLruProcessActivityStart++; 2396 } 2397 if (inService) { 2398 mLruProcessActivityStart++; 2399 } 2400 */ 2401 2402 int nextIndex; 2403 if (hasActivity) { 2404 final int N = mLruProcesses.size(); 2405 if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) { 2406 // Process doesn't have activities, but has clients with 2407 // activities... move it up, but one below the top (the top 2408 // should always have a real activity). 2409 if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app); 2410 mLruProcesses.add(N-1, app); 2411 // To keep it from spamming the LRU list (by making a bunch of clients), 2412 // we will push down any other entries owned by the app. 2413 final int uid = app.info.uid; 2414 for (int i=N-2; i>mLruProcessActivityStart; i--) { 2415 ProcessRecord subProc = mLruProcesses.get(i); 2416 if (subProc.info.uid == uid) { 2417 // We want to push this one down the list. If the process after 2418 // it is for the same uid, however, don't do so, because we don't 2419 // want them internally to be re-ordered. 2420 if (mLruProcesses.get(i-1).info.uid != uid) { 2421 if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i 2422 + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1)); 2423 ProcessRecord tmp = mLruProcesses.get(i); 2424 mLruProcesses.set(i, mLruProcesses.get(i-1)); 2425 mLruProcesses.set(i-1, tmp); 2426 i--; 2427 } 2428 } else { 2429 // A gap, we can stop here. 2430 break; 2431 } 2432 } 2433 } else { 2434 // Process has activities, put it at the very tipsy-top. 2435 if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app); 2436 mLruProcesses.add(app); 2437 } 2438 nextIndex = mLruProcessServiceStart; 2439 } else if (hasService) { 2440 // Process has services, put it at the top of the service list. 2441 if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app); 2442 mLruProcesses.add(mLruProcessActivityStart, app); 2443 nextIndex = mLruProcessServiceStart; 2444 mLruProcessActivityStart++; 2445 } else { 2446 // Process not otherwise of interest, it goes to the top of the non-service area. 2447 int index = mLruProcessServiceStart; 2448 if (client != null) { 2449 // If there is a client, don't allow the process to be moved up higher 2450 // in the list than that client. 2451 int clientIndex = mLruProcesses.lastIndexOf(client); 2452 if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client 2453 + " when updating " + app); 2454 if (clientIndex <= lrui) { 2455 // Don't allow the client index restriction to push it down farther in the 2456 // list than it already is. 2457 clientIndex = lrui; 2458 } 2459 if (clientIndex >= 0 && index > clientIndex) { 2460 index = clientIndex; 2461 } 2462 } 2463 if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app); 2464 mLruProcesses.add(index, app); 2465 nextIndex = index-1; 2466 mLruProcessActivityStart++; 2467 mLruProcessServiceStart++; 2468 } 2469 2470 // If the app is currently using a content provider or service, 2471 // bump those processes as well. 2472 for (int j=app.connections.size()-1; j>=0; j--) { 2473 ConnectionRecord cr = app.connections.valueAt(j); 2474 if (cr.binding != null && !cr.serviceDead && cr.binding.service != null 2475 && cr.binding.service.app != null 2476 && cr.binding.service.app.lruSeq != mLruSeq 2477 && !cr.binding.service.app.persistent) { 2478 nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex, 2479 "service connection", cr, app); 2480 } 2481 } 2482 for (int j=app.conProviders.size()-1; j>=0; j--) { 2483 ContentProviderRecord cpr = app.conProviders.get(j).provider; 2484 if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) { 2485 nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex, 2486 "provider reference", cpr, app); 2487 } 2488 } 2489 } 2490 2491 final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) { 2492 if (uid == Process.SYSTEM_UID) { 2493 // The system gets to run in any process. If there are multiple 2494 // processes with the same uid, just pick the first (this 2495 // should never happen). 2496 SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName); 2497 if (procs == null) return null; 2498 final int N = procs.size(); 2499 for (int i = 0; i < N; i++) { 2500 if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i); 2501 } 2502 } 2503 ProcessRecord proc = mProcessNames.get(processName, uid); 2504 if (false && proc != null && !keepIfLarge 2505 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY 2506 && proc.lastCachedPss >= 4000) { 2507 // Turn this condition on to cause killing to happen regularly, for testing. 2508 if (proc.baseProcessTracker != null) { 2509 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss); 2510 } 2511 killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss) 2512 + "k from cached"); 2513 } else if (proc != null && !keepIfLarge 2514 && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL 2515 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) { 2516 if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss); 2517 if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) { 2518 if (proc.baseProcessTracker != null) { 2519 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss); 2520 } 2521 killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss) 2522 + "k from cached"); 2523 } 2524 } 2525 return proc; 2526 } 2527 2528 void ensurePackageDexOpt(String packageName) { 2529 IPackageManager pm = AppGlobals.getPackageManager(); 2530 try { 2531 if (pm.performDexOpt(packageName)) { 2532 mDidDexOpt = true; 2533 } 2534 } catch (RemoteException e) { 2535 } 2536 } 2537 2538 boolean isNextTransitionForward() { 2539 int transit = mWindowManager.getPendingAppTransition(); 2540 return transit == AppTransition.TRANSIT_ACTIVITY_OPEN 2541 || transit == AppTransition.TRANSIT_TASK_OPEN 2542 || transit == AppTransition.TRANSIT_TASK_TO_FRONT; 2543 } 2544 2545 final ProcessRecord startProcessLocked(String processName, 2546 ApplicationInfo info, boolean knownToBeDead, int intentFlags, 2547 String hostingType, ComponentName hostingName, boolean allowWhileBooting, 2548 boolean isolated, boolean keepIfLarge) { 2549 ProcessRecord app; 2550 if (!isolated) { 2551 app = getProcessRecordLocked(processName, info.uid, keepIfLarge); 2552 } else { 2553 // If this is an isolated process, it can't re-use an existing process. 2554 app = null; 2555 } 2556 // We don't have to do anything more if: 2557 // (1) There is an existing application record; and 2558 // (2) The caller doesn't think it is dead, OR there is no thread 2559 // object attached to it so we know it couldn't have crashed; and 2560 // (3) There is a pid assigned to it, so it is either starting or 2561 // already running. 2562 if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName 2563 + " app=" + app + " knownToBeDead=" + knownToBeDead 2564 + " thread=" + (app != null ? app.thread : null) 2565 + " pid=" + (app != null ? app.pid : -1)); 2566 if (app != null && app.pid > 0) { 2567 if (!knownToBeDead || app.thread == null) { 2568 // We already have the app running, or are waiting for it to 2569 // come up (we have a pid but not yet its thread), so keep it. 2570 if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app); 2571 // If this is a new package in the process, add the package to the list 2572 app.addPackage(info.packageName, mProcessStats); 2573 return app; 2574 } 2575 2576 // An application record is attached to a previous process, 2577 // clean it up now. 2578 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app); 2579 handleAppDiedLocked(app, true, true); 2580 } 2581 2582 String hostingNameStr = hostingName != null 2583 ? hostingName.flattenToShortString() : null; 2584 2585 if (!isolated) { 2586 if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) { 2587 // If we are in the background, then check to see if this process 2588 // is bad. If so, we will just silently fail. 2589 if (mBadProcesses.get(info.processName, info.uid) != null) { 2590 if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid 2591 + "/" + info.processName); 2592 return null; 2593 } 2594 } else { 2595 // When the user is explicitly starting a process, then clear its 2596 // crash count so that we won't make it bad until they see at 2597 // least one crash dialog again, and make the process good again 2598 // if it had been bad. 2599 if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid 2600 + "/" + info.processName); 2601 mProcessCrashTimes.remove(info.processName, info.uid); 2602 if (mBadProcesses.get(info.processName, info.uid) != null) { 2603 EventLog.writeEvent(EventLogTags.AM_PROC_GOOD, 2604 UserHandle.getUserId(info.uid), info.uid, 2605 info.processName); 2606 mBadProcesses.remove(info.processName, info.uid); 2607 if (app != null) { 2608 app.bad = false; 2609 } 2610 } 2611 } 2612 } 2613 2614 if (app == null) { 2615 app = newProcessRecordLocked(info, processName, isolated); 2616 if (app == null) { 2617 Slog.w(TAG, "Failed making new process record for " 2618 + processName + "/" + info.uid + " isolated=" + isolated); 2619 return null; 2620 } 2621 mProcessNames.put(processName, app.uid, app); 2622 if (isolated) { 2623 mIsolatedProcesses.put(app.uid, app); 2624 } 2625 } else { 2626 // If this is a new package in the process, add the package to the list 2627 app.addPackage(info.packageName, mProcessStats); 2628 } 2629 2630 // If the system is not ready yet, then hold off on starting this 2631 // process until it is. 2632 if (!mProcessesReady 2633 && !isAllowedWhileBooting(info) 2634 && !allowWhileBooting) { 2635 if (!mProcessesOnHold.contains(app)) { 2636 mProcessesOnHold.add(app); 2637 } 2638 if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app); 2639 return app; 2640 } 2641 2642 startProcessLocked(app, hostingType, hostingNameStr); 2643 return (app.pid != 0) ? app : null; 2644 } 2645 2646 boolean isAllowedWhileBooting(ApplicationInfo ai) { 2647 return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0; 2648 } 2649 2650 private final void startProcessLocked(ProcessRecord app, 2651 String hostingType, String hostingNameStr) { 2652 if (app.pid > 0 && app.pid != MY_PID) { 2653 synchronized (mPidsSelfLocked) { 2654 mPidsSelfLocked.remove(app.pid); 2655 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 2656 } 2657 app.setPid(0); 2658 } 2659 2660 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 2661 "startProcessLocked removing on hold: " + app); 2662 mProcessesOnHold.remove(app); 2663 2664 updateCpuStats(); 2665 2666 try { 2667 int uid = app.uid; 2668 2669 int[] gids = null; 2670 int mountExternal = Zygote.MOUNT_EXTERNAL_NONE; 2671 if (!app.isolated) { 2672 int[] permGids = null; 2673 try { 2674 final PackageManager pm = mContext.getPackageManager(); 2675 permGids = pm.getPackageGids(app.info.packageName); 2676 2677 if (Environment.isExternalStorageEmulated()) { 2678 if (pm.checkPermission( 2679 android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE, 2680 app.info.packageName) == PERMISSION_GRANTED) { 2681 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL; 2682 } else { 2683 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER; 2684 } 2685 } 2686 } catch (PackageManager.NameNotFoundException e) { 2687 Slog.w(TAG, "Unable to retrieve gids", e); 2688 } 2689 2690 /* 2691 * Add shared application GID so applications can share some 2692 * resources like shared libraries 2693 */ 2694 if (permGids == null) { 2695 gids = new int[1]; 2696 } else { 2697 gids = new int[permGids.length + 1]; 2698 System.arraycopy(permGids, 0, gids, 1, permGids.length); 2699 } 2700 gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid)); 2701 } 2702 if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) { 2703 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL 2704 && mTopComponent != null 2705 && app.processName.equals(mTopComponent.getPackageName())) { 2706 uid = 0; 2707 } 2708 if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL 2709 && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) { 2710 uid = 0; 2711 } 2712 } 2713 int debugFlags = 0; 2714 if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) { 2715 debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER; 2716 // Also turn on CheckJNI for debuggable apps. It's quite 2717 // awkward to turn on otherwise. 2718 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 2719 } 2720 // Run the app in safe mode if its manifest requests so or the 2721 // system is booted in safe mode. 2722 if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 || 2723 Zygote.systemInSafeMode == true) { 2724 debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE; 2725 } 2726 if ("1".equals(SystemProperties.get("debug.checkjni"))) { 2727 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 2728 } 2729 if ("1".equals(SystemProperties.get("debug.jni.logging"))) { 2730 debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING; 2731 } 2732 if ("1".equals(SystemProperties.get("debug.assert"))) { 2733 debugFlags |= Zygote.DEBUG_ENABLE_ASSERT; 2734 } 2735 2736 // Start the process. It will either succeed and return a result containing 2737 // the PID of the new process, or else throw a RuntimeException. 2738 Process.ProcessStartResult startResult = Process.start("android.app.ActivityThread", 2739 app.processName, uid, uid, gids, debugFlags, mountExternal, 2740 app.info.targetSdkVersion, app.info.seinfo, null); 2741 2742 BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics(); 2743 synchronized (bs) { 2744 if (bs.isOnBattery()) { 2745 bs.getProcessStatsLocked(app.uid, app.processName).incStartsLocked(); 2746 } 2747 } 2748 2749 EventLog.writeEvent(EventLogTags.AM_PROC_START, 2750 UserHandle.getUserId(uid), startResult.pid, uid, 2751 app.processName, hostingType, 2752 hostingNameStr != null ? hostingNameStr : ""); 2753 2754 if (app.persistent) { 2755 Watchdog.getInstance().processStarted(app.processName, startResult.pid); 2756 } 2757 2758 StringBuilder buf = mStringBuilder; 2759 buf.setLength(0); 2760 buf.append("Start proc "); 2761 buf.append(app.processName); 2762 buf.append(" for "); 2763 buf.append(hostingType); 2764 if (hostingNameStr != null) { 2765 buf.append(" "); 2766 buf.append(hostingNameStr); 2767 } 2768 buf.append(": pid="); 2769 buf.append(startResult.pid); 2770 buf.append(" uid="); 2771 buf.append(uid); 2772 buf.append(" gids={"); 2773 if (gids != null) { 2774 for (int gi=0; gi<gids.length; gi++) { 2775 if (gi != 0) buf.append(", "); 2776 buf.append(gids[gi]); 2777 2778 } 2779 } 2780 buf.append("}"); 2781 Slog.i(TAG, buf.toString()); 2782 app.setPid(startResult.pid); 2783 app.usingWrapper = startResult.usingWrapper; 2784 app.removed = false; 2785 synchronized (mPidsSelfLocked) { 2786 this.mPidsSelfLocked.put(startResult.pid, app); 2787 Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 2788 msg.obj = app; 2789 mHandler.sendMessageDelayed(msg, startResult.usingWrapper 2790 ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT); 2791 } 2792 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_START, 2793 app.processName, app.info.uid); 2794 if (app.isolated) { 2795 mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid); 2796 } 2797 } catch (RuntimeException e) { 2798 // XXX do better error recovery. 2799 app.setPid(0); 2800 Slog.e(TAG, "Failure starting process " + app.processName, e); 2801 } 2802 } 2803 2804 void updateUsageStats(ActivityRecord component, boolean resumed) { 2805 if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed); 2806 final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 2807 if (resumed) { 2808 mUsageStatsService.noteResumeComponent(component.realActivity); 2809 synchronized (stats) { 2810 stats.noteActivityResumedLocked(component.app.uid); 2811 } 2812 } else { 2813 mUsageStatsService.notePauseComponent(component.realActivity); 2814 synchronized (stats) { 2815 stats.noteActivityPausedLocked(component.app.uid); 2816 } 2817 } 2818 } 2819 2820 Intent getHomeIntent() { 2821 Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null); 2822 intent.setComponent(mTopComponent); 2823 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 2824 intent.addCategory(Intent.CATEGORY_HOME); 2825 } 2826 return intent; 2827 } 2828 2829 boolean startHomeActivityLocked(int userId) { 2830 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL 2831 && mTopAction == null) { 2832 // We are running in factory test mode, but unable to find 2833 // the factory test app, so just sit around displaying the 2834 // error message and don't try to start anything. 2835 return false; 2836 } 2837 Intent intent = getHomeIntent(); 2838 ActivityInfo aInfo = 2839 resolveActivityInfo(intent, STOCK_PM_FLAGS, userId); 2840 if (aInfo != null) { 2841 intent.setComponent(new ComponentName( 2842 aInfo.applicationInfo.packageName, aInfo.name)); 2843 // Don't do this if the home app is currently being 2844 // instrumented. 2845 aInfo = new ActivityInfo(aInfo); 2846 aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId); 2847 ProcessRecord app = getProcessRecordLocked(aInfo.processName, 2848 aInfo.applicationInfo.uid, true); 2849 if (app == null || app.instrumentationClass == null) { 2850 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK); 2851 mStackSupervisor.startHomeActivity(intent, aInfo); 2852 } 2853 } 2854 2855 return true; 2856 } 2857 2858 private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) { 2859 ActivityInfo ai = null; 2860 ComponentName comp = intent.getComponent(); 2861 try { 2862 if (comp != null) { 2863 ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId); 2864 } else { 2865 ResolveInfo info = AppGlobals.getPackageManager().resolveIntent( 2866 intent, 2867 intent.resolveTypeIfNeeded(mContext.getContentResolver()), 2868 flags, userId); 2869 2870 if (info != null) { 2871 ai = info.activityInfo; 2872 } 2873 } 2874 } catch (RemoteException e) { 2875 // ignore 2876 } 2877 2878 return ai; 2879 } 2880 2881 /** 2882 * Starts the "new version setup screen" if appropriate. 2883 */ 2884 void startSetupActivityLocked() { 2885 // Only do this once per boot. 2886 if (mCheckedForSetup) { 2887 return; 2888 } 2889 2890 // We will show this screen if the current one is a different 2891 // version than the last one shown, and we are not running in 2892 // low-level factory test mode. 2893 final ContentResolver resolver = mContext.getContentResolver(); 2894 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL && 2895 Settings.Global.getInt(resolver, 2896 Settings.Global.DEVICE_PROVISIONED, 0) != 0) { 2897 mCheckedForSetup = true; 2898 2899 // See if we should be showing the platform update setup UI. 2900 Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP); 2901 List<ResolveInfo> ris = mContext.getPackageManager() 2902 .queryIntentActivities(intent, PackageManager.GET_META_DATA); 2903 2904 // We don't allow third party apps to replace this. 2905 ResolveInfo ri = null; 2906 for (int i=0; ris != null && i<ris.size(); i++) { 2907 if ((ris.get(i).activityInfo.applicationInfo.flags 2908 & ApplicationInfo.FLAG_SYSTEM) != 0) { 2909 ri = ris.get(i); 2910 break; 2911 } 2912 } 2913 2914 if (ri != null) { 2915 String vers = ri.activityInfo.metaData != null 2916 ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION) 2917 : null; 2918 if (vers == null && ri.activityInfo.applicationInfo.metaData != null) { 2919 vers = ri.activityInfo.applicationInfo.metaData.getString( 2920 Intent.METADATA_SETUP_VERSION); 2921 } 2922 String lastVers = Settings.Secure.getString( 2923 resolver, Settings.Secure.LAST_SETUP_SHOWN); 2924 if (vers != null && !vers.equals(lastVers)) { 2925 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 2926 intent.setComponent(new ComponentName( 2927 ri.activityInfo.packageName, ri.activityInfo.name)); 2928 mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo, 2929 null, null, 0, 0, 0, null, 0, null, false, null, null); 2930 } 2931 } 2932 } 2933 } 2934 2935 CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) { 2936 return mCompatModePackages.compatibilityInfoForPackageLocked(ai); 2937 } 2938 2939 void enforceNotIsolatedCaller(String caller) { 2940 if (UserHandle.isIsolated(Binder.getCallingUid())) { 2941 throw new SecurityException("Isolated process not allowed to call " + caller); 2942 } 2943 } 2944 2945 @Override 2946 public int getFrontActivityScreenCompatMode() { 2947 enforceNotIsolatedCaller("getFrontActivityScreenCompatMode"); 2948 synchronized (this) { 2949 return mCompatModePackages.getFrontActivityScreenCompatModeLocked(); 2950 } 2951 } 2952 2953 @Override 2954 public void setFrontActivityScreenCompatMode(int mode) { 2955 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 2956 "setFrontActivityScreenCompatMode"); 2957 synchronized (this) { 2958 mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode); 2959 } 2960 } 2961 2962 @Override 2963 public int getPackageScreenCompatMode(String packageName) { 2964 enforceNotIsolatedCaller("getPackageScreenCompatMode"); 2965 synchronized (this) { 2966 return mCompatModePackages.getPackageScreenCompatModeLocked(packageName); 2967 } 2968 } 2969 2970 @Override 2971 public void setPackageScreenCompatMode(String packageName, int mode) { 2972 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 2973 "setPackageScreenCompatMode"); 2974 synchronized (this) { 2975 mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode); 2976 } 2977 } 2978 2979 @Override 2980 public boolean getPackageAskScreenCompat(String packageName) { 2981 enforceNotIsolatedCaller("getPackageAskScreenCompat"); 2982 synchronized (this) { 2983 return mCompatModePackages.getPackageAskCompatModeLocked(packageName); 2984 } 2985 } 2986 2987 @Override 2988 public void setPackageAskScreenCompat(String packageName, boolean ask) { 2989 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 2990 "setPackageAskScreenCompat"); 2991 synchronized (this) { 2992 mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask); 2993 } 2994 } 2995 2996 private void dispatchProcessesChanged() { 2997 int N; 2998 synchronized (this) { 2999 N = mPendingProcessChanges.size(); 3000 if (mActiveProcessChanges.length < N) { 3001 mActiveProcessChanges = new ProcessChangeItem[N]; 3002 } 3003 mPendingProcessChanges.toArray(mActiveProcessChanges); 3004 mAvailProcessChanges.addAll(mPendingProcessChanges); 3005 mPendingProcessChanges.clear(); 3006 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes"); 3007 } 3008 3009 int i = mProcessObservers.beginBroadcast(); 3010 while (i > 0) { 3011 i--; 3012 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 3013 if (observer != null) { 3014 try { 3015 for (int j=0; j<N; j++) { 3016 ProcessChangeItem item = mActiveProcessChanges[j]; 3017 if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) { 3018 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid=" 3019 + item.pid + " uid=" + item.uid + ": " 3020 + item.foregroundActivities); 3021 observer.onForegroundActivitiesChanged(item.pid, item.uid, 3022 item.foregroundActivities); 3023 } 3024 if ((item.changes&ProcessChangeItem.CHANGE_IMPORTANCE) != 0) { 3025 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "IMPORTANCE CHANGED pid=" 3026 + item.pid + " uid=" + item.uid + ": " + item.importance); 3027 observer.onImportanceChanged(item.pid, item.uid, 3028 item.importance); 3029 } 3030 } 3031 } catch (RemoteException e) { 3032 } 3033 } 3034 } 3035 mProcessObservers.finishBroadcast(); 3036 } 3037 3038 private void dispatchProcessDied(int pid, int uid) { 3039 int i = mProcessObservers.beginBroadcast(); 3040 while (i > 0) { 3041 i--; 3042 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 3043 if (observer != null) { 3044 try { 3045 observer.onProcessDied(pid, uid); 3046 } catch (RemoteException e) { 3047 } 3048 } 3049 } 3050 mProcessObservers.finishBroadcast(); 3051 } 3052 3053 final void doPendingActivityLaunchesLocked(boolean doResume) { 3054 final int N = mPendingActivityLaunches.size(); 3055 if (N <= 0) { 3056 return; 3057 } 3058 for (int i=0; i<N; i++) { 3059 PendingActivityLaunch pal = mPendingActivityLaunches.get(i); 3060 mStackSupervisor.startActivityUncheckedLocked(pal.r, pal.sourceRecord, pal.startFlags, 3061 doResume && i == (N-1), null); 3062 } 3063 mPendingActivityLaunches.clear(); 3064 } 3065 3066 @Override 3067 public final int startActivity(IApplicationThread caller, String callingPackage, 3068 Intent intent, String resolvedType, IBinder resultTo, 3069 String resultWho, int requestCode, int startFlags, 3070 String profileFile, ParcelFileDescriptor profileFd, Bundle options) { 3071 return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo, 3072 resultWho, requestCode, 3073 startFlags, profileFile, profileFd, options, UserHandle.getCallingUserId()); 3074 } 3075 3076 @Override 3077 public final int startActivityAsUser(IApplicationThread caller, String callingPackage, 3078 Intent intent, String resolvedType, IBinder resultTo, 3079 String resultWho, int requestCode, int startFlags, 3080 String profileFile, ParcelFileDescriptor profileFd, Bundle options, int userId) { 3081 enforceNotIsolatedCaller("startActivity"); 3082 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3083 false, true, "startActivity", null); 3084 // TODO: Switch to user app stacks here. 3085 return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType, 3086 resultTo, resultWho, requestCode, startFlags, profileFile, profileFd, 3087 null, null, options, userId, null); 3088 } 3089 3090 @Override 3091 public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage, 3092 Intent intent, String resolvedType, IBinder resultTo, 3093 String resultWho, int requestCode, int startFlags, String profileFile, 3094 ParcelFileDescriptor profileFd, Bundle options, int userId) { 3095 enforceNotIsolatedCaller("startActivityAndWait"); 3096 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3097 false, true, "startActivityAndWait", null); 3098 WaitResult res = new WaitResult(); 3099 // TODO: Switch to user app stacks here. 3100 mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType, 3101 resultTo, resultWho, requestCode, startFlags, profileFile, profileFd, 3102 res, null, options, UserHandle.getCallingUserId(), null); 3103 return res; 3104 } 3105 3106 @Override 3107 public final int startActivityWithConfig(IApplicationThread caller, String callingPackage, 3108 Intent intent, String resolvedType, IBinder resultTo, 3109 String resultWho, int requestCode, int startFlags, Configuration config, 3110 Bundle options, int userId) { 3111 enforceNotIsolatedCaller("startActivityWithConfig"); 3112 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3113 false, true, "startActivityWithConfig", null); 3114 // TODO: Switch to user app stacks here. 3115 int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, 3116 resolvedType, resultTo, resultWho, requestCode, startFlags, 3117 null, null, null, config, options, userId, null); 3118 return ret; 3119 } 3120 3121 @Override 3122 public int startActivityIntentSender(IApplicationThread caller, 3123 IntentSender intent, Intent fillInIntent, String resolvedType, 3124 IBinder resultTo, String resultWho, int requestCode, 3125 int flagsMask, int flagsValues, Bundle options) { 3126 enforceNotIsolatedCaller("startActivityIntentSender"); 3127 // Refuse possible leaked file descriptors 3128 if (fillInIntent != null && fillInIntent.hasFileDescriptors()) { 3129 throw new IllegalArgumentException("File descriptors passed in Intent"); 3130 } 3131 3132 IIntentSender sender = intent.getTarget(); 3133 if (!(sender instanceof PendingIntentRecord)) { 3134 throw new IllegalArgumentException("Bad PendingIntent object"); 3135 } 3136 3137 PendingIntentRecord pir = (PendingIntentRecord)sender; 3138 3139 synchronized (this) { 3140 // If this is coming from the currently resumed activity, it is 3141 // effectively saying that app switches are allowed at this point. 3142 final ActivityStack stack = getFocusedStack(); 3143 if (stack.mResumedActivity != null && 3144 stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) { 3145 mAppSwitchesAllowedTime = 0; 3146 } 3147 } 3148 int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null, 3149 resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null); 3150 return ret; 3151 } 3152 3153 @Override 3154 public boolean startNextMatchingActivity(IBinder callingActivity, 3155 Intent intent, Bundle options) { 3156 // Refuse possible leaked file descriptors 3157 if (intent != null && intent.hasFileDescriptors() == true) { 3158 throw new IllegalArgumentException("File descriptors passed in Intent"); 3159 } 3160 3161 synchronized (this) { 3162 final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity); 3163 if (r == null) { 3164 ActivityOptions.abort(options); 3165 return false; 3166 } 3167 if (r.app == null || r.app.thread == null) { 3168 // The caller is not running... d'oh! 3169 ActivityOptions.abort(options); 3170 return false; 3171 } 3172 intent = new Intent(intent); 3173 // The caller is not allowed to change the data. 3174 intent.setDataAndType(r.intent.getData(), r.intent.getType()); 3175 // And we are resetting to find the next component... 3176 intent.setComponent(null); 3177 3178 final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0); 3179 3180 ActivityInfo aInfo = null; 3181 try { 3182 List<ResolveInfo> resolves = 3183 AppGlobals.getPackageManager().queryIntentActivities( 3184 intent, r.resolvedType, 3185 PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS, 3186 UserHandle.getCallingUserId()); 3187 3188 // Look for the original activity in the list... 3189 final int N = resolves != null ? resolves.size() : 0; 3190 for (int i=0; i<N; i++) { 3191 ResolveInfo rInfo = resolves.get(i); 3192 if (rInfo.activityInfo.packageName.equals(r.packageName) 3193 && rInfo.activityInfo.name.equals(r.info.name)) { 3194 // We found the current one... the next matching is 3195 // after it. 3196 i++; 3197 if (i<N) { 3198 aInfo = resolves.get(i).activityInfo; 3199 } 3200 if (debug) { 3201 Slog.v(TAG, "Next matching activity: found current " + r.packageName 3202 + "/" + r.info.name); 3203 Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName 3204 + "/" + aInfo.name); 3205 } 3206 break; 3207 } 3208 } 3209 } catch (RemoteException e) { 3210 } 3211 3212 if (aInfo == null) { 3213 // Nobody who is next! 3214 ActivityOptions.abort(options); 3215 if (debug) Slog.d(TAG, "Next matching activity: nothing found"); 3216 return false; 3217 } 3218 3219 intent.setComponent(new ComponentName( 3220 aInfo.applicationInfo.packageName, aInfo.name)); 3221 intent.setFlags(intent.getFlags()&~( 3222 Intent.FLAG_ACTIVITY_FORWARD_RESULT| 3223 Intent.FLAG_ACTIVITY_CLEAR_TOP| 3224 Intent.FLAG_ACTIVITY_MULTIPLE_TASK| 3225 Intent.FLAG_ACTIVITY_NEW_TASK)); 3226 3227 // Okay now we need to start the new activity, replacing the 3228 // currently running activity. This is a little tricky because 3229 // we want to start the new one as if the current one is finished, 3230 // but not finish the current one first so that there is no flicker. 3231 // And thus... 3232 final boolean wasFinishing = r.finishing; 3233 r.finishing = true; 3234 3235 // Propagate reply information over to the new activity. 3236 final ActivityRecord resultTo = r.resultTo; 3237 final String resultWho = r.resultWho; 3238 final int requestCode = r.requestCode; 3239 r.resultTo = null; 3240 if (resultTo != null) { 3241 resultTo.removeResultsLocked(r, resultWho, requestCode); 3242 } 3243 3244 final long origId = Binder.clearCallingIdentity(); 3245 int res = mStackSupervisor.startActivityLocked(r.app.thread, intent, 3246 r.resolvedType, aInfo, resultTo != null ? resultTo.appToken : null, 3247 resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage, 0, 3248 options, false, null, null); 3249 Binder.restoreCallingIdentity(origId); 3250 3251 r.finishing = wasFinishing; 3252 if (res != ActivityManager.START_SUCCESS) { 3253 return false; 3254 } 3255 return true; 3256 } 3257 } 3258 3259 final int startActivityInPackage(int uid, String callingPackage, 3260 Intent intent, String resolvedType, IBinder resultTo, 3261 String resultWho, int requestCode, int startFlags, Bundle options, int userId, 3262 IActivityContainer container) { 3263 3264 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3265 false, true, "startActivityInPackage", null); 3266 3267 // TODO: Switch to user app stacks here. 3268 int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent, resolvedType, 3269 resultTo, resultWho, requestCode, startFlags, 3270 null, null, null, null, options, userId, container); 3271 return ret; 3272 } 3273 3274 @Override 3275 public final int startActivities(IApplicationThread caller, String callingPackage, 3276 Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options, 3277 int userId) { 3278 enforceNotIsolatedCaller("startActivities"); 3279 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3280 false, true, "startActivity", null); 3281 // TODO: Switch to user app stacks here. 3282 int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents, 3283 resolvedTypes, resultTo, options, userId); 3284 return ret; 3285 } 3286 3287 final int startActivitiesInPackage(int uid, String callingPackage, 3288 Intent[] intents, String[] resolvedTypes, IBinder resultTo, 3289 Bundle options, int userId) { 3290 3291 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3292 false, true, "startActivityInPackage", null); 3293 // TODO: Switch to user app stacks here. 3294 int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes, 3295 resultTo, options, userId); 3296 return ret; 3297 } 3298 3299 final void addRecentTaskLocked(TaskRecord task) { 3300 int N = mRecentTasks.size(); 3301 // Quick case: check if the top-most recent task is the same. 3302 if (N > 0 && mRecentTasks.get(0) == task) { 3303 return; 3304 } 3305 // Remove any existing entries that are the same kind of task. 3306 for (int i=0; i<N; i++) { 3307 TaskRecord tr = mRecentTasks.get(i); 3308 if (task.userId == tr.userId 3309 && ((task.affinity != null && task.affinity.equals(tr.affinity)) 3310 || (task.intent != null && task.intent.filterEquals(tr.intent)))) { 3311 tr.disposeThumbnail(); 3312 mRecentTasks.remove(i); 3313 i--; 3314 N--; 3315 if (task.intent == null) { 3316 // If the new recent task we are adding is not fully 3317 // specified, then replace it with the existing recent task. 3318 task = tr; 3319 } 3320 } 3321 } 3322 if (N >= MAX_RECENT_TASKS) { 3323 mRecentTasks.remove(N-1).disposeThumbnail(); 3324 } 3325 mRecentTasks.add(0, task); 3326 } 3327 3328 @Override 3329 public void reportActivityFullyDrawn(IBinder token) { 3330 synchronized (this) { 3331 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3332 if (r == null) { 3333 return; 3334 } 3335 r.reportFullyDrawnLocked(); 3336 } 3337 } 3338 3339 @Override 3340 public void setRequestedOrientation(IBinder token, int requestedOrientation) { 3341 synchronized (this) { 3342 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3343 if (r == null) { 3344 return; 3345 } 3346 final long origId = Binder.clearCallingIdentity(); 3347 mWindowManager.setAppOrientation(r.appToken, requestedOrientation); 3348 Configuration config = mWindowManager.updateOrientationFromAppTokens( 3349 mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null); 3350 if (config != null) { 3351 r.frozenBeforeDestroy = true; 3352 if (!updateConfigurationLocked(config, r, false, false)) { 3353 mStackSupervisor.resumeTopActivitiesLocked(); 3354 } 3355 } 3356 Binder.restoreCallingIdentity(origId); 3357 } 3358 } 3359 3360 @Override 3361 public int getRequestedOrientation(IBinder token) { 3362 synchronized (this) { 3363 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3364 if (r == null) { 3365 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; 3366 } 3367 return mWindowManager.getAppOrientation(r.appToken); 3368 } 3369 } 3370 3371 /** 3372 * This is the internal entry point for handling Activity.finish(). 3373 * 3374 * @param token The Binder token referencing the Activity we want to finish. 3375 * @param resultCode Result code, if any, from this Activity. 3376 * @param resultData Result data (Intent), if any, from this Activity. 3377 * 3378 * @return Returns true if the activity successfully finished, or false if it is still running. 3379 */ 3380 @Override 3381 public final boolean finishActivity(IBinder token, int resultCode, Intent resultData) { 3382 // Refuse possible leaked file descriptors 3383 if (resultData != null && resultData.hasFileDescriptors() == true) { 3384 throw new IllegalArgumentException("File descriptors passed in Intent"); 3385 } 3386 3387 synchronized(this) { 3388 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3389 if (r == null) { 3390 return true; 3391 } 3392 if (mController != null) { 3393 // Find the first activity that is not finishing. 3394 ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0); 3395 if (next != null) { 3396 // ask watcher if this is allowed 3397 boolean resumeOK = true; 3398 try { 3399 resumeOK = mController.activityResuming(next.packageName); 3400 } catch (RemoteException e) { 3401 mController = null; 3402 Watchdog.getInstance().setActivityController(null); 3403 } 3404 3405 if (!resumeOK) { 3406 return false; 3407 } 3408 } 3409 } 3410 final long origId = Binder.clearCallingIdentity(); 3411 boolean res = r.task.stack.requestFinishActivityLocked(token, resultCode, 3412 resultData, "app-request", true); 3413 Binder.restoreCallingIdentity(origId); 3414 return res; 3415 } 3416 } 3417 3418 @Override 3419 public final void finishHeavyWeightApp() { 3420 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 3421 != PackageManager.PERMISSION_GRANTED) { 3422 String msg = "Permission Denial: finishHeavyWeightApp() from pid=" 3423 + Binder.getCallingPid() 3424 + ", uid=" + Binder.getCallingUid() 3425 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 3426 Slog.w(TAG, msg); 3427 throw new SecurityException(msg); 3428 } 3429 3430 synchronized(this) { 3431 if (mHeavyWeightProcess == null) { 3432 return; 3433 } 3434 3435 ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>( 3436 mHeavyWeightProcess.activities); 3437 for (int i=0; i<activities.size(); i++) { 3438 ActivityRecord r = activities.get(i); 3439 if (!r.finishing) { 3440 r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED, 3441 null, "finish-heavy", true); 3442 } 3443 } 3444 3445 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 3446 mHeavyWeightProcess.userId, 0)); 3447 mHeavyWeightProcess = null; 3448 } 3449 } 3450 3451 @Override 3452 public void crashApplication(int uid, int initialPid, String packageName, 3453 String message) { 3454 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 3455 != PackageManager.PERMISSION_GRANTED) { 3456 String msg = "Permission Denial: crashApplication() from pid=" 3457 + Binder.getCallingPid() 3458 + ", uid=" + Binder.getCallingUid() 3459 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 3460 Slog.w(TAG, msg); 3461 throw new SecurityException(msg); 3462 } 3463 3464 synchronized(this) { 3465 ProcessRecord proc = null; 3466 3467 // Figure out which process to kill. We don't trust that initialPid 3468 // still has any relation to current pids, so must scan through the 3469 // list. 3470 synchronized (mPidsSelfLocked) { 3471 for (int i=0; i<mPidsSelfLocked.size(); i++) { 3472 ProcessRecord p = mPidsSelfLocked.valueAt(i); 3473 if (p.uid != uid) { 3474 continue; 3475 } 3476 if (p.pid == initialPid) { 3477 proc = p; 3478 break; 3479 } 3480 if (p.pkgList.containsKey(packageName)) { 3481 proc = p; 3482 } 3483 } 3484 } 3485 3486 if (proc == null) { 3487 Slog.w(TAG, "crashApplication: nothing for uid=" + uid 3488 + " initialPid=" + initialPid 3489 + " packageName=" + packageName); 3490 return; 3491 } 3492 3493 if (proc.thread != null) { 3494 if (proc.pid == Process.myPid()) { 3495 Log.w(TAG, "crashApplication: trying to crash self!"); 3496 return; 3497 } 3498 long ident = Binder.clearCallingIdentity(); 3499 try { 3500 proc.thread.scheduleCrash(message); 3501 } catch (RemoteException e) { 3502 } 3503 Binder.restoreCallingIdentity(ident); 3504 } 3505 } 3506 } 3507 3508 @Override 3509 public final void finishSubActivity(IBinder token, String resultWho, 3510 int requestCode) { 3511 synchronized(this) { 3512 final long origId = Binder.clearCallingIdentity(); 3513 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3514 if (r != null) { 3515 r.task.stack.finishSubActivityLocked(r, resultWho, requestCode); 3516 } 3517 Binder.restoreCallingIdentity(origId); 3518 } 3519 } 3520 3521 @Override 3522 public boolean finishActivityAffinity(IBinder token) { 3523 synchronized(this) { 3524 final long origId = Binder.clearCallingIdentity(); 3525 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3526 boolean res = false; 3527 if (r != null) { 3528 res = r.task.stack.finishActivityAffinityLocked(r); 3529 } 3530 Binder.restoreCallingIdentity(origId); 3531 return res; 3532 } 3533 } 3534 3535 @Override 3536 public boolean willActivityBeVisible(IBinder token) { 3537 synchronized(this) { 3538 ActivityStack stack = ActivityRecord.getStackLocked(token); 3539 if (stack != null) { 3540 return stack.willActivityBeVisibleLocked(token); 3541 } 3542 return false; 3543 } 3544 } 3545 3546 @Override 3547 public void overridePendingTransition(IBinder token, String packageName, 3548 int enterAnim, int exitAnim) { 3549 synchronized(this) { 3550 ActivityRecord self = ActivityRecord.isInStackLocked(token); 3551 if (self == null) { 3552 return; 3553 } 3554 3555 final long origId = Binder.clearCallingIdentity(); 3556 3557 if (self.state == ActivityState.RESUMED 3558 || self.state == ActivityState.PAUSING) { 3559 mWindowManager.overridePendingAppTransition(packageName, 3560 enterAnim, exitAnim, null); 3561 } 3562 3563 Binder.restoreCallingIdentity(origId); 3564 } 3565 } 3566 3567 /** 3568 * Main function for removing an existing process from the activity manager 3569 * as a result of that process going away. Clears out all connections 3570 * to the process. 3571 */ 3572 private final void handleAppDiedLocked(ProcessRecord app, 3573 boolean restarting, boolean allowRestart) { 3574 int pid = app.pid; 3575 cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1); 3576 if (!restarting) { 3577 removeLruProcessLocked(app); 3578 if (pid > 0) { 3579 ProcessList.remove(pid); 3580 } 3581 } 3582 3583 if (mProfileProc == app) { 3584 clearProfilerLocked(); 3585 } 3586 3587 // Remove this application's activities from active lists. 3588 boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app); 3589 3590 app.activities.clear(); 3591 3592 if (app.instrumentationClass != null) { 3593 Slog.w(TAG, "Crash of app " + app.processName 3594 + " running instrumentation " + app.instrumentationClass); 3595 Bundle info = new Bundle(); 3596 info.putString("shortMsg", "Process crashed."); 3597 finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info); 3598 } 3599 3600 if (!restarting) { 3601 if (!mStackSupervisor.resumeTopActivitiesLocked()) { 3602 // If there was nothing to resume, and we are not already 3603 // restarting this process, but there is a visible activity that 3604 // is hosted by the process... then make sure all visible 3605 // activities are running, taking care of restarting this 3606 // process. 3607 if (hasVisibleActivities) { 3608 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 3609 } 3610 } 3611 } 3612 } 3613 3614 private final int getLRURecordIndexForAppLocked(IApplicationThread thread) { 3615 IBinder threadBinder = thread.asBinder(); 3616 // Find the application record. 3617 for (int i=mLruProcesses.size()-1; i>=0; i--) { 3618 ProcessRecord rec = mLruProcesses.get(i); 3619 if (rec.thread != null && rec.thread.asBinder() == threadBinder) { 3620 return i; 3621 } 3622 } 3623 return -1; 3624 } 3625 3626 final ProcessRecord getRecordForAppLocked( 3627 IApplicationThread thread) { 3628 if (thread == null) { 3629 return null; 3630 } 3631 3632 int appIndex = getLRURecordIndexForAppLocked(thread); 3633 return appIndex >= 0 ? mLruProcesses.get(appIndex) : null; 3634 } 3635 3636 final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) { 3637 // If there are no longer any background processes running, 3638 // and the app that died was not running instrumentation, 3639 // then tell everyone we are now low on memory. 3640 boolean haveBg = false; 3641 for (int i=mLruProcesses.size()-1; i>=0; i--) { 3642 ProcessRecord rec = mLruProcesses.get(i); 3643 if (rec.thread != null 3644 && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 3645 haveBg = true; 3646 break; 3647 } 3648 } 3649 3650 if (!haveBg) { 3651 boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 3652 if (doReport) { 3653 long now = SystemClock.uptimeMillis(); 3654 if (now < (mLastMemUsageReportTime+5*60*1000)) { 3655 doReport = false; 3656 } else { 3657 mLastMemUsageReportTime = now; 3658 } 3659 } 3660 final ArrayList<ProcessMemInfo> memInfos 3661 = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null; 3662 EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size()); 3663 long now = SystemClock.uptimeMillis(); 3664 for (int i=mLruProcesses.size()-1; i>=0; i--) { 3665 ProcessRecord rec = mLruProcesses.get(i); 3666 if (rec == dyingProc || rec.thread == null) { 3667 continue; 3668 } 3669 if (doReport) { 3670 memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj, 3671 rec.setProcState, rec.adjType, rec.makeAdjReason())); 3672 } 3673 if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) { 3674 // The low memory report is overriding any current 3675 // state for a GC request. Make sure to do 3676 // heavy/important/visible/foreground processes first. 3677 if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 3678 rec.lastRequestedGc = 0; 3679 } else { 3680 rec.lastRequestedGc = rec.lastLowMemory; 3681 } 3682 rec.reportLowMemory = true; 3683 rec.lastLowMemory = now; 3684 mProcessesToGc.remove(rec); 3685 addProcessToGcListLocked(rec); 3686 } 3687 } 3688 if (doReport) { 3689 Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos); 3690 mHandler.sendMessage(msg); 3691 } 3692 scheduleAppGcsLocked(); 3693 } 3694 } 3695 3696 final void appDiedLocked(ProcessRecord app, int pid, 3697 IApplicationThread thread) { 3698 3699 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 3700 synchronized (stats) { 3701 stats.noteProcessDiedLocked(app.info.uid, pid); 3702 } 3703 3704 // Clean up already done if the process has been re-started. 3705 if (app.pid == pid && app.thread != null && 3706 app.thread.asBinder() == thread.asBinder()) { 3707 boolean doLowMem = app.instrumentationClass == null; 3708 boolean doOomAdj = doLowMem; 3709 if (!app.killedByAm) { 3710 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 3711 + ") has died."); 3712 mAllowLowerMemLevel = true; 3713 } else { 3714 // Note that we always want to do oom adj to update our state with the 3715 // new number of procs. 3716 mAllowLowerMemLevel = false; 3717 doLowMem = false; 3718 } 3719 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName); 3720 if (DEBUG_CLEANUP) Slog.v( 3721 TAG, "Dying app: " + app + ", pid: " + pid 3722 + ", thread: " + thread.asBinder()); 3723 handleAppDiedLocked(app, false, true); 3724 3725 if (doOomAdj) { 3726 updateOomAdjLocked(); 3727 } 3728 if (doLowMem) { 3729 doLowMemReportIfNeededLocked(app); 3730 } 3731 } else if (app.pid != pid) { 3732 // A new process has already been started. 3733 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 3734 + ") has died and restarted (pid " + app.pid + ")."); 3735 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName); 3736 } else if (DEBUG_PROCESSES) { 3737 Slog.d(TAG, "Received spurious death notification for thread " 3738 + thread.asBinder()); 3739 } 3740 } 3741 3742 /** 3743 * If a stack trace dump file is configured, dump process stack traces. 3744 * @param clearTraces causes the dump file to be erased prior to the new 3745 * traces being written, if true; when false, the new traces will be 3746 * appended to any existing file content. 3747 * @param firstPids of dalvik VM processes to dump stack traces for first 3748 * @param lastPids of dalvik VM processes to dump stack traces for last 3749 * @param nativeProcs optional list of native process names to dump stack crawls 3750 * @return file containing stack traces, or null if no dump file is configured 3751 */ 3752 public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids, 3753 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) { 3754 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 3755 if (tracesPath == null || tracesPath.length() == 0) { 3756 return null; 3757 } 3758 3759 File tracesFile = new File(tracesPath); 3760 try { 3761 File tracesDir = tracesFile.getParentFile(); 3762 if (!tracesDir.exists()) { 3763 tracesFile.mkdirs(); 3764 if (!SELinux.restorecon(tracesDir)) { 3765 return null; 3766 } 3767 } 3768 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 3769 3770 if (clearTraces && tracesFile.exists()) tracesFile.delete(); 3771 tracesFile.createNewFile(); 3772 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 3773 } catch (IOException e) { 3774 Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e); 3775 return null; 3776 } 3777 3778 dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs); 3779 return tracesFile; 3780 } 3781 3782 private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids, 3783 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) { 3784 // Use a FileObserver to detect when traces finish writing. 3785 // The order of traces is considered important to maintain for legibility. 3786 FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) { 3787 @Override 3788 public synchronized void onEvent(int event, String path) { notify(); } 3789 }; 3790 3791 try { 3792 observer.startWatching(); 3793 3794 // First collect all of the stacks of the most important pids. 3795 if (firstPids != null) { 3796 try { 3797 int num = firstPids.size(); 3798 for (int i = 0; i < num; i++) { 3799 synchronized (observer) { 3800 Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT); 3801 observer.wait(200); // Wait for write-close, give up after 200msec 3802 } 3803 } 3804 } catch (InterruptedException e) { 3805 Log.wtf(TAG, e); 3806 } 3807 } 3808 3809 // Next collect the stacks of the native pids 3810 if (nativeProcs != null) { 3811 int[] pids = Process.getPidsForCommands(nativeProcs); 3812 if (pids != null) { 3813 for (int pid : pids) { 3814 Debug.dumpNativeBacktraceToFile(pid, tracesPath); 3815 } 3816 } 3817 } 3818 3819 // Lastly, measure CPU usage. 3820 if (processCpuTracker != null) { 3821 processCpuTracker.init(); 3822 System.gc(); 3823 processCpuTracker.update(); 3824 try { 3825 synchronized (processCpuTracker) { 3826 processCpuTracker.wait(500); // measure over 1/2 second. 3827 } 3828 } catch (InterruptedException e) { 3829 } 3830 processCpuTracker.update(); 3831 3832 // We'll take the stack crawls of just the top apps using CPU. 3833 final int N = processCpuTracker.countWorkingStats(); 3834 int numProcs = 0; 3835 for (int i=0; i<N && numProcs<5; i++) { 3836 ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i); 3837 if (lastPids.indexOfKey(stats.pid) >= 0) { 3838 numProcs++; 3839 try { 3840 synchronized (observer) { 3841 Process.sendSignal(stats.pid, Process.SIGNAL_QUIT); 3842 observer.wait(200); // Wait for write-close, give up after 200msec 3843 } 3844 } catch (InterruptedException e) { 3845 Log.wtf(TAG, e); 3846 } 3847 3848 } 3849 } 3850 } 3851 } finally { 3852 observer.stopWatching(); 3853 } 3854 } 3855 3856 final void logAppTooSlow(ProcessRecord app, long startTime, String msg) { 3857 if (true || IS_USER_BUILD) { 3858 return; 3859 } 3860 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 3861 if (tracesPath == null || tracesPath.length() == 0) { 3862 return; 3863 } 3864 3865 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads(); 3866 StrictMode.allowThreadDiskWrites(); 3867 try { 3868 final File tracesFile = new File(tracesPath); 3869 final File tracesDir = tracesFile.getParentFile(); 3870 final File tracesTmp = new File(tracesDir, "__tmp__"); 3871 try { 3872 if (!tracesDir.exists()) { 3873 tracesFile.mkdirs(); 3874 if (!SELinux.restorecon(tracesDir.getPath())) { 3875 return; 3876 } 3877 } 3878 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 3879 3880 if (tracesFile.exists()) { 3881 tracesTmp.delete(); 3882 tracesFile.renameTo(tracesTmp); 3883 } 3884 StringBuilder sb = new StringBuilder(); 3885 Time tobj = new Time(); 3886 tobj.set(System.currentTimeMillis()); 3887 sb.append(tobj.format("%Y-%m-%d %H:%M:%S")); 3888 sb.append(": "); 3889 TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb); 3890 sb.append(" since "); 3891 sb.append(msg); 3892 FileOutputStream fos = new FileOutputStream(tracesFile); 3893 fos.write(sb.toString().getBytes()); 3894 if (app == null) { 3895 fos.write("\n*** No application process!".getBytes()); 3896 } 3897 fos.close(); 3898 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 3899 } catch (IOException e) { 3900 Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e); 3901 return; 3902 } 3903 3904 if (app != null) { 3905 ArrayList<Integer> firstPids = new ArrayList<Integer>(); 3906 firstPids.add(app.pid); 3907 dumpStackTraces(tracesPath, firstPids, null, null, null); 3908 } 3909 3910 File lastTracesFile = null; 3911 File curTracesFile = null; 3912 for (int i=9; i>=0; i--) { 3913 String name = String.format(Locale.US, "slow%02d.txt", i); 3914 curTracesFile = new File(tracesDir, name); 3915 if (curTracesFile.exists()) { 3916 if (lastTracesFile != null) { 3917 curTracesFile.renameTo(lastTracesFile); 3918 } else { 3919 curTracesFile.delete(); 3920 } 3921 } 3922 lastTracesFile = curTracesFile; 3923 } 3924 tracesFile.renameTo(curTracesFile); 3925 if (tracesTmp.exists()) { 3926 tracesTmp.renameTo(tracesFile); 3927 } 3928 } finally { 3929 StrictMode.setThreadPolicy(oldPolicy); 3930 } 3931 } 3932 3933 final void appNotResponding(ProcessRecord app, ActivityRecord activity, 3934 ActivityRecord parent, boolean aboveSystem, final String annotation) { 3935 ArrayList<Integer> firstPids = new ArrayList<Integer>(5); 3936 SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20); 3937 3938 if (mController != null) { 3939 try { 3940 // 0 == continue, -1 = kill process immediately 3941 int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation); 3942 if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid); 3943 } catch (RemoteException e) { 3944 mController = null; 3945 Watchdog.getInstance().setActivityController(null); 3946 } 3947 } 3948 3949 long anrTime = SystemClock.uptimeMillis(); 3950 if (MONITOR_CPU_USAGE) { 3951 updateCpuStatsNow(); 3952 } 3953 3954 synchronized (this) { 3955 // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down. 3956 if (mShuttingDown) { 3957 Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation); 3958 return; 3959 } else if (app.notResponding) { 3960 Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation); 3961 return; 3962 } else if (app.crashing) { 3963 Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation); 3964 return; 3965 } 3966 3967 // In case we come through here for the same app before completing 3968 // this one, mark as anring now so we will bail out. 3969 app.notResponding = true; 3970 3971 // Log the ANR to the event log. 3972 EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid, 3973 app.processName, app.info.flags, annotation); 3974 3975 // Dump thread traces as quickly as we can, starting with "interesting" processes. 3976 firstPids.add(app.pid); 3977 3978 int parentPid = app.pid; 3979 if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid; 3980 if (parentPid != app.pid) firstPids.add(parentPid); 3981 3982 if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID); 3983 3984 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 3985 ProcessRecord r = mLruProcesses.get(i); 3986 if (r != null && r.thread != null) { 3987 int pid = r.pid; 3988 if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) { 3989 if (r.persistent) { 3990 firstPids.add(pid); 3991 } else { 3992 lastPids.put(pid, Boolean.TRUE); 3993 } 3994 } 3995 } 3996 } 3997 } 3998 3999 // Log the ANR to the main log. 4000 StringBuilder info = new StringBuilder(); 4001 info.setLength(0); 4002 info.append("ANR in ").append(app.processName); 4003 if (activity != null && activity.shortComponentName != null) { 4004 info.append(" (").append(activity.shortComponentName).append(")"); 4005 } 4006 info.append("\n"); 4007 info.append("PID: ").append(app.pid).append("\n"); 4008 if (annotation != null) { 4009 info.append("Reason: ").append(annotation).append("\n"); 4010 } 4011 if (parent != null && parent != activity) { 4012 info.append("Parent: ").append(parent.shortComponentName).append("\n"); 4013 } 4014 4015 final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true); 4016 4017 File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids, 4018 NATIVE_STACKS_OF_INTEREST); 4019 4020 String cpuInfo = null; 4021 if (MONITOR_CPU_USAGE) { 4022 updateCpuStatsNow(); 4023 synchronized (mProcessCpuThread) { 4024 cpuInfo = mProcessCpuTracker.printCurrentState(anrTime); 4025 } 4026 info.append(processCpuTracker.printCurrentLoad()); 4027 info.append(cpuInfo); 4028 } 4029 4030 info.append(processCpuTracker.printCurrentState(anrTime)); 4031 4032 Slog.e(TAG, info.toString()); 4033 if (tracesFile == null) { 4034 // There is no trace file, so dump (only) the alleged culprit's threads to the log 4035 Process.sendSignal(app.pid, Process.SIGNAL_QUIT); 4036 } 4037 4038 addErrorToDropBox("anr", app, app.processName, activity, parent, annotation, 4039 cpuInfo, tracesFile, null); 4040 4041 if (mController != null) { 4042 try { 4043 // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately 4044 int res = mController.appNotResponding(app.processName, app.pid, info.toString()); 4045 if (res != 0) { 4046 if (res < 0 && app.pid != MY_PID) { 4047 Process.killProcess(app.pid); 4048 } else { 4049 synchronized (this) { 4050 mServices.scheduleServiceTimeoutLocked(app); 4051 } 4052 } 4053 return; 4054 } 4055 } catch (RemoteException e) { 4056 mController = null; 4057 Watchdog.getInstance().setActivityController(null); 4058 } 4059 } 4060 4061 // Unless configured otherwise, swallow ANRs in background processes & kill the process. 4062 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), 4063 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; 4064 4065 synchronized (this) { 4066 if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) { 4067 killUnneededProcessLocked(app, "background ANR"); 4068 return; 4069 } 4070 4071 // Set the app's notResponding state, and look up the errorReportReceiver 4072 makeAppNotRespondingLocked(app, 4073 activity != null ? activity.shortComponentName : null, 4074 annotation != null ? "ANR " + annotation : "ANR", 4075 info.toString()); 4076 4077 // Bring up the infamous App Not Responding dialog 4078 Message msg = Message.obtain(); 4079 HashMap<String, Object> map = new HashMap<String, Object>(); 4080 msg.what = SHOW_NOT_RESPONDING_MSG; 4081 msg.obj = map; 4082 msg.arg1 = aboveSystem ? 1 : 0; 4083 map.put("app", app); 4084 if (activity != null) { 4085 map.put("activity", activity); 4086 } 4087 4088 mHandler.sendMessage(msg); 4089 } 4090 } 4091 4092 final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) { 4093 if (!mLaunchWarningShown) { 4094 mLaunchWarningShown = true; 4095 mHandler.post(new Runnable() { 4096 @Override 4097 public void run() { 4098 synchronized (ActivityManagerService.this) { 4099 final Dialog d = new LaunchWarningWindow(mContext, cur, next); 4100 d.show(); 4101 mHandler.postDelayed(new Runnable() { 4102 @Override 4103 public void run() { 4104 synchronized (ActivityManagerService.this) { 4105 d.dismiss(); 4106 mLaunchWarningShown = false; 4107 } 4108 } 4109 }, 4000); 4110 } 4111 } 4112 }); 4113 } 4114 } 4115 4116 @Override 4117 public boolean clearApplicationUserData(final String packageName, 4118 final IPackageDataObserver observer, int userId) { 4119 enforceNotIsolatedCaller("clearApplicationUserData"); 4120 int uid = Binder.getCallingUid(); 4121 int pid = Binder.getCallingPid(); 4122 userId = handleIncomingUser(pid, uid, 4123 userId, false, true, "clearApplicationUserData", null); 4124 long callingId = Binder.clearCallingIdentity(); 4125 try { 4126 IPackageManager pm = AppGlobals.getPackageManager(); 4127 int pkgUid = -1; 4128 synchronized(this) { 4129 try { 4130 pkgUid = pm.getPackageUid(packageName, userId); 4131 } catch (RemoteException e) { 4132 } 4133 if (pkgUid == -1) { 4134 Slog.w(TAG, "Invalid packageName: " + packageName); 4135 if (observer != null) { 4136 try { 4137 observer.onRemoveCompleted(packageName, false); 4138 } catch (RemoteException e) { 4139 Slog.i(TAG, "Observer no longer exists."); 4140 } 4141 } 4142 return false; 4143 } 4144 if (uid == pkgUid || checkComponentPermission( 4145 android.Manifest.permission.CLEAR_APP_USER_DATA, 4146 pid, uid, -1, true) 4147 == PackageManager.PERMISSION_GRANTED) { 4148 forceStopPackageLocked(packageName, pkgUid, "clear data"); 4149 } else { 4150 throw new SecurityException("PID " + pid + " does not have permission " 4151 + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data" 4152 + " of package " + packageName); 4153 } 4154 } 4155 4156 try { 4157 // Clear application user data 4158 pm.clearApplicationUserData(packageName, observer, userId); 4159 4160 // Remove all permissions granted from/to this package 4161 removeUriPermissionsForPackageLocked(packageName, userId, true); 4162 4163 Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED, 4164 Uri.fromParts("package", packageName, null)); 4165 intent.putExtra(Intent.EXTRA_UID, pkgUid); 4166 broadcastIntentInPackage("android", Process.SYSTEM_UID, intent, 4167 null, null, 0, null, null, null, false, false, userId); 4168 } catch (RemoteException e) { 4169 } 4170 } finally { 4171 Binder.restoreCallingIdentity(callingId); 4172 } 4173 return true; 4174 } 4175 4176 @Override 4177 public void killBackgroundProcesses(final String packageName, int userId) { 4178 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 4179 != PackageManager.PERMISSION_GRANTED && 4180 checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES) 4181 != PackageManager.PERMISSION_GRANTED) { 4182 String msg = "Permission Denial: killBackgroundProcesses() from pid=" 4183 + Binder.getCallingPid() 4184 + ", uid=" + Binder.getCallingUid() 4185 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 4186 Slog.w(TAG, msg); 4187 throw new SecurityException(msg); 4188 } 4189 4190 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 4191 userId, true, true, "killBackgroundProcesses", null); 4192 long callingId = Binder.clearCallingIdentity(); 4193 try { 4194 IPackageManager pm = AppGlobals.getPackageManager(); 4195 synchronized(this) { 4196 int appId = -1; 4197 try { 4198 appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0)); 4199 } catch (RemoteException e) { 4200 } 4201 if (appId == -1) { 4202 Slog.w(TAG, "Invalid packageName: " + packageName); 4203 return; 4204 } 4205 killPackageProcessesLocked(packageName, appId, userId, 4206 ProcessList.SERVICE_ADJ, false, true, true, false, "kill background"); 4207 } 4208 } finally { 4209 Binder.restoreCallingIdentity(callingId); 4210 } 4211 } 4212 4213 @Override 4214 public void killAllBackgroundProcesses() { 4215 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 4216 != PackageManager.PERMISSION_GRANTED) { 4217 String msg = "Permission Denial: killAllBackgroundProcesses() from pid=" 4218 + Binder.getCallingPid() 4219 + ", uid=" + Binder.getCallingUid() 4220 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 4221 Slog.w(TAG, msg); 4222 throw new SecurityException(msg); 4223 } 4224 4225 long callingId = Binder.clearCallingIdentity(); 4226 try { 4227 synchronized(this) { 4228 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 4229 final int NP = mProcessNames.getMap().size(); 4230 for (int ip=0; ip<NP; ip++) { 4231 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 4232 final int NA = apps.size(); 4233 for (int ia=0; ia<NA; ia++) { 4234 ProcessRecord app = apps.valueAt(ia); 4235 if (app.persistent) { 4236 // we don't kill persistent processes 4237 continue; 4238 } 4239 if (app.removed) { 4240 procs.add(app); 4241 } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 4242 app.removed = true; 4243 procs.add(app); 4244 } 4245 } 4246 } 4247 4248 int N = procs.size(); 4249 for (int i=0; i<N; i++) { 4250 removeProcessLocked(procs.get(i), false, true, "kill all background"); 4251 } 4252 mAllowLowerMemLevel = true; 4253 updateOomAdjLocked(); 4254 doLowMemReportIfNeededLocked(null); 4255 } 4256 } finally { 4257 Binder.restoreCallingIdentity(callingId); 4258 } 4259 } 4260 4261 @Override 4262 public void forceStopPackage(final String packageName, int userId) { 4263 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 4264 != PackageManager.PERMISSION_GRANTED) { 4265 String msg = "Permission Denial: forceStopPackage() from pid=" 4266 + Binder.getCallingPid() 4267 + ", uid=" + Binder.getCallingUid() 4268 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 4269 Slog.w(TAG, msg); 4270 throw new SecurityException(msg); 4271 } 4272 final int callingPid = Binder.getCallingPid(); 4273 userId = handleIncomingUser(callingPid, Binder.getCallingUid(), 4274 userId, true, true, "forceStopPackage", null); 4275 long callingId = Binder.clearCallingIdentity(); 4276 try { 4277 IPackageManager pm = AppGlobals.getPackageManager(); 4278 synchronized(this) { 4279 int[] users = userId == UserHandle.USER_ALL 4280 ? getUsersLocked() : new int[] { userId }; 4281 for (int user : users) { 4282 int pkgUid = -1; 4283 try { 4284 pkgUid = pm.getPackageUid(packageName, user); 4285 } catch (RemoteException e) { 4286 } 4287 if (pkgUid == -1) { 4288 Slog.w(TAG, "Invalid packageName: " + packageName); 4289 continue; 4290 } 4291 try { 4292 pm.setPackageStoppedState(packageName, true, user); 4293 } catch (RemoteException e) { 4294 } catch (IllegalArgumentException e) { 4295 Slog.w(TAG, "Failed trying to unstop package " 4296 + packageName + ": " + e); 4297 } 4298 if (isUserRunningLocked(user, false)) { 4299 forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid); 4300 } 4301 } 4302 } 4303 } finally { 4304 Binder.restoreCallingIdentity(callingId); 4305 } 4306 } 4307 4308 /* 4309 * The pkg name and app id have to be specified. 4310 */ 4311 @Override 4312 public void killApplicationWithAppId(String pkg, int appid, String reason) { 4313 if (pkg == null) { 4314 return; 4315 } 4316 // Make sure the uid is valid. 4317 if (appid < 0) { 4318 Slog.w(TAG, "Invalid appid specified for pkg : " + pkg); 4319 return; 4320 } 4321 int callerUid = Binder.getCallingUid(); 4322 // Only the system server can kill an application 4323 if (callerUid == Process.SYSTEM_UID) { 4324 // Post an aysnc message to kill the application 4325 Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG); 4326 msg.arg1 = appid; 4327 msg.arg2 = 0; 4328 Bundle bundle = new Bundle(); 4329 bundle.putString("pkg", pkg); 4330 bundle.putString("reason", reason); 4331 msg.obj = bundle; 4332 mHandler.sendMessage(msg); 4333 } else { 4334 throw new SecurityException(callerUid + " cannot kill pkg: " + 4335 pkg); 4336 } 4337 } 4338 4339 @Override 4340 public void closeSystemDialogs(String reason) { 4341 enforceNotIsolatedCaller("closeSystemDialogs"); 4342 4343 final int pid = Binder.getCallingPid(); 4344 final int uid = Binder.getCallingUid(); 4345 final long origId = Binder.clearCallingIdentity(); 4346 try { 4347 synchronized (this) { 4348 // Only allow this from foreground processes, so that background 4349 // applications can't abuse it to prevent system UI from being shown. 4350 if (uid >= Process.FIRST_APPLICATION_UID) { 4351 ProcessRecord proc; 4352 synchronized (mPidsSelfLocked) { 4353 proc = mPidsSelfLocked.get(pid); 4354 } 4355 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 4356 Slog.w(TAG, "Ignoring closeSystemDialogs " + reason 4357 + " from background process " + proc); 4358 return; 4359 } 4360 } 4361 closeSystemDialogsLocked(reason); 4362 } 4363 } finally { 4364 Binder.restoreCallingIdentity(origId); 4365 } 4366 } 4367 4368 void closeSystemDialogsLocked(String reason) { 4369 Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS); 4370 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 4371 | Intent.FLAG_RECEIVER_FOREGROUND); 4372 if (reason != null) { 4373 intent.putExtra("reason", reason); 4374 } 4375 mWindowManager.closeSystemDialogs(reason); 4376 4377 mStackSupervisor.closeSystemDialogsLocked(); 4378 4379 broadcastIntentLocked(null, null, intent, null, 4380 null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1, 4381 Process.SYSTEM_UID, UserHandle.USER_ALL); 4382 } 4383 4384 @Override 4385 public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) { 4386 enforceNotIsolatedCaller("getProcessMemoryInfo"); 4387 Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length]; 4388 for (int i=pids.length-1; i>=0; i--) { 4389 ProcessRecord proc; 4390 int oomAdj; 4391 synchronized (this) { 4392 synchronized (mPidsSelfLocked) { 4393 proc = mPidsSelfLocked.get(pids[i]); 4394 oomAdj = proc != null ? proc.setAdj : 0; 4395 } 4396 } 4397 infos[i] = new Debug.MemoryInfo(); 4398 Debug.getMemoryInfo(pids[i], infos[i]); 4399 if (proc != null) { 4400 synchronized (this) { 4401 if (proc.thread != null && proc.setAdj == oomAdj) { 4402 // Record this for posterity if the process has been stable. 4403 proc.baseProcessTracker.addPss(infos[i].getTotalPss(), 4404 infos[i].getTotalUss(), false, proc.pkgList); 4405 } 4406 } 4407 } 4408 } 4409 return infos; 4410 } 4411 4412 @Override 4413 public long[] getProcessPss(int[] pids) { 4414 enforceNotIsolatedCaller("getProcessPss"); 4415 long[] pss = new long[pids.length]; 4416 for (int i=pids.length-1; i>=0; i--) { 4417 ProcessRecord proc; 4418 int oomAdj; 4419 synchronized (this) { 4420 synchronized (mPidsSelfLocked) { 4421 proc = mPidsSelfLocked.get(pids[i]); 4422 oomAdj = proc != null ? proc.setAdj : 0; 4423 } 4424 } 4425 long[] tmpUss = new long[1]; 4426 pss[i] = Debug.getPss(pids[i], tmpUss); 4427 if (proc != null) { 4428 synchronized (this) { 4429 if (proc.thread != null && proc.setAdj == oomAdj) { 4430 // Record this for posterity if the process has been stable. 4431 proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList); 4432 } 4433 } 4434 } 4435 } 4436 return pss; 4437 } 4438 4439 @Override 4440 public void killApplicationProcess(String processName, int uid) { 4441 if (processName == null) { 4442 return; 4443 } 4444 4445 int callerUid = Binder.getCallingUid(); 4446 // Only the system server can kill an application 4447 if (callerUid == Process.SYSTEM_UID) { 4448 synchronized (this) { 4449 ProcessRecord app = getProcessRecordLocked(processName, uid, true); 4450 if (app != null && app.thread != null) { 4451 try { 4452 app.thread.scheduleSuicide(); 4453 } catch (RemoteException e) { 4454 // If the other end already died, then our work here is done. 4455 } 4456 } else { 4457 Slog.w(TAG, "Process/uid not found attempting kill of " 4458 + processName + " / " + uid); 4459 } 4460 } 4461 } else { 4462 throw new SecurityException(callerUid + " cannot kill app process: " + 4463 processName); 4464 } 4465 } 4466 4467 private void forceStopPackageLocked(final String packageName, int uid, String reason) { 4468 forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false, 4469 false, true, false, false, UserHandle.getUserId(uid), reason); 4470 Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED, 4471 Uri.fromParts("package", packageName, null)); 4472 if (!mProcessesReady) { 4473 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 4474 | Intent.FLAG_RECEIVER_FOREGROUND); 4475 } 4476 intent.putExtra(Intent.EXTRA_UID, uid); 4477 intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid)); 4478 broadcastIntentLocked(null, null, intent, 4479 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 4480 false, false, 4481 MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid)); 4482 } 4483 4484 private void forceStopUserLocked(int userId, String reason) { 4485 forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason); 4486 Intent intent = new Intent(Intent.ACTION_USER_STOPPED); 4487 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 4488 | Intent.FLAG_RECEIVER_FOREGROUND); 4489 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 4490 broadcastIntentLocked(null, null, intent, 4491 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 4492 false, false, 4493 MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 4494 } 4495 4496 private final boolean killPackageProcessesLocked(String packageName, int appId, 4497 int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart, 4498 boolean doit, boolean evenPersistent, String reason) { 4499 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 4500 4501 // Remove all processes this package may have touched: all with the 4502 // same UID (except for the system or root user), and all whose name 4503 // matches the package name. 4504 final String procNamePrefix = packageName != null ? (packageName + ":") : null; 4505 final int NP = mProcessNames.getMap().size(); 4506 for (int ip=0; ip<NP; ip++) { 4507 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 4508 final int NA = apps.size(); 4509 for (int ia=0; ia<NA; ia++) { 4510 ProcessRecord app = apps.valueAt(ia); 4511 if (app.persistent && !evenPersistent) { 4512 // we don't kill persistent processes 4513 continue; 4514 } 4515 if (app.removed) { 4516 if (doit) { 4517 procs.add(app); 4518 } 4519 continue; 4520 } 4521 4522 // Skip process if it doesn't meet our oom adj requirement. 4523 if (app.setAdj < minOomAdj) { 4524 continue; 4525 } 4526 4527 // If no package is specified, we call all processes under the 4528 // give user id. 4529 if (packageName == null) { 4530 if (app.userId != userId) { 4531 continue; 4532 } 4533 if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) { 4534 continue; 4535 } 4536 // Package has been specified, we want to hit all processes 4537 // that match it. We need to qualify this by the processes 4538 // that are running under the specified app and user ID. 4539 } else { 4540 if (UserHandle.getAppId(app.uid) != appId) { 4541 continue; 4542 } 4543 if (userId != UserHandle.USER_ALL && app.userId != userId) { 4544 continue; 4545 } 4546 if (!app.pkgList.containsKey(packageName)) { 4547 continue; 4548 } 4549 } 4550 4551 // Process has passed all conditions, kill it! 4552 if (!doit) { 4553 return true; 4554 } 4555 app.removed = true; 4556 procs.add(app); 4557 } 4558 } 4559 4560 int N = procs.size(); 4561 for (int i=0; i<N; i++) { 4562 removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason); 4563 } 4564 updateOomAdjLocked(); 4565 return N > 0; 4566 } 4567 4568 private final boolean forceStopPackageLocked(String name, int appId, 4569 boolean callerWillRestart, boolean purgeCache, boolean doit, 4570 boolean evenPersistent, boolean uninstalling, int userId, String reason) { 4571 int i; 4572 int N; 4573 4574 if (userId == UserHandle.USER_ALL && name == null) { 4575 Slog.w(TAG, "Can't force stop all processes of all users, that is insane!"); 4576 } 4577 4578 if (appId < 0 && name != null) { 4579 try { 4580 appId = UserHandle.getAppId( 4581 AppGlobals.getPackageManager().getPackageUid(name, 0)); 4582 } catch (RemoteException e) { 4583 } 4584 } 4585 4586 if (doit) { 4587 if (name != null) { 4588 Slog.i(TAG, "Force stopping " + name + " appid=" + appId 4589 + " user=" + userId + ": " + reason); 4590 } else { 4591 Slog.i(TAG, "Force stopping u" + userId + ": " + reason); 4592 } 4593 4594 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap(); 4595 for (int ip=pmap.size()-1; ip>=0; ip--) { 4596 SparseArray<Long> ba = pmap.valueAt(ip); 4597 for (i=ba.size()-1; i>=0; i--) { 4598 boolean remove = false; 4599 final int entUid = ba.keyAt(i); 4600 if (name != null) { 4601 if (userId == UserHandle.USER_ALL) { 4602 if (UserHandle.getAppId(entUid) == appId) { 4603 remove = true; 4604 } 4605 } else { 4606 if (entUid == UserHandle.getUid(userId, appId)) { 4607 remove = true; 4608 } 4609 } 4610 } else if (UserHandle.getUserId(entUid) == userId) { 4611 remove = true; 4612 } 4613 if (remove) { 4614 ba.removeAt(i); 4615 } 4616 } 4617 if (ba.size() == 0) { 4618 pmap.removeAt(ip); 4619 } 4620 } 4621 } 4622 4623 boolean didSomething = killPackageProcessesLocked(name, appId, userId, 4624 -100, callerWillRestart, true, doit, evenPersistent, 4625 name == null ? ("stop user " + userId) : ("stop " + name)); 4626 4627 if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) { 4628 if (!doit) { 4629 return true; 4630 } 4631 didSomething = true; 4632 } 4633 4634 if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) { 4635 if (!doit) { 4636 return true; 4637 } 4638 didSomething = true; 4639 } 4640 4641 if (name == null) { 4642 // Remove all sticky broadcasts from this user. 4643 mStickyBroadcasts.remove(userId); 4644 } 4645 4646 ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>(); 4647 if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent, 4648 userId, providers)) { 4649 if (!doit) { 4650 return true; 4651 } 4652 didSomething = true; 4653 } 4654 N = providers.size(); 4655 for (i=0; i<N; i++) { 4656 removeDyingProviderLocked(null, providers.get(i), true); 4657 } 4658 4659 // Remove transient permissions granted from/to this package/user 4660 removeUriPermissionsForPackageLocked(name, userId, false); 4661 4662 if (name == null || uninstalling) { 4663 // Remove pending intents. For now we only do this when force 4664 // stopping users, because we have some problems when doing this 4665 // for packages -- app widgets are not currently cleaned up for 4666 // such packages, so they can be left with bad pending intents. 4667 if (mIntentSenderRecords.size() > 0) { 4668 Iterator<WeakReference<PendingIntentRecord>> it 4669 = mIntentSenderRecords.values().iterator(); 4670 while (it.hasNext()) { 4671 WeakReference<PendingIntentRecord> wpir = it.next(); 4672 if (wpir == null) { 4673 it.remove(); 4674 continue; 4675 } 4676 PendingIntentRecord pir = wpir.get(); 4677 if (pir == null) { 4678 it.remove(); 4679 continue; 4680 } 4681 if (name == null) { 4682 // Stopping user, remove all objects for the user. 4683 if (pir.key.userId != userId) { 4684 // Not the same user, skip it. 4685 continue; 4686 } 4687 } else { 4688 if (UserHandle.getAppId(pir.uid) != appId) { 4689 // Different app id, skip it. 4690 continue; 4691 } 4692 if (userId != UserHandle.USER_ALL && pir.key.userId != userId) { 4693 // Different user, skip it. 4694 continue; 4695 } 4696 if (!pir.key.packageName.equals(name)) { 4697 // Different package, skip it. 4698 continue; 4699 } 4700 } 4701 if (!doit) { 4702 return true; 4703 } 4704 didSomething = true; 4705 it.remove(); 4706 pir.canceled = true; 4707 if (pir.key.activity != null) { 4708 pir.key.activity.pendingResults.remove(pir.ref); 4709 } 4710 } 4711 } 4712 } 4713 4714 if (doit) { 4715 if (purgeCache && name != null) { 4716 AttributeCache ac = AttributeCache.instance(); 4717 if (ac != null) { 4718 ac.removePackage(name); 4719 } 4720 } 4721 if (mBooted) { 4722 mStackSupervisor.resumeTopActivitiesLocked(); 4723 mStackSupervisor.scheduleIdleLocked(); 4724 } 4725 } 4726 4727 return didSomething; 4728 } 4729 4730 private final boolean removeProcessLocked(ProcessRecord app, 4731 boolean callerWillRestart, boolean allowRestart, String reason) { 4732 final String name = app.processName; 4733 final int uid = app.uid; 4734 if (DEBUG_PROCESSES) Slog.d( 4735 TAG, "Force removing proc " + app.toShortString() + " (" + name 4736 + "/" + uid + ")"); 4737 4738 mProcessNames.remove(name, uid); 4739 mIsolatedProcesses.remove(app.uid); 4740 if (mHeavyWeightProcess == app) { 4741 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 4742 mHeavyWeightProcess.userId, 0)); 4743 mHeavyWeightProcess = null; 4744 } 4745 boolean needRestart = false; 4746 if (app.pid > 0 && app.pid != MY_PID) { 4747 int pid = app.pid; 4748 synchronized (mPidsSelfLocked) { 4749 mPidsSelfLocked.remove(pid); 4750 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 4751 } 4752 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH, 4753 app.processName, app.info.uid); 4754 if (app.isolated) { 4755 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 4756 } 4757 killUnneededProcessLocked(app, reason); 4758 handleAppDiedLocked(app, true, allowRestart); 4759 removeLruProcessLocked(app); 4760 4761 if (app.persistent && !app.isolated) { 4762 if (!callerWillRestart) { 4763 addAppLocked(app.info, false); 4764 } else { 4765 needRestart = true; 4766 } 4767 } 4768 } else { 4769 mRemovedProcesses.add(app); 4770 } 4771 4772 return needRestart; 4773 } 4774 4775 private final void processStartTimedOutLocked(ProcessRecord app) { 4776 final int pid = app.pid; 4777 boolean gone = false; 4778 synchronized (mPidsSelfLocked) { 4779 ProcessRecord knownApp = mPidsSelfLocked.get(pid); 4780 if (knownApp != null && knownApp.thread == null) { 4781 mPidsSelfLocked.remove(pid); 4782 gone = true; 4783 } 4784 } 4785 4786 if (gone) { 4787 Slog.w(TAG, "Process " + app + " failed to attach"); 4788 EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId, 4789 pid, app.uid, app.processName); 4790 mProcessNames.remove(app.processName, app.uid); 4791 mIsolatedProcesses.remove(app.uid); 4792 if (mHeavyWeightProcess == app) { 4793 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 4794 mHeavyWeightProcess.userId, 0)); 4795 mHeavyWeightProcess = null; 4796 } 4797 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH, 4798 app.processName, app.info.uid); 4799 if (app.isolated) { 4800 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 4801 } 4802 // Take care of any launching providers waiting for this process. 4803 checkAppInLaunchingProvidersLocked(app, true); 4804 // Take care of any services that are waiting for the process. 4805 mServices.processStartTimedOutLocked(app); 4806 killUnneededProcessLocked(app, "start timeout"); 4807 if (mBackupTarget != null && mBackupTarget.app.pid == pid) { 4808 Slog.w(TAG, "Unattached app died before backup, skipping"); 4809 try { 4810 IBackupManager bm = IBackupManager.Stub.asInterface( 4811 ServiceManager.getService(Context.BACKUP_SERVICE)); 4812 bm.agentDisconnected(app.info.packageName); 4813 } catch (RemoteException e) { 4814 // Can't happen; the backup manager is local 4815 } 4816 } 4817 if (isPendingBroadcastProcessLocked(pid)) { 4818 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 4819 skipPendingBroadcastLocked(pid); 4820 } 4821 } else { 4822 Slog.w(TAG, "Spurious process start timeout - pid not known for " + app); 4823 } 4824 } 4825 4826 private final boolean attachApplicationLocked(IApplicationThread thread, 4827 int pid) { 4828 4829 // Find the application record that is being attached... either via 4830 // the pid if we are running in multiple processes, or just pull the 4831 // next app record if we are emulating process with anonymous threads. 4832 ProcessRecord app; 4833 if (pid != MY_PID && pid >= 0) { 4834 synchronized (mPidsSelfLocked) { 4835 app = mPidsSelfLocked.get(pid); 4836 } 4837 } else { 4838 app = null; 4839 } 4840 4841 if (app == null) { 4842 Slog.w(TAG, "No pending application record for pid " + pid 4843 + " (IApplicationThread " + thread + "); dropping process"); 4844 EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid); 4845 if (pid > 0 && pid != MY_PID) { 4846 Process.killProcessQuiet(pid); 4847 } else { 4848 try { 4849 thread.scheduleExit(); 4850 } catch (Exception e) { 4851 // Ignore exceptions. 4852 } 4853 } 4854 return false; 4855 } 4856 4857 // If this application record is still attached to a previous 4858 // process, clean it up now. 4859 if (app.thread != null) { 4860 handleAppDiedLocked(app, true, true); 4861 } 4862 4863 // Tell the process all about itself. 4864 4865 if (localLOGV) Slog.v( 4866 TAG, "Binding process pid " + pid + " to record " + app); 4867 4868 final String processName = app.processName; 4869 try { 4870 AppDeathRecipient adr = new AppDeathRecipient( 4871 app, pid, thread); 4872 thread.asBinder().linkToDeath(adr, 0); 4873 app.deathRecipient = adr; 4874 } catch (RemoteException e) { 4875 app.resetPackageList(mProcessStats); 4876 startProcessLocked(app, "link fail", processName); 4877 return false; 4878 } 4879 4880 EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName); 4881 4882 app.makeActive(thread, mProcessStats); 4883 app.curAdj = app.setAdj = -100; 4884 app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT; 4885 app.forcingToForeground = null; 4886 updateProcessForegroundLocked(app, false, false); 4887 app.hasShownUi = false; 4888 app.debugging = false; 4889 app.cached = false; 4890 4891 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 4892 4893 boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info); 4894 List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null; 4895 4896 if (!normalMode) { 4897 Slog.i(TAG, "Launching preboot mode app: " + app); 4898 } 4899 4900 if (localLOGV) Slog.v( 4901 TAG, "New app record " + app 4902 + " thread=" + thread.asBinder() + " pid=" + pid); 4903 try { 4904 int testMode = IApplicationThread.DEBUG_OFF; 4905 if (mDebugApp != null && mDebugApp.equals(processName)) { 4906 testMode = mWaitForDebugger 4907 ? IApplicationThread.DEBUG_WAIT 4908 : IApplicationThread.DEBUG_ON; 4909 app.debugging = true; 4910 if (mDebugTransient) { 4911 mDebugApp = mOrigDebugApp; 4912 mWaitForDebugger = mOrigWaitForDebugger; 4913 } 4914 } 4915 String profileFile = app.instrumentationProfileFile; 4916 ParcelFileDescriptor profileFd = null; 4917 boolean profileAutoStop = false; 4918 if (mProfileApp != null && mProfileApp.equals(processName)) { 4919 mProfileProc = app; 4920 profileFile = mProfileFile; 4921 profileFd = mProfileFd; 4922 profileAutoStop = mAutoStopProfiler; 4923 } 4924 boolean enableOpenGlTrace = false; 4925 if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) { 4926 enableOpenGlTrace = true; 4927 mOpenGlTraceApp = null; 4928 } 4929 4930 // If the app is being launched for restore or full backup, set it up specially 4931 boolean isRestrictedBackupMode = false; 4932 if (mBackupTarget != null && mBackupAppName.equals(processName)) { 4933 isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE) 4934 || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL) 4935 || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL); 4936 } 4937 4938 ensurePackageDexOpt(app.instrumentationInfo != null 4939 ? app.instrumentationInfo.packageName 4940 : app.info.packageName); 4941 if (app.instrumentationClass != null) { 4942 ensurePackageDexOpt(app.instrumentationClass.getPackageName()); 4943 } 4944 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc " 4945 + processName + " with config " + mConfiguration); 4946 ApplicationInfo appInfo = app.instrumentationInfo != null 4947 ? app.instrumentationInfo : app.info; 4948 app.compat = compatibilityInfoForPackageLocked(appInfo); 4949 if (profileFd != null) { 4950 profileFd = profileFd.dup(); 4951 } 4952 thread.bindApplication(processName, appInfo, providers, 4953 app.instrumentationClass, profileFile, profileFd, profileAutoStop, 4954 app.instrumentationArguments, app.instrumentationWatcher, 4955 app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace, 4956 isRestrictedBackupMode || !normalMode, app.persistent, 4957 new Configuration(mConfiguration), app.compat, getCommonServicesLocked(), 4958 mCoreSettingsObserver.getCoreSettingsLocked()); 4959 updateLruProcessLocked(app, false, null); 4960 app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis(); 4961 } catch (Exception e) { 4962 // todo: Yikes! What should we do? For now we will try to 4963 // start another process, but that could easily get us in 4964 // an infinite loop of restarting processes... 4965 Slog.w(TAG, "Exception thrown during bind!", e); 4966 4967 app.resetPackageList(mProcessStats); 4968 app.unlinkDeathRecipient(); 4969 startProcessLocked(app, "bind fail", processName); 4970 return false; 4971 } 4972 4973 // Remove this record from the list of starting applications. 4974 mPersistentStartingProcesses.remove(app); 4975 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 4976 "Attach application locked removing on hold: " + app); 4977 mProcessesOnHold.remove(app); 4978 4979 boolean badApp = false; 4980 boolean didSomething = false; 4981 4982 // See if the top visible activity is waiting to run in this process... 4983 if (normalMode) { 4984 try { 4985 if (mStackSupervisor.attachApplicationLocked(app)) { 4986 didSomething = true; 4987 } 4988 } catch (Exception e) { 4989 badApp = true; 4990 } 4991 } 4992 4993 // Find any services that should be running in this process... 4994 if (!badApp) { 4995 try { 4996 didSomething |= mServices.attachApplicationLocked(app, processName); 4997 } catch (Exception e) { 4998 badApp = true; 4999 } 5000 } 5001 5002 // Check if a next-broadcast receiver is in this process... 5003 if (!badApp && isPendingBroadcastProcessLocked(pid)) { 5004 try { 5005 didSomething |= sendPendingBroadcastsLocked(app); 5006 } catch (Exception e) { 5007 // If the app died trying to launch the receiver we declare it 'bad' 5008 badApp = true; 5009 } 5010 } 5011 5012 // Check whether the next backup agent is in this process... 5013 if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) { 5014 if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app); 5015 ensurePackageDexOpt(mBackupTarget.appInfo.packageName); 5016 try { 5017 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo, 5018 compatibilityInfoForPackageLocked(mBackupTarget.appInfo), 5019 mBackupTarget.backupMode); 5020 } catch (Exception e) { 5021 Slog.w(TAG, "Exception scheduling backup agent creation: "); 5022 e.printStackTrace(); 5023 } 5024 } 5025 5026 if (badApp) { 5027 // todo: Also need to kill application to deal with all 5028 // kinds of exceptions. 5029 handleAppDiedLocked(app, false, true); 5030 return false; 5031 } 5032 5033 if (!didSomething) { 5034 updateOomAdjLocked(); 5035 } 5036 5037 return true; 5038 } 5039 5040 @Override 5041 public final void attachApplication(IApplicationThread thread) { 5042 synchronized (this) { 5043 int callingPid = Binder.getCallingPid(); 5044 final long origId = Binder.clearCallingIdentity(); 5045 attachApplicationLocked(thread, callingPid); 5046 Binder.restoreCallingIdentity(origId); 5047 } 5048 } 5049 5050 @Override 5051 public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) { 5052 final long origId = Binder.clearCallingIdentity(); 5053 synchronized (this) { 5054 ActivityStack stack = ActivityRecord.getStackLocked(token); 5055 if (stack != null) { 5056 ActivityRecord r = 5057 mStackSupervisor.activityIdleInternalLocked(token, false, config); 5058 if (stopProfiling) { 5059 if ((mProfileProc == r.app) && (mProfileFd != null)) { 5060 try { 5061 mProfileFd.close(); 5062 } catch (IOException e) { 5063 } 5064 clearProfilerLocked(); 5065 } 5066 } 5067 } 5068 } 5069 Binder.restoreCallingIdentity(origId); 5070 } 5071 5072 void enableScreenAfterBoot() { 5073 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN, 5074 SystemClock.uptimeMillis()); 5075 mWindowManager.enableScreenAfterBoot(); 5076 5077 synchronized (this) { 5078 updateEventDispatchingLocked(); 5079 } 5080 } 5081 5082 @Override 5083 public void showBootMessage(final CharSequence msg, final boolean always) { 5084 enforceNotIsolatedCaller("showBootMessage"); 5085 mWindowManager.showBootMessage(msg, always); 5086 } 5087 5088 @Override 5089 public void dismissKeyguardOnNextActivity() { 5090 enforceNotIsolatedCaller("dismissKeyguardOnNextActivity"); 5091 final long token = Binder.clearCallingIdentity(); 5092 try { 5093 synchronized (this) { 5094 if (DEBUG_LOCKSCREEN) logLockScreen(""); 5095 if (mLockScreenShown) { 5096 mLockScreenShown = false; 5097 comeOutOfSleepIfNeededLocked(); 5098 } 5099 mStackSupervisor.setDismissKeyguard(true); 5100 } 5101 } finally { 5102 Binder.restoreCallingIdentity(token); 5103 } 5104 } 5105 5106 final void finishBooting() { 5107 IntentFilter pkgFilter = new IntentFilter(); 5108 pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART); 5109 pkgFilter.addDataScheme("package"); 5110 mContext.registerReceiver(new BroadcastReceiver() { 5111 @Override 5112 public void onReceive(Context context, Intent intent) { 5113 String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES); 5114 if (pkgs != null) { 5115 for (String pkg : pkgs) { 5116 synchronized (ActivityManagerService.this) { 5117 if (forceStopPackageLocked(pkg, -1, false, false, false, false, false, 0, 5118 "finished booting")) { 5119 setResultCode(Activity.RESULT_OK); 5120 return; 5121 } 5122 } 5123 } 5124 } 5125 } 5126 }, pkgFilter); 5127 5128 synchronized (this) { 5129 // Ensure that any processes we had put on hold are now started 5130 // up. 5131 final int NP = mProcessesOnHold.size(); 5132 if (NP > 0) { 5133 ArrayList<ProcessRecord> procs = 5134 new ArrayList<ProcessRecord>(mProcessesOnHold); 5135 for (int ip=0; ip<NP; ip++) { 5136 if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: " 5137 + procs.get(ip)); 5138 startProcessLocked(procs.get(ip), "on-hold", null); 5139 } 5140 } 5141 5142 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 5143 // Start looking for apps that are abusing wake locks. 5144 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 5145 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 5146 // Tell anyone interested that we are done booting! 5147 SystemProperties.set("sys.boot_completed", "1"); 5148 SystemProperties.set("dev.bootcomplete", "1"); 5149 for (int i=0; i<mStartedUsers.size(); i++) { 5150 UserStartedState uss = mStartedUsers.valueAt(i); 5151 if (uss.mState == UserStartedState.STATE_BOOTING) { 5152 uss.mState = UserStartedState.STATE_RUNNING; 5153 final int userId = mStartedUsers.keyAt(i); 5154 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 5155 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 5156 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT); 5157 broadcastIntentLocked(null, null, intent, null, 5158 new IIntentReceiver.Stub() { 5159 @Override 5160 public void performReceive(Intent intent, int resultCode, 5161 String data, Bundle extras, boolean ordered, 5162 boolean sticky, int sendingUser) { 5163 synchronized (ActivityManagerService.this) { 5164 requestPssAllProcsLocked(SystemClock.uptimeMillis(), 5165 true, false); 5166 } 5167 } 5168 }, 5169 0, null, null, 5170 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, 5171 AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID, 5172 userId); 5173 } 5174 } 5175 scheduleStartRelatedUsersLocked(); 5176 } 5177 } 5178 } 5179 5180 final void ensureBootCompleted() { 5181 boolean booting; 5182 boolean enableScreen; 5183 synchronized (this) { 5184 booting = mBooting; 5185 mBooting = false; 5186 enableScreen = !mBooted; 5187 mBooted = true; 5188 } 5189 5190 if (booting) { 5191 finishBooting(); 5192 } 5193 5194 if (enableScreen) { 5195 enableScreenAfterBoot(); 5196 } 5197 } 5198 5199 @Override 5200 public final void activityResumed(IBinder token) { 5201 final long origId = Binder.clearCallingIdentity(); 5202 synchronized(this) { 5203 ActivityStack stack = ActivityRecord.getStackLocked(token); 5204 if (stack != null) { 5205 ActivityRecord.activityResumedLocked(token); 5206 } 5207 } 5208 Binder.restoreCallingIdentity(origId); 5209 } 5210 5211 @Override 5212 public final void activityPaused(IBinder token) { 5213 final long origId = Binder.clearCallingIdentity(); 5214 synchronized(this) { 5215 ActivityStack stack = ActivityRecord.getStackLocked(token); 5216 if (stack != null) { 5217 stack.activityPausedLocked(token, false); 5218 } 5219 } 5220 Binder.restoreCallingIdentity(origId); 5221 } 5222 5223 @Override 5224 public final void activityStopped(IBinder token, Bundle icicle, Bitmap thumbnail, 5225 CharSequence description) { 5226 if (localLOGV) Slog.v( 5227 TAG, "Activity stopped: token=" + token); 5228 5229 // Refuse possible leaked file descriptors 5230 if (icicle != null && icicle.hasFileDescriptors()) { 5231 throw new IllegalArgumentException("File descriptors passed in Bundle"); 5232 } 5233 5234 ActivityRecord r = null; 5235 5236 final long origId = Binder.clearCallingIdentity(); 5237 5238 synchronized (this) { 5239 r = ActivityRecord.isInStackLocked(token); 5240 if (r != null) { 5241 r.task.stack.activityStoppedLocked(r, icicle, thumbnail, description); 5242 } 5243 } 5244 5245 if (r != null) { 5246 sendPendingThumbnail(r, null, null, null, false); 5247 } 5248 5249 trimApplications(); 5250 5251 Binder.restoreCallingIdentity(origId); 5252 } 5253 5254 @Override 5255 public final void activityDestroyed(IBinder token) { 5256 if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token); 5257 synchronized (this) { 5258 ActivityStack stack = ActivityRecord.getStackLocked(token); 5259 if (stack != null) { 5260 stack.activityDestroyedLocked(token); 5261 } 5262 } 5263 } 5264 5265 @Override 5266 public String getCallingPackage(IBinder token) { 5267 synchronized (this) { 5268 ActivityRecord r = getCallingRecordLocked(token); 5269 return r != null ? r.info.packageName : null; 5270 } 5271 } 5272 5273 @Override 5274 public ComponentName getCallingActivity(IBinder token) { 5275 synchronized (this) { 5276 ActivityRecord r = getCallingRecordLocked(token); 5277 return r != null ? r.intent.getComponent() : null; 5278 } 5279 } 5280 5281 private ActivityRecord getCallingRecordLocked(IBinder token) { 5282 ActivityRecord r = ActivityRecord.isInStackLocked(token); 5283 if (r == null) { 5284 return null; 5285 } 5286 return r.resultTo; 5287 } 5288 5289 @Override 5290 public ComponentName getActivityClassForToken(IBinder token) { 5291 synchronized(this) { 5292 ActivityRecord r = ActivityRecord.isInStackLocked(token); 5293 if (r == null) { 5294 return null; 5295 } 5296 return r.intent.getComponent(); 5297 } 5298 } 5299 5300 @Override 5301 public String getPackageForToken(IBinder token) { 5302 synchronized(this) { 5303 ActivityRecord r = ActivityRecord.isInStackLocked(token); 5304 if (r == null) { 5305 return null; 5306 } 5307 return r.packageName; 5308 } 5309 } 5310 5311 @Override 5312 public IIntentSender getIntentSender(int type, 5313 String packageName, IBinder token, String resultWho, 5314 int requestCode, Intent[] intents, String[] resolvedTypes, 5315 int flags, Bundle options, int userId) { 5316 enforceNotIsolatedCaller("getIntentSender"); 5317 // Refuse possible leaked file descriptors 5318 if (intents != null) { 5319 if (intents.length < 1) { 5320 throw new IllegalArgumentException("Intents array length must be >= 1"); 5321 } 5322 for (int i=0; i<intents.length; i++) { 5323 Intent intent = intents[i]; 5324 if (intent != null) { 5325 if (intent.hasFileDescriptors()) { 5326 throw new IllegalArgumentException("File descriptors passed in Intent"); 5327 } 5328 if (type == ActivityManager.INTENT_SENDER_BROADCAST && 5329 (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 5330 throw new IllegalArgumentException( 5331 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 5332 } 5333 intents[i] = new Intent(intent); 5334 } 5335 } 5336 if (resolvedTypes != null && resolvedTypes.length != intents.length) { 5337 throw new IllegalArgumentException( 5338 "Intent array length does not match resolvedTypes length"); 5339 } 5340 } 5341 if (options != null) { 5342 if (options.hasFileDescriptors()) { 5343 throw new IllegalArgumentException("File descriptors passed in options"); 5344 } 5345 } 5346 5347 synchronized(this) { 5348 int callingUid = Binder.getCallingUid(); 5349 int origUserId = userId; 5350 userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId, 5351 type == ActivityManager.INTENT_SENDER_BROADCAST, false, 5352 "getIntentSender", null); 5353 if (origUserId == UserHandle.USER_CURRENT) { 5354 // We don't want to evaluate this until the pending intent is 5355 // actually executed. However, we do want to always do the 5356 // security checking for it above. 5357 userId = UserHandle.USER_CURRENT; 5358 } 5359 try { 5360 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 5361 int uid = AppGlobals.getPackageManager() 5362 .getPackageUid(packageName, UserHandle.getUserId(callingUid)); 5363 if (!UserHandle.isSameApp(callingUid, uid)) { 5364 String msg = "Permission Denial: getIntentSender() from pid=" 5365 + Binder.getCallingPid() 5366 + ", uid=" + Binder.getCallingUid() 5367 + ", (need uid=" + uid + ")" 5368 + " is not allowed to send as package " + packageName; 5369 Slog.w(TAG, msg); 5370 throw new SecurityException(msg); 5371 } 5372 } 5373 5374 return getIntentSenderLocked(type, packageName, callingUid, userId, 5375 token, resultWho, requestCode, intents, resolvedTypes, flags, options); 5376 5377 } catch (RemoteException e) { 5378 throw new SecurityException(e); 5379 } 5380 } 5381 } 5382 5383 IIntentSender getIntentSenderLocked(int type, String packageName, 5384 int callingUid, int userId, IBinder token, String resultWho, 5385 int requestCode, Intent[] intents, String[] resolvedTypes, int flags, 5386 Bundle options) { 5387 if (DEBUG_MU) 5388 Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid); 5389 ActivityRecord activity = null; 5390 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 5391 activity = ActivityRecord.isInStackLocked(token); 5392 if (activity == null) { 5393 return null; 5394 } 5395 if (activity.finishing) { 5396 return null; 5397 } 5398 } 5399 5400 final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0; 5401 final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0; 5402 final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0; 5403 flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT 5404 |PendingIntent.FLAG_UPDATE_CURRENT); 5405 5406 PendingIntentRecord.Key key = new PendingIntentRecord.Key( 5407 type, packageName, activity, resultWho, 5408 requestCode, intents, resolvedTypes, flags, options, userId); 5409 WeakReference<PendingIntentRecord> ref; 5410 ref = mIntentSenderRecords.get(key); 5411 PendingIntentRecord rec = ref != null ? ref.get() : null; 5412 if (rec != null) { 5413 if (!cancelCurrent) { 5414 if (updateCurrent) { 5415 if (rec.key.requestIntent != null) { 5416 rec.key.requestIntent.replaceExtras(intents != null ? 5417 intents[intents.length - 1] : null); 5418 } 5419 if (intents != null) { 5420 intents[intents.length-1] = rec.key.requestIntent; 5421 rec.key.allIntents = intents; 5422 rec.key.allResolvedTypes = resolvedTypes; 5423 } else { 5424 rec.key.allIntents = null; 5425 rec.key.allResolvedTypes = null; 5426 } 5427 } 5428 return rec; 5429 } 5430 rec.canceled = true; 5431 mIntentSenderRecords.remove(key); 5432 } 5433 if (noCreate) { 5434 return rec; 5435 } 5436 rec = new PendingIntentRecord(this, key, callingUid); 5437 mIntentSenderRecords.put(key, rec.ref); 5438 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 5439 if (activity.pendingResults == null) { 5440 activity.pendingResults 5441 = new HashSet<WeakReference<PendingIntentRecord>>(); 5442 } 5443 activity.pendingResults.add(rec.ref); 5444 } 5445 return rec; 5446 } 5447 5448 @Override 5449 public void cancelIntentSender(IIntentSender sender) { 5450 if (!(sender instanceof PendingIntentRecord)) { 5451 return; 5452 } 5453 synchronized(this) { 5454 PendingIntentRecord rec = (PendingIntentRecord)sender; 5455 try { 5456 int uid = AppGlobals.getPackageManager() 5457 .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId()); 5458 if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) { 5459 String msg = "Permission Denial: cancelIntentSender() from pid=" 5460 + Binder.getCallingPid() 5461 + ", uid=" + Binder.getCallingUid() 5462 + " is not allowed to cancel packges " 5463 + rec.key.packageName; 5464 Slog.w(TAG, msg); 5465 throw new SecurityException(msg); 5466 } 5467 } catch (RemoteException e) { 5468 throw new SecurityException(e); 5469 } 5470 cancelIntentSenderLocked(rec, true); 5471 } 5472 } 5473 5474 void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) { 5475 rec.canceled = true; 5476 mIntentSenderRecords.remove(rec.key); 5477 if (cleanActivity && rec.key.activity != null) { 5478 rec.key.activity.pendingResults.remove(rec.ref); 5479 } 5480 } 5481 5482 @Override 5483 public String getPackageForIntentSender(IIntentSender pendingResult) { 5484 if (!(pendingResult instanceof PendingIntentRecord)) { 5485 return null; 5486 } 5487 try { 5488 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5489 return res.key.packageName; 5490 } catch (ClassCastException e) { 5491 } 5492 return null; 5493 } 5494 5495 @Override 5496 public int getUidForIntentSender(IIntentSender sender) { 5497 if (sender instanceof PendingIntentRecord) { 5498 try { 5499 PendingIntentRecord res = (PendingIntentRecord)sender; 5500 return res.uid; 5501 } catch (ClassCastException e) { 5502 } 5503 } 5504 return -1; 5505 } 5506 5507 @Override 5508 public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) { 5509 if (!(pendingResult instanceof PendingIntentRecord)) { 5510 return false; 5511 } 5512 try { 5513 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5514 if (res.key.allIntents == null) { 5515 return false; 5516 } 5517 for (int i=0; i<res.key.allIntents.length; i++) { 5518 Intent intent = res.key.allIntents[i]; 5519 if (intent.getPackage() != null && intent.getComponent() != null) { 5520 return false; 5521 } 5522 } 5523 return true; 5524 } catch (ClassCastException e) { 5525 } 5526 return false; 5527 } 5528 5529 @Override 5530 public boolean isIntentSenderAnActivity(IIntentSender pendingResult) { 5531 if (!(pendingResult instanceof PendingIntentRecord)) { 5532 return false; 5533 } 5534 try { 5535 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5536 if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) { 5537 return true; 5538 } 5539 return false; 5540 } catch (ClassCastException e) { 5541 } 5542 return false; 5543 } 5544 5545 @Override 5546 public Intent getIntentForIntentSender(IIntentSender pendingResult) { 5547 if (!(pendingResult instanceof PendingIntentRecord)) { 5548 return null; 5549 } 5550 try { 5551 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5552 return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null; 5553 } catch (ClassCastException e) { 5554 } 5555 return null; 5556 } 5557 5558 @Override 5559 public String getTagForIntentSender(IIntentSender pendingResult, String prefix) { 5560 if (!(pendingResult instanceof PendingIntentRecord)) { 5561 return null; 5562 } 5563 try { 5564 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5565 Intent intent = res.key.requestIntent; 5566 if (intent != null) { 5567 if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null 5568 || res.lastTagPrefix.equals(prefix))) { 5569 return res.lastTag; 5570 } 5571 res.lastTagPrefix = prefix; 5572 StringBuilder sb = new StringBuilder(128); 5573 if (prefix != null) { 5574 sb.append(prefix); 5575 } 5576 if (intent.getAction() != null) { 5577 sb.append(intent.getAction()); 5578 } else if (intent.getComponent() != null) { 5579 intent.getComponent().appendShortString(sb); 5580 } else { 5581 sb.append("?"); 5582 } 5583 return res.lastTag = sb.toString(); 5584 } 5585 } catch (ClassCastException e) { 5586 } 5587 return null; 5588 } 5589 5590 @Override 5591 public void setProcessLimit(int max) { 5592 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 5593 "setProcessLimit()"); 5594 synchronized (this) { 5595 mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max; 5596 mProcessLimitOverride = max; 5597 } 5598 trimApplications(); 5599 } 5600 5601 @Override 5602 public int getProcessLimit() { 5603 synchronized (this) { 5604 return mProcessLimitOverride; 5605 } 5606 } 5607 5608 void foregroundTokenDied(ForegroundToken token) { 5609 synchronized (ActivityManagerService.this) { 5610 synchronized (mPidsSelfLocked) { 5611 ForegroundToken cur 5612 = mForegroundProcesses.get(token.pid); 5613 if (cur != token) { 5614 return; 5615 } 5616 mForegroundProcesses.remove(token.pid); 5617 ProcessRecord pr = mPidsSelfLocked.get(token.pid); 5618 if (pr == null) { 5619 return; 5620 } 5621 pr.forcingToForeground = null; 5622 updateProcessForegroundLocked(pr, false, false); 5623 } 5624 updateOomAdjLocked(); 5625 } 5626 } 5627 5628 @Override 5629 public void setProcessForeground(IBinder token, int pid, boolean isForeground) { 5630 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 5631 "setProcessForeground()"); 5632 synchronized(this) { 5633 boolean changed = false; 5634 5635 synchronized (mPidsSelfLocked) { 5636 ProcessRecord pr = mPidsSelfLocked.get(pid); 5637 if (pr == null && isForeground) { 5638 Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid); 5639 return; 5640 } 5641 ForegroundToken oldToken = mForegroundProcesses.get(pid); 5642 if (oldToken != null) { 5643 oldToken.token.unlinkToDeath(oldToken, 0); 5644 mForegroundProcesses.remove(pid); 5645 if (pr != null) { 5646 pr.forcingToForeground = null; 5647 } 5648 changed = true; 5649 } 5650 if (isForeground && token != null) { 5651 ForegroundToken newToken = new ForegroundToken() { 5652 @Override 5653 public void binderDied() { 5654 foregroundTokenDied(this); 5655 } 5656 }; 5657 newToken.pid = pid; 5658 newToken.token = token; 5659 try { 5660 token.linkToDeath(newToken, 0); 5661 mForegroundProcesses.put(pid, newToken); 5662 pr.forcingToForeground = token; 5663 changed = true; 5664 } catch (RemoteException e) { 5665 // If the process died while doing this, we will later 5666 // do the cleanup with the process death link. 5667 } 5668 } 5669 } 5670 5671 if (changed) { 5672 updateOomAdjLocked(); 5673 } 5674 } 5675 } 5676 5677 // ========================================================= 5678 // PERMISSIONS 5679 // ========================================================= 5680 5681 static class PermissionController extends IPermissionController.Stub { 5682 ActivityManagerService mActivityManagerService; 5683 PermissionController(ActivityManagerService activityManagerService) { 5684 mActivityManagerService = activityManagerService; 5685 } 5686 5687 @Override 5688 public boolean checkPermission(String permission, int pid, int uid) { 5689 return mActivityManagerService.checkPermission(permission, pid, 5690 uid) == PackageManager.PERMISSION_GRANTED; 5691 } 5692 } 5693 5694 class IntentFirewallInterface implements IntentFirewall.AMSInterface { 5695 @Override 5696 public int checkComponentPermission(String permission, int pid, int uid, 5697 int owningUid, boolean exported) { 5698 return ActivityManagerService.this.checkComponentPermission(permission, pid, uid, 5699 owningUid, exported); 5700 } 5701 5702 @Override 5703 public Object getAMSLock() { 5704 return ActivityManagerService.this; 5705 } 5706 } 5707 5708 /** 5709 * This can be called with or without the global lock held. 5710 */ 5711 int checkComponentPermission(String permission, int pid, int uid, 5712 int owningUid, boolean exported) { 5713 // We might be performing an operation on behalf of an indirect binder 5714 // invocation, e.g. via {@link #openContentUri}. Check and adjust the 5715 // client identity accordingly before proceeding. 5716 Identity tlsIdentity = sCallerIdentity.get(); 5717 if (tlsIdentity != null) { 5718 Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {" 5719 + tlsIdentity.pid + "," + tlsIdentity.uid + "}"); 5720 uid = tlsIdentity.uid; 5721 pid = tlsIdentity.pid; 5722 } 5723 5724 if (pid == MY_PID) { 5725 return PackageManager.PERMISSION_GRANTED; 5726 } 5727 5728 return ActivityManager.checkComponentPermission(permission, uid, 5729 owningUid, exported); 5730 } 5731 5732 /** 5733 * As the only public entry point for permissions checking, this method 5734 * can enforce the semantic that requesting a check on a null global 5735 * permission is automatically denied. (Internally a null permission 5736 * string is used when calling {@link #checkComponentPermission} in cases 5737 * when only uid-based security is needed.) 5738 * 5739 * This can be called with or without the global lock held. 5740 */ 5741 @Override 5742 public int checkPermission(String permission, int pid, int uid) { 5743 if (permission == null) { 5744 return PackageManager.PERMISSION_DENIED; 5745 } 5746 return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true); 5747 } 5748 5749 /** 5750 * Binder IPC calls go through the public entry point. 5751 * This can be called with or without the global lock held. 5752 */ 5753 int checkCallingPermission(String permission) { 5754 return checkPermission(permission, 5755 Binder.getCallingPid(), 5756 UserHandle.getAppId(Binder.getCallingUid())); 5757 } 5758 5759 /** 5760 * This can be called with or without the global lock held. 5761 */ 5762 void enforceCallingPermission(String permission, String func) { 5763 if (checkCallingPermission(permission) 5764 == PackageManager.PERMISSION_GRANTED) { 5765 return; 5766 } 5767 5768 String msg = "Permission Denial: " + func + " from pid=" 5769 + Binder.getCallingPid() 5770 + ", uid=" + Binder.getCallingUid() 5771 + " requires " + permission; 5772 Slog.w(TAG, msg); 5773 throw new SecurityException(msg); 5774 } 5775 5776 /** 5777 * Determine if UID is holding permissions required to access {@link Uri} in 5778 * the given {@link ProviderInfo}. Final permission checking is always done 5779 * in {@link ContentProvider}. 5780 */ 5781 private final boolean checkHoldingPermissionsLocked( 5782 IPackageManager pm, ProviderInfo pi, Uri uri, int uid, int modeFlags) { 5783 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5784 "checkHoldingPermissionsLocked: uri=" + uri + " uid=" + uid); 5785 5786 if (pi.applicationInfo.uid == uid) { 5787 return true; 5788 } else if (!pi.exported) { 5789 return false; 5790 } 5791 5792 boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0; 5793 boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0; 5794 try { 5795 // check if target holds top-level <provider> permissions 5796 if (!readMet && pi.readPermission != null 5797 && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) { 5798 readMet = true; 5799 } 5800 if (!writeMet && pi.writePermission != null 5801 && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) { 5802 writeMet = true; 5803 } 5804 5805 // track if unprotected read/write is allowed; any denied 5806 // <path-permission> below removes this ability 5807 boolean allowDefaultRead = pi.readPermission == null; 5808 boolean allowDefaultWrite = pi.writePermission == null; 5809 5810 // check if target holds any <path-permission> that match uri 5811 final PathPermission[] pps = pi.pathPermissions; 5812 if (pps != null) { 5813 final String path = uri.getPath(); 5814 int i = pps.length; 5815 while (i > 0 && (!readMet || !writeMet)) { 5816 i--; 5817 PathPermission pp = pps[i]; 5818 if (pp.match(path)) { 5819 if (!readMet) { 5820 final String pprperm = pp.getReadPermission(); 5821 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for " 5822 + pprperm + " for " + pp.getPath() 5823 + ": match=" + pp.match(path) 5824 + " check=" + pm.checkUidPermission(pprperm, uid)); 5825 if (pprperm != null) { 5826 if (pm.checkUidPermission(pprperm, uid) == PERMISSION_GRANTED) { 5827 readMet = true; 5828 } else { 5829 allowDefaultRead = false; 5830 } 5831 } 5832 } 5833 if (!writeMet) { 5834 final String ppwperm = pp.getWritePermission(); 5835 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm " 5836 + ppwperm + " for " + pp.getPath() 5837 + ": match=" + pp.match(path) 5838 + " check=" + pm.checkUidPermission(ppwperm, uid)); 5839 if (ppwperm != null) { 5840 if (pm.checkUidPermission(ppwperm, uid) == PERMISSION_GRANTED) { 5841 writeMet = true; 5842 } else { 5843 allowDefaultWrite = false; 5844 } 5845 } 5846 } 5847 } 5848 } 5849 } 5850 5851 // grant unprotected <provider> read/write, if not blocked by 5852 // <path-permission> above 5853 if (allowDefaultRead) readMet = true; 5854 if (allowDefaultWrite) writeMet = true; 5855 5856 } catch (RemoteException e) { 5857 return false; 5858 } 5859 5860 return readMet && writeMet; 5861 } 5862 5863 private ProviderInfo getProviderInfoLocked(String authority, int userHandle) { 5864 ProviderInfo pi = null; 5865 ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle); 5866 if (cpr != null) { 5867 pi = cpr.info; 5868 } else { 5869 try { 5870 pi = AppGlobals.getPackageManager().resolveContentProvider( 5871 authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle); 5872 } catch (RemoteException ex) { 5873 } 5874 } 5875 return pi; 5876 } 5877 5878 private UriPermission findUriPermissionLocked(int targetUid, Uri uri) { 5879 ArrayMap<Uri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid); 5880 if (targetUris != null) { 5881 return targetUris.get(uri); 5882 } else { 5883 return null; 5884 } 5885 } 5886 5887 private UriPermission findOrCreateUriPermissionLocked( 5888 String sourcePkg, String targetPkg, int targetUid, Uri uri) { 5889 ArrayMap<Uri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid); 5890 if (targetUris == null) { 5891 targetUris = Maps.newArrayMap(); 5892 mGrantedUriPermissions.put(targetUid, targetUris); 5893 } 5894 5895 UriPermission perm = targetUris.get(uri); 5896 if (perm == null) { 5897 perm = new UriPermission(sourcePkg, targetPkg, targetUid, uri); 5898 targetUris.put(uri, perm); 5899 } 5900 5901 return perm; 5902 } 5903 5904 private final boolean checkUriPermissionLocked( 5905 Uri uri, int uid, int modeFlags, int minStrength) { 5906 // Root gets to do everything. 5907 if (uid == 0) { 5908 return true; 5909 } 5910 ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(uid); 5911 if (perms == null) return false; 5912 UriPermission perm = perms.get(uri); 5913 if (perm == null) return false; 5914 return perm.getStrength(modeFlags) >= minStrength; 5915 } 5916 5917 @Override 5918 public int checkUriPermission(Uri uri, int pid, int uid, int modeFlags) { 5919 enforceNotIsolatedCaller("checkUriPermission"); 5920 5921 // Another redirected-binder-call permissions check as in 5922 // {@link checkComponentPermission}. 5923 Identity tlsIdentity = sCallerIdentity.get(); 5924 if (tlsIdentity != null) { 5925 uid = tlsIdentity.uid; 5926 pid = tlsIdentity.pid; 5927 } 5928 5929 // Our own process gets to do everything. 5930 if (pid == MY_PID) { 5931 return PackageManager.PERMISSION_GRANTED; 5932 } 5933 synchronized(this) { 5934 return checkUriPermissionLocked(uri, uid, modeFlags, UriPermission.STRENGTH_OWNED) 5935 ? PackageManager.PERMISSION_GRANTED 5936 : PackageManager.PERMISSION_DENIED; 5937 } 5938 } 5939 5940 /** 5941 * Check if the targetPkg can be granted permission to access uri by 5942 * the callingUid using the given modeFlags. Throws a security exception 5943 * if callingUid is not allowed to do this. Returns the uid of the target 5944 * if the URI permission grant should be performed; returns -1 if it is not 5945 * needed (for example targetPkg already has permission to access the URI). 5946 * If you already know the uid of the target, you can supply it in 5947 * lastTargetUid else set that to -1. 5948 */ 5949 int checkGrantUriPermissionLocked(int callingUid, String targetPkg, 5950 Uri uri, int modeFlags, int lastTargetUid) { 5951 final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0; 5952 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION 5953 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 5954 if (modeFlags == 0) { 5955 return -1; 5956 } 5957 5958 if (targetPkg != null) { 5959 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5960 "Checking grant " + targetPkg + " permission to " + uri); 5961 } 5962 5963 final IPackageManager pm = AppGlobals.getPackageManager(); 5964 5965 // If this is not a content: uri, we can't do anything with it. 5966 if (!ContentResolver.SCHEME_CONTENT.equals(uri.getScheme())) { 5967 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5968 "Can't grant URI permission for non-content URI: " + uri); 5969 return -1; 5970 } 5971 5972 final String authority = uri.getAuthority(); 5973 final ProviderInfo pi = getProviderInfoLocked(authority, UserHandle.getUserId(callingUid)); 5974 if (pi == null) { 5975 Slog.w(TAG, "No content provider found for permission check: " + uri.toSafeString()); 5976 return -1; 5977 } 5978 5979 int targetUid = lastTargetUid; 5980 if (targetUid < 0 && targetPkg != null) { 5981 try { 5982 targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid)); 5983 if (targetUid < 0) { 5984 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5985 "Can't grant URI permission no uid for: " + targetPkg); 5986 return -1; 5987 } 5988 } catch (RemoteException ex) { 5989 return -1; 5990 } 5991 } 5992 5993 if (targetUid >= 0) { 5994 // First... does the target actually need this permission? 5995 if (checkHoldingPermissionsLocked(pm, pi, uri, targetUid, modeFlags)) { 5996 // No need to grant the target this permission. 5997 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5998 "Target " + targetPkg + " already has full permission to " + uri); 5999 return -1; 6000 } 6001 } else { 6002 // First... there is no target package, so can anyone access it? 6003 boolean allowed = pi.exported; 6004 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) { 6005 if (pi.readPermission != null) { 6006 allowed = false; 6007 } 6008 } 6009 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) { 6010 if (pi.writePermission != null) { 6011 allowed = false; 6012 } 6013 } 6014 if (allowed) { 6015 return -1; 6016 } 6017 } 6018 6019 // Second... is the provider allowing granting of URI permissions? 6020 if (!pi.grantUriPermissions) { 6021 throw new SecurityException("Provider " + pi.packageName 6022 + "/" + pi.name 6023 + " does not allow granting of Uri permissions (uri " 6024 + uri + ")"); 6025 } 6026 if (pi.uriPermissionPatterns != null) { 6027 final int N = pi.uriPermissionPatterns.length; 6028 boolean allowed = false; 6029 for (int i=0; i<N; i++) { 6030 if (pi.uriPermissionPatterns[i] != null 6031 && pi.uriPermissionPatterns[i].match(uri.getPath())) { 6032 allowed = true; 6033 break; 6034 } 6035 } 6036 if (!allowed) { 6037 throw new SecurityException("Provider " + pi.packageName 6038 + "/" + pi.name 6039 + " does not allow granting of permission to path of Uri " 6040 + uri); 6041 } 6042 } 6043 6044 // Third... does the caller itself have permission to access 6045 // this uri? 6046 if (callingUid != Process.myUid()) { 6047 if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) { 6048 // Require they hold a strong enough Uri permission 6049 final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE 6050 : UriPermission.STRENGTH_OWNED; 6051 if (!checkUriPermissionLocked(uri, callingUid, modeFlags, minStrength)) { 6052 throw new SecurityException("Uid " + callingUid 6053 + " does not have permission to uri " + uri); 6054 } 6055 } 6056 } 6057 6058 return targetUid; 6059 } 6060 6061 @Override 6062 public int checkGrantUriPermission(int callingUid, String targetPkg, 6063 Uri uri, int modeFlags) { 6064 enforceNotIsolatedCaller("checkGrantUriPermission"); 6065 synchronized(this) { 6066 return checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1); 6067 } 6068 } 6069 6070 void grantUriPermissionUncheckedLocked( 6071 int targetUid, String targetPkg, Uri uri, int modeFlags, UriPermissionOwner owner) { 6072 final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0; 6073 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION 6074 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 6075 if (modeFlags == 0) { 6076 return; 6077 } 6078 6079 // So here we are: the caller has the assumed permission 6080 // to the uri, and the target doesn't. Let's now give this to 6081 // the target. 6082 6083 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6084 "Granting " + targetPkg + "/" + targetUid + " permission to " + uri); 6085 6086 final String authority = uri.getAuthority(); 6087 final ProviderInfo pi = getProviderInfoLocked(authority, UserHandle.getUserId(targetUid)); 6088 if (pi == null) { 6089 Slog.w(TAG, "No content provider found for grant: " + uri.toSafeString()); 6090 return; 6091 } 6092 6093 final UriPermission perm = findOrCreateUriPermissionLocked( 6094 pi.packageName, targetPkg, targetUid, uri); 6095 perm.grantModes(modeFlags, persistable, owner); 6096 } 6097 6098 void grantUriPermissionLocked(int callingUid, String targetPkg, Uri uri, 6099 int modeFlags, UriPermissionOwner owner) { 6100 if (targetPkg == null) { 6101 throw new NullPointerException("targetPkg"); 6102 } 6103 6104 int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1); 6105 if (targetUid < 0) { 6106 return; 6107 } 6108 6109 grantUriPermissionUncheckedLocked(targetUid, targetPkg, uri, modeFlags, owner); 6110 } 6111 6112 static class NeededUriGrants extends ArrayList<Uri> { 6113 final String targetPkg; 6114 final int targetUid; 6115 final int flags; 6116 6117 NeededUriGrants(String targetPkg, int targetUid, int flags) { 6118 this.targetPkg = targetPkg; 6119 this.targetUid = targetUid; 6120 this.flags = flags; 6121 } 6122 } 6123 6124 /** 6125 * Like checkGrantUriPermissionLocked, but takes an Intent. 6126 */ 6127 NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid, 6128 String targetPkg, Intent intent, int mode, NeededUriGrants needed) { 6129 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6130 "Checking URI perm to data=" + (intent != null ? intent.getData() : null) 6131 + " clip=" + (intent != null ? intent.getClipData() : null) 6132 + " from " + intent + "; flags=0x" 6133 + Integer.toHexString(intent != null ? intent.getFlags() : 0)); 6134 6135 if (targetPkg == null) { 6136 throw new NullPointerException("targetPkg"); 6137 } 6138 6139 if (intent == null) { 6140 return null; 6141 } 6142 Uri data = intent.getData(); 6143 ClipData clip = intent.getClipData(); 6144 if (data == null && clip == null) { 6145 return null; 6146 } 6147 6148 if (data != null) { 6149 int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, data, 6150 mode, needed != null ? needed.targetUid : -1); 6151 if (targetUid > 0) { 6152 if (needed == null) { 6153 needed = new NeededUriGrants(targetPkg, targetUid, mode); 6154 } 6155 needed.add(data); 6156 } 6157 } 6158 if (clip != null) { 6159 for (int i=0; i<clip.getItemCount(); i++) { 6160 Uri uri = clip.getItemAt(i).getUri(); 6161 if (uri != null) { 6162 int targetUid = -1; 6163 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri, 6164 mode, needed != null ? needed.targetUid : -1); 6165 if (targetUid > 0) { 6166 if (needed == null) { 6167 needed = new NeededUriGrants(targetPkg, targetUid, mode); 6168 } 6169 needed.add(uri); 6170 } 6171 } else { 6172 Intent clipIntent = clip.getItemAt(i).getIntent(); 6173 if (clipIntent != null) { 6174 NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked( 6175 callingUid, targetPkg, clipIntent, mode, needed); 6176 if (newNeeded != null) { 6177 needed = newNeeded; 6178 } 6179 } 6180 } 6181 } 6182 } 6183 6184 return needed; 6185 } 6186 6187 /** 6188 * Like grantUriPermissionUncheckedLocked, but takes an Intent. 6189 */ 6190 void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed, 6191 UriPermissionOwner owner) { 6192 if (needed != null) { 6193 for (int i=0; i<needed.size(); i++) { 6194 grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg, 6195 needed.get(i), needed.flags, owner); 6196 } 6197 } 6198 } 6199 6200 void grantUriPermissionFromIntentLocked(int callingUid, 6201 String targetPkg, Intent intent, UriPermissionOwner owner) { 6202 NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg, 6203 intent, intent != null ? intent.getFlags() : 0, null); 6204 if (needed == null) { 6205 return; 6206 } 6207 6208 grantUriPermissionUncheckedFromIntentLocked(needed, owner); 6209 } 6210 6211 @Override 6212 public void grantUriPermission(IApplicationThread caller, String targetPkg, 6213 Uri uri, int modeFlags) { 6214 enforceNotIsolatedCaller("grantUriPermission"); 6215 synchronized(this) { 6216 final ProcessRecord r = getRecordForAppLocked(caller); 6217 if (r == null) { 6218 throw new SecurityException("Unable to find app for caller " 6219 + caller 6220 + " when granting permission to uri " + uri); 6221 } 6222 if (targetPkg == null) { 6223 throw new IllegalArgumentException("null target"); 6224 } 6225 if (uri == null) { 6226 throw new IllegalArgumentException("null uri"); 6227 } 6228 6229 // Persistable only supported through Intents 6230 Preconditions.checkFlagsArgument(modeFlags, 6231 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 6232 6233 grantUriPermissionLocked(r.uid, targetPkg, uri, modeFlags, 6234 null); 6235 } 6236 } 6237 6238 void removeUriPermissionIfNeededLocked(UriPermission perm) { 6239 if ((perm.modeFlags&(Intent.FLAG_GRANT_READ_URI_PERMISSION 6240 |Intent.FLAG_GRANT_WRITE_URI_PERMISSION)) == 0) { 6241 ArrayMap<Uri, UriPermission> perms 6242 = mGrantedUriPermissions.get(perm.targetUid); 6243 if (perms != null) { 6244 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6245 "Removing " + perm.targetUid + " permission to " + perm.uri); 6246 perms.remove(perm.uri); 6247 if (perms.size() == 0) { 6248 mGrantedUriPermissions.remove(perm.targetUid); 6249 } 6250 } 6251 } 6252 } 6253 6254 private void revokeUriPermissionLocked(int callingUid, Uri uri, int modeFlags) { 6255 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + uri); 6256 6257 final IPackageManager pm = AppGlobals.getPackageManager(); 6258 final String authority = uri.getAuthority(); 6259 final ProviderInfo pi = getProviderInfoLocked(authority, UserHandle.getUserId(callingUid)); 6260 if (pi == null) { 6261 Slog.w(TAG, "No content provider found for permission revoke: " + uri.toSafeString()); 6262 return; 6263 } 6264 6265 // Does the caller have this permission on the URI? 6266 if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) { 6267 // Right now, if you are not the original owner of the permission, 6268 // you are not allowed to revoke it. 6269 //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) { 6270 throw new SecurityException("Uid " + callingUid 6271 + " does not have permission to uri " + uri); 6272 //} 6273 } 6274 6275 boolean persistChanged = false; 6276 6277 // Go through all of the permissions and remove any that match. 6278 final List<String> SEGMENTS = uri.getPathSegments(); 6279 if (SEGMENTS != null) { 6280 final int NS = SEGMENTS.size(); 6281 int N = mGrantedUriPermissions.size(); 6282 for (int i=0; i<N; i++) { 6283 ArrayMap<Uri, UriPermission> perms 6284 = mGrantedUriPermissions.valueAt(i); 6285 Iterator<UriPermission> it = perms.values().iterator(); 6286 toploop: 6287 while (it.hasNext()) { 6288 UriPermission perm = it.next(); 6289 Uri targetUri = perm.uri; 6290 if (!authority.equals(targetUri.getAuthority())) { 6291 continue; 6292 } 6293 List<String> targetSegments = targetUri.getPathSegments(); 6294 if (targetSegments == null) { 6295 continue; 6296 } 6297 if (targetSegments.size() < NS) { 6298 continue; 6299 } 6300 for (int j=0; j<NS; j++) { 6301 if (!SEGMENTS.get(j).equals(targetSegments.get(j))) { 6302 continue toploop; 6303 } 6304 } 6305 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6306 "Revoking " + perm.targetUid + " permission to " + perm.uri); 6307 persistChanged |= perm.clearModes(modeFlags, true); 6308 if (perm.modeFlags == 0) { 6309 it.remove(); 6310 } 6311 } 6312 if (perms.size() == 0) { 6313 mGrantedUriPermissions.remove( 6314 mGrantedUriPermissions.keyAt(i)); 6315 N--; 6316 i--; 6317 } 6318 } 6319 } 6320 6321 if (persistChanged) { 6322 schedulePersistUriGrants(); 6323 } 6324 } 6325 6326 @Override 6327 public void revokeUriPermission(IApplicationThread caller, Uri uri, 6328 int modeFlags) { 6329 enforceNotIsolatedCaller("revokeUriPermission"); 6330 synchronized(this) { 6331 final ProcessRecord r = getRecordForAppLocked(caller); 6332 if (r == null) { 6333 throw new SecurityException("Unable to find app for caller " 6334 + caller 6335 + " when revoking permission to uri " + uri); 6336 } 6337 if (uri == null) { 6338 Slog.w(TAG, "revokeUriPermission: null uri"); 6339 return; 6340 } 6341 6342 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION 6343 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 6344 if (modeFlags == 0) { 6345 return; 6346 } 6347 6348 final IPackageManager pm = AppGlobals.getPackageManager(); 6349 final String authority = uri.getAuthority(); 6350 final ProviderInfo pi = getProviderInfoLocked(authority, r.userId); 6351 if (pi == null) { 6352 Slog.w(TAG, "No content provider found for permission revoke: " 6353 + uri.toSafeString()); 6354 return; 6355 } 6356 6357 revokeUriPermissionLocked(r.uid, uri, modeFlags); 6358 } 6359 } 6360 6361 /** 6362 * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the 6363 * given package. 6364 * 6365 * @param packageName Package name to match, or {@code null} to apply to all 6366 * packages. 6367 * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply 6368 * to all users. 6369 * @param persistable If persistable grants should be removed. 6370 */ 6371 private void removeUriPermissionsForPackageLocked( 6372 String packageName, int userHandle, boolean persistable) { 6373 if (userHandle == UserHandle.USER_ALL && packageName == null) { 6374 throw new IllegalArgumentException("Must narrow by either package or user"); 6375 } 6376 6377 boolean persistChanged = false; 6378 6379 final int size = mGrantedUriPermissions.size(); 6380 for (int i = 0; i < size; i++) { 6381 // Only inspect grants matching user 6382 if (userHandle == UserHandle.USER_ALL 6383 || userHandle == UserHandle.getUserId(mGrantedUriPermissions.keyAt(i))) { 6384 final Iterator<UriPermission> it = mGrantedUriPermissions.valueAt(i) 6385 .values().iterator(); 6386 while (it.hasNext()) { 6387 final UriPermission perm = it.next(); 6388 6389 // Only inspect grants matching package 6390 if (packageName == null || perm.sourcePkg.equals(packageName) 6391 || perm.targetPkg.equals(packageName)) { 6392 persistChanged |= perm.clearModes(~0, persistable); 6393 6394 // Only remove when no modes remain; any persisted grants 6395 // will keep this alive. 6396 if (perm.modeFlags == 0) { 6397 it.remove(); 6398 } 6399 } 6400 } 6401 } 6402 } 6403 6404 if (persistChanged) { 6405 schedulePersistUriGrants(); 6406 } 6407 } 6408 6409 @Override 6410 public IBinder newUriPermissionOwner(String name) { 6411 enforceNotIsolatedCaller("newUriPermissionOwner"); 6412 synchronized(this) { 6413 UriPermissionOwner owner = new UriPermissionOwner(this, name); 6414 return owner.getExternalTokenLocked(); 6415 } 6416 } 6417 6418 @Override 6419 public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, 6420 Uri uri, int modeFlags) { 6421 synchronized(this) { 6422 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 6423 if (owner == null) { 6424 throw new IllegalArgumentException("Unknown owner: " + token); 6425 } 6426 if (fromUid != Binder.getCallingUid()) { 6427 if (Binder.getCallingUid() != Process.myUid()) { 6428 // Only system code can grant URI permissions on behalf 6429 // of other users. 6430 throw new SecurityException("nice try"); 6431 } 6432 } 6433 if (targetPkg == null) { 6434 throw new IllegalArgumentException("null target"); 6435 } 6436 if (uri == null) { 6437 throw new IllegalArgumentException("null uri"); 6438 } 6439 6440 grantUriPermissionLocked(fromUid, targetPkg, uri, modeFlags, owner); 6441 } 6442 } 6443 6444 @Override 6445 public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode) { 6446 synchronized(this) { 6447 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 6448 if (owner == null) { 6449 throw new IllegalArgumentException("Unknown owner: " + token); 6450 } 6451 6452 if (uri == null) { 6453 owner.removeUriPermissionsLocked(mode); 6454 } else { 6455 owner.removeUriPermissionLocked(uri, mode); 6456 } 6457 } 6458 } 6459 6460 private void schedulePersistUriGrants() { 6461 if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) { 6462 mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG), 6463 10 * DateUtils.SECOND_IN_MILLIS); 6464 } 6465 } 6466 6467 private void writeGrantedUriPermissions() { 6468 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()"); 6469 6470 // Snapshot permissions so we can persist without lock 6471 ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList(); 6472 synchronized (this) { 6473 final int size = mGrantedUriPermissions.size(); 6474 for (int i = 0 ; i < size; i++) { 6475 for (UriPermission perm : mGrantedUriPermissions.valueAt(i).values()) { 6476 if (perm.persistedModeFlags != 0) { 6477 persist.add(perm.snapshot()); 6478 } 6479 } 6480 } 6481 } 6482 6483 FileOutputStream fos = null; 6484 try { 6485 fos = mGrantFile.startWrite(); 6486 6487 XmlSerializer out = new FastXmlSerializer(); 6488 out.setOutput(fos, "utf-8"); 6489 out.startDocument(null, true); 6490 out.startTag(null, TAG_URI_GRANTS); 6491 for (UriPermission.Snapshot perm : persist) { 6492 out.startTag(null, TAG_URI_GRANT); 6493 writeIntAttribute(out, ATTR_USER_HANDLE, perm.userHandle); 6494 out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg); 6495 out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg); 6496 out.attribute(null, ATTR_URI, String.valueOf(perm.uri)); 6497 writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags); 6498 writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime); 6499 out.endTag(null, TAG_URI_GRANT); 6500 } 6501 out.endTag(null, TAG_URI_GRANTS); 6502 out.endDocument(); 6503 6504 mGrantFile.finishWrite(fos); 6505 } catch (IOException e) { 6506 if (fos != null) { 6507 mGrantFile.failWrite(fos); 6508 } 6509 } 6510 } 6511 6512 private void readGrantedUriPermissionsLocked() { 6513 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()"); 6514 6515 final long now = System.currentTimeMillis(); 6516 6517 FileInputStream fis = null; 6518 try { 6519 fis = mGrantFile.openRead(); 6520 final XmlPullParser in = Xml.newPullParser(); 6521 in.setInput(fis, null); 6522 6523 int type; 6524 while ((type = in.next()) != END_DOCUMENT) { 6525 final String tag = in.getName(); 6526 if (type == START_TAG) { 6527 if (TAG_URI_GRANT.equals(tag)) { 6528 final int userHandle = readIntAttribute(in, ATTR_USER_HANDLE); 6529 final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG); 6530 final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG); 6531 final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI)); 6532 final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS); 6533 final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now); 6534 6535 // Sanity check that provider still belongs to source package 6536 final ProviderInfo pi = getProviderInfoLocked( 6537 uri.getAuthority(), userHandle); 6538 if (pi != null && sourcePkg.equals(pi.packageName)) { 6539 int targetUid = -1; 6540 try { 6541 targetUid = AppGlobals.getPackageManager() 6542 .getPackageUid(targetPkg, userHandle); 6543 } catch (RemoteException e) { 6544 } 6545 if (targetUid != -1) { 6546 final UriPermission perm = findOrCreateUriPermissionLocked( 6547 sourcePkg, targetPkg, targetUid, uri); 6548 perm.initPersistedModes(modeFlags, createdTime); 6549 } 6550 } else { 6551 Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg 6552 + " but instead found " + pi); 6553 } 6554 } 6555 } 6556 } 6557 } catch (FileNotFoundException e) { 6558 // Missing grants is okay 6559 } catch (IOException e) { 6560 Log.wtf(TAG, "Failed reading Uri grants", e); 6561 } catch (XmlPullParserException e) { 6562 Log.wtf(TAG, "Failed reading Uri grants", e); 6563 } finally { 6564 IoUtils.closeQuietly(fis); 6565 } 6566 } 6567 6568 @Override 6569 public void takePersistableUriPermission(Uri uri, int modeFlags) { 6570 enforceNotIsolatedCaller("takePersistableUriPermission"); 6571 6572 Preconditions.checkFlagsArgument(modeFlags, 6573 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 6574 6575 synchronized (this) { 6576 final int callingUid = Binder.getCallingUid(); 6577 final UriPermission perm = findUriPermissionLocked(callingUid, uri); 6578 if (perm == null) { 6579 throw new SecurityException("No permission grant found for UID " + callingUid 6580 + " and Uri " + uri.toSafeString()); 6581 } 6582 6583 boolean persistChanged = perm.takePersistableModes(modeFlags); 6584 persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid); 6585 6586 if (persistChanged) { 6587 schedulePersistUriGrants(); 6588 } 6589 } 6590 } 6591 6592 @Override 6593 public void releasePersistableUriPermission(Uri uri, int modeFlags) { 6594 enforceNotIsolatedCaller("releasePersistableUriPermission"); 6595 6596 Preconditions.checkFlagsArgument(modeFlags, 6597 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 6598 6599 synchronized (this) { 6600 final int callingUid = Binder.getCallingUid(); 6601 6602 final UriPermission perm = findUriPermissionLocked(callingUid, uri); 6603 if (perm == null) { 6604 Slog.w(TAG, "No permission grant found for UID " + callingUid + " and Uri " 6605 + uri.toSafeString()); 6606 return; 6607 } 6608 6609 final boolean persistChanged = perm.releasePersistableModes(modeFlags); 6610 removeUriPermissionIfNeededLocked(perm); 6611 if (persistChanged) { 6612 schedulePersistUriGrants(); 6613 } 6614 } 6615 } 6616 6617 /** 6618 * Prune any older {@link UriPermission} for the given UID until outstanding 6619 * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}. 6620 * 6621 * @return if any mutations occured that require persisting. 6622 */ 6623 private boolean maybePrunePersistedUriGrantsLocked(int uid) { 6624 final ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(uid); 6625 if (perms == null) return false; 6626 if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false; 6627 6628 final ArrayList<UriPermission> persisted = Lists.newArrayList(); 6629 for (UriPermission perm : perms.values()) { 6630 if (perm.persistedModeFlags != 0) { 6631 persisted.add(perm); 6632 } 6633 } 6634 6635 final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS; 6636 if (trimCount <= 0) return false; 6637 6638 Collections.sort(persisted, new UriPermission.PersistedTimeComparator()); 6639 for (int i = 0; i < trimCount; i++) { 6640 final UriPermission perm = persisted.get(i); 6641 6642 if (DEBUG_URI_PERMISSION) { 6643 Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime); 6644 } 6645 6646 perm.releasePersistableModes(~0); 6647 removeUriPermissionIfNeededLocked(perm); 6648 } 6649 6650 return true; 6651 } 6652 6653 @Override 6654 public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions( 6655 String packageName, boolean incoming) { 6656 enforceNotIsolatedCaller("getPersistedUriPermissions"); 6657 Preconditions.checkNotNull(packageName, "packageName"); 6658 6659 final int callingUid = Binder.getCallingUid(); 6660 final IPackageManager pm = AppGlobals.getPackageManager(); 6661 try { 6662 final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid)); 6663 if (packageUid != callingUid) { 6664 throw new SecurityException( 6665 "Package " + packageName + " does not belong to calling UID " + callingUid); 6666 } 6667 } catch (RemoteException e) { 6668 throw new SecurityException("Failed to verify package name ownership"); 6669 } 6670 6671 final ArrayList<android.content.UriPermission> result = Lists.newArrayList(); 6672 synchronized (this) { 6673 if (incoming) { 6674 final ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(callingUid); 6675 if (perms == null) { 6676 Slog.w(TAG, "No permission grants found for " + packageName); 6677 } else { 6678 final int size = perms.size(); 6679 for (int i = 0; i < size; i++) { 6680 final UriPermission perm = perms.valueAt(i); 6681 if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) { 6682 result.add(perm.buildPersistedPublicApiObject()); 6683 } 6684 } 6685 } 6686 } else { 6687 final int size = mGrantedUriPermissions.size(); 6688 for (int i = 0; i < size; i++) { 6689 final ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 6690 final int permsSize = perms.size(); 6691 for (int j = 0; j < permsSize; j++) { 6692 final UriPermission perm = perms.valueAt(j); 6693 if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) { 6694 result.add(perm.buildPersistedPublicApiObject()); 6695 } 6696 } 6697 } 6698 } 6699 } 6700 return new ParceledListSlice<android.content.UriPermission>(result); 6701 } 6702 6703 @Override 6704 public void showWaitingForDebugger(IApplicationThread who, boolean waiting) { 6705 synchronized (this) { 6706 ProcessRecord app = 6707 who != null ? getRecordForAppLocked(who) : null; 6708 if (app == null) return; 6709 6710 Message msg = Message.obtain(); 6711 msg.what = WAIT_FOR_DEBUGGER_MSG; 6712 msg.obj = app; 6713 msg.arg1 = waiting ? 1 : 0; 6714 mHandler.sendMessage(msg); 6715 } 6716 } 6717 6718 @Override 6719 public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) { 6720 final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ); 6721 final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ); 6722 outInfo.availMem = Process.getFreeMemory(); 6723 outInfo.totalMem = Process.getTotalMemory(); 6724 outInfo.threshold = homeAppMem; 6725 outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2)); 6726 outInfo.hiddenAppThreshold = cachedAppMem; 6727 outInfo.secondaryServerThreshold = mProcessList.getMemLevel( 6728 ProcessList.SERVICE_ADJ); 6729 outInfo.visibleAppThreshold = mProcessList.getMemLevel( 6730 ProcessList.VISIBLE_APP_ADJ); 6731 outInfo.foregroundAppThreshold = mProcessList.getMemLevel( 6732 ProcessList.FOREGROUND_APP_ADJ); 6733 } 6734 6735 // ========================================================= 6736 // TASK MANAGEMENT 6737 // ========================================================= 6738 6739 @Override 6740 public List<RunningTaskInfo> getTasks(int maxNum, int flags, 6741 IThumbnailReceiver receiver) { 6742 ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>(); 6743 6744 PendingThumbnailsRecord pending = new PendingThumbnailsRecord(receiver); 6745 ActivityRecord topRecord = null; 6746 6747 synchronized(this) { 6748 if (localLOGV) Slog.v( 6749 TAG, "getTasks: max=" + maxNum + ", flags=" + flags 6750 + ", receiver=" + receiver); 6751 6752 if (checkCallingPermission(android.Manifest.permission.GET_TASKS) 6753 != PackageManager.PERMISSION_GRANTED) { 6754 if (receiver != null) { 6755 // If the caller wants to wait for pending thumbnails, 6756 // it ain't gonna get them. 6757 try { 6758 receiver.finished(); 6759 } catch (RemoteException ex) { 6760 } 6761 } 6762 String msg = "Permission Denial: getTasks() from pid=" 6763 + Binder.getCallingPid() 6764 + ", uid=" + Binder.getCallingUid() 6765 + " requires " + android.Manifest.permission.GET_TASKS; 6766 Slog.w(TAG, msg); 6767 throw new SecurityException(msg); 6768 } 6769 6770 // TODO: Improve with MRU list from all ActivityStacks. 6771 topRecord = mStackSupervisor.getTasksLocked(maxNum, receiver, pending, list); 6772 6773 if (!pending.pendingRecords.isEmpty()) { 6774 mPendingThumbnails.add(pending); 6775 } 6776 } 6777 6778 if (localLOGV) Slog.v(TAG, "We have pending thumbnails: " + pending); 6779 6780 if (topRecord != null) { 6781 if (localLOGV) Slog.v(TAG, "Requesting top thumbnail"); 6782 try { 6783 IApplicationThread topThumbnail = topRecord.app.thread; 6784 topThumbnail.requestThumbnail(topRecord.appToken); 6785 } catch (Exception e) { 6786 Slog.w(TAG, "Exception thrown when requesting thumbnail", e); 6787 sendPendingThumbnail(null, topRecord.appToken, null, null, true); 6788 } 6789 } 6790 6791 if (pending == null && receiver != null) { 6792 // In this case all thumbnails were available and the client 6793 // is being asked to be told when the remaining ones come in... 6794 // which is unusually, since the top-most currently running 6795 // activity should never have a canned thumbnail! Oh well. 6796 try { 6797 receiver.finished(); 6798 } catch (RemoteException ex) { 6799 } 6800 } 6801 6802 return list; 6803 } 6804 6805 TaskRecord getMostRecentTask() { 6806 return mRecentTasks.get(0); 6807 } 6808 6809 @Override 6810 public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, 6811 int flags, int userId) { 6812 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 6813 false, true, "getRecentTasks", null); 6814 6815 synchronized (this) { 6816 enforceCallingPermission(android.Manifest.permission.GET_TASKS, 6817 "getRecentTasks()"); 6818 final boolean detailed = checkCallingPermission( 6819 android.Manifest.permission.GET_DETAILED_TASKS) 6820 == PackageManager.PERMISSION_GRANTED; 6821 6822 IPackageManager pm = AppGlobals.getPackageManager(); 6823 6824 final int N = mRecentTasks.size(); 6825 ArrayList<ActivityManager.RecentTaskInfo> res 6826 = new ArrayList<ActivityManager.RecentTaskInfo>( 6827 maxNum < N ? maxNum : N); 6828 for (int i=0; i<N && maxNum > 0; i++) { 6829 TaskRecord tr = mRecentTasks.get(i); 6830 // Only add calling user's recent tasks 6831 if (tr.userId != userId) continue; 6832 // Return the entry if desired by the caller. We always return 6833 // the first entry, because callers always expect this to be the 6834 // foreground app. We may filter others if the caller has 6835 // not supplied RECENT_WITH_EXCLUDED and there is some reason 6836 // we should exclude the entry. 6837 6838 if (i == 0 6839 || ((flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0) 6840 || (tr.intent == null) 6841 || ((tr.intent.getFlags() 6842 &Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0)) { 6843 ActivityManager.RecentTaskInfo rti 6844 = new ActivityManager.RecentTaskInfo(); 6845 rti.id = tr.numActivities > 0 ? tr.taskId : -1; 6846 rti.persistentId = tr.taskId; 6847 rti.baseIntent = new Intent( 6848 tr.intent != null ? tr.intent : tr.affinityIntent); 6849 if (!detailed) { 6850 rti.baseIntent.replaceExtras((Bundle)null); 6851 } 6852 rti.origActivity = tr.origActivity; 6853 rti.description = tr.lastDescription; 6854 rti.stackId = tr.stack.mStackId; 6855 6856 if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) { 6857 // Check whether this activity is currently available. 6858 try { 6859 if (rti.origActivity != null) { 6860 if (pm.getActivityInfo(rti.origActivity, 0, userId) 6861 == null) { 6862 continue; 6863 } 6864 } else if (rti.baseIntent != null) { 6865 if (pm.queryIntentActivities(rti.baseIntent, 6866 null, 0, userId) == null) { 6867 continue; 6868 } 6869 } 6870 } catch (RemoteException e) { 6871 // Will never happen. 6872 } 6873 } 6874 6875 res.add(rti); 6876 maxNum--; 6877 } 6878 } 6879 return res; 6880 } 6881 } 6882 6883 private TaskRecord recentTaskForIdLocked(int id) { 6884 final int N = mRecentTasks.size(); 6885 for (int i=0; i<N; i++) { 6886 TaskRecord tr = mRecentTasks.get(i); 6887 if (tr.taskId == id) { 6888 return tr; 6889 } 6890 } 6891 return null; 6892 } 6893 6894 @Override 6895 public ActivityManager.TaskThumbnails getTaskThumbnails(int id) { 6896 synchronized (this) { 6897 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER, 6898 "getTaskThumbnails()"); 6899 TaskRecord tr = recentTaskForIdLocked(id); 6900 if (tr != null) { 6901 return tr.getTaskThumbnailsLocked(); 6902 } 6903 } 6904 return null; 6905 } 6906 6907 @Override 6908 public Bitmap getTaskTopThumbnail(int id) { 6909 synchronized (this) { 6910 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER, 6911 "getTaskTopThumbnail()"); 6912 TaskRecord tr = recentTaskForIdLocked(id); 6913 if (tr != null) { 6914 return tr.getTaskTopThumbnailLocked(); 6915 } 6916 } 6917 return null; 6918 } 6919 6920 @Override 6921 public boolean removeSubTask(int taskId, int subTaskIndex) { 6922 synchronized (this) { 6923 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, 6924 "removeSubTask()"); 6925 long ident = Binder.clearCallingIdentity(); 6926 try { 6927 TaskRecord tr = recentTaskForIdLocked(taskId); 6928 if (tr != null) { 6929 return tr.removeTaskActivitiesLocked(subTaskIndex, true) != null; 6930 } 6931 return false; 6932 } finally { 6933 Binder.restoreCallingIdentity(ident); 6934 } 6935 } 6936 } 6937 6938 private void killUnneededProcessLocked(ProcessRecord pr, String reason) { 6939 if (!pr.killedByAm) { 6940 Slog.i(TAG, "Killing " + pr.toShortString() + " (adj " + pr.setAdj + "): " + reason); 6941 EventLog.writeEvent(EventLogTags.AM_KILL, pr.userId, pr.pid, 6942 pr.processName, pr.setAdj, reason); 6943 pr.killedByAm = true; 6944 Process.killProcessQuiet(pr.pid); 6945 } 6946 } 6947 6948 private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) { 6949 tr.disposeThumbnail(); 6950 mRecentTasks.remove(tr); 6951 final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0; 6952 Intent baseIntent = new Intent( 6953 tr.intent != null ? tr.intent : tr.affinityIntent); 6954 ComponentName component = baseIntent.getComponent(); 6955 if (component == null) { 6956 Slog.w(TAG, "Now component for base intent of task: " + tr); 6957 return; 6958 } 6959 6960 // Find any running services associated with this app. 6961 mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent); 6962 6963 if (killProcesses) { 6964 // Find any running processes associated with this app. 6965 final String pkg = component.getPackageName(); 6966 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 6967 ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap(); 6968 for (int i=0; i<pmap.size(); i++) { 6969 SparseArray<ProcessRecord> uids = pmap.valueAt(i); 6970 for (int j=0; j<uids.size(); j++) { 6971 ProcessRecord proc = uids.valueAt(j); 6972 if (proc.userId != tr.userId) { 6973 continue; 6974 } 6975 if (!proc.pkgList.containsKey(pkg)) { 6976 continue; 6977 } 6978 procs.add(proc); 6979 } 6980 } 6981 6982 // Kill the running processes. 6983 for (int i=0; i<procs.size(); i++) { 6984 ProcessRecord pr = procs.get(i); 6985 if (pr == mHomeProcess) { 6986 // Don't kill the home process along with tasks from the same package. 6987 continue; 6988 } 6989 if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 6990 killUnneededProcessLocked(pr, "remove task"); 6991 } else { 6992 pr.waitingToKill = "remove task"; 6993 } 6994 } 6995 } 6996 } 6997 6998 @Override 6999 public boolean removeTask(int taskId, int flags) { 7000 synchronized (this) { 7001 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, 7002 "removeTask()"); 7003 long ident = Binder.clearCallingIdentity(); 7004 try { 7005 TaskRecord tr = recentTaskForIdLocked(taskId); 7006 if (tr != null) { 7007 ActivityRecord r = tr.removeTaskActivitiesLocked(-1, false); 7008 if (r != null) { 7009 cleanUpRemovedTaskLocked(tr, flags); 7010 return true; 7011 } 7012 if (tr.mActivities.size() == 0) { 7013 // Caller is just removing a recent task that is 7014 // not actively running. That is easy! 7015 cleanUpRemovedTaskLocked(tr, flags); 7016 return true; 7017 } 7018 Slog.w(TAG, "removeTask: task " + taskId 7019 + " does not have activities to remove, " 7020 + " but numActivities=" + tr.numActivities 7021 + ": " + tr); 7022 } 7023 } finally { 7024 Binder.restoreCallingIdentity(ident); 7025 } 7026 } 7027 return false; 7028 } 7029 7030 /** 7031 * TODO: Add mController hook 7032 */ 7033 @Override 7034 public void moveTaskToFront(int task, int flags, Bundle options) { 7035 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 7036 "moveTaskToFront()"); 7037 7038 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving task=" + task); 7039 synchronized(this) { 7040 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 7041 Binder.getCallingUid(), "Task to front")) { 7042 ActivityOptions.abort(options); 7043 return; 7044 } 7045 final long origId = Binder.clearCallingIdentity(); 7046 try { 7047 mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options); 7048 } finally { 7049 Binder.restoreCallingIdentity(origId); 7050 } 7051 ActivityOptions.abort(options); 7052 } 7053 } 7054 7055 @Override 7056 public void moveTaskToBack(int taskId) { 7057 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 7058 "moveTaskToBack()"); 7059 7060 synchronized(this) { 7061 TaskRecord tr = recentTaskForIdLocked(taskId); 7062 if (tr != null) { 7063 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr); 7064 ActivityStack stack = tr.stack; 7065 if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) { 7066 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 7067 Binder.getCallingUid(), "Task to back")) { 7068 return; 7069 } 7070 } 7071 final long origId = Binder.clearCallingIdentity(); 7072 try { 7073 stack.moveTaskToBackLocked(taskId, null); 7074 } finally { 7075 Binder.restoreCallingIdentity(origId); 7076 } 7077 } 7078 } 7079 } 7080 7081 /** 7082 * Moves an activity, and all of the other activities within the same task, to the bottom 7083 * of the history stack. The activity's order within the task is unchanged. 7084 * 7085 * @param token A reference to the activity we wish to move 7086 * @param nonRoot If false then this only works if the activity is the root 7087 * of a task; if true it will work for any activity in a task. 7088 * @return Returns true if the move completed, false if not. 7089 */ 7090 @Override 7091 public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) { 7092 enforceNotIsolatedCaller("moveActivityTaskToBack"); 7093 synchronized(this) { 7094 final long origId = Binder.clearCallingIdentity(); 7095 int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot); 7096 if (taskId >= 0) { 7097 return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null); 7098 } 7099 Binder.restoreCallingIdentity(origId); 7100 } 7101 return false; 7102 } 7103 7104 @Override 7105 public void moveTaskBackwards(int task) { 7106 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 7107 "moveTaskBackwards()"); 7108 7109 synchronized(this) { 7110 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 7111 Binder.getCallingUid(), "Task backwards")) { 7112 return; 7113 } 7114 final long origId = Binder.clearCallingIdentity(); 7115 moveTaskBackwardsLocked(task); 7116 Binder.restoreCallingIdentity(origId); 7117 } 7118 } 7119 7120 private final void moveTaskBackwardsLocked(int task) { 7121 Slog.e(TAG, "moveTaskBackwards not yet implemented!"); 7122 } 7123 7124 @Override 7125 public IBinder getHomeActivityToken() throws RemoteException { 7126 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7127 "getHomeActivityToken()"); 7128 synchronized (this) { 7129 return mStackSupervisor.getHomeActivityToken(); 7130 } 7131 } 7132 7133 @Override 7134 public IActivityContainer createActivityContainer(IBinder parentActivityToken, 7135 IActivityContainerCallback callback) throws RemoteException { 7136 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7137 "createActivityContainer()"); 7138 synchronized (this) { 7139 if (parentActivityToken == null) { 7140 throw new IllegalArgumentException("parent token must not be null"); 7141 } 7142 ActivityRecord r = ActivityRecord.forToken(parentActivityToken); 7143 if (r == null) { 7144 return null; 7145 } 7146 return mStackSupervisor.createActivityContainer(r, callback); 7147 } 7148 } 7149 7150 @Override 7151 public void deleteActivityContainer(IActivityContainer container) throws RemoteException { 7152 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7153 "deleteActivityContainer()"); 7154 synchronized (this) { 7155 mStackSupervisor.deleteActivityContainer(container); 7156 } 7157 } 7158 7159 @Override 7160 public IActivityContainer getEnclosingActivityContainer(IBinder activityToken) 7161 throws RemoteException { 7162 synchronized (this) { 7163 ActivityStack stack = ActivityRecord.getStackLocked(activityToken); 7164 if (stack != null) { 7165 return stack.mActivityContainer; 7166 } 7167 return null; 7168 } 7169 } 7170 7171 @Override 7172 public void moveTaskToStack(int taskId, int stackId, boolean toTop) { 7173 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7174 "moveTaskToStack()"); 7175 if (stackId == HOME_STACK_ID) { 7176 Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack", 7177 new RuntimeException("here").fillInStackTrace()); 7178 } 7179 synchronized (this) { 7180 long ident = Binder.clearCallingIdentity(); 7181 try { 7182 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId=" 7183 + stackId + " toTop=" + toTop); 7184 mStackSupervisor.moveTaskToStack(taskId, stackId, toTop); 7185 } finally { 7186 Binder.restoreCallingIdentity(ident); 7187 } 7188 } 7189 } 7190 7191 @Override 7192 public void resizeStack(int stackBoxId, Rect bounds) { 7193 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7194 "resizeStackBox()"); 7195 long ident = Binder.clearCallingIdentity(); 7196 try { 7197 mWindowManager.resizeStack(stackBoxId, bounds); 7198 } finally { 7199 Binder.restoreCallingIdentity(ident); 7200 } 7201 } 7202 7203 @Override 7204 public List<StackInfo> getAllStackInfos() { 7205 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7206 "getAllStackInfos()"); 7207 long ident = Binder.clearCallingIdentity(); 7208 try { 7209 synchronized (this) { 7210 return mStackSupervisor.getAllStackInfosLocked(); 7211 } 7212 } finally { 7213 Binder.restoreCallingIdentity(ident); 7214 } 7215 } 7216 7217 @Override 7218 public StackInfo getStackInfo(int stackId) { 7219 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7220 "getStackInfo()"); 7221 long ident = Binder.clearCallingIdentity(); 7222 try { 7223 synchronized (this) { 7224 return mStackSupervisor.getStackInfoLocked(stackId); 7225 } 7226 } finally { 7227 Binder.restoreCallingIdentity(ident); 7228 } 7229 } 7230 7231 @Override 7232 public int getTaskForActivity(IBinder token, boolean onlyRoot) { 7233 synchronized(this) { 7234 return ActivityRecord.getTaskForActivityLocked(token, onlyRoot); 7235 } 7236 } 7237 7238 // ========================================================= 7239 // THUMBNAILS 7240 // ========================================================= 7241 7242 public void reportThumbnail(IBinder token, 7243 Bitmap thumbnail, CharSequence description) { 7244 //System.out.println("Report thumbnail for " + token + ": " + thumbnail); 7245 final long origId = Binder.clearCallingIdentity(); 7246 sendPendingThumbnail(null, token, thumbnail, description, true); 7247 Binder.restoreCallingIdentity(origId); 7248 } 7249 7250 final void sendPendingThumbnail(ActivityRecord r, IBinder token, 7251 Bitmap thumbnail, CharSequence description, boolean always) { 7252 TaskRecord task; 7253 ArrayList<PendingThumbnailsRecord> receivers = null; 7254 7255 //System.out.println("Send pending thumbnail: " + r); 7256 7257 synchronized(this) { 7258 if (r == null) { 7259 r = ActivityRecord.isInStackLocked(token); 7260 if (r == null) { 7261 return; 7262 } 7263 } 7264 if (thumbnail == null && r.thumbHolder != null) { 7265 thumbnail = r.thumbHolder.lastThumbnail; 7266 description = r.thumbHolder.lastDescription; 7267 } 7268 if (thumbnail == null && !always) { 7269 // If there is no thumbnail, and this entry is not actually 7270 // going away, then abort for now and pick up the next 7271 // thumbnail we get. 7272 return; 7273 } 7274 task = r.task; 7275 7276 int N = mPendingThumbnails.size(); 7277 int i=0; 7278 while (i<N) { 7279 PendingThumbnailsRecord pr = mPendingThumbnails.get(i); 7280 //System.out.println("Looking in " + pr.pendingRecords); 7281 if (pr.pendingRecords.remove(r)) { 7282 if (receivers == null) { 7283 receivers = new ArrayList<PendingThumbnailsRecord>(); 7284 } 7285 receivers.add(pr); 7286 if (pr.pendingRecords.size() == 0) { 7287 pr.finished = true; 7288 mPendingThumbnails.remove(i); 7289 N--; 7290 continue; 7291 } 7292 } 7293 i++; 7294 } 7295 } 7296 7297 if (receivers != null) { 7298 final int N = receivers.size(); 7299 for (int i=0; i<N; i++) { 7300 try { 7301 PendingThumbnailsRecord pr = receivers.get(i); 7302 pr.receiver.newThumbnail( 7303 task != null ? task.taskId : -1, thumbnail, description); 7304 if (pr.finished) { 7305 pr.receiver.finished(); 7306 } 7307 } catch (Exception e) { 7308 Slog.w(TAG, "Exception thrown when sending thumbnail", e); 7309 } 7310 } 7311 } 7312 } 7313 7314 // ========================================================= 7315 // CONTENT PROVIDERS 7316 // ========================================================= 7317 7318 private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) { 7319 List<ProviderInfo> providers = null; 7320 try { 7321 providers = AppGlobals.getPackageManager(). 7322 queryContentProviders(app.processName, app.uid, 7323 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS); 7324 } catch (RemoteException ex) { 7325 } 7326 if (DEBUG_MU) 7327 Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid); 7328 int userId = app.userId; 7329 if (providers != null) { 7330 int N = providers.size(); 7331 app.pubProviders.ensureCapacity(N + app.pubProviders.size()); 7332 for (int i=0; i<N; i++) { 7333 ProviderInfo cpi = 7334 (ProviderInfo)providers.get(i); 7335 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo, 7336 cpi.name, cpi.flags); 7337 if (singleton && UserHandle.getUserId(app.uid) != 0) { 7338 // This is a singleton provider, but a user besides the 7339 // default user is asking to initialize a process it runs 7340 // in... well, no, it doesn't actually run in this process, 7341 // it runs in the process of the default user. Get rid of it. 7342 providers.remove(i); 7343 N--; 7344 i--; 7345 continue; 7346 } 7347 7348 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 7349 ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId); 7350 if (cpr == null) { 7351 cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton); 7352 mProviderMap.putProviderByClass(comp, cpr); 7353 } 7354 if (DEBUG_MU) 7355 Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid); 7356 app.pubProviders.put(cpi.name, cpr); 7357 if (!cpi.multiprocess || !"android".equals(cpi.packageName)) { 7358 // Don't add this if it is a platform component that is marked 7359 // to run in multiple processes, because this is actually 7360 // part of the framework so doesn't make sense to track as a 7361 // separate apk in the process. 7362 app.addPackage(cpi.applicationInfo.packageName, mProcessStats); 7363 } 7364 ensurePackageDexOpt(cpi.applicationInfo.packageName); 7365 } 7366 } 7367 return providers; 7368 } 7369 7370 /** 7371 * Check if {@link ProcessRecord} has a possible chance at accessing the 7372 * given {@link ProviderInfo}. Final permission checking is always done 7373 * in {@link ContentProvider}. 7374 */ 7375 private final String checkContentProviderPermissionLocked( 7376 ProviderInfo cpi, ProcessRecord r) { 7377 final int callingPid = (r != null) ? r.pid : Binder.getCallingPid(); 7378 final int callingUid = (r != null) ? r.uid : Binder.getCallingUid(); 7379 if (checkComponentPermission(cpi.readPermission, callingPid, callingUid, 7380 cpi.applicationInfo.uid, cpi.exported) 7381 == PackageManager.PERMISSION_GRANTED) { 7382 return null; 7383 } 7384 if (checkComponentPermission(cpi.writePermission, callingPid, callingUid, 7385 cpi.applicationInfo.uid, cpi.exported) 7386 == PackageManager.PERMISSION_GRANTED) { 7387 return null; 7388 } 7389 7390 PathPermission[] pps = cpi.pathPermissions; 7391 if (pps != null) { 7392 int i = pps.length; 7393 while (i > 0) { 7394 i--; 7395 PathPermission pp = pps[i]; 7396 if (checkComponentPermission(pp.getReadPermission(), callingPid, callingUid, 7397 cpi.applicationInfo.uid, cpi.exported) 7398 == PackageManager.PERMISSION_GRANTED) { 7399 return null; 7400 } 7401 if (checkComponentPermission(pp.getWritePermission(), callingPid, callingUid, 7402 cpi.applicationInfo.uid, cpi.exported) 7403 == PackageManager.PERMISSION_GRANTED) { 7404 return null; 7405 } 7406 } 7407 } 7408 7409 ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(callingUid); 7410 if (perms != null) { 7411 for (Map.Entry<Uri, UriPermission> uri : perms.entrySet()) { 7412 if (uri.getKey().getAuthority().equals(cpi.authority)) { 7413 return null; 7414 } 7415 } 7416 } 7417 7418 String msg; 7419 if (!cpi.exported) { 7420 msg = "Permission Denial: opening provider " + cpi.name 7421 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 7422 + ", uid=" + callingUid + ") that is not exported from uid " 7423 + cpi.applicationInfo.uid; 7424 } else { 7425 msg = "Permission Denial: opening provider " + cpi.name 7426 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 7427 + ", uid=" + callingUid + ") requires " 7428 + cpi.readPermission + " or " + cpi.writePermission; 7429 } 7430 Slog.w(TAG, msg); 7431 return msg; 7432 } 7433 7434 ContentProviderConnection incProviderCountLocked(ProcessRecord r, 7435 final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 7436 if (r != null) { 7437 for (int i=0; i<r.conProviders.size(); i++) { 7438 ContentProviderConnection conn = r.conProviders.get(i); 7439 if (conn.provider == cpr) { 7440 if (DEBUG_PROVIDER) Slog.v(TAG, 7441 "Adding provider requested by " 7442 + r.processName + " from process " 7443 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 7444 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 7445 if (stable) { 7446 conn.stableCount++; 7447 conn.numStableIncs++; 7448 } else { 7449 conn.unstableCount++; 7450 conn.numUnstableIncs++; 7451 } 7452 return conn; 7453 } 7454 } 7455 ContentProviderConnection conn = new ContentProviderConnection(cpr, r); 7456 if (stable) { 7457 conn.stableCount = 1; 7458 conn.numStableIncs = 1; 7459 } else { 7460 conn.unstableCount = 1; 7461 conn.numUnstableIncs = 1; 7462 } 7463 cpr.connections.add(conn); 7464 r.conProviders.add(conn); 7465 return conn; 7466 } 7467 cpr.addExternalProcessHandleLocked(externalProcessToken); 7468 return null; 7469 } 7470 7471 boolean decProviderCountLocked(ContentProviderConnection conn, 7472 ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 7473 if (conn != null) { 7474 cpr = conn.provider; 7475 if (DEBUG_PROVIDER) Slog.v(TAG, 7476 "Removing provider requested by " 7477 + conn.client.processName + " from process " 7478 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 7479 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 7480 if (stable) { 7481 conn.stableCount--; 7482 } else { 7483 conn.unstableCount--; 7484 } 7485 if (conn.stableCount == 0 && conn.unstableCount == 0) { 7486 cpr.connections.remove(conn); 7487 conn.client.conProviders.remove(conn); 7488 return true; 7489 } 7490 return false; 7491 } 7492 cpr.removeExternalProcessHandleLocked(externalProcessToken); 7493 return false; 7494 } 7495 7496 private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller, 7497 String name, IBinder token, boolean stable, int userId) { 7498 ContentProviderRecord cpr; 7499 ContentProviderConnection conn = null; 7500 ProviderInfo cpi = null; 7501 7502 synchronized(this) { 7503 ProcessRecord r = null; 7504 if (caller != null) { 7505 r = getRecordForAppLocked(caller); 7506 if (r == null) { 7507 throw new SecurityException( 7508 "Unable to find app for caller " + caller 7509 + " (pid=" + Binder.getCallingPid() 7510 + ") when getting content provider " + name); 7511 } 7512 } 7513 7514 // First check if this content provider has been published... 7515 cpr = mProviderMap.getProviderByName(name, userId); 7516 boolean providerRunning = cpr != null; 7517 if (providerRunning) { 7518 cpi = cpr.info; 7519 String msg; 7520 if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) { 7521 throw new SecurityException(msg); 7522 } 7523 7524 if (r != null && cpr.canRunHere(r)) { 7525 // This provider has been published or is in the process 7526 // of being published... but it is also allowed to run 7527 // in the caller's process, so don't make a connection 7528 // and just let the caller instantiate its own instance. 7529 ContentProviderHolder holder = cpr.newHolder(null); 7530 // don't give caller the provider object, it needs 7531 // to make its own. 7532 holder.provider = null; 7533 return holder; 7534 } 7535 7536 final long origId = Binder.clearCallingIdentity(); 7537 7538 // In this case the provider instance already exists, so we can 7539 // return it right away. 7540 conn = incProviderCountLocked(r, cpr, token, stable); 7541 if (conn != null && (conn.stableCount+conn.unstableCount) == 1) { 7542 if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 7543 // If this is a perceptible app accessing the provider, 7544 // make sure to count it as being accessed and thus 7545 // back up on the LRU list. This is good because 7546 // content providers are often expensive to start. 7547 updateLruProcessLocked(cpr.proc, false, null); 7548 } 7549 } 7550 7551 if (cpr.proc != null) { 7552 if (false) { 7553 if (cpr.name.flattenToShortString().equals( 7554 "com.android.providers.calendar/.CalendarProvider2")) { 7555 Slog.v(TAG, "****************** KILLING " 7556 + cpr.name.flattenToShortString()); 7557 Process.killProcess(cpr.proc.pid); 7558 } 7559 } 7560 boolean success = updateOomAdjLocked(cpr.proc); 7561 if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success); 7562 // NOTE: there is still a race here where a signal could be 7563 // pending on the process even though we managed to update its 7564 // adj level. Not sure what to do about this, but at least 7565 // the race is now smaller. 7566 if (!success) { 7567 // Uh oh... it looks like the provider's process 7568 // has been killed on us. We need to wait for a new 7569 // process to be started, and make sure its death 7570 // doesn't kill our process. 7571 Slog.i(TAG, 7572 "Existing provider " + cpr.name.flattenToShortString() 7573 + " is crashing; detaching " + r); 7574 boolean lastRef = decProviderCountLocked(conn, cpr, token, stable); 7575 appDiedLocked(cpr.proc, cpr.proc.pid, cpr.proc.thread); 7576 if (!lastRef) { 7577 // This wasn't the last ref our process had on 7578 // the provider... we have now been killed, bail. 7579 return null; 7580 } 7581 providerRunning = false; 7582 conn = null; 7583 } 7584 } 7585 7586 Binder.restoreCallingIdentity(origId); 7587 } 7588 7589 boolean singleton; 7590 if (!providerRunning) { 7591 try { 7592 cpi = AppGlobals.getPackageManager(). 7593 resolveContentProvider(name, 7594 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId); 7595 } catch (RemoteException ex) { 7596 } 7597 if (cpi == null) { 7598 return null; 7599 } 7600 singleton = isSingleton(cpi.processName, cpi.applicationInfo, 7601 cpi.name, cpi.flags); 7602 if (singleton) { 7603 userId = 0; 7604 } 7605 cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId); 7606 7607 String msg; 7608 if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) { 7609 throw new SecurityException(msg); 7610 } 7611 7612 if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate 7613 && !cpi.processName.equals("system")) { 7614 // If this content provider does not run in the system 7615 // process, and the system is not yet ready to run other 7616 // processes, then fail fast instead of hanging. 7617 throw new IllegalArgumentException( 7618 "Attempt to launch content provider before system ready"); 7619 } 7620 7621 // Make sure that the user who owns this provider is started. If not, 7622 // we don't want to allow it to run. 7623 if (mStartedUsers.get(userId) == null) { 7624 Slog.w(TAG, "Unable to launch app " 7625 + cpi.applicationInfo.packageName + "/" 7626 + cpi.applicationInfo.uid + " for provider " 7627 + name + ": user " + userId + " is stopped"); 7628 return null; 7629 } 7630 7631 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 7632 cpr = mProviderMap.getProviderByClass(comp, userId); 7633 final boolean firstClass = cpr == null; 7634 if (firstClass) { 7635 try { 7636 ApplicationInfo ai = 7637 AppGlobals.getPackageManager(). 7638 getApplicationInfo( 7639 cpi.applicationInfo.packageName, 7640 STOCK_PM_FLAGS, userId); 7641 if (ai == null) { 7642 Slog.w(TAG, "No package info for content provider " 7643 + cpi.name); 7644 return null; 7645 } 7646 ai = getAppInfoForUser(ai, userId); 7647 cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton); 7648 } catch (RemoteException ex) { 7649 // pm is in same process, this will never happen. 7650 } 7651 } 7652 7653 if (r != null && cpr.canRunHere(r)) { 7654 // If this is a multiprocess provider, then just return its 7655 // info and allow the caller to instantiate it. Only do 7656 // this if the provider is the same user as the caller's 7657 // process, or can run as root (so can be in any process). 7658 return cpr.newHolder(null); 7659 } 7660 7661 if (DEBUG_PROVIDER) { 7662 RuntimeException e = new RuntimeException("here"); 7663 Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null) 7664 + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e); 7665 } 7666 7667 // This is single process, and our app is now connecting to it. 7668 // See if we are already in the process of launching this 7669 // provider. 7670 final int N = mLaunchingProviders.size(); 7671 int i; 7672 for (i=0; i<N; i++) { 7673 if (mLaunchingProviders.get(i) == cpr) { 7674 break; 7675 } 7676 } 7677 7678 // If the provider is not already being launched, then get it 7679 // started. 7680 if (i >= N) { 7681 final long origId = Binder.clearCallingIdentity(); 7682 7683 try { 7684 // Content provider is now in use, its package can't be stopped. 7685 try { 7686 AppGlobals.getPackageManager().setPackageStoppedState( 7687 cpr.appInfo.packageName, false, userId); 7688 } catch (RemoteException e) { 7689 } catch (IllegalArgumentException e) { 7690 Slog.w(TAG, "Failed trying to unstop package " 7691 + cpr.appInfo.packageName + ": " + e); 7692 } 7693 7694 // Use existing process if already started 7695 ProcessRecord proc = getProcessRecordLocked( 7696 cpi.processName, cpr.appInfo.uid, false); 7697 if (proc != null && proc.thread != null) { 7698 if (DEBUG_PROVIDER) { 7699 Slog.d(TAG, "Installing in existing process " + proc); 7700 } 7701 proc.pubProviders.put(cpi.name, cpr); 7702 try { 7703 proc.thread.scheduleInstallProvider(cpi); 7704 } catch (RemoteException e) { 7705 } 7706 } else { 7707 proc = startProcessLocked(cpi.processName, 7708 cpr.appInfo, false, 0, "content provider", 7709 new ComponentName(cpi.applicationInfo.packageName, 7710 cpi.name), false, false, false); 7711 if (proc == null) { 7712 Slog.w(TAG, "Unable to launch app " 7713 + cpi.applicationInfo.packageName + "/" 7714 + cpi.applicationInfo.uid + " for provider " 7715 + name + ": process is bad"); 7716 return null; 7717 } 7718 } 7719 cpr.launchingApp = proc; 7720 mLaunchingProviders.add(cpr); 7721 } finally { 7722 Binder.restoreCallingIdentity(origId); 7723 } 7724 } 7725 7726 // Make sure the provider is published (the same provider class 7727 // may be published under multiple names). 7728 if (firstClass) { 7729 mProviderMap.putProviderByClass(comp, cpr); 7730 } 7731 7732 mProviderMap.putProviderByName(name, cpr); 7733 conn = incProviderCountLocked(r, cpr, token, stable); 7734 if (conn != null) { 7735 conn.waiting = true; 7736 } 7737 } 7738 } 7739 7740 // Wait for the provider to be published... 7741 synchronized (cpr) { 7742 while (cpr.provider == null) { 7743 if (cpr.launchingApp == null) { 7744 Slog.w(TAG, "Unable to launch app " 7745 + cpi.applicationInfo.packageName + "/" 7746 + cpi.applicationInfo.uid + " for provider " 7747 + name + ": launching app became null"); 7748 EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS, 7749 UserHandle.getUserId(cpi.applicationInfo.uid), 7750 cpi.applicationInfo.packageName, 7751 cpi.applicationInfo.uid, name); 7752 return null; 7753 } 7754 try { 7755 if (DEBUG_MU) { 7756 Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp=" 7757 + cpr.launchingApp); 7758 } 7759 if (conn != null) { 7760 conn.waiting = true; 7761 } 7762 cpr.wait(); 7763 } catch (InterruptedException ex) { 7764 } finally { 7765 if (conn != null) { 7766 conn.waiting = false; 7767 } 7768 } 7769 } 7770 } 7771 return cpr != null ? cpr.newHolder(conn) : null; 7772 } 7773 7774 public final ContentProviderHolder getContentProvider( 7775 IApplicationThread caller, String name, int userId, boolean stable) { 7776 enforceNotIsolatedCaller("getContentProvider"); 7777 if (caller == null) { 7778 String msg = "null IApplicationThread when getting content provider " 7779 + name; 7780 Slog.w(TAG, msg); 7781 throw new SecurityException(msg); 7782 } 7783 7784 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 7785 false, true, "getContentProvider", null); 7786 return getContentProviderImpl(caller, name, null, stable, userId); 7787 } 7788 7789 public ContentProviderHolder getContentProviderExternal( 7790 String name, int userId, IBinder token) { 7791 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 7792 "Do not have permission in call getContentProviderExternal()"); 7793 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 7794 false, true, "getContentProvider", null); 7795 return getContentProviderExternalUnchecked(name, token, userId); 7796 } 7797 7798 private ContentProviderHolder getContentProviderExternalUnchecked(String name, 7799 IBinder token, int userId) { 7800 return getContentProviderImpl(null, name, token, true, userId); 7801 } 7802 7803 /** 7804 * Drop a content provider from a ProcessRecord's bookkeeping 7805 */ 7806 public void removeContentProvider(IBinder connection, boolean stable) { 7807 enforceNotIsolatedCaller("removeContentProvider"); 7808 long ident = Binder.clearCallingIdentity(); 7809 try { 7810 synchronized (this) { 7811 ContentProviderConnection conn; 7812 try { 7813 conn = (ContentProviderConnection)connection; 7814 } catch (ClassCastException e) { 7815 String msg ="removeContentProvider: " + connection 7816 + " not a ContentProviderConnection"; 7817 Slog.w(TAG, msg); 7818 throw new IllegalArgumentException(msg); 7819 } 7820 if (conn == null) { 7821 throw new NullPointerException("connection is null"); 7822 } 7823 if (decProviderCountLocked(conn, null, null, stable)) { 7824 updateOomAdjLocked(); 7825 } 7826 } 7827 } finally { 7828 Binder.restoreCallingIdentity(ident); 7829 } 7830 } 7831 7832 public void removeContentProviderExternal(String name, IBinder token) { 7833 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 7834 "Do not have permission in call removeContentProviderExternal()"); 7835 removeContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId()); 7836 } 7837 7838 private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) { 7839 synchronized (this) { 7840 ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId); 7841 if(cpr == null) { 7842 //remove from mProvidersByClass 7843 if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list"); 7844 return; 7845 } 7846 7847 //update content provider record entry info 7848 ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name); 7849 ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId); 7850 if (localCpr.hasExternalProcessHandles()) { 7851 if (localCpr.removeExternalProcessHandleLocked(token)) { 7852 updateOomAdjLocked(); 7853 } else { 7854 Slog.e(TAG, "Attmpt to remove content provider " + localCpr 7855 + " with no external reference for token: " 7856 + token + "."); 7857 } 7858 } else { 7859 Slog.e(TAG, "Attmpt to remove content provider: " + localCpr 7860 + " with no external references."); 7861 } 7862 } 7863 } 7864 7865 public final void publishContentProviders(IApplicationThread caller, 7866 List<ContentProviderHolder> providers) { 7867 if (providers == null) { 7868 return; 7869 } 7870 7871 enforceNotIsolatedCaller("publishContentProviders"); 7872 synchronized (this) { 7873 final ProcessRecord r = getRecordForAppLocked(caller); 7874 if (DEBUG_MU) 7875 Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid); 7876 if (r == null) { 7877 throw new SecurityException( 7878 "Unable to find app for caller " + caller 7879 + " (pid=" + Binder.getCallingPid() 7880 + ") when publishing content providers"); 7881 } 7882 7883 final long origId = Binder.clearCallingIdentity(); 7884 7885 final int N = providers.size(); 7886 for (int i=0; i<N; i++) { 7887 ContentProviderHolder src = providers.get(i); 7888 if (src == null || src.info == null || src.provider == null) { 7889 continue; 7890 } 7891 ContentProviderRecord dst = r.pubProviders.get(src.info.name); 7892 if (DEBUG_MU) 7893 Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid); 7894 if (dst != null) { 7895 ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name); 7896 mProviderMap.putProviderByClass(comp, dst); 7897 String names[] = dst.info.authority.split(";"); 7898 for (int j = 0; j < names.length; j++) { 7899 mProviderMap.putProviderByName(names[j], dst); 7900 } 7901 7902 int NL = mLaunchingProviders.size(); 7903 int j; 7904 for (j=0; j<NL; j++) { 7905 if (mLaunchingProviders.get(j) == dst) { 7906 mLaunchingProviders.remove(j); 7907 j--; 7908 NL--; 7909 } 7910 } 7911 synchronized (dst) { 7912 dst.provider = src.provider; 7913 dst.proc = r; 7914 dst.notifyAll(); 7915 } 7916 updateOomAdjLocked(r); 7917 } 7918 } 7919 7920 Binder.restoreCallingIdentity(origId); 7921 } 7922 } 7923 7924 public boolean refContentProvider(IBinder connection, int stable, int unstable) { 7925 ContentProviderConnection conn; 7926 try { 7927 conn = (ContentProviderConnection)connection; 7928 } catch (ClassCastException e) { 7929 String msg ="refContentProvider: " + connection 7930 + " not a ContentProviderConnection"; 7931 Slog.w(TAG, msg); 7932 throw new IllegalArgumentException(msg); 7933 } 7934 if (conn == null) { 7935 throw new NullPointerException("connection is null"); 7936 } 7937 7938 synchronized (this) { 7939 if (stable > 0) { 7940 conn.numStableIncs += stable; 7941 } 7942 stable = conn.stableCount + stable; 7943 if (stable < 0) { 7944 throw new IllegalStateException("stableCount < 0: " + stable); 7945 } 7946 7947 if (unstable > 0) { 7948 conn.numUnstableIncs += unstable; 7949 } 7950 unstable = conn.unstableCount + unstable; 7951 if (unstable < 0) { 7952 throw new IllegalStateException("unstableCount < 0: " + unstable); 7953 } 7954 7955 if ((stable+unstable) <= 0) { 7956 throw new IllegalStateException("ref counts can't go to zero here: stable=" 7957 + stable + " unstable=" + unstable); 7958 } 7959 conn.stableCount = stable; 7960 conn.unstableCount = unstable; 7961 return !conn.dead; 7962 } 7963 } 7964 7965 public void unstableProviderDied(IBinder connection) { 7966 ContentProviderConnection conn; 7967 try { 7968 conn = (ContentProviderConnection)connection; 7969 } catch (ClassCastException e) { 7970 String msg ="refContentProvider: " + connection 7971 + " not a ContentProviderConnection"; 7972 Slog.w(TAG, msg); 7973 throw new IllegalArgumentException(msg); 7974 } 7975 if (conn == null) { 7976 throw new NullPointerException("connection is null"); 7977 } 7978 7979 // Safely retrieve the content provider associated with the connection. 7980 IContentProvider provider; 7981 synchronized (this) { 7982 provider = conn.provider.provider; 7983 } 7984 7985 if (provider == null) { 7986 // Um, yeah, we're way ahead of you. 7987 return; 7988 } 7989 7990 // Make sure the caller is being honest with us. 7991 if (provider.asBinder().pingBinder()) { 7992 // Er, no, still looks good to us. 7993 synchronized (this) { 7994 Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid() 7995 + " says " + conn + " died, but we don't agree"); 7996 return; 7997 } 7998 } 7999 8000 // Well look at that! It's dead! 8001 synchronized (this) { 8002 if (conn.provider.provider != provider) { 8003 // But something changed... good enough. 8004 return; 8005 } 8006 8007 ProcessRecord proc = conn.provider.proc; 8008 if (proc == null || proc.thread == null) { 8009 // Seems like the process is already cleaned up. 8010 return; 8011 } 8012 8013 // As far as we're concerned, this is just like receiving a 8014 // death notification... just a bit prematurely. 8015 Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid 8016 + ") early provider death"); 8017 final long ident = Binder.clearCallingIdentity(); 8018 try { 8019 appDiedLocked(proc, proc.pid, proc.thread); 8020 } finally { 8021 Binder.restoreCallingIdentity(ident); 8022 } 8023 } 8024 } 8025 8026 @Override 8027 public void appNotRespondingViaProvider(IBinder connection) { 8028 enforceCallingPermission( 8029 android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()"); 8030 8031 final ContentProviderConnection conn = (ContentProviderConnection) connection; 8032 if (conn == null) { 8033 Slog.w(TAG, "ContentProviderConnection is null"); 8034 return; 8035 } 8036 8037 final ProcessRecord host = conn.provider.proc; 8038 if (host == null) { 8039 Slog.w(TAG, "Failed to find hosting ProcessRecord"); 8040 return; 8041 } 8042 8043 final long token = Binder.clearCallingIdentity(); 8044 try { 8045 appNotResponding(host, null, null, false, "ContentProvider not responding"); 8046 } finally { 8047 Binder.restoreCallingIdentity(token); 8048 } 8049 } 8050 8051 public final void installSystemProviders() { 8052 List<ProviderInfo> providers; 8053 synchronized (this) { 8054 ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID); 8055 providers = generateApplicationProvidersLocked(app); 8056 if (providers != null) { 8057 for (int i=providers.size()-1; i>=0; i--) { 8058 ProviderInfo pi = (ProviderInfo)providers.get(i); 8059 if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) { 8060 Slog.w(TAG, "Not installing system proc provider " + pi.name 8061 + ": not system .apk"); 8062 providers.remove(i); 8063 } 8064 } 8065 } 8066 } 8067 if (providers != null) { 8068 mSystemThread.installSystemProviders(providers); 8069 } 8070 8071 mCoreSettingsObserver = new CoreSettingsObserver(this); 8072 8073 mUsageStatsService.monitorPackages(); 8074 } 8075 8076 /** 8077 * Allows app to retrieve the MIME type of a URI without having permission 8078 * to access its content provider. 8079 * 8080 * CTS tests for this functionality can be run with "runtest cts-appsecurity". 8081 * 8082 * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/ 8083 * src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java 8084 */ 8085 public String getProviderMimeType(Uri uri, int userId) { 8086 enforceNotIsolatedCaller("getProviderMimeType"); 8087 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 8088 userId, false, true, "getProviderMimeType", null); 8089 final String name = uri.getAuthority(); 8090 final long ident = Binder.clearCallingIdentity(); 8091 ContentProviderHolder holder = null; 8092 8093 try { 8094 holder = getContentProviderExternalUnchecked(name, null, userId); 8095 if (holder != null) { 8096 return holder.provider.getType(uri); 8097 } 8098 } catch (RemoteException e) { 8099 Log.w(TAG, "Content provider dead retrieving " + uri, e); 8100 return null; 8101 } finally { 8102 if (holder != null) { 8103 removeContentProviderExternalUnchecked(name, null, userId); 8104 } 8105 Binder.restoreCallingIdentity(ident); 8106 } 8107 8108 return null; 8109 } 8110 8111 // ========================================================= 8112 // GLOBAL MANAGEMENT 8113 // ========================================================= 8114 8115 final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess, 8116 boolean isolated) { 8117 String proc = customProcess != null ? customProcess : info.processName; 8118 BatteryStatsImpl.Uid.Proc ps = null; 8119 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 8120 int uid = info.uid; 8121 if (isolated) { 8122 int userId = UserHandle.getUserId(uid); 8123 int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1; 8124 while (true) { 8125 if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID 8126 || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) { 8127 mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID; 8128 } 8129 uid = UserHandle.getUid(userId, mNextIsolatedProcessUid); 8130 mNextIsolatedProcessUid++; 8131 if (mIsolatedProcesses.indexOfKey(uid) < 0) { 8132 // No process for this uid, use it. 8133 break; 8134 } 8135 stepsLeft--; 8136 if (stepsLeft <= 0) { 8137 return null; 8138 } 8139 } 8140 } 8141 return new ProcessRecord(stats, info, proc, uid); 8142 } 8143 8144 final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated) { 8145 ProcessRecord app; 8146 if (!isolated) { 8147 app = getProcessRecordLocked(info.processName, info.uid, true); 8148 } else { 8149 app = null; 8150 } 8151 8152 if (app == null) { 8153 app = newProcessRecordLocked(info, null, isolated); 8154 mProcessNames.put(info.processName, app.uid, app); 8155 if (isolated) { 8156 mIsolatedProcesses.put(app.uid, app); 8157 } 8158 updateLruProcessLocked(app, false, null); 8159 updateOomAdjLocked(); 8160 } 8161 8162 // This package really, really can not be stopped. 8163 try { 8164 AppGlobals.getPackageManager().setPackageStoppedState( 8165 info.packageName, false, UserHandle.getUserId(app.uid)); 8166 } catch (RemoteException e) { 8167 } catch (IllegalArgumentException e) { 8168 Slog.w(TAG, "Failed trying to unstop package " 8169 + info.packageName + ": " + e); 8170 } 8171 8172 if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) 8173 == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) { 8174 app.persistent = true; 8175 app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ; 8176 } 8177 if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) { 8178 mPersistentStartingProcesses.add(app); 8179 startProcessLocked(app, "added application", app.processName); 8180 } 8181 8182 return app; 8183 } 8184 8185 public void unhandledBack() { 8186 enforceCallingPermission(android.Manifest.permission.FORCE_BACK, 8187 "unhandledBack()"); 8188 8189 synchronized(this) { 8190 final long origId = Binder.clearCallingIdentity(); 8191 try { 8192 getFocusedStack().unhandledBackLocked(); 8193 } finally { 8194 Binder.restoreCallingIdentity(origId); 8195 } 8196 } 8197 } 8198 8199 public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException { 8200 enforceNotIsolatedCaller("openContentUri"); 8201 final int userId = UserHandle.getCallingUserId(); 8202 String name = uri.getAuthority(); 8203 ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId); 8204 ParcelFileDescriptor pfd = null; 8205 if (cph != null) { 8206 // We record the binder invoker's uid in thread-local storage before 8207 // going to the content provider to open the file. Later, in the code 8208 // that handles all permissions checks, we look for this uid and use 8209 // that rather than the Activity Manager's own uid. The effect is that 8210 // we do the check against the caller's permissions even though it looks 8211 // to the content provider like the Activity Manager itself is making 8212 // the request. 8213 sCallerIdentity.set(new Identity( 8214 Binder.getCallingPid(), Binder.getCallingUid())); 8215 try { 8216 pfd = cph.provider.openFile(null, uri, "r", null); 8217 } catch (FileNotFoundException e) { 8218 // do nothing; pfd will be returned null 8219 } finally { 8220 // Ensure that whatever happens, we clean up the identity state 8221 sCallerIdentity.remove(); 8222 } 8223 8224 // We've got the fd now, so we're done with the provider. 8225 removeContentProviderExternalUnchecked(name, null, userId); 8226 } else { 8227 Slog.d(TAG, "Failed to get provider for authority '" + name + "'"); 8228 } 8229 return pfd; 8230 } 8231 8232 // Actually is sleeping or shutting down or whatever else in the future 8233 // is an inactive state. 8234 public boolean isSleepingOrShuttingDown() { 8235 return mSleeping || mShuttingDown; 8236 } 8237 8238 public void goingToSleep() { 8239 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER) 8240 != PackageManager.PERMISSION_GRANTED) { 8241 throw new SecurityException("Requires permission " 8242 + android.Manifest.permission.DEVICE_POWER); 8243 } 8244 8245 synchronized(this) { 8246 mWentToSleep = true; 8247 updateEventDispatchingLocked(); 8248 8249 if (!mSleeping) { 8250 mSleeping = true; 8251 mStackSupervisor.goingToSleepLocked(); 8252 8253 // Initialize the wake times of all processes. 8254 checkExcessivePowerUsageLocked(false); 8255 mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 8256 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 8257 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 8258 } 8259 } 8260 } 8261 8262 @Override 8263 public boolean shutdown(int timeout) { 8264 if (checkCallingPermission(android.Manifest.permission.SHUTDOWN) 8265 != PackageManager.PERMISSION_GRANTED) { 8266 throw new SecurityException("Requires permission " 8267 + android.Manifest.permission.SHUTDOWN); 8268 } 8269 8270 boolean timedout = false; 8271 8272 synchronized(this) { 8273 mShuttingDown = true; 8274 updateEventDispatchingLocked(); 8275 timedout = mStackSupervisor.shutdownLocked(timeout); 8276 } 8277 8278 mAppOpsService.shutdown(); 8279 mUsageStatsService.shutdown(); 8280 mBatteryStatsService.shutdown(); 8281 synchronized (this) { 8282 mProcessStats.shutdownLocked(); 8283 } 8284 8285 return timedout; 8286 } 8287 8288 public final void activitySlept(IBinder token) { 8289 if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token); 8290 8291 final long origId = Binder.clearCallingIdentity(); 8292 8293 synchronized (this) { 8294 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 8295 if (r != null) { 8296 mStackSupervisor.activitySleptLocked(r); 8297 } 8298 } 8299 8300 Binder.restoreCallingIdentity(origId); 8301 } 8302 8303 void logLockScreen(String msg) { 8304 if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg + 8305 " mLockScreenShown=" + mLockScreenShown + " mWentToSleep=" + 8306 mWentToSleep + " mSleeping=" + mSleeping + " mDismissKeyguardOnNextActivity=" + 8307 mStackSupervisor.mDismissKeyguardOnNextActivity); 8308 } 8309 8310 private void comeOutOfSleepIfNeededLocked() { 8311 if (!mWentToSleep && !mLockScreenShown) { 8312 if (mSleeping) { 8313 mSleeping = false; 8314 mStackSupervisor.comeOutOfSleepIfNeededLocked(); 8315 } 8316 } 8317 } 8318 8319 public void wakingUp() { 8320 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER) 8321 != PackageManager.PERMISSION_GRANTED) { 8322 throw new SecurityException("Requires permission " 8323 + android.Manifest.permission.DEVICE_POWER); 8324 } 8325 8326 synchronized(this) { 8327 mWentToSleep = false; 8328 updateEventDispatchingLocked(); 8329 comeOutOfSleepIfNeededLocked(); 8330 } 8331 } 8332 8333 private void updateEventDispatchingLocked() { 8334 mWindowManager.setEventDispatching(mBooted && !mWentToSleep && !mShuttingDown); 8335 } 8336 8337 public void setLockScreenShown(boolean shown) { 8338 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER) 8339 != PackageManager.PERMISSION_GRANTED) { 8340 throw new SecurityException("Requires permission " 8341 + android.Manifest.permission.DEVICE_POWER); 8342 } 8343 8344 synchronized(this) { 8345 long ident = Binder.clearCallingIdentity(); 8346 try { 8347 if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown); 8348 mLockScreenShown = shown; 8349 comeOutOfSleepIfNeededLocked(); 8350 } finally { 8351 Binder.restoreCallingIdentity(ident); 8352 } 8353 } 8354 } 8355 8356 public void stopAppSwitches() { 8357 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 8358 != PackageManager.PERMISSION_GRANTED) { 8359 throw new SecurityException("Requires permission " 8360 + android.Manifest.permission.STOP_APP_SWITCHES); 8361 } 8362 8363 synchronized(this) { 8364 mAppSwitchesAllowedTime = SystemClock.uptimeMillis() 8365 + APP_SWITCH_DELAY_TIME; 8366 mDidAppSwitch = false; 8367 mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 8368 Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 8369 mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME); 8370 } 8371 } 8372 8373 public void resumeAppSwitches() { 8374 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 8375 != PackageManager.PERMISSION_GRANTED) { 8376 throw new SecurityException("Requires permission " 8377 + android.Manifest.permission.STOP_APP_SWITCHES); 8378 } 8379 8380 synchronized(this) { 8381 // Note that we don't execute any pending app switches... we will 8382 // let those wait until either the timeout, or the next start 8383 // activity request. 8384 mAppSwitchesAllowedTime = 0; 8385 } 8386 } 8387 8388 boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid, 8389 String name) { 8390 if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) { 8391 return true; 8392 } 8393 8394 final int perm = checkComponentPermission( 8395 android.Manifest.permission.STOP_APP_SWITCHES, callingPid, 8396 callingUid, -1, true); 8397 if (perm == PackageManager.PERMISSION_GRANTED) { 8398 return true; 8399 } 8400 8401 Slog.w(TAG, name + " request from " + callingUid + " stopped"); 8402 return false; 8403 } 8404 8405 public void setDebugApp(String packageName, boolean waitForDebugger, 8406 boolean persistent) { 8407 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP, 8408 "setDebugApp()"); 8409 8410 long ident = Binder.clearCallingIdentity(); 8411 try { 8412 // Note that this is not really thread safe if there are multiple 8413 // callers into it at the same time, but that's not a situation we 8414 // care about. 8415 if (persistent) { 8416 final ContentResolver resolver = mContext.getContentResolver(); 8417 Settings.Global.putString( 8418 resolver, Settings.Global.DEBUG_APP, 8419 packageName); 8420 Settings.Global.putInt( 8421 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 8422 waitForDebugger ? 1 : 0); 8423 } 8424 8425 synchronized (this) { 8426 if (!persistent) { 8427 mOrigDebugApp = mDebugApp; 8428 mOrigWaitForDebugger = mWaitForDebugger; 8429 } 8430 mDebugApp = packageName; 8431 mWaitForDebugger = waitForDebugger; 8432 mDebugTransient = !persistent; 8433 if (packageName != null) { 8434 forceStopPackageLocked(packageName, -1, false, false, true, true, 8435 false, UserHandle.USER_ALL, "set debug app"); 8436 } 8437 } 8438 } finally { 8439 Binder.restoreCallingIdentity(ident); 8440 } 8441 } 8442 8443 void setOpenGlTraceApp(ApplicationInfo app, String processName) { 8444 synchronized (this) { 8445 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 8446 if (!isDebuggable) { 8447 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 8448 throw new SecurityException("Process not debuggable: " + app.packageName); 8449 } 8450 } 8451 8452 mOpenGlTraceApp = processName; 8453 } 8454 } 8455 8456 void setProfileApp(ApplicationInfo app, String processName, String profileFile, 8457 ParcelFileDescriptor profileFd, boolean autoStopProfiler) { 8458 synchronized (this) { 8459 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 8460 if (!isDebuggable) { 8461 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 8462 throw new SecurityException("Process not debuggable: " + app.packageName); 8463 } 8464 } 8465 mProfileApp = processName; 8466 mProfileFile = profileFile; 8467 if (mProfileFd != null) { 8468 try { 8469 mProfileFd.close(); 8470 } catch (IOException e) { 8471 } 8472 mProfileFd = null; 8473 } 8474 mProfileFd = profileFd; 8475 mProfileType = 0; 8476 mAutoStopProfiler = autoStopProfiler; 8477 } 8478 } 8479 8480 @Override 8481 public void setAlwaysFinish(boolean enabled) { 8482 enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH, 8483 "setAlwaysFinish()"); 8484 8485 Settings.Global.putInt( 8486 mContext.getContentResolver(), 8487 Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0); 8488 8489 synchronized (this) { 8490 mAlwaysFinishActivities = enabled; 8491 } 8492 } 8493 8494 @Override 8495 public void setActivityController(IActivityController controller) { 8496 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 8497 "setActivityController()"); 8498 synchronized (this) { 8499 mController = controller; 8500 Watchdog.getInstance().setActivityController(controller); 8501 } 8502 } 8503 8504 @Override 8505 public void setUserIsMonkey(boolean userIsMonkey) { 8506 synchronized (this) { 8507 synchronized (mPidsSelfLocked) { 8508 final int callingPid = Binder.getCallingPid(); 8509 ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid); 8510 if (precessRecord == null) { 8511 throw new SecurityException("Unknown process: " + callingPid); 8512 } 8513 if (precessRecord.instrumentationUiAutomationConnection == null) { 8514 throw new SecurityException("Only an instrumentation process " 8515 + "with a UiAutomation can call setUserIsMonkey"); 8516 } 8517 } 8518 mUserIsMonkey = userIsMonkey; 8519 } 8520 } 8521 8522 @Override 8523 public boolean isUserAMonkey() { 8524 synchronized (this) { 8525 // If there is a controller also implies the user is a monkey. 8526 return (mUserIsMonkey || mController != null); 8527 } 8528 } 8529 8530 public void requestBugReport() { 8531 enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport"); 8532 SystemProperties.set("ctl.start", "bugreport"); 8533 } 8534 8535 public static long getInputDispatchingTimeoutLocked(ActivityRecord r) { 8536 return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT; 8537 } 8538 8539 public static long getInputDispatchingTimeoutLocked(ProcessRecord r) { 8540 if (r != null && (r.instrumentationClass != null || r.usingWrapper)) { 8541 return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT; 8542 } 8543 return KEY_DISPATCHING_TIMEOUT; 8544 } 8545 8546 @Override 8547 public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) { 8548 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS) 8549 != PackageManager.PERMISSION_GRANTED) { 8550 throw new SecurityException("Requires permission " 8551 + android.Manifest.permission.FILTER_EVENTS); 8552 } 8553 ProcessRecord proc; 8554 long timeout; 8555 synchronized (this) { 8556 synchronized (mPidsSelfLocked) { 8557 proc = mPidsSelfLocked.get(pid); 8558 } 8559 timeout = getInputDispatchingTimeoutLocked(proc); 8560 } 8561 8562 if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) { 8563 return -1; 8564 } 8565 8566 return timeout; 8567 } 8568 8569 /** 8570 * Handle input dispatching timeouts. 8571 * Returns whether input dispatching should be aborted or not. 8572 */ 8573 public boolean inputDispatchingTimedOut(final ProcessRecord proc, 8574 final ActivityRecord activity, final ActivityRecord parent, 8575 final boolean aboveSystem, String reason) { 8576 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS) 8577 != PackageManager.PERMISSION_GRANTED) { 8578 throw new SecurityException("Requires permission " 8579 + android.Manifest.permission.FILTER_EVENTS); 8580 } 8581 8582 final String annotation; 8583 if (reason == null) { 8584 annotation = "Input dispatching timed out"; 8585 } else { 8586 annotation = "Input dispatching timed out (" + reason + ")"; 8587 } 8588 8589 if (proc != null) { 8590 synchronized (this) { 8591 if (proc.debugging) { 8592 return false; 8593 } 8594 8595 if (mDidDexOpt) { 8596 // Give more time since we were dexopting. 8597 mDidDexOpt = false; 8598 return false; 8599 } 8600 8601 if (proc.instrumentationClass != null) { 8602 Bundle info = new Bundle(); 8603 info.putString("shortMsg", "keyDispatchingTimedOut"); 8604 info.putString("longMsg", annotation); 8605 finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info); 8606 return true; 8607 } 8608 } 8609 mHandler.post(new Runnable() { 8610 @Override 8611 public void run() { 8612 appNotResponding(proc, activity, parent, aboveSystem, annotation); 8613 } 8614 }); 8615 } 8616 8617 return true; 8618 } 8619 8620 public Bundle getAssistContextExtras(int requestType) { 8621 enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO, 8622 "getAssistContextExtras()"); 8623 PendingAssistExtras pae; 8624 Bundle extras = new Bundle(); 8625 synchronized (this) { 8626 ActivityRecord activity = getFocusedStack().mResumedActivity; 8627 if (activity == null) { 8628 Slog.w(TAG, "getAssistContextExtras failed: no resumed activity"); 8629 return null; 8630 } 8631 extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName); 8632 if (activity.app == null || activity.app.thread == null) { 8633 Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity); 8634 return extras; 8635 } 8636 if (activity.app.pid == Binder.getCallingPid()) { 8637 Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity); 8638 return extras; 8639 } 8640 pae = new PendingAssistExtras(activity); 8641 try { 8642 activity.app.thread.requestAssistContextExtras(activity.appToken, pae, 8643 requestType); 8644 mPendingAssistExtras.add(pae); 8645 mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT); 8646 } catch (RemoteException e) { 8647 Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity); 8648 return extras; 8649 } 8650 } 8651 synchronized (pae) { 8652 while (!pae.haveResult) { 8653 try { 8654 pae.wait(); 8655 } catch (InterruptedException e) { 8656 } 8657 } 8658 if (pae.result != null) { 8659 extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result); 8660 } 8661 } 8662 synchronized (this) { 8663 mPendingAssistExtras.remove(pae); 8664 mHandler.removeCallbacks(pae); 8665 } 8666 return extras; 8667 } 8668 8669 public void reportAssistContextExtras(IBinder token, Bundle extras) { 8670 PendingAssistExtras pae = (PendingAssistExtras)token; 8671 synchronized (pae) { 8672 pae.result = extras; 8673 pae.haveResult = true; 8674 pae.notifyAll(); 8675 } 8676 } 8677 8678 public void registerProcessObserver(IProcessObserver observer) { 8679 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 8680 "registerProcessObserver()"); 8681 synchronized (this) { 8682 mProcessObservers.register(observer); 8683 } 8684 } 8685 8686 @Override 8687 public void unregisterProcessObserver(IProcessObserver observer) { 8688 synchronized (this) { 8689 mProcessObservers.unregister(observer); 8690 } 8691 } 8692 8693 @Override 8694 public boolean convertFromTranslucent(IBinder token) { 8695 final long origId = Binder.clearCallingIdentity(); 8696 try { 8697 synchronized (this) { 8698 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 8699 if (r == null) { 8700 return false; 8701 } 8702 if (r.changeWindowTranslucency(true)) { 8703 mWindowManager.setAppFullscreen(token, true); 8704 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 8705 return true; 8706 } 8707 return false; 8708 } 8709 } finally { 8710 Binder.restoreCallingIdentity(origId); 8711 } 8712 } 8713 8714 @Override 8715 public boolean convertToTranslucent(IBinder token) { 8716 final long origId = Binder.clearCallingIdentity(); 8717 try { 8718 synchronized (this) { 8719 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 8720 if (r == null) { 8721 return false; 8722 } 8723 if (r.changeWindowTranslucency(false)) { 8724 r.task.stack.convertToTranslucent(r); 8725 mWindowManager.setAppFullscreen(token, false); 8726 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 8727 return true; 8728 } 8729 return false; 8730 } 8731 } finally { 8732 Binder.restoreCallingIdentity(origId); 8733 } 8734 } 8735 8736 @Override 8737 public void setImmersive(IBinder token, boolean immersive) { 8738 synchronized(this) { 8739 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 8740 if (r == null) { 8741 throw new IllegalArgumentException(); 8742 } 8743 r.immersive = immersive; 8744 8745 // update associated state if we're frontmost 8746 if (r == mFocusedActivity) { 8747 if (DEBUG_IMMERSIVE) { 8748 Slog.d(TAG, "Frontmost changed immersion: "+ r); 8749 } 8750 applyUpdateLockStateLocked(r); 8751 } 8752 } 8753 } 8754 8755 @Override 8756 public boolean isImmersive(IBinder token) { 8757 synchronized (this) { 8758 ActivityRecord r = ActivityRecord.isInStackLocked(token); 8759 if (r == null) { 8760 throw new IllegalArgumentException(); 8761 } 8762 return r.immersive; 8763 } 8764 } 8765 8766 public boolean isTopActivityImmersive() { 8767 enforceNotIsolatedCaller("startActivity"); 8768 synchronized (this) { 8769 ActivityRecord r = getFocusedStack().topRunningActivityLocked(null); 8770 return (r != null) ? r.immersive : false; 8771 } 8772 } 8773 8774 public final void enterSafeMode() { 8775 synchronized(this) { 8776 // It only makes sense to do this before the system is ready 8777 // and started launching other packages. 8778 if (!mSystemReady) { 8779 try { 8780 AppGlobals.getPackageManager().enterSafeMode(); 8781 } catch (RemoteException e) { 8782 } 8783 } 8784 } 8785 } 8786 8787 public final void showSafeModeOverlay() { 8788 View v = LayoutInflater.from(mContext).inflate( 8789 com.android.internal.R.layout.safe_mode, null); 8790 WindowManager.LayoutParams lp = new WindowManager.LayoutParams(); 8791 lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY; 8792 lp.width = WindowManager.LayoutParams.WRAP_CONTENT; 8793 lp.height = WindowManager.LayoutParams.WRAP_CONTENT; 8794 lp.gravity = Gravity.BOTTOM | Gravity.START; 8795 lp.format = v.getBackground().getOpacity(); 8796 lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE 8797 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE; 8798 lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS; 8799 ((WindowManager)mContext.getSystemService( 8800 Context.WINDOW_SERVICE)).addView(v, lp); 8801 } 8802 8803 public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) { 8804 if (!(sender instanceof PendingIntentRecord)) { 8805 return; 8806 } 8807 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 8808 synchronized (stats) { 8809 if (mBatteryStatsService.isOnBattery()) { 8810 mBatteryStatsService.enforceCallingPermission(); 8811 PendingIntentRecord rec = (PendingIntentRecord)sender; 8812 int MY_UID = Binder.getCallingUid(); 8813 int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid; 8814 BatteryStatsImpl.Uid.Pkg pkg = 8815 stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid, 8816 sourcePkg != null ? sourcePkg : rec.key.packageName); 8817 pkg.incWakeupsLocked(); 8818 } 8819 } 8820 } 8821 8822 public boolean killPids(int[] pids, String pReason, boolean secure) { 8823 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 8824 throw new SecurityException("killPids only available to the system"); 8825 } 8826 String reason = (pReason == null) ? "Unknown" : pReason; 8827 // XXX Note: don't acquire main activity lock here, because the window 8828 // manager calls in with its locks held. 8829 8830 boolean killed = false; 8831 synchronized (mPidsSelfLocked) { 8832 int[] types = new int[pids.length]; 8833 int worstType = 0; 8834 for (int i=0; i<pids.length; i++) { 8835 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 8836 if (proc != null) { 8837 int type = proc.setAdj; 8838 types[i] = type; 8839 if (type > worstType) { 8840 worstType = type; 8841 } 8842 } 8843 } 8844 8845 // If the worst oom_adj is somewhere in the cached proc LRU range, 8846 // then constrain it so we will kill all cached procs. 8847 if (worstType < ProcessList.CACHED_APP_MAX_ADJ 8848 && worstType > ProcessList.CACHED_APP_MIN_ADJ) { 8849 worstType = ProcessList.CACHED_APP_MIN_ADJ; 8850 } 8851 8852 // If this is not a secure call, don't let it kill processes that 8853 // are important. 8854 if (!secure && worstType < ProcessList.SERVICE_ADJ) { 8855 worstType = ProcessList.SERVICE_ADJ; 8856 } 8857 8858 Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType); 8859 for (int i=0; i<pids.length; i++) { 8860 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 8861 if (proc == null) { 8862 continue; 8863 } 8864 int adj = proc.setAdj; 8865 if (adj >= worstType && !proc.killedByAm) { 8866 killUnneededProcessLocked(proc, reason); 8867 killed = true; 8868 } 8869 } 8870 } 8871 return killed; 8872 } 8873 8874 @Override 8875 public void killUid(int uid, String reason) { 8876 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 8877 throw new SecurityException("killUid only available to the system"); 8878 } 8879 synchronized (this) { 8880 killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid), 8881 ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false, 8882 reason != null ? reason : "kill uid"); 8883 } 8884 } 8885 8886 @Override 8887 public boolean killProcessesBelowForeground(String reason) { 8888 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 8889 throw new SecurityException("killProcessesBelowForeground() only available to system"); 8890 } 8891 8892 return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason); 8893 } 8894 8895 private boolean killProcessesBelowAdj(int belowAdj, String reason) { 8896 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 8897 throw new SecurityException("killProcessesBelowAdj() only available to system"); 8898 } 8899 8900 boolean killed = false; 8901 synchronized (mPidsSelfLocked) { 8902 final int size = mPidsSelfLocked.size(); 8903 for (int i = 0; i < size; i++) { 8904 final int pid = mPidsSelfLocked.keyAt(i); 8905 final ProcessRecord proc = mPidsSelfLocked.valueAt(i); 8906 if (proc == null) continue; 8907 8908 final int adj = proc.setAdj; 8909 if (adj > belowAdj && !proc.killedByAm) { 8910 killUnneededProcessLocked(proc, reason); 8911 killed = true; 8912 } 8913 } 8914 } 8915 return killed; 8916 } 8917 8918 @Override 8919 public void hang(final IBinder who, boolean allowRestart) { 8920 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 8921 != PackageManager.PERMISSION_GRANTED) { 8922 throw new SecurityException("Requires permission " 8923 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 8924 } 8925 8926 final IBinder.DeathRecipient death = new DeathRecipient() { 8927 @Override 8928 public void binderDied() { 8929 synchronized (this) { 8930 notifyAll(); 8931 } 8932 } 8933 }; 8934 8935 try { 8936 who.linkToDeath(death, 0); 8937 } catch (RemoteException e) { 8938 Slog.w(TAG, "hang: given caller IBinder is already dead."); 8939 return; 8940 } 8941 8942 synchronized (this) { 8943 Watchdog.getInstance().setAllowRestart(allowRestart); 8944 Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid()); 8945 synchronized (death) { 8946 while (who.isBinderAlive()) { 8947 try { 8948 death.wait(); 8949 } catch (InterruptedException e) { 8950 } 8951 } 8952 } 8953 Watchdog.getInstance().setAllowRestart(true); 8954 } 8955 } 8956 8957 @Override 8958 public void restart() { 8959 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 8960 != PackageManager.PERMISSION_GRANTED) { 8961 throw new SecurityException("Requires permission " 8962 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 8963 } 8964 8965 Log.i(TAG, "Sending shutdown broadcast..."); 8966 8967 BroadcastReceiver br = new BroadcastReceiver() { 8968 @Override public void onReceive(Context context, Intent intent) { 8969 // Now the broadcast is done, finish up the low-level shutdown. 8970 Log.i(TAG, "Shutting down activity manager..."); 8971 shutdown(10000); 8972 Log.i(TAG, "Shutdown complete, restarting!"); 8973 Process.killProcess(Process.myPid()); 8974 System.exit(10); 8975 } 8976 }; 8977 8978 // First send the high-level shut down broadcast. 8979 Intent intent = new Intent(Intent.ACTION_SHUTDOWN); 8980 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 8981 intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true); 8982 /* For now we are not doing a clean shutdown, because things seem to get unhappy. 8983 mContext.sendOrderedBroadcastAsUser(intent, 8984 UserHandle.ALL, null, br, mHandler, 0, null, null); 8985 */ 8986 br.onReceive(mContext, intent); 8987 } 8988 8989 private long getLowRamTimeSinceIdle(long now) { 8990 return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0); 8991 } 8992 8993 @Override 8994 public void performIdleMaintenance() { 8995 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 8996 != PackageManager.PERMISSION_GRANTED) { 8997 throw new SecurityException("Requires permission " 8998 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 8999 } 9000 9001 synchronized (this) { 9002 final long now = SystemClock.uptimeMillis(); 9003 final long timeSinceLastIdle = now - mLastIdleTime; 9004 final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now); 9005 mLastIdleTime = now; 9006 mLowRamTimeSinceLastIdle = 0; 9007 if (mLowRamStartTime != 0) { 9008 mLowRamStartTime = now; 9009 } 9010 9011 StringBuilder sb = new StringBuilder(128); 9012 sb.append("Idle maintenance over "); 9013 TimeUtils.formatDuration(timeSinceLastIdle, sb); 9014 sb.append(" low RAM for "); 9015 TimeUtils.formatDuration(lowRamSinceLastIdle, sb); 9016 Slog.i(TAG, sb.toString()); 9017 9018 // If at least 1/3 of our time since the last idle period has been spent 9019 // with RAM low, then we want to kill processes. 9020 boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3); 9021 9022 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 9023 ProcessRecord proc = mLruProcesses.get(i); 9024 if (proc.notCachedSinceIdle) { 9025 if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP 9026 && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) { 9027 if (doKilling && proc.initialIdlePss != 0 9028 && proc.lastPss > ((proc.initialIdlePss*3)/2)) { 9029 killUnneededProcessLocked(proc, "idle maint (pss " + proc.lastPss 9030 + " from " + proc.initialIdlePss + ")"); 9031 } 9032 } 9033 } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) { 9034 proc.notCachedSinceIdle = true; 9035 proc.initialIdlePss = 0; 9036 proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true, 9037 mSleeping, now); 9038 } 9039 } 9040 9041 mHandler.removeMessages(REQUEST_ALL_PSS_MSG); 9042 mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000); 9043 } 9044 } 9045 9046 public final void startRunning(String pkg, String cls, String action, 9047 String data) { 9048 synchronized(this) { 9049 if (mStartRunning) { 9050 return; 9051 } 9052 mStartRunning = true; 9053 mTopComponent = pkg != null && cls != null 9054 ? new ComponentName(pkg, cls) : null; 9055 mTopAction = action != null ? action : Intent.ACTION_MAIN; 9056 mTopData = data; 9057 if (!mSystemReady) { 9058 return; 9059 } 9060 } 9061 9062 systemReady(null); 9063 } 9064 9065 private void retrieveSettings() { 9066 final ContentResolver resolver = mContext.getContentResolver(); 9067 String debugApp = Settings.Global.getString( 9068 resolver, Settings.Global.DEBUG_APP); 9069 boolean waitForDebugger = Settings.Global.getInt( 9070 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0; 9071 boolean alwaysFinishActivities = Settings.Global.getInt( 9072 resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0; 9073 boolean forceRtl = Settings.Global.getInt( 9074 resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0; 9075 // Transfer any global setting for forcing RTL layout, into a System Property 9076 SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0"); 9077 9078 Configuration configuration = new Configuration(); 9079 Settings.System.getConfiguration(resolver, configuration); 9080 if (forceRtl) { 9081 // This will take care of setting the correct layout direction flags 9082 configuration.setLayoutDirection(configuration.locale); 9083 } 9084 9085 synchronized (this) { 9086 mDebugApp = mOrigDebugApp = debugApp; 9087 mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger; 9088 mAlwaysFinishActivities = alwaysFinishActivities; 9089 // This happens before any activities are started, so we can 9090 // change mConfiguration in-place. 9091 updateConfigurationLocked(configuration, null, false, true); 9092 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration); 9093 } 9094 } 9095 9096 public boolean testIsSystemReady() { 9097 // no need to synchronize(this) just to read & return the value 9098 return mSystemReady; 9099 } 9100 9101 private static File getCalledPreBootReceiversFile() { 9102 File dataDir = Environment.getDataDirectory(); 9103 File systemDir = new File(dataDir, "system"); 9104 File fname = new File(systemDir, "called_pre_boots.dat"); 9105 return fname; 9106 } 9107 9108 static final int LAST_DONE_VERSION = 10000; 9109 9110 private static ArrayList<ComponentName> readLastDonePreBootReceivers() { 9111 ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>(); 9112 File file = getCalledPreBootReceiversFile(); 9113 FileInputStream fis = null; 9114 try { 9115 fis = new FileInputStream(file); 9116 DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048)); 9117 int fvers = dis.readInt(); 9118 if (fvers == LAST_DONE_VERSION) { 9119 String vers = dis.readUTF(); 9120 String codename = dis.readUTF(); 9121 String build = dis.readUTF(); 9122 if (android.os.Build.VERSION.RELEASE.equals(vers) 9123 && android.os.Build.VERSION.CODENAME.equals(codename) 9124 && android.os.Build.VERSION.INCREMENTAL.equals(build)) { 9125 int num = dis.readInt(); 9126 while (num > 0) { 9127 num--; 9128 String pkg = dis.readUTF(); 9129 String cls = dis.readUTF(); 9130 lastDoneReceivers.add(new ComponentName(pkg, cls)); 9131 } 9132 } 9133 } 9134 } catch (FileNotFoundException e) { 9135 } catch (IOException e) { 9136 Slog.w(TAG, "Failure reading last done pre-boot receivers", e); 9137 } finally { 9138 if (fis != null) { 9139 try { 9140 fis.close(); 9141 } catch (IOException e) { 9142 } 9143 } 9144 } 9145 return lastDoneReceivers; 9146 } 9147 9148 private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) { 9149 File file = getCalledPreBootReceiversFile(); 9150 FileOutputStream fos = null; 9151 DataOutputStream dos = null; 9152 try { 9153 Slog.i(TAG, "Writing new set of last done pre-boot receivers..."); 9154 fos = new FileOutputStream(file); 9155 dos = new DataOutputStream(new BufferedOutputStream(fos, 2048)); 9156 dos.writeInt(LAST_DONE_VERSION); 9157 dos.writeUTF(android.os.Build.VERSION.RELEASE); 9158 dos.writeUTF(android.os.Build.VERSION.CODENAME); 9159 dos.writeUTF(android.os.Build.VERSION.INCREMENTAL); 9160 dos.writeInt(list.size()); 9161 for (int i=0; i<list.size(); i++) { 9162 dos.writeUTF(list.get(i).getPackageName()); 9163 dos.writeUTF(list.get(i).getClassName()); 9164 } 9165 } catch (IOException e) { 9166 Slog.w(TAG, "Failure writing last done pre-boot receivers", e); 9167 file.delete(); 9168 } finally { 9169 FileUtils.sync(fos); 9170 if (dos != null) { 9171 try { 9172 dos.close(); 9173 } catch (IOException e) { 9174 // TODO Auto-generated catch block 9175 e.printStackTrace(); 9176 } 9177 } 9178 } 9179 } 9180 9181 public void systemReady(final Runnable goingCallback) { 9182 synchronized(this) { 9183 if (mSystemReady) { 9184 if (goingCallback != null) goingCallback.run(); 9185 return; 9186 } 9187 9188 // Check to see if there are any update receivers to run. 9189 if (!mDidUpdate) { 9190 if (mWaitingUpdate) { 9191 return; 9192 } 9193 Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED); 9194 List<ResolveInfo> ris = null; 9195 try { 9196 ris = AppGlobals.getPackageManager().queryIntentReceivers( 9197 intent, null, 0, 0); 9198 } catch (RemoteException e) { 9199 } 9200 if (ris != null) { 9201 for (int i=ris.size()-1; i>=0; i--) { 9202 if ((ris.get(i).activityInfo.applicationInfo.flags 9203 &ApplicationInfo.FLAG_SYSTEM) == 0) { 9204 ris.remove(i); 9205 } 9206 } 9207 intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE); 9208 9209 ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers(); 9210 9211 final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>(); 9212 for (int i=0; i<ris.size(); i++) { 9213 ActivityInfo ai = ris.get(i).activityInfo; 9214 ComponentName comp = new ComponentName(ai.packageName, ai.name); 9215 if (lastDoneReceivers.contains(comp)) { 9216 ris.remove(i); 9217 i--; 9218 } 9219 } 9220 9221 final int[] users = getUsersLocked(); 9222 for (int i=0; i<ris.size(); i++) { 9223 ActivityInfo ai = ris.get(i).activityInfo; 9224 ComponentName comp = new ComponentName(ai.packageName, ai.name); 9225 doneReceivers.add(comp); 9226 intent.setComponent(comp); 9227 for (int j=0; j<users.length; j++) { 9228 IIntentReceiver finisher = null; 9229 if (i == ris.size()-1 && j == users.length-1) { 9230 finisher = new IIntentReceiver.Stub() { 9231 public void performReceive(Intent intent, int resultCode, 9232 String data, Bundle extras, boolean ordered, 9233 boolean sticky, int sendingUser) { 9234 // The raw IIntentReceiver interface is called 9235 // with the AM lock held, so redispatch to 9236 // execute our code without the lock. 9237 mHandler.post(new Runnable() { 9238 public void run() { 9239 synchronized (ActivityManagerService.this) { 9240 mDidUpdate = true; 9241 } 9242 writeLastDonePreBootReceivers(doneReceivers); 9243 showBootMessage(mContext.getText( 9244 R.string.android_upgrading_complete), 9245 false); 9246 systemReady(goingCallback); 9247 } 9248 }); 9249 } 9250 }; 9251 } 9252 Slog.i(TAG, "Sending system update to " + intent.getComponent() 9253 + " for user " + users[j]); 9254 broadcastIntentLocked(null, null, intent, null, finisher, 9255 0, null, null, null, AppOpsManager.OP_NONE, 9256 true, false, MY_PID, Process.SYSTEM_UID, 9257 users[j]); 9258 if (finisher != null) { 9259 mWaitingUpdate = true; 9260 } 9261 } 9262 } 9263 } 9264 if (mWaitingUpdate) { 9265 return; 9266 } 9267 mDidUpdate = true; 9268 } 9269 9270 mAppOpsService.systemReady(); 9271 mSystemReady = true; 9272 if (!mStartRunning) { 9273 return; 9274 } 9275 } 9276 9277 ArrayList<ProcessRecord> procsToKill = null; 9278 synchronized(mPidsSelfLocked) { 9279 for (int i=mPidsSelfLocked.size()-1; i>=0; i--) { 9280 ProcessRecord proc = mPidsSelfLocked.valueAt(i); 9281 if (!isAllowedWhileBooting(proc.info)){ 9282 if (procsToKill == null) { 9283 procsToKill = new ArrayList<ProcessRecord>(); 9284 } 9285 procsToKill.add(proc); 9286 } 9287 } 9288 } 9289 9290 synchronized(this) { 9291 if (procsToKill != null) { 9292 for (int i=procsToKill.size()-1; i>=0; i--) { 9293 ProcessRecord proc = procsToKill.get(i); 9294 Slog.i(TAG, "Removing system update proc: " + proc); 9295 removeProcessLocked(proc, true, false, "system update done"); 9296 } 9297 } 9298 9299 // Now that we have cleaned up any update processes, we 9300 // are ready to start launching real processes and know that 9301 // we won't trample on them any more. 9302 mProcessesReady = true; 9303 } 9304 9305 Slog.i(TAG, "System now ready"); 9306 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY, 9307 SystemClock.uptimeMillis()); 9308 9309 synchronized(this) { 9310 // Make sure we have no pre-ready processes sitting around. 9311 9312 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) { 9313 ResolveInfo ri = mContext.getPackageManager() 9314 .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST), 9315 STOCK_PM_FLAGS); 9316 CharSequence errorMsg = null; 9317 if (ri != null) { 9318 ActivityInfo ai = ri.activityInfo; 9319 ApplicationInfo app = ai.applicationInfo; 9320 if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) { 9321 mTopAction = Intent.ACTION_FACTORY_TEST; 9322 mTopData = null; 9323 mTopComponent = new ComponentName(app.packageName, 9324 ai.name); 9325 } else { 9326 errorMsg = mContext.getResources().getText( 9327 com.android.internal.R.string.factorytest_not_system); 9328 } 9329 } else { 9330 errorMsg = mContext.getResources().getText( 9331 com.android.internal.R.string.factorytest_no_action); 9332 } 9333 if (errorMsg != null) { 9334 mTopAction = null; 9335 mTopData = null; 9336 mTopComponent = null; 9337 Message msg = Message.obtain(); 9338 msg.what = SHOW_FACTORY_ERROR_MSG; 9339 msg.getData().putCharSequence("msg", errorMsg); 9340 mHandler.sendMessage(msg); 9341 } 9342 } 9343 } 9344 9345 retrieveSettings(); 9346 9347 synchronized (this) { 9348 readGrantedUriPermissionsLocked(); 9349 } 9350 9351 if (goingCallback != null) goingCallback.run(); 9352 9353 synchronized (this) { 9354 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 9355 try { 9356 List apps = AppGlobals.getPackageManager(). 9357 getPersistentApplications(STOCK_PM_FLAGS); 9358 if (apps != null) { 9359 int N = apps.size(); 9360 int i; 9361 for (i=0; i<N; i++) { 9362 ApplicationInfo info 9363 = (ApplicationInfo)apps.get(i); 9364 if (info != null && 9365 !info.packageName.equals("android")) { 9366 addAppLocked(info, false); 9367 } 9368 } 9369 } 9370 } catch (RemoteException ex) { 9371 // pm is in same process, this will never happen. 9372 } 9373 } 9374 9375 // Start up initial activity. 9376 mBooting = true; 9377 9378 try { 9379 if (AppGlobals.getPackageManager().hasSystemUidErrors()) { 9380 Message msg = Message.obtain(); 9381 msg.what = SHOW_UID_ERROR_MSG; 9382 mHandler.sendMessage(msg); 9383 } 9384 } catch (RemoteException e) { 9385 } 9386 9387 long ident = Binder.clearCallingIdentity(); 9388 try { 9389 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 9390 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 9391 | Intent.FLAG_RECEIVER_FOREGROUND); 9392 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); 9393 broadcastIntentLocked(null, null, intent, 9394 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 9395 false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId); 9396 intent = new Intent(Intent.ACTION_USER_STARTING); 9397 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 9398 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); 9399 broadcastIntentLocked(null, null, intent, 9400 null, new IIntentReceiver.Stub() { 9401 @Override 9402 public void performReceive(Intent intent, int resultCode, String data, 9403 Bundle extras, boolean ordered, boolean sticky, int sendingUser) 9404 throws RemoteException { 9405 } 9406 }, 0, null, null, 9407 android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 9408 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 9409 } finally { 9410 Binder.restoreCallingIdentity(ident); 9411 } 9412 mStackSupervisor.resumeTopActivitiesLocked(); 9413 sendUserSwitchBroadcastsLocked(-1, mCurrentUserId); 9414 } 9415 } 9416 9417 private boolean makeAppCrashingLocked(ProcessRecord app, 9418 String shortMsg, String longMsg, String stackTrace) { 9419 app.crashing = true; 9420 app.crashingReport = generateProcessError(app, 9421 ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace); 9422 startAppProblemLocked(app); 9423 app.stopFreezingAllLocked(); 9424 return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace); 9425 } 9426 9427 private void makeAppNotRespondingLocked(ProcessRecord app, 9428 String activity, String shortMsg, String longMsg) { 9429 app.notResponding = true; 9430 app.notRespondingReport = generateProcessError(app, 9431 ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING, 9432 activity, shortMsg, longMsg, null); 9433 startAppProblemLocked(app); 9434 app.stopFreezingAllLocked(); 9435 } 9436 9437 /** 9438 * Generate a process error record, suitable for attachment to a ProcessRecord. 9439 * 9440 * @param app The ProcessRecord in which the error occurred. 9441 * @param condition Crashing, Application Not Responding, etc. Values are defined in 9442 * ActivityManager.AppErrorStateInfo 9443 * @param activity The activity associated with the crash, if known. 9444 * @param shortMsg Short message describing the crash. 9445 * @param longMsg Long message describing the crash. 9446 * @param stackTrace Full crash stack trace, may be null. 9447 * 9448 * @return Returns a fully-formed AppErrorStateInfo record. 9449 */ 9450 private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app, 9451 int condition, String activity, String shortMsg, String longMsg, String stackTrace) { 9452 ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo(); 9453 9454 report.condition = condition; 9455 report.processName = app.processName; 9456 report.pid = app.pid; 9457 report.uid = app.info.uid; 9458 report.tag = activity; 9459 report.shortMsg = shortMsg; 9460 report.longMsg = longMsg; 9461 report.stackTrace = stackTrace; 9462 9463 return report; 9464 } 9465 9466 void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) { 9467 synchronized (this) { 9468 app.crashing = false; 9469 app.crashingReport = null; 9470 app.notResponding = false; 9471 app.notRespondingReport = null; 9472 if (app.anrDialog == fromDialog) { 9473 app.anrDialog = null; 9474 } 9475 if (app.waitDialog == fromDialog) { 9476 app.waitDialog = null; 9477 } 9478 if (app.pid > 0 && app.pid != MY_PID) { 9479 handleAppCrashLocked(app, null, null, null); 9480 killUnneededProcessLocked(app, "user request after error"); 9481 } 9482 } 9483 } 9484 9485 private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg, 9486 String stackTrace) { 9487 long now = SystemClock.uptimeMillis(); 9488 9489 Long crashTime; 9490 if (!app.isolated) { 9491 crashTime = mProcessCrashTimes.get(app.info.processName, app.uid); 9492 } else { 9493 crashTime = null; 9494 } 9495 if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) { 9496 // This process loses! 9497 Slog.w(TAG, "Process " + app.info.processName 9498 + " has crashed too many times: killing!"); 9499 EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH, 9500 app.userId, app.info.processName, app.uid); 9501 mStackSupervisor.handleAppCrashLocked(app); 9502 if (!app.persistent) { 9503 // We don't want to start this process again until the user 9504 // explicitly does so... but for persistent process, we really 9505 // need to keep it running. If a persistent process is actually 9506 // repeatedly crashing, then badness for everyone. 9507 EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid, 9508 app.info.processName); 9509 if (!app.isolated) { 9510 // XXX We don't have a way to mark isolated processes 9511 // as bad, since they don't have a peristent identity. 9512 mBadProcesses.put(app.info.processName, app.uid, 9513 new BadProcessInfo(now, shortMsg, longMsg, stackTrace)); 9514 mProcessCrashTimes.remove(app.info.processName, app.uid); 9515 } 9516 app.bad = true; 9517 app.removed = true; 9518 // Don't let services in this process be restarted and potentially 9519 // annoy the user repeatedly. Unless it is persistent, since those 9520 // processes run critical code. 9521 removeProcessLocked(app, false, false, "crash"); 9522 mStackSupervisor.resumeTopActivitiesLocked(); 9523 return false; 9524 } 9525 mStackSupervisor.resumeTopActivitiesLocked(); 9526 } else { 9527 mStackSupervisor.finishTopRunningActivityLocked(app); 9528 } 9529 9530 // Bump up the crash count of any services currently running in the proc. 9531 for (int i=app.services.size()-1; i>=0; i--) { 9532 // Any services running in the application need to be placed 9533 // back in the pending list. 9534 ServiceRecord sr = app.services.valueAt(i); 9535 sr.crashCount++; 9536 } 9537 9538 // If the crashing process is what we consider to be the "home process" and it has been 9539 // replaced by a third-party app, clear the package preferred activities from packages 9540 // with a home activity running in the process to prevent a repeatedly crashing app 9541 // from blocking the user to manually clear the list. 9542 final ArrayList<ActivityRecord> activities = app.activities; 9543 if (app == mHomeProcess && activities.size() > 0 9544 && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) { 9545 for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) { 9546 final ActivityRecord r = activities.get(activityNdx); 9547 if (r.isHomeActivity()) { 9548 Log.i(TAG, "Clearing package preferred activities from " + r.packageName); 9549 try { 9550 ActivityThread.getPackageManager() 9551 .clearPackagePreferredActivities(r.packageName); 9552 } catch (RemoteException c) { 9553 // pm is in same process, this will never happen. 9554 } 9555 } 9556 } 9557 } 9558 9559 if (!app.isolated) { 9560 // XXX Can't keep track of crash times for isolated processes, 9561 // because they don't have a perisistent identity. 9562 mProcessCrashTimes.put(app.info.processName, app.uid, now); 9563 } 9564 9565 return true; 9566 } 9567 9568 void startAppProblemLocked(ProcessRecord app) { 9569 if (app.userId == mCurrentUserId) { 9570 app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver( 9571 mContext, app.info.packageName, app.info.flags); 9572 } else { 9573 // If this app is not running under the current user, then we 9574 // can't give it a report button because that would require 9575 // launching the report UI under a different user. 9576 app.errorReportReceiver = null; 9577 } 9578 skipCurrentReceiverLocked(app); 9579 } 9580 9581 void skipCurrentReceiverLocked(ProcessRecord app) { 9582 for (BroadcastQueue queue : mBroadcastQueues) { 9583 queue.skipCurrentReceiverLocked(app); 9584 } 9585 } 9586 9587 /** 9588 * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes. 9589 * The application process will exit immediately after this call returns. 9590 * @param app object of the crashing app, null for the system server 9591 * @param crashInfo describing the exception 9592 */ 9593 public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) { 9594 ProcessRecord r = findAppProcess(app, "Crash"); 9595 final String processName = app == null ? "system_server" 9596 : (r == null ? "unknown" : r.processName); 9597 9598 handleApplicationCrashInner("crash", r, processName, crashInfo); 9599 } 9600 9601 /* Native crash reporting uses this inner version because it needs to be somewhat 9602 * decoupled from the AM-managed cleanup lifecycle 9603 */ 9604 void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName, 9605 ApplicationErrorReport.CrashInfo crashInfo) { 9606 EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(), 9607 UserHandle.getUserId(Binder.getCallingUid()), processName, 9608 r == null ? -1 : r.info.flags, 9609 crashInfo.exceptionClassName, 9610 crashInfo.exceptionMessage, 9611 crashInfo.throwFileName, 9612 crashInfo.throwLineNumber); 9613 9614 addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo); 9615 9616 crashApplication(r, crashInfo); 9617 } 9618 9619 public void handleApplicationStrictModeViolation( 9620 IBinder app, 9621 int violationMask, 9622 StrictMode.ViolationInfo info) { 9623 ProcessRecord r = findAppProcess(app, "StrictMode"); 9624 if (r == null) { 9625 return; 9626 } 9627 9628 if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) { 9629 Integer stackFingerprint = info.hashCode(); 9630 boolean logIt = true; 9631 synchronized (mAlreadyLoggedViolatedStacks) { 9632 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) { 9633 logIt = false; 9634 // TODO: sub-sample into EventLog for these, with 9635 // the info.durationMillis? Then we'd get 9636 // the relative pain numbers, without logging all 9637 // the stack traces repeatedly. We'd want to do 9638 // likewise in the client code, which also does 9639 // dup suppression, before the Binder call. 9640 } else { 9641 if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) { 9642 mAlreadyLoggedViolatedStacks.clear(); 9643 } 9644 mAlreadyLoggedViolatedStacks.add(stackFingerprint); 9645 } 9646 } 9647 if (logIt) { 9648 logStrictModeViolationToDropBox(r, info); 9649 } 9650 } 9651 9652 if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) { 9653 AppErrorResult result = new AppErrorResult(); 9654 synchronized (this) { 9655 final long origId = Binder.clearCallingIdentity(); 9656 9657 Message msg = Message.obtain(); 9658 msg.what = SHOW_STRICT_MODE_VIOLATION_MSG; 9659 HashMap<String, Object> data = new HashMap<String, Object>(); 9660 data.put("result", result); 9661 data.put("app", r); 9662 data.put("violationMask", violationMask); 9663 data.put("info", info); 9664 msg.obj = data; 9665 mHandler.sendMessage(msg); 9666 9667 Binder.restoreCallingIdentity(origId); 9668 } 9669 int res = result.get(); 9670 Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res); 9671 } 9672 } 9673 9674 // Depending on the policy in effect, there could be a bunch of 9675 // these in quick succession so we try to batch these together to 9676 // minimize disk writes, number of dropbox entries, and maximize 9677 // compression, by having more fewer, larger records. 9678 private void logStrictModeViolationToDropBox( 9679 ProcessRecord process, 9680 StrictMode.ViolationInfo info) { 9681 if (info == null) { 9682 return; 9683 } 9684 final boolean isSystemApp = process == null || 9685 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM | 9686 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0; 9687 final String processName = process == null ? "unknown" : process.processName; 9688 final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode"; 9689 final DropBoxManager dbox = (DropBoxManager) 9690 mContext.getSystemService(Context.DROPBOX_SERVICE); 9691 9692 // Exit early if the dropbox isn't configured to accept this report type. 9693 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 9694 9695 boolean bufferWasEmpty; 9696 boolean needsFlush; 9697 final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024); 9698 synchronized (sb) { 9699 bufferWasEmpty = sb.length() == 0; 9700 appendDropBoxProcessHeaders(process, processName, sb); 9701 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 9702 sb.append("System-App: ").append(isSystemApp).append("\n"); 9703 sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n"); 9704 if (info.violationNumThisLoop != 0) { 9705 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n"); 9706 } 9707 if (info.numAnimationsRunning != 0) { 9708 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n"); 9709 } 9710 if (info.broadcastIntentAction != null) { 9711 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n"); 9712 } 9713 if (info.durationMillis != -1) { 9714 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n"); 9715 } 9716 if (info.numInstances != -1) { 9717 sb.append("Instance-Count: ").append(info.numInstances).append("\n"); 9718 } 9719 if (info.tags != null) { 9720 for (String tag : info.tags) { 9721 sb.append("Span-Tag: ").append(tag).append("\n"); 9722 } 9723 } 9724 sb.append("\n"); 9725 if (info.crashInfo != null && info.crashInfo.stackTrace != null) { 9726 sb.append(info.crashInfo.stackTrace); 9727 } 9728 sb.append("\n"); 9729 9730 // Only buffer up to ~64k. Various logging bits truncate 9731 // things at 128k. 9732 needsFlush = (sb.length() > 64 * 1024); 9733 } 9734 9735 // Flush immediately if the buffer's grown too large, or this 9736 // is a non-system app. Non-system apps are isolated with a 9737 // different tag & policy and not batched. 9738 // 9739 // Batching is useful during internal testing with 9740 // StrictMode settings turned up high. Without batching, 9741 // thousands of separate files could be created on boot. 9742 if (!isSystemApp || needsFlush) { 9743 new Thread("Error dump: " + dropboxTag) { 9744 @Override 9745 public void run() { 9746 String report; 9747 synchronized (sb) { 9748 report = sb.toString(); 9749 sb.delete(0, sb.length()); 9750 sb.trimToSize(); 9751 } 9752 if (report.length() != 0) { 9753 dbox.addText(dropboxTag, report); 9754 } 9755 } 9756 }.start(); 9757 return; 9758 } 9759 9760 // System app batching: 9761 if (!bufferWasEmpty) { 9762 // An existing dropbox-writing thread is outstanding, so 9763 // we don't need to start it up. The existing thread will 9764 // catch the buffer appends we just did. 9765 return; 9766 } 9767 9768 // Worker thread to both batch writes and to avoid blocking the caller on I/O. 9769 // (After this point, we shouldn't access AMS internal data structures.) 9770 new Thread("Error dump: " + dropboxTag) { 9771 @Override 9772 public void run() { 9773 // 5 second sleep to let stacks arrive and be batched together 9774 try { 9775 Thread.sleep(5000); // 5 seconds 9776 } catch (InterruptedException e) {} 9777 9778 String errorReport; 9779 synchronized (mStrictModeBuffer) { 9780 errorReport = mStrictModeBuffer.toString(); 9781 if (errorReport.length() == 0) { 9782 return; 9783 } 9784 mStrictModeBuffer.delete(0, mStrictModeBuffer.length()); 9785 mStrictModeBuffer.trimToSize(); 9786 } 9787 dbox.addText(dropboxTag, errorReport); 9788 } 9789 }.start(); 9790 } 9791 9792 /** 9793 * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors. 9794 * @param app object of the crashing app, null for the system server 9795 * @param tag reported by the caller 9796 * @param crashInfo describing the context of the error 9797 * @return true if the process should exit immediately (WTF is fatal) 9798 */ 9799 public boolean handleApplicationWtf(IBinder app, String tag, 9800 ApplicationErrorReport.CrashInfo crashInfo) { 9801 ProcessRecord r = findAppProcess(app, "WTF"); 9802 final String processName = app == null ? "system_server" 9803 : (r == null ? "unknown" : r.processName); 9804 9805 EventLog.writeEvent(EventLogTags.AM_WTF, 9806 UserHandle.getUserId(Binder.getCallingUid()), Binder.getCallingPid(), 9807 processName, 9808 r == null ? -1 : r.info.flags, 9809 tag, crashInfo.exceptionMessage); 9810 9811 addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo); 9812 9813 if (r != null && r.pid != Process.myPid() && 9814 Settings.Global.getInt(mContext.getContentResolver(), 9815 Settings.Global.WTF_IS_FATAL, 0) != 0) { 9816 crashApplication(r, crashInfo); 9817 return true; 9818 } else { 9819 return false; 9820 } 9821 } 9822 9823 /** 9824 * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit}) 9825 * @return the corresponding {@link ProcessRecord} object, or null if none could be found 9826 */ 9827 private ProcessRecord findAppProcess(IBinder app, String reason) { 9828 if (app == null) { 9829 return null; 9830 } 9831 9832 synchronized (this) { 9833 final int NP = mProcessNames.getMap().size(); 9834 for (int ip=0; ip<NP; ip++) { 9835 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 9836 final int NA = apps.size(); 9837 for (int ia=0; ia<NA; ia++) { 9838 ProcessRecord p = apps.valueAt(ia); 9839 if (p.thread != null && p.thread.asBinder() == app) { 9840 return p; 9841 } 9842 } 9843 } 9844 9845 Slog.w(TAG, "Can't find mystery application for " + reason 9846 + " from pid=" + Binder.getCallingPid() 9847 + " uid=" + Binder.getCallingUid() + ": " + app); 9848 return null; 9849 } 9850 } 9851 9852 /** 9853 * Utility function for addErrorToDropBox and handleStrictModeViolation's logging 9854 * to append various headers to the dropbox log text. 9855 */ 9856 private void appendDropBoxProcessHeaders(ProcessRecord process, String processName, 9857 StringBuilder sb) { 9858 // Watchdog thread ends up invoking this function (with 9859 // a null ProcessRecord) to add the stack file to dropbox. 9860 // Do not acquire a lock on this (am) in such cases, as it 9861 // could cause a potential deadlock, if and when watchdog 9862 // is invoked due to unavailability of lock on am and it 9863 // would prevent watchdog from killing system_server. 9864 if (process == null) { 9865 sb.append("Process: ").append(processName).append("\n"); 9866 return; 9867 } 9868 // Note: ProcessRecord 'process' is guarded by the service 9869 // instance. (notably process.pkgList, which could otherwise change 9870 // concurrently during execution of this method) 9871 synchronized (this) { 9872 sb.append("Process: ").append(processName).append("\n"); 9873 int flags = process.info.flags; 9874 IPackageManager pm = AppGlobals.getPackageManager(); 9875 sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n"); 9876 for (int ip=0; ip<process.pkgList.size(); ip++) { 9877 String pkg = process.pkgList.keyAt(ip); 9878 sb.append("Package: ").append(pkg); 9879 try { 9880 PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId()); 9881 if (pi != null) { 9882 sb.append(" v").append(pi.versionCode); 9883 if (pi.versionName != null) { 9884 sb.append(" (").append(pi.versionName).append(")"); 9885 } 9886 } 9887 } catch (RemoteException e) { 9888 Slog.e(TAG, "Error getting package info: " + pkg, e); 9889 } 9890 sb.append("\n"); 9891 } 9892 } 9893 } 9894 9895 private static String processClass(ProcessRecord process) { 9896 if (process == null || process.pid == MY_PID) { 9897 return "system_server"; 9898 } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) { 9899 return "system_app"; 9900 } else { 9901 return "data_app"; 9902 } 9903 } 9904 9905 /** 9906 * Write a description of an error (crash, WTF, ANR) to the drop box. 9907 * @param eventType to include in the drop box tag ("crash", "wtf", etc.) 9908 * @param process which caused the error, null means the system server 9909 * @param activity which triggered the error, null if unknown 9910 * @param parent activity related to the error, null if unknown 9911 * @param subject line related to the error, null if absent 9912 * @param report in long form describing the error, null if absent 9913 * @param logFile to include in the report, null if none 9914 * @param crashInfo giving an application stack trace, null if absent 9915 */ 9916 public void addErrorToDropBox(String eventType, 9917 ProcessRecord process, String processName, ActivityRecord activity, 9918 ActivityRecord parent, String subject, 9919 final String report, final File logFile, 9920 final ApplicationErrorReport.CrashInfo crashInfo) { 9921 // NOTE -- this must never acquire the ActivityManagerService lock, 9922 // otherwise the watchdog may be prevented from resetting the system. 9923 9924 final String dropboxTag = processClass(process) + "_" + eventType; 9925 final DropBoxManager dbox = (DropBoxManager) 9926 mContext.getSystemService(Context.DROPBOX_SERVICE); 9927 9928 // Exit early if the dropbox isn't configured to accept this report type. 9929 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 9930 9931 final StringBuilder sb = new StringBuilder(1024); 9932 appendDropBoxProcessHeaders(process, processName, sb); 9933 if (activity != null) { 9934 sb.append("Activity: ").append(activity.shortComponentName).append("\n"); 9935 } 9936 if (parent != null && parent.app != null && parent.app.pid != process.pid) { 9937 sb.append("Parent-Process: ").append(parent.app.processName).append("\n"); 9938 } 9939 if (parent != null && parent != activity) { 9940 sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n"); 9941 } 9942 if (subject != null) { 9943 sb.append("Subject: ").append(subject).append("\n"); 9944 } 9945 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 9946 if (Debug.isDebuggerConnected()) { 9947 sb.append("Debugger: Connected\n"); 9948 } 9949 sb.append("\n"); 9950 9951 // Do the rest in a worker thread to avoid blocking the caller on I/O 9952 // (After this point, we shouldn't access AMS internal data structures.) 9953 Thread worker = new Thread("Error dump: " + dropboxTag) { 9954 @Override 9955 public void run() { 9956 if (report != null) { 9957 sb.append(report); 9958 } 9959 if (logFile != null) { 9960 try { 9961 sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE, 9962 "\n\n[[TRUNCATED]]")); 9963 } catch (IOException e) { 9964 Slog.e(TAG, "Error reading " + logFile, e); 9965 } 9966 } 9967 if (crashInfo != null && crashInfo.stackTrace != null) { 9968 sb.append(crashInfo.stackTrace); 9969 } 9970 9971 String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag; 9972 int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0); 9973 if (lines > 0) { 9974 sb.append("\n"); 9975 9976 // Merge several logcat streams, and take the last N lines 9977 InputStreamReader input = null; 9978 try { 9979 java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat", 9980 "-v", "time", "-b", "events", "-b", "system", "-b", "main", 9981 "-t", String.valueOf(lines)).redirectErrorStream(true).start(); 9982 9983 try { logcat.getOutputStream().close(); } catch (IOException e) {} 9984 try { logcat.getErrorStream().close(); } catch (IOException e) {} 9985 input = new InputStreamReader(logcat.getInputStream()); 9986 9987 int num; 9988 char[] buf = new char[8192]; 9989 while ((num = input.read(buf)) > 0) sb.append(buf, 0, num); 9990 } catch (IOException e) { 9991 Slog.e(TAG, "Error running logcat", e); 9992 } finally { 9993 if (input != null) try { input.close(); } catch (IOException e) {} 9994 } 9995 } 9996 9997 dbox.addText(dropboxTag, sb.toString()); 9998 } 9999 }; 10000 10001 if (process == null) { 10002 // If process is null, we are being called from some internal code 10003 // and may be about to die -- run this synchronously. 10004 worker.run(); 10005 } else { 10006 worker.start(); 10007 } 10008 } 10009 10010 /** 10011 * Bring up the "unexpected error" dialog box for a crashing app. 10012 * Deal with edge cases (intercepts from instrumented applications, 10013 * ActivityController, error intent receivers, that sort of thing). 10014 * @param r the application crashing 10015 * @param crashInfo describing the failure 10016 */ 10017 private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) { 10018 long timeMillis = System.currentTimeMillis(); 10019 String shortMsg = crashInfo.exceptionClassName; 10020 String longMsg = crashInfo.exceptionMessage; 10021 String stackTrace = crashInfo.stackTrace; 10022 if (shortMsg != null && longMsg != null) { 10023 longMsg = shortMsg + ": " + longMsg; 10024 } else if (shortMsg != null) { 10025 longMsg = shortMsg; 10026 } 10027 10028 AppErrorResult result = new AppErrorResult(); 10029 synchronized (this) { 10030 if (mController != null) { 10031 try { 10032 String name = r != null ? r.processName : null; 10033 int pid = r != null ? r.pid : Binder.getCallingPid(); 10034 if (!mController.appCrashed(name, pid, 10035 shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) { 10036 Slog.w(TAG, "Force-killing crashed app " + name 10037 + " at watcher's request"); 10038 Process.killProcess(pid); 10039 return; 10040 } 10041 } catch (RemoteException e) { 10042 mController = null; 10043 Watchdog.getInstance().setActivityController(null); 10044 } 10045 } 10046 10047 final long origId = Binder.clearCallingIdentity(); 10048 10049 // If this process is running instrumentation, finish it. 10050 if (r != null && r.instrumentationClass != null) { 10051 Slog.w(TAG, "Error in app " + r.processName 10052 + " running instrumentation " + r.instrumentationClass + ":"); 10053 if (shortMsg != null) Slog.w(TAG, " " + shortMsg); 10054 if (longMsg != null) Slog.w(TAG, " " + longMsg); 10055 Bundle info = new Bundle(); 10056 info.putString("shortMsg", shortMsg); 10057 info.putString("longMsg", longMsg); 10058 finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info); 10059 Binder.restoreCallingIdentity(origId); 10060 return; 10061 } 10062 10063 // If we can't identify the process or it's already exceeded its crash quota, 10064 // quit right away without showing a crash dialog. 10065 if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) { 10066 Binder.restoreCallingIdentity(origId); 10067 return; 10068 } 10069 10070 Message msg = Message.obtain(); 10071 msg.what = SHOW_ERROR_MSG; 10072 HashMap data = new HashMap(); 10073 data.put("result", result); 10074 data.put("app", r); 10075 msg.obj = data; 10076 mHandler.sendMessage(msg); 10077 10078 Binder.restoreCallingIdentity(origId); 10079 } 10080 10081 int res = result.get(); 10082 10083 Intent appErrorIntent = null; 10084 synchronized (this) { 10085 if (r != null && !r.isolated) { 10086 // XXX Can't keep track of crash time for isolated processes, 10087 // since they don't have a persistent identity. 10088 mProcessCrashTimes.put(r.info.processName, r.uid, 10089 SystemClock.uptimeMillis()); 10090 } 10091 if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) { 10092 appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo); 10093 } 10094 } 10095 10096 if (appErrorIntent != null) { 10097 try { 10098 mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId)); 10099 } catch (ActivityNotFoundException e) { 10100 Slog.w(TAG, "bug report receiver dissappeared", e); 10101 } 10102 } 10103 } 10104 10105 Intent createAppErrorIntentLocked(ProcessRecord r, 10106 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 10107 ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo); 10108 if (report == null) { 10109 return null; 10110 } 10111 Intent result = new Intent(Intent.ACTION_APP_ERROR); 10112 result.setComponent(r.errorReportReceiver); 10113 result.putExtra(Intent.EXTRA_BUG_REPORT, report); 10114 result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 10115 return result; 10116 } 10117 10118 private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r, 10119 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 10120 if (r.errorReportReceiver == null) { 10121 return null; 10122 } 10123 10124 if (!r.crashing && !r.notResponding && !r.forceCrashReport) { 10125 return null; 10126 } 10127 10128 ApplicationErrorReport report = new ApplicationErrorReport(); 10129 report.packageName = r.info.packageName; 10130 report.installerPackageName = r.errorReportReceiver.getPackageName(); 10131 report.processName = r.processName; 10132 report.time = timeMillis; 10133 report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0; 10134 10135 if (r.crashing || r.forceCrashReport) { 10136 report.type = ApplicationErrorReport.TYPE_CRASH; 10137 report.crashInfo = crashInfo; 10138 } else if (r.notResponding) { 10139 report.type = ApplicationErrorReport.TYPE_ANR; 10140 report.anrInfo = new ApplicationErrorReport.AnrInfo(); 10141 10142 report.anrInfo.activity = r.notRespondingReport.tag; 10143 report.anrInfo.cause = r.notRespondingReport.shortMsg; 10144 report.anrInfo.info = r.notRespondingReport.longMsg; 10145 } 10146 10147 return report; 10148 } 10149 10150 public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() { 10151 enforceNotIsolatedCaller("getProcessesInErrorState"); 10152 // assume our apps are happy - lazy create the list 10153 List<ActivityManager.ProcessErrorStateInfo> errList = null; 10154 10155 final boolean allUsers = ActivityManager.checkUidPermission( 10156 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 10157 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 10158 int userId = UserHandle.getUserId(Binder.getCallingUid()); 10159 10160 synchronized (this) { 10161 10162 // iterate across all processes 10163 for (int i=mLruProcesses.size()-1; i>=0; i--) { 10164 ProcessRecord app = mLruProcesses.get(i); 10165 if (!allUsers && app.userId != userId) { 10166 continue; 10167 } 10168 if ((app.thread != null) && (app.crashing || app.notResponding)) { 10169 // This one's in trouble, so we'll generate a report for it 10170 // crashes are higher priority (in case there's a crash *and* an anr) 10171 ActivityManager.ProcessErrorStateInfo report = null; 10172 if (app.crashing) { 10173 report = app.crashingReport; 10174 } else if (app.notResponding) { 10175 report = app.notRespondingReport; 10176 } 10177 10178 if (report != null) { 10179 if (errList == null) { 10180 errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1); 10181 } 10182 errList.add(report); 10183 } else { 10184 Slog.w(TAG, "Missing app error report, app = " + app.processName + 10185 " crashing = " + app.crashing + 10186 " notResponding = " + app.notResponding); 10187 } 10188 } 10189 } 10190 } 10191 10192 return errList; 10193 } 10194 10195 static int oomAdjToImportance(int adj, ActivityManager.RunningAppProcessInfo currApp) { 10196 if (adj >= ProcessList.CACHED_APP_MIN_ADJ) { 10197 if (currApp != null) { 10198 currApp.lru = adj - ProcessList.CACHED_APP_MIN_ADJ + 1; 10199 } 10200 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 10201 } else if (adj >= ProcessList.SERVICE_B_ADJ) { 10202 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 10203 } else if (adj >= ProcessList.HOME_APP_ADJ) { 10204 if (currApp != null) { 10205 currApp.lru = 0; 10206 } 10207 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 10208 } else if (adj >= ProcessList.SERVICE_ADJ) { 10209 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 10210 } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 10211 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE; 10212 } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) { 10213 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE; 10214 } else if (adj >= ProcessList.VISIBLE_APP_ADJ) { 10215 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE; 10216 } else { 10217 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND; 10218 } 10219 } 10220 10221 private void fillInProcMemInfo(ProcessRecord app, 10222 ActivityManager.RunningAppProcessInfo outInfo) { 10223 outInfo.pid = app.pid; 10224 outInfo.uid = app.info.uid; 10225 if (mHeavyWeightProcess == app) { 10226 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE; 10227 } 10228 if (app.persistent) { 10229 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT; 10230 } 10231 if (app.activities.size() > 0) { 10232 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES; 10233 } 10234 outInfo.lastTrimLevel = app.trimMemoryLevel; 10235 int adj = app.curAdj; 10236 outInfo.importance = oomAdjToImportance(adj, outInfo); 10237 outInfo.importanceReasonCode = app.adjTypeCode; 10238 } 10239 10240 public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() { 10241 enforceNotIsolatedCaller("getRunningAppProcesses"); 10242 // Lazy instantiation of list 10243 List<ActivityManager.RunningAppProcessInfo> runList = null; 10244 final boolean allUsers = ActivityManager.checkUidPermission( 10245 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 10246 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 10247 int userId = UserHandle.getUserId(Binder.getCallingUid()); 10248 synchronized (this) { 10249 // Iterate across all processes 10250 for (int i=mLruProcesses.size()-1; i>=0; i--) { 10251 ProcessRecord app = mLruProcesses.get(i); 10252 if (!allUsers && app.userId != userId) { 10253 continue; 10254 } 10255 if ((app.thread != null) && (!app.crashing && !app.notResponding)) { 10256 // Generate process state info for running application 10257 ActivityManager.RunningAppProcessInfo currApp = 10258 new ActivityManager.RunningAppProcessInfo(app.processName, 10259 app.pid, app.getPackageList()); 10260 fillInProcMemInfo(app, currApp); 10261 if (app.adjSource instanceof ProcessRecord) { 10262 currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid; 10263 currApp.importanceReasonImportance = oomAdjToImportance( 10264 app.adjSourceOom, null); 10265 } else if (app.adjSource instanceof ActivityRecord) { 10266 ActivityRecord r = (ActivityRecord)app.adjSource; 10267 if (r.app != null) currApp.importanceReasonPid = r.app.pid; 10268 } 10269 if (app.adjTarget instanceof ComponentName) { 10270 currApp.importanceReasonComponent = (ComponentName)app.adjTarget; 10271 } 10272 //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance 10273 // + " lru=" + currApp.lru); 10274 if (runList == null) { 10275 runList = new ArrayList<ActivityManager.RunningAppProcessInfo>(); 10276 } 10277 runList.add(currApp); 10278 } 10279 } 10280 } 10281 return runList; 10282 } 10283 10284 public List<ApplicationInfo> getRunningExternalApplications() { 10285 enforceNotIsolatedCaller("getRunningExternalApplications"); 10286 List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses(); 10287 List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>(); 10288 if (runningApps != null && runningApps.size() > 0) { 10289 Set<String> extList = new HashSet<String>(); 10290 for (ActivityManager.RunningAppProcessInfo app : runningApps) { 10291 if (app.pkgList != null) { 10292 for (String pkg : app.pkgList) { 10293 extList.add(pkg); 10294 } 10295 } 10296 } 10297 IPackageManager pm = AppGlobals.getPackageManager(); 10298 for (String pkg : extList) { 10299 try { 10300 ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId()); 10301 if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) { 10302 retList.add(info); 10303 } 10304 } catch (RemoteException e) { 10305 } 10306 } 10307 } 10308 return retList; 10309 } 10310 10311 @Override 10312 public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) { 10313 enforceNotIsolatedCaller("getMyMemoryState"); 10314 synchronized (this) { 10315 ProcessRecord proc; 10316 synchronized (mPidsSelfLocked) { 10317 proc = mPidsSelfLocked.get(Binder.getCallingPid()); 10318 } 10319 fillInProcMemInfo(proc, outInfo); 10320 } 10321 } 10322 10323 @Override 10324 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 10325 if (checkCallingPermission(android.Manifest.permission.DUMP) 10326 != PackageManager.PERMISSION_GRANTED) { 10327 pw.println("Permission Denial: can't dump ActivityManager from from pid=" 10328 + Binder.getCallingPid() 10329 + ", uid=" + Binder.getCallingUid() 10330 + " without permission " 10331 + android.Manifest.permission.DUMP); 10332 return; 10333 } 10334 10335 boolean dumpAll = false; 10336 boolean dumpClient = false; 10337 String dumpPackage = null; 10338 10339 int opti = 0; 10340 while (opti < args.length) { 10341 String opt = args[opti]; 10342 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 10343 break; 10344 } 10345 opti++; 10346 if ("-a".equals(opt)) { 10347 dumpAll = true; 10348 } else if ("-c".equals(opt)) { 10349 dumpClient = true; 10350 } else if ("-h".equals(opt)) { 10351 pw.println("Activity manager dump options:"); 10352 pw.println(" [-a] [-c] [-h] [cmd] ..."); 10353 pw.println(" cmd may be one of:"); 10354 pw.println(" a[ctivities]: activity stack state"); 10355 pw.println(" b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state"); 10356 pw.println(" i[ntents] [PACKAGE_NAME]: pending intent state"); 10357 pw.println(" p[rocesses] [PACKAGE_NAME]: process state"); 10358 pw.println(" o[om]: out of memory management"); 10359 pw.println(" prov[iders] [COMP_SPEC ...]: content provider state"); 10360 pw.println(" provider [COMP_SPEC]: provider client-side state"); 10361 pw.println(" s[ervices] [COMP_SPEC ...]: service state"); 10362 pw.println(" service [COMP_SPEC]: service client-side state"); 10363 pw.println(" package [PACKAGE_NAME]: all state related to given package"); 10364 pw.println(" all: dump all activities"); 10365 pw.println(" top: dump the top activity"); 10366 pw.println(" cmd may also be a COMP_SPEC to dump activities."); 10367 pw.println(" COMP_SPEC may be a component name (com.foo/.myApp),"); 10368 pw.println(" a partial substring in a component name, a"); 10369 pw.println(" hex object identifier."); 10370 pw.println(" -a: include all available server state."); 10371 pw.println(" -c: include client state."); 10372 return; 10373 } else { 10374 pw.println("Unknown argument: " + opt + "; use -h for help"); 10375 } 10376 } 10377 10378 long origId = Binder.clearCallingIdentity(); 10379 boolean more = false; 10380 // Is the caller requesting to dump a particular piece of data? 10381 if (opti < args.length) { 10382 String cmd = args[opti]; 10383 opti++; 10384 if ("activities".equals(cmd) || "a".equals(cmd)) { 10385 synchronized (this) { 10386 dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null); 10387 } 10388 } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) { 10389 String[] newArgs; 10390 String name; 10391 if (opti >= args.length) { 10392 name = null; 10393 newArgs = EMPTY_STRING_ARRAY; 10394 } else { 10395 name = args[opti]; 10396 opti++; 10397 newArgs = new String[args.length - opti]; 10398 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 10399 args.length - opti); 10400 } 10401 synchronized (this) { 10402 dumpBroadcastsLocked(fd, pw, args, opti, true, name); 10403 } 10404 } else if ("intents".equals(cmd) || "i".equals(cmd)) { 10405 String[] newArgs; 10406 String name; 10407 if (opti >= args.length) { 10408 name = null; 10409 newArgs = EMPTY_STRING_ARRAY; 10410 } else { 10411 name = args[opti]; 10412 opti++; 10413 newArgs = new String[args.length - opti]; 10414 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 10415 args.length - opti); 10416 } 10417 synchronized (this) { 10418 dumpPendingIntentsLocked(fd, pw, args, opti, true, name); 10419 } 10420 } else if ("processes".equals(cmd) || "p".equals(cmd)) { 10421 String[] newArgs; 10422 String name; 10423 if (opti >= args.length) { 10424 name = null; 10425 newArgs = EMPTY_STRING_ARRAY; 10426 } else { 10427 name = args[opti]; 10428 opti++; 10429 newArgs = new String[args.length - opti]; 10430 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 10431 args.length - opti); 10432 } 10433 synchronized (this) { 10434 dumpProcessesLocked(fd, pw, args, opti, true, name); 10435 } 10436 } else if ("oom".equals(cmd) || "o".equals(cmd)) { 10437 synchronized (this) { 10438 dumpOomLocked(fd, pw, args, opti, true); 10439 } 10440 } else if ("provider".equals(cmd)) { 10441 String[] newArgs; 10442 String name; 10443 if (opti >= args.length) { 10444 name = null; 10445 newArgs = EMPTY_STRING_ARRAY; 10446 } else { 10447 name = args[opti]; 10448 opti++; 10449 newArgs = new String[args.length - opti]; 10450 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti); 10451 } 10452 if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) { 10453 pw.println("No providers match: " + name); 10454 pw.println("Use -h for help."); 10455 } 10456 } else if ("providers".equals(cmd) || "prov".equals(cmd)) { 10457 synchronized (this) { 10458 dumpProvidersLocked(fd, pw, args, opti, true, null); 10459 } 10460 } else if ("service".equals(cmd)) { 10461 String[] newArgs; 10462 String name; 10463 if (opti >= args.length) { 10464 name = null; 10465 newArgs = EMPTY_STRING_ARRAY; 10466 } else { 10467 name = args[opti]; 10468 opti++; 10469 newArgs = new String[args.length - opti]; 10470 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 10471 args.length - opti); 10472 } 10473 if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) { 10474 pw.println("No services match: " + name); 10475 pw.println("Use -h for help."); 10476 } 10477 } else if ("package".equals(cmd)) { 10478 String[] newArgs; 10479 if (opti >= args.length) { 10480 pw.println("package: no package name specified"); 10481 pw.println("Use -h for help."); 10482 } else { 10483 dumpPackage = args[opti]; 10484 opti++; 10485 newArgs = new String[args.length - opti]; 10486 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 10487 args.length - opti); 10488 args = newArgs; 10489 opti = 0; 10490 more = true; 10491 } 10492 } else if ("services".equals(cmd) || "s".equals(cmd)) { 10493 synchronized (this) { 10494 mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null); 10495 } 10496 } else { 10497 // Dumping a single activity? 10498 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) { 10499 pw.println("Bad activity command, or no activities match: " + cmd); 10500 pw.println("Use -h for help."); 10501 } 10502 } 10503 if (!more) { 10504 Binder.restoreCallingIdentity(origId); 10505 return; 10506 } 10507 } 10508 10509 // No piece of data specified, dump everything. 10510 synchronized (this) { 10511 dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 10512 pw.println(); 10513 if (dumpAll) { 10514 pw.println("-------------------------------------------------------------------------------"); 10515 } 10516 dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 10517 pw.println(); 10518 if (dumpAll) { 10519 pw.println("-------------------------------------------------------------------------------"); 10520 } 10521 dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage); 10522 pw.println(); 10523 if (dumpAll) { 10524 pw.println("-------------------------------------------------------------------------------"); 10525 } 10526 mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 10527 pw.println(); 10528 if (dumpAll) { 10529 pw.println("-------------------------------------------------------------------------------"); 10530 } 10531 dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 10532 pw.println(); 10533 if (dumpAll) { 10534 pw.println("-------------------------------------------------------------------------------"); 10535 } 10536 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage); 10537 } 10538 Binder.restoreCallingIdentity(origId); 10539 } 10540 10541 void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 10542 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) { 10543 pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)"); 10544 10545 boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient, 10546 dumpPackage); 10547 boolean needSep = printedAnything; 10548 10549 boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity, 10550 dumpPackage, needSep, " mFocusedActivity: "); 10551 if (printed) { 10552 printedAnything = true; 10553 needSep = false; 10554 } 10555 10556 if (dumpPackage == null) { 10557 if (needSep) { 10558 pw.println(); 10559 } 10560 needSep = true; 10561 printedAnything = true; 10562 mStackSupervisor.dump(pw, " "); 10563 } 10564 10565 if (mRecentTasks.size() > 0) { 10566 boolean printedHeader = false; 10567 10568 final int N = mRecentTasks.size(); 10569 for (int i=0; i<N; i++) { 10570 TaskRecord tr = mRecentTasks.get(i); 10571 if (dumpPackage != null) { 10572 if (tr.realActivity == null || 10573 !dumpPackage.equals(tr.realActivity)) { 10574 continue; 10575 } 10576 } 10577 if (!printedHeader) { 10578 if (needSep) { 10579 pw.println(); 10580 } 10581 pw.println(" Recent tasks:"); 10582 printedHeader = true; 10583 printedAnything = true; 10584 } 10585 pw.print(" * Recent #"); pw.print(i); pw.print(": "); 10586 pw.println(tr); 10587 if (dumpAll) { 10588 mRecentTasks.get(i).dump(pw, " "); 10589 } 10590 } 10591 } 10592 10593 if (!printedAnything) { 10594 pw.println(" (nothing)"); 10595 } 10596 } 10597 10598 void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 10599 int opti, boolean dumpAll, String dumpPackage) { 10600 boolean needSep = false; 10601 boolean printedAnything = false; 10602 int numPers = 0; 10603 10604 pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)"); 10605 10606 if (dumpAll) { 10607 final int NP = mProcessNames.getMap().size(); 10608 for (int ip=0; ip<NP; ip++) { 10609 SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip); 10610 final int NA = procs.size(); 10611 for (int ia=0; ia<NA; ia++) { 10612 ProcessRecord r = procs.valueAt(ia); 10613 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 10614 continue; 10615 } 10616 if (!needSep) { 10617 pw.println(" All known processes:"); 10618 needSep = true; 10619 printedAnything = true; 10620 } 10621 pw.print(r.persistent ? " *PERS*" : " *APP*"); 10622 pw.print(" UID "); pw.print(procs.keyAt(ia)); 10623 pw.print(" "); pw.println(r); 10624 r.dump(pw, " "); 10625 if (r.persistent) { 10626 numPers++; 10627 } 10628 } 10629 } 10630 } 10631 10632 if (mIsolatedProcesses.size() > 0) { 10633 boolean printed = false; 10634 for (int i=0; i<mIsolatedProcesses.size(); i++) { 10635 ProcessRecord r = mIsolatedProcesses.valueAt(i); 10636 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 10637 continue; 10638 } 10639 if (!printed) { 10640 if (needSep) { 10641 pw.println(); 10642 } 10643 pw.println(" Isolated process list (sorted by uid):"); 10644 printedAnything = true; 10645 printed = true; 10646 needSep = true; 10647 } 10648 pw.println(String.format("%sIsolated #%2d: %s", 10649 " ", i, r.toString())); 10650 } 10651 } 10652 10653 if (mLruProcesses.size() > 0) { 10654 if (needSep) { 10655 pw.println(); 10656 } 10657 pw.print(" Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size()); 10658 pw.print(" total, non-act at "); 10659 pw.print(mLruProcesses.size()-mLruProcessActivityStart); 10660 pw.print(", non-svc at "); 10661 pw.print(mLruProcesses.size()-mLruProcessServiceStart); 10662 pw.println("):"); 10663 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", false, dumpPackage); 10664 needSep = true; 10665 printedAnything = true; 10666 } 10667 10668 if (dumpAll || dumpPackage != null) { 10669 synchronized (mPidsSelfLocked) { 10670 boolean printed = false; 10671 for (int i=0; i<mPidsSelfLocked.size(); i++) { 10672 ProcessRecord r = mPidsSelfLocked.valueAt(i); 10673 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 10674 continue; 10675 } 10676 if (!printed) { 10677 if (needSep) pw.println(); 10678 needSep = true; 10679 pw.println(" PID mappings:"); 10680 printed = true; 10681 printedAnything = true; 10682 } 10683 pw.print(" PID #"); pw.print(mPidsSelfLocked.keyAt(i)); 10684 pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i)); 10685 } 10686 } 10687 } 10688 10689 if (mForegroundProcesses.size() > 0) { 10690 synchronized (mPidsSelfLocked) { 10691 boolean printed = false; 10692 for (int i=0; i<mForegroundProcesses.size(); i++) { 10693 ProcessRecord r = mPidsSelfLocked.get( 10694 mForegroundProcesses.valueAt(i).pid); 10695 if (dumpPackage != null && (r == null 10696 || !r.pkgList.containsKey(dumpPackage))) { 10697 continue; 10698 } 10699 if (!printed) { 10700 if (needSep) pw.println(); 10701 needSep = true; 10702 pw.println(" Foreground Processes:"); 10703 printed = true; 10704 printedAnything = true; 10705 } 10706 pw.print(" PID #"); pw.print(mForegroundProcesses.keyAt(i)); 10707 pw.print(": "); pw.println(mForegroundProcesses.valueAt(i)); 10708 } 10709 } 10710 } 10711 10712 if (mPersistentStartingProcesses.size() > 0) { 10713 if (needSep) pw.println(); 10714 needSep = true; 10715 printedAnything = true; 10716 pw.println(" Persisent processes that are starting:"); 10717 dumpProcessList(pw, this, mPersistentStartingProcesses, " ", 10718 "Starting Norm", "Restarting PERS", dumpPackage); 10719 } 10720 10721 if (mRemovedProcesses.size() > 0) { 10722 if (needSep) pw.println(); 10723 needSep = true; 10724 printedAnything = true; 10725 pw.println(" Processes that are being removed:"); 10726 dumpProcessList(pw, this, mRemovedProcesses, " ", 10727 "Removed Norm", "Removed PERS", dumpPackage); 10728 } 10729 10730 if (mProcessesOnHold.size() > 0) { 10731 if (needSep) pw.println(); 10732 needSep = true; 10733 printedAnything = true; 10734 pw.println(" Processes that are on old until the system is ready:"); 10735 dumpProcessList(pw, this, mProcessesOnHold, " ", 10736 "OnHold Norm", "OnHold PERS", dumpPackage); 10737 } 10738 10739 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage); 10740 10741 if (mProcessCrashTimes.getMap().size() > 0) { 10742 boolean printed = false; 10743 long now = SystemClock.uptimeMillis(); 10744 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap(); 10745 final int NP = pmap.size(); 10746 for (int ip=0; ip<NP; ip++) { 10747 String pname = pmap.keyAt(ip); 10748 SparseArray<Long> uids = pmap.valueAt(ip); 10749 final int N = uids.size(); 10750 for (int i=0; i<N; i++) { 10751 int puid = uids.keyAt(i); 10752 ProcessRecord r = mProcessNames.get(pname, puid); 10753 if (dumpPackage != null && (r == null 10754 || !r.pkgList.containsKey(dumpPackage))) { 10755 continue; 10756 } 10757 if (!printed) { 10758 if (needSep) pw.println(); 10759 needSep = true; 10760 pw.println(" Time since processes crashed:"); 10761 printed = true; 10762 printedAnything = true; 10763 } 10764 pw.print(" Process "); pw.print(pname); 10765 pw.print(" uid "); pw.print(puid); 10766 pw.print(": last crashed "); 10767 TimeUtils.formatDuration(now-uids.valueAt(i), pw); 10768 pw.println(" ago"); 10769 } 10770 } 10771 } 10772 10773 if (mBadProcesses.getMap().size() > 0) { 10774 boolean printed = false; 10775 final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap(); 10776 final int NP = pmap.size(); 10777 for (int ip=0; ip<NP; ip++) { 10778 String pname = pmap.keyAt(ip); 10779 SparseArray<BadProcessInfo> uids = pmap.valueAt(ip); 10780 final int N = uids.size(); 10781 for (int i=0; i<N; i++) { 10782 int puid = uids.keyAt(i); 10783 ProcessRecord r = mProcessNames.get(pname, puid); 10784 if (dumpPackage != null && (r == null 10785 || !r.pkgList.containsKey(dumpPackage))) { 10786 continue; 10787 } 10788 if (!printed) { 10789 if (needSep) pw.println(); 10790 needSep = true; 10791 pw.println(" Bad processes:"); 10792 printedAnything = true; 10793 } 10794 BadProcessInfo info = uids.valueAt(i); 10795 pw.print(" Bad process "); pw.print(pname); 10796 pw.print(" uid "); pw.print(puid); 10797 pw.print(": crashed at time "); pw.println(info.time); 10798 if (info.shortMsg != null) { 10799 pw.print(" Short msg: "); pw.println(info.shortMsg); 10800 } 10801 if (info.longMsg != null) { 10802 pw.print(" Long msg: "); pw.println(info.longMsg); 10803 } 10804 if (info.stack != null) { 10805 pw.println(" Stack:"); 10806 int lastPos = 0; 10807 for (int pos=0; pos<info.stack.length(); pos++) { 10808 if (info.stack.charAt(pos) == '\n') { 10809 pw.print(" "); 10810 pw.write(info.stack, lastPos, pos-lastPos); 10811 pw.println(); 10812 lastPos = pos+1; 10813 } 10814 } 10815 if (lastPos < info.stack.length()) { 10816 pw.print(" "); 10817 pw.write(info.stack, lastPos, info.stack.length()-lastPos); 10818 pw.println(); 10819 } 10820 } 10821 } 10822 } 10823 } 10824 10825 if (dumpPackage == null) { 10826 pw.println(); 10827 needSep = false; 10828 pw.println(" mStartedUsers:"); 10829 for (int i=0; i<mStartedUsers.size(); i++) { 10830 UserStartedState uss = mStartedUsers.valueAt(i); 10831 pw.print(" User #"); pw.print(uss.mHandle.getIdentifier()); 10832 pw.print(": "); uss.dump("", pw); 10833 } 10834 pw.print(" mStartedUserArray: ["); 10835 for (int i=0; i<mStartedUserArray.length; i++) { 10836 if (i > 0) pw.print(", "); 10837 pw.print(mStartedUserArray[i]); 10838 } 10839 pw.println("]"); 10840 pw.print(" mUserLru: ["); 10841 for (int i=0; i<mUserLru.size(); i++) { 10842 if (i > 0) pw.print(", "); 10843 pw.print(mUserLru.get(i)); 10844 } 10845 pw.println("]"); 10846 if (dumpAll) { 10847 pw.print(" mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray)); 10848 } 10849 } 10850 if (mHomeProcess != null && (dumpPackage == null 10851 || mHomeProcess.pkgList.containsKey(dumpPackage))) { 10852 if (needSep) { 10853 pw.println(); 10854 needSep = false; 10855 } 10856 pw.println(" mHomeProcess: " + mHomeProcess); 10857 } 10858 if (mPreviousProcess != null && (dumpPackage == null 10859 || mPreviousProcess.pkgList.containsKey(dumpPackage))) { 10860 if (needSep) { 10861 pw.println(); 10862 needSep = false; 10863 } 10864 pw.println(" mPreviousProcess: " + mPreviousProcess); 10865 } 10866 if (dumpAll) { 10867 StringBuilder sb = new StringBuilder(128); 10868 sb.append(" mPreviousProcessVisibleTime: "); 10869 TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb); 10870 pw.println(sb); 10871 } 10872 if (mHeavyWeightProcess != null && (dumpPackage == null 10873 || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) { 10874 if (needSep) { 10875 pw.println(); 10876 needSep = false; 10877 } 10878 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 10879 } 10880 if (dumpPackage == null) { 10881 pw.println(" mConfiguration: " + mConfiguration); 10882 } 10883 if (dumpAll) { 10884 pw.println(" mConfigWillChange: " + getFocusedStack().mConfigWillChange); 10885 if (mCompatModePackages.getPackages().size() > 0) { 10886 boolean printed = false; 10887 for (Map.Entry<String, Integer> entry 10888 : mCompatModePackages.getPackages().entrySet()) { 10889 String pkg = entry.getKey(); 10890 int mode = entry.getValue(); 10891 if (dumpPackage != null && !dumpPackage.equals(pkg)) { 10892 continue; 10893 } 10894 if (!printed) { 10895 pw.println(" mScreenCompatPackages:"); 10896 printed = true; 10897 } 10898 pw.print(" "); pw.print(pkg); pw.print(": "); 10899 pw.print(mode); pw.println(); 10900 } 10901 } 10902 } 10903 if (dumpPackage == null) { 10904 if (mSleeping || mWentToSleep || mLockScreenShown) { 10905 pw.println(" mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep 10906 + " mLockScreenShown " + mLockScreenShown); 10907 } 10908 if (mShuttingDown) { 10909 pw.println(" mShuttingDown=" + mShuttingDown); 10910 } 10911 } 10912 if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient 10913 || mOrigWaitForDebugger) { 10914 if (dumpPackage == null || dumpPackage.equals(mDebugApp) 10915 || dumpPackage.equals(mOrigDebugApp)) { 10916 if (needSep) { 10917 pw.println(); 10918 needSep = false; 10919 } 10920 pw.println(" mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp 10921 + " mDebugTransient=" + mDebugTransient 10922 + " mOrigWaitForDebugger=" + mOrigWaitForDebugger); 10923 } 10924 } 10925 if (mOpenGlTraceApp != null) { 10926 if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) { 10927 if (needSep) { 10928 pw.println(); 10929 needSep = false; 10930 } 10931 pw.println(" mOpenGlTraceApp=" + mOpenGlTraceApp); 10932 } 10933 } 10934 if (mProfileApp != null || mProfileProc != null || mProfileFile != null 10935 || mProfileFd != null) { 10936 if (dumpPackage == null || dumpPackage.equals(mProfileApp)) { 10937 if (needSep) { 10938 pw.println(); 10939 needSep = false; 10940 } 10941 pw.println(" mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc); 10942 pw.println(" mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd); 10943 pw.println(" mProfileType=" + mProfileType + " mAutoStopProfiler=" 10944 + mAutoStopProfiler); 10945 } 10946 } 10947 if (dumpPackage == null) { 10948 if (mAlwaysFinishActivities || mController != null) { 10949 pw.println(" mAlwaysFinishActivities=" + mAlwaysFinishActivities 10950 + " mController=" + mController); 10951 } 10952 if (dumpAll) { 10953 pw.println(" Total persistent processes: " + numPers); 10954 pw.println(" mStartRunning=" + mStartRunning 10955 + " mProcessesReady=" + mProcessesReady 10956 + " mSystemReady=" + mSystemReady); 10957 pw.println(" mBooting=" + mBooting 10958 + " mBooted=" + mBooted 10959 + " mFactoryTest=" + mFactoryTest); 10960 pw.print(" mLastPowerCheckRealtime="); 10961 TimeUtils.formatDuration(mLastPowerCheckRealtime, pw); 10962 pw.println(""); 10963 pw.print(" mLastPowerCheckUptime="); 10964 TimeUtils.formatDuration(mLastPowerCheckUptime, pw); 10965 pw.println(""); 10966 pw.println(" mGoingToSleep=" + mStackSupervisor.mGoingToSleep); 10967 pw.println(" mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity); 10968 pw.println(" mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq); 10969 pw.println(" mNumNonCachedProcs=" + mNumNonCachedProcs 10970 + " (" + mLruProcesses.size() + " total)" 10971 + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs 10972 + " mNumServiceProcs=" + mNumServiceProcs 10973 + " mNewNumServiceProcs=" + mNewNumServiceProcs); 10974 pw.println(" mAllowLowerMemLevel=" + mAllowLowerMemLevel 10975 + " mLastMemoryLevel" + mLastMemoryLevel 10976 + " mLastNumProcesses" + mLastNumProcesses); 10977 long now = SystemClock.uptimeMillis(); 10978 pw.print(" mLastIdleTime="); 10979 TimeUtils.formatDuration(now, mLastIdleTime, pw); 10980 pw.print(" mLowRamSinceLastIdle="); 10981 TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw); 10982 pw.println(); 10983 } 10984 } 10985 10986 if (!printedAnything) { 10987 pw.println(" (nothing)"); 10988 } 10989 } 10990 10991 boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args, 10992 int opti, boolean needSep, boolean dumpAll, String dumpPackage) { 10993 if (mProcessesToGc.size() > 0) { 10994 boolean printed = false; 10995 long now = SystemClock.uptimeMillis(); 10996 for (int i=0; i<mProcessesToGc.size(); i++) { 10997 ProcessRecord proc = mProcessesToGc.get(i); 10998 if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) { 10999 continue; 11000 } 11001 if (!printed) { 11002 if (needSep) pw.println(); 11003 needSep = true; 11004 pw.println(" Processes that are waiting to GC:"); 11005 printed = true; 11006 } 11007 pw.print(" Process "); pw.println(proc); 11008 pw.print(" lowMem="); pw.print(proc.reportLowMemory); 11009 pw.print(", last gced="); 11010 pw.print(now-proc.lastRequestedGc); 11011 pw.print(" ms ago, last lowMem="); 11012 pw.print(now-proc.lastLowMemory); 11013 pw.println(" ms ago"); 11014 11015 } 11016 } 11017 return needSep; 11018 } 11019 11020 void printOomLevel(PrintWriter pw, String name, int adj) { 11021 pw.print(" "); 11022 if (adj >= 0) { 11023 pw.print(' '); 11024 if (adj < 10) pw.print(' '); 11025 } else { 11026 if (adj > -10) pw.print(' '); 11027 } 11028 pw.print(adj); 11029 pw.print(": "); 11030 pw.print(name); 11031 pw.print(" ("); 11032 pw.print(mProcessList.getMemLevel(adj)/1024); 11033 pw.println(" kB)"); 11034 } 11035 11036 boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args, 11037 int opti, boolean dumpAll) { 11038 boolean needSep = false; 11039 11040 if (mLruProcesses.size() > 0) { 11041 if (needSep) pw.println(); 11042 needSep = true; 11043 pw.println(" OOM levels:"); 11044 printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ); 11045 printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ); 11046 printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ); 11047 printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ); 11048 printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ); 11049 printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ); 11050 printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ); 11051 printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ); 11052 printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ); 11053 printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ); 11054 printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ); 11055 printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ); 11056 printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ); 11057 11058 if (needSep) pw.println(); 11059 pw.print(" Process OOM control ("); pw.print(mLruProcesses.size()); 11060 pw.print(" total, non-act at "); 11061 pw.print(mLruProcesses.size()-mLruProcessActivityStart); 11062 pw.print(", non-svc at "); 11063 pw.print(mLruProcesses.size()-mLruProcessServiceStart); 11064 pw.println("):"); 11065 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", true, null); 11066 needSep = true; 11067 } 11068 11069 dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null); 11070 11071 pw.println(); 11072 pw.println(" mHomeProcess: " + mHomeProcess); 11073 pw.println(" mPreviousProcess: " + mPreviousProcess); 11074 if (mHeavyWeightProcess != null) { 11075 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 11076 } 11077 11078 return true; 11079 } 11080 11081 /** 11082 * There are three ways to call this: 11083 * - no provider specified: dump all the providers 11084 * - a flattened component name that matched an existing provider was specified as the 11085 * first arg: dump that one provider 11086 * - the first arg isn't the flattened component name of an existing provider: 11087 * dump all providers whose component contains the first arg as a substring 11088 */ 11089 protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args, 11090 int opti, boolean dumpAll) { 11091 return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll); 11092 } 11093 11094 static class ItemMatcher { 11095 ArrayList<ComponentName> components; 11096 ArrayList<String> strings; 11097 ArrayList<Integer> objects; 11098 boolean all; 11099 11100 ItemMatcher() { 11101 all = true; 11102 } 11103 11104 void build(String name) { 11105 ComponentName componentName = ComponentName.unflattenFromString(name); 11106 if (componentName != null) { 11107 if (components == null) { 11108 components = new ArrayList<ComponentName>(); 11109 } 11110 components.add(componentName); 11111 all = false; 11112 } else { 11113 int objectId = 0; 11114 // Not a '/' separated full component name; maybe an object ID? 11115 try { 11116 objectId = Integer.parseInt(name, 16); 11117 if (objects == null) { 11118 objects = new ArrayList<Integer>(); 11119 } 11120 objects.add(objectId); 11121 all = false; 11122 } catch (RuntimeException e) { 11123 // Not an integer; just do string match. 11124 if (strings == null) { 11125 strings = new ArrayList<String>(); 11126 } 11127 strings.add(name); 11128 all = false; 11129 } 11130 } 11131 } 11132 11133 int build(String[] args, int opti) { 11134 for (; opti<args.length; opti++) { 11135 String name = args[opti]; 11136 if ("--".equals(name)) { 11137 return opti+1; 11138 } 11139 build(name); 11140 } 11141 return opti; 11142 } 11143 11144 boolean match(Object object, ComponentName comp) { 11145 if (all) { 11146 return true; 11147 } 11148 if (components != null) { 11149 for (int i=0; i<components.size(); i++) { 11150 if (components.get(i).equals(comp)) { 11151 return true; 11152 } 11153 } 11154 } 11155 if (objects != null) { 11156 for (int i=0; i<objects.size(); i++) { 11157 if (System.identityHashCode(object) == objects.get(i)) { 11158 return true; 11159 } 11160 } 11161 } 11162 if (strings != null) { 11163 String flat = comp.flattenToString(); 11164 for (int i=0; i<strings.size(); i++) { 11165 if (flat.contains(strings.get(i))) { 11166 return true; 11167 } 11168 } 11169 } 11170 return false; 11171 } 11172 } 11173 11174 /** 11175 * There are three things that cmd can be: 11176 * - a flattened component name that matches an existing activity 11177 * - the cmd arg isn't the flattened component name of an existing activity: 11178 * dump all activity whose component contains the cmd as a substring 11179 * - A hex number of the ActivityRecord object instance. 11180 */ 11181 protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args, 11182 int opti, boolean dumpAll) { 11183 ArrayList<ActivityRecord> activities; 11184 11185 synchronized (this) { 11186 activities = mStackSupervisor.getDumpActivitiesLocked(name); 11187 } 11188 11189 if (activities.size() <= 0) { 11190 return false; 11191 } 11192 11193 String[] newArgs = new String[args.length - opti]; 11194 System.arraycopy(args, opti, newArgs, 0, args.length - opti); 11195 11196 TaskRecord lastTask = null; 11197 boolean needSep = false; 11198 for (int i=activities.size()-1; i>=0; i--) { 11199 ActivityRecord r = activities.get(i); 11200 if (needSep) { 11201 pw.println(); 11202 } 11203 needSep = true; 11204 synchronized (this) { 11205 if (lastTask != r.task) { 11206 lastTask = r.task; 11207 pw.print("TASK "); pw.print(lastTask.affinity); 11208 pw.print(" id="); pw.println(lastTask.taskId); 11209 if (dumpAll) { 11210 lastTask.dump(pw, " "); 11211 } 11212 } 11213 } 11214 dumpActivity(" ", fd, pw, activities.get(i), newArgs, dumpAll); 11215 } 11216 return true; 11217 } 11218 11219 /** 11220 * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if 11221 * there is a thread associated with the activity. 11222 */ 11223 private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw, 11224 final ActivityRecord r, String[] args, boolean dumpAll) { 11225 String innerPrefix = prefix + " "; 11226 synchronized (this) { 11227 pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName); 11228 pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r))); 11229 pw.print(" pid="); 11230 if (r.app != null) pw.println(r.app.pid); 11231 else pw.println("(not running)"); 11232 if (dumpAll) { 11233 r.dump(pw, innerPrefix); 11234 } 11235 } 11236 if (r.app != null && r.app.thread != null) { 11237 // flush anything that is already in the PrintWriter since the thread is going 11238 // to write to the file descriptor directly 11239 pw.flush(); 11240 try { 11241 TransferPipe tp = new TransferPipe(); 11242 try { 11243 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(), 11244 r.appToken, innerPrefix, args); 11245 tp.go(fd); 11246 } finally { 11247 tp.kill(); 11248 } 11249 } catch (IOException e) { 11250 pw.println(innerPrefix + "Failure while dumping the activity: " + e); 11251 } catch (RemoteException e) { 11252 pw.println(innerPrefix + "Got a RemoteException while dumping the activity"); 11253 } 11254 } 11255 } 11256 11257 void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 11258 int opti, boolean dumpAll, String dumpPackage) { 11259 boolean needSep = false; 11260 boolean onlyHistory = false; 11261 boolean printedAnything = false; 11262 11263 if ("history".equals(dumpPackage)) { 11264 if (opti < args.length && "-s".equals(args[opti])) { 11265 dumpAll = false; 11266 } 11267 onlyHistory = true; 11268 dumpPackage = null; 11269 } 11270 11271 pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)"); 11272 if (!onlyHistory && dumpAll) { 11273 if (mRegisteredReceivers.size() > 0) { 11274 boolean printed = false; 11275 Iterator it = mRegisteredReceivers.values().iterator(); 11276 while (it.hasNext()) { 11277 ReceiverList r = (ReceiverList)it.next(); 11278 if (dumpPackage != null && (r.app == null || 11279 !dumpPackage.equals(r.app.info.packageName))) { 11280 continue; 11281 } 11282 if (!printed) { 11283 pw.println(" Registered Receivers:"); 11284 needSep = true; 11285 printed = true; 11286 printedAnything = true; 11287 } 11288 pw.print(" * "); pw.println(r); 11289 r.dump(pw, " "); 11290 } 11291 } 11292 11293 if (mReceiverResolver.dump(pw, needSep ? 11294 "\n Receiver Resolver Table:" : " Receiver Resolver Table:", 11295 " ", dumpPackage, false)) { 11296 needSep = true; 11297 printedAnything = true; 11298 } 11299 } 11300 11301 for (BroadcastQueue q : mBroadcastQueues) { 11302 needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep); 11303 printedAnything |= needSep; 11304 } 11305 11306 needSep = true; 11307 11308 if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) { 11309 for (int user=0; user<mStickyBroadcasts.size(); user++) { 11310 if (needSep) { 11311 pw.println(); 11312 } 11313 needSep = true; 11314 printedAnything = true; 11315 pw.print(" Sticky broadcasts for user "); 11316 pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":"); 11317 StringBuilder sb = new StringBuilder(128); 11318 for (Map.Entry<String, ArrayList<Intent>> ent 11319 : mStickyBroadcasts.valueAt(user).entrySet()) { 11320 pw.print(" * Sticky action "); pw.print(ent.getKey()); 11321 if (dumpAll) { 11322 pw.println(":"); 11323 ArrayList<Intent> intents = ent.getValue(); 11324 final int N = intents.size(); 11325 for (int i=0; i<N; i++) { 11326 sb.setLength(0); 11327 sb.append(" Intent: "); 11328 intents.get(i).toShortString(sb, false, true, false, false); 11329 pw.println(sb.toString()); 11330 Bundle bundle = intents.get(i).getExtras(); 11331 if (bundle != null) { 11332 pw.print(" "); 11333 pw.println(bundle.toString()); 11334 } 11335 } 11336 } else { 11337 pw.println(""); 11338 } 11339 } 11340 } 11341 } 11342 11343 if (!onlyHistory && dumpAll) { 11344 pw.println(); 11345 for (BroadcastQueue queue : mBroadcastQueues) { 11346 pw.println(" mBroadcastsScheduled [" + queue.mQueueName + "]=" 11347 + queue.mBroadcastsScheduled); 11348 } 11349 pw.println(" mHandler:"); 11350 mHandler.dump(new PrintWriterPrinter(pw), " "); 11351 needSep = true; 11352 printedAnything = true; 11353 } 11354 11355 if (!printedAnything) { 11356 pw.println(" (nothing)"); 11357 } 11358 } 11359 11360 void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args, 11361 int opti, boolean dumpAll, String dumpPackage) { 11362 boolean needSep; 11363 boolean printedAnything = false; 11364 11365 ItemMatcher matcher = new ItemMatcher(); 11366 matcher.build(args, opti); 11367 11368 pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)"); 11369 11370 needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage); 11371 printedAnything |= needSep; 11372 11373 if (mLaunchingProviders.size() > 0) { 11374 boolean printed = false; 11375 for (int i=mLaunchingProviders.size()-1; i>=0; i--) { 11376 ContentProviderRecord r = mLaunchingProviders.get(i); 11377 if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) { 11378 continue; 11379 } 11380 if (!printed) { 11381 if (needSep) pw.println(); 11382 needSep = true; 11383 pw.println(" Launching content providers:"); 11384 printed = true; 11385 printedAnything = true; 11386 } 11387 pw.print(" Launching #"); pw.print(i); pw.print(": "); 11388 pw.println(r); 11389 } 11390 } 11391 11392 if (mGrantedUriPermissions.size() > 0) { 11393 boolean printed = false; 11394 int dumpUid = -2; 11395 if (dumpPackage != null) { 11396 try { 11397 dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0); 11398 } catch (NameNotFoundException e) { 11399 dumpUid = -1; 11400 } 11401 } 11402 for (int i=0; i<mGrantedUriPermissions.size(); i++) { 11403 int uid = mGrantedUriPermissions.keyAt(i); 11404 if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) { 11405 continue; 11406 } 11407 ArrayMap<Uri, UriPermission> perms 11408 = mGrantedUriPermissions.valueAt(i); 11409 if (!printed) { 11410 if (needSep) pw.println(); 11411 needSep = true; 11412 pw.println(" Granted Uri Permissions:"); 11413 printed = true; 11414 printedAnything = true; 11415 } 11416 pw.print(" * UID "); pw.print(uid); 11417 pw.println(" holds:"); 11418 for (UriPermission perm : perms.values()) { 11419 pw.print(" "); pw.println(perm); 11420 if (dumpAll) { 11421 perm.dump(pw, " "); 11422 } 11423 } 11424 } 11425 } 11426 11427 if (!printedAnything) { 11428 pw.println(" (nothing)"); 11429 } 11430 } 11431 11432 void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 11433 int opti, boolean dumpAll, String dumpPackage) { 11434 boolean printed = false; 11435 11436 pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)"); 11437 11438 if (mIntentSenderRecords.size() > 0) { 11439 Iterator<WeakReference<PendingIntentRecord>> it 11440 = mIntentSenderRecords.values().iterator(); 11441 while (it.hasNext()) { 11442 WeakReference<PendingIntentRecord> ref = it.next(); 11443 PendingIntentRecord rec = ref != null ? ref.get(): null; 11444 if (dumpPackage != null && (rec == null 11445 || !dumpPackage.equals(rec.key.packageName))) { 11446 continue; 11447 } 11448 printed = true; 11449 if (rec != null) { 11450 pw.print(" * "); pw.println(rec); 11451 if (dumpAll) { 11452 rec.dump(pw, " "); 11453 } 11454 } else { 11455 pw.print(" * "); pw.println(ref); 11456 } 11457 } 11458 } 11459 11460 if (!printed) { 11461 pw.println(" (nothing)"); 11462 } 11463 } 11464 11465 private static final int dumpProcessList(PrintWriter pw, 11466 ActivityManagerService service, List list, 11467 String prefix, String normalLabel, String persistentLabel, 11468 String dumpPackage) { 11469 int numPers = 0; 11470 final int N = list.size()-1; 11471 for (int i=N; i>=0; i--) { 11472 ProcessRecord r = (ProcessRecord)list.get(i); 11473 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 11474 continue; 11475 } 11476 pw.println(String.format("%s%s #%2d: %s", 11477 prefix, (r.persistent ? persistentLabel : normalLabel), 11478 i, r.toString())); 11479 if (r.persistent) { 11480 numPers++; 11481 } 11482 } 11483 return numPers; 11484 } 11485 11486 private static final boolean dumpProcessOomList(PrintWriter pw, 11487 ActivityManagerService service, List<ProcessRecord> origList, 11488 String prefix, String normalLabel, String persistentLabel, 11489 boolean inclDetails, String dumpPackage) { 11490 11491 ArrayList<Pair<ProcessRecord, Integer>> list 11492 = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size()); 11493 for (int i=0; i<origList.size(); i++) { 11494 ProcessRecord r = origList.get(i); 11495 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 11496 continue; 11497 } 11498 list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i)); 11499 } 11500 11501 if (list.size() <= 0) { 11502 return false; 11503 } 11504 11505 Comparator<Pair<ProcessRecord, Integer>> comparator 11506 = new Comparator<Pair<ProcessRecord, Integer>>() { 11507 @Override 11508 public int compare(Pair<ProcessRecord, Integer> object1, 11509 Pair<ProcessRecord, Integer> object2) { 11510 if (object1.first.setAdj != object2.first.setAdj) { 11511 return object1.first.setAdj > object2.first.setAdj ? -1 : 1; 11512 } 11513 if (object1.second.intValue() != object2.second.intValue()) { 11514 return object1.second.intValue() > object2.second.intValue() ? -1 : 1; 11515 } 11516 return 0; 11517 } 11518 }; 11519 11520 Collections.sort(list, comparator); 11521 11522 final long curRealtime = SystemClock.elapsedRealtime(); 11523 final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime; 11524 final long curUptime = SystemClock.uptimeMillis(); 11525 final long uptimeSince = curUptime - service.mLastPowerCheckUptime; 11526 11527 for (int i=list.size()-1; i>=0; i--) { 11528 ProcessRecord r = list.get(i).first; 11529 String oomAdj = ProcessList.makeOomAdjString(r.setAdj); 11530 char schedGroup; 11531 switch (r.setSchedGroup) { 11532 case Process.THREAD_GROUP_BG_NONINTERACTIVE: 11533 schedGroup = 'B'; 11534 break; 11535 case Process.THREAD_GROUP_DEFAULT: 11536 schedGroup = 'F'; 11537 break; 11538 default: 11539 schedGroup = '?'; 11540 break; 11541 } 11542 char foreground; 11543 if (r.foregroundActivities) { 11544 foreground = 'A'; 11545 } else if (r.foregroundServices) { 11546 foreground = 'S'; 11547 } else { 11548 foreground = ' '; 11549 } 11550 String procState = ProcessList.makeProcStateString(r.curProcState); 11551 pw.print(prefix); 11552 pw.print(r.persistent ? persistentLabel : normalLabel); 11553 pw.print(" #"); 11554 int num = (origList.size()-1)-list.get(i).second; 11555 if (num < 10) pw.print(' '); 11556 pw.print(num); 11557 pw.print(": "); 11558 pw.print(oomAdj); 11559 pw.print(' '); 11560 pw.print(schedGroup); 11561 pw.print('/'); 11562 pw.print(foreground); 11563 pw.print('/'); 11564 pw.print(procState); 11565 pw.print(" trm:"); 11566 if (r.trimMemoryLevel < 10) pw.print(' '); 11567 pw.print(r.trimMemoryLevel); 11568 pw.print(' '); 11569 pw.print(r.toShortString()); 11570 pw.print(" ("); 11571 pw.print(r.adjType); 11572 pw.println(')'); 11573 if (r.adjSource != null || r.adjTarget != null) { 11574 pw.print(prefix); 11575 pw.print(" "); 11576 if (r.adjTarget instanceof ComponentName) { 11577 pw.print(((ComponentName)r.adjTarget).flattenToShortString()); 11578 } else if (r.adjTarget != null) { 11579 pw.print(r.adjTarget.toString()); 11580 } else { 11581 pw.print("{null}"); 11582 } 11583 pw.print("<="); 11584 if (r.adjSource instanceof ProcessRecord) { 11585 pw.print("Proc{"); 11586 pw.print(((ProcessRecord)r.adjSource).toShortString()); 11587 pw.println("}"); 11588 } else if (r.adjSource != null) { 11589 pw.println(r.adjSource.toString()); 11590 } else { 11591 pw.println("{null}"); 11592 } 11593 } 11594 if (inclDetails) { 11595 pw.print(prefix); 11596 pw.print(" "); 11597 pw.print("oom: max="); pw.print(r.maxAdj); 11598 pw.print(" curRaw="); pw.print(r.curRawAdj); 11599 pw.print(" setRaw="); pw.print(r.setRawAdj); 11600 pw.print(" cur="); pw.print(r.curAdj); 11601 pw.print(" set="); pw.println(r.setAdj); 11602 pw.print(prefix); 11603 pw.print(" "); 11604 pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState)); 11605 pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState)); 11606 pw.print(" lastPss="); pw.print(r.lastPss); 11607 pw.print(" lastCachedPss="); pw.println(r.lastCachedPss); 11608 pw.print(prefix); 11609 pw.print(" "); 11610 pw.print("keeping="); pw.print(r.keeping); 11611 pw.print(" cached="); pw.print(r.cached); 11612 pw.print(" empty="); pw.print(r.empty); 11613 pw.print(" hasAboveClient="); pw.println(r.hasAboveClient); 11614 11615 if (!r.keeping) { 11616 if (r.lastWakeTime != 0) { 11617 long wtime; 11618 BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics(); 11619 synchronized (stats) { 11620 wtime = stats.getProcessWakeTime(r.info.uid, 11621 r.pid, curRealtime); 11622 } 11623 long timeUsed = wtime - r.lastWakeTime; 11624 pw.print(prefix); 11625 pw.print(" "); 11626 pw.print("keep awake over "); 11627 TimeUtils.formatDuration(realtimeSince, pw); 11628 pw.print(" used "); 11629 TimeUtils.formatDuration(timeUsed, pw); 11630 pw.print(" ("); 11631 pw.print((timeUsed*100)/realtimeSince); 11632 pw.println("%)"); 11633 } 11634 if (r.lastCpuTime != 0) { 11635 long timeUsed = r.curCpuTime - r.lastCpuTime; 11636 pw.print(prefix); 11637 pw.print(" "); 11638 pw.print("run cpu over "); 11639 TimeUtils.formatDuration(uptimeSince, pw); 11640 pw.print(" used "); 11641 TimeUtils.formatDuration(timeUsed, pw); 11642 pw.print(" ("); 11643 pw.print((timeUsed*100)/uptimeSince); 11644 pw.println("%)"); 11645 } 11646 } 11647 } 11648 } 11649 return true; 11650 } 11651 11652 ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) { 11653 ArrayList<ProcessRecord> procs; 11654 synchronized (this) { 11655 if (args != null && args.length > start 11656 && args[start].charAt(0) != '-') { 11657 procs = new ArrayList<ProcessRecord>(); 11658 int pid = -1; 11659 try { 11660 pid = Integer.parseInt(args[start]); 11661 } catch (NumberFormatException e) { 11662 } 11663 for (int i=mLruProcesses.size()-1; i>=0; i--) { 11664 ProcessRecord proc = mLruProcesses.get(i); 11665 if (proc.pid == pid) { 11666 procs.add(proc); 11667 } else if (proc.processName.equals(args[start])) { 11668 procs.add(proc); 11669 } 11670 } 11671 if (procs.size() <= 0) { 11672 return null; 11673 } 11674 } else { 11675 procs = new ArrayList<ProcessRecord>(mLruProcesses); 11676 } 11677 } 11678 return procs; 11679 } 11680 11681 final void dumpGraphicsHardwareUsage(FileDescriptor fd, 11682 PrintWriter pw, String[] args) { 11683 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args); 11684 if (procs == null) { 11685 pw.println("No process found for: " + args[0]); 11686 return; 11687 } 11688 11689 long uptime = SystemClock.uptimeMillis(); 11690 long realtime = SystemClock.elapsedRealtime(); 11691 pw.println("Applications Graphics Acceleration Info:"); 11692 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 11693 11694 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 11695 ProcessRecord r = procs.get(i); 11696 if (r.thread != null) { 11697 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **"); 11698 pw.flush(); 11699 try { 11700 TransferPipe tp = new TransferPipe(); 11701 try { 11702 r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args); 11703 tp.go(fd); 11704 } finally { 11705 tp.kill(); 11706 } 11707 } catch (IOException e) { 11708 pw.println("Failure while dumping the app: " + r); 11709 pw.flush(); 11710 } catch (RemoteException e) { 11711 pw.println("Got a RemoteException while dumping the app " + r); 11712 pw.flush(); 11713 } 11714 } 11715 } 11716 } 11717 11718 final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) { 11719 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args); 11720 if (procs == null) { 11721 pw.println("No process found for: " + args[0]); 11722 return; 11723 } 11724 11725 pw.println("Applications Database Info:"); 11726 11727 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 11728 ProcessRecord r = procs.get(i); 11729 if (r.thread != null) { 11730 pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **"); 11731 pw.flush(); 11732 try { 11733 TransferPipe tp = new TransferPipe(); 11734 try { 11735 r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args); 11736 tp.go(fd); 11737 } finally { 11738 tp.kill(); 11739 } 11740 } catch (IOException e) { 11741 pw.println("Failure while dumping the app: " + r); 11742 pw.flush(); 11743 } catch (RemoteException e) { 11744 pw.println("Got a RemoteException while dumping the app " + r); 11745 pw.flush(); 11746 } 11747 } 11748 } 11749 } 11750 11751 final static class MemItem { 11752 final boolean isProc; 11753 final String label; 11754 final String shortLabel; 11755 final long pss; 11756 final int id; 11757 final boolean hasActivities; 11758 ArrayList<MemItem> subitems; 11759 11760 public MemItem(String _label, String _shortLabel, long _pss, int _id, 11761 boolean _hasActivities) { 11762 isProc = true; 11763 label = _label; 11764 shortLabel = _shortLabel; 11765 pss = _pss; 11766 id = _id; 11767 hasActivities = _hasActivities; 11768 } 11769 11770 public MemItem(String _label, String _shortLabel, long _pss, int _id) { 11771 isProc = false; 11772 label = _label; 11773 shortLabel = _shortLabel; 11774 pss = _pss; 11775 id = _id; 11776 hasActivities = false; 11777 } 11778 } 11779 11780 static final void dumpMemItems(PrintWriter pw, String prefix, String tag, 11781 ArrayList<MemItem> items, boolean sort, boolean isCompact) { 11782 if (sort && !isCompact) { 11783 Collections.sort(items, new Comparator<MemItem>() { 11784 @Override 11785 public int compare(MemItem lhs, MemItem rhs) { 11786 if (lhs.pss < rhs.pss) { 11787 return 1; 11788 } else if (lhs.pss > rhs.pss) { 11789 return -1; 11790 } 11791 return 0; 11792 } 11793 }); 11794 } 11795 11796 for (int i=0; i<items.size(); i++) { 11797 MemItem mi = items.get(i); 11798 if (!isCompact) { 11799 pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label); 11800 } else if (mi.isProc) { 11801 pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel); 11802 pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss); 11803 pw.println(mi.hasActivities ? ",a" : ",e"); 11804 } else { 11805 pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(","); 11806 pw.println(mi.pss); 11807 } 11808 if (mi.subitems != null) { 11809 dumpMemItems(pw, prefix + " ", mi.shortLabel, mi.subitems, 11810 true, isCompact); 11811 } 11812 } 11813 } 11814 11815 // These are in KB. 11816 static final long[] DUMP_MEM_BUCKETS = new long[] { 11817 5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024, 11818 120*1024, 160*1024, 200*1024, 11819 250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024, 11820 1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024 11821 }; 11822 11823 static final void appendMemBucket(StringBuilder out, long memKB, String label, 11824 boolean stackLike) { 11825 int start = label.lastIndexOf('.'); 11826 if (start >= 0) start++; 11827 else start = 0; 11828 int end = label.length(); 11829 for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) { 11830 if (DUMP_MEM_BUCKETS[i] >= memKB) { 11831 long bucket = DUMP_MEM_BUCKETS[i]/1024; 11832 out.append(bucket); 11833 out.append(stackLike ? "MB." : "MB "); 11834 out.append(label, start, end); 11835 return; 11836 } 11837 } 11838 out.append(memKB/1024); 11839 out.append(stackLike ? "MB." : "MB "); 11840 out.append(label, start, end); 11841 } 11842 11843 static final int[] DUMP_MEM_OOM_ADJ = new int[] { 11844 ProcessList.NATIVE_ADJ, 11845 ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ, 11846 ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ, 11847 ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ, 11848 ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ, 11849 ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ 11850 }; 11851 static final String[] DUMP_MEM_OOM_LABEL = new String[] { 11852 "Native", 11853 "System", "Persistent", "Foreground", 11854 "Visible", "Perceptible", 11855 "Heavy Weight", "Backup", 11856 "A Services", "Home", 11857 "Previous", "B Services", "Cached" 11858 }; 11859 static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] { 11860 "native", 11861 "sys", "pers", "fore", 11862 "vis", "percept", 11863 "heavy", "backup", 11864 "servicea", "home", 11865 "prev", "serviceb", "cached" 11866 }; 11867 11868 private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime, 11869 long realtime, boolean isCheckinRequest, boolean isCompact) { 11870 if (isCheckinRequest || isCompact) { 11871 // short checkin version 11872 pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime); 11873 } else { 11874 pw.println("Applications Memory Usage (kB):"); 11875 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 11876 } 11877 } 11878 11879 final void dumpApplicationMemoryUsage(FileDescriptor fd, 11880 PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) { 11881 boolean dumpDetails = false; 11882 boolean dumpFullDetails = false; 11883 boolean dumpDalvik = false; 11884 boolean oomOnly = false; 11885 boolean isCompact = false; 11886 boolean localOnly = false; 11887 11888 int opti = 0; 11889 while (opti < args.length) { 11890 String opt = args[opti]; 11891 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 11892 break; 11893 } 11894 opti++; 11895 if ("-a".equals(opt)) { 11896 dumpDetails = true; 11897 dumpFullDetails = true; 11898 dumpDalvik = true; 11899 } else if ("-d".equals(opt)) { 11900 dumpDalvik = true; 11901 } else if ("-c".equals(opt)) { 11902 isCompact = true; 11903 } else if ("--oom".equals(opt)) { 11904 oomOnly = true; 11905 } else if ("--local".equals(opt)) { 11906 localOnly = true; 11907 } else if ("-h".equals(opt)) { 11908 pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]"); 11909 pw.println(" -a: include all available information for each process."); 11910 pw.println(" -d: include dalvik details when dumping process details."); 11911 pw.println(" -c: dump in a compact machine-parseable representation."); 11912 pw.println(" --oom: only show processes organized by oom adj."); 11913 pw.println(" --local: only collect details locally, don't call process."); 11914 pw.println("If [process] is specified it can be the name or "); 11915 pw.println("pid of a specific process to dump."); 11916 return; 11917 } else { 11918 pw.println("Unknown argument: " + opt + "; use -h for help"); 11919 } 11920 } 11921 11922 final boolean isCheckinRequest = scanArgs(args, "--checkin"); 11923 long uptime = SystemClock.uptimeMillis(); 11924 long realtime = SystemClock.elapsedRealtime(); 11925 final long[] tmpLong = new long[1]; 11926 11927 ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args); 11928 if (procs == null) { 11929 // No Java processes. Maybe they want to print a native process. 11930 if (args != null && args.length > opti 11931 && args[opti].charAt(0) != '-') { 11932 ArrayList<ProcessCpuTracker.Stats> nativeProcs 11933 = new ArrayList<ProcessCpuTracker.Stats>(); 11934 updateCpuStatsNow(); 11935 int findPid = -1; 11936 try { 11937 findPid = Integer.parseInt(args[opti]); 11938 } catch (NumberFormatException e) { 11939 } 11940 synchronized (mProcessCpuThread) { 11941 final int N = mProcessCpuTracker.countStats(); 11942 for (int i=0; i<N; i++) { 11943 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 11944 if (st.pid == findPid || (st.baseName != null 11945 && st.baseName.equals(args[opti]))) { 11946 nativeProcs.add(st); 11947 } 11948 } 11949 } 11950 if (nativeProcs.size() > 0) { 11951 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, 11952 isCompact); 11953 Debug.MemoryInfo mi = null; 11954 for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) { 11955 final ProcessCpuTracker.Stats r = nativeProcs.get(i); 11956 final int pid = r.pid; 11957 if (!isCheckinRequest && dumpDetails) { 11958 pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **"); 11959 } 11960 if (mi == null) { 11961 mi = new Debug.MemoryInfo(); 11962 } 11963 if (dumpDetails || (!brief && !oomOnly)) { 11964 Debug.getMemoryInfo(pid, mi); 11965 } else { 11966 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong); 11967 mi.dalvikPrivateDirty = (int)tmpLong[0]; 11968 } 11969 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails, 11970 dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0); 11971 if (isCheckinRequest) { 11972 pw.println(); 11973 } 11974 } 11975 return; 11976 } 11977 } 11978 pw.println("No process found for: " + args[opti]); 11979 return; 11980 } 11981 11982 if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest)) { 11983 dumpDetails = true; 11984 } 11985 11986 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact); 11987 11988 String[] innerArgs = new String[args.length-opti]; 11989 System.arraycopy(args, opti, innerArgs, 0, args.length-opti); 11990 11991 ArrayList<MemItem> procMems = new ArrayList<MemItem>(); 11992 final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>(); 11993 long nativePss=0, dalvikPss=0, otherPss=0; 11994 long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS]; 11995 11996 long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length]; 11997 ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[]) 11998 new ArrayList[DUMP_MEM_OOM_LABEL.length]; 11999 12000 long totalPss = 0; 12001 long cachedPss = 0; 12002 12003 Debug.MemoryInfo mi = null; 12004 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 12005 final ProcessRecord r = procs.get(i); 12006 final IApplicationThread thread; 12007 final int pid; 12008 final int oomAdj; 12009 final boolean hasActivities; 12010 synchronized (this) { 12011 thread = r.thread; 12012 pid = r.pid; 12013 oomAdj = r.getSetAdjWithServices(); 12014 hasActivities = r.activities.size() > 0; 12015 } 12016 if (thread != null) { 12017 if (!isCheckinRequest && dumpDetails) { 12018 pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **"); 12019 } 12020 if (mi == null) { 12021 mi = new Debug.MemoryInfo(); 12022 } 12023 if (dumpDetails || (!brief && !oomOnly)) { 12024 Debug.getMemoryInfo(pid, mi); 12025 } else { 12026 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong); 12027 mi.dalvikPrivateDirty = (int)tmpLong[0]; 12028 } 12029 if (dumpDetails) { 12030 if (localOnly) { 12031 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails, 12032 dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0); 12033 if (isCheckinRequest) { 12034 pw.println(); 12035 } 12036 } else { 12037 try { 12038 pw.flush(); 12039 thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails, 12040 dumpDalvik, innerArgs); 12041 } catch (RemoteException e) { 12042 if (!isCheckinRequest) { 12043 pw.println("Got RemoteException!"); 12044 pw.flush(); 12045 } 12046 } 12047 } 12048 } 12049 12050 final long myTotalPss = mi.getTotalPss(); 12051 final long myTotalUss = mi.getTotalUss(); 12052 12053 synchronized (this) { 12054 if (r.thread != null && oomAdj == r.getSetAdjWithServices()) { 12055 // Record this for posterity if the process has been stable. 12056 r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList); 12057 } 12058 } 12059 12060 if (!isCheckinRequest && mi != null) { 12061 totalPss += myTotalPss; 12062 MemItem pssItem = new MemItem(r.processName + " (pid " + pid + 12063 (hasActivities ? " / activities)" : ")"), 12064 r.processName, myTotalPss, pid, hasActivities); 12065 procMems.add(pssItem); 12066 procMemsMap.put(pid, pssItem); 12067 12068 nativePss += mi.nativePss; 12069 dalvikPss += mi.dalvikPss; 12070 otherPss += mi.otherPss; 12071 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 12072 long mem = mi.getOtherPss(j); 12073 miscPss[j] += mem; 12074 otherPss -= mem; 12075 } 12076 12077 if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 12078 cachedPss += myTotalPss; 12079 } 12080 12081 for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) { 12082 if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex] 12083 || oomIndex == (oomPss.length-1)) { 12084 oomPss[oomIndex] += myTotalPss; 12085 if (oomProcs[oomIndex] == null) { 12086 oomProcs[oomIndex] = new ArrayList<MemItem>(); 12087 } 12088 oomProcs[oomIndex].add(pssItem); 12089 break; 12090 } 12091 } 12092 } 12093 } 12094 } 12095 12096 if (!isCheckinRequest && procs.size() > 1) { 12097 // If we are showing aggregations, also look for native processes to 12098 // include so that our aggregations are more accurate. 12099 updateCpuStatsNow(); 12100 synchronized (mProcessCpuThread) { 12101 final int N = mProcessCpuTracker.countStats(); 12102 for (int i=0; i<N; i++) { 12103 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 12104 if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) { 12105 if (mi == null) { 12106 mi = new Debug.MemoryInfo(); 12107 } 12108 if (!brief && !oomOnly) { 12109 Debug.getMemoryInfo(st.pid, mi); 12110 } else { 12111 mi.nativePss = (int)Debug.getPss(st.pid, tmpLong); 12112 mi.nativePrivateDirty = (int)tmpLong[0]; 12113 } 12114 12115 final long myTotalPss = mi.getTotalPss(); 12116 totalPss += myTotalPss; 12117 12118 MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")", 12119 st.name, myTotalPss, st.pid, false); 12120 procMems.add(pssItem); 12121 12122 nativePss += mi.nativePss; 12123 dalvikPss += mi.dalvikPss; 12124 otherPss += mi.otherPss; 12125 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 12126 long mem = mi.getOtherPss(j); 12127 miscPss[j] += mem; 12128 otherPss -= mem; 12129 } 12130 oomPss[0] += myTotalPss; 12131 if (oomProcs[0] == null) { 12132 oomProcs[0] = new ArrayList<MemItem>(); 12133 } 12134 oomProcs[0].add(pssItem); 12135 } 12136 } 12137 } 12138 12139 ArrayList<MemItem> catMems = new ArrayList<MemItem>(); 12140 12141 catMems.add(new MemItem("Native", "Native", nativePss, -1)); 12142 catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2)); 12143 catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3)); 12144 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 12145 String label = Debug.MemoryInfo.getOtherLabel(j); 12146 catMems.add(new MemItem(label, label, miscPss[j], j)); 12147 } 12148 12149 ArrayList<MemItem> oomMems = new ArrayList<MemItem>(); 12150 for (int j=0; j<oomPss.length; j++) { 12151 if (oomPss[j] != 0) { 12152 String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j] 12153 : DUMP_MEM_OOM_LABEL[j]; 12154 MemItem item = new MemItem(label, label, oomPss[j], 12155 DUMP_MEM_OOM_ADJ[j]); 12156 item.subitems = oomProcs[j]; 12157 oomMems.add(item); 12158 } 12159 } 12160 12161 if (!brief && !oomOnly && !isCompact) { 12162 pw.println(); 12163 pw.println("Total PSS by process:"); 12164 dumpMemItems(pw, " ", "proc", procMems, true, isCompact); 12165 pw.println(); 12166 } 12167 if (!isCompact) { 12168 pw.println("Total PSS by OOM adjustment:"); 12169 } 12170 dumpMemItems(pw, " ", "oom", oomMems, false, isCompact); 12171 if (!brief && !oomOnly) { 12172 PrintWriter out = categoryPw != null ? categoryPw : pw; 12173 if (!isCompact) { 12174 out.println(); 12175 out.println("Total PSS by category:"); 12176 } 12177 dumpMemItems(out, " ", "cat", catMems, true, isCompact); 12178 } 12179 if (!isCompact) { 12180 pw.println(); 12181 } 12182 MemInfoReader memInfo = new MemInfoReader(); 12183 memInfo.readMemInfo(); 12184 if (!brief) { 12185 if (!isCompact) { 12186 pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb()); 12187 pw.print(" kB (status "); 12188 switch (mLastMemoryLevel) { 12189 case ProcessStats.ADJ_MEM_FACTOR_NORMAL: 12190 pw.println("normal)"); 12191 break; 12192 case ProcessStats.ADJ_MEM_FACTOR_MODERATE: 12193 pw.println("moderate)"); 12194 break; 12195 case ProcessStats.ADJ_MEM_FACTOR_LOW: 12196 pw.println("low)"); 12197 break; 12198 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL: 12199 pw.println("critical)"); 12200 break; 12201 default: 12202 pw.print(mLastMemoryLevel); 12203 pw.println(")"); 12204 break; 12205 } 12206 pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb() 12207 + memInfo.getFreeSizeKb()); pw.print(" kB ("); 12208 pw.print(cachedPss); pw.print(" cached pss + "); 12209 pw.print(memInfo.getCachedSizeKb()); pw.print(" cached + "); 12210 pw.print(memInfo.getFreeSizeKb()); pw.println(" free)"); 12211 } else { 12212 pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(","); 12213 pw.print(cachedPss + memInfo.getCachedSizeKb() 12214 + memInfo.getFreeSizeKb()); pw.print(","); 12215 pw.println(totalPss - cachedPss); 12216 } 12217 } 12218 if (!isCompact) { 12219 pw.print(" Used RAM: "); pw.print(totalPss - cachedPss 12220 + memInfo.getBuffersSizeKb() + memInfo.getShmemSizeKb() 12221 + memInfo.getSlabSizeKb()); pw.print(" kB ("); 12222 pw.print(totalPss - cachedPss); pw.print(" used pss + "); 12223 pw.print(memInfo.getBuffersSizeKb()); pw.print(" buffers + "); 12224 pw.print(memInfo.getShmemSizeKb()); pw.print(" shmem + "); 12225 pw.print(memInfo.getSlabSizeKb()); pw.println(" slab)"); 12226 pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb() 12227 - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb() 12228 - memInfo.getBuffersSizeKb() - memInfo.getShmemSizeKb() 12229 - memInfo.getSlabSizeKb()); pw.println(" kB"); 12230 } 12231 if (!brief) { 12232 if (memInfo.getZramTotalSizeKb() != 0) { 12233 if (!isCompact) { 12234 pw.print(" ZRAM: "); pw.print(memInfo.getZramTotalSizeKb()); 12235 pw.print(" kB physical used for "); 12236 pw.print(memInfo.getSwapTotalSizeKb() 12237 - memInfo.getSwapFreeSizeKb()); 12238 pw.print(" kB in swap ("); 12239 pw.print(memInfo.getSwapTotalSizeKb()); 12240 pw.println(" kB total swap)"); 12241 } else { 12242 pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(","); 12243 pw.print(memInfo.getSwapTotalSizeKb()); pw.print(","); 12244 pw.println(memInfo.getSwapFreeSizeKb()); 12245 } 12246 } 12247 final int[] SINGLE_LONG_FORMAT = new int[] { 12248 Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG 12249 }; 12250 long[] longOut = new long[1]; 12251 Process.readProcFile("/sys/kernel/mm/ksm/pages_shared", 12252 SINGLE_LONG_FORMAT, null, longOut, null); 12253 long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024; 12254 longOut[0] = 0; 12255 Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing", 12256 SINGLE_LONG_FORMAT, null, longOut, null); 12257 long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024; 12258 longOut[0] = 0; 12259 Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared", 12260 SINGLE_LONG_FORMAT, null, longOut, null); 12261 long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024; 12262 longOut[0] = 0; 12263 Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile", 12264 SINGLE_LONG_FORMAT, null, longOut, null); 12265 long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024; 12266 if (!isCompact) { 12267 if (sharing != 0 || shared != 0 || unshared != 0 || voltile != 0) { 12268 pw.print(" KSM: "); pw.print(sharing); 12269 pw.print(" kB saved from shared "); 12270 pw.print(shared); pw.println(" kB"); 12271 pw.print(" "); pw.print(unshared); pw.print(" kB unshared; "); 12272 pw.print(voltile); pw.println(" kB volatile"); 12273 } 12274 pw.print(" Tuning: "); 12275 pw.print(ActivityManager.staticGetMemoryClass()); 12276 pw.print(" (large "); 12277 pw.print(ActivityManager.staticGetLargeMemoryClass()); 12278 pw.print("), oom "); 12279 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024); 12280 pw.print(" kB"); 12281 pw.print(", restore limit "); 12282 pw.print(mProcessList.getCachedRestoreThresholdKb()); 12283 pw.print(" kB"); 12284 if (ActivityManager.isLowRamDeviceStatic()) { 12285 pw.print(" (low-ram)"); 12286 } 12287 if (ActivityManager.isHighEndGfx()) { 12288 pw.print(" (high-end-gfx)"); 12289 } 12290 pw.println(); 12291 } else { 12292 pw.print("ksm,"); pw.print(sharing); pw.print(","); 12293 pw.print(shared); pw.print(","); pw.print(unshared); pw.print(","); 12294 pw.println(voltile); 12295 pw.print("tuning,"); 12296 pw.print(ActivityManager.staticGetMemoryClass()); 12297 pw.print(','); 12298 pw.print(ActivityManager.staticGetLargeMemoryClass()); 12299 pw.print(','); 12300 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024); 12301 if (ActivityManager.isLowRamDeviceStatic()) { 12302 pw.print(",low-ram"); 12303 } 12304 if (ActivityManager.isHighEndGfx()) { 12305 pw.print(",high-end-gfx"); 12306 } 12307 pw.println(); 12308 } 12309 } 12310 } 12311 } 12312 12313 /** 12314 * Searches array of arguments for the specified string 12315 * @param args array of argument strings 12316 * @param value value to search for 12317 * @return true if the value is contained in the array 12318 */ 12319 private static boolean scanArgs(String[] args, String value) { 12320 if (args != null) { 12321 for (String arg : args) { 12322 if (value.equals(arg)) { 12323 return true; 12324 } 12325 } 12326 } 12327 return false; 12328 } 12329 12330 private final boolean removeDyingProviderLocked(ProcessRecord proc, 12331 ContentProviderRecord cpr, boolean always) { 12332 final boolean inLaunching = mLaunchingProviders.contains(cpr); 12333 12334 if (!inLaunching || always) { 12335 synchronized (cpr) { 12336 cpr.launchingApp = null; 12337 cpr.notifyAll(); 12338 } 12339 mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid)); 12340 String names[] = cpr.info.authority.split(";"); 12341 for (int j = 0; j < names.length; j++) { 12342 mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid)); 12343 } 12344 } 12345 12346 for (int i=0; i<cpr.connections.size(); i++) { 12347 ContentProviderConnection conn = cpr.connections.get(i); 12348 if (conn.waiting) { 12349 // If this connection is waiting for the provider, then we don't 12350 // need to mess with its process unless we are always removing 12351 // or for some reason the provider is not currently launching. 12352 if (inLaunching && !always) { 12353 continue; 12354 } 12355 } 12356 ProcessRecord capp = conn.client; 12357 conn.dead = true; 12358 if (conn.stableCount > 0) { 12359 if (!capp.persistent && capp.thread != null 12360 && capp.pid != 0 12361 && capp.pid != MY_PID) { 12362 killUnneededProcessLocked(capp, "depends on provider " 12363 + cpr.name.flattenToShortString() 12364 + " in dying proc " + (proc != null ? proc.processName : "??")); 12365 } 12366 } else if (capp.thread != null && conn.provider.provider != null) { 12367 try { 12368 capp.thread.unstableProviderDied(conn.provider.provider.asBinder()); 12369 } catch (RemoteException e) { 12370 } 12371 // In the protocol here, we don't expect the client to correctly 12372 // clean up this connection, we'll just remove it. 12373 cpr.connections.remove(i); 12374 conn.client.conProviders.remove(conn); 12375 } 12376 } 12377 12378 if (inLaunching && always) { 12379 mLaunchingProviders.remove(cpr); 12380 } 12381 return inLaunching; 12382 } 12383 12384 /** 12385 * Main code for cleaning up a process when it has gone away. This is 12386 * called both as a result of the process dying, or directly when stopping 12387 * a process when running in single process mode. 12388 */ 12389 private final void cleanUpApplicationRecordLocked(ProcessRecord app, 12390 boolean restarting, boolean allowRestart, int index) { 12391 if (index >= 0) { 12392 removeLruProcessLocked(app); 12393 ProcessList.remove(app.pid); 12394 } 12395 12396 mProcessesToGc.remove(app); 12397 mPendingPssProcesses.remove(app); 12398 12399 // Dismiss any open dialogs. 12400 if (app.crashDialog != null && !app.forceCrashReport) { 12401 app.crashDialog.dismiss(); 12402 app.crashDialog = null; 12403 } 12404 if (app.anrDialog != null) { 12405 app.anrDialog.dismiss(); 12406 app.anrDialog = null; 12407 } 12408 if (app.waitDialog != null) { 12409 app.waitDialog.dismiss(); 12410 app.waitDialog = null; 12411 } 12412 12413 app.crashing = false; 12414 app.notResponding = false; 12415 12416 app.resetPackageList(mProcessStats); 12417 app.unlinkDeathRecipient(); 12418 app.makeInactive(mProcessStats); 12419 app.forcingToForeground = null; 12420 updateProcessForegroundLocked(app, false, false); 12421 app.foregroundActivities = false; 12422 app.hasShownUi = false; 12423 app.hasAboveClient = false; 12424 12425 mServices.killServicesLocked(app, allowRestart); 12426 12427 boolean restart = false; 12428 12429 // Remove published content providers. 12430 for (int i=app.pubProviders.size()-1; i>=0; i--) { 12431 ContentProviderRecord cpr = app.pubProviders.valueAt(i); 12432 final boolean always = app.bad || !allowRestart; 12433 if (removeDyingProviderLocked(app, cpr, always) || always) { 12434 // We left the provider in the launching list, need to 12435 // restart it. 12436 restart = true; 12437 } 12438 12439 cpr.provider = null; 12440 cpr.proc = null; 12441 } 12442 app.pubProviders.clear(); 12443 12444 // Take care of any launching providers waiting for this process. 12445 if (checkAppInLaunchingProvidersLocked(app, false)) { 12446 restart = true; 12447 } 12448 12449 // Unregister from connected content providers. 12450 if (!app.conProviders.isEmpty()) { 12451 for (int i=0; i<app.conProviders.size(); i++) { 12452 ContentProviderConnection conn = app.conProviders.get(i); 12453 conn.provider.connections.remove(conn); 12454 } 12455 app.conProviders.clear(); 12456 } 12457 12458 // At this point there may be remaining entries in mLaunchingProviders 12459 // where we were the only one waiting, so they are no longer of use. 12460 // Look for these and clean up if found. 12461 // XXX Commented out for now. Trying to figure out a way to reproduce 12462 // the actual situation to identify what is actually going on. 12463 if (false) { 12464 for (int i=0; i<mLaunchingProviders.size(); i++) { 12465 ContentProviderRecord cpr = (ContentProviderRecord) 12466 mLaunchingProviders.get(i); 12467 if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) { 12468 synchronized (cpr) { 12469 cpr.launchingApp = null; 12470 cpr.notifyAll(); 12471 } 12472 } 12473 } 12474 } 12475 12476 skipCurrentReceiverLocked(app); 12477 12478 // Unregister any receivers. 12479 for (int i=app.receivers.size()-1; i>=0; i--) { 12480 removeReceiverLocked(app.receivers.valueAt(i)); 12481 } 12482 app.receivers.clear(); 12483 12484 // If the app is undergoing backup, tell the backup manager about it 12485 if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) { 12486 if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App " 12487 + mBackupTarget.appInfo + " died during backup"); 12488 try { 12489 IBackupManager bm = IBackupManager.Stub.asInterface( 12490 ServiceManager.getService(Context.BACKUP_SERVICE)); 12491 bm.agentDisconnected(app.info.packageName); 12492 } catch (RemoteException e) { 12493 // can't happen; backup manager is local 12494 } 12495 } 12496 12497 for (int i = mPendingProcessChanges.size()-1; i>=0; i--) { 12498 ProcessChangeItem item = mPendingProcessChanges.get(i); 12499 if (item.pid == app.pid) { 12500 mPendingProcessChanges.remove(i); 12501 mAvailProcessChanges.add(item); 12502 } 12503 } 12504 mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget(); 12505 12506 // If the caller is restarting this app, then leave it in its 12507 // current lists and let the caller take care of it. 12508 if (restarting) { 12509 return; 12510 } 12511 12512 if (!app.persistent || app.isolated) { 12513 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, 12514 "Removing non-persistent process during cleanup: " + app); 12515 mProcessNames.remove(app.processName, app.uid); 12516 mIsolatedProcesses.remove(app.uid); 12517 if (mHeavyWeightProcess == app) { 12518 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 12519 mHeavyWeightProcess.userId, 0)); 12520 mHeavyWeightProcess = null; 12521 } 12522 } else if (!app.removed) { 12523 // This app is persistent, so we need to keep its record around. 12524 // If it is not already on the pending app list, add it there 12525 // and start a new process for it. 12526 if (mPersistentStartingProcesses.indexOf(app) < 0) { 12527 mPersistentStartingProcesses.add(app); 12528 restart = true; 12529 } 12530 } 12531 if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG, 12532 "Clean-up removing on hold: " + app); 12533 mProcessesOnHold.remove(app); 12534 12535 if (app == mHomeProcess) { 12536 mHomeProcess = null; 12537 } 12538 if (app == mPreviousProcess) { 12539 mPreviousProcess = null; 12540 } 12541 12542 if (restart && !app.isolated) { 12543 // We have components that still need to be running in the 12544 // process, so re-launch it. 12545 mProcessNames.put(app.processName, app.uid, app); 12546 startProcessLocked(app, "restart", app.processName); 12547 } else if (app.pid > 0 && app.pid != MY_PID) { 12548 // Goodbye! 12549 boolean removed; 12550 synchronized (mPidsSelfLocked) { 12551 mPidsSelfLocked.remove(app.pid); 12552 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 12553 } 12554 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH, 12555 app.processName, app.info.uid); 12556 if (app.isolated) { 12557 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 12558 } 12559 app.setPid(0); 12560 } 12561 } 12562 12563 boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) { 12564 // Look through the content providers we are waiting to have launched, 12565 // and if any run in this process then either schedule a restart of 12566 // the process or kill the client waiting for it if this process has 12567 // gone bad. 12568 int NL = mLaunchingProviders.size(); 12569 boolean restart = false; 12570 for (int i=0; i<NL; i++) { 12571 ContentProviderRecord cpr = mLaunchingProviders.get(i); 12572 if (cpr.launchingApp == app) { 12573 if (!alwaysBad && !app.bad) { 12574 restart = true; 12575 } else { 12576 removeDyingProviderLocked(app, cpr, true); 12577 // cpr should have been removed from mLaunchingProviders 12578 NL = mLaunchingProviders.size(); 12579 i--; 12580 } 12581 } 12582 } 12583 return restart; 12584 } 12585 12586 // ========================================================= 12587 // SERVICES 12588 // ========================================================= 12589 12590 public List<ActivityManager.RunningServiceInfo> getServices(int maxNum, 12591 int flags) { 12592 enforceNotIsolatedCaller("getServices"); 12593 synchronized (this) { 12594 return mServices.getRunningServiceInfoLocked(maxNum, flags); 12595 } 12596 } 12597 12598 public PendingIntent getRunningServiceControlPanel(ComponentName name) { 12599 enforceNotIsolatedCaller("getRunningServiceControlPanel"); 12600 synchronized (this) { 12601 return mServices.getRunningServiceControlPanelLocked(name); 12602 } 12603 } 12604 12605 public ComponentName startService(IApplicationThread caller, Intent service, 12606 String resolvedType, int userId) { 12607 enforceNotIsolatedCaller("startService"); 12608 // Refuse possible leaked file descriptors 12609 if (service != null && service.hasFileDescriptors() == true) { 12610 throw new IllegalArgumentException("File descriptors passed in Intent"); 12611 } 12612 12613 if (DEBUG_SERVICE) 12614 Slog.v(TAG, "startService: " + service + " type=" + resolvedType); 12615 synchronized(this) { 12616 final int callingPid = Binder.getCallingPid(); 12617 final int callingUid = Binder.getCallingUid(); 12618 final long origId = Binder.clearCallingIdentity(); 12619 ComponentName res = mServices.startServiceLocked(caller, service, 12620 resolvedType, callingPid, callingUid, userId); 12621 Binder.restoreCallingIdentity(origId); 12622 return res; 12623 } 12624 } 12625 12626 ComponentName startServiceInPackage(int uid, 12627 Intent service, String resolvedType, int userId) { 12628 synchronized(this) { 12629 if (DEBUG_SERVICE) 12630 Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType); 12631 final long origId = Binder.clearCallingIdentity(); 12632 ComponentName res = mServices.startServiceLocked(null, service, 12633 resolvedType, -1, uid, userId); 12634 Binder.restoreCallingIdentity(origId); 12635 return res; 12636 } 12637 } 12638 12639 public int stopService(IApplicationThread caller, Intent service, 12640 String resolvedType, int userId) { 12641 enforceNotIsolatedCaller("stopService"); 12642 // Refuse possible leaked file descriptors 12643 if (service != null && service.hasFileDescriptors() == true) { 12644 throw new IllegalArgumentException("File descriptors passed in Intent"); 12645 } 12646 12647 synchronized(this) { 12648 return mServices.stopServiceLocked(caller, service, resolvedType, userId); 12649 } 12650 } 12651 12652 public IBinder peekService(Intent service, String resolvedType) { 12653 enforceNotIsolatedCaller("peekService"); 12654 // Refuse possible leaked file descriptors 12655 if (service != null && service.hasFileDescriptors() == true) { 12656 throw new IllegalArgumentException("File descriptors passed in Intent"); 12657 } 12658 synchronized(this) { 12659 return mServices.peekServiceLocked(service, resolvedType); 12660 } 12661 } 12662 12663 public boolean stopServiceToken(ComponentName className, IBinder token, 12664 int startId) { 12665 synchronized(this) { 12666 return mServices.stopServiceTokenLocked(className, token, startId); 12667 } 12668 } 12669 12670 public void setServiceForeground(ComponentName className, IBinder token, 12671 int id, Notification notification, boolean removeNotification) { 12672 synchronized(this) { 12673 mServices.setServiceForegroundLocked(className, token, id, notification, 12674 removeNotification); 12675 } 12676 } 12677 12678 public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll, 12679 boolean requireFull, String name, String callerPackage) { 12680 final int callingUserId = UserHandle.getUserId(callingUid); 12681 if (callingUserId != userId) { 12682 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 12683 if ((requireFull || checkComponentPermission( 12684 android.Manifest.permission.INTERACT_ACROSS_USERS, 12685 callingPid, callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) 12686 && checkComponentPermission( 12687 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 12688 callingPid, callingUid, -1, true) 12689 != PackageManager.PERMISSION_GRANTED) { 12690 if (userId == UserHandle.USER_CURRENT_OR_SELF) { 12691 // In this case, they would like to just execute as their 12692 // owner user instead of failing. 12693 userId = callingUserId; 12694 } else { 12695 StringBuilder builder = new StringBuilder(128); 12696 builder.append("Permission Denial: "); 12697 builder.append(name); 12698 if (callerPackage != null) { 12699 builder.append(" from "); 12700 builder.append(callerPackage); 12701 } 12702 builder.append(" asks to run as user "); 12703 builder.append(userId); 12704 builder.append(" but is calling from user "); 12705 builder.append(UserHandle.getUserId(callingUid)); 12706 builder.append("; this requires "); 12707 builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL); 12708 if (!requireFull) { 12709 builder.append(" or "); 12710 builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS); 12711 } 12712 String msg = builder.toString(); 12713 Slog.w(TAG, msg); 12714 throw new SecurityException(msg); 12715 } 12716 } 12717 } 12718 if (userId == UserHandle.USER_CURRENT 12719 || userId == UserHandle.USER_CURRENT_OR_SELF) { 12720 // Note that we may be accessing this outside of a lock... 12721 // shouldn't be a big deal, if this is being called outside 12722 // of a locked context there is intrinsically a race with 12723 // the value the caller will receive and someone else changing it. 12724 userId = mCurrentUserId; 12725 } 12726 if (!allowAll && userId < 0) { 12727 throw new IllegalArgumentException( 12728 "Call does not support special user #" + userId); 12729 } 12730 } 12731 return userId; 12732 } 12733 12734 boolean isSingleton(String componentProcessName, ApplicationInfo aInfo, 12735 String className, int flags) { 12736 boolean result = false; 12737 if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) { 12738 if ((flags&ServiceInfo.FLAG_SINGLE_USER) != 0) { 12739 if (ActivityManager.checkUidPermission( 12740 android.Manifest.permission.INTERACT_ACROSS_USERS, 12741 aInfo.uid) != PackageManager.PERMISSION_GRANTED) { 12742 ComponentName comp = new ComponentName(aInfo.packageName, className); 12743 String msg = "Permission Denial: Component " + comp.flattenToShortString() 12744 + " requests FLAG_SINGLE_USER, but app does not hold " 12745 + android.Manifest.permission.INTERACT_ACROSS_USERS; 12746 Slog.w(TAG, msg); 12747 throw new SecurityException(msg); 12748 } 12749 result = true; 12750 } 12751 } else if (componentProcessName == aInfo.packageName) { 12752 result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0; 12753 } else if ("system".equals(componentProcessName)) { 12754 result = true; 12755 } 12756 if (DEBUG_MU) { 12757 Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo 12758 + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result); 12759 } 12760 return result; 12761 } 12762 12763 public int bindService(IApplicationThread caller, IBinder token, 12764 Intent service, String resolvedType, 12765 IServiceConnection connection, int flags, int userId) { 12766 enforceNotIsolatedCaller("bindService"); 12767 // Refuse possible leaked file descriptors 12768 if (service != null && service.hasFileDescriptors() == true) { 12769 throw new IllegalArgumentException("File descriptors passed in Intent"); 12770 } 12771 12772 synchronized(this) { 12773 return mServices.bindServiceLocked(caller, token, service, resolvedType, 12774 connection, flags, userId); 12775 } 12776 } 12777 12778 public boolean unbindService(IServiceConnection connection) { 12779 synchronized (this) { 12780 return mServices.unbindServiceLocked(connection); 12781 } 12782 } 12783 12784 public void publishService(IBinder token, Intent intent, IBinder service) { 12785 // Refuse possible leaked file descriptors 12786 if (intent != null && intent.hasFileDescriptors() == true) { 12787 throw new IllegalArgumentException("File descriptors passed in Intent"); 12788 } 12789 12790 synchronized(this) { 12791 if (!(token instanceof ServiceRecord)) { 12792 throw new IllegalArgumentException("Invalid service token"); 12793 } 12794 mServices.publishServiceLocked((ServiceRecord)token, intent, service); 12795 } 12796 } 12797 12798 public void unbindFinished(IBinder token, Intent intent, boolean doRebind) { 12799 // Refuse possible leaked file descriptors 12800 if (intent != null && intent.hasFileDescriptors() == true) { 12801 throw new IllegalArgumentException("File descriptors passed in Intent"); 12802 } 12803 12804 synchronized(this) { 12805 mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind); 12806 } 12807 } 12808 12809 public void serviceDoneExecuting(IBinder token, int type, int startId, int res) { 12810 synchronized(this) { 12811 if (!(token instanceof ServiceRecord)) { 12812 throw new IllegalArgumentException("Invalid service token"); 12813 } 12814 mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res); 12815 } 12816 } 12817 12818 // ========================================================= 12819 // BACKUP AND RESTORE 12820 // ========================================================= 12821 12822 // Cause the target app to be launched if necessary and its backup agent 12823 // instantiated. The backup agent will invoke backupAgentCreated() on the 12824 // activity manager to announce its creation. 12825 public boolean bindBackupAgent(ApplicationInfo app, int backupMode) { 12826 if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode); 12827 enforceCallingPermission("android.permission.BACKUP", "bindBackupAgent"); 12828 12829 synchronized(this) { 12830 // !!! TODO: currently no check here that we're already bound 12831 BatteryStatsImpl.Uid.Pkg.Serv ss = null; 12832 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 12833 synchronized (stats) { 12834 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name); 12835 } 12836 12837 // Backup agent is now in use, its package can't be stopped. 12838 try { 12839 AppGlobals.getPackageManager().setPackageStoppedState( 12840 app.packageName, false, UserHandle.getUserId(app.uid)); 12841 } catch (RemoteException e) { 12842 } catch (IllegalArgumentException e) { 12843 Slog.w(TAG, "Failed trying to unstop package " 12844 + app.packageName + ": " + e); 12845 } 12846 12847 BackupRecord r = new BackupRecord(ss, app, backupMode); 12848 ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL) 12849 ? new ComponentName(app.packageName, app.backupAgentName) 12850 : new ComponentName("android", "FullBackupAgent"); 12851 // startProcessLocked() returns existing proc's record if it's already running 12852 ProcessRecord proc = startProcessLocked(app.processName, app, 12853 false, 0, "backup", hostingName, false, false, false); 12854 if (proc == null) { 12855 Slog.e(TAG, "Unable to start backup agent process " + r); 12856 return false; 12857 } 12858 12859 r.app = proc; 12860 mBackupTarget = r; 12861 mBackupAppName = app.packageName; 12862 12863 // Try not to kill the process during backup 12864 updateOomAdjLocked(proc); 12865 12866 // If the process is already attached, schedule the creation of the backup agent now. 12867 // If it is not yet live, this will be done when it attaches to the framework. 12868 if (proc.thread != null) { 12869 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc); 12870 try { 12871 proc.thread.scheduleCreateBackupAgent(app, 12872 compatibilityInfoForPackageLocked(app), backupMode); 12873 } catch (RemoteException e) { 12874 // Will time out on the backup manager side 12875 } 12876 } else { 12877 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach"); 12878 } 12879 // Invariants: at this point, the target app process exists and the application 12880 // is either already running or in the process of coming up. mBackupTarget and 12881 // mBackupAppName describe the app, so that when it binds back to the AM we 12882 // know that it's scheduled for a backup-agent operation. 12883 } 12884 12885 return true; 12886 } 12887 12888 @Override 12889 public void clearPendingBackup() { 12890 if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup"); 12891 enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup"); 12892 12893 synchronized (this) { 12894 mBackupTarget = null; 12895 mBackupAppName = null; 12896 } 12897 } 12898 12899 // A backup agent has just come up 12900 public void backupAgentCreated(String agentPackageName, IBinder agent) { 12901 if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName 12902 + " = " + agent); 12903 12904 synchronized(this) { 12905 if (!agentPackageName.equals(mBackupAppName)) { 12906 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!"); 12907 return; 12908 } 12909 } 12910 12911 long oldIdent = Binder.clearCallingIdentity(); 12912 try { 12913 IBackupManager bm = IBackupManager.Stub.asInterface( 12914 ServiceManager.getService(Context.BACKUP_SERVICE)); 12915 bm.agentConnected(agentPackageName, agent); 12916 } catch (RemoteException e) { 12917 // can't happen; the backup manager service is local 12918 } catch (Exception e) { 12919 Slog.w(TAG, "Exception trying to deliver BackupAgent binding: "); 12920 e.printStackTrace(); 12921 } finally { 12922 Binder.restoreCallingIdentity(oldIdent); 12923 } 12924 } 12925 12926 // done with this agent 12927 public void unbindBackupAgent(ApplicationInfo appInfo) { 12928 if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo); 12929 if (appInfo == null) { 12930 Slog.w(TAG, "unbind backup agent for null app"); 12931 return; 12932 } 12933 12934 synchronized(this) { 12935 try { 12936 if (mBackupAppName == null) { 12937 Slog.w(TAG, "Unbinding backup agent with no active backup"); 12938 return; 12939 } 12940 12941 if (!mBackupAppName.equals(appInfo.packageName)) { 12942 Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target"); 12943 return; 12944 } 12945 12946 // Not backing this app up any more; reset its OOM adjustment 12947 final ProcessRecord proc = mBackupTarget.app; 12948 updateOomAdjLocked(proc); 12949 12950 // If the app crashed during backup, 'thread' will be null here 12951 if (proc.thread != null) { 12952 try { 12953 proc.thread.scheduleDestroyBackupAgent(appInfo, 12954 compatibilityInfoForPackageLocked(appInfo)); 12955 } catch (Exception e) { 12956 Slog.e(TAG, "Exception when unbinding backup agent:"); 12957 e.printStackTrace(); 12958 } 12959 } 12960 } finally { 12961 mBackupTarget = null; 12962 mBackupAppName = null; 12963 } 12964 } 12965 } 12966 // ========================================================= 12967 // BROADCASTS 12968 // ========================================================= 12969 12970 private final List getStickiesLocked(String action, IntentFilter filter, 12971 List cur, int userId) { 12972 final ContentResolver resolver = mContext.getContentResolver(); 12973 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 12974 if (stickies == null) { 12975 return cur; 12976 } 12977 final ArrayList<Intent> list = stickies.get(action); 12978 if (list == null) { 12979 return cur; 12980 } 12981 int N = list.size(); 12982 for (int i=0; i<N; i++) { 12983 Intent intent = list.get(i); 12984 if (filter.match(resolver, intent, true, TAG) >= 0) { 12985 if (cur == null) { 12986 cur = new ArrayList<Intent>(); 12987 } 12988 cur.add(intent); 12989 } 12990 } 12991 return cur; 12992 } 12993 12994 boolean isPendingBroadcastProcessLocked(int pid) { 12995 return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid) 12996 || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid); 12997 } 12998 12999 void skipPendingBroadcastLocked(int pid) { 13000 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 13001 for (BroadcastQueue queue : mBroadcastQueues) { 13002 queue.skipPendingBroadcastLocked(pid); 13003 } 13004 } 13005 13006 // The app just attached; send any pending broadcasts that it should receive 13007 boolean sendPendingBroadcastsLocked(ProcessRecord app) { 13008 boolean didSomething = false; 13009 for (BroadcastQueue queue : mBroadcastQueues) { 13010 didSomething |= queue.sendPendingBroadcastsLocked(app); 13011 } 13012 return didSomething; 13013 } 13014 13015 public Intent registerReceiver(IApplicationThread caller, String callerPackage, 13016 IIntentReceiver receiver, IntentFilter filter, String permission, int userId) { 13017 enforceNotIsolatedCaller("registerReceiver"); 13018 int callingUid; 13019 int callingPid; 13020 synchronized(this) { 13021 ProcessRecord callerApp = null; 13022 if (caller != null) { 13023 callerApp = getRecordForAppLocked(caller); 13024 if (callerApp == null) { 13025 throw new SecurityException( 13026 "Unable to find app for caller " + caller 13027 + " (pid=" + Binder.getCallingPid() 13028 + ") when registering receiver " + receiver); 13029 } 13030 if (callerApp.info.uid != Process.SYSTEM_UID && 13031 !callerApp.pkgList.containsKey(callerPackage) && 13032 !"android".equals(callerPackage)) { 13033 throw new SecurityException("Given caller package " + callerPackage 13034 + " is not running in process " + callerApp); 13035 } 13036 callingUid = callerApp.info.uid; 13037 callingPid = callerApp.pid; 13038 } else { 13039 callerPackage = null; 13040 callingUid = Binder.getCallingUid(); 13041 callingPid = Binder.getCallingPid(); 13042 } 13043 13044 userId = this.handleIncomingUser(callingPid, callingUid, userId, 13045 true, true, "registerReceiver", callerPackage); 13046 13047 List allSticky = null; 13048 13049 // Look for any matching sticky broadcasts... 13050 Iterator actions = filter.actionsIterator(); 13051 if (actions != null) { 13052 while (actions.hasNext()) { 13053 String action = (String)actions.next(); 13054 allSticky = getStickiesLocked(action, filter, allSticky, 13055 UserHandle.USER_ALL); 13056 allSticky = getStickiesLocked(action, filter, allSticky, 13057 UserHandle.getUserId(callingUid)); 13058 } 13059 } else { 13060 allSticky = getStickiesLocked(null, filter, allSticky, 13061 UserHandle.USER_ALL); 13062 allSticky = getStickiesLocked(null, filter, allSticky, 13063 UserHandle.getUserId(callingUid)); 13064 } 13065 13066 // The first sticky in the list is returned directly back to 13067 // the client. 13068 Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null; 13069 13070 if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter 13071 + ": " + sticky); 13072 13073 if (receiver == null) { 13074 return sticky; 13075 } 13076 13077 ReceiverList rl 13078 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder()); 13079 if (rl == null) { 13080 rl = new ReceiverList(this, callerApp, callingPid, callingUid, 13081 userId, receiver); 13082 if (rl.app != null) { 13083 rl.app.receivers.add(rl); 13084 } else { 13085 try { 13086 receiver.asBinder().linkToDeath(rl, 0); 13087 } catch (RemoteException e) { 13088 return sticky; 13089 } 13090 rl.linkedToDeath = true; 13091 } 13092 mRegisteredReceivers.put(receiver.asBinder(), rl); 13093 } else if (rl.uid != callingUid) { 13094 throw new IllegalArgumentException( 13095 "Receiver requested to register for uid " + callingUid 13096 + " was previously registered for uid " + rl.uid); 13097 } else if (rl.pid != callingPid) { 13098 throw new IllegalArgumentException( 13099 "Receiver requested to register for pid " + callingPid 13100 + " was previously registered for pid " + rl.pid); 13101 } else if (rl.userId != userId) { 13102 throw new IllegalArgumentException( 13103 "Receiver requested to register for user " + userId 13104 + " was previously registered for user " + rl.userId); 13105 } 13106 BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage, 13107 permission, callingUid, userId); 13108 rl.add(bf); 13109 if (!bf.debugCheck()) { 13110 Slog.w(TAG, "==> For Dynamic broadast"); 13111 } 13112 mReceiverResolver.addFilter(bf); 13113 13114 // Enqueue broadcasts for all existing stickies that match 13115 // this filter. 13116 if (allSticky != null) { 13117 ArrayList receivers = new ArrayList(); 13118 receivers.add(bf); 13119 13120 int N = allSticky.size(); 13121 for (int i=0; i<N; i++) { 13122 Intent intent = (Intent)allSticky.get(i); 13123 BroadcastQueue queue = broadcastQueueForIntent(intent); 13124 BroadcastRecord r = new BroadcastRecord(queue, intent, null, 13125 null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0, 13126 null, null, false, true, true, -1); 13127 queue.enqueueParallelBroadcastLocked(r); 13128 queue.scheduleBroadcastsLocked(); 13129 } 13130 } 13131 13132 return sticky; 13133 } 13134 } 13135 13136 public void unregisterReceiver(IIntentReceiver receiver) { 13137 if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver); 13138 13139 final long origId = Binder.clearCallingIdentity(); 13140 try { 13141 boolean doTrim = false; 13142 13143 synchronized(this) { 13144 ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder()); 13145 if (rl != null) { 13146 if (rl.curBroadcast != null) { 13147 BroadcastRecord r = rl.curBroadcast; 13148 final boolean doNext = finishReceiverLocked( 13149 receiver.asBinder(), r.resultCode, r.resultData, 13150 r.resultExtras, r.resultAbort); 13151 if (doNext) { 13152 doTrim = true; 13153 r.queue.processNextBroadcast(false); 13154 } 13155 } 13156 13157 if (rl.app != null) { 13158 rl.app.receivers.remove(rl); 13159 } 13160 removeReceiverLocked(rl); 13161 if (rl.linkedToDeath) { 13162 rl.linkedToDeath = false; 13163 rl.receiver.asBinder().unlinkToDeath(rl, 0); 13164 } 13165 } 13166 } 13167 13168 // If we actually concluded any broadcasts, we might now be able 13169 // to trim the recipients' apps from our working set 13170 if (doTrim) { 13171 trimApplications(); 13172 return; 13173 } 13174 13175 } finally { 13176 Binder.restoreCallingIdentity(origId); 13177 } 13178 } 13179 13180 void removeReceiverLocked(ReceiverList rl) { 13181 mRegisteredReceivers.remove(rl.receiver.asBinder()); 13182 int N = rl.size(); 13183 for (int i=0; i<N; i++) { 13184 mReceiverResolver.removeFilter(rl.get(i)); 13185 } 13186 } 13187 13188 private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) { 13189 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 13190 ProcessRecord r = mLruProcesses.get(i); 13191 if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) { 13192 try { 13193 r.thread.dispatchPackageBroadcast(cmd, packages); 13194 } catch (RemoteException ex) { 13195 } 13196 } 13197 } 13198 } 13199 13200 private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType, 13201 int[] users) { 13202 List<ResolveInfo> receivers = null; 13203 try { 13204 HashSet<ComponentName> singleUserReceivers = null; 13205 boolean scannedFirstReceivers = false; 13206 for (int user : users) { 13207 List<ResolveInfo> newReceivers = AppGlobals.getPackageManager() 13208 .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user); 13209 if (user != 0 && newReceivers != null) { 13210 // If this is not the primary user, we need to check for 13211 // any receivers that should be filtered out. 13212 for (int i=0; i<newReceivers.size(); i++) { 13213 ResolveInfo ri = newReceivers.get(i); 13214 if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) { 13215 newReceivers.remove(i); 13216 i--; 13217 } 13218 } 13219 } 13220 if (newReceivers != null && newReceivers.size() == 0) { 13221 newReceivers = null; 13222 } 13223 if (receivers == null) { 13224 receivers = newReceivers; 13225 } else if (newReceivers != null) { 13226 // We need to concatenate the additional receivers 13227 // found with what we have do far. This would be easy, 13228 // but we also need to de-dup any receivers that are 13229 // singleUser. 13230 if (!scannedFirstReceivers) { 13231 // Collect any single user receivers we had already retrieved. 13232 scannedFirstReceivers = true; 13233 for (int i=0; i<receivers.size(); i++) { 13234 ResolveInfo ri = receivers.get(i); 13235 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 13236 ComponentName cn = new ComponentName( 13237 ri.activityInfo.packageName, ri.activityInfo.name); 13238 if (singleUserReceivers == null) { 13239 singleUserReceivers = new HashSet<ComponentName>(); 13240 } 13241 singleUserReceivers.add(cn); 13242 } 13243 } 13244 } 13245 // Add the new results to the existing results, tracking 13246 // and de-dupping single user receivers. 13247 for (int i=0; i<newReceivers.size(); i++) { 13248 ResolveInfo ri = newReceivers.get(i); 13249 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 13250 ComponentName cn = new ComponentName( 13251 ri.activityInfo.packageName, ri.activityInfo.name); 13252 if (singleUserReceivers == null) { 13253 singleUserReceivers = new HashSet<ComponentName>(); 13254 } 13255 if (!singleUserReceivers.contains(cn)) { 13256 singleUserReceivers.add(cn); 13257 receivers.add(ri); 13258 } 13259 } else { 13260 receivers.add(ri); 13261 } 13262 } 13263 } 13264 } 13265 } catch (RemoteException ex) { 13266 // pm is in same process, this will never happen. 13267 } 13268 return receivers; 13269 } 13270 13271 private final int broadcastIntentLocked(ProcessRecord callerApp, 13272 String callerPackage, Intent intent, String resolvedType, 13273 IIntentReceiver resultTo, int resultCode, String resultData, 13274 Bundle map, String requiredPermission, int appOp, 13275 boolean ordered, boolean sticky, int callingPid, int callingUid, 13276 int userId) { 13277 intent = new Intent(intent); 13278 13279 // By default broadcasts do not go to stopped apps. 13280 intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES); 13281 13282 if (DEBUG_BROADCAST_LIGHT) Slog.v( 13283 TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent 13284 + " ordered=" + ordered + " userid=" + userId); 13285 if ((resultTo != null) && !ordered) { 13286 Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!"); 13287 } 13288 13289 userId = handleIncomingUser(callingPid, callingUid, userId, 13290 true, false, "broadcast", callerPackage); 13291 13292 // Make sure that the user who is receiving this broadcast is started. 13293 // If not, we will just skip it. 13294 if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) { 13295 if (callingUid != Process.SYSTEM_UID || (intent.getFlags() 13296 & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) { 13297 Slog.w(TAG, "Skipping broadcast of " + intent 13298 + ": user " + userId + " is stopped"); 13299 return ActivityManager.BROADCAST_SUCCESS; 13300 } 13301 } 13302 13303 /* 13304 * Prevent non-system code (defined here to be non-persistent 13305 * processes) from sending protected broadcasts. 13306 */ 13307 int callingAppId = UserHandle.getAppId(callingUid); 13308 if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID 13309 || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID || 13310 callingUid == 0) { 13311 // Always okay. 13312 } else if (callerApp == null || !callerApp.persistent) { 13313 try { 13314 if (AppGlobals.getPackageManager().isProtectedBroadcast( 13315 intent.getAction())) { 13316 String msg = "Permission Denial: not allowed to send broadcast " 13317 + intent.getAction() + " from pid=" 13318 + callingPid + ", uid=" + callingUid; 13319 Slog.w(TAG, msg); 13320 throw new SecurityException(msg); 13321 } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) { 13322 // Special case for compatibility: we don't want apps to send this, 13323 // but historically it has not been protected and apps may be using it 13324 // to poke their own app widget. So, instead of making it protected, 13325 // just limit it to the caller. 13326 if (callerApp == null) { 13327 String msg = "Permission Denial: not allowed to send broadcast " 13328 + intent.getAction() + " from unknown caller."; 13329 Slog.w(TAG, msg); 13330 throw new SecurityException(msg); 13331 } else if (intent.getComponent() != null) { 13332 // They are good enough to send to an explicit component... verify 13333 // it is being sent to the calling app. 13334 if (!intent.getComponent().getPackageName().equals( 13335 callerApp.info.packageName)) { 13336 String msg = "Permission Denial: not allowed to send broadcast " 13337 + intent.getAction() + " to " 13338 + intent.getComponent().getPackageName() + " from " 13339 + callerApp.info.packageName; 13340 Slog.w(TAG, msg); 13341 throw new SecurityException(msg); 13342 } 13343 } else { 13344 // Limit broadcast to their own package. 13345 intent.setPackage(callerApp.info.packageName); 13346 } 13347 } 13348 } catch (RemoteException e) { 13349 Slog.w(TAG, "Remote exception", e); 13350 return ActivityManager.BROADCAST_SUCCESS; 13351 } 13352 } 13353 13354 // Handle special intents: if this broadcast is from the package 13355 // manager about a package being removed, we need to remove all of 13356 // its activities from the history stack. 13357 final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals( 13358 intent.getAction()); 13359 if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction()) 13360 || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction()) 13361 || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction()) 13362 || uidRemoved) { 13363 if (checkComponentPermission( 13364 android.Manifest.permission.BROADCAST_PACKAGE_REMOVED, 13365 callingPid, callingUid, -1, true) 13366 == PackageManager.PERMISSION_GRANTED) { 13367 if (uidRemoved) { 13368 final Bundle intentExtras = intent.getExtras(); 13369 final int uid = intentExtras != null 13370 ? intentExtras.getInt(Intent.EXTRA_UID) : -1; 13371 if (uid >= 0) { 13372 BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics(); 13373 synchronized (bs) { 13374 bs.removeUidStatsLocked(uid); 13375 } 13376 mAppOpsService.uidRemoved(uid); 13377 } 13378 } else { 13379 // If resources are unavailable just force stop all 13380 // those packages and flush the attribute cache as well. 13381 if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) { 13382 String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 13383 if (list != null && (list.length > 0)) { 13384 for (String pkg : list) { 13385 forceStopPackageLocked(pkg, -1, false, true, true, false, false, userId, 13386 "storage unmount"); 13387 } 13388 sendPackageBroadcastLocked( 13389 IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId); 13390 } 13391 } else { 13392 Uri data = intent.getData(); 13393 String ssp; 13394 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 13395 boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals( 13396 intent.getAction()); 13397 boolean fullUninstall = removed && 13398 !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false); 13399 if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) { 13400 forceStopPackageLocked(ssp, UserHandle.getAppId( 13401 intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true, 13402 false, fullUninstall, userId, 13403 removed ? "pkg removed" : "pkg changed"); 13404 } 13405 if (removed) { 13406 sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED, 13407 new String[] {ssp}, userId); 13408 if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) { 13409 mAppOpsService.packageRemoved( 13410 intent.getIntExtra(Intent.EXTRA_UID, -1), ssp); 13411 13412 // Remove all permissions granted from/to this package 13413 removeUriPermissionsForPackageLocked(ssp, userId, true); 13414 } 13415 } 13416 } 13417 } 13418 } 13419 } else { 13420 String msg = "Permission Denial: " + intent.getAction() 13421 + " broadcast from " + callerPackage + " (pid=" + callingPid 13422 + ", uid=" + callingUid + ")" 13423 + " requires " 13424 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED; 13425 Slog.w(TAG, msg); 13426 throw new SecurityException(msg); 13427 } 13428 13429 // Special case for adding a package: by default turn on compatibility 13430 // mode. 13431 } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) { 13432 Uri data = intent.getData(); 13433 String ssp; 13434 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 13435 mCompatModePackages.handlePackageAddedLocked(ssp, 13436 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)); 13437 } 13438 } 13439 13440 /* 13441 * If this is the time zone changed action, queue up a message that will reset the timezone 13442 * of all currently running processes. This message will get queued up before the broadcast 13443 * happens. 13444 */ 13445 if (intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) { 13446 mHandler.sendEmptyMessage(UPDATE_TIME_ZONE); 13447 } 13448 13449 if (intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) { 13450 mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG); 13451 } 13452 13453 if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) { 13454 ProxyProperties proxy = intent.getParcelableExtra("proxy"); 13455 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy)); 13456 } 13457 13458 // Add to the sticky list if requested. 13459 if (sticky) { 13460 if (checkPermission(android.Manifest.permission.BROADCAST_STICKY, 13461 callingPid, callingUid) 13462 != PackageManager.PERMISSION_GRANTED) { 13463 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid=" 13464 + callingPid + ", uid=" + callingUid 13465 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 13466 Slog.w(TAG, msg); 13467 throw new SecurityException(msg); 13468 } 13469 if (requiredPermission != null) { 13470 Slog.w(TAG, "Can't broadcast sticky intent " + intent 13471 + " and enforce permission " + requiredPermission); 13472 return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION; 13473 } 13474 if (intent.getComponent() != null) { 13475 throw new SecurityException( 13476 "Sticky broadcasts can't target a specific component"); 13477 } 13478 // We use userId directly here, since the "all" target is maintained 13479 // as a separate set of sticky broadcasts. 13480 if (userId != UserHandle.USER_ALL) { 13481 // But first, if this is not a broadcast to all users, then 13482 // make sure it doesn't conflict with an existing broadcast to 13483 // all users. 13484 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get( 13485 UserHandle.USER_ALL); 13486 if (stickies != null) { 13487 ArrayList<Intent> list = stickies.get(intent.getAction()); 13488 if (list != null) { 13489 int N = list.size(); 13490 int i; 13491 for (i=0; i<N; i++) { 13492 if (intent.filterEquals(list.get(i))) { 13493 throw new IllegalArgumentException( 13494 "Sticky broadcast " + intent + " for user " 13495 + userId + " conflicts with existing global broadcast"); 13496 } 13497 } 13498 } 13499 } 13500 } 13501 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 13502 if (stickies == null) { 13503 stickies = new ArrayMap<String, ArrayList<Intent>>(); 13504 mStickyBroadcasts.put(userId, stickies); 13505 } 13506 ArrayList<Intent> list = stickies.get(intent.getAction()); 13507 if (list == null) { 13508 list = new ArrayList<Intent>(); 13509 stickies.put(intent.getAction(), list); 13510 } 13511 int N = list.size(); 13512 int i; 13513 for (i=0; i<N; i++) { 13514 if (intent.filterEquals(list.get(i))) { 13515 // This sticky already exists, replace it. 13516 list.set(i, new Intent(intent)); 13517 break; 13518 } 13519 } 13520 if (i >= N) { 13521 list.add(new Intent(intent)); 13522 } 13523 } 13524 13525 int[] users; 13526 if (userId == UserHandle.USER_ALL) { 13527 // Caller wants broadcast to go to all started users. 13528 users = mStartedUserArray; 13529 } else { 13530 // Caller wants broadcast to go to one specific user. 13531 users = new int[] {userId}; 13532 } 13533 13534 // Figure out who all will receive this broadcast. 13535 List receivers = null; 13536 List<BroadcastFilter> registeredReceivers = null; 13537 // Need to resolve the intent to interested receivers... 13538 if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) 13539 == 0) { 13540 receivers = collectReceiverComponents(intent, resolvedType, users); 13541 } 13542 if (intent.getComponent() == null) { 13543 registeredReceivers = mReceiverResolver.queryIntent(intent, 13544 resolvedType, false, userId); 13545 } 13546 13547 final boolean replacePending = 13548 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0; 13549 13550 if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction() 13551 + " replacePending=" + replacePending); 13552 13553 int NR = registeredReceivers != null ? registeredReceivers.size() : 0; 13554 if (!ordered && NR > 0) { 13555 // If we are not serializing this broadcast, then send the 13556 // registered receivers separately so they don't wait for the 13557 // components to be launched. 13558 final BroadcastQueue queue = broadcastQueueForIntent(intent); 13559 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 13560 callerPackage, callingPid, callingUid, resolvedType, requiredPermission, 13561 appOp, registeredReceivers, resultTo, resultCode, resultData, map, 13562 ordered, sticky, false, userId); 13563 if (DEBUG_BROADCAST) Slog.v( 13564 TAG, "Enqueueing parallel broadcast " + r); 13565 final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r); 13566 if (!replaced) { 13567 queue.enqueueParallelBroadcastLocked(r); 13568 queue.scheduleBroadcastsLocked(); 13569 } 13570 registeredReceivers = null; 13571 NR = 0; 13572 } 13573 13574 // Merge into one list. 13575 int ir = 0; 13576 if (receivers != null) { 13577 // A special case for PACKAGE_ADDED: do not allow the package 13578 // being added to see this broadcast. This prevents them from 13579 // using this as a back door to get run as soon as they are 13580 // installed. Maybe in the future we want to have a special install 13581 // broadcast or such for apps, but we'd like to deliberately make 13582 // this decision. 13583 String skipPackages[] = null; 13584 if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction()) 13585 || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction()) 13586 || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) { 13587 Uri data = intent.getData(); 13588 if (data != null) { 13589 String pkgName = data.getSchemeSpecificPart(); 13590 if (pkgName != null) { 13591 skipPackages = new String[] { pkgName }; 13592 } 13593 } 13594 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) { 13595 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 13596 } 13597 if (skipPackages != null && (skipPackages.length > 0)) { 13598 for (String skipPackage : skipPackages) { 13599 if (skipPackage != null) { 13600 int NT = receivers.size(); 13601 for (int it=0; it<NT; it++) { 13602 ResolveInfo curt = (ResolveInfo)receivers.get(it); 13603 if (curt.activityInfo.packageName.equals(skipPackage)) { 13604 receivers.remove(it); 13605 it--; 13606 NT--; 13607 } 13608 } 13609 } 13610 } 13611 } 13612 13613 int NT = receivers != null ? receivers.size() : 0; 13614 int it = 0; 13615 ResolveInfo curt = null; 13616 BroadcastFilter curr = null; 13617 while (it < NT && ir < NR) { 13618 if (curt == null) { 13619 curt = (ResolveInfo)receivers.get(it); 13620 } 13621 if (curr == null) { 13622 curr = registeredReceivers.get(ir); 13623 } 13624 if (curr.getPriority() >= curt.priority) { 13625 // Insert this broadcast record into the final list. 13626 receivers.add(it, curr); 13627 ir++; 13628 curr = null; 13629 it++; 13630 NT++; 13631 } else { 13632 // Skip to the next ResolveInfo in the final list. 13633 it++; 13634 curt = null; 13635 } 13636 } 13637 } 13638 while (ir < NR) { 13639 if (receivers == null) { 13640 receivers = new ArrayList(); 13641 } 13642 receivers.add(registeredReceivers.get(ir)); 13643 ir++; 13644 } 13645 13646 if ((receivers != null && receivers.size() > 0) 13647 || resultTo != null) { 13648 BroadcastQueue queue = broadcastQueueForIntent(intent); 13649 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 13650 callerPackage, callingPid, callingUid, resolvedType, 13651 requiredPermission, appOp, receivers, resultTo, resultCode, 13652 resultData, map, ordered, sticky, false, userId); 13653 if (DEBUG_BROADCAST) Slog.v( 13654 TAG, "Enqueueing ordered broadcast " + r 13655 + ": prev had " + queue.mOrderedBroadcasts.size()); 13656 if (DEBUG_BROADCAST) { 13657 int seq = r.intent.getIntExtra("seq", -1); 13658 Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq); 13659 } 13660 boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r); 13661 if (!replaced) { 13662 queue.enqueueOrderedBroadcastLocked(r); 13663 queue.scheduleBroadcastsLocked(); 13664 } 13665 } 13666 13667 return ActivityManager.BROADCAST_SUCCESS; 13668 } 13669 13670 final Intent verifyBroadcastLocked(Intent intent) { 13671 // Refuse possible leaked file descriptors 13672 if (intent != null && intent.hasFileDescriptors() == true) { 13673 throw new IllegalArgumentException("File descriptors passed in Intent"); 13674 } 13675 13676 int flags = intent.getFlags(); 13677 13678 if (!mProcessesReady) { 13679 // if the caller really truly claims to know what they're doing, go 13680 // ahead and allow the broadcast without launching any receivers 13681 if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) { 13682 intent = new Intent(intent); 13683 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 13684 } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) { 13685 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent 13686 + " before boot completion"); 13687 throw new IllegalStateException("Cannot broadcast before boot completed"); 13688 } 13689 } 13690 13691 if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 13692 throw new IllegalArgumentException( 13693 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 13694 } 13695 13696 return intent; 13697 } 13698 13699 public final int broadcastIntent(IApplicationThread caller, 13700 Intent intent, String resolvedType, IIntentReceiver resultTo, 13701 int resultCode, String resultData, Bundle map, 13702 String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) { 13703 enforceNotIsolatedCaller("broadcastIntent"); 13704 synchronized(this) { 13705 intent = verifyBroadcastLocked(intent); 13706 13707 final ProcessRecord callerApp = getRecordForAppLocked(caller); 13708 final int callingPid = Binder.getCallingPid(); 13709 final int callingUid = Binder.getCallingUid(); 13710 final long origId = Binder.clearCallingIdentity(); 13711 int res = broadcastIntentLocked(callerApp, 13712 callerApp != null ? callerApp.info.packageName : null, 13713 intent, resolvedType, resultTo, 13714 resultCode, resultData, map, requiredPermission, appOp, serialized, sticky, 13715 callingPid, callingUid, userId); 13716 Binder.restoreCallingIdentity(origId); 13717 return res; 13718 } 13719 } 13720 13721 int broadcastIntentInPackage(String packageName, int uid, 13722 Intent intent, String resolvedType, IIntentReceiver resultTo, 13723 int resultCode, String resultData, Bundle map, 13724 String requiredPermission, boolean serialized, boolean sticky, int userId) { 13725 synchronized(this) { 13726 intent = verifyBroadcastLocked(intent); 13727 13728 final long origId = Binder.clearCallingIdentity(); 13729 int res = broadcastIntentLocked(null, packageName, intent, resolvedType, 13730 resultTo, resultCode, resultData, map, requiredPermission, 13731 AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId); 13732 Binder.restoreCallingIdentity(origId); 13733 return res; 13734 } 13735 } 13736 13737 public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) { 13738 // Refuse possible leaked file descriptors 13739 if (intent != null && intent.hasFileDescriptors() == true) { 13740 throw new IllegalArgumentException("File descriptors passed in Intent"); 13741 } 13742 13743 userId = handleIncomingUser(Binder.getCallingPid(), 13744 Binder.getCallingUid(), userId, true, false, "removeStickyBroadcast", null); 13745 13746 synchronized(this) { 13747 if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY) 13748 != PackageManager.PERMISSION_GRANTED) { 13749 String msg = "Permission Denial: unbroadcastIntent() from pid=" 13750 + Binder.getCallingPid() 13751 + ", uid=" + Binder.getCallingUid() 13752 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 13753 Slog.w(TAG, msg); 13754 throw new SecurityException(msg); 13755 } 13756 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 13757 if (stickies != null) { 13758 ArrayList<Intent> list = stickies.get(intent.getAction()); 13759 if (list != null) { 13760 int N = list.size(); 13761 int i; 13762 for (i=0; i<N; i++) { 13763 if (intent.filterEquals(list.get(i))) { 13764 list.remove(i); 13765 break; 13766 } 13767 } 13768 if (list.size() <= 0) { 13769 stickies.remove(intent.getAction()); 13770 } 13771 } 13772 if (stickies.size() <= 0) { 13773 mStickyBroadcasts.remove(userId); 13774 } 13775 } 13776 } 13777 } 13778 13779 private final boolean finishReceiverLocked(IBinder receiver, int resultCode, 13780 String resultData, Bundle resultExtras, boolean resultAbort) { 13781 final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver); 13782 if (r == null) { 13783 Slog.w(TAG, "finishReceiver called but not found on queue"); 13784 return false; 13785 } 13786 13787 return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false); 13788 } 13789 13790 void backgroundServicesFinishedLocked(int userId) { 13791 for (BroadcastQueue queue : mBroadcastQueues) { 13792 queue.backgroundServicesFinishedLocked(userId); 13793 } 13794 } 13795 13796 public void finishReceiver(IBinder who, int resultCode, String resultData, 13797 Bundle resultExtras, boolean resultAbort) { 13798 if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who); 13799 13800 // Refuse possible leaked file descriptors 13801 if (resultExtras != null && resultExtras.hasFileDescriptors()) { 13802 throw new IllegalArgumentException("File descriptors passed in Bundle"); 13803 } 13804 13805 final long origId = Binder.clearCallingIdentity(); 13806 try { 13807 boolean doNext = false; 13808 BroadcastRecord r; 13809 13810 synchronized(this) { 13811 r = broadcastRecordForReceiverLocked(who); 13812 if (r != null) { 13813 doNext = r.queue.finishReceiverLocked(r, resultCode, 13814 resultData, resultExtras, resultAbort, true); 13815 } 13816 } 13817 13818 if (doNext) { 13819 r.queue.processNextBroadcast(false); 13820 } 13821 trimApplications(); 13822 } finally { 13823 Binder.restoreCallingIdentity(origId); 13824 } 13825 } 13826 13827 // ========================================================= 13828 // INSTRUMENTATION 13829 // ========================================================= 13830 13831 public boolean startInstrumentation(ComponentName className, 13832 String profileFile, int flags, Bundle arguments, 13833 IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection, 13834 int userId) { 13835 enforceNotIsolatedCaller("startInstrumentation"); 13836 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 13837 userId, false, true, "startInstrumentation", null); 13838 // Refuse possible leaked file descriptors 13839 if (arguments != null && arguments.hasFileDescriptors()) { 13840 throw new IllegalArgumentException("File descriptors passed in Bundle"); 13841 } 13842 13843 synchronized(this) { 13844 InstrumentationInfo ii = null; 13845 ApplicationInfo ai = null; 13846 try { 13847 ii = mContext.getPackageManager().getInstrumentationInfo( 13848 className, STOCK_PM_FLAGS); 13849 ai = AppGlobals.getPackageManager().getApplicationInfo( 13850 ii.targetPackage, STOCK_PM_FLAGS, userId); 13851 } catch (PackageManager.NameNotFoundException e) { 13852 } catch (RemoteException e) { 13853 } 13854 if (ii == null) { 13855 reportStartInstrumentationFailure(watcher, className, 13856 "Unable to find instrumentation info for: " + className); 13857 return false; 13858 } 13859 if (ai == null) { 13860 reportStartInstrumentationFailure(watcher, className, 13861 "Unable to find instrumentation target package: " + ii.targetPackage); 13862 return false; 13863 } 13864 13865 int match = mContext.getPackageManager().checkSignatures( 13866 ii.targetPackage, ii.packageName); 13867 if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) { 13868 String msg = "Permission Denial: starting instrumentation " 13869 + className + " from pid=" 13870 + Binder.getCallingPid() 13871 + ", uid=" + Binder.getCallingPid() 13872 + " not allowed because package " + ii.packageName 13873 + " does not have a signature matching the target " 13874 + ii.targetPackage; 13875 reportStartInstrumentationFailure(watcher, className, msg); 13876 throw new SecurityException(msg); 13877 } 13878 13879 final long origId = Binder.clearCallingIdentity(); 13880 // Instrumentation can kill and relaunch even persistent processes 13881 forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId, 13882 "start instr"); 13883 ProcessRecord app = addAppLocked(ai, false); 13884 app.instrumentationClass = className; 13885 app.instrumentationInfo = ai; 13886 app.instrumentationProfileFile = profileFile; 13887 app.instrumentationArguments = arguments; 13888 app.instrumentationWatcher = watcher; 13889 app.instrumentationUiAutomationConnection = uiAutomationConnection; 13890 app.instrumentationResultClass = className; 13891 Binder.restoreCallingIdentity(origId); 13892 } 13893 13894 return true; 13895 } 13896 13897 /** 13898 * Report errors that occur while attempting to start Instrumentation. Always writes the 13899 * error to the logs, but if somebody is watching, send the report there too. This enables 13900 * the "am" command to report errors with more information. 13901 * 13902 * @param watcher The IInstrumentationWatcher. Null if there isn't one. 13903 * @param cn The component name of the instrumentation. 13904 * @param report The error report. 13905 */ 13906 private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher, 13907 ComponentName cn, String report) { 13908 Slog.w(TAG, report); 13909 try { 13910 if (watcher != null) { 13911 Bundle results = new Bundle(); 13912 results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService"); 13913 results.putString("Error", report); 13914 watcher.instrumentationStatus(cn, -1, results); 13915 } 13916 } catch (RemoteException e) { 13917 Slog.w(TAG, e); 13918 } 13919 } 13920 13921 void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) { 13922 if (app.instrumentationWatcher != null) { 13923 try { 13924 // NOTE: IInstrumentationWatcher *must* be oneway here 13925 app.instrumentationWatcher.instrumentationFinished( 13926 app.instrumentationClass, 13927 resultCode, 13928 results); 13929 } catch (RemoteException e) { 13930 } 13931 } 13932 if (app.instrumentationUiAutomationConnection != null) { 13933 try { 13934 app.instrumentationUiAutomationConnection.shutdown(); 13935 } catch (RemoteException re) { 13936 /* ignore */ 13937 } 13938 // Only a UiAutomation can set this flag and now that 13939 // it is finished we make sure it is reset to its default. 13940 mUserIsMonkey = false; 13941 } 13942 app.instrumentationWatcher = null; 13943 app.instrumentationUiAutomationConnection = null; 13944 app.instrumentationClass = null; 13945 app.instrumentationInfo = null; 13946 app.instrumentationProfileFile = null; 13947 app.instrumentationArguments = null; 13948 13949 forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId, 13950 "finished inst"); 13951 } 13952 13953 public void finishInstrumentation(IApplicationThread target, 13954 int resultCode, Bundle results) { 13955 int userId = UserHandle.getCallingUserId(); 13956 // Refuse possible leaked file descriptors 13957 if (results != null && results.hasFileDescriptors()) { 13958 throw new IllegalArgumentException("File descriptors passed in Intent"); 13959 } 13960 13961 synchronized(this) { 13962 ProcessRecord app = getRecordForAppLocked(target); 13963 if (app == null) { 13964 Slog.w(TAG, "finishInstrumentation: no app for " + target); 13965 return; 13966 } 13967 final long origId = Binder.clearCallingIdentity(); 13968 finishInstrumentationLocked(app, resultCode, results); 13969 Binder.restoreCallingIdentity(origId); 13970 } 13971 } 13972 13973 // ========================================================= 13974 // CONFIGURATION 13975 // ========================================================= 13976 13977 public ConfigurationInfo getDeviceConfigurationInfo() { 13978 ConfigurationInfo config = new ConfigurationInfo(); 13979 synchronized (this) { 13980 config.reqTouchScreen = mConfiguration.touchscreen; 13981 config.reqKeyboardType = mConfiguration.keyboard; 13982 config.reqNavigation = mConfiguration.navigation; 13983 if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD 13984 || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) { 13985 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV; 13986 } 13987 if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED 13988 && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) { 13989 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD; 13990 } 13991 config.reqGlEsVersion = GL_ES_VERSION; 13992 } 13993 return config; 13994 } 13995 13996 ActivityStack getFocusedStack() { 13997 return mStackSupervisor.getFocusedStack(); 13998 } 13999 14000 public Configuration getConfiguration() { 14001 Configuration ci; 14002 synchronized(this) { 14003 ci = new Configuration(mConfiguration); 14004 } 14005 return ci; 14006 } 14007 14008 public void updatePersistentConfiguration(Configuration values) { 14009 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 14010 "updateConfiguration()"); 14011 enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS, 14012 "updateConfiguration()"); 14013 if (values == null) { 14014 throw new NullPointerException("Configuration must not be null"); 14015 } 14016 14017 synchronized(this) { 14018 final long origId = Binder.clearCallingIdentity(); 14019 updateConfigurationLocked(values, null, true, false); 14020 Binder.restoreCallingIdentity(origId); 14021 } 14022 } 14023 14024 public void updateConfiguration(Configuration values) { 14025 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 14026 "updateConfiguration()"); 14027 14028 synchronized(this) { 14029 if (values == null && mWindowManager != null) { 14030 // sentinel: fetch the current configuration from the window manager 14031 values = mWindowManager.computeNewConfiguration(); 14032 } 14033 14034 if (mWindowManager != null) { 14035 mProcessList.applyDisplaySize(mWindowManager); 14036 } 14037 14038 final long origId = Binder.clearCallingIdentity(); 14039 if (values != null) { 14040 Settings.System.clearConfiguration(values); 14041 } 14042 updateConfigurationLocked(values, null, false, false); 14043 Binder.restoreCallingIdentity(origId); 14044 } 14045 } 14046 14047 /** 14048 * Do either or both things: (1) change the current configuration, and (2) 14049 * make sure the given activity is running with the (now) current 14050 * configuration. Returns true if the activity has been left running, or 14051 * false if <var>starting</var> is being destroyed to match the new 14052 * configuration. 14053 * @param persistent TODO 14054 */ 14055 boolean updateConfigurationLocked(Configuration values, 14056 ActivityRecord starting, boolean persistent, boolean initLocale) { 14057 int changes = 0; 14058 14059 if (values != null) { 14060 Configuration newConfig = new Configuration(mConfiguration); 14061 changes = newConfig.updateFrom(values); 14062 if (changes != 0) { 14063 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) { 14064 Slog.i(TAG, "Updating configuration to: " + values); 14065 } 14066 14067 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes); 14068 14069 if (values.locale != null && !initLocale) { 14070 saveLocaleLocked(values.locale, 14071 !values.locale.equals(mConfiguration.locale), 14072 values.userSetLocale); 14073 } 14074 14075 mConfigurationSeq++; 14076 if (mConfigurationSeq <= 0) { 14077 mConfigurationSeq = 1; 14078 } 14079 newConfig.seq = mConfigurationSeq; 14080 mConfiguration = newConfig; 14081 Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig); 14082 14083 final Configuration configCopy = new Configuration(mConfiguration); 14084 14085 // TODO: If our config changes, should we auto dismiss any currently 14086 // showing dialogs? 14087 mShowDialogs = shouldShowDialogs(newConfig); 14088 14089 AttributeCache ac = AttributeCache.instance(); 14090 if (ac != null) { 14091 ac.updateConfiguration(configCopy); 14092 } 14093 14094 // Make sure all resources in our process are updated 14095 // right now, so that anyone who is going to retrieve 14096 // resource values after we return will be sure to get 14097 // the new ones. This is especially important during 14098 // boot, where the first config change needs to guarantee 14099 // all resources have that config before following boot 14100 // code is executed. 14101 mSystemThread.applyConfigurationToResources(configCopy); 14102 14103 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) { 14104 Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG); 14105 msg.obj = new Configuration(configCopy); 14106 mHandler.sendMessage(msg); 14107 } 14108 14109 for (int i=mLruProcesses.size()-1; i>=0; i--) { 14110 ProcessRecord app = mLruProcesses.get(i); 14111 try { 14112 if (app.thread != null) { 14113 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc " 14114 + app.processName + " new config " + mConfiguration); 14115 app.thread.scheduleConfigurationChanged(configCopy); 14116 } 14117 } catch (Exception e) { 14118 } 14119 } 14120 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED); 14121 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 14122 | Intent.FLAG_RECEIVER_REPLACE_PENDING 14123 | Intent.FLAG_RECEIVER_FOREGROUND); 14124 broadcastIntentLocked(null, null, intent, null, null, 0, null, null, 14125 null, AppOpsManager.OP_NONE, false, false, MY_PID, 14126 Process.SYSTEM_UID, UserHandle.USER_ALL); 14127 if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) { 14128 intent = new Intent(Intent.ACTION_LOCALE_CHANGED); 14129 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 14130 broadcastIntentLocked(null, null, intent, 14131 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 14132 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 14133 } 14134 } 14135 } 14136 14137 boolean kept = true; 14138 final ActivityStack mainStack = mStackSupervisor.getFocusedStack(); 14139 // mainStack is null during startup. 14140 if (mainStack != null) { 14141 if (changes != 0 && starting == null) { 14142 // If the configuration changed, and the caller is not already 14143 // in the process of starting an activity, then find the top 14144 // activity to check if its configuration needs to change. 14145 starting = mainStack.topRunningActivityLocked(null); 14146 } 14147 14148 if (starting != null) { 14149 kept = mainStack.ensureActivityConfigurationLocked(starting, changes); 14150 // And we need to make sure at this point that all other activities 14151 // are made visible with the correct configuration. 14152 mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes); 14153 } 14154 } 14155 14156 if (values != null && mWindowManager != null) { 14157 mWindowManager.setNewConfiguration(mConfiguration); 14158 } 14159 14160 return kept; 14161 } 14162 14163 /** 14164 * Decide based on the configuration whether we should shouw the ANR, 14165 * crash, etc dialogs. The idea is that if there is no affordnace to 14166 * press the on-screen buttons, we shouldn't show the dialog. 14167 * 14168 * A thought: SystemUI might also want to get told about this, the Power 14169 * dialog / global actions also might want different behaviors. 14170 */ 14171 private static final boolean shouldShowDialogs(Configuration config) { 14172 return !(config.keyboard == Configuration.KEYBOARD_NOKEYS 14173 && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH); 14174 } 14175 14176 /** 14177 * Save the locale. You must be inside a synchronized (this) block. 14178 */ 14179 private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) { 14180 if(isDiff) { 14181 SystemProperties.set("user.language", l.getLanguage()); 14182 SystemProperties.set("user.region", l.getCountry()); 14183 } 14184 14185 if(isPersist) { 14186 SystemProperties.set("persist.sys.language", l.getLanguage()); 14187 SystemProperties.set("persist.sys.country", l.getCountry()); 14188 SystemProperties.set("persist.sys.localevar", l.getVariant()); 14189 } 14190 } 14191 14192 @Override 14193 public boolean targetTaskAffinityMatchesActivity(IBinder token, String destAffinity) { 14194 ActivityRecord srec = ActivityRecord.forToken(token); 14195 return srec != null && srec.task.affinity != null && 14196 srec.task.affinity.equals(destAffinity); 14197 } 14198 14199 public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode, 14200 Intent resultData) { 14201 14202 synchronized (this) { 14203 final ActivityStack stack = ActivityRecord.getStackLocked(token); 14204 if (stack != null) { 14205 return stack.navigateUpToLocked(token, destIntent, resultCode, resultData); 14206 } 14207 return false; 14208 } 14209 } 14210 14211 public int getLaunchedFromUid(IBinder activityToken) { 14212 ActivityRecord srec = ActivityRecord.forToken(activityToken); 14213 if (srec == null) { 14214 return -1; 14215 } 14216 return srec.launchedFromUid; 14217 } 14218 14219 public String getLaunchedFromPackage(IBinder activityToken) { 14220 ActivityRecord srec = ActivityRecord.forToken(activityToken); 14221 if (srec == null) { 14222 return null; 14223 } 14224 return srec.launchedFromPackage; 14225 } 14226 14227 // ========================================================= 14228 // LIFETIME MANAGEMENT 14229 // ========================================================= 14230 14231 // Returns which broadcast queue the app is the current [or imminent] receiver 14232 // on, or 'null' if the app is not an active broadcast recipient. 14233 private BroadcastQueue isReceivingBroadcast(ProcessRecord app) { 14234 BroadcastRecord r = app.curReceiver; 14235 if (r != null) { 14236 return r.queue; 14237 } 14238 14239 // It's not the current receiver, but it might be starting up to become one 14240 synchronized (this) { 14241 for (BroadcastQueue queue : mBroadcastQueues) { 14242 r = queue.mPendingBroadcast; 14243 if (r != null && r.curApp == app) { 14244 // found it; report which queue it's in 14245 return queue; 14246 } 14247 } 14248 } 14249 14250 return null; 14251 } 14252 14253 private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP, 14254 boolean doingAll, long now) { 14255 if (mAdjSeq == app.adjSeq) { 14256 // This adjustment has already been computed. 14257 return app.curRawAdj; 14258 } 14259 14260 if (app.thread == null) { 14261 app.adjSeq = mAdjSeq; 14262 app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 14263 app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 14264 return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ); 14265 } 14266 14267 app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN; 14268 app.adjSource = null; 14269 app.adjTarget = null; 14270 app.empty = false; 14271 app.cached = false; 14272 14273 final int activitiesSize = app.activities.size(); 14274 14275 if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) { 14276 // The max adjustment doesn't allow this app to be anything 14277 // below foreground, so it is not worth doing work for it. 14278 app.adjType = "fixed"; 14279 app.adjSeq = mAdjSeq; 14280 app.curRawAdj = app.maxAdj; 14281 app.foregroundActivities = false; 14282 app.keeping = true; 14283 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT; 14284 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT; 14285 // System process can do UI, and when they do we want to have 14286 // them trim their memory after the user leaves the UI. To 14287 // facilitate this, here we need to determine whether or not it 14288 // is currently showing UI. 14289 app.systemNoUi = true; 14290 if (app == TOP_APP) { 14291 app.systemNoUi = false; 14292 } else if (activitiesSize > 0) { 14293 for (int j = 0; j < activitiesSize; j++) { 14294 final ActivityRecord r = app.activities.get(j); 14295 if (r.visible) { 14296 app.systemNoUi = false; 14297 } 14298 } 14299 } 14300 if (!app.systemNoUi) { 14301 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI; 14302 } 14303 return (app.curAdj=app.maxAdj); 14304 } 14305 14306 app.keeping = false; 14307 app.systemNoUi = false; 14308 14309 // Determine the importance of the process, starting with most 14310 // important to least, and assign an appropriate OOM adjustment. 14311 int adj; 14312 int schedGroup; 14313 int procState; 14314 boolean foregroundActivities = false; 14315 boolean interesting = false; 14316 BroadcastQueue queue; 14317 if (app == TOP_APP) { 14318 // The last app on the list is the foreground app. 14319 adj = ProcessList.FOREGROUND_APP_ADJ; 14320 schedGroup = Process.THREAD_GROUP_DEFAULT; 14321 app.adjType = "top-activity"; 14322 foregroundActivities = true; 14323 interesting = true; 14324 procState = ActivityManager.PROCESS_STATE_TOP; 14325 } else if (app.instrumentationClass != null) { 14326 // Don't want to kill running instrumentation. 14327 adj = ProcessList.FOREGROUND_APP_ADJ; 14328 schedGroup = Process.THREAD_GROUP_DEFAULT; 14329 app.adjType = "instrumentation"; 14330 interesting = true; 14331 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14332 } else if ((queue = isReceivingBroadcast(app)) != null) { 14333 // An app that is currently receiving a broadcast also 14334 // counts as being in the foreground for OOM killer purposes. 14335 // It's placed in a sched group based on the nature of the 14336 // broadcast as reflected by which queue it's active in. 14337 adj = ProcessList.FOREGROUND_APP_ADJ; 14338 schedGroup = (queue == mFgBroadcastQueue) 14339 ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 14340 app.adjType = "broadcast"; 14341 procState = ActivityManager.PROCESS_STATE_RECEIVER; 14342 } else if (app.executingServices.size() > 0) { 14343 // An app that is currently executing a service callback also 14344 // counts as being in the foreground. 14345 adj = ProcessList.FOREGROUND_APP_ADJ; 14346 schedGroup = app.execServicesFg ? 14347 Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 14348 app.adjType = "exec-service"; 14349 procState = ActivityManager.PROCESS_STATE_SERVICE; 14350 //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app); 14351 } else { 14352 // As far as we know the process is empty. We may change our mind later. 14353 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 14354 // At this point we don't actually know the adjustment. Use the cached adj 14355 // value that the caller wants us to. 14356 adj = cachedAdj; 14357 procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 14358 app.cached = true; 14359 app.empty = true; 14360 app.adjType = "cch-empty"; 14361 } 14362 14363 // Examine all activities if not already foreground. 14364 if (!foregroundActivities && activitiesSize > 0) { 14365 for (int j = 0; j < activitiesSize; j++) { 14366 final ActivityRecord r = app.activities.get(j); 14367 if (r.app != app) { 14368 Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc " 14369 + app + "?!?"); 14370 continue; 14371 } 14372 if (r.visible) { 14373 // App has a visible activity; only upgrade adjustment. 14374 if (adj > ProcessList.VISIBLE_APP_ADJ) { 14375 adj = ProcessList.VISIBLE_APP_ADJ; 14376 app.adjType = "visible"; 14377 } 14378 if (procState > ActivityManager.PROCESS_STATE_TOP) { 14379 procState = ActivityManager.PROCESS_STATE_TOP; 14380 } 14381 schedGroup = Process.THREAD_GROUP_DEFAULT; 14382 app.cached = false; 14383 app.empty = false; 14384 foregroundActivities = true; 14385 break; 14386 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) { 14387 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14388 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 14389 app.adjType = "pausing"; 14390 } 14391 if (procState > ActivityManager.PROCESS_STATE_TOP) { 14392 procState = ActivityManager.PROCESS_STATE_TOP; 14393 } 14394 schedGroup = Process.THREAD_GROUP_DEFAULT; 14395 app.cached = false; 14396 app.empty = false; 14397 foregroundActivities = true; 14398 } else if (r.state == ActivityState.STOPPING) { 14399 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14400 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 14401 app.adjType = "stopping"; 14402 } 14403 // For the process state, we will at this point consider the 14404 // process to be cached. It will be cached either as an activity 14405 // or empty depending on whether the activity is finishing. We do 14406 // this so that we can treat the process as cached for purposes of 14407 // memory trimming (determing current memory level, trim command to 14408 // send to process) since there can be an arbitrary number of stopping 14409 // processes and they should soon all go into the cached state. 14410 if (!r.finishing) { 14411 if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 14412 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 14413 } 14414 } 14415 app.cached = false; 14416 app.empty = false; 14417 foregroundActivities = true; 14418 } else { 14419 if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 14420 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 14421 app.adjType = "cch-act"; 14422 } 14423 } 14424 } 14425 } 14426 14427 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14428 if (app.foregroundServices) { 14429 // The user is aware of this app, so make it visible. 14430 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 14431 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14432 app.cached = false; 14433 app.adjType = "fg-service"; 14434 schedGroup = Process.THREAD_GROUP_DEFAULT; 14435 } else if (app.forcingToForeground != null) { 14436 // The user is aware of this app, so make it visible. 14437 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 14438 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14439 app.cached = false; 14440 app.adjType = "force-fg"; 14441 app.adjSource = app.forcingToForeground; 14442 schedGroup = Process.THREAD_GROUP_DEFAULT; 14443 } 14444 } 14445 14446 if (app.foregroundServices) { 14447 interesting = true; 14448 } 14449 14450 if (app == mHeavyWeightProcess) { 14451 if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) { 14452 // We don't want to kill the current heavy-weight process. 14453 adj = ProcessList.HEAVY_WEIGHT_APP_ADJ; 14454 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 14455 app.cached = false; 14456 app.adjType = "heavy"; 14457 } 14458 if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) { 14459 procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT; 14460 } 14461 } 14462 14463 if (app == mHomeProcess) { 14464 if (adj > ProcessList.HOME_APP_ADJ) { 14465 // This process is hosting what we currently consider to be the 14466 // home app, so we don't want to let it go into the background. 14467 adj = ProcessList.HOME_APP_ADJ; 14468 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 14469 app.cached = false; 14470 app.adjType = "home"; 14471 } 14472 if (procState > ActivityManager.PROCESS_STATE_HOME) { 14473 procState = ActivityManager.PROCESS_STATE_HOME; 14474 } 14475 } 14476 14477 if (app == mPreviousProcess && app.activities.size() > 0) { 14478 if (adj > ProcessList.PREVIOUS_APP_ADJ) { 14479 // This was the previous process that showed UI to the user. 14480 // We want to try to keep it around more aggressively, to give 14481 // a good experience around switching between two apps. 14482 adj = ProcessList.PREVIOUS_APP_ADJ; 14483 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 14484 app.cached = false; 14485 app.adjType = "previous"; 14486 } 14487 if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) { 14488 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY; 14489 } 14490 } 14491 14492 if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj 14493 + " reason=" + app.adjType); 14494 14495 // By default, we use the computed adjustment. It may be changed if 14496 // there are applications dependent on our services or providers, but 14497 // this gives us a baseline and makes sure we don't get into an 14498 // infinite recursion. 14499 app.adjSeq = mAdjSeq; 14500 app.curRawAdj = adj; 14501 app.hasStartedServices = false; 14502 14503 if (mBackupTarget != null && app == mBackupTarget.app) { 14504 // If possible we want to avoid killing apps while they're being backed up 14505 if (adj > ProcessList.BACKUP_APP_ADJ) { 14506 if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app); 14507 adj = ProcessList.BACKUP_APP_ADJ; 14508 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) { 14509 procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND; 14510 } 14511 app.adjType = "backup"; 14512 app.cached = false; 14513 } 14514 if (procState > ActivityManager.PROCESS_STATE_BACKUP) { 14515 procState = ActivityManager.PROCESS_STATE_BACKUP; 14516 } 14517 } 14518 14519 boolean mayBeTop = false; 14520 14521 for (int is = app.services.size()-1; 14522 is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 14523 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 14524 || procState > ActivityManager.PROCESS_STATE_TOP); 14525 is--) { 14526 ServiceRecord s = app.services.valueAt(is); 14527 if (s.startRequested) { 14528 app.hasStartedServices = true; 14529 if (procState > ActivityManager.PROCESS_STATE_SERVICE) { 14530 procState = ActivityManager.PROCESS_STATE_SERVICE; 14531 } 14532 if (app.hasShownUi && app != mHomeProcess) { 14533 // If this process has shown some UI, let it immediately 14534 // go to the LRU list because it may be pretty heavy with 14535 // UI stuff. We'll tag it with a label just to help 14536 // debug and understand what is going on. 14537 if (adj > ProcessList.SERVICE_ADJ) { 14538 app.adjType = "cch-started-ui-services"; 14539 } 14540 } else { 14541 if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) { 14542 // This service has seen some activity within 14543 // recent memory, so we will keep its process ahead 14544 // of the background processes. 14545 if (adj > ProcessList.SERVICE_ADJ) { 14546 adj = ProcessList.SERVICE_ADJ; 14547 app.adjType = "started-services"; 14548 app.cached = false; 14549 } 14550 } 14551 // If we have let the service slide into the background 14552 // state, still have some text describing what it is doing 14553 // even though the service no longer has an impact. 14554 if (adj > ProcessList.SERVICE_ADJ) { 14555 app.adjType = "cch-started-services"; 14556 } 14557 } 14558 // Don't kill this process because it is doing work; it 14559 // has said it is doing work. 14560 app.keeping = true; 14561 } 14562 for (int conni = s.connections.size()-1; 14563 conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 14564 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 14565 || procState > ActivityManager.PROCESS_STATE_TOP); 14566 conni--) { 14567 ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni); 14568 for (int i = 0; 14569 i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ 14570 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 14571 || procState > ActivityManager.PROCESS_STATE_TOP); 14572 i++) { 14573 // XXX should compute this based on the max of 14574 // all connected clients. 14575 ConnectionRecord cr = clist.get(i); 14576 if (cr.binding.client == app) { 14577 // Binding to ourself is not interesting. 14578 continue; 14579 } 14580 if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) { 14581 ProcessRecord client = cr.binding.client; 14582 int clientAdj = computeOomAdjLocked(client, cachedAdj, 14583 TOP_APP, doingAll, now); 14584 int clientProcState = client.curProcState; 14585 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 14586 // If the other app is cached for any reason, for purposes here 14587 // we are going to consider it empty. The specific cached state 14588 // doesn't propagate except under certain conditions. 14589 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 14590 } 14591 String adjType = null; 14592 if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) { 14593 // Not doing bind OOM management, so treat 14594 // this guy more like a started service. 14595 if (app.hasShownUi && app != mHomeProcess) { 14596 // If this process has shown some UI, let it immediately 14597 // go to the LRU list because it may be pretty heavy with 14598 // UI stuff. We'll tag it with a label just to help 14599 // debug and understand what is going on. 14600 if (adj > clientAdj) { 14601 adjType = "cch-bound-ui-services"; 14602 } 14603 app.cached = false; 14604 clientAdj = adj; 14605 clientProcState = procState; 14606 } else { 14607 if (now >= (s.lastActivity 14608 + ActiveServices.MAX_SERVICE_INACTIVITY)) { 14609 // This service has not seen activity within 14610 // recent memory, so allow it to drop to the 14611 // LRU list if there is no other reason to keep 14612 // it around. We'll also tag it with a label just 14613 // to help debug and undertand what is going on. 14614 if (adj > clientAdj) { 14615 adjType = "cch-bound-services"; 14616 } 14617 clientAdj = adj; 14618 } 14619 } 14620 } 14621 if (adj > clientAdj) { 14622 // If this process has recently shown UI, and 14623 // the process that is binding to it is less 14624 // important than being visible, then we don't 14625 // care about the binding as much as we care 14626 // about letting this process get into the LRU 14627 // list to be killed and restarted if needed for 14628 // memory. 14629 if (app.hasShownUi && app != mHomeProcess 14630 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14631 adjType = "cch-bound-ui-services"; 14632 } else { 14633 if ((cr.flags&(Context.BIND_ABOVE_CLIENT 14634 |Context.BIND_IMPORTANT)) != 0) { 14635 adj = clientAdj; 14636 } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0 14637 && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ 14638 && adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14639 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 14640 } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) { 14641 adj = clientAdj; 14642 } else { 14643 if (adj > ProcessList.VISIBLE_APP_ADJ) { 14644 adj = ProcessList.VISIBLE_APP_ADJ; 14645 } 14646 } 14647 if (!client.cached) { 14648 app.cached = false; 14649 } 14650 if (client.keeping) { 14651 app.keeping = true; 14652 } 14653 adjType = "service"; 14654 } 14655 } 14656 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 14657 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 14658 schedGroup = Process.THREAD_GROUP_DEFAULT; 14659 } 14660 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) { 14661 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) { 14662 // Special handling of clients who are in the top state. 14663 // We *may* want to consider this process to be in the 14664 // top state as well, but only if there is not another 14665 // reason for it to be running. Being on the top is a 14666 // special state, meaning you are specifically running 14667 // for the current top app. If the process is already 14668 // running in the background for some other reason, it 14669 // is more important to continue considering it to be 14670 // in the background state. 14671 mayBeTop = true; 14672 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 14673 } else { 14674 // Special handling for above-top states (persistent 14675 // processes). These should not bring the current process 14676 // into the top state, since they are not on top. Instead 14677 // give them the best state after that. 14678 clientProcState = 14679 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14680 } 14681 } 14682 } else { 14683 if (clientProcState < 14684 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) { 14685 clientProcState = 14686 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND; 14687 } 14688 } 14689 if (procState > clientProcState) { 14690 procState = clientProcState; 14691 } 14692 if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 14693 && (cr.flags&Context.BIND_SHOWING_UI) != 0) { 14694 app.pendingUiClean = true; 14695 } 14696 if (adjType != null) { 14697 app.adjType = adjType; 14698 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 14699 .REASON_SERVICE_IN_USE; 14700 app.adjSource = cr.binding.client; 14701 app.adjSourceOom = clientAdj; 14702 app.adjTarget = s.name; 14703 } 14704 } 14705 final ActivityRecord a = cr.activity; 14706 if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) { 14707 if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ && 14708 (a.visible || a.state == ActivityState.RESUMED 14709 || a.state == ActivityState.PAUSING)) { 14710 adj = ProcessList.FOREGROUND_APP_ADJ; 14711 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 14712 schedGroup = Process.THREAD_GROUP_DEFAULT; 14713 } 14714 app.cached = false; 14715 app.adjType = "service"; 14716 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 14717 .REASON_SERVICE_IN_USE; 14718 app.adjSource = a; 14719 app.adjSourceOom = adj; 14720 app.adjTarget = s.name; 14721 } 14722 } 14723 } 14724 } 14725 } 14726 14727 for (int provi = app.pubProviders.size()-1; 14728 provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 14729 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 14730 || procState > ActivityManager.PROCESS_STATE_TOP); 14731 provi--) { 14732 ContentProviderRecord cpr = app.pubProviders.valueAt(provi); 14733 for (int i = cpr.connections.size()-1; 14734 i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 14735 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 14736 || procState > ActivityManager.PROCESS_STATE_TOP); 14737 i--) { 14738 ContentProviderConnection conn = cpr.connections.get(i); 14739 ProcessRecord client = conn.client; 14740 if (client == app) { 14741 // Being our own client is not interesting. 14742 continue; 14743 } 14744 int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now); 14745 int clientProcState = client.curProcState; 14746 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 14747 // If the other app is cached for any reason, for purposes here 14748 // we are going to consider it empty. 14749 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 14750 } 14751 if (adj > clientAdj) { 14752 if (app.hasShownUi && app != mHomeProcess 14753 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14754 app.adjType = "cch-ui-provider"; 14755 } else { 14756 adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ 14757 ? clientAdj : ProcessList.FOREGROUND_APP_ADJ; 14758 app.adjType = "provider"; 14759 } 14760 app.cached &= client.cached; 14761 app.keeping |= client.keeping; 14762 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 14763 .REASON_PROVIDER_IN_USE; 14764 app.adjSource = client; 14765 app.adjSourceOom = clientAdj; 14766 app.adjTarget = cpr.name; 14767 } 14768 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) { 14769 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) { 14770 // Special handling of clients who are in the top state. 14771 // We *may* want to consider this process to be in the 14772 // top state as well, but only if there is not another 14773 // reason for it to be running. Being on the top is a 14774 // special state, meaning you are specifically running 14775 // for the current top app. If the process is already 14776 // running in the background for some other reason, it 14777 // is more important to continue considering it to be 14778 // in the background state. 14779 mayBeTop = true; 14780 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 14781 } else { 14782 // Special handling for above-top states (persistent 14783 // processes). These should not bring the current process 14784 // into the top state, since they are not on top. Instead 14785 // give them the best state after that. 14786 clientProcState = 14787 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14788 } 14789 } 14790 if (procState > clientProcState) { 14791 procState = clientProcState; 14792 } 14793 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 14794 schedGroup = Process.THREAD_GROUP_DEFAULT; 14795 } 14796 } 14797 // If the provider has external (non-framework) process 14798 // dependencies, ensure that its adjustment is at least 14799 // FOREGROUND_APP_ADJ. 14800 if (cpr.hasExternalProcessHandles()) { 14801 if (adj > ProcessList.FOREGROUND_APP_ADJ) { 14802 adj = ProcessList.FOREGROUND_APP_ADJ; 14803 schedGroup = Process.THREAD_GROUP_DEFAULT; 14804 app.cached = false; 14805 app.keeping = true; 14806 app.adjType = "provider"; 14807 app.adjTarget = cpr.name; 14808 } 14809 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) { 14810 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14811 } 14812 } 14813 } 14814 14815 if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) { 14816 // A client of one of our services or providers is in the top state. We 14817 // *may* want to be in the top state, but not if we are already running in 14818 // the background for some other reason. For the decision here, we are going 14819 // to pick out a few specific states that we want to remain in when a client 14820 // is top (states that tend to be longer-term) and otherwise allow it to go 14821 // to the top state. 14822 switch (procState) { 14823 case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND: 14824 case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND: 14825 case ActivityManager.PROCESS_STATE_SERVICE: 14826 // These all are longer-term states, so pull them up to the top 14827 // of the background states, but not all the way to the top state. 14828 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14829 break; 14830 default: 14831 // Otherwise, top is a better choice, so take it. 14832 procState = ActivityManager.PROCESS_STATE_TOP; 14833 break; 14834 } 14835 } 14836 14837 if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY && app.hasClientActivities) { 14838 // This is a cached process, but with client activities. Mark it so. 14839 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT; 14840 app.adjType = "cch-client-act"; 14841 } 14842 14843 if (adj == ProcessList.SERVICE_ADJ) { 14844 if (doingAll) { 14845 app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3); 14846 mNewNumServiceProcs++; 14847 //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb); 14848 if (!app.serviceb) { 14849 // This service isn't far enough down on the LRU list to 14850 // normally be a B service, but if we are low on RAM and it 14851 // is large we want to force it down since we would prefer to 14852 // keep launcher over it. 14853 if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL 14854 && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) { 14855 app.serviceHighRam = true; 14856 app.serviceb = true; 14857 //Slog.i(TAG, "ADJ " + app + " high ram!"); 14858 } else { 14859 mNewNumAServiceProcs++; 14860 //Slog.i(TAG, "ADJ " + app + " not high ram!"); 14861 } 14862 } else { 14863 app.serviceHighRam = false; 14864 } 14865 } 14866 if (app.serviceb) { 14867 adj = ProcessList.SERVICE_B_ADJ; 14868 } 14869 } 14870 14871 app.curRawAdj = adj; 14872 14873 //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid + 14874 // " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj); 14875 if (adj > app.maxAdj) { 14876 adj = app.maxAdj; 14877 if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 14878 schedGroup = Process.THREAD_GROUP_DEFAULT; 14879 } 14880 } 14881 if (adj < ProcessList.CACHED_APP_MIN_ADJ) { 14882 app.keeping = true; 14883 } 14884 14885 // Do final modification to adj. Everything we do between here and applying 14886 // the final setAdj must be done in this function, because we will also use 14887 // it when computing the final cached adj later. Note that we don't need to 14888 // worry about this for max adj above, since max adj will always be used to 14889 // keep it out of the cached vaues. 14890 adj = app.modifyRawOomAdj(adj); 14891 14892 app.curProcState = procState; 14893 14894 int importance = app.memImportance; 14895 if (importance == 0 || adj != app.curAdj || schedGroup != app.curSchedGroup) { 14896 app.curAdj = adj; 14897 app.curSchedGroup = schedGroup; 14898 if (!interesting) { 14899 // For this reporting, if there is not something explicitly 14900 // interesting in this process then we will push it to the 14901 // background importance. 14902 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 14903 } else if (adj >= ProcessList.CACHED_APP_MIN_ADJ) { 14904 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 14905 } else if (adj >= ProcessList.SERVICE_B_ADJ) { 14906 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 14907 } else if (adj >= ProcessList.HOME_APP_ADJ) { 14908 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 14909 } else if (adj >= ProcessList.SERVICE_ADJ) { 14910 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 14911 } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 14912 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE; 14913 } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) { 14914 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE; 14915 } else if (adj >= ProcessList.VISIBLE_APP_ADJ) { 14916 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE; 14917 } else if (adj >= ProcessList.FOREGROUND_APP_ADJ) { 14918 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND; 14919 } else { 14920 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERSISTENT; 14921 } 14922 } 14923 14924 int changes = importance != app.memImportance ? ProcessChangeItem.CHANGE_IMPORTANCE : 0; 14925 if (foregroundActivities != app.foregroundActivities) { 14926 changes |= ProcessChangeItem.CHANGE_ACTIVITIES; 14927 } 14928 if (changes != 0) { 14929 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes); 14930 app.memImportance = importance; 14931 app.foregroundActivities = foregroundActivities; 14932 int i = mPendingProcessChanges.size()-1; 14933 ProcessChangeItem item = null; 14934 while (i >= 0) { 14935 item = mPendingProcessChanges.get(i); 14936 if (item.pid == app.pid) { 14937 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item); 14938 break; 14939 } 14940 i--; 14941 } 14942 if (i < 0) { 14943 // No existing item in pending changes; need a new one. 14944 final int NA = mAvailProcessChanges.size(); 14945 if (NA > 0) { 14946 item = mAvailProcessChanges.remove(NA-1); 14947 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item); 14948 } else { 14949 item = new ProcessChangeItem(); 14950 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item); 14951 } 14952 item.changes = 0; 14953 item.pid = app.pid; 14954 item.uid = app.info.uid; 14955 if (mPendingProcessChanges.size() == 0) { 14956 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, 14957 "*** Enqueueing dispatch processes changed!"); 14958 mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget(); 14959 } 14960 mPendingProcessChanges.add(item); 14961 } 14962 item.changes |= changes; 14963 item.importance = importance; 14964 item.foregroundActivities = foregroundActivities; 14965 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item " 14966 + Integer.toHexString(System.identityHashCode(item)) 14967 + " " + app.toShortString() + ": changes=" + item.changes 14968 + " importance=" + item.importance 14969 + " foreground=" + item.foregroundActivities 14970 + " type=" + app.adjType + " source=" + app.adjSource 14971 + " target=" + app.adjTarget); 14972 } 14973 14974 return app.curRawAdj; 14975 } 14976 14977 /** 14978 * Schedule PSS collection of a process. 14979 */ 14980 void requestPssLocked(ProcessRecord proc, int procState) { 14981 if (mPendingPssProcesses.contains(proc)) { 14982 return; 14983 } 14984 if (mPendingPssProcesses.size() == 0) { 14985 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG); 14986 } 14987 if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc); 14988 proc.pssProcState = procState; 14989 mPendingPssProcesses.add(proc); 14990 } 14991 14992 /** 14993 * Schedule PSS collection of all processes. 14994 */ 14995 void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) { 14996 if (!always) { 14997 if (now < (mLastFullPssTime + 14998 (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) { 14999 return; 15000 } 15001 } 15002 if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs! memLowered=" + memLowered); 15003 mLastFullPssTime = now; 15004 mPendingPssProcesses.ensureCapacity(mLruProcesses.size()); 15005 mPendingPssProcesses.clear(); 15006 for (int i=mLruProcesses.size()-1; i>=0; i--) { 15007 ProcessRecord app = mLruProcesses.get(i); 15008 if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) { 15009 app.pssProcState = app.setProcState; 15010 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true, 15011 mSleeping, now); 15012 mPendingPssProcesses.add(app); 15013 } 15014 } 15015 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG); 15016 } 15017 15018 /** 15019 * Ask a given process to GC right now. 15020 */ 15021 final void performAppGcLocked(ProcessRecord app) { 15022 try { 15023 app.lastRequestedGc = SystemClock.uptimeMillis(); 15024 if (app.thread != null) { 15025 if (app.reportLowMemory) { 15026 app.reportLowMemory = false; 15027 app.thread.scheduleLowMemory(); 15028 } else { 15029 app.thread.processInBackground(); 15030 } 15031 } 15032 } catch (Exception e) { 15033 // whatever. 15034 } 15035 } 15036 15037 /** 15038 * Returns true if things are idle enough to perform GCs. 15039 */ 15040 private final boolean canGcNowLocked() { 15041 boolean processingBroadcasts = false; 15042 for (BroadcastQueue q : mBroadcastQueues) { 15043 if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) { 15044 processingBroadcasts = true; 15045 } 15046 } 15047 return !processingBroadcasts 15048 && (mSleeping || mStackSupervisor.allResumedActivitiesIdle()); 15049 } 15050 15051 /** 15052 * Perform GCs on all processes that are waiting for it, but only 15053 * if things are idle. 15054 */ 15055 final void performAppGcsLocked() { 15056 final int N = mProcessesToGc.size(); 15057 if (N <= 0) { 15058 return; 15059 } 15060 if (canGcNowLocked()) { 15061 while (mProcessesToGc.size() > 0) { 15062 ProcessRecord proc = mProcessesToGc.remove(0); 15063 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) { 15064 if ((proc.lastRequestedGc+GC_MIN_INTERVAL) 15065 <= SystemClock.uptimeMillis()) { 15066 // To avoid spamming the system, we will GC processes one 15067 // at a time, waiting a few seconds between each. 15068 performAppGcLocked(proc); 15069 scheduleAppGcsLocked(); 15070 return; 15071 } else { 15072 // It hasn't been long enough since we last GCed this 15073 // process... put it in the list to wait for its time. 15074 addProcessToGcListLocked(proc); 15075 break; 15076 } 15077 } 15078 } 15079 15080 scheduleAppGcsLocked(); 15081 } 15082 } 15083 15084 /** 15085 * If all looks good, perform GCs on all processes waiting for them. 15086 */ 15087 final void performAppGcsIfAppropriateLocked() { 15088 if (canGcNowLocked()) { 15089 performAppGcsLocked(); 15090 return; 15091 } 15092 // Still not idle, wait some more. 15093 scheduleAppGcsLocked(); 15094 } 15095 15096 /** 15097 * Schedule the execution of all pending app GCs. 15098 */ 15099 final void scheduleAppGcsLocked() { 15100 mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG); 15101 15102 if (mProcessesToGc.size() > 0) { 15103 // Schedule a GC for the time to the next process. 15104 ProcessRecord proc = mProcessesToGc.get(0); 15105 Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG); 15106 15107 long when = proc.lastRequestedGc + GC_MIN_INTERVAL; 15108 long now = SystemClock.uptimeMillis(); 15109 if (when < (now+GC_TIMEOUT)) { 15110 when = now + GC_TIMEOUT; 15111 } 15112 mHandler.sendMessageAtTime(msg, when); 15113 } 15114 } 15115 15116 /** 15117 * Add a process to the array of processes waiting to be GCed. Keeps the 15118 * list in sorted order by the last GC time. The process can't already be 15119 * on the list. 15120 */ 15121 final void addProcessToGcListLocked(ProcessRecord proc) { 15122 boolean added = false; 15123 for (int i=mProcessesToGc.size()-1; i>=0; i--) { 15124 if (mProcessesToGc.get(i).lastRequestedGc < 15125 proc.lastRequestedGc) { 15126 added = true; 15127 mProcessesToGc.add(i+1, proc); 15128 break; 15129 } 15130 } 15131 if (!added) { 15132 mProcessesToGc.add(0, proc); 15133 } 15134 } 15135 15136 /** 15137 * Set up to ask a process to GC itself. This will either do it 15138 * immediately, or put it on the list of processes to gc the next 15139 * time things are idle. 15140 */ 15141 final void scheduleAppGcLocked(ProcessRecord app) { 15142 long now = SystemClock.uptimeMillis(); 15143 if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) { 15144 return; 15145 } 15146 if (!mProcessesToGc.contains(app)) { 15147 addProcessToGcListLocked(app); 15148 scheduleAppGcsLocked(); 15149 } 15150 } 15151 15152 final void checkExcessivePowerUsageLocked(boolean doKills) { 15153 updateCpuStatsNow(); 15154 15155 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 15156 boolean doWakeKills = doKills; 15157 boolean doCpuKills = doKills; 15158 if (mLastPowerCheckRealtime == 0) { 15159 doWakeKills = false; 15160 } 15161 if (mLastPowerCheckUptime == 0) { 15162 doCpuKills = false; 15163 } 15164 if (stats.isScreenOn()) { 15165 doWakeKills = false; 15166 } 15167 final long curRealtime = SystemClock.elapsedRealtime(); 15168 final long realtimeSince = curRealtime - mLastPowerCheckRealtime; 15169 final long curUptime = SystemClock.uptimeMillis(); 15170 final long uptimeSince = curUptime - mLastPowerCheckUptime; 15171 mLastPowerCheckRealtime = curRealtime; 15172 mLastPowerCheckUptime = curUptime; 15173 if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) { 15174 doWakeKills = false; 15175 } 15176 if (uptimeSince < CPU_MIN_CHECK_DURATION) { 15177 doCpuKills = false; 15178 } 15179 int i = mLruProcesses.size(); 15180 while (i > 0) { 15181 i--; 15182 ProcessRecord app = mLruProcesses.get(i); 15183 if (!app.keeping) { 15184 long wtime; 15185 synchronized (stats) { 15186 wtime = stats.getProcessWakeTime(app.info.uid, 15187 app.pid, curRealtime); 15188 } 15189 long wtimeUsed = wtime - app.lastWakeTime; 15190 long cputimeUsed = app.curCpuTime - app.lastCpuTime; 15191 if (DEBUG_POWER) { 15192 StringBuilder sb = new StringBuilder(128); 15193 sb.append("Wake for "); 15194 app.toShortString(sb); 15195 sb.append(": over "); 15196 TimeUtils.formatDuration(realtimeSince, sb); 15197 sb.append(" used "); 15198 TimeUtils.formatDuration(wtimeUsed, sb); 15199 sb.append(" ("); 15200 sb.append((wtimeUsed*100)/realtimeSince); 15201 sb.append("%)"); 15202 Slog.i(TAG, sb.toString()); 15203 sb.setLength(0); 15204 sb.append("CPU for "); 15205 app.toShortString(sb); 15206 sb.append(": over "); 15207 TimeUtils.formatDuration(uptimeSince, sb); 15208 sb.append(" used "); 15209 TimeUtils.formatDuration(cputimeUsed, sb); 15210 sb.append(" ("); 15211 sb.append((cputimeUsed*100)/uptimeSince); 15212 sb.append("%)"); 15213 Slog.i(TAG, sb.toString()); 15214 } 15215 // If a process has held a wake lock for more 15216 // than 50% of the time during this period, 15217 // that sounds bad. Kill! 15218 if (doWakeKills && realtimeSince > 0 15219 && ((wtimeUsed*100)/realtimeSince) >= 50) { 15220 synchronized (stats) { 15221 stats.reportExcessiveWakeLocked(app.info.uid, app.processName, 15222 realtimeSince, wtimeUsed); 15223 } 15224 killUnneededProcessLocked(app, "excessive wake held " + wtimeUsed 15225 + " during " + realtimeSince); 15226 app.baseProcessTracker.reportExcessiveWake(app.pkgList); 15227 } else if (doCpuKills && uptimeSince > 0 15228 && ((cputimeUsed*100)/uptimeSince) >= 50) { 15229 synchronized (stats) { 15230 stats.reportExcessiveCpuLocked(app.info.uid, app.processName, 15231 uptimeSince, cputimeUsed); 15232 } 15233 killUnneededProcessLocked(app, "excessive cpu " + cputimeUsed 15234 + " during " + uptimeSince); 15235 app.baseProcessTracker.reportExcessiveCpu(app.pkgList); 15236 } else { 15237 app.lastWakeTime = wtime; 15238 app.lastCpuTime = app.curCpuTime; 15239 } 15240 } 15241 } 15242 } 15243 15244 private final boolean applyOomAdjLocked(ProcessRecord app, boolean wasKeeping, 15245 ProcessRecord TOP_APP, boolean doingAll, boolean reportingProcessState, long now) { 15246 boolean success = true; 15247 15248 if (app.curRawAdj != app.setRawAdj) { 15249 if (wasKeeping && !app.keeping) { 15250 // This app is no longer something we want to keep. Note 15251 // its current wake lock time to later know to kill it if 15252 // it is not behaving well. 15253 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 15254 synchronized (stats) { 15255 app.lastWakeTime = stats.getProcessWakeTime(app.info.uid, 15256 app.pid, SystemClock.elapsedRealtime()); 15257 } 15258 app.lastCpuTime = app.curCpuTime; 15259 } 15260 15261 app.setRawAdj = app.curRawAdj; 15262 } 15263 15264 if (app.curAdj != app.setAdj) { 15265 ProcessList.setOomAdj(app.pid, app.curAdj); 15266 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v( 15267 TAG, "Set " + app.pid + " " + app.processName + 15268 " adj " + app.curAdj + ": " + app.adjType); 15269 app.setAdj = app.curAdj; 15270 } 15271 15272 if (app.setSchedGroup != app.curSchedGroup) { 15273 app.setSchedGroup = app.curSchedGroup; 15274 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 15275 "Setting process group of " + app.processName 15276 + " to " + app.curSchedGroup); 15277 if (app.waitingToKill != null && 15278 app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 15279 killUnneededProcessLocked(app, app.waitingToKill); 15280 success = false; 15281 } else { 15282 if (true) { 15283 long oldId = Binder.clearCallingIdentity(); 15284 try { 15285 Process.setProcessGroup(app.pid, app.curSchedGroup); 15286 } catch (Exception e) { 15287 Slog.w(TAG, "Failed setting process group of " + app.pid 15288 + " to " + app.curSchedGroup); 15289 e.printStackTrace(); 15290 } finally { 15291 Binder.restoreCallingIdentity(oldId); 15292 } 15293 } else { 15294 if (app.thread != null) { 15295 try { 15296 app.thread.setSchedulingGroup(app.curSchedGroup); 15297 } catch (RemoteException e) { 15298 } 15299 } 15300 } 15301 Process.setSwappiness(app.pid, 15302 app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE); 15303 } 15304 } 15305 if (app.repProcState != app.curProcState) { 15306 app.repProcState = app.curProcState; 15307 if (!reportingProcessState && app.thread != null) { 15308 try { 15309 if (false) { 15310 //RuntimeException h = new RuntimeException("here"); 15311 Slog.i(TAG, "Sending new process state " + app.repProcState 15312 + " to " + app /*, h*/); 15313 } 15314 app.thread.setProcessState(app.repProcState); 15315 } catch (RemoteException e) { 15316 } 15317 } 15318 } 15319 if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState, 15320 app.setProcState)) { 15321 app.lastStateTime = now; 15322 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true, 15323 mSleeping, now); 15324 if (DEBUG_PSS) Slog.d(TAG, "Process state change from " 15325 + ProcessList.makeProcStateString(app.setProcState) + " to " 15326 + ProcessList.makeProcStateString(app.curProcState) + " next pss in " 15327 + (app.nextPssTime-now) + ": " + app); 15328 } else { 15329 if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL) 15330 && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) { 15331 requestPssLocked(app, app.setProcState); 15332 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false, 15333 mSleeping, now); 15334 } else if (false && DEBUG_PSS) { 15335 Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now)); 15336 } 15337 } 15338 if (app.setProcState != app.curProcState) { 15339 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 15340 "Proc state change of " + app.processName 15341 + " to " + app.curProcState); 15342 app.setProcState = app.curProcState; 15343 if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) { 15344 app.notCachedSinceIdle = false; 15345 } 15346 if (!doingAll) { 15347 setProcessTrackerState(app, mProcessStats.getMemFactorLocked(), now); 15348 } else { 15349 app.procStateChanged = true; 15350 } 15351 } 15352 return success; 15353 } 15354 15355 private final void setProcessTrackerState(ProcessRecord proc, int memFactor, long now) { 15356 if (proc.thread != null && proc.baseProcessTracker != null) { 15357 proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList); 15358 } 15359 } 15360 15361 private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj, 15362 ProcessRecord TOP_APP, boolean doingAll, boolean reportingProcessState, long now) { 15363 if (app.thread == null) { 15364 return false; 15365 } 15366 15367 final boolean wasKeeping = app.keeping; 15368 15369 computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now); 15370 15371 return applyOomAdjLocked(app, wasKeeping, TOP_APP, doingAll, 15372 reportingProcessState, now); 15373 } 15374 15375 final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground, 15376 boolean oomAdj) { 15377 if (isForeground != proc.foregroundServices) { 15378 proc.foregroundServices = isForeground; 15379 ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName, 15380 proc.info.uid); 15381 if (isForeground) { 15382 if (curProcs == null) { 15383 curProcs = new ArrayList<ProcessRecord>(); 15384 mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs); 15385 } 15386 if (!curProcs.contains(proc)) { 15387 curProcs.add(proc); 15388 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START, 15389 proc.info.packageName, proc.info.uid); 15390 } 15391 } else { 15392 if (curProcs != null) { 15393 if (curProcs.remove(proc)) { 15394 mBatteryStatsService.noteEvent( 15395 BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH, 15396 proc.info.packageName, proc.info.uid); 15397 if (curProcs.size() <= 0) { 15398 mForegroundPackages.remove(proc.info.packageName, proc.info.uid); 15399 } 15400 } 15401 } 15402 } 15403 if (oomAdj) { 15404 updateOomAdjLocked(); 15405 } 15406 } 15407 } 15408 15409 private final ActivityRecord resumedAppLocked() { 15410 ActivityRecord act = mStackSupervisor.resumedAppLocked(); 15411 String pkg; 15412 int uid; 15413 if (act != null) { 15414 pkg = act.packageName; 15415 uid = act.info.applicationInfo.uid; 15416 } else { 15417 pkg = null; 15418 uid = -1; 15419 } 15420 // Has the UID or resumed package name changed? 15421 if (uid != mCurResumedUid || (pkg != mCurResumedPackage 15422 && (pkg == null || !pkg.equals(mCurResumedPackage)))) { 15423 if (mCurResumedPackage != null) { 15424 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH, 15425 mCurResumedPackage, mCurResumedUid); 15426 } 15427 mCurResumedPackage = pkg; 15428 mCurResumedUid = uid; 15429 if (mCurResumedPackage != null) { 15430 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START, 15431 mCurResumedPackage, mCurResumedUid); 15432 } 15433 } 15434 return act; 15435 } 15436 15437 final boolean updateOomAdjLocked(ProcessRecord app) { 15438 return updateOomAdjLocked(app, false); 15439 } 15440 15441 final boolean updateOomAdjLocked(ProcessRecord app, boolean doingProcessState) { 15442 final ActivityRecord TOP_ACT = resumedAppLocked(); 15443 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 15444 final boolean wasCached = app.cached; 15445 15446 mAdjSeq++; 15447 15448 // This is the desired cached adjusment we want to tell it to use. 15449 // If our app is currently cached, we know it, and that is it. Otherwise, 15450 // we don't know it yet, and it needs to now be cached we will then 15451 // need to do a complete oom adj. 15452 final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ 15453 ? app.curRawAdj : ProcessList.UNKNOWN_ADJ; 15454 boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false, doingProcessState, 15455 SystemClock.uptimeMillis()); 15456 if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) { 15457 // Changed to/from cached state, so apps after it in the LRU 15458 // list may also be changed. 15459 updateOomAdjLocked(); 15460 } 15461 return success; 15462 } 15463 15464 final void updateOomAdjLocked() { 15465 final ActivityRecord TOP_ACT = resumedAppLocked(); 15466 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 15467 final long now = SystemClock.uptimeMillis(); 15468 final long oldTime = now - ProcessList.MAX_EMPTY_TIME; 15469 final int N = mLruProcesses.size(); 15470 15471 if (false) { 15472 RuntimeException e = new RuntimeException(); 15473 e.fillInStackTrace(); 15474 Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e); 15475 } 15476 15477 mAdjSeq++; 15478 mNewNumServiceProcs = 0; 15479 mNewNumAServiceProcs = 0; 15480 15481 final int emptyProcessLimit; 15482 final int cachedProcessLimit; 15483 if (mProcessLimit <= 0) { 15484 emptyProcessLimit = cachedProcessLimit = 0; 15485 } else if (mProcessLimit == 1) { 15486 emptyProcessLimit = 1; 15487 cachedProcessLimit = 0; 15488 } else { 15489 emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit); 15490 cachedProcessLimit = mProcessLimit - emptyProcessLimit; 15491 } 15492 15493 // Let's determine how many processes we have running vs. 15494 // how many slots we have for background processes; we may want 15495 // to put multiple processes in a slot of there are enough of 15496 // them. 15497 int numSlots = (ProcessList.CACHED_APP_MAX_ADJ 15498 - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2; 15499 int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs; 15500 if (numEmptyProcs > cachedProcessLimit) { 15501 // If there are more empty processes than our limit on cached 15502 // processes, then use the cached process limit for the factor. 15503 // This ensures that the really old empty processes get pushed 15504 // down to the bottom, so if we are running low on memory we will 15505 // have a better chance at keeping around more cached processes 15506 // instead of a gazillion empty processes. 15507 numEmptyProcs = cachedProcessLimit; 15508 } 15509 int emptyFactor = numEmptyProcs/numSlots; 15510 if (emptyFactor < 1) emptyFactor = 1; 15511 int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots; 15512 if (cachedFactor < 1) cachedFactor = 1; 15513 int stepCached = 0; 15514 int stepEmpty = 0; 15515 int numCached = 0; 15516 int numEmpty = 0; 15517 int numTrimming = 0; 15518 15519 mNumNonCachedProcs = 0; 15520 mNumCachedHiddenProcs = 0; 15521 15522 // First update the OOM adjustment for each of the 15523 // application processes based on their current state. 15524 int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ; 15525 int nextCachedAdj = curCachedAdj+1; 15526 int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ; 15527 int nextEmptyAdj = curEmptyAdj+2; 15528 for (int i=N-1; i>=0; i--) { 15529 ProcessRecord app = mLruProcesses.get(i); 15530 if (!app.killedByAm && app.thread != null) { 15531 app.procStateChanged = false; 15532 final boolean wasKeeping = app.keeping; 15533 computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now); 15534 15535 // If we haven't yet assigned the final cached adj 15536 // to the process, do that now. 15537 if (app.curAdj >= ProcessList.UNKNOWN_ADJ) { 15538 switch (app.curProcState) { 15539 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY: 15540 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: 15541 // This process is a cached process holding activities... 15542 // assign it the next cached value for that type, and then 15543 // step that cached level. 15544 app.curRawAdj = curCachedAdj; 15545 app.curAdj = app.modifyRawOomAdj(curCachedAdj); 15546 if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i 15547 + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj 15548 + ")"); 15549 if (curCachedAdj != nextCachedAdj) { 15550 stepCached++; 15551 if (stepCached >= cachedFactor) { 15552 stepCached = 0; 15553 curCachedAdj = nextCachedAdj; 15554 nextCachedAdj += 2; 15555 if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) { 15556 nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ; 15557 } 15558 } 15559 } 15560 break; 15561 default: 15562 // For everything else, assign next empty cached process 15563 // level and bump that up. Note that this means that 15564 // long-running services that have dropped down to the 15565 // cached level will be treated as empty (since their process 15566 // state is still as a service), which is what we want. 15567 app.curRawAdj = curEmptyAdj; 15568 app.curAdj = app.modifyRawOomAdj(curEmptyAdj); 15569 if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i 15570 + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj 15571 + ")"); 15572 if (curEmptyAdj != nextEmptyAdj) { 15573 stepEmpty++; 15574 if (stepEmpty >= emptyFactor) { 15575 stepEmpty = 0; 15576 curEmptyAdj = nextEmptyAdj; 15577 nextEmptyAdj += 2; 15578 if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) { 15579 nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ; 15580 } 15581 } 15582 } 15583 break; 15584 } 15585 } 15586 15587 applyOomAdjLocked(app, wasKeeping, TOP_APP, true, false, now); 15588 15589 // Count the number of process types. 15590 switch (app.curProcState) { 15591 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY: 15592 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: 15593 mNumCachedHiddenProcs++; 15594 numCached++; 15595 if (numCached > cachedProcessLimit) { 15596 killUnneededProcessLocked(app, "cached #" + numCached); 15597 } 15598 break; 15599 case ActivityManager.PROCESS_STATE_CACHED_EMPTY: 15600 if (numEmpty > ProcessList.TRIM_EMPTY_APPS 15601 && app.lastActivityTime < oldTime) { 15602 killUnneededProcessLocked(app, "empty for " 15603 + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime) 15604 / 1000) + "s"); 15605 } else { 15606 numEmpty++; 15607 if (numEmpty > emptyProcessLimit) { 15608 killUnneededProcessLocked(app, "empty #" + numEmpty); 15609 } 15610 } 15611 break; 15612 default: 15613 mNumNonCachedProcs++; 15614 break; 15615 } 15616 15617 if (app.isolated && app.services.size() <= 0) { 15618 // If this is an isolated process, and there are no 15619 // services running in it, then the process is no longer 15620 // needed. We agressively kill these because we can by 15621 // definition not re-use the same process again, and it is 15622 // good to avoid having whatever code was running in them 15623 // left sitting around after no longer needed. 15624 killUnneededProcessLocked(app, "isolated not needed"); 15625 } 15626 15627 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME 15628 && !app.killedByAm) { 15629 numTrimming++; 15630 } 15631 } 15632 } 15633 15634 mNumServiceProcs = mNewNumServiceProcs; 15635 15636 // Now determine the memory trimming level of background processes. 15637 // Unfortunately we need to start at the back of the list to do this 15638 // properly. We only do this if the number of background apps we 15639 // are managing to keep around is less than half the maximum we desire; 15640 // if we are keeping a good number around, we'll let them use whatever 15641 // memory they want. 15642 final int numCachedAndEmpty = numCached + numEmpty; 15643 int memFactor; 15644 if (numCached <= ProcessList.TRIM_CACHED_APPS 15645 && numEmpty <= ProcessList.TRIM_EMPTY_APPS) { 15646 if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) { 15647 memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL; 15648 } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) { 15649 memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW; 15650 } else { 15651 memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE; 15652 } 15653 } else { 15654 memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL; 15655 } 15656 // We always allow the memory level to go up (better). We only allow it to go 15657 // down if we are in a state where that is allowed, *and* the total number of processes 15658 // has gone down since last time. 15659 if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel 15660 + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size() 15661 + " last=" + mLastNumProcesses); 15662 if (memFactor > mLastMemoryLevel) { 15663 if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) { 15664 memFactor = mLastMemoryLevel; 15665 if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!"); 15666 } 15667 } 15668 mLastMemoryLevel = memFactor; 15669 mLastNumProcesses = mLruProcesses.size(); 15670 boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !mSleeping, now); 15671 final int trackerMemFactor = mProcessStats.getMemFactorLocked(); 15672 if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) { 15673 if (mLowRamStartTime == 0) { 15674 mLowRamStartTime = now; 15675 } 15676 int step = 0; 15677 int fgTrimLevel; 15678 switch (memFactor) { 15679 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL: 15680 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL; 15681 break; 15682 case ProcessStats.ADJ_MEM_FACTOR_LOW: 15683 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW; 15684 break; 15685 default: 15686 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE; 15687 break; 15688 } 15689 int factor = numTrimming/3; 15690 int minFactor = 2; 15691 if (mHomeProcess != null) minFactor++; 15692 if (mPreviousProcess != null) minFactor++; 15693 if (factor < minFactor) factor = minFactor; 15694 int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE; 15695 for (int i=N-1; i>=0; i--) { 15696 ProcessRecord app = mLruProcesses.get(i); 15697 if (allChanged || app.procStateChanged) { 15698 setProcessTrackerState(app, trackerMemFactor, now); 15699 app.procStateChanged = false; 15700 } 15701 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME 15702 && !app.killedByAm) { 15703 if (app.trimMemoryLevel < curLevel && app.thread != null) { 15704 try { 15705 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 15706 "Trimming memory of " + app.processName 15707 + " to " + curLevel); 15708 app.thread.scheduleTrimMemory(curLevel); 15709 } catch (RemoteException e) { 15710 } 15711 if (false) { 15712 // For now we won't do this; our memory trimming seems 15713 // to be good enough at this point that destroying 15714 // activities causes more harm than good. 15715 if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE 15716 && app != mHomeProcess && app != mPreviousProcess) { 15717 // Need to do this on its own message because the stack may not 15718 // be in a consistent state at this point. 15719 // For these apps we will also finish their activities 15720 // to help them free memory. 15721 mStackSupervisor.scheduleDestroyAllActivities(app, "trim"); 15722 } 15723 } 15724 } 15725 app.trimMemoryLevel = curLevel; 15726 step++; 15727 if (step >= factor) { 15728 step = 0; 15729 switch (curLevel) { 15730 case ComponentCallbacks2.TRIM_MEMORY_COMPLETE: 15731 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE; 15732 break; 15733 case ComponentCallbacks2.TRIM_MEMORY_MODERATE: 15734 curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 15735 break; 15736 } 15737 } 15738 } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) { 15739 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND 15740 && app.thread != null) { 15741 try { 15742 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 15743 "Trimming memory of heavy-weight " + app.processName 15744 + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 15745 app.thread.scheduleTrimMemory( 15746 ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 15747 } catch (RemoteException e) { 15748 } 15749 } 15750 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 15751 } else { 15752 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 15753 || app.systemNoUi) && app.pendingUiClean) { 15754 // If this application is now in the background and it 15755 // had done UI, then give it the special trim level to 15756 // have it free UI resources. 15757 final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN; 15758 if (app.trimMemoryLevel < level && app.thread != null) { 15759 try { 15760 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 15761 "Trimming memory of bg-ui " + app.processName 15762 + " to " + level); 15763 app.thread.scheduleTrimMemory(level); 15764 } catch (RemoteException e) { 15765 } 15766 } 15767 app.pendingUiClean = false; 15768 } 15769 if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) { 15770 try { 15771 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 15772 "Trimming memory of fg " + app.processName 15773 + " to " + fgTrimLevel); 15774 app.thread.scheduleTrimMemory(fgTrimLevel); 15775 } catch (RemoteException e) { 15776 } 15777 } 15778 app.trimMemoryLevel = fgTrimLevel; 15779 } 15780 } 15781 } else { 15782 if (mLowRamStartTime != 0) { 15783 mLowRamTimeSinceLastIdle += now - mLowRamStartTime; 15784 mLowRamStartTime = 0; 15785 } 15786 for (int i=N-1; i>=0; i--) { 15787 ProcessRecord app = mLruProcesses.get(i); 15788 if (allChanged || app.procStateChanged) { 15789 setProcessTrackerState(app, trackerMemFactor, now); 15790 app.procStateChanged = false; 15791 } 15792 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 15793 || app.systemNoUi) && app.pendingUiClean) { 15794 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN 15795 && app.thread != null) { 15796 try { 15797 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 15798 "Trimming memory of ui hidden " + app.processName 15799 + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 15800 app.thread.scheduleTrimMemory( 15801 ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 15802 } catch (RemoteException e) { 15803 } 15804 } 15805 app.pendingUiClean = false; 15806 } 15807 app.trimMemoryLevel = 0; 15808 } 15809 } 15810 15811 if (mAlwaysFinishActivities) { 15812 // Need to do this on its own message because the stack may not 15813 // be in a consistent state at this point. 15814 mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish"); 15815 } 15816 15817 if (allChanged) { 15818 requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered()); 15819 } 15820 15821 if (mProcessStats.shouldWriteNowLocked(now)) { 15822 mHandler.post(new Runnable() { 15823 @Override public void run() { 15824 synchronized (ActivityManagerService.this) { 15825 mProcessStats.writeStateAsyncLocked(); 15826 } 15827 } 15828 }); 15829 } 15830 15831 if (DEBUG_OOM_ADJ) { 15832 Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms"); 15833 } 15834 } 15835 15836 final void trimApplications() { 15837 synchronized (this) { 15838 int i; 15839 15840 // First remove any unused application processes whose package 15841 // has been removed. 15842 for (i=mRemovedProcesses.size()-1; i>=0; i--) { 15843 final ProcessRecord app = mRemovedProcesses.get(i); 15844 if (app.activities.size() == 0 15845 && app.curReceiver == null && app.services.size() == 0) { 15846 Slog.i( 15847 TAG, "Exiting empty application process " 15848 + app.processName + " (" 15849 + (app.thread != null ? app.thread.asBinder() : null) 15850 + ")\n"); 15851 if (app.pid > 0 && app.pid != MY_PID) { 15852 EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid, 15853 app.processName, app.setAdj, "empty"); 15854 app.killedByAm = true; 15855 Process.killProcessQuiet(app.pid); 15856 } else { 15857 try { 15858 app.thread.scheduleExit(); 15859 } catch (Exception e) { 15860 // Ignore exceptions. 15861 } 15862 } 15863 cleanUpApplicationRecordLocked(app, false, true, -1); 15864 mRemovedProcesses.remove(i); 15865 15866 if (app.persistent) { 15867 if (app.persistent) { 15868 addAppLocked(app.info, false); 15869 } 15870 } 15871 } 15872 } 15873 15874 // Now update the oom adj for all processes. 15875 updateOomAdjLocked(); 15876 } 15877 } 15878 15879 /** This method sends the specified signal to each of the persistent apps */ 15880 public void signalPersistentProcesses(int sig) throws RemoteException { 15881 if (sig != Process.SIGNAL_USR1) { 15882 throw new SecurityException("Only SIGNAL_USR1 is allowed"); 15883 } 15884 15885 synchronized (this) { 15886 if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES) 15887 != PackageManager.PERMISSION_GRANTED) { 15888 throw new SecurityException("Requires permission " 15889 + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES); 15890 } 15891 15892 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 15893 ProcessRecord r = mLruProcesses.get(i); 15894 if (r.thread != null && r.persistent) { 15895 Process.sendSignal(r.pid, sig); 15896 } 15897 } 15898 } 15899 } 15900 15901 private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) { 15902 if (proc == null || proc == mProfileProc) { 15903 proc = mProfileProc; 15904 path = mProfileFile; 15905 profileType = mProfileType; 15906 clearProfilerLocked(); 15907 } 15908 if (proc == null) { 15909 return; 15910 } 15911 try { 15912 proc.thread.profilerControl(false, path, null, profileType); 15913 } catch (RemoteException e) { 15914 throw new IllegalStateException("Process disappeared"); 15915 } 15916 } 15917 15918 private void clearProfilerLocked() { 15919 if (mProfileFd != null) { 15920 try { 15921 mProfileFd.close(); 15922 } catch (IOException e) { 15923 } 15924 } 15925 mProfileApp = null; 15926 mProfileProc = null; 15927 mProfileFile = null; 15928 mProfileType = 0; 15929 mAutoStopProfiler = false; 15930 } 15931 15932 public boolean profileControl(String process, int userId, boolean start, 15933 String path, ParcelFileDescriptor fd, int profileType) throws RemoteException { 15934 15935 try { 15936 synchronized (this) { 15937 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 15938 // its own permission. 15939 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 15940 != PackageManager.PERMISSION_GRANTED) { 15941 throw new SecurityException("Requires permission " 15942 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 15943 } 15944 15945 if (start && fd == null) { 15946 throw new IllegalArgumentException("null fd"); 15947 } 15948 15949 ProcessRecord proc = null; 15950 if (process != null) { 15951 proc = findProcessLocked(process, userId, "profileControl"); 15952 } 15953 15954 if (start && (proc == null || proc.thread == null)) { 15955 throw new IllegalArgumentException("Unknown process: " + process); 15956 } 15957 15958 if (start) { 15959 stopProfilerLocked(null, null, 0); 15960 setProfileApp(proc.info, proc.processName, path, fd, false); 15961 mProfileProc = proc; 15962 mProfileType = profileType; 15963 try { 15964 fd = fd.dup(); 15965 } catch (IOException e) { 15966 fd = null; 15967 } 15968 proc.thread.profilerControl(start, path, fd, profileType); 15969 fd = null; 15970 mProfileFd = null; 15971 } else { 15972 stopProfilerLocked(proc, path, profileType); 15973 if (fd != null) { 15974 try { 15975 fd.close(); 15976 } catch (IOException e) { 15977 } 15978 } 15979 } 15980 15981 return true; 15982 } 15983 } catch (RemoteException e) { 15984 throw new IllegalStateException("Process disappeared"); 15985 } finally { 15986 if (fd != null) { 15987 try { 15988 fd.close(); 15989 } catch (IOException e) { 15990 } 15991 } 15992 } 15993 } 15994 15995 private ProcessRecord findProcessLocked(String process, int userId, String callName) { 15996 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 15997 userId, true, true, callName, null); 15998 ProcessRecord proc = null; 15999 try { 16000 int pid = Integer.parseInt(process); 16001 synchronized (mPidsSelfLocked) { 16002 proc = mPidsSelfLocked.get(pid); 16003 } 16004 } catch (NumberFormatException e) { 16005 } 16006 16007 if (proc == null) { 16008 ArrayMap<String, SparseArray<ProcessRecord>> all 16009 = mProcessNames.getMap(); 16010 SparseArray<ProcessRecord> procs = all.get(process); 16011 if (procs != null && procs.size() > 0) { 16012 proc = procs.valueAt(0); 16013 if (userId != UserHandle.USER_ALL && proc.userId != userId) { 16014 for (int i=1; i<procs.size(); i++) { 16015 ProcessRecord thisProc = procs.valueAt(i); 16016 if (thisProc.userId == userId) { 16017 proc = thisProc; 16018 break; 16019 } 16020 } 16021 } 16022 } 16023 } 16024 16025 return proc; 16026 } 16027 16028 public boolean dumpHeap(String process, int userId, boolean managed, 16029 String path, ParcelFileDescriptor fd) throws RemoteException { 16030 16031 try { 16032 synchronized (this) { 16033 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 16034 // its own permission (same as profileControl). 16035 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 16036 != PackageManager.PERMISSION_GRANTED) { 16037 throw new SecurityException("Requires permission " 16038 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 16039 } 16040 16041 if (fd == null) { 16042 throw new IllegalArgumentException("null fd"); 16043 } 16044 16045 ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap"); 16046 if (proc == null || proc.thread == null) { 16047 throw new IllegalArgumentException("Unknown process: " + process); 16048 } 16049 16050 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 16051 if (!isDebuggable) { 16052 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 16053 throw new SecurityException("Process not debuggable: " + proc); 16054 } 16055 } 16056 16057 proc.thread.dumpHeap(managed, path, fd); 16058 fd = null; 16059 return true; 16060 } 16061 } catch (RemoteException e) { 16062 throw new IllegalStateException("Process disappeared"); 16063 } finally { 16064 if (fd != null) { 16065 try { 16066 fd.close(); 16067 } catch (IOException e) { 16068 } 16069 } 16070 } 16071 } 16072 16073 /** In this method we try to acquire our lock to make sure that we have not deadlocked */ 16074 public void monitor() { 16075 synchronized (this) { } 16076 } 16077 16078 void onCoreSettingsChange(Bundle settings) { 16079 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 16080 ProcessRecord processRecord = mLruProcesses.get(i); 16081 try { 16082 if (processRecord.thread != null) { 16083 processRecord.thread.setCoreSettings(settings); 16084 } 16085 } catch (RemoteException re) { 16086 /* ignore */ 16087 } 16088 } 16089 } 16090 16091 // Multi-user methods 16092 16093 /** 16094 * Start user, if its not already running, but don't bring it to foreground. 16095 */ 16096 @Override 16097 public boolean startUserInBackground(final int userId) { 16098 return startUser(userId, /* foreground */ false); 16099 } 16100 16101 /** 16102 * Refreshes the list of users related to the current user when either a 16103 * user switch happens or when a new related user is started in the 16104 * background. 16105 */ 16106 private void updateRelatedUserIdsLocked() { 16107 final List<UserInfo> relatedUsers = getUserManagerLocked().getRelatedUsers(mCurrentUserId); 16108 int[] relatedUserIds = new int[relatedUsers.size()]; // relatedUsers will not be null 16109 for (int i = 0; i < relatedUserIds.length; i++) { 16110 relatedUserIds[i] = relatedUsers.get(i).id; 16111 } 16112 mRelatedUserIds = relatedUserIds; 16113 } 16114 16115 @Override 16116 public boolean switchUser(final int userId) { 16117 return startUser(userId, /* foregound */ true); 16118 } 16119 16120 private boolean startUser(final int userId, boolean foreground) { 16121 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 16122 != PackageManager.PERMISSION_GRANTED) { 16123 String msg = "Permission Denial: switchUser() from pid=" 16124 + Binder.getCallingPid() 16125 + ", uid=" + Binder.getCallingUid() 16126 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 16127 Slog.w(TAG, msg); 16128 throw new SecurityException(msg); 16129 } 16130 16131 if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground); 16132 16133 final long ident = Binder.clearCallingIdentity(); 16134 try { 16135 synchronized (this) { 16136 final int oldUserId = mCurrentUserId; 16137 if (oldUserId == userId) { 16138 return true; 16139 } 16140 16141 final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId); 16142 if (userInfo == null) { 16143 Slog.w(TAG, "No user info for user #" + userId); 16144 return false; 16145 } 16146 16147 if (foreground) { 16148 mWindowManager.startFreezingScreen(R.anim.screen_user_exit, 16149 R.anim.screen_user_enter); 16150 } 16151 16152 boolean needStart = false; 16153 16154 // If the user we are switching to is not currently started, then 16155 // we need to start it now. 16156 if (mStartedUsers.get(userId) == null) { 16157 mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false)); 16158 updateStartedUserArrayLocked(); 16159 needStart = true; 16160 } 16161 16162 final Integer userIdInt = Integer.valueOf(userId); 16163 mUserLru.remove(userIdInt); 16164 mUserLru.add(userIdInt); 16165 16166 if (foreground) { 16167 mCurrentUserId = userId; 16168 updateRelatedUserIdsLocked(); 16169 mWindowManager.setCurrentUser(userId, mRelatedUserIds); 16170 // Once the internal notion of the active user has switched, we lock the device 16171 // with the option to show the user switcher on the keyguard. 16172 mWindowManager.lockNow(null); 16173 } else { 16174 final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId); 16175 updateRelatedUserIdsLocked(); 16176 mWindowManager.updateRelatedUserIds(mRelatedUserIds); 16177 mUserLru.remove(currentUserIdInt); 16178 mUserLru.add(currentUserIdInt); 16179 } 16180 16181 final UserStartedState uss = mStartedUsers.get(userId); 16182 16183 // Make sure user is in the started state. If it is currently 16184 // stopping, we need to knock that off. 16185 if (uss.mState == UserStartedState.STATE_STOPPING) { 16186 // If we are stopping, we haven't sent ACTION_SHUTDOWN, 16187 // so we can just fairly silently bring the user back from 16188 // the almost-dead. 16189 uss.mState = UserStartedState.STATE_RUNNING; 16190 updateStartedUserArrayLocked(); 16191 needStart = true; 16192 } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) { 16193 // This means ACTION_SHUTDOWN has been sent, so we will 16194 // need to treat this as a new boot of the user. 16195 uss.mState = UserStartedState.STATE_BOOTING; 16196 updateStartedUserArrayLocked(); 16197 needStart = true; 16198 } 16199 16200 if (foreground) { 16201 mHandler.removeMessages(REPORT_USER_SWITCH_MSG); 16202 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 16203 mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG, 16204 oldUserId, userId, uss)); 16205 mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG, 16206 oldUserId, userId, uss), USER_SWITCH_TIMEOUT); 16207 } 16208 16209 if (needStart) { 16210 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 16211 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16212 | Intent.FLAG_RECEIVER_FOREGROUND); 16213 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 16214 broadcastIntentLocked(null, null, intent, 16215 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 16216 false, false, MY_PID, Process.SYSTEM_UID, userId); 16217 } 16218 16219 if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) { 16220 if (userId != 0) { 16221 Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE); 16222 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 16223 broadcastIntentLocked(null, null, intent, null, 16224 new IIntentReceiver.Stub() { 16225 public void performReceive(Intent intent, int resultCode, 16226 String data, Bundle extras, boolean ordered, 16227 boolean sticky, int sendingUser) { 16228 userInitialized(uss, userId); 16229 } 16230 }, 0, null, null, null, AppOpsManager.OP_NONE, 16231 true, false, MY_PID, Process.SYSTEM_UID, 16232 userId); 16233 uss.initializing = true; 16234 } else { 16235 getUserManagerLocked().makeInitialized(userInfo.id); 16236 } 16237 } 16238 16239 if (foreground) { 16240 boolean homeInFront = mStackSupervisor.switchUserLocked(userId, uss); 16241 if (homeInFront) { 16242 startHomeActivityLocked(userId); 16243 } else { 16244 mStackSupervisor.resumeTopActivitiesLocked(); 16245 } 16246 EventLogTags.writeAmSwitchUser(userId); 16247 getUserManagerLocked().userForeground(userId); 16248 sendUserSwitchBroadcastsLocked(oldUserId, userId); 16249 } 16250 16251 if (needStart) { 16252 Intent intent = new Intent(Intent.ACTION_USER_STARTING); 16253 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 16254 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 16255 broadcastIntentLocked(null, null, intent, 16256 null, new IIntentReceiver.Stub() { 16257 @Override 16258 public void performReceive(Intent intent, int resultCode, String data, 16259 Bundle extras, boolean ordered, boolean sticky, int sendingUser) 16260 throws RemoteException { 16261 } 16262 }, 0, null, null, 16263 android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 16264 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 16265 } 16266 } 16267 } finally { 16268 Binder.restoreCallingIdentity(ident); 16269 } 16270 16271 return true; 16272 } 16273 16274 void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) { 16275 long ident = Binder.clearCallingIdentity(); 16276 try { 16277 Intent intent; 16278 if (oldUserId >= 0) { 16279 intent = new Intent(Intent.ACTION_USER_BACKGROUND); 16280 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16281 | Intent.FLAG_RECEIVER_FOREGROUND); 16282 intent.putExtra(Intent.EXTRA_USER_HANDLE, oldUserId); 16283 broadcastIntentLocked(null, null, intent, 16284 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 16285 false, false, MY_PID, Process.SYSTEM_UID, oldUserId); 16286 } 16287 if (newUserId >= 0) { 16288 intent = new Intent(Intent.ACTION_USER_FOREGROUND); 16289 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16290 | Intent.FLAG_RECEIVER_FOREGROUND); 16291 intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId); 16292 broadcastIntentLocked(null, null, intent, 16293 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 16294 false, false, MY_PID, Process.SYSTEM_UID, newUserId); 16295 intent = new Intent(Intent.ACTION_USER_SWITCHED); 16296 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16297 | Intent.FLAG_RECEIVER_FOREGROUND); 16298 intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId); 16299 broadcastIntentLocked(null, null, intent, 16300 null, null, 0, null, null, 16301 android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE, 16302 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 16303 } 16304 } finally { 16305 Binder.restoreCallingIdentity(ident); 16306 } 16307 } 16308 16309 void dispatchUserSwitch(final UserStartedState uss, final int oldUserId, 16310 final int newUserId) { 16311 final int N = mUserSwitchObservers.beginBroadcast(); 16312 if (N > 0) { 16313 final IRemoteCallback callback = new IRemoteCallback.Stub() { 16314 int mCount = 0; 16315 @Override 16316 public void sendResult(Bundle data) throws RemoteException { 16317 synchronized (ActivityManagerService.this) { 16318 if (mCurUserSwitchCallback == this) { 16319 mCount++; 16320 if (mCount == N) { 16321 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 16322 } 16323 } 16324 } 16325 } 16326 }; 16327 synchronized (this) { 16328 uss.switching = true; 16329 mCurUserSwitchCallback = callback; 16330 } 16331 for (int i=0; i<N; i++) { 16332 try { 16333 mUserSwitchObservers.getBroadcastItem(i).onUserSwitching( 16334 newUserId, callback); 16335 } catch (RemoteException e) { 16336 } 16337 } 16338 } else { 16339 synchronized (this) { 16340 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 16341 } 16342 } 16343 mUserSwitchObservers.finishBroadcast(); 16344 } 16345 16346 void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 16347 synchronized (this) { 16348 Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId); 16349 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 16350 } 16351 } 16352 16353 void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) { 16354 mCurUserSwitchCallback = null; 16355 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 16356 mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG, 16357 oldUserId, newUserId, uss)); 16358 } 16359 16360 void userInitialized(UserStartedState uss, int newUserId) { 16361 completeSwitchAndInitalize(uss, newUserId, true, false); 16362 } 16363 16364 void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 16365 completeSwitchAndInitalize(uss, newUserId, false, true); 16366 } 16367 16368 void completeSwitchAndInitalize(UserStartedState uss, int newUserId, 16369 boolean clearInitializing, boolean clearSwitching) { 16370 boolean unfrozen = false; 16371 synchronized (this) { 16372 if (clearInitializing) { 16373 uss.initializing = false; 16374 getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier()); 16375 } 16376 if (clearSwitching) { 16377 uss.switching = false; 16378 } 16379 if (!uss.switching && !uss.initializing) { 16380 mWindowManager.stopFreezingScreen(); 16381 unfrozen = true; 16382 } 16383 } 16384 if (unfrozen) { 16385 final int N = mUserSwitchObservers.beginBroadcast(); 16386 for (int i=0; i<N; i++) { 16387 try { 16388 mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId); 16389 } catch (RemoteException e) { 16390 } 16391 } 16392 mUserSwitchObservers.finishBroadcast(); 16393 } 16394 } 16395 16396 void scheduleStartRelatedUsersLocked() { 16397 if (!mHandler.hasMessages(START_RELATED_USERS_MSG)) { 16398 mHandler.sendMessageDelayed(mHandler.obtainMessage(START_RELATED_USERS_MSG), 16399 DateUtils.SECOND_IN_MILLIS); 16400 } 16401 } 16402 16403 void startRelatedUsersLocked() { 16404 if (DEBUG_MU) Slog.i(TAG_MU, "startRelatedUsersLocked"); 16405 List<UserInfo> relatedUsers = getUserManagerLocked().getRelatedUsers(mCurrentUserId); 16406 List<UserInfo> toStart = new ArrayList<UserInfo>(relatedUsers.size()); 16407 for (UserInfo relatedUser : relatedUsers) { 16408 if ((relatedUser.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED) { 16409 toStart.add(relatedUser); 16410 } 16411 } 16412 final int n = toStart.size(); 16413 int i = 0; 16414 for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) { 16415 startUserInBackground(toStart.get(i).id); 16416 } 16417 if (i < n) { 16418 Slog.w(TAG_MU, "More related users than MAX_RUNNING_USERS"); 16419 } 16420 } 16421 16422 void finishUserSwitch(UserStartedState uss) { 16423 synchronized (this) { 16424 if (uss.mState == UserStartedState.STATE_BOOTING 16425 && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) { 16426 uss.mState = UserStartedState.STATE_RUNNING; 16427 final int userId = uss.mHandle.getIdentifier(); 16428 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 16429 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 16430 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT); 16431 broadcastIntentLocked(null, null, intent, 16432 null, null, 0, null, null, 16433 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE, 16434 true, false, MY_PID, Process.SYSTEM_UID, userId); 16435 } 16436 16437 startRelatedUsersLocked(); 16438 16439 int num = mUserLru.size(); 16440 int i = 0; 16441 while (num > MAX_RUNNING_USERS && i < mUserLru.size()) { 16442 Integer oldUserId = mUserLru.get(i); 16443 UserStartedState oldUss = mStartedUsers.get(oldUserId); 16444 if (oldUss == null) { 16445 // Shouldn't happen, but be sane if it does. 16446 mUserLru.remove(i); 16447 num--; 16448 continue; 16449 } 16450 if (oldUss.mState == UserStartedState.STATE_STOPPING 16451 || oldUss.mState == UserStartedState.STATE_SHUTDOWN) { 16452 // This user is already stopping, doesn't count. 16453 num--; 16454 i++; 16455 continue; 16456 } 16457 if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) { 16458 // Owner and current can't be stopped, but count as running. 16459 i++; 16460 continue; 16461 } 16462 // This is a user to be stopped. 16463 stopUserLocked(oldUserId, null); 16464 num--; 16465 i++; 16466 } 16467 } 16468 } 16469 16470 @Override 16471 public int stopUser(final int userId, final IStopUserCallback callback) { 16472 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 16473 != PackageManager.PERMISSION_GRANTED) { 16474 String msg = "Permission Denial: switchUser() from pid=" 16475 + Binder.getCallingPid() 16476 + ", uid=" + Binder.getCallingUid() 16477 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 16478 Slog.w(TAG, msg); 16479 throw new SecurityException(msg); 16480 } 16481 if (userId <= 0) { 16482 throw new IllegalArgumentException("Can't stop primary user " + userId); 16483 } 16484 synchronized (this) { 16485 return stopUserLocked(userId, callback); 16486 } 16487 } 16488 16489 private int stopUserLocked(final int userId, final IStopUserCallback callback) { 16490 if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId); 16491 if (mCurrentUserId == userId) { 16492 return ActivityManager.USER_OP_IS_CURRENT; 16493 } 16494 16495 final UserStartedState uss = mStartedUsers.get(userId); 16496 if (uss == null) { 16497 // User is not started, nothing to do... but we do need to 16498 // callback if requested. 16499 if (callback != null) { 16500 mHandler.post(new Runnable() { 16501 @Override 16502 public void run() { 16503 try { 16504 callback.userStopped(userId); 16505 } catch (RemoteException e) { 16506 } 16507 } 16508 }); 16509 } 16510 return ActivityManager.USER_OP_SUCCESS; 16511 } 16512 16513 if (callback != null) { 16514 uss.mStopCallbacks.add(callback); 16515 } 16516 16517 if (uss.mState != UserStartedState.STATE_STOPPING 16518 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 16519 uss.mState = UserStartedState.STATE_STOPPING; 16520 updateStartedUserArrayLocked(); 16521 16522 long ident = Binder.clearCallingIdentity(); 16523 try { 16524 // We are going to broadcast ACTION_USER_STOPPING and then 16525 // once that is done send a final ACTION_SHUTDOWN and then 16526 // stop the user. 16527 final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING); 16528 stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 16529 stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 16530 stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true); 16531 final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN); 16532 // This is the result receiver for the final shutdown broadcast. 16533 final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() { 16534 @Override 16535 public void performReceive(Intent intent, int resultCode, String data, 16536 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 16537 finishUserStop(uss); 16538 } 16539 }; 16540 // This is the result receiver for the initial stopping broadcast. 16541 final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() { 16542 @Override 16543 public void performReceive(Intent intent, int resultCode, String data, 16544 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 16545 // On to the next. 16546 synchronized (ActivityManagerService.this) { 16547 if (uss.mState != UserStartedState.STATE_STOPPING) { 16548 // Whoops, we are being started back up. Abort, abort! 16549 return; 16550 } 16551 uss.mState = UserStartedState.STATE_SHUTDOWN; 16552 } 16553 broadcastIntentLocked(null, null, shutdownIntent, 16554 null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE, 16555 true, false, MY_PID, Process.SYSTEM_UID, userId); 16556 } 16557 }; 16558 // Kick things off. 16559 broadcastIntentLocked(null, null, stoppingIntent, 16560 null, stoppingReceiver, 0, null, null, 16561 android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 16562 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 16563 } finally { 16564 Binder.restoreCallingIdentity(ident); 16565 } 16566 } 16567 16568 return ActivityManager.USER_OP_SUCCESS; 16569 } 16570 16571 void finishUserStop(UserStartedState uss) { 16572 final int userId = uss.mHandle.getIdentifier(); 16573 boolean stopped; 16574 ArrayList<IStopUserCallback> callbacks; 16575 synchronized (this) { 16576 callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks); 16577 if (mStartedUsers.get(userId) != uss) { 16578 stopped = false; 16579 } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) { 16580 stopped = false; 16581 } else { 16582 stopped = true; 16583 // User can no longer run. 16584 mStartedUsers.remove(userId); 16585 mUserLru.remove(Integer.valueOf(userId)); 16586 updateStartedUserArrayLocked(); 16587 16588 // Clean up all state and processes associated with the user. 16589 // Kill all the processes for the user. 16590 forceStopUserLocked(userId, "finish user"); 16591 } 16592 } 16593 16594 for (int i=0; i<callbacks.size(); i++) { 16595 try { 16596 if (stopped) callbacks.get(i).userStopped(userId); 16597 else callbacks.get(i).userStopAborted(userId); 16598 } catch (RemoteException e) { 16599 } 16600 } 16601 16602 mStackSupervisor.removeUserLocked(userId); 16603 } 16604 16605 @Override 16606 public UserInfo getCurrentUser() { 16607 if ((checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) 16608 != PackageManager.PERMISSION_GRANTED) && ( 16609 checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 16610 != PackageManager.PERMISSION_GRANTED)) { 16611 String msg = "Permission Denial: getCurrentUser() from pid=" 16612 + Binder.getCallingPid() 16613 + ", uid=" + Binder.getCallingUid() 16614 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS; 16615 Slog.w(TAG, msg); 16616 throw new SecurityException(msg); 16617 } 16618 synchronized (this) { 16619 return getUserManagerLocked().getUserInfo(mCurrentUserId); 16620 } 16621 } 16622 16623 int getCurrentUserIdLocked() { 16624 return mCurrentUserId; 16625 } 16626 16627 @Override 16628 public boolean isUserRunning(int userId, boolean orStopped) { 16629 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) 16630 != PackageManager.PERMISSION_GRANTED) { 16631 String msg = "Permission Denial: isUserRunning() from pid=" 16632 + Binder.getCallingPid() 16633 + ", uid=" + Binder.getCallingUid() 16634 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS; 16635 Slog.w(TAG, msg); 16636 throw new SecurityException(msg); 16637 } 16638 synchronized (this) { 16639 return isUserRunningLocked(userId, orStopped); 16640 } 16641 } 16642 16643 boolean isUserRunningLocked(int userId, boolean orStopped) { 16644 UserStartedState state = mStartedUsers.get(userId); 16645 if (state == null) { 16646 return false; 16647 } 16648 if (orStopped) { 16649 return true; 16650 } 16651 return state.mState != UserStartedState.STATE_STOPPING 16652 && state.mState != UserStartedState.STATE_SHUTDOWN; 16653 } 16654 16655 @Override 16656 public int[] getRunningUserIds() { 16657 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) 16658 != PackageManager.PERMISSION_GRANTED) { 16659 String msg = "Permission Denial: isUserRunning() from pid=" 16660 + Binder.getCallingPid() 16661 + ", uid=" + Binder.getCallingUid() 16662 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS; 16663 Slog.w(TAG, msg); 16664 throw new SecurityException(msg); 16665 } 16666 synchronized (this) { 16667 return mStartedUserArray; 16668 } 16669 } 16670 16671 private void updateStartedUserArrayLocked() { 16672 int num = 0; 16673 for (int i=0; i<mStartedUsers.size(); i++) { 16674 UserStartedState uss = mStartedUsers.valueAt(i); 16675 // This list does not include stopping users. 16676 if (uss.mState != UserStartedState.STATE_STOPPING 16677 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 16678 num++; 16679 } 16680 } 16681 mStartedUserArray = new int[num]; 16682 num = 0; 16683 for (int i=0; i<mStartedUsers.size(); i++) { 16684 UserStartedState uss = mStartedUsers.valueAt(i); 16685 if (uss.mState != UserStartedState.STATE_STOPPING 16686 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 16687 mStartedUserArray[num] = mStartedUsers.keyAt(i); 16688 num++; 16689 } 16690 } 16691 } 16692 16693 @Override 16694 public void registerUserSwitchObserver(IUserSwitchObserver observer) { 16695 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 16696 != PackageManager.PERMISSION_GRANTED) { 16697 String msg = "Permission Denial: registerUserSwitchObserver() from pid=" 16698 + Binder.getCallingPid() 16699 + ", uid=" + Binder.getCallingUid() 16700 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 16701 Slog.w(TAG, msg); 16702 throw new SecurityException(msg); 16703 } 16704 16705 mUserSwitchObservers.register(observer); 16706 } 16707 16708 @Override 16709 public void unregisterUserSwitchObserver(IUserSwitchObserver observer) { 16710 mUserSwitchObservers.unregister(observer); 16711 } 16712 16713 private boolean userExists(int userId) { 16714 if (userId == 0) { 16715 return true; 16716 } 16717 UserManagerService ums = getUserManagerLocked(); 16718 return ums != null ? (ums.getUserInfo(userId) != null) : false; 16719 } 16720 16721 int[] getUsersLocked() { 16722 UserManagerService ums = getUserManagerLocked(); 16723 return ums != null ? ums.getUserIds() : new int[] { 0 }; 16724 } 16725 16726 UserManagerService getUserManagerLocked() { 16727 if (mUserManager == null) { 16728 IBinder b = ServiceManager.getService(Context.USER_SERVICE); 16729 mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b); 16730 } 16731 return mUserManager; 16732 } 16733 16734 private int applyUserId(int uid, int userId) { 16735 return UserHandle.getUid(userId, uid); 16736 } 16737 16738 ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) { 16739 if (info == null) return null; 16740 ApplicationInfo newInfo = new ApplicationInfo(info); 16741 newInfo.uid = applyUserId(info.uid, userId); 16742 newInfo.dataDir = USER_DATA_DIR + userId + "/" 16743 + info.packageName; 16744 return newInfo; 16745 } 16746 16747 ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) { 16748 if (aInfo == null 16749 || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) { 16750 return aInfo; 16751 } 16752 16753 ActivityInfo info = new ActivityInfo(aInfo); 16754 info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId); 16755 return info; 16756 } 16757} 16758