ActivityManagerService.java revision ccb2a086fe0de77a4e3277454cb4a66f8e7dc57d
1/* 2 * Copyright (C) 2006-2008 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17package com.android.server.am; 18 19import static android.content.pm.PackageManager.PERMISSION_GRANTED; 20import static com.android.internal.util.XmlUtils.readIntAttribute; 21import static com.android.internal.util.XmlUtils.readLongAttribute; 22import static com.android.internal.util.XmlUtils.writeIntAttribute; 23import static com.android.internal.util.XmlUtils.writeLongAttribute; 24import static com.android.server.Watchdog.NATIVE_STACKS_OF_INTEREST; 25import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT; 26import static org.xmlpull.v1.XmlPullParser.START_TAG; 27 28import static com.android.server.am.ActivityStackSupervisor.HOME_STACK_ID; 29 30import android.app.AppOpsManager; 31import android.app.IActivityContainer; 32import android.app.IActivityContainerCallback; 33import android.appwidget.AppWidgetManager; 34import android.graphics.Rect; 35import android.os.BatteryStats; 36import android.util.ArrayMap; 37import com.android.internal.R; 38import com.android.internal.annotations.GuardedBy; 39import com.android.internal.app.IAppOpsService; 40import com.android.internal.app.ProcessMap; 41import com.android.internal.app.ProcessStats; 42import com.android.internal.os.BackgroundThread; 43import com.android.internal.os.BatteryStatsImpl; 44import com.android.internal.os.ProcessCpuTracker; 45import com.android.internal.os.TransferPipe; 46import com.android.internal.util.FastPrintWriter; 47import com.android.internal.util.FastXmlSerializer; 48import com.android.internal.util.MemInfoReader; 49import com.android.internal.util.Preconditions; 50import com.android.server.AppOpsService; 51import com.android.server.AttributeCache; 52import com.android.server.IntentResolver; 53import com.android.server.ServiceThread; 54import com.android.server.SystemService; 55import com.android.server.Watchdog; 56import com.android.server.am.ActivityStack.ActivityState; 57import com.android.server.firewall.IntentFirewall; 58import com.android.server.pm.UserManagerService; 59import com.android.server.wm.AppTransition; 60import com.android.server.wm.WindowManagerService; 61import com.google.android.collect.Lists; 62import com.google.android.collect.Maps; 63 64import dalvik.system.Zygote; 65 66import libcore.io.IoUtils; 67 68import org.xmlpull.v1.XmlPullParser; 69import org.xmlpull.v1.XmlPullParserException; 70import org.xmlpull.v1.XmlSerializer; 71 72import android.app.Activity; 73import android.app.ActivityManager; 74import android.app.ActivityManager.RunningTaskInfo; 75import android.app.ActivityManager.StackInfo; 76import android.app.ActivityManagerNative; 77import android.app.ActivityOptions; 78import android.app.ActivityThread; 79import android.app.AlertDialog; 80import android.app.AppGlobals; 81import android.app.ApplicationErrorReport; 82import android.app.Dialog; 83import android.app.IActivityController; 84import android.app.IApplicationThread; 85import android.app.IInstrumentationWatcher; 86import android.app.INotificationManager; 87import android.app.IProcessObserver; 88import android.app.IServiceConnection; 89import android.app.IStopUserCallback; 90import android.app.IThumbnailReceiver; 91import android.app.IUiAutomationConnection; 92import android.app.IUserSwitchObserver; 93import android.app.Instrumentation; 94import android.app.Notification; 95import android.app.NotificationManager; 96import android.app.PendingIntent; 97import android.app.backup.IBackupManager; 98import android.content.ActivityNotFoundException; 99import android.content.BroadcastReceiver; 100import android.content.ClipData; 101import android.content.ComponentCallbacks2; 102import android.content.ComponentName; 103import android.content.ContentProvider; 104import android.content.ContentResolver; 105import android.content.Context; 106import android.content.DialogInterface; 107import android.content.IContentProvider; 108import android.content.IIntentReceiver; 109import android.content.IIntentSender; 110import android.content.Intent; 111import android.content.IntentFilter; 112import android.content.IntentSender; 113import android.content.pm.ActivityInfo; 114import android.content.pm.ApplicationInfo; 115import android.content.pm.ConfigurationInfo; 116import android.content.pm.IPackageDataObserver; 117import android.content.pm.IPackageManager; 118import android.content.pm.InstrumentationInfo; 119import android.content.pm.PackageInfo; 120import android.content.pm.PackageManager; 121import android.content.pm.ParceledListSlice; 122import android.content.pm.UserInfo; 123import android.content.pm.PackageManager.NameNotFoundException; 124import android.content.pm.PathPermission; 125import android.content.pm.ProviderInfo; 126import android.content.pm.ResolveInfo; 127import android.content.pm.ServiceInfo; 128import android.content.res.CompatibilityInfo; 129import android.content.res.Configuration; 130import android.graphics.Bitmap; 131import android.net.Proxy; 132import android.net.ProxyProperties; 133import android.net.Uri; 134import android.os.Binder; 135import android.os.Build; 136import android.os.Bundle; 137import android.os.Debug; 138import android.os.DropBoxManager; 139import android.os.Environment; 140import android.os.FactoryTest; 141import android.os.FileObserver; 142import android.os.FileUtils; 143import android.os.Handler; 144import android.os.IBinder; 145import android.os.IPermissionController; 146import android.os.IRemoteCallback; 147import android.os.IUserManager; 148import android.os.Looper; 149import android.os.Message; 150import android.os.Parcel; 151import android.os.ParcelFileDescriptor; 152import android.os.Process; 153import android.os.RemoteCallbackList; 154import android.os.RemoteException; 155import android.os.SELinux; 156import android.os.ServiceManager; 157import android.os.StrictMode; 158import android.os.SystemClock; 159import android.os.SystemProperties; 160import android.os.UpdateLock; 161import android.os.UserHandle; 162import android.provider.Settings; 163import android.text.format.DateUtils; 164import android.text.format.Time; 165import android.util.AtomicFile; 166import android.util.EventLog; 167import android.util.Log; 168import android.util.Pair; 169import android.util.PrintWriterPrinter; 170import android.util.Slog; 171import android.util.SparseArray; 172import android.util.TimeUtils; 173import android.util.Xml; 174import android.view.Gravity; 175import android.view.LayoutInflater; 176import android.view.View; 177import android.view.WindowManager; 178 179import java.io.BufferedInputStream; 180import java.io.BufferedOutputStream; 181import java.io.DataInputStream; 182import java.io.DataOutputStream; 183import java.io.File; 184import java.io.FileDescriptor; 185import java.io.FileInputStream; 186import java.io.FileNotFoundException; 187import java.io.FileOutputStream; 188import java.io.IOException; 189import java.io.InputStreamReader; 190import java.io.PrintWriter; 191import java.io.StringWriter; 192import java.lang.ref.WeakReference; 193import java.util.ArrayList; 194import java.util.Arrays; 195import java.util.Collections; 196import java.util.Comparator; 197import java.util.HashMap; 198import java.util.HashSet; 199import java.util.Iterator; 200import java.util.List; 201import java.util.Locale; 202import java.util.Map; 203import java.util.Set; 204import java.util.concurrent.atomic.AtomicBoolean; 205import java.util.concurrent.atomic.AtomicLong; 206 207public final class ActivityManagerService extends ActivityManagerNative 208 implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback { 209 private static final String USER_DATA_DIR = "/data/user/"; 210 static final String TAG = "ActivityManager"; 211 static final String TAG_MU = "ActivityManagerServiceMU"; 212 static final boolean DEBUG = false; 213 static final boolean localLOGV = DEBUG; 214 static final boolean DEBUG_BACKUP = localLOGV || false; 215 static final boolean DEBUG_BROADCAST = localLOGV || false; 216 static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false; 217 static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false; 218 static final boolean DEBUG_CLEANUP = localLOGV || false; 219 static final boolean DEBUG_CONFIGURATION = localLOGV || false; 220 static final boolean DEBUG_FOCUS = false; 221 static final boolean DEBUG_IMMERSIVE = localLOGV || false; 222 static final boolean DEBUG_MU = localLOGV || false; 223 static final boolean DEBUG_OOM_ADJ = localLOGV || false; 224 static final boolean DEBUG_LRU = localLOGV || false; 225 static final boolean DEBUG_PAUSE = localLOGV || false; 226 static final boolean DEBUG_POWER = localLOGV || false; 227 static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false; 228 static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false; 229 static final boolean DEBUG_PROCESSES = localLOGV || false; 230 static final boolean DEBUG_PROVIDER = localLOGV || false; 231 static final boolean DEBUG_RESULTS = localLOGV || false; 232 static final boolean DEBUG_SERVICE = localLOGV || false; 233 static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false; 234 static final boolean DEBUG_STACK = localLOGV || false; 235 static final boolean DEBUG_SWITCH = localLOGV || false; 236 static final boolean DEBUG_TASKS = localLOGV || false; 237 static final boolean DEBUG_THUMBNAILS = localLOGV || false; 238 static final boolean DEBUG_TRANSITION = localLOGV || false; 239 static final boolean DEBUG_URI_PERMISSION = localLOGV || false; 240 static final boolean DEBUG_USER_LEAVING = localLOGV || false; 241 static final boolean DEBUG_VISBILITY = localLOGV || false; 242 static final boolean DEBUG_PSS = localLOGV || false; 243 static final boolean DEBUG_LOCKSCREEN = localLOGV || false; 244 static final boolean VALIDATE_TOKENS = false; 245 static final boolean SHOW_ACTIVITY_START_TIME = true; 246 247 // Control over CPU and battery monitoring. 248 static final long BATTERY_STATS_TIME = 30*60*1000; // write battery stats every 30 minutes. 249 static final boolean MONITOR_CPU_USAGE = true; 250 static final long MONITOR_CPU_MIN_TIME = 5*1000; // don't sample cpu less than every 5 seconds. 251 static final long MONITOR_CPU_MAX_TIME = 0x0fffffff; // wait possibly forever for next cpu sample. 252 static final boolean MONITOR_THREAD_CPU_USAGE = false; 253 254 // The flags that are set for all calls we make to the package manager. 255 static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES; 256 257 private static final String SYSTEM_DEBUGGABLE = "ro.debuggable"; 258 259 static final boolean IS_USER_BUILD = "user".equals(Build.TYPE); 260 261 // Maximum number of recent tasks that we can remember. 262 static final int MAX_RECENT_TASKS = ActivityManager.isLowRamDeviceStatic() ? 10 : 20; 263 264 // Amount of time after a call to stopAppSwitches() during which we will 265 // prevent further untrusted switches from happening. 266 static final long APP_SWITCH_DELAY_TIME = 5*1000; 267 268 // How long we wait for a launched process to attach to the activity manager 269 // before we decide it's never going to come up for real. 270 static final int PROC_START_TIMEOUT = 10*1000; 271 272 // How long we wait for a launched process to attach to the activity manager 273 // before we decide it's never going to come up for real, when the process was 274 // started with a wrapper for instrumentation (such as Valgrind) because it 275 // could take much longer than usual. 276 static final int PROC_START_TIMEOUT_WITH_WRAPPER = 300*1000; 277 278 // How long to wait after going idle before forcing apps to GC. 279 static final int GC_TIMEOUT = 5*1000; 280 281 // The minimum amount of time between successive GC requests for a process. 282 static final int GC_MIN_INTERVAL = 60*1000; 283 284 // The minimum amount of time between successive PSS requests for a process. 285 static final int FULL_PSS_MIN_INTERVAL = 10*60*1000; 286 287 // The minimum amount of time between successive PSS requests for a process 288 // when the request is due to the memory state being lowered. 289 static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000; 290 291 // The rate at which we check for apps using excessive power -- 15 mins. 292 static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000; 293 294 // The minimum sample duration we will allow before deciding we have 295 // enough data on wake locks to start killing things. 296 static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000; 297 298 // The minimum sample duration we will allow before deciding we have 299 // enough data on CPU usage to start killing things. 300 static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000; 301 302 // How long we allow a receiver to run before giving up on it. 303 static final int BROADCAST_FG_TIMEOUT = 10*1000; 304 static final int BROADCAST_BG_TIMEOUT = 60*1000; 305 306 // How long we wait until we timeout on key dispatching. 307 static final int KEY_DISPATCHING_TIMEOUT = 5*1000; 308 309 // How long we wait until we timeout on key dispatching during instrumentation. 310 static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000; 311 312 // Amount of time we wait for observers to handle a user switch before 313 // giving up on them and unfreezing the screen. 314 static final int USER_SWITCH_TIMEOUT = 2*1000; 315 316 // Maximum number of users we allow to be running at a time. 317 static final int MAX_RUNNING_USERS = 3; 318 319 // How long to wait in getAssistContextExtras for the activity and foreground services 320 // to respond with the result. 321 static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500; 322 323 // Maximum number of persisted Uri grants a package is allowed 324 static final int MAX_PERSISTED_URI_GRANTS = 128; 325 326 static final int MY_PID = Process.myPid(); 327 328 static final String[] EMPTY_STRING_ARRAY = new String[0]; 329 330 // How many bytes to write into the dropbox log before truncating 331 static final int DROPBOX_MAX_SIZE = 256 * 1024; 332 333 /** Run all ActivityStacks through this */ 334 ActivityStackSupervisor mStackSupervisor; 335 336 public IntentFirewall mIntentFirewall; 337 338 // Whether we should show our dialogs (ANR, crash, etc) or just perform their 339 // default actuion automatically. Important for devices without direct input 340 // devices. 341 private boolean mShowDialogs = true; 342 343 /** 344 * Description of a request to start a new activity, which has been held 345 * due to app switches being disabled. 346 */ 347 static class PendingActivityLaunch { 348 final ActivityRecord r; 349 final ActivityRecord sourceRecord; 350 final int startFlags; 351 final ActivityStack stack; 352 353 PendingActivityLaunch(ActivityRecord _r, ActivityRecord _sourceRecord, 354 int _startFlags, ActivityStack _stack) { 355 r = _r; 356 sourceRecord = _sourceRecord; 357 startFlags = _startFlags; 358 stack = _stack; 359 } 360 } 361 362 final ArrayList<PendingActivityLaunch> mPendingActivityLaunches 363 = new ArrayList<PendingActivityLaunch>(); 364 365 BroadcastQueue mFgBroadcastQueue; 366 BroadcastQueue mBgBroadcastQueue; 367 // Convenient for easy iteration over the queues. Foreground is first 368 // so that dispatch of foreground broadcasts gets precedence. 369 final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2]; 370 371 BroadcastQueue broadcastQueueForIntent(Intent intent) { 372 final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0; 373 if (DEBUG_BACKGROUND_BROADCAST) { 374 Slog.i(TAG, "Broadcast intent " + intent + " on " 375 + (isFg ? "foreground" : "background") 376 + " queue"); 377 } 378 return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue; 379 } 380 381 BroadcastRecord broadcastRecordForReceiverLocked(IBinder receiver) { 382 for (BroadcastQueue queue : mBroadcastQueues) { 383 BroadcastRecord r = queue.getMatchingOrderedReceiver(receiver); 384 if (r != null) { 385 return r; 386 } 387 } 388 return null; 389 } 390 391 /** 392 * Activity we have told the window manager to have key focus. 393 */ 394 ActivityRecord mFocusedActivity = null; 395 396 /** 397 * List of intents that were used to start the most recent tasks. 398 */ 399 private final ArrayList<TaskRecord> mRecentTasks = new ArrayList<TaskRecord>(); 400 401 public class PendingAssistExtras extends Binder implements Runnable { 402 public final ActivityRecord activity; 403 public boolean haveResult = false; 404 public Bundle result = null; 405 public PendingAssistExtras(ActivityRecord _activity) { 406 activity = _activity; 407 } 408 @Override 409 public void run() { 410 Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity); 411 synchronized (this) { 412 haveResult = true; 413 notifyAll(); 414 } 415 } 416 } 417 418 final ArrayList<PendingAssistExtras> mPendingAssistExtras 419 = new ArrayList<PendingAssistExtras>(); 420 421 /** 422 * Process management. 423 */ 424 final ProcessList mProcessList = new ProcessList(); 425 426 /** 427 * All of the applications we currently have running organized by name. 428 * The keys are strings of the application package name (as 429 * returned by the package manager), and the keys are ApplicationRecord 430 * objects. 431 */ 432 final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>(); 433 434 /** 435 * Tracking long-term execution of processes to look for abuse and other 436 * bad app behavior. 437 */ 438 final ProcessStatsService mProcessStats; 439 440 /** 441 * The currently running isolated processes. 442 */ 443 final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>(); 444 445 /** 446 * Counter for assigning isolated process uids, to avoid frequently reusing the 447 * same ones. 448 */ 449 int mNextIsolatedProcessUid = 0; 450 451 /** 452 * The currently running heavy-weight process, if any. 453 */ 454 ProcessRecord mHeavyWeightProcess = null; 455 456 /** 457 * The last time that various processes have crashed. 458 */ 459 final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>(); 460 461 /** 462 * Information about a process that is currently marked as bad. 463 */ 464 static final class BadProcessInfo { 465 BadProcessInfo(long time, String shortMsg, String longMsg, String stack) { 466 this.time = time; 467 this.shortMsg = shortMsg; 468 this.longMsg = longMsg; 469 this.stack = stack; 470 } 471 472 final long time; 473 final String shortMsg; 474 final String longMsg; 475 final String stack; 476 } 477 478 /** 479 * Set of applications that we consider to be bad, and will reject 480 * incoming broadcasts from (which the user has no control over). 481 * Processes are added to this set when they have crashed twice within 482 * a minimum amount of time; they are removed from it when they are 483 * later restarted (hopefully due to some user action). The value is the 484 * time it was added to the list. 485 */ 486 final ProcessMap<BadProcessInfo> mBadProcesses = new ProcessMap<BadProcessInfo>(); 487 488 /** 489 * All of the processes we currently have running organized by pid. 490 * The keys are the pid running the application. 491 * 492 * <p>NOTE: This object is protected by its own lock, NOT the global 493 * activity manager lock! 494 */ 495 final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>(); 496 497 /** 498 * All of the processes that have been forced to be foreground. The key 499 * is the pid of the caller who requested it (we hold a death 500 * link on it). 501 */ 502 abstract class ForegroundToken implements IBinder.DeathRecipient { 503 int pid; 504 IBinder token; 505 } 506 final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>(); 507 508 /** 509 * List of records for processes that someone had tried to start before the 510 * system was ready. We don't start them at that point, but ensure they 511 * are started by the time booting is complete. 512 */ 513 final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>(); 514 515 /** 516 * List of persistent applications that are in the process 517 * of being started. 518 */ 519 final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>(); 520 521 /** 522 * Processes that are being forcibly torn down. 523 */ 524 final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>(); 525 526 /** 527 * List of running applications, sorted by recent usage. 528 * The first entry in the list is the least recently used. 529 */ 530 final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>(); 531 532 /** 533 * Where in mLruProcesses that the processes hosting activities start. 534 */ 535 int mLruProcessActivityStart = 0; 536 537 /** 538 * Where in mLruProcesses that the processes hosting services start. 539 * This is after (lower index) than mLruProcessesActivityStart. 540 */ 541 int mLruProcessServiceStart = 0; 542 543 /** 544 * List of processes that should gc as soon as things are idle. 545 */ 546 final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>(); 547 548 /** 549 * Processes we want to collect PSS data from. 550 */ 551 final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>(); 552 553 /** 554 * Last time we requested PSS data of all processes. 555 */ 556 long mLastFullPssTime = SystemClock.uptimeMillis(); 557 558 /** 559 * This is the process holding what we currently consider to be 560 * the "home" activity. 561 */ 562 ProcessRecord mHomeProcess; 563 564 /** 565 * This is the process holding the activity the user last visited that 566 * is in a different process from the one they are currently in. 567 */ 568 ProcessRecord mPreviousProcess; 569 570 /** 571 * The time at which the previous process was last visible. 572 */ 573 long mPreviousProcessVisibleTime; 574 575 /** 576 * Which uses have been started, so are allowed to run code. 577 */ 578 final SparseArray<UserStartedState> mStartedUsers = new SparseArray<UserStartedState>(); 579 580 /** 581 * LRU list of history of current users. Most recently current is at the end. 582 */ 583 final ArrayList<Integer> mUserLru = new ArrayList<Integer>(); 584 585 /** 586 * Constant array of the users that are currently started. 587 */ 588 int[] mStartedUserArray = new int[] { 0 }; 589 590 /** 591 * Registered observers of the user switching mechanics. 592 */ 593 final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers 594 = new RemoteCallbackList<IUserSwitchObserver>(); 595 596 /** 597 * Currently active user switch. 598 */ 599 Object mCurUserSwitchCallback; 600 601 /** 602 * Packages that the user has asked to have run in screen size 603 * compatibility mode instead of filling the screen. 604 */ 605 final CompatModePackages mCompatModePackages; 606 607 /** 608 * Set of IntentSenderRecord objects that are currently active. 609 */ 610 final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords 611 = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>(); 612 613 /** 614 * Fingerprints (hashCode()) of stack traces that we've 615 * already logged DropBox entries for. Guarded by itself. If 616 * something (rogue user app) forces this over 617 * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared. 618 */ 619 private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>(); 620 private static final int MAX_DUP_SUPPRESSED_STACKS = 5000; 621 622 /** 623 * Strict Mode background batched logging state. 624 * 625 * The string buffer is guarded by itself, and its lock is also 626 * used to determine if another batched write is already 627 * in-flight. 628 */ 629 private final StringBuilder mStrictModeBuffer = new StringBuilder(); 630 631 /** 632 * Keeps track of all IIntentReceivers that have been registered for 633 * broadcasts. Hash keys are the receiver IBinder, hash value is 634 * a ReceiverList. 635 */ 636 final HashMap<IBinder, ReceiverList> mRegisteredReceivers = 637 new HashMap<IBinder, ReceiverList>(); 638 639 /** 640 * Resolver for broadcast intents to registered receivers. 641 * Holds BroadcastFilter (subclass of IntentFilter). 642 */ 643 final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver 644 = new IntentResolver<BroadcastFilter, BroadcastFilter>() { 645 @Override 646 protected boolean allowFilterResult( 647 BroadcastFilter filter, List<BroadcastFilter> dest) { 648 IBinder target = filter.receiverList.receiver.asBinder(); 649 for (int i=dest.size()-1; i>=0; i--) { 650 if (dest.get(i).receiverList.receiver.asBinder() == target) { 651 return false; 652 } 653 } 654 return true; 655 } 656 657 @Override 658 protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) { 659 if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL 660 || userId == filter.owningUserId) { 661 return super.newResult(filter, match, userId); 662 } 663 return null; 664 } 665 666 @Override 667 protected BroadcastFilter[] newArray(int size) { 668 return new BroadcastFilter[size]; 669 } 670 671 @Override 672 protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) { 673 return packageName.equals(filter.packageName); 674 } 675 }; 676 677 /** 678 * State of all active sticky broadcasts per user. Keys are the action of the 679 * sticky Intent, values are an ArrayList of all broadcasted intents with 680 * that action (which should usually be one). The SparseArray is keyed 681 * by the user ID the sticky is for, and can include UserHandle.USER_ALL 682 * for stickies that are sent to all users. 683 */ 684 final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts = 685 new SparseArray<ArrayMap<String, ArrayList<Intent>>>(); 686 687 final ActiveServices mServices; 688 689 /** 690 * Backup/restore process management 691 */ 692 String mBackupAppName = null; 693 BackupRecord mBackupTarget = null; 694 695 /** 696 * List of PendingThumbnailsRecord objects of clients who are still 697 * waiting to receive all of the thumbnails for a task. 698 */ 699 final ArrayList<PendingThumbnailsRecord> mPendingThumbnails = 700 new ArrayList<PendingThumbnailsRecord>(); 701 702 final ProviderMap mProviderMap; 703 704 /** 705 * List of content providers who have clients waiting for them. The 706 * application is currently being launched and the provider will be 707 * removed from this list once it is published. 708 */ 709 final ArrayList<ContentProviderRecord> mLaunchingProviders 710 = new ArrayList<ContentProviderRecord>(); 711 712 /** 713 * File storing persisted {@link #mGrantedUriPermissions}. 714 */ 715 private final AtomicFile mGrantFile; 716 717 /** XML constants used in {@link #mGrantFile} */ 718 private static final String TAG_URI_GRANTS = "uri-grants"; 719 private static final String TAG_URI_GRANT = "uri-grant"; 720 private static final String ATTR_USER_HANDLE = "userHandle"; 721 private static final String ATTR_SOURCE_PKG = "sourcePkg"; 722 private static final String ATTR_TARGET_PKG = "targetPkg"; 723 private static final String ATTR_URI = "uri"; 724 private static final String ATTR_MODE_FLAGS = "modeFlags"; 725 private static final String ATTR_CREATED_TIME = "createdTime"; 726 727 /** 728 * Global set of specific {@link Uri} permissions that have been granted. 729 * This optimized lookup structure maps from {@link UriPermission#targetUid} 730 * to {@link UriPermission#uri} to {@link UriPermission}. 731 */ 732 @GuardedBy("this") 733 private final SparseArray<ArrayMap<Uri, UriPermission>> 734 mGrantedUriPermissions = new SparseArray<ArrayMap<Uri, UriPermission>>(); 735 736 CoreSettingsObserver mCoreSettingsObserver; 737 738 /** 739 * Thread-local storage used to carry caller permissions over through 740 * indirect content-provider access. 741 */ 742 private class Identity { 743 public int pid; 744 public int uid; 745 746 Identity(int _pid, int _uid) { 747 pid = _pid; 748 uid = _uid; 749 } 750 } 751 752 private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>(); 753 754 /** 755 * All information we have collected about the runtime performance of 756 * any user id that can impact battery performance. 757 */ 758 final BatteryStatsService mBatteryStatsService; 759 760 /** 761 * Information about component usage 762 */ 763 final UsageStatsService mUsageStatsService; 764 765 /** 766 * Information about and control over application operations 767 */ 768 final AppOpsService mAppOpsService; 769 770 /** 771 * Current configuration information. HistoryRecord objects are given 772 * a reference to this object to indicate which configuration they are 773 * currently running in, so this object must be kept immutable. 774 */ 775 Configuration mConfiguration = new Configuration(); 776 777 /** 778 * Current sequencing integer of the configuration, for skipping old 779 * configurations. 780 */ 781 int mConfigurationSeq = 0; 782 783 /** 784 * Hardware-reported OpenGLES version. 785 */ 786 final int GL_ES_VERSION; 787 788 /** 789 * List of initialization arguments to pass to all processes when binding applications to them. 790 * For example, references to the commonly used services. 791 */ 792 HashMap<String, IBinder> mAppBindArgs; 793 794 /** 795 * Temporary to avoid allocations. Protected by main lock. 796 */ 797 final StringBuilder mStringBuilder = new StringBuilder(256); 798 799 /** 800 * Used to control how we initialize the service. 801 */ 802 boolean mStartRunning = false; 803 ComponentName mTopComponent; 804 String mTopAction; 805 String mTopData; 806 boolean mProcessesReady = false; 807 boolean mSystemReady = false; 808 boolean mBooting = false; 809 boolean mWaitingUpdate = false; 810 boolean mDidUpdate = false; 811 boolean mOnBattery = false; 812 boolean mLaunchWarningShown = false; 813 814 Context mContext; 815 816 int mFactoryTest; 817 818 boolean mCheckedForSetup; 819 820 /** 821 * The time at which we will allow normal application switches again, 822 * after a call to {@link #stopAppSwitches()}. 823 */ 824 long mAppSwitchesAllowedTime; 825 826 /** 827 * This is set to true after the first switch after mAppSwitchesAllowedTime 828 * is set; any switches after that will clear the time. 829 */ 830 boolean mDidAppSwitch; 831 832 /** 833 * Last time (in realtime) at which we checked for power usage. 834 */ 835 long mLastPowerCheckRealtime; 836 837 /** 838 * Last time (in uptime) at which we checked for power usage. 839 */ 840 long mLastPowerCheckUptime; 841 842 /** 843 * Set while we are wanting to sleep, to prevent any 844 * activities from being started/resumed. 845 */ 846 boolean mSleeping = false; 847 848 /** 849 * State of external calls telling us if the device is asleep. 850 */ 851 boolean mWentToSleep = false; 852 853 /** 854 * State of external call telling us if the lock screen is shown. 855 */ 856 boolean mLockScreenShown = false; 857 858 /** 859 * Set if we are shutting down the system, similar to sleeping. 860 */ 861 boolean mShuttingDown = false; 862 863 /** 864 * Current sequence id for oom_adj computation traversal. 865 */ 866 int mAdjSeq = 0; 867 868 /** 869 * Current sequence id for process LRU updating. 870 */ 871 int mLruSeq = 0; 872 873 /** 874 * Keep track of the non-cached/empty process we last found, to help 875 * determine how to distribute cached/empty processes next time. 876 */ 877 int mNumNonCachedProcs = 0; 878 879 /** 880 * Keep track of the number of cached hidden procs, to balance oom adj 881 * distribution between those and empty procs. 882 */ 883 int mNumCachedHiddenProcs = 0; 884 885 /** 886 * Keep track of the number of service processes we last found, to 887 * determine on the next iteration which should be B services. 888 */ 889 int mNumServiceProcs = 0; 890 int mNewNumAServiceProcs = 0; 891 int mNewNumServiceProcs = 0; 892 893 /** 894 * Allow the current computed overall memory level of the system to go down? 895 * This is set to false when we are killing processes for reasons other than 896 * memory management, so that the now smaller process list will not be taken as 897 * an indication that memory is tighter. 898 */ 899 boolean mAllowLowerMemLevel = false; 900 901 /** 902 * The last computed memory level, for holding when we are in a state that 903 * processes are going away for other reasons. 904 */ 905 int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL; 906 907 /** 908 * The last total number of process we have, to determine if changes actually look 909 * like a shrinking number of process due to lower RAM. 910 */ 911 int mLastNumProcesses; 912 913 /** 914 * The uptime of the last time we performed idle maintenance. 915 */ 916 long mLastIdleTime = SystemClock.uptimeMillis(); 917 918 /** 919 * Total time spent with RAM that has been added in the past since the last idle time. 920 */ 921 long mLowRamTimeSinceLastIdle = 0; 922 923 /** 924 * If RAM is currently low, when that horrible situation started. 925 */ 926 long mLowRamStartTime = 0; 927 928 /** 929 * For reporting to battery stats the current top application. 930 */ 931 private String mCurResumedPackage = null; 932 private int mCurResumedUid = -1; 933 934 /** 935 * For reporting to battery stats the apps currently running foreground 936 * service. The ProcessMap is package/uid tuples; each of these contain 937 * an array of the currently foreground processes. 938 */ 939 final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages 940 = new ProcessMap<ArrayList<ProcessRecord>>(); 941 942 /** 943 * This is set if we had to do a delayed dexopt of an app before launching 944 * it, to increasing the ANR timeouts in that case. 945 */ 946 boolean mDidDexOpt; 947 948 String mDebugApp = null; 949 boolean mWaitForDebugger = false; 950 boolean mDebugTransient = false; 951 String mOrigDebugApp = null; 952 boolean mOrigWaitForDebugger = false; 953 boolean mAlwaysFinishActivities = false; 954 IActivityController mController = null; 955 String mProfileApp = null; 956 ProcessRecord mProfileProc = null; 957 String mProfileFile; 958 ParcelFileDescriptor mProfileFd; 959 int mProfileType = 0; 960 boolean mAutoStopProfiler = false; 961 String mOpenGlTraceApp = null; 962 963 static class ProcessChangeItem { 964 static final int CHANGE_ACTIVITIES = 1<<0; 965 static final int CHANGE_IMPORTANCE= 1<<1; 966 int changes; 967 int uid; 968 int pid; 969 int importance; 970 boolean foregroundActivities; 971 } 972 973 final RemoteCallbackList<IProcessObserver> mProcessObservers 974 = new RemoteCallbackList<IProcessObserver>(); 975 ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5]; 976 977 final ArrayList<ProcessChangeItem> mPendingProcessChanges 978 = new ArrayList<ProcessChangeItem>(); 979 final ArrayList<ProcessChangeItem> mAvailProcessChanges 980 = new ArrayList<ProcessChangeItem>(); 981 982 /** 983 * Runtime CPU use collection thread. This object's lock is used to 984 * protect all related state. 985 */ 986 final Thread mProcessCpuThread; 987 988 /** 989 * Used to collect process stats when showing not responding dialog. 990 * Protected by mProcessCpuThread. 991 */ 992 final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker( 993 MONITOR_THREAD_CPU_USAGE); 994 final AtomicLong mLastCpuTime = new AtomicLong(0); 995 final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true); 996 997 long mLastWriteTime = 0; 998 999 /** 1000 * Used to retain an update lock when the foreground activity is in 1001 * immersive mode. 1002 */ 1003 final UpdateLock mUpdateLock = new UpdateLock("immersive"); 1004 1005 /** 1006 * Set to true after the system has finished booting. 1007 */ 1008 boolean mBooted = false; 1009 1010 int mProcessLimit = ProcessList.MAX_CACHED_APPS; 1011 int mProcessLimitOverride = -1; 1012 1013 WindowManagerService mWindowManager; 1014 1015 final ActivityThread mSystemThread; 1016 1017 int mCurrentUserId = 0; 1018 private UserManagerService mUserManager; 1019 1020 private final class AppDeathRecipient implements IBinder.DeathRecipient { 1021 final ProcessRecord mApp; 1022 final int mPid; 1023 final IApplicationThread mAppThread; 1024 1025 AppDeathRecipient(ProcessRecord app, int pid, 1026 IApplicationThread thread) { 1027 if (localLOGV) Slog.v( 1028 TAG, "New death recipient " + this 1029 + " for thread " + thread.asBinder()); 1030 mApp = app; 1031 mPid = pid; 1032 mAppThread = thread; 1033 } 1034 1035 @Override 1036 public void binderDied() { 1037 if (localLOGV) Slog.v( 1038 TAG, "Death received in " + this 1039 + " for thread " + mAppThread.asBinder()); 1040 synchronized(ActivityManagerService.this) { 1041 appDiedLocked(mApp, mPid, mAppThread); 1042 } 1043 } 1044 } 1045 1046 static final int SHOW_ERROR_MSG = 1; 1047 static final int SHOW_NOT_RESPONDING_MSG = 2; 1048 static final int SHOW_FACTORY_ERROR_MSG = 3; 1049 static final int UPDATE_CONFIGURATION_MSG = 4; 1050 static final int GC_BACKGROUND_PROCESSES_MSG = 5; 1051 static final int WAIT_FOR_DEBUGGER_MSG = 6; 1052 static final int SERVICE_TIMEOUT_MSG = 12; 1053 static final int UPDATE_TIME_ZONE = 13; 1054 static final int SHOW_UID_ERROR_MSG = 14; 1055 static final int IM_FEELING_LUCKY_MSG = 15; 1056 static final int PROC_START_TIMEOUT_MSG = 20; 1057 static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21; 1058 static final int KILL_APPLICATION_MSG = 22; 1059 static final int FINALIZE_PENDING_INTENT_MSG = 23; 1060 static final int POST_HEAVY_NOTIFICATION_MSG = 24; 1061 static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25; 1062 static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26; 1063 static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27; 1064 static final int CLEAR_DNS_CACHE_MSG = 28; 1065 static final int UPDATE_HTTP_PROXY_MSG = 29; 1066 static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30; 1067 static final int DISPATCH_PROCESSES_CHANGED = 31; 1068 static final int DISPATCH_PROCESS_DIED = 32; 1069 static final int REPORT_MEM_USAGE_MSG = 33; 1070 static final int REPORT_USER_SWITCH_MSG = 34; 1071 static final int CONTINUE_USER_SWITCH_MSG = 35; 1072 static final int USER_SWITCH_TIMEOUT_MSG = 36; 1073 static final int IMMERSIVE_MODE_LOCK_MSG = 37; 1074 static final int PERSIST_URI_GRANTS_MSG = 38; 1075 static final int REQUEST_ALL_PSS_MSG = 39; 1076 static final int START_RELATED_USERS_MSG = 40; 1077 static final int UPDATE_TIME = 41; 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 case UPDATE_TIME: { 1698 synchronized (ActivityManagerService.this) { 1699 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1700 ProcessRecord r = mLruProcesses.get(i); 1701 if (r.thread != null) { 1702 try { 1703 r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true); 1704 } catch (RemoteException ex) { 1705 Slog.w(TAG, "Failed to update preferences for: " + r.info.processName); 1706 } 1707 } 1708 } 1709 } 1710 break; 1711 } 1712 } 1713 } 1714 }; 1715 1716 static final int COLLECT_PSS_BG_MSG = 1; 1717 1718 final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) { 1719 @Override 1720 public void handleMessage(Message msg) { 1721 switch (msg.what) { 1722 case COLLECT_PSS_BG_MSG: { 1723 int i=0, num=0; 1724 long start = SystemClock.uptimeMillis(); 1725 long[] tmp = new long[1]; 1726 do { 1727 ProcessRecord proc; 1728 int procState; 1729 int pid; 1730 synchronized (ActivityManagerService.this) { 1731 if (i >= mPendingPssProcesses.size()) { 1732 if (DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num + " of " + i 1733 + " processes in " + (SystemClock.uptimeMillis()-start) + "ms"); 1734 mPendingPssProcesses.clear(); 1735 return; 1736 } 1737 proc = mPendingPssProcesses.get(i); 1738 procState = proc.pssProcState; 1739 if (proc.thread != null && procState == proc.setProcState) { 1740 pid = proc.pid; 1741 } else { 1742 proc = null; 1743 pid = 0; 1744 } 1745 i++; 1746 } 1747 if (proc != null) { 1748 long pss = Debug.getPss(pid, tmp); 1749 synchronized (ActivityManagerService.this) { 1750 if (proc.thread != null && proc.setProcState == procState 1751 && proc.pid == pid) { 1752 num++; 1753 proc.lastPssTime = SystemClock.uptimeMillis(); 1754 proc.baseProcessTracker.addPss(pss, tmp[0], true, proc.pkgList); 1755 if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString() 1756 + ": " + pss + " lastPss=" + proc.lastPss 1757 + " state=" + ProcessList.makeProcStateString(procState)); 1758 if (proc.initialIdlePss == 0) { 1759 proc.initialIdlePss = pss; 1760 } 1761 proc.lastPss = pss; 1762 if (procState >= ActivityManager.PROCESS_STATE_HOME) { 1763 proc.lastCachedPss = pss; 1764 } 1765 } 1766 } 1767 } 1768 } while (true); 1769 } 1770 } 1771 } 1772 }; 1773 1774 public void setSystemProcess() { 1775 try { 1776 ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true); 1777 ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats); 1778 ServiceManager.addService("meminfo", new MemBinder(this)); 1779 ServiceManager.addService("gfxinfo", new GraphicsBinder(this)); 1780 ServiceManager.addService("dbinfo", new DbBinder(this)); 1781 if (MONITOR_CPU_USAGE) { 1782 ServiceManager.addService("cpuinfo", new CpuBinder(this)); 1783 } 1784 ServiceManager.addService("permission", new PermissionController(this)); 1785 1786 ApplicationInfo info = mContext.getPackageManager().getApplicationInfo( 1787 "android", STOCK_PM_FLAGS); 1788 mSystemThread.installSystemApplicationInfo(info); 1789 1790 synchronized (this) { 1791 ProcessRecord app = newProcessRecordLocked(info, info.processName, false); 1792 app.persistent = true; 1793 app.pid = MY_PID; 1794 app.maxAdj = ProcessList.SYSTEM_ADJ; 1795 app.makeActive(mSystemThread.getApplicationThread(), mProcessStats); 1796 mProcessNames.put(app.processName, app.uid, app); 1797 synchronized (mPidsSelfLocked) { 1798 mPidsSelfLocked.put(app.pid, app); 1799 } 1800 updateLruProcessLocked(app, false, null); 1801 updateOomAdjLocked(); 1802 } 1803 } catch (PackageManager.NameNotFoundException e) { 1804 throw new RuntimeException( 1805 "Unable to find android system package", e); 1806 } 1807 } 1808 1809 public void setWindowManager(WindowManagerService wm) { 1810 mWindowManager = wm; 1811 mStackSupervisor.setWindowManager(wm); 1812 } 1813 1814 public void startObservingNativeCrashes() { 1815 final NativeCrashListener ncl = new NativeCrashListener(this); 1816 ncl.start(); 1817 } 1818 1819 public IAppOpsService getAppOpsService() { 1820 return mAppOpsService; 1821 } 1822 1823 static class MemBinder extends Binder { 1824 ActivityManagerService mActivityManagerService; 1825 MemBinder(ActivityManagerService activityManagerService) { 1826 mActivityManagerService = activityManagerService; 1827 } 1828 1829 @Override 1830 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1831 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1832 != PackageManager.PERMISSION_GRANTED) { 1833 pw.println("Permission Denial: can't dump meminfo from from pid=" 1834 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1835 + " without permission " + android.Manifest.permission.DUMP); 1836 return; 1837 } 1838 1839 mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, " ", args, false, null); 1840 } 1841 } 1842 1843 static class GraphicsBinder extends Binder { 1844 ActivityManagerService mActivityManagerService; 1845 GraphicsBinder(ActivityManagerService activityManagerService) { 1846 mActivityManagerService = activityManagerService; 1847 } 1848 1849 @Override 1850 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1851 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1852 != PackageManager.PERMISSION_GRANTED) { 1853 pw.println("Permission Denial: can't dump gfxinfo from from pid=" 1854 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1855 + " without permission " + android.Manifest.permission.DUMP); 1856 return; 1857 } 1858 1859 mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args); 1860 } 1861 } 1862 1863 static class DbBinder extends Binder { 1864 ActivityManagerService mActivityManagerService; 1865 DbBinder(ActivityManagerService activityManagerService) { 1866 mActivityManagerService = activityManagerService; 1867 } 1868 1869 @Override 1870 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1871 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1872 != PackageManager.PERMISSION_GRANTED) { 1873 pw.println("Permission Denial: can't dump dbinfo from from pid=" 1874 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1875 + " without permission " + android.Manifest.permission.DUMP); 1876 return; 1877 } 1878 1879 mActivityManagerService.dumpDbInfo(fd, pw, args); 1880 } 1881 } 1882 1883 static class CpuBinder extends Binder { 1884 ActivityManagerService mActivityManagerService; 1885 CpuBinder(ActivityManagerService activityManagerService) { 1886 mActivityManagerService = activityManagerService; 1887 } 1888 1889 @Override 1890 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1891 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1892 != PackageManager.PERMISSION_GRANTED) { 1893 pw.println("Permission Denial: can't dump cpuinfo from from pid=" 1894 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1895 + " without permission " + android.Manifest.permission.DUMP); 1896 return; 1897 } 1898 1899 synchronized (mActivityManagerService.mProcessCpuThread) { 1900 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad()); 1901 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState( 1902 SystemClock.uptimeMillis())); 1903 } 1904 } 1905 } 1906 1907 public static final class Lifecycle extends SystemService { 1908 private final ActivityManagerService mService; 1909 1910 public Lifecycle(Context context) { 1911 super(context); 1912 mService = new ActivityManagerService(context); 1913 } 1914 1915 @Override 1916 public void onStart() { 1917 mService.start(); 1918 } 1919 1920 public ActivityManagerService getService() { 1921 return mService; 1922 } 1923 } 1924 1925 // Note: This method is invoked on the main thread but may need to attach various 1926 // handlers to other threads. So take care to be explicit about the looper. 1927 public ActivityManagerService(Context systemContext) { 1928 mContext = systemContext; 1929 mFactoryTest = FactoryTest.getMode(); 1930 mSystemThread = ActivityThread.currentActivityThread(); 1931 1932 Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass()); 1933 1934 mHandlerThread = new ServiceThread(TAG, 1935 android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/); 1936 mHandlerThread.start(); 1937 mHandler = new MainHandler(mHandlerThread.getLooper()); 1938 1939 mFgBroadcastQueue = new BroadcastQueue(this, mHandler, 1940 "foreground", BROADCAST_FG_TIMEOUT, false); 1941 mBgBroadcastQueue = new BroadcastQueue(this, mHandler, 1942 "background", BROADCAST_BG_TIMEOUT, true); 1943 mBroadcastQueues[0] = mFgBroadcastQueue; 1944 mBroadcastQueues[1] = mBgBroadcastQueue; 1945 1946 mServices = new ActiveServices(this); 1947 mProviderMap = new ProviderMap(this); 1948 1949 // TODO: Move creation of battery stats service outside of activity manager service. 1950 File dataDir = Environment.getDataDirectory(); 1951 File systemDir = new File(dataDir, "system"); 1952 systemDir.mkdirs(); 1953 mBatteryStatsService = new BatteryStatsService(new File( 1954 systemDir, "batterystats.bin").toString(), mHandler); 1955 mBatteryStatsService.getActiveStatistics().readLocked(); 1956 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 1957 mOnBattery = DEBUG_POWER ? true 1958 : mBatteryStatsService.getActiveStatistics().getIsOnBattery(); 1959 mBatteryStatsService.getActiveStatistics().setCallback(this); 1960 1961 mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats")); 1962 1963 mUsageStatsService = new UsageStatsService(new File(systemDir, "usagestats").toString()); 1964 mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler); 1965 1966 mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml")); 1967 1968 // User 0 is the first and only user that runs at boot. 1969 mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true)); 1970 mUserLru.add(Integer.valueOf(0)); 1971 updateStartedUserArrayLocked(); 1972 1973 GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version", 1974 ConfigurationInfo.GL_ES_VERSION_UNDEFINED); 1975 1976 mConfiguration.setToDefaults(); 1977 mConfiguration.setLocale(Locale.getDefault()); 1978 1979 mConfigurationSeq = mConfiguration.seq = 1; 1980 mProcessCpuTracker.init(); 1981 1982 mCompatModePackages = new CompatModePackages(this, systemDir, mHandler); 1983 mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler); 1984 mStackSupervisor = new ActivityStackSupervisor(this); 1985 1986 mProcessCpuThread = new Thread("CpuTracker") { 1987 @Override 1988 public void run() { 1989 while (true) { 1990 try { 1991 try { 1992 synchronized(this) { 1993 final long now = SystemClock.uptimeMillis(); 1994 long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now; 1995 long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now; 1996 //Slog.i(TAG, "Cpu delay=" + nextCpuDelay 1997 // + ", write delay=" + nextWriteDelay); 1998 if (nextWriteDelay < nextCpuDelay) { 1999 nextCpuDelay = nextWriteDelay; 2000 } 2001 if (nextCpuDelay > 0) { 2002 mProcessCpuMutexFree.set(true); 2003 this.wait(nextCpuDelay); 2004 } 2005 } 2006 } catch (InterruptedException e) { 2007 } 2008 updateCpuStatsNow(); 2009 } catch (Exception e) { 2010 Slog.e(TAG, "Unexpected exception collecting process stats", e); 2011 } 2012 } 2013 } 2014 }; 2015 2016 Watchdog.getInstance().addMonitor(this); 2017 Watchdog.getInstance().addThread(mHandler); 2018 } 2019 2020 private void start() { 2021 mProcessCpuThread.start(); 2022 2023 mBatteryStatsService.publish(mContext); 2024 mUsageStatsService.publish(mContext); 2025 mAppOpsService.publish(mContext); 2026 startRunning(null, null, null, null); 2027 } 2028 2029 @Override 2030 public boolean onTransact(int code, Parcel data, Parcel reply, int flags) 2031 throws RemoteException { 2032 if (code == SYSPROPS_TRANSACTION) { 2033 // We need to tell all apps about the system property change. 2034 ArrayList<IBinder> procs = new ArrayList<IBinder>(); 2035 synchronized(this) { 2036 final int NP = mProcessNames.getMap().size(); 2037 for (int ip=0; ip<NP; ip++) { 2038 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 2039 final int NA = apps.size(); 2040 for (int ia=0; ia<NA; ia++) { 2041 ProcessRecord app = apps.valueAt(ia); 2042 if (app.thread != null) { 2043 procs.add(app.thread.asBinder()); 2044 } 2045 } 2046 } 2047 } 2048 2049 int N = procs.size(); 2050 for (int i=0; i<N; i++) { 2051 Parcel data2 = Parcel.obtain(); 2052 try { 2053 procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0); 2054 } catch (RemoteException e) { 2055 } 2056 data2.recycle(); 2057 } 2058 } 2059 try { 2060 return super.onTransact(code, data, reply, flags); 2061 } catch (RuntimeException e) { 2062 // The activity manager only throws security exceptions, so let's 2063 // log all others. 2064 if (!(e instanceof SecurityException)) { 2065 Slog.wtf(TAG, "Activity Manager Crash", e); 2066 } 2067 throw e; 2068 } 2069 } 2070 2071 void updateCpuStats() { 2072 final long now = SystemClock.uptimeMillis(); 2073 if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) { 2074 return; 2075 } 2076 if (mProcessCpuMutexFree.compareAndSet(true, false)) { 2077 synchronized (mProcessCpuThread) { 2078 mProcessCpuThread.notify(); 2079 } 2080 } 2081 } 2082 2083 void updateCpuStatsNow() { 2084 synchronized (mProcessCpuThread) { 2085 mProcessCpuMutexFree.set(false); 2086 final long now = SystemClock.uptimeMillis(); 2087 boolean haveNewCpuStats = false; 2088 2089 if (MONITOR_CPU_USAGE && 2090 mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) { 2091 mLastCpuTime.set(now); 2092 haveNewCpuStats = true; 2093 mProcessCpuTracker.update(); 2094 //Slog.i(TAG, mProcessCpu.printCurrentState()); 2095 //Slog.i(TAG, "Total CPU usage: " 2096 // + mProcessCpu.getTotalCpuPercent() + "%"); 2097 2098 // Slog the cpu usage if the property is set. 2099 if ("true".equals(SystemProperties.get("events.cpu"))) { 2100 int user = mProcessCpuTracker.getLastUserTime(); 2101 int system = mProcessCpuTracker.getLastSystemTime(); 2102 int iowait = mProcessCpuTracker.getLastIoWaitTime(); 2103 int irq = mProcessCpuTracker.getLastIrqTime(); 2104 int softIrq = mProcessCpuTracker.getLastSoftIrqTime(); 2105 int idle = mProcessCpuTracker.getLastIdleTime(); 2106 2107 int total = user + system + iowait + irq + softIrq + idle; 2108 if (total == 0) total = 1; 2109 2110 EventLog.writeEvent(EventLogTags.CPU, 2111 ((user+system+iowait+irq+softIrq) * 100) / total, 2112 (user * 100) / total, 2113 (system * 100) / total, 2114 (iowait * 100) / total, 2115 (irq * 100) / total, 2116 (softIrq * 100) / total); 2117 } 2118 } 2119 2120 long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes(); 2121 final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics(); 2122 synchronized(bstats) { 2123 synchronized(mPidsSelfLocked) { 2124 if (haveNewCpuStats) { 2125 if (mOnBattery) { 2126 int perc = bstats.startAddingCpuLocked(); 2127 int totalUTime = 0; 2128 int totalSTime = 0; 2129 final int N = mProcessCpuTracker.countStats(); 2130 for (int i=0; i<N; i++) { 2131 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 2132 if (!st.working) { 2133 continue; 2134 } 2135 ProcessRecord pr = mPidsSelfLocked.get(st.pid); 2136 int otherUTime = (st.rel_utime*perc)/100; 2137 int otherSTime = (st.rel_stime*perc)/100; 2138 totalUTime += otherUTime; 2139 totalSTime += otherSTime; 2140 if (pr != null) { 2141 BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats; 2142 if (ps == null || !ps.isActive()) { 2143 pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked( 2144 pr.info.uid, pr.processName); 2145 } 2146 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 2147 st.rel_stime-otherSTime); 2148 ps.addSpeedStepTimes(cpuSpeedTimes); 2149 pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10; 2150 } else { 2151 BatteryStatsImpl.Uid.Proc ps = st.batteryStats; 2152 if (ps == null || !ps.isActive()) { 2153 st.batteryStats = ps = bstats.getProcessStatsLocked( 2154 bstats.mapUid(st.uid), st.name); 2155 } 2156 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 2157 st.rel_stime-otherSTime); 2158 ps.addSpeedStepTimes(cpuSpeedTimes); 2159 } 2160 } 2161 bstats.finishAddingCpuLocked(perc, totalUTime, 2162 totalSTime, cpuSpeedTimes); 2163 } 2164 } 2165 } 2166 2167 if (mLastWriteTime < (now-BATTERY_STATS_TIME)) { 2168 mLastWriteTime = now; 2169 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 2170 } 2171 } 2172 } 2173 } 2174 2175 @Override 2176 public void batteryNeedsCpuUpdate() { 2177 updateCpuStatsNow(); 2178 } 2179 2180 @Override 2181 public void batteryPowerChanged(boolean onBattery) { 2182 // When plugging in, update the CPU stats first before changing 2183 // the plug state. 2184 updateCpuStatsNow(); 2185 synchronized (this) { 2186 synchronized(mPidsSelfLocked) { 2187 mOnBattery = DEBUG_POWER ? true : onBattery; 2188 } 2189 } 2190 } 2191 2192 /** 2193 * Initialize the application bind args. These are passed to each 2194 * process when the bindApplication() IPC is sent to the process. They're 2195 * lazily setup to make sure the services are running when they're asked for. 2196 */ 2197 private HashMap<String, IBinder> getCommonServicesLocked() { 2198 if (mAppBindArgs == null) { 2199 mAppBindArgs = new HashMap<String, IBinder>(); 2200 2201 // Setup the application init args 2202 mAppBindArgs.put("package", ServiceManager.getService("package")); 2203 mAppBindArgs.put("window", ServiceManager.getService("window")); 2204 mAppBindArgs.put(Context.ALARM_SERVICE, 2205 ServiceManager.getService(Context.ALARM_SERVICE)); 2206 } 2207 return mAppBindArgs; 2208 } 2209 2210 final void setFocusedActivityLocked(ActivityRecord r) { 2211 if (mFocusedActivity != r) { 2212 if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r); 2213 mFocusedActivity = r; 2214 mStackSupervisor.setFocusedStack(r); 2215 if (r != null) { 2216 mWindowManager.setFocusedApp(r.appToken, true); 2217 } 2218 applyUpdateLockStateLocked(r); 2219 } 2220 } 2221 2222 @Override 2223 public void setFocusedStack(int stackId) { 2224 if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId); 2225 synchronized (ActivityManagerService.this) { 2226 ActivityStack stack = mStackSupervisor.getStack(stackId); 2227 if (stack != null) { 2228 ActivityRecord r = stack.topRunningActivityLocked(null); 2229 if (r != null) { 2230 setFocusedActivityLocked(r); 2231 } 2232 } 2233 } 2234 } 2235 2236 @Override 2237 public void notifyActivityDrawn(IBinder token) { 2238 if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token); 2239 synchronized (this) { 2240 ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token); 2241 if (r != null) { 2242 r.task.stack.notifyActivityDrawnLocked(r); 2243 } 2244 } 2245 } 2246 2247 final void applyUpdateLockStateLocked(ActivityRecord r) { 2248 // Modifications to the UpdateLock state are done on our handler, outside 2249 // the activity manager's locks. The new state is determined based on the 2250 // state *now* of the relevant activity record. The object is passed to 2251 // the handler solely for logging detail, not to be consulted/modified. 2252 final boolean nextState = r != null && r.immersive; 2253 mHandler.sendMessage( 2254 mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r)); 2255 } 2256 2257 final void showAskCompatModeDialogLocked(ActivityRecord r) { 2258 Message msg = Message.obtain(); 2259 msg.what = SHOW_COMPAT_MODE_DIALOG_MSG; 2260 msg.obj = r.task.askedCompatMode ? null : r; 2261 mHandler.sendMessage(msg); 2262 } 2263 2264 private final int updateLruProcessInternalLocked(ProcessRecord app, long now, int index, 2265 String what, Object obj, ProcessRecord srcApp) { 2266 app.lastActivityTime = now; 2267 2268 if (app.activities.size() > 0) { 2269 // Don't want to touch dependent processes that are hosting activities. 2270 return index; 2271 } 2272 2273 int lrui = mLruProcesses.lastIndexOf(app); 2274 if (lrui < 0) { 2275 Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: " 2276 + what + " " + obj + " from " + srcApp); 2277 return index; 2278 } 2279 2280 if (lrui >= index) { 2281 // Don't want to cause this to move dependent processes *back* in the 2282 // list as if they were less frequently used. 2283 return index; 2284 } 2285 2286 if (lrui >= mLruProcessActivityStart) { 2287 // Don't want to touch dependent processes that are hosting activities. 2288 return index; 2289 } 2290 2291 mLruProcesses.remove(lrui); 2292 if (index > 0) { 2293 index--; 2294 } 2295 if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index 2296 + " in LRU list: " + app); 2297 mLruProcesses.add(index, app); 2298 return index; 2299 } 2300 2301 final void removeLruProcessLocked(ProcessRecord app) { 2302 int lrui = mLruProcesses.lastIndexOf(app); 2303 if (lrui >= 0) { 2304 if (lrui <= mLruProcessActivityStart) { 2305 mLruProcessActivityStart--; 2306 } 2307 if (lrui <= mLruProcessServiceStart) { 2308 mLruProcessServiceStart--; 2309 } 2310 mLruProcesses.remove(lrui); 2311 } 2312 } 2313 2314 final void updateLruProcessLocked(ProcessRecord app, boolean activityChange, 2315 ProcessRecord client) { 2316 final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities; 2317 final boolean hasService = false; // not impl yet. app.services.size() > 0; 2318 if (!activityChange && hasActivity) { 2319 // The process has activties, so we are only going to allow activity-based 2320 // adjustments move it. It should be kept in the front of the list with other 2321 // processes that have activities, and we don't want those to change their 2322 // order except due to activity operations. 2323 return; 2324 } 2325 2326 mLruSeq++; 2327 final long now = SystemClock.uptimeMillis(); 2328 app.lastActivityTime = now; 2329 2330 // First a quick reject: if the app is already at the position we will 2331 // put it, then there is nothing to do. 2332 if (hasActivity) { 2333 final int N = mLruProcesses.size(); 2334 if (N > 0 && mLruProcesses.get(N-1) == app) { 2335 if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app); 2336 return; 2337 } 2338 } else { 2339 if (mLruProcessServiceStart > 0 2340 && mLruProcesses.get(mLruProcessServiceStart-1) == app) { 2341 if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app); 2342 return; 2343 } 2344 } 2345 2346 int lrui = mLruProcesses.lastIndexOf(app); 2347 2348 if (app.persistent && lrui >= 0) { 2349 // We don't care about the position of persistent processes, as long as 2350 // they are in the list. 2351 if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app); 2352 return; 2353 } 2354 2355 /* In progress: compute new position first, so we can avoid doing work 2356 if the process is not actually going to move. Not yet working. 2357 int addIndex; 2358 int nextIndex; 2359 boolean inActivity = false, inService = false; 2360 if (hasActivity) { 2361 // Process has activities, put it at the very tipsy-top. 2362 addIndex = mLruProcesses.size(); 2363 nextIndex = mLruProcessServiceStart; 2364 inActivity = true; 2365 } else if (hasService) { 2366 // Process has services, put it at the top of the service list. 2367 addIndex = mLruProcessActivityStart; 2368 nextIndex = mLruProcessServiceStart; 2369 inActivity = true; 2370 inService = true; 2371 } else { 2372 // Process not otherwise of interest, it goes to the top of the non-service area. 2373 addIndex = mLruProcessServiceStart; 2374 if (client != null) { 2375 int clientIndex = mLruProcesses.lastIndexOf(client); 2376 if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating " 2377 + app); 2378 if (clientIndex >= 0 && addIndex > clientIndex) { 2379 addIndex = clientIndex; 2380 } 2381 } 2382 nextIndex = addIndex > 0 ? addIndex-1 : addIndex; 2383 } 2384 2385 Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act=" 2386 + mLruProcessActivityStart + "): " + app); 2387 */ 2388 2389 if (lrui >= 0) { 2390 if (lrui < mLruProcessActivityStart) { 2391 mLruProcessActivityStart--; 2392 } 2393 if (lrui < mLruProcessServiceStart) { 2394 mLruProcessServiceStart--; 2395 } 2396 /* 2397 if (addIndex > lrui) { 2398 addIndex--; 2399 } 2400 if (nextIndex > lrui) { 2401 nextIndex--; 2402 } 2403 */ 2404 mLruProcesses.remove(lrui); 2405 } 2406 2407 /* 2408 mLruProcesses.add(addIndex, app); 2409 if (inActivity) { 2410 mLruProcessActivityStart++; 2411 } 2412 if (inService) { 2413 mLruProcessActivityStart++; 2414 } 2415 */ 2416 2417 int nextIndex; 2418 if (hasActivity) { 2419 final int N = mLruProcesses.size(); 2420 if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) { 2421 // Process doesn't have activities, but has clients with 2422 // activities... move it up, but one below the top (the top 2423 // should always have a real activity). 2424 if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app); 2425 mLruProcesses.add(N-1, app); 2426 // To keep it from spamming the LRU list (by making a bunch of clients), 2427 // we will push down any other entries owned by the app. 2428 final int uid = app.info.uid; 2429 for (int i=N-2; i>mLruProcessActivityStart; i--) { 2430 ProcessRecord subProc = mLruProcesses.get(i); 2431 if (subProc.info.uid == uid) { 2432 // We want to push this one down the list. If the process after 2433 // it is for the same uid, however, don't do so, because we don't 2434 // want them internally to be re-ordered. 2435 if (mLruProcesses.get(i-1).info.uid != uid) { 2436 if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i 2437 + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1)); 2438 ProcessRecord tmp = mLruProcesses.get(i); 2439 mLruProcesses.set(i, mLruProcesses.get(i-1)); 2440 mLruProcesses.set(i-1, tmp); 2441 i--; 2442 } 2443 } else { 2444 // A gap, we can stop here. 2445 break; 2446 } 2447 } 2448 } else { 2449 // Process has activities, put it at the very tipsy-top. 2450 if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app); 2451 mLruProcesses.add(app); 2452 } 2453 nextIndex = mLruProcessServiceStart; 2454 } else if (hasService) { 2455 // Process has services, put it at the top of the service list. 2456 if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app); 2457 mLruProcesses.add(mLruProcessActivityStart, app); 2458 nextIndex = mLruProcessServiceStart; 2459 mLruProcessActivityStart++; 2460 } else { 2461 // Process not otherwise of interest, it goes to the top of the non-service area. 2462 int index = mLruProcessServiceStart; 2463 if (client != null) { 2464 // If there is a client, don't allow the process to be moved up higher 2465 // in the list than that client. 2466 int clientIndex = mLruProcesses.lastIndexOf(client); 2467 if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client 2468 + " when updating " + app); 2469 if (clientIndex <= lrui) { 2470 // Don't allow the client index restriction to push it down farther in the 2471 // list than it already is. 2472 clientIndex = lrui; 2473 } 2474 if (clientIndex >= 0 && index > clientIndex) { 2475 index = clientIndex; 2476 } 2477 } 2478 if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app); 2479 mLruProcesses.add(index, app); 2480 nextIndex = index-1; 2481 mLruProcessActivityStart++; 2482 mLruProcessServiceStart++; 2483 } 2484 2485 // If the app is currently using a content provider or service, 2486 // bump those processes as well. 2487 for (int j=app.connections.size()-1; j>=0; j--) { 2488 ConnectionRecord cr = app.connections.valueAt(j); 2489 if (cr.binding != null && !cr.serviceDead && cr.binding.service != null 2490 && cr.binding.service.app != null 2491 && cr.binding.service.app.lruSeq != mLruSeq 2492 && !cr.binding.service.app.persistent) { 2493 nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex, 2494 "service connection", cr, app); 2495 } 2496 } 2497 for (int j=app.conProviders.size()-1; j>=0; j--) { 2498 ContentProviderRecord cpr = app.conProviders.get(j).provider; 2499 if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) { 2500 nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex, 2501 "provider reference", cpr, app); 2502 } 2503 } 2504 } 2505 2506 final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) { 2507 if (uid == Process.SYSTEM_UID) { 2508 // The system gets to run in any process. If there are multiple 2509 // processes with the same uid, just pick the first (this 2510 // should never happen). 2511 SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName); 2512 if (procs == null) return null; 2513 final int N = procs.size(); 2514 for (int i = 0; i < N; i++) { 2515 if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i); 2516 } 2517 } 2518 ProcessRecord proc = mProcessNames.get(processName, uid); 2519 if (false && proc != null && !keepIfLarge 2520 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY 2521 && proc.lastCachedPss >= 4000) { 2522 // Turn this condition on to cause killing to happen regularly, for testing. 2523 if (proc.baseProcessTracker != null) { 2524 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss); 2525 } 2526 killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss) 2527 + "k from cached"); 2528 } else if (proc != null && !keepIfLarge 2529 && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL 2530 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) { 2531 if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss); 2532 if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) { 2533 if (proc.baseProcessTracker != null) { 2534 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss); 2535 } 2536 killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss) 2537 + "k from cached"); 2538 } 2539 } 2540 return proc; 2541 } 2542 2543 void ensurePackageDexOpt(String packageName) { 2544 IPackageManager pm = AppGlobals.getPackageManager(); 2545 try { 2546 if (pm.performDexOpt(packageName)) { 2547 mDidDexOpt = true; 2548 } 2549 } catch (RemoteException e) { 2550 } 2551 } 2552 2553 boolean isNextTransitionForward() { 2554 int transit = mWindowManager.getPendingAppTransition(); 2555 return transit == AppTransition.TRANSIT_ACTIVITY_OPEN 2556 || transit == AppTransition.TRANSIT_TASK_OPEN 2557 || transit == AppTransition.TRANSIT_TASK_TO_FRONT; 2558 } 2559 2560 final ProcessRecord startProcessLocked(String processName, 2561 ApplicationInfo info, boolean knownToBeDead, int intentFlags, 2562 String hostingType, ComponentName hostingName, boolean allowWhileBooting, 2563 boolean isolated, boolean keepIfLarge) { 2564 ProcessRecord app; 2565 if (!isolated) { 2566 app = getProcessRecordLocked(processName, info.uid, keepIfLarge); 2567 } else { 2568 // If this is an isolated process, it can't re-use an existing process. 2569 app = null; 2570 } 2571 // We don't have to do anything more if: 2572 // (1) There is an existing application record; and 2573 // (2) The caller doesn't think it is dead, OR there is no thread 2574 // object attached to it so we know it couldn't have crashed; and 2575 // (3) There is a pid assigned to it, so it is either starting or 2576 // already running. 2577 if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName 2578 + " app=" + app + " knownToBeDead=" + knownToBeDead 2579 + " thread=" + (app != null ? app.thread : null) 2580 + " pid=" + (app != null ? app.pid : -1)); 2581 if (app != null && app.pid > 0) { 2582 if (!knownToBeDead || app.thread == null) { 2583 // We already have the app running, or are waiting for it to 2584 // come up (we have a pid but not yet its thread), so keep it. 2585 if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app); 2586 // If this is a new package in the process, add the package to the list 2587 app.addPackage(info.packageName, mProcessStats); 2588 return app; 2589 } 2590 2591 // An application record is attached to a previous process, 2592 // clean it up now. 2593 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app); 2594 handleAppDiedLocked(app, true, true); 2595 } 2596 2597 String hostingNameStr = hostingName != null 2598 ? hostingName.flattenToShortString() : null; 2599 2600 if (!isolated) { 2601 if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) { 2602 // If we are in the background, then check to see if this process 2603 // is bad. If so, we will just silently fail. 2604 if (mBadProcesses.get(info.processName, info.uid) != null) { 2605 if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid 2606 + "/" + info.processName); 2607 return null; 2608 } 2609 } else { 2610 // When the user is explicitly starting a process, then clear its 2611 // crash count so that we won't make it bad until they see at 2612 // least one crash dialog again, and make the process good again 2613 // if it had been bad. 2614 if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid 2615 + "/" + info.processName); 2616 mProcessCrashTimes.remove(info.processName, info.uid); 2617 if (mBadProcesses.get(info.processName, info.uid) != null) { 2618 EventLog.writeEvent(EventLogTags.AM_PROC_GOOD, 2619 UserHandle.getUserId(info.uid), info.uid, 2620 info.processName); 2621 mBadProcesses.remove(info.processName, info.uid); 2622 if (app != null) { 2623 app.bad = false; 2624 } 2625 } 2626 } 2627 } 2628 2629 if (app == null) { 2630 app = newProcessRecordLocked(info, processName, isolated); 2631 if (app == null) { 2632 Slog.w(TAG, "Failed making new process record for " 2633 + processName + "/" + info.uid + " isolated=" + isolated); 2634 return null; 2635 } 2636 mProcessNames.put(processName, app.uid, app); 2637 if (isolated) { 2638 mIsolatedProcesses.put(app.uid, app); 2639 } 2640 } else { 2641 // If this is a new package in the process, add the package to the list 2642 app.addPackage(info.packageName, mProcessStats); 2643 } 2644 2645 // If the system is not ready yet, then hold off on starting this 2646 // process until it is. 2647 if (!mProcessesReady 2648 && !isAllowedWhileBooting(info) 2649 && !allowWhileBooting) { 2650 if (!mProcessesOnHold.contains(app)) { 2651 mProcessesOnHold.add(app); 2652 } 2653 if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app); 2654 return app; 2655 } 2656 2657 startProcessLocked(app, hostingType, hostingNameStr); 2658 return (app.pid != 0) ? app : null; 2659 } 2660 2661 boolean isAllowedWhileBooting(ApplicationInfo ai) { 2662 return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0; 2663 } 2664 2665 private final void startProcessLocked(ProcessRecord app, 2666 String hostingType, String hostingNameStr) { 2667 if (app.pid > 0 && app.pid != MY_PID) { 2668 synchronized (mPidsSelfLocked) { 2669 mPidsSelfLocked.remove(app.pid); 2670 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 2671 } 2672 app.setPid(0); 2673 } 2674 2675 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 2676 "startProcessLocked removing on hold: " + app); 2677 mProcessesOnHold.remove(app); 2678 2679 updateCpuStats(); 2680 2681 try { 2682 int uid = app.uid; 2683 2684 int[] gids = null; 2685 int mountExternal = Zygote.MOUNT_EXTERNAL_NONE; 2686 if (!app.isolated) { 2687 int[] permGids = null; 2688 try { 2689 final PackageManager pm = mContext.getPackageManager(); 2690 permGids = pm.getPackageGids(app.info.packageName); 2691 2692 if (Environment.isExternalStorageEmulated()) { 2693 if (pm.checkPermission( 2694 android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE, 2695 app.info.packageName) == PERMISSION_GRANTED) { 2696 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL; 2697 } else { 2698 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER; 2699 } 2700 } 2701 } catch (PackageManager.NameNotFoundException e) { 2702 Slog.w(TAG, "Unable to retrieve gids", e); 2703 } 2704 2705 /* 2706 * Add shared application GID so applications can share some 2707 * resources like shared libraries 2708 */ 2709 if (permGids == null) { 2710 gids = new int[1]; 2711 } else { 2712 gids = new int[permGids.length + 1]; 2713 System.arraycopy(permGids, 0, gids, 1, permGids.length); 2714 } 2715 gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid)); 2716 } 2717 if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) { 2718 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL 2719 && mTopComponent != null 2720 && app.processName.equals(mTopComponent.getPackageName())) { 2721 uid = 0; 2722 } 2723 if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL 2724 && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) { 2725 uid = 0; 2726 } 2727 } 2728 int debugFlags = 0; 2729 if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) { 2730 debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER; 2731 // Also turn on CheckJNI for debuggable apps. It's quite 2732 // awkward to turn on otherwise. 2733 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 2734 } 2735 // Run the app in safe mode if its manifest requests so or the 2736 // system is booted in safe mode. 2737 if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 || 2738 Zygote.systemInSafeMode == true) { 2739 debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE; 2740 } 2741 if ("1".equals(SystemProperties.get("debug.checkjni"))) { 2742 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 2743 } 2744 if ("1".equals(SystemProperties.get("debug.jni.logging"))) { 2745 debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING; 2746 } 2747 if ("1".equals(SystemProperties.get("debug.assert"))) { 2748 debugFlags |= Zygote.DEBUG_ENABLE_ASSERT; 2749 } 2750 2751 // Start the process. It will either succeed and return a result containing 2752 // the PID of the new process, or else throw a RuntimeException. 2753 Process.ProcessStartResult startResult = Process.start("android.app.ActivityThread", 2754 app.processName, uid, uid, gids, debugFlags, mountExternal, 2755 app.info.targetSdkVersion, app.info.seinfo, null); 2756 2757 BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics(); 2758 synchronized (bs) { 2759 if (bs.isOnBattery()) { 2760 bs.getProcessStatsLocked(app.uid, app.processName).incStartsLocked(); 2761 } 2762 } 2763 2764 EventLog.writeEvent(EventLogTags.AM_PROC_START, 2765 UserHandle.getUserId(uid), startResult.pid, uid, 2766 app.processName, hostingType, 2767 hostingNameStr != null ? hostingNameStr : ""); 2768 2769 if (app.persistent) { 2770 Watchdog.getInstance().processStarted(app.processName, startResult.pid); 2771 } 2772 2773 StringBuilder buf = mStringBuilder; 2774 buf.setLength(0); 2775 buf.append("Start proc "); 2776 buf.append(app.processName); 2777 buf.append(" for "); 2778 buf.append(hostingType); 2779 if (hostingNameStr != null) { 2780 buf.append(" "); 2781 buf.append(hostingNameStr); 2782 } 2783 buf.append(": pid="); 2784 buf.append(startResult.pid); 2785 buf.append(" uid="); 2786 buf.append(uid); 2787 buf.append(" gids={"); 2788 if (gids != null) { 2789 for (int gi=0; gi<gids.length; gi++) { 2790 if (gi != 0) buf.append(", "); 2791 buf.append(gids[gi]); 2792 2793 } 2794 } 2795 buf.append("}"); 2796 Slog.i(TAG, buf.toString()); 2797 app.setPid(startResult.pid); 2798 app.usingWrapper = startResult.usingWrapper; 2799 app.removed = false; 2800 synchronized (mPidsSelfLocked) { 2801 this.mPidsSelfLocked.put(startResult.pid, app); 2802 Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 2803 msg.obj = app; 2804 mHandler.sendMessageDelayed(msg, startResult.usingWrapper 2805 ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT); 2806 } 2807 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_START, 2808 app.processName, app.info.uid); 2809 if (app.isolated) { 2810 mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid); 2811 } 2812 } catch (RuntimeException e) { 2813 // XXX do better error recovery. 2814 app.setPid(0); 2815 Slog.e(TAG, "Failure starting process " + app.processName, e); 2816 } 2817 } 2818 2819 void updateUsageStats(ActivityRecord component, boolean resumed) { 2820 if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed); 2821 final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 2822 if (resumed) { 2823 mUsageStatsService.noteResumeComponent(component.realActivity); 2824 synchronized (stats) { 2825 stats.noteActivityResumedLocked(component.app.uid); 2826 } 2827 } else { 2828 mUsageStatsService.notePauseComponent(component.realActivity); 2829 synchronized (stats) { 2830 stats.noteActivityPausedLocked(component.app.uid); 2831 } 2832 } 2833 } 2834 2835 Intent getHomeIntent() { 2836 Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null); 2837 intent.setComponent(mTopComponent); 2838 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 2839 intent.addCategory(Intent.CATEGORY_HOME); 2840 } 2841 return intent; 2842 } 2843 2844 boolean startHomeActivityLocked(int userId) { 2845 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL 2846 && mTopAction == null) { 2847 // We are running in factory test mode, but unable to find 2848 // the factory test app, so just sit around displaying the 2849 // error message and don't try to start anything. 2850 return false; 2851 } 2852 Intent intent = getHomeIntent(); 2853 ActivityInfo aInfo = 2854 resolveActivityInfo(intent, STOCK_PM_FLAGS, userId); 2855 if (aInfo != null) { 2856 intent.setComponent(new ComponentName( 2857 aInfo.applicationInfo.packageName, aInfo.name)); 2858 // Don't do this if the home app is currently being 2859 // instrumented. 2860 aInfo = new ActivityInfo(aInfo); 2861 aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId); 2862 ProcessRecord app = getProcessRecordLocked(aInfo.processName, 2863 aInfo.applicationInfo.uid, true); 2864 if (app == null || app.instrumentationClass == null) { 2865 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK); 2866 mStackSupervisor.startHomeActivity(intent, aInfo); 2867 } 2868 } 2869 2870 return true; 2871 } 2872 2873 private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) { 2874 ActivityInfo ai = null; 2875 ComponentName comp = intent.getComponent(); 2876 try { 2877 if (comp != null) { 2878 ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId); 2879 } else { 2880 ResolveInfo info = AppGlobals.getPackageManager().resolveIntent( 2881 intent, 2882 intent.resolveTypeIfNeeded(mContext.getContentResolver()), 2883 flags, userId); 2884 2885 if (info != null) { 2886 ai = info.activityInfo; 2887 } 2888 } 2889 } catch (RemoteException e) { 2890 // ignore 2891 } 2892 2893 return ai; 2894 } 2895 2896 /** 2897 * Starts the "new version setup screen" if appropriate. 2898 */ 2899 void startSetupActivityLocked() { 2900 // Only do this once per boot. 2901 if (mCheckedForSetup) { 2902 return; 2903 } 2904 2905 // We will show this screen if the current one is a different 2906 // version than the last one shown, and we are not running in 2907 // low-level factory test mode. 2908 final ContentResolver resolver = mContext.getContentResolver(); 2909 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL && 2910 Settings.Global.getInt(resolver, 2911 Settings.Global.DEVICE_PROVISIONED, 0) != 0) { 2912 mCheckedForSetup = true; 2913 2914 // See if we should be showing the platform update setup UI. 2915 Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP); 2916 List<ResolveInfo> ris = mContext.getPackageManager() 2917 .queryIntentActivities(intent, PackageManager.GET_META_DATA); 2918 2919 // We don't allow third party apps to replace this. 2920 ResolveInfo ri = null; 2921 for (int i=0; ris != null && i<ris.size(); i++) { 2922 if ((ris.get(i).activityInfo.applicationInfo.flags 2923 & ApplicationInfo.FLAG_SYSTEM) != 0) { 2924 ri = ris.get(i); 2925 break; 2926 } 2927 } 2928 2929 if (ri != null) { 2930 String vers = ri.activityInfo.metaData != null 2931 ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION) 2932 : null; 2933 if (vers == null && ri.activityInfo.applicationInfo.metaData != null) { 2934 vers = ri.activityInfo.applicationInfo.metaData.getString( 2935 Intent.METADATA_SETUP_VERSION); 2936 } 2937 String lastVers = Settings.Secure.getString( 2938 resolver, Settings.Secure.LAST_SETUP_SHOWN); 2939 if (vers != null && !vers.equals(lastVers)) { 2940 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 2941 intent.setComponent(new ComponentName( 2942 ri.activityInfo.packageName, ri.activityInfo.name)); 2943 mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo, 2944 null, null, 0, 0, 0, null, 0, null, false, null, null); 2945 } 2946 } 2947 } 2948 } 2949 2950 CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) { 2951 return mCompatModePackages.compatibilityInfoForPackageLocked(ai); 2952 } 2953 2954 void enforceNotIsolatedCaller(String caller) { 2955 if (UserHandle.isIsolated(Binder.getCallingUid())) { 2956 throw new SecurityException("Isolated process not allowed to call " + caller); 2957 } 2958 } 2959 2960 @Override 2961 public int getFrontActivityScreenCompatMode() { 2962 enforceNotIsolatedCaller("getFrontActivityScreenCompatMode"); 2963 synchronized (this) { 2964 return mCompatModePackages.getFrontActivityScreenCompatModeLocked(); 2965 } 2966 } 2967 2968 @Override 2969 public void setFrontActivityScreenCompatMode(int mode) { 2970 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 2971 "setFrontActivityScreenCompatMode"); 2972 synchronized (this) { 2973 mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode); 2974 } 2975 } 2976 2977 @Override 2978 public int getPackageScreenCompatMode(String packageName) { 2979 enforceNotIsolatedCaller("getPackageScreenCompatMode"); 2980 synchronized (this) { 2981 return mCompatModePackages.getPackageScreenCompatModeLocked(packageName); 2982 } 2983 } 2984 2985 @Override 2986 public void setPackageScreenCompatMode(String packageName, int mode) { 2987 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 2988 "setPackageScreenCompatMode"); 2989 synchronized (this) { 2990 mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode); 2991 } 2992 } 2993 2994 @Override 2995 public boolean getPackageAskScreenCompat(String packageName) { 2996 enforceNotIsolatedCaller("getPackageAskScreenCompat"); 2997 synchronized (this) { 2998 return mCompatModePackages.getPackageAskCompatModeLocked(packageName); 2999 } 3000 } 3001 3002 @Override 3003 public void setPackageAskScreenCompat(String packageName, boolean ask) { 3004 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3005 "setPackageAskScreenCompat"); 3006 synchronized (this) { 3007 mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask); 3008 } 3009 } 3010 3011 private void dispatchProcessesChanged() { 3012 int N; 3013 synchronized (this) { 3014 N = mPendingProcessChanges.size(); 3015 if (mActiveProcessChanges.length < N) { 3016 mActiveProcessChanges = new ProcessChangeItem[N]; 3017 } 3018 mPendingProcessChanges.toArray(mActiveProcessChanges); 3019 mAvailProcessChanges.addAll(mPendingProcessChanges); 3020 mPendingProcessChanges.clear(); 3021 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes"); 3022 } 3023 3024 int i = mProcessObservers.beginBroadcast(); 3025 while (i > 0) { 3026 i--; 3027 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 3028 if (observer != null) { 3029 try { 3030 for (int j=0; j<N; j++) { 3031 ProcessChangeItem item = mActiveProcessChanges[j]; 3032 if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) { 3033 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid=" 3034 + item.pid + " uid=" + item.uid + ": " 3035 + item.foregroundActivities); 3036 observer.onForegroundActivitiesChanged(item.pid, item.uid, 3037 item.foregroundActivities); 3038 } 3039 if ((item.changes&ProcessChangeItem.CHANGE_IMPORTANCE) != 0) { 3040 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "IMPORTANCE CHANGED pid=" 3041 + item.pid + " uid=" + item.uid + ": " + item.importance); 3042 observer.onImportanceChanged(item.pid, item.uid, 3043 item.importance); 3044 } 3045 } 3046 } catch (RemoteException e) { 3047 } 3048 } 3049 } 3050 mProcessObservers.finishBroadcast(); 3051 } 3052 3053 private void dispatchProcessDied(int pid, int uid) { 3054 int i = mProcessObservers.beginBroadcast(); 3055 while (i > 0) { 3056 i--; 3057 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 3058 if (observer != null) { 3059 try { 3060 observer.onProcessDied(pid, uid); 3061 } catch (RemoteException e) { 3062 } 3063 } 3064 } 3065 mProcessObservers.finishBroadcast(); 3066 } 3067 3068 final void doPendingActivityLaunchesLocked(boolean doResume) { 3069 final int N = mPendingActivityLaunches.size(); 3070 if (N <= 0) { 3071 return; 3072 } 3073 for (int i=0; i<N; i++) { 3074 PendingActivityLaunch pal = mPendingActivityLaunches.get(i); 3075 mStackSupervisor.startActivityUncheckedLocked(pal.r, pal.sourceRecord, pal.startFlags, 3076 doResume && i == (N-1), null); 3077 } 3078 mPendingActivityLaunches.clear(); 3079 } 3080 3081 @Override 3082 public final int startActivity(IApplicationThread caller, String callingPackage, 3083 Intent intent, String resolvedType, IBinder resultTo, 3084 String resultWho, int requestCode, int startFlags, 3085 String profileFile, ParcelFileDescriptor profileFd, Bundle options) { 3086 return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo, 3087 resultWho, requestCode, 3088 startFlags, profileFile, profileFd, options, UserHandle.getCallingUserId()); 3089 } 3090 3091 @Override 3092 public final int startActivityAsUser(IApplicationThread caller, String callingPackage, 3093 Intent intent, String resolvedType, IBinder resultTo, 3094 String resultWho, int requestCode, int startFlags, 3095 String profileFile, ParcelFileDescriptor profileFd, Bundle options, int userId) { 3096 enforceNotIsolatedCaller("startActivity"); 3097 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3098 false, true, "startActivity", null); 3099 // TODO: Switch to user app stacks here. 3100 return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType, 3101 resultTo, resultWho, requestCode, startFlags, profileFile, profileFd, 3102 null, null, options, userId, null); 3103 } 3104 3105 @Override 3106 public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage, 3107 Intent intent, String resolvedType, IBinder resultTo, 3108 String resultWho, int requestCode, int startFlags, String profileFile, 3109 ParcelFileDescriptor profileFd, Bundle options, int userId) { 3110 enforceNotIsolatedCaller("startActivityAndWait"); 3111 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3112 false, true, "startActivityAndWait", null); 3113 WaitResult res = new WaitResult(); 3114 // TODO: Switch to user app stacks here. 3115 mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType, 3116 resultTo, resultWho, requestCode, startFlags, profileFile, profileFd, 3117 res, null, options, UserHandle.getCallingUserId(), null); 3118 return res; 3119 } 3120 3121 @Override 3122 public final int startActivityWithConfig(IApplicationThread caller, String callingPackage, 3123 Intent intent, String resolvedType, IBinder resultTo, 3124 String resultWho, int requestCode, int startFlags, Configuration config, 3125 Bundle options, int userId) { 3126 enforceNotIsolatedCaller("startActivityWithConfig"); 3127 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3128 false, true, "startActivityWithConfig", null); 3129 // TODO: Switch to user app stacks here. 3130 int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, 3131 resolvedType, resultTo, resultWho, requestCode, startFlags, 3132 null, null, null, config, options, userId, null); 3133 return ret; 3134 } 3135 3136 @Override 3137 public int startActivityIntentSender(IApplicationThread caller, 3138 IntentSender intent, Intent fillInIntent, String resolvedType, 3139 IBinder resultTo, String resultWho, int requestCode, 3140 int flagsMask, int flagsValues, Bundle options) { 3141 enforceNotIsolatedCaller("startActivityIntentSender"); 3142 // Refuse possible leaked file descriptors 3143 if (fillInIntent != null && fillInIntent.hasFileDescriptors()) { 3144 throw new IllegalArgumentException("File descriptors passed in Intent"); 3145 } 3146 3147 IIntentSender sender = intent.getTarget(); 3148 if (!(sender instanceof PendingIntentRecord)) { 3149 throw new IllegalArgumentException("Bad PendingIntent object"); 3150 } 3151 3152 PendingIntentRecord pir = (PendingIntentRecord)sender; 3153 3154 synchronized (this) { 3155 // If this is coming from the currently resumed activity, it is 3156 // effectively saying that app switches are allowed at this point. 3157 final ActivityStack stack = getFocusedStack(); 3158 if (stack.mResumedActivity != null && 3159 stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) { 3160 mAppSwitchesAllowedTime = 0; 3161 } 3162 } 3163 int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null, 3164 resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null); 3165 return ret; 3166 } 3167 3168 @Override 3169 public boolean startNextMatchingActivity(IBinder callingActivity, 3170 Intent intent, Bundle options) { 3171 // Refuse possible leaked file descriptors 3172 if (intent != null && intent.hasFileDescriptors() == true) { 3173 throw new IllegalArgumentException("File descriptors passed in Intent"); 3174 } 3175 3176 synchronized (this) { 3177 final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity); 3178 if (r == null) { 3179 ActivityOptions.abort(options); 3180 return false; 3181 } 3182 if (r.app == null || r.app.thread == null) { 3183 // The caller is not running... d'oh! 3184 ActivityOptions.abort(options); 3185 return false; 3186 } 3187 intent = new Intent(intent); 3188 // The caller is not allowed to change the data. 3189 intent.setDataAndType(r.intent.getData(), r.intent.getType()); 3190 // And we are resetting to find the next component... 3191 intent.setComponent(null); 3192 3193 final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0); 3194 3195 ActivityInfo aInfo = null; 3196 try { 3197 List<ResolveInfo> resolves = 3198 AppGlobals.getPackageManager().queryIntentActivities( 3199 intent, r.resolvedType, 3200 PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS, 3201 UserHandle.getCallingUserId()); 3202 3203 // Look for the original activity in the list... 3204 final int N = resolves != null ? resolves.size() : 0; 3205 for (int i=0; i<N; i++) { 3206 ResolveInfo rInfo = resolves.get(i); 3207 if (rInfo.activityInfo.packageName.equals(r.packageName) 3208 && rInfo.activityInfo.name.equals(r.info.name)) { 3209 // We found the current one... the next matching is 3210 // after it. 3211 i++; 3212 if (i<N) { 3213 aInfo = resolves.get(i).activityInfo; 3214 } 3215 if (debug) { 3216 Slog.v(TAG, "Next matching activity: found current " + r.packageName 3217 + "/" + r.info.name); 3218 Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName 3219 + "/" + aInfo.name); 3220 } 3221 break; 3222 } 3223 } 3224 } catch (RemoteException e) { 3225 } 3226 3227 if (aInfo == null) { 3228 // Nobody who is next! 3229 ActivityOptions.abort(options); 3230 if (debug) Slog.d(TAG, "Next matching activity: nothing found"); 3231 return false; 3232 } 3233 3234 intent.setComponent(new ComponentName( 3235 aInfo.applicationInfo.packageName, aInfo.name)); 3236 intent.setFlags(intent.getFlags()&~( 3237 Intent.FLAG_ACTIVITY_FORWARD_RESULT| 3238 Intent.FLAG_ACTIVITY_CLEAR_TOP| 3239 Intent.FLAG_ACTIVITY_MULTIPLE_TASK| 3240 Intent.FLAG_ACTIVITY_NEW_TASK)); 3241 3242 // Okay now we need to start the new activity, replacing the 3243 // currently running activity. This is a little tricky because 3244 // we want to start the new one as if the current one is finished, 3245 // but not finish the current one first so that there is no flicker. 3246 // And thus... 3247 final boolean wasFinishing = r.finishing; 3248 r.finishing = true; 3249 3250 // Propagate reply information over to the new activity. 3251 final ActivityRecord resultTo = r.resultTo; 3252 final String resultWho = r.resultWho; 3253 final int requestCode = r.requestCode; 3254 r.resultTo = null; 3255 if (resultTo != null) { 3256 resultTo.removeResultsLocked(r, resultWho, requestCode); 3257 } 3258 3259 final long origId = Binder.clearCallingIdentity(); 3260 int res = mStackSupervisor.startActivityLocked(r.app.thread, intent, 3261 r.resolvedType, aInfo, resultTo != null ? resultTo.appToken : null, 3262 resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage, 0, 3263 options, false, null, null); 3264 Binder.restoreCallingIdentity(origId); 3265 3266 r.finishing = wasFinishing; 3267 if (res != ActivityManager.START_SUCCESS) { 3268 return false; 3269 } 3270 return true; 3271 } 3272 } 3273 3274 final int startActivityInPackage(int uid, String callingPackage, 3275 Intent intent, String resolvedType, IBinder resultTo, 3276 String resultWho, int requestCode, int startFlags, Bundle options, int userId, 3277 IActivityContainer container) { 3278 3279 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3280 false, true, "startActivityInPackage", null); 3281 3282 // TODO: Switch to user app stacks here. 3283 int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent, resolvedType, 3284 resultTo, resultWho, requestCode, startFlags, 3285 null, null, null, null, options, userId, container); 3286 return ret; 3287 } 3288 3289 @Override 3290 public final int startActivities(IApplicationThread caller, String callingPackage, 3291 Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options, 3292 int userId) { 3293 enforceNotIsolatedCaller("startActivities"); 3294 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3295 false, true, "startActivity", null); 3296 // TODO: Switch to user app stacks here. 3297 int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents, 3298 resolvedTypes, resultTo, options, userId); 3299 return ret; 3300 } 3301 3302 final int startActivitiesInPackage(int uid, String callingPackage, 3303 Intent[] intents, String[] resolvedTypes, IBinder resultTo, 3304 Bundle options, int userId) { 3305 3306 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3307 false, true, "startActivityInPackage", null); 3308 // TODO: Switch to user app stacks here. 3309 int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes, 3310 resultTo, options, userId); 3311 return ret; 3312 } 3313 3314 final void addRecentTaskLocked(TaskRecord task) { 3315 int N = mRecentTasks.size(); 3316 // Quick case: check if the top-most recent task is the same. 3317 if (N > 0 && mRecentTasks.get(0) == task) { 3318 return; 3319 } 3320 // Remove any existing entries that are the same kind of task. 3321 for (int i=0; i<N; i++) { 3322 TaskRecord tr = mRecentTasks.get(i); 3323 if (task.userId == tr.userId 3324 && ((task.affinity != null && task.affinity.equals(tr.affinity)) 3325 || (task.intent != null && task.intent.filterEquals(tr.intent)))) { 3326 tr.disposeThumbnail(); 3327 mRecentTasks.remove(i); 3328 i--; 3329 N--; 3330 if (task.intent == null) { 3331 // If the new recent task we are adding is not fully 3332 // specified, then replace it with the existing recent task. 3333 task = tr; 3334 } 3335 } 3336 } 3337 if (N >= MAX_RECENT_TASKS) { 3338 mRecentTasks.remove(N-1).disposeThumbnail(); 3339 } 3340 mRecentTasks.add(0, task); 3341 } 3342 3343 @Override 3344 public void reportActivityFullyDrawn(IBinder token) { 3345 synchronized (this) { 3346 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3347 if (r == null) { 3348 return; 3349 } 3350 r.reportFullyDrawnLocked(); 3351 } 3352 } 3353 3354 @Override 3355 public void setRequestedOrientation(IBinder token, int requestedOrientation) { 3356 synchronized (this) { 3357 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3358 if (r == null) { 3359 return; 3360 } 3361 final long origId = Binder.clearCallingIdentity(); 3362 mWindowManager.setAppOrientation(r.appToken, requestedOrientation); 3363 Configuration config = mWindowManager.updateOrientationFromAppTokens( 3364 mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null); 3365 if (config != null) { 3366 r.frozenBeforeDestroy = true; 3367 if (!updateConfigurationLocked(config, r, false, false)) { 3368 mStackSupervisor.resumeTopActivitiesLocked(); 3369 } 3370 } 3371 Binder.restoreCallingIdentity(origId); 3372 } 3373 } 3374 3375 @Override 3376 public int getRequestedOrientation(IBinder token) { 3377 synchronized (this) { 3378 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3379 if (r == null) { 3380 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; 3381 } 3382 return mWindowManager.getAppOrientation(r.appToken); 3383 } 3384 } 3385 3386 /** 3387 * This is the internal entry point for handling Activity.finish(). 3388 * 3389 * @param token The Binder token referencing the Activity we want to finish. 3390 * @param resultCode Result code, if any, from this Activity. 3391 * @param resultData Result data (Intent), if any, from this Activity. 3392 * 3393 * @return Returns true if the activity successfully finished, or false if it is still running. 3394 */ 3395 @Override 3396 public final boolean finishActivity(IBinder token, int resultCode, Intent resultData) { 3397 // Refuse possible leaked file descriptors 3398 if (resultData != null && resultData.hasFileDescriptors() == true) { 3399 throw new IllegalArgumentException("File descriptors passed in Intent"); 3400 } 3401 3402 synchronized(this) { 3403 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3404 if (r == null) { 3405 return true; 3406 } 3407 if (mController != null) { 3408 // Find the first activity that is not finishing. 3409 ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0); 3410 if (next != null) { 3411 // ask watcher if this is allowed 3412 boolean resumeOK = true; 3413 try { 3414 resumeOK = mController.activityResuming(next.packageName); 3415 } catch (RemoteException e) { 3416 mController = null; 3417 Watchdog.getInstance().setActivityController(null); 3418 } 3419 3420 if (!resumeOK) { 3421 return false; 3422 } 3423 } 3424 } 3425 final long origId = Binder.clearCallingIdentity(); 3426 boolean res = r.task.stack.requestFinishActivityLocked(token, resultCode, 3427 resultData, "app-request", true); 3428 Binder.restoreCallingIdentity(origId); 3429 return res; 3430 } 3431 } 3432 3433 @Override 3434 public final void finishHeavyWeightApp() { 3435 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 3436 != PackageManager.PERMISSION_GRANTED) { 3437 String msg = "Permission Denial: finishHeavyWeightApp() from pid=" 3438 + Binder.getCallingPid() 3439 + ", uid=" + Binder.getCallingUid() 3440 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 3441 Slog.w(TAG, msg); 3442 throw new SecurityException(msg); 3443 } 3444 3445 synchronized(this) { 3446 if (mHeavyWeightProcess == null) { 3447 return; 3448 } 3449 3450 ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>( 3451 mHeavyWeightProcess.activities); 3452 for (int i=0; i<activities.size(); i++) { 3453 ActivityRecord r = activities.get(i); 3454 if (!r.finishing) { 3455 r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED, 3456 null, "finish-heavy", true); 3457 } 3458 } 3459 3460 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 3461 mHeavyWeightProcess.userId, 0)); 3462 mHeavyWeightProcess = null; 3463 } 3464 } 3465 3466 @Override 3467 public void crashApplication(int uid, int initialPid, String packageName, 3468 String message) { 3469 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 3470 != PackageManager.PERMISSION_GRANTED) { 3471 String msg = "Permission Denial: crashApplication() from pid=" 3472 + Binder.getCallingPid() 3473 + ", uid=" + Binder.getCallingUid() 3474 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 3475 Slog.w(TAG, msg); 3476 throw new SecurityException(msg); 3477 } 3478 3479 synchronized(this) { 3480 ProcessRecord proc = null; 3481 3482 // Figure out which process to kill. We don't trust that initialPid 3483 // still has any relation to current pids, so must scan through the 3484 // list. 3485 synchronized (mPidsSelfLocked) { 3486 for (int i=0; i<mPidsSelfLocked.size(); i++) { 3487 ProcessRecord p = mPidsSelfLocked.valueAt(i); 3488 if (p.uid != uid) { 3489 continue; 3490 } 3491 if (p.pid == initialPid) { 3492 proc = p; 3493 break; 3494 } 3495 if (p.pkgList.containsKey(packageName)) { 3496 proc = p; 3497 } 3498 } 3499 } 3500 3501 if (proc == null) { 3502 Slog.w(TAG, "crashApplication: nothing for uid=" + uid 3503 + " initialPid=" + initialPid 3504 + " packageName=" + packageName); 3505 return; 3506 } 3507 3508 if (proc.thread != null) { 3509 if (proc.pid == Process.myPid()) { 3510 Log.w(TAG, "crashApplication: trying to crash self!"); 3511 return; 3512 } 3513 long ident = Binder.clearCallingIdentity(); 3514 try { 3515 proc.thread.scheduleCrash(message); 3516 } catch (RemoteException e) { 3517 } 3518 Binder.restoreCallingIdentity(ident); 3519 } 3520 } 3521 } 3522 3523 @Override 3524 public final void finishSubActivity(IBinder token, String resultWho, 3525 int requestCode) { 3526 synchronized(this) { 3527 final long origId = Binder.clearCallingIdentity(); 3528 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3529 if (r != null) { 3530 r.task.stack.finishSubActivityLocked(r, resultWho, requestCode); 3531 } 3532 Binder.restoreCallingIdentity(origId); 3533 } 3534 } 3535 3536 @Override 3537 public boolean finishActivityAffinity(IBinder token) { 3538 synchronized(this) { 3539 final long origId = Binder.clearCallingIdentity(); 3540 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3541 boolean res = false; 3542 if (r != null) { 3543 res = r.task.stack.finishActivityAffinityLocked(r); 3544 } 3545 Binder.restoreCallingIdentity(origId); 3546 return res; 3547 } 3548 } 3549 3550 @Override 3551 public boolean willActivityBeVisible(IBinder token) { 3552 synchronized(this) { 3553 ActivityStack stack = ActivityRecord.getStackLocked(token); 3554 if (stack != null) { 3555 return stack.willActivityBeVisibleLocked(token); 3556 } 3557 return false; 3558 } 3559 } 3560 3561 @Override 3562 public void overridePendingTransition(IBinder token, String packageName, 3563 int enterAnim, int exitAnim) { 3564 synchronized(this) { 3565 ActivityRecord self = ActivityRecord.isInStackLocked(token); 3566 if (self == null) { 3567 return; 3568 } 3569 3570 final long origId = Binder.clearCallingIdentity(); 3571 3572 if (self.state == ActivityState.RESUMED 3573 || self.state == ActivityState.PAUSING) { 3574 mWindowManager.overridePendingAppTransition(packageName, 3575 enterAnim, exitAnim, null); 3576 } 3577 3578 Binder.restoreCallingIdentity(origId); 3579 } 3580 } 3581 3582 /** 3583 * Main function for removing an existing process from the activity manager 3584 * as a result of that process going away. Clears out all connections 3585 * to the process. 3586 */ 3587 private final void handleAppDiedLocked(ProcessRecord app, 3588 boolean restarting, boolean allowRestart) { 3589 int pid = app.pid; 3590 cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1); 3591 if (!restarting) { 3592 removeLruProcessLocked(app); 3593 if (pid > 0) { 3594 ProcessList.remove(pid); 3595 } 3596 } 3597 3598 if (mProfileProc == app) { 3599 clearProfilerLocked(); 3600 } 3601 3602 // Remove this application's activities from active lists. 3603 boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app); 3604 3605 app.activities.clear(); 3606 3607 if (app.instrumentationClass != null) { 3608 Slog.w(TAG, "Crash of app " + app.processName 3609 + " running instrumentation " + app.instrumentationClass); 3610 Bundle info = new Bundle(); 3611 info.putString("shortMsg", "Process crashed."); 3612 finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info); 3613 } 3614 3615 if (!restarting) { 3616 if (!mStackSupervisor.resumeTopActivitiesLocked()) { 3617 // If there was nothing to resume, and we are not already 3618 // restarting this process, but there is a visible activity that 3619 // is hosted by the process... then make sure all visible 3620 // activities are running, taking care of restarting this 3621 // process. 3622 if (hasVisibleActivities) { 3623 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 3624 } 3625 } 3626 } 3627 } 3628 3629 private final int getLRURecordIndexForAppLocked(IApplicationThread thread) { 3630 IBinder threadBinder = thread.asBinder(); 3631 // Find the application record. 3632 for (int i=mLruProcesses.size()-1; i>=0; i--) { 3633 ProcessRecord rec = mLruProcesses.get(i); 3634 if (rec.thread != null && rec.thread.asBinder() == threadBinder) { 3635 return i; 3636 } 3637 } 3638 return -1; 3639 } 3640 3641 final ProcessRecord getRecordForAppLocked( 3642 IApplicationThread thread) { 3643 if (thread == null) { 3644 return null; 3645 } 3646 3647 int appIndex = getLRURecordIndexForAppLocked(thread); 3648 return appIndex >= 0 ? mLruProcesses.get(appIndex) : null; 3649 } 3650 3651 final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) { 3652 // If there are no longer any background processes running, 3653 // and the app that died was not running instrumentation, 3654 // then tell everyone we are now low on memory. 3655 boolean haveBg = false; 3656 for (int i=mLruProcesses.size()-1; i>=0; i--) { 3657 ProcessRecord rec = mLruProcesses.get(i); 3658 if (rec.thread != null 3659 && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 3660 haveBg = true; 3661 break; 3662 } 3663 } 3664 3665 if (!haveBg) { 3666 boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 3667 if (doReport) { 3668 long now = SystemClock.uptimeMillis(); 3669 if (now < (mLastMemUsageReportTime+5*60*1000)) { 3670 doReport = false; 3671 } else { 3672 mLastMemUsageReportTime = now; 3673 } 3674 } 3675 final ArrayList<ProcessMemInfo> memInfos 3676 = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null; 3677 EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size()); 3678 long now = SystemClock.uptimeMillis(); 3679 for (int i=mLruProcesses.size()-1; i>=0; i--) { 3680 ProcessRecord rec = mLruProcesses.get(i); 3681 if (rec == dyingProc || rec.thread == null) { 3682 continue; 3683 } 3684 if (doReport) { 3685 memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj, 3686 rec.setProcState, rec.adjType, rec.makeAdjReason())); 3687 } 3688 if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) { 3689 // The low memory report is overriding any current 3690 // state for a GC request. Make sure to do 3691 // heavy/important/visible/foreground processes first. 3692 if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 3693 rec.lastRequestedGc = 0; 3694 } else { 3695 rec.lastRequestedGc = rec.lastLowMemory; 3696 } 3697 rec.reportLowMemory = true; 3698 rec.lastLowMemory = now; 3699 mProcessesToGc.remove(rec); 3700 addProcessToGcListLocked(rec); 3701 } 3702 } 3703 if (doReport) { 3704 Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos); 3705 mHandler.sendMessage(msg); 3706 } 3707 scheduleAppGcsLocked(); 3708 } 3709 } 3710 3711 final void appDiedLocked(ProcessRecord app, int pid, 3712 IApplicationThread thread) { 3713 3714 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 3715 synchronized (stats) { 3716 stats.noteProcessDiedLocked(app.info.uid, pid); 3717 } 3718 3719 // Clean up already done if the process has been re-started. 3720 if (app.pid == pid && app.thread != null && 3721 app.thread.asBinder() == thread.asBinder()) { 3722 boolean doLowMem = app.instrumentationClass == null; 3723 boolean doOomAdj = doLowMem; 3724 if (!app.killedByAm) { 3725 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 3726 + ") has died."); 3727 mAllowLowerMemLevel = true; 3728 } else { 3729 // Note that we always want to do oom adj to update our state with the 3730 // new number of procs. 3731 mAllowLowerMemLevel = false; 3732 doLowMem = false; 3733 } 3734 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName); 3735 if (DEBUG_CLEANUP) Slog.v( 3736 TAG, "Dying app: " + app + ", pid: " + pid 3737 + ", thread: " + thread.asBinder()); 3738 handleAppDiedLocked(app, false, true); 3739 3740 if (doOomAdj) { 3741 updateOomAdjLocked(); 3742 } 3743 if (doLowMem) { 3744 doLowMemReportIfNeededLocked(app); 3745 } 3746 } else if (app.pid != pid) { 3747 // A new process has already been started. 3748 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 3749 + ") has died and restarted (pid " + app.pid + ")."); 3750 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName); 3751 } else if (DEBUG_PROCESSES) { 3752 Slog.d(TAG, "Received spurious death notification for thread " 3753 + thread.asBinder()); 3754 } 3755 } 3756 3757 /** 3758 * If a stack trace dump file is configured, dump process stack traces. 3759 * @param clearTraces causes the dump file to be erased prior to the new 3760 * traces being written, if true; when false, the new traces will be 3761 * appended to any existing file content. 3762 * @param firstPids of dalvik VM processes to dump stack traces for first 3763 * @param lastPids of dalvik VM processes to dump stack traces for last 3764 * @param nativeProcs optional list of native process names to dump stack crawls 3765 * @return file containing stack traces, or null if no dump file is configured 3766 */ 3767 public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids, 3768 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) { 3769 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 3770 if (tracesPath == null || tracesPath.length() == 0) { 3771 return null; 3772 } 3773 3774 File tracesFile = new File(tracesPath); 3775 try { 3776 File tracesDir = tracesFile.getParentFile(); 3777 if (!tracesDir.exists()) { 3778 tracesFile.mkdirs(); 3779 if (!SELinux.restorecon(tracesDir)) { 3780 return null; 3781 } 3782 } 3783 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 3784 3785 if (clearTraces && tracesFile.exists()) tracesFile.delete(); 3786 tracesFile.createNewFile(); 3787 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 3788 } catch (IOException e) { 3789 Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e); 3790 return null; 3791 } 3792 3793 dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs); 3794 return tracesFile; 3795 } 3796 3797 private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids, 3798 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) { 3799 // Use a FileObserver to detect when traces finish writing. 3800 // The order of traces is considered important to maintain for legibility. 3801 FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) { 3802 @Override 3803 public synchronized void onEvent(int event, String path) { notify(); } 3804 }; 3805 3806 try { 3807 observer.startWatching(); 3808 3809 // First collect all of the stacks of the most important pids. 3810 if (firstPids != null) { 3811 try { 3812 int num = firstPids.size(); 3813 for (int i = 0; i < num; i++) { 3814 synchronized (observer) { 3815 Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT); 3816 observer.wait(200); // Wait for write-close, give up after 200msec 3817 } 3818 } 3819 } catch (InterruptedException e) { 3820 Log.wtf(TAG, e); 3821 } 3822 } 3823 3824 // Next collect the stacks of the native pids 3825 if (nativeProcs != null) { 3826 int[] pids = Process.getPidsForCommands(nativeProcs); 3827 if (pids != null) { 3828 for (int pid : pids) { 3829 Debug.dumpNativeBacktraceToFile(pid, tracesPath); 3830 } 3831 } 3832 } 3833 3834 // Lastly, measure CPU usage. 3835 if (processCpuTracker != null) { 3836 processCpuTracker.init(); 3837 System.gc(); 3838 processCpuTracker.update(); 3839 try { 3840 synchronized (processCpuTracker) { 3841 processCpuTracker.wait(500); // measure over 1/2 second. 3842 } 3843 } catch (InterruptedException e) { 3844 } 3845 processCpuTracker.update(); 3846 3847 // We'll take the stack crawls of just the top apps using CPU. 3848 final int N = processCpuTracker.countWorkingStats(); 3849 int numProcs = 0; 3850 for (int i=0; i<N && numProcs<5; i++) { 3851 ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i); 3852 if (lastPids.indexOfKey(stats.pid) >= 0) { 3853 numProcs++; 3854 try { 3855 synchronized (observer) { 3856 Process.sendSignal(stats.pid, Process.SIGNAL_QUIT); 3857 observer.wait(200); // Wait for write-close, give up after 200msec 3858 } 3859 } catch (InterruptedException e) { 3860 Log.wtf(TAG, e); 3861 } 3862 3863 } 3864 } 3865 } 3866 } finally { 3867 observer.stopWatching(); 3868 } 3869 } 3870 3871 final void logAppTooSlow(ProcessRecord app, long startTime, String msg) { 3872 if (true || IS_USER_BUILD) { 3873 return; 3874 } 3875 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 3876 if (tracesPath == null || tracesPath.length() == 0) { 3877 return; 3878 } 3879 3880 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads(); 3881 StrictMode.allowThreadDiskWrites(); 3882 try { 3883 final File tracesFile = new File(tracesPath); 3884 final File tracesDir = tracesFile.getParentFile(); 3885 final File tracesTmp = new File(tracesDir, "__tmp__"); 3886 try { 3887 if (!tracesDir.exists()) { 3888 tracesFile.mkdirs(); 3889 if (!SELinux.restorecon(tracesDir.getPath())) { 3890 return; 3891 } 3892 } 3893 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 3894 3895 if (tracesFile.exists()) { 3896 tracesTmp.delete(); 3897 tracesFile.renameTo(tracesTmp); 3898 } 3899 StringBuilder sb = new StringBuilder(); 3900 Time tobj = new Time(); 3901 tobj.set(System.currentTimeMillis()); 3902 sb.append(tobj.format("%Y-%m-%d %H:%M:%S")); 3903 sb.append(": "); 3904 TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb); 3905 sb.append(" since "); 3906 sb.append(msg); 3907 FileOutputStream fos = new FileOutputStream(tracesFile); 3908 fos.write(sb.toString().getBytes()); 3909 if (app == null) { 3910 fos.write("\n*** No application process!".getBytes()); 3911 } 3912 fos.close(); 3913 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 3914 } catch (IOException e) { 3915 Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e); 3916 return; 3917 } 3918 3919 if (app != null) { 3920 ArrayList<Integer> firstPids = new ArrayList<Integer>(); 3921 firstPids.add(app.pid); 3922 dumpStackTraces(tracesPath, firstPids, null, null, null); 3923 } 3924 3925 File lastTracesFile = null; 3926 File curTracesFile = null; 3927 for (int i=9; i>=0; i--) { 3928 String name = String.format(Locale.US, "slow%02d.txt", i); 3929 curTracesFile = new File(tracesDir, name); 3930 if (curTracesFile.exists()) { 3931 if (lastTracesFile != null) { 3932 curTracesFile.renameTo(lastTracesFile); 3933 } else { 3934 curTracesFile.delete(); 3935 } 3936 } 3937 lastTracesFile = curTracesFile; 3938 } 3939 tracesFile.renameTo(curTracesFile); 3940 if (tracesTmp.exists()) { 3941 tracesTmp.renameTo(tracesFile); 3942 } 3943 } finally { 3944 StrictMode.setThreadPolicy(oldPolicy); 3945 } 3946 } 3947 3948 final void appNotResponding(ProcessRecord app, ActivityRecord activity, 3949 ActivityRecord parent, boolean aboveSystem, final String annotation) { 3950 ArrayList<Integer> firstPids = new ArrayList<Integer>(5); 3951 SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20); 3952 3953 if (mController != null) { 3954 try { 3955 // 0 == continue, -1 = kill process immediately 3956 int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation); 3957 if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid); 3958 } catch (RemoteException e) { 3959 mController = null; 3960 Watchdog.getInstance().setActivityController(null); 3961 } 3962 } 3963 3964 long anrTime = SystemClock.uptimeMillis(); 3965 if (MONITOR_CPU_USAGE) { 3966 updateCpuStatsNow(); 3967 } 3968 3969 synchronized (this) { 3970 // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down. 3971 if (mShuttingDown) { 3972 Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation); 3973 return; 3974 } else if (app.notResponding) { 3975 Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation); 3976 return; 3977 } else if (app.crashing) { 3978 Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation); 3979 return; 3980 } 3981 3982 // In case we come through here for the same app before completing 3983 // this one, mark as anring now so we will bail out. 3984 app.notResponding = true; 3985 3986 // Log the ANR to the event log. 3987 EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid, 3988 app.processName, app.info.flags, annotation); 3989 3990 // Dump thread traces as quickly as we can, starting with "interesting" processes. 3991 firstPids.add(app.pid); 3992 3993 int parentPid = app.pid; 3994 if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid; 3995 if (parentPid != app.pid) firstPids.add(parentPid); 3996 3997 if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID); 3998 3999 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 4000 ProcessRecord r = mLruProcesses.get(i); 4001 if (r != null && r.thread != null) { 4002 int pid = r.pid; 4003 if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) { 4004 if (r.persistent) { 4005 firstPids.add(pid); 4006 } else { 4007 lastPids.put(pid, Boolean.TRUE); 4008 } 4009 } 4010 } 4011 } 4012 } 4013 4014 // Log the ANR to the main log. 4015 StringBuilder info = new StringBuilder(); 4016 info.setLength(0); 4017 info.append("ANR in ").append(app.processName); 4018 if (activity != null && activity.shortComponentName != null) { 4019 info.append(" (").append(activity.shortComponentName).append(")"); 4020 } 4021 info.append("\n"); 4022 info.append("PID: ").append(app.pid).append("\n"); 4023 if (annotation != null) { 4024 info.append("Reason: ").append(annotation).append("\n"); 4025 } 4026 if (parent != null && parent != activity) { 4027 info.append("Parent: ").append(parent.shortComponentName).append("\n"); 4028 } 4029 4030 final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true); 4031 4032 File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids, 4033 NATIVE_STACKS_OF_INTEREST); 4034 4035 String cpuInfo = null; 4036 if (MONITOR_CPU_USAGE) { 4037 updateCpuStatsNow(); 4038 synchronized (mProcessCpuThread) { 4039 cpuInfo = mProcessCpuTracker.printCurrentState(anrTime); 4040 } 4041 info.append(processCpuTracker.printCurrentLoad()); 4042 info.append(cpuInfo); 4043 } 4044 4045 info.append(processCpuTracker.printCurrentState(anrTime)); 4046 4047 Slog.e(TAG, info.toString()); 4048 if (tracesFile == null) { 4049 // There is no trace file, so dump (only) the alleged culprit's threads to the log 4050 Process.sendSignal(app.pid, Process.SIGNAL_QUIT); 4051 } 4052 4053 addErrorToDropBox("anr", app, app.processName, activity, parent, annotation, 4054 cpuInfo, tracesFile, null); 4055 4056 if (mController != null) { 4057 try { 4058 // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately 4059 int res = mController.appNotResponding(app.processName, app.pid, info.toString()); 4060 if (res != 0) { 4061 if (res < 0 && app.pid != MY_PID) { 4062 Process.killProcess(app.pid); 4063 } else { 4064 synchronized (this) { 4065 mServices.scheduleServiceTimeoutLocked(app); 4066 } 4067 } 4068 return; 4069 } 4070 } catch (RemoteException e) { 4071 mController = null; 4072 Watchdog.getInstance().setActivityController(null); 4073 } 4074 } 4075 4076 // Unless configured otherwise, swallow ANRs in background processes & kill the process. 4077 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), 4078 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; 4079 4080 synchronized (this) { 4081 if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) { 4082 killUnneededProcessLocked(app, "background ANR"); 4083 return; 4084 } 4085 4086 // Set the app's notResponding state, and look up the errorReportReceiver 4087 makeAppNotRespondingLocked(app, 4088 activity != null ? activity.shortComponentName : null, 4089 annotation != null ? "ANR " + annotation : "ANR", 4090 info.toString()); 4091 4092 // Bring up the infamous App Not Responding dialog 4093 Message msg = Message.obtain(); 4094 HashMap<String, Object> map = new HashMap<String, Object>(); 4095 msg.what = SHOW_NOT_RESPONDING_MSG; 4096 msg.obj = map; 4097 msg.arg1 = aboveSystem ? 1 : 0; 4098 map.put("app", app); 4099 if (activity != null) { 4100 map.put("activity", activity); 4101 } 4102 4103 mHandler.sendMessage(msg); 4104 } 4105 } 4106 4107 final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) { 4108 if (!mLaunchWarningShown) { 4109 mLaunchWarningShown = true; 4110 mHandler.post(new Runnable() { 4111 @Override 4112 public void run() { 4113 synchronized (ActivityManagerService.this) { 4114 final Dialog d = new LaunchWarningWindow(mContext, cur, next); 4115 d.show(); 4116 mHandler.postDelayed(new Runnable() { 4117 @Override 4118 public void run() { 4119 synchronized (ActivityManagerService.this) { 4120 d.dismiss(); 4121 mLaunchWarningShown = false; 4122 } 4123 } 4124 }, 4000); 4125 } 4126 } 4127 }); 4128 } 4129 } 4130 4131 @Override 4132 public boolean clearApplicationUserData(final String packageName, 4133 final IPackageDataObserver observer, int userId) { 4134 enforceNotIsolatedCaller("clearApplicationUserData"); 4135 int uid = Binder.getCallingUid(); 4136 int pid = Binder.getCallingPid(); 4137 userId = handleIncomingUser(pid, uid, 4138 userId, false, true, "clearApplicationUserData", null); 4139 long callingId = Binder.clearCallingIdentity(); 4140 try { 4141 IPackageManager pm = AppGlobals.getPackageManager(); 4142 int pkgUid = -1; 4143 synchronized(this) { 4144 try { 4145 pkgUid = pm.getPackageUid(packageName, userId); 4146 } catch (RemoteException e) { 4147 } 4148 if (pkgUid == -1) { 4149 Slog.w(TAG, "Invalid packageName: " + packageName); 4150 if (observer != null) { 4151 try { 4152 observer.onRemoveCompleted(packageName, false); 4153 } catch (RemoteException e) { 4154 Slog.i(TAG, "Observer no longer exists."); 4155 } 4156 } 4157 return false; 4158 } 4159 if (uid == pkgUid || checkComponentPermission( 4160 android.Manifest.permission.CLEAR_APP_USER_DATA, 4161 pid, uid, -1, true) 4162 == PackageManager.PERMISSION_GRANTED) { 4163 forceStopPackageLocked(packageName, pkgUid, "clear data"); 4164 } else { 4165 throw new SecurityException("PID " + pid + " does not have permission " 4166 + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data" 4167 + " of package " + packageName); 4168 } 4169 } 4170 4171 try { 4172 // Clear application user data 4173 pm.clearApplicationUserData(packageName, observer, userId); 4174 4175 // Remove all permissions granted from/to this package 4176 removeUriPermissionsForPackageLocked(packageName, userId, true); 4177 4178 Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED, 4179 Uri.fromParts("package", packageName, null)); 4180 intent.putExtra(Intent.EXTRA_UID, pkgUid); 4181 broadcastIntentInPackage("android", Process.SYSTEM_UID, intent, 4182 null, null, 0, null, null, null, false, false, userId); 4183 } catch (RemoteException e) { 4184 } 4185 } finally { 4186 Binder.restoreCallingIdentity(callingId); 4187 } 4188 return true; 4189 } 4190 4191 @Override 4192 public void killBackgroundProcesses(final String packageName, int userId) { 4193 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 4194 != PackageManager.PERMISSION_GRANTED && 4195 checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES) 4196 != PackageManager.PERMISSION_GRANTED) { 4197 String msg = "Permission Denial: killBackgroundProcesses() from pid=" 4198 + Binder.getCallingPid() 4199 + ", uid=" + Binder.getCallingUid() 4200 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 4201 Slog.w(TAG, msg); 4202 throw new SecurityException(msg); 4203 } 4204 4205 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 4206 userId, true, true, "killBackgroundProcesses", null); 4207 long callingId = Binder.clearCallingIdentity(); 4208 try { 4209 IPackageManager pm = AppGlobals.getPackageManager(); 4210 synchronized(this) { 4211 int appId = -1; 4212 try { 4213 appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0)); 4214 } catch (RemoteException e) { 4215 } 4216 if (appId == -1) { 4217 Slog.w(TAG, "Invalid packageName: " + packageName); 4218 return; 4219 } 4220 killPackageProcessesLocked(packageName, appId, userId, 4221 ProcessList.SERVICE_ADJ, false, true, true, false, "kill background"); 4222 } 4223 } finally { 4224 Binder.restoreCallingIdentity(callingId); 4225 } 4226 } 4227 4228 @Override 4229 public void killAllBackgroundProcesses() { 4230 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 4231 != PackageManager.PERMISSION_GRANTED) { 4232 String msg = "Permission Denial: killAllBackgroundProcesses() from pid=" 4233 + Binder.getCallingPid() 4234 + ", uid=" + Binder.getCallingUid() 4235 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 4236 Slog.w(TAG, msg); 4237 throw new SecurityException(msg); 4238 } 4239 4240 long callingId = Binder.clearCallingIdentity(); 4241 try { 4242 synchronized(this) { 4243 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 4244 final int NP = mProcessNames.getMap().size(); 4245 for (int ip=0; ip<NP; ip++) { 4246 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 4247 final int NA = apps.size(); 4248 for (int ia=0; ia<NA; ia++) { 4249 ProcessRecord app = apps.valueAt(ia); 4250 if (app.persistent) { 4251 // we don't kill persistent processes 4252 continue; 4253 } 4254 if (app.removed) { 4255 procs.add(app); 4256 } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 4257 app.removed = true; 4258 procs.add(app); 4259 } 4260 } 4261 } 4262 4263 int N = procs.size(); 4264 for (int i=0; i<N; i++) { 4265 removeProcessLocked(procs.get(i), false, true, "kill all background"); 4266 } 4267 mAllowLowerMemLevel = true; 4268 updateOomAdjLocked(); 4269 doLowMemReportIfNeededLocked(null); 4270 } 4271 } finally { 4272 Binder.restoreCallingIdentity(callingId); 4273 } 4274 } 4275 4276 @Override 4277 public void forceStopPackage(final String packageName, int userId) { 4278 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 4279 != PackageManager.PERMISSION_GRANTED) { 4280 String msg = "Permission Denial: forceStopPackage() from pid=" 4281 + Binder.getCallingPid() 4282 + ", uid=" + Binder.getCallingUid() 4283 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 4284 Slog.w(TAG, msg); 4285 throw new SecurityException(msg); 4286 } 4287 final int callingPid = Binder.getCallingPid(); 4288 userId = handleIncomingUser(callingPid, Binder.getCallingUid(), 4289 userId, true, true, "forceStopPackage", null); 4290 long callingId = Binder.clearCallingIdentity(); 4291 try { 4292 IPackageManager pm = AppGlobals.getPackageManager(); 4293 synchronized(this) { 4294 int[] users = userId == UserHandle.USER_ALL 4295 ? getUsersLocked() : new int[] { userId }; 4296 for (int user : users) { 4297 int pkgUid = -1; 4298 try { 4299 pkgUid = pm.getPackageUid(packageName, user); 4300 } catch (RemoteException e) { 4301 } 4302 if (pkgUid == -1) { 4303 Slog.w(TAG, "Invalid packageName: " + packageName); 4304 continue; 4305 } 4306 try { 4307 pm.setPackageStoppedState(packageName, true, user); 4308 } catch (RemoteException e) { 4309 } catch (IllegalArgumentException e) { 4310 Slog.w(TAG, "Failed trying to unstop package " 4311 + packageName + ": " + e); 4312 } 4313 if (isUserRunningLocked(user, false)) { 4314 forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid); 4315 } 4316 } 4317 } 4318 } finally { 4319 Binder.restoreCallingIdentity(callingId); 4320 } 4321 } 4322 4323 /* 4324 * The pkg name and app id have to be specified. 4325 */ 4326 @Override 4327 public void killApplicationWithAppId(String pkg, int appid, String reason) { 4328 if (pkg == null) { 4329 return; 4330 } 4331 // Make sure the uid is valid. 4332 if (appid < 0) { 4333 Slog.w(TAG, "Invalid appid specified for pkg : " + pkg); 4334 return; 4335 } 4336 int callerUid = Binder.getCallingUid(); 4337 // Only the system server can kill an application 4338 if (callerUid == Process.SYSTEM_UID) { 4339 // Post an aysnc message to kill the application 4340 Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG); 4341 msg.arg1 = appid; 4342 msg.arg2 = 0; 4343 Bundle bundle = new Bundle(); 4344 bundle.putString("pkg", pkg); 4345 bundle.putString("reason", reason); 4346 msg.obj = bundle; 4347 mHandler.sendMessage(msg); 4348 } else { 4349 throw new SecurityException(callerUid + " cannot kill pkg: " + 4350 pkg); 4351 } 4352 } 4353 4354 @Override 4355 public void closeSystemDialogs(String reason) { 4356 enforceNotIsolatedCaller("closeSystemDialogs"); 4357 4358 final int pid = Binder.getCallingPid(); 4359 final int uid = Binder.getCallingUid(); 4360 final long origId = Binder.clearCallingIdentity(); 4361 try { 4362 synchronized (this) { 4363 // Only allow this from foreground processes, so that background 4364 // applications can't abuse it to prevent system UI from being shown. 4365 if (uid >= Process.FIRST_APPLICATION_UID) { 4366 ProcessRecord proc; 4367 synchronized (mPidsSelfLocked) { 4368 proc = mPidsSelfLocked.get(pid); 4369 } 4370 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 4371 Slog.w(TAG, "Ignoring closeSystemDialogs " + reason 4372 + " from background process " + proc); 4373 return; 4374 } 4375 } 4376 closeSystemDialogsLocked(reason); 4377 } 4378 } finally { 4379 Binder.restoreCallingIdentity(origId); 4380 } 4381 } 4382 4383 void closeSystemDialogsLocked(String reason) { 4384 Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS); 4385 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 4386 | Intent.FLAG_RECEIVER_FOREGROUND); 4387 if (reason != null) { 4388 intent.putExtra("reason", reason); 4389 } 4390 mWindowManager.closeSystemDialogs(reason); 4391 4392 mStackSupervisor.closeSystemDialogsLocked(); 4393 4394 broadcastIntentLocked(null, null, intent, null, 4395 null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1, 4396 Process.SYSTEM_UID, UserHandle.USER_ALL); 4397 } 4398 4399 @Override 4400 public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) { 4401 enforceNotIsolatedCaller("getProcessMemoryInfo"); 4402 Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length]; 4403 for (int i=pids.length-1; i>=0; i--) { 4404 ProcessRecord proc; 4405 int oomAdj; 4406 synchronized (this) { 4407 synchronized (mPidsSelfLocked) { 4408 proc = mPidsSelfLocked.get(pids[i]); 4409 oomAdj = proc != null ? proc.setAdj : 0; 4410 } 4411 } 4412 infos[i] = new Debug.MemoryInfo(); 4413 Debug.getMemoryInfo(pids[i], infos[i]); 4414 if (proc != null) { 4415 synchronized (this) { 4416 if (proc.thread != null && proc.setAdj == oomAdj) { 4417 // Record this for posterity if the process has been stable. 4418 proc.baseProcessTracker.addPss(infos[i].getTotalPss(), 4419 infos[i].getTotalUss(), false, proc.pkgList); 4420 } 4421 } 4422 } 4423 } 4424 return infos; 4425 } 4426 4427 @Override 4428 public long[] getProcessPss(int[] pids) { 4429 enforceNotIsolatedCaller("getProcessPss"); 4430 long[] pss = new long[pids.length]; 4431 for (int i=pids.length-1; i>=0; i--) { 4432 ProcessRecord proc; 4433 int oomAdj; 4434 synchronized (this) { 4435 synchronized (mPidsSelfLocked) { 4436 proc = mPidsSelfLocked.get(pids[i]); 4437 oomAdj = proc != null ? proc.setAdj : 0; 4438 } 4439 } 4440 long[] tmpUss = new long[1]; 4441 pss[i] = Debug.getPss(pids[i], tmpUss); 4442 if (proc != null) { 4443 synchronized (this) { 4444 if (proc.thread != null && proc.setAdj == oomAdj) { 4445 // Record this for posterity if the process has been stable. 4446 proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList); 4447 } 4448 } 4449 } 4450 } 4451 return pss; 4452 } 4453 4454 @Override 4455 public void killApplicationProcess(String processName, int uid) { 4456 if (processName == null) { 4457 return; 4458 } 4459 4460 int callerUid = Binder.getCallingUid(); 4461 // Only the system server can kill an application 4462 if (callerUid == Process.SYSTEM_UID) { 4463 synchronized (this) { 4464 ProcessRecord app = getProcessRecordLocked(processName, uid, true); 4465 if (app != null && app.thread != null) { 4466 try { 4467 app.thread.scheduleSuicide(); 4468 } catch (RemoteException e) { 4469 // If the other end already died, then our work here is done. 4470 } 4471 } else { 4472 Slog.w(TAG, "Process/uid not found attempting kill of " 4473 + processName + " / " + uid); 4474 } 4475 } 4476 } else { 4477 throw new SecurityException(callerUid + " cannot kill app process: " + 4478 processName); 4479 } 4480 } 4481 4482 private void forceStopPackageLocked(final String packageName, int uid, String reason) { 4483 forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false, 4484 false, true, false, false, UserHandle.getUserId(uid), reason); 4485 Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED, 4486 Uri.fromParts("package", packageName, null)); 4487 if (!mProcessesReady) { 4488 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 4489 | Intent.FLAG_RECEIVER_FOREGROUND); 4490 } 4491 intent.putExtra(Intent.EXTRA_UID, uid); 4492 intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid)); 4493 broadcastIntentLocked(null, null, intent, 4494 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 4495 false, false, 4496 MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid)); 4497 } 4498 4499 private void forceStopUserLocked(int userId, String reason) { 4500 forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason); 4501 Intent intent = new Intent(Intent.ACTION_USER_STOPPED); 4502 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 4503 | Intent.FLAG_RECEIVER_FOREGROUND); 4504 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 4505 broadcastIntentLocked(null, null, intent, 4506 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 4507 false, false, 4508 MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 4509 } 4510 4511 private final boolean killPackageProcessesLocked(String packageName, int appId, 4512 int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart, 4513 boolean doit, boolean evenPersistent, String reason) { 4514 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 4515 4516 // Remove all processes this package may have touched: all with the 4517 // same UID (except for the system or root user), and all whose name 4518 // matches the package name. 4519 final String procNamePrefix = packageName != null ? (packageName + ":") : null; 4520 final int NP = mProcessNames.getMap().size(); 4521 for (int ip=0; ip<NP; ip++) { 4522 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 4523 final int NA = apps.size(); 4524 for (int ia=0; ia<NA; ia++) { 4525 ProcessRecord app = apps.valueAt(ia); 4526 if (app.persistent && !evenPersistent) { 4527 // we don't kill persistent processes 4528 continue; 4529 } 4530 if (app.removed) { 4531 if (doit) { 4532 procs.add(app); 4533 } 4534 continue; 4535 } 4536 4537 // Skip process if it doesn't meet our oom adj requirement. 4538 if (app.setAdj < minOomAdj) { 4539 continue; 4540 } 4541 4542 // If no package is specified, we call all processes under the 4543 // give user id. 4544 if (packageName == null) { 4545 if (app.userId != userId) { 4546 continue; 4547 } 4548 if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) { 4549 continue; 4550 } 4551 // Package has been specified, we want to hit all processes 4552 // that match it. We need to qualify this by the processes 4553 // that are running under the specified app and user ID. 4554 } else { 4555 if (UserHandle.getAppId(app.uid) != appId) { 4556 continue; 4557 } 4558 if (userId != UserHandle.USER_ALL && app.userId != userId) { 4559 continue; 4560 } 4561 if (!app.pkgList.containsKey(packageName)) { 4562 continue; 4563 } 4564 } 4565 4566 // Process has passed all conditions, kill it! 4567 if (!doit) { 4568 return true; 4569 } 4570 app.removed = true; 4571 procs.add(app); 4572 } 4573 } 4574 4575 int N = procs.size(); 4576 for (int i=0; i<N; i++) { 4577 removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason); 4578 } 4579 updateOomAdjLocked(); 4580 return N > 0; 4581 } 4582 4583 private final boolean forceStopPackageLocked(String name, int appId, 4584 boolean callerWillRestart, boolean purgeCache, boolean doit, 4585 boolean evenPersistent, boolean uninstalling, int userId, String reason) { 4586 int i; 4587 int N; 4588 4589 if (userId == UserHandle.USER_ALL && name == null) { 4590 Slog.w(TAG, "Can't force stop all processes of all users, that is insane!"); 4591 } 4592 4593 if (appId < 0 && name != null) { 4594 try { 4595 appId = UserHandle.getAppId( 4596 AppGlobals.getPackageManager().getPackageUid(name, 0)); 4597 } catch (RemoteException e) { 4598 } 4599 } 4600 4601 if (doit) { 4602 if (name != null) { 4603 Slog.i(TAG, "Force stopping " + name + " appid=" + appId 4604 + " user=" + userId + ": " + reason); 4605 } else { 4606 Slog.i(TAG, "Force stopping u" + userId + ": " + reason); 4607 } 4608 4609 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap(); 4610 for (int ip=pmap.size()-1; ip>=0; ip--) { 4611 SparseArray<Long> ba = pmap.valueAt(ip); 4612 for (i=ba.size()-1; i>=0; i--) { 4613 boolean remove = false; 4614 final int entUid = ba.keyAt(i); 4615 if (name != null) { 4616 if (userId == UserHandle.USER_ALL) { 4617 if (UserHandle.getAppId(entUid) == appId) { 4618 remove = true; 4619 } 4620 } else { 4621 if (entUid == UserHandle.getUid(userId, appId)) { 4622 remove = true; 4623 } 4624 } 4625 } else if (UserHandle.getUserId(entUid) == userId) { 4626 remove = true; 4627 } 4628 if (remove) { 4629 ba.removeAt(i); 4630 } 4631 } 4632 if (ba.size() == 0) { 4633 pmap.removeAt(ip); 4634 } 4635 } 4636 } 4637 4638 boolean didSomething = killPackageProcessesLocked(name, appId, userId, 4639 -100, callerWillRestart, true, doit, evenPersistent, 4640 name == null ? ("stop user " + userId) : ("stop " + name)); 4641 4642 if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) { 4643 if (!doit) { 4644 return true; 4645 } 4646 didSomething = true; 4647 } 4648 4649 if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) { 4650 if (!doit) { 4651 return true; 4652 } 4653 didSomething = true; 4654 } 4655 4656 if (name == null) { 4657 // Remove all sticky broadcasts from this user. 4658 mStickyBroadcasts.remove(userId); 4659 } 4660 4661 ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>(); 4662 if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent, 4663 userId, providers)) { 4664 if (!doit) { 4665 return true; 4666 } 4667 didSomething = true; 4668 } 4669 N = providers.size(); 4670 for (i=0; i<N; i++) { 4671 removeDyingProviderLocked(null, providers.get(i), true); 4672 } 4673 4674 // Remove transient permissions granted from/to this package/user 4675 removeUriPermissionsForPackageLocked(name, userId, false); 4676 4677 if (name == null || uninstalling) { 4678 // Remove pending intents. For now we only do this when force 4679 // stopping users, because we have some problems when doing this 4680 // for packages -- app widgets are not currently cleaned up for 4681 // such packages, so they can be left with bad pending intents. 4682 if (mIntentSenderRecords.size() > 0) { 4683 Iterator<WeakReference<PendingIntentRecord>> it 4684 = mIntentSenderRecords.values().iterator(); 4685 while (it.hasNext()) { 4686 WeakReference<PendingIntentRecord> wpir = it.next(); 4687 if (wpir == null) { 4688 it.remove(); 4689 continue; 4690 } 4691 PendingIntentRecord pir = wpir.get(); 4692 if (pir == null) { 4693 it.remove(); 4694 continue; 4695 } 4696 if (name == null) { 4697 // Stopping user, remove all objects for the user. 4698 if (pir.key.userId != userId) { 4699 // Not the same user, skip it. 4700 continue; 4701 } 4702 } else { 4703 if (UserHandle.getAppId(pir.uid) != appId) { 4704 // Different app id, skip it. 4705 continue; 4706 } 4707 if (userId != UserHandle.USER_ALL && pir.key.userId != userId) { 4708 // Different user, skip it. 4709 continue; 4710 } 4711 if (!pir.key.packageName.equals(name)) { 4712 // Different package, skip it. 4713 continue; 4714 } 4715 } 4716 if (!doit) { 4717 return true; 4718 } 4719 didSomething = true; 4720 it.remove(); 4721 pir.canceled = true; 4722 if (pir.key.activity != null) { 4723 pir.key.activity.pendingResults.remove(pir.ref); 4724 } 4725 } 4726 } 4727 } 4728 4729 if (doit) { 4730 if (purgeCache && name != null) { 4731 AttributeCache ac = AttributeCache.instance(); 4732 if (ac != null) { 4733 ac.removePackage(name); 4734 } 4735 } 4736 if (mBooted) { 4737 mStackSupervisor.resumeTopActivitiesLocked(); 4738 mStackSupervisor.scheduleIdleLocked(); 4739 } 4740 } 4741 4742 return didSomething; 4743 } 4744 4745 private final boolean removeProcessLocked(ProcessRecord app, 4746 boolean callerWillRestart, boolean allowRestart, String reason) { 4747 final String name = app.processName; 4748 final int uid = app.uid; 4749 if (DEBUG_PROCESSES) Slog.d( 4750 TAG, "Force removing proc " + app.toShortString() + " (" + name 4751 + "/" + uid + ")"); 4752 4753 mProcessNames.remove(name, uid); 4754 mIsolatedProcesses.remove(app.uid); 4755 if (mHeavyWeightProcess == app) { 4756 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 4757 mHeavyWeightProcess.userId, 0)); 4758 mHeavyWeightProcess = null; 4759 } 4760 boolean needRestart = false; 4761 if (app.pid > 0 && app.pid != MY_PID) { 4762 int pid = app.pid; 4763 synchronized (mPidsSelfLocked) { 4764 mPidsSelfLocked.remove(pid); 4765 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 4766 } 4767 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH, 4768 app.processName, app.info.uid); 4769 if (app.isolated) { 4770 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 4771 } 4772 killUnneededProcessLocked(app, reason); 4773 handleAppDiedLocked(app, true, allowRestart); 4774 removeLruProcessLocked(app); 4775 4776 if (app.persistent && !app.isolated) { 4777 if (!callerWillRestart) { 4778 addAppLocked(app.info, false); 4779 } else { 4780 needRestart = true; 4781 } 4782 } 4783 } else { 4784 mRemovedProcesses.add(app); 4785 } 4786 4787 return needRestart; 4788 } 4789 4790 private final void processStartTimedOutLocked(ProcessRecord app) { 4791 final int pid = app.pid; 4792 boolean gone = false; 4793 synchronized (mPidsSelfLocked) { 4794 ProcessRecord knownApp = mPidsSelfLocked.get(pid); 4795 if (knownApp != null && knownApp.thread == null) { 4796 mPidsSelfLocked.remove(pid); 4797 gone = true; 4798 } 4799 } 4800 4801 if (gone) { 4802 Slog.w(TAG, "Process " + app + " failed to attach"); 4803 EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId, 4804 pid, app.uid, app.processName); 4805 mProcessNames.remove(app.processName, app.uid); 4806 mIsolatedProcesses.remove(app.uid); 4807 if (mHeavyWeightProcess == app) { 4808 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 4809 mHeavyWeightProcess.userId, 0)); 4810 mHeavyWeightProcess = null; 4811 } 4812 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH, 4813 app.processName, app.info.uid); 4814 if (app.isolated) { 4815 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 4816 } 4817 // Take care of any launching providers waiting for this process. 4818 checkAppInLaunchingProvidersLocked(app, true); 4819 // Take care of any services that are waiting for the process. 4820 mServices.processStartTimedOutLocked(app); 4821 killUnneededProcessLocked(app, "start timeout"); 4822 if (mBackupTarget != null && mBackupTarget.app.pid == pid) { 4823 Slog.w(TAG, "Unattached app died before backup, skipping"); 4824 try { 4825 IBackupManager bm = IBackupManager.Stub.asInterface( 4826 ServiceManager.getService(Context.BACKUP_SERVICE)); 4827 bm.agentDisconnected(app.info.packageName); 4828 } catch (RemoteException e) { 4829 // Can't happen; the backup manager is local 4830 } 4831 } 4832 if (isPendingBroadcastProcessLocked(pid)) { 4833 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 4834 skipPendingBroadcastLocked(pid); 4835 } 4836 } else { 4837 Slog.w(TAG, "Spurious process start timeout - pid not known for " + app); 4838 } 4839 } 4840 4841 private final boolean attachApplicationLocked(IApplicationThread thread, 4842 int pid) { 4843 4844 // Find the application record that is being attached... either via 4845 // the pid if we are running in multiple processes, or just pull the 4846 // next app record if we are emulating process with anonymous threads. 4847 ProcessRecord app; 4848 if (pid != MY_PID && pid >= 0) { 4849 synchronized (mPidsSelfLocked) { 4850 app = mPidsSelfLocked.get(pid); 4851 } 4852 } else { 4853 app = null; 4854 } 4855 4856 if (app == null) { 4857 Slog.w(TAG, "No pending application record for pid " + pid 4858 + " (IApplicationThread " + thread + "); dropping process"); 4859 EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid); 4860 if (pid > 0 && pid != MY_PID) { 4861 Process.killProcessQuiet(pid); 4862 } else { 4863 try { 4864 thread.scheduleExit(); 4865 } catch (Exception e) { 4866 // Ignore exceptions. 4867 } 4868 } 4869 return false; 4870 } 4871 4872 // If this application record is still attached to a previous 4873 // process, clean it up now. 4874 if (app.thread != null) { 4875 handleAppDiedLocked(app, true, true); 4876 } 4877 4878 // Tell the process all about itself. 4879 4880 if (localLOGV) Slog.v( 4881 TAG, "Binding process pid " + pid + " to record " + app); 4882 4883 final String processName = app.processName; 4884 try { 4885 AppDeathRecipient adr = new AppDeathRecipient( 4886 app, pid, thread); 4887 thread.asBinder().linkToDeath(adr, 0); 4888 app.deathRecipient = adr; 4889 } catch (RemoteException e) { 4890 app.resetPackageList(mProcessStats); 4891 startProcessLocked(app, "link fail", processName); 4892 return false; 4893 } 4894 4895 EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName); 4896 4897 app.makeActive(thread, mProcessStats); 4898 app.curAdj = app.setAdj = -100; 4899 app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT; 4900 app.forcingToForeground = null; 4901 updateProcessForegroundLocked(app, false, false); 4902 app.hasShownUi = false; 4903 app.debugging = false; 4904 app.cached = false; 4905 4906 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 4907 4908 boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info); 4909 List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null; 4910 4911 if (!normalMode) { 4912 Slog.i(TAG, "Launching preboot mode app: " + app); 4913 } 4914 4915 if (localLOGV) Slog.v( 4916 TAG, "New app record " + app 4917 + " thread=" + thread.asBinder() + " pid=" + pid); 4918 try { 4919 int testMode = IApplicationThread.DEBUG_OFF; 4920 if (mDebugApp != null && mDebugApp.equals(processName)) { 4921 testMode = mWaitForDebugger 4922 ? IApplicationThread.DEBUG_WAIT 4923 : IApplicationThread.DEBUG_ON; 4924 app.debugging = true; 4925 if (mDebugTransient) { 4926 mDebugApp = mOrigDebugApp; 4927 mWaitForDebugger = mOrigWaitForDebugger; 4928 } 4929 } 4930 String profileFile = app.instrumentationProfileFile; 4931 ParcelFileDescriptor profileFd = null; 4932 boolean profileAutoStop = false; 4933 if (mProfileApp != null && mProfileApp.equals(processName)) { 4934 mProfileProc = app; 4935 profileFile = mProfileFile; 4936 profileFd = mProfileFd; 4937 profileAutoStop = mAutoStopProfiler; 4938 } 4939 boolean enableOpenGlTrace = false; 4940 if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) { 4941 enableOpenGlTrace = true; 4942 mOpenGlTraceApp = null; 4943 } 4944 4945 // If the app is being launched for restore or full backup, set it up specially 4946 boolean isRestrictedBackupMode = false; 4947 if (mBackupTarget != null && mBackupAppName.equals(processName)) { 4948 isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE) 4949 || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL) 4950 || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL); 4951 } 4952 4953 ensurePackageDexOpt(app.instrumentationInfo != null 4954 ? app.instrumentationInfo.packageName 4955 : app.info.packageName); 4956 if (app.instrumentationClass != null) { 4957 ensurePackageDexOpt(app.instrumentationClass.getPackageName()); 4958 } 4959 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc " 4960 + processName + " with config " + mConfiguration); 4961 ApplicationInfo appInfo = app.instrumentationInfo != null 4962 ? app.instrumentationInfo : app.info; 4963 app.compat = compatibilityInfoForPackageLocked(appInfo); 4964 if (profileFd != null) { 4965 profileFd = profileFd.dup(); 4966 } 4967 thread.bindApplication(processName, appInfo, providers, 4968 app.instrumentationClass, profileFile, profileFd, profileAutoStop, 4969 app.instrumentationArguments, app.instrumentationWatcher, 4970 app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace, 4971 isRestrictedBackupMode || !normalMode, app.persistent, 4972 new Configuration(mConfiguration), app.compat, getCommonServicesLocked(), 4973 mCoreSettingsObserver.getCoreSettingsLocked()); 4974 updateLruProcessLocked(app, false, null); 4975 app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis(); 4976 } catch (Exception e) { 4977 // todo: Yikes! What should we do? For now we will try to 4978 // start another process, but that could easily get us in 4979 // an infinite loop of restarting processes... 4980 Slog.w(TAG, "Exception thrown during bind!", e); 4981 4982 app.resetPackageList(mProcessStats); 4983 app.unlinkDeathRecipient(); 4984 startProcessLocked(app, "bind fail", processName); 4985 return false; 4986 } 4987 4988 // Remove this record from the list of starting applications. 4989 mPersistentStartingProcesses.remove(app); 4990 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 4991 "Attach application locked removing on hold: " + app); 4992 mProcessesOnHold.remove(app); 4993 4994 boolean badApp = false; 4995 boolean didSomething = false; 4996 4997 // See if the top visible activity is waiting to run in this process... 4998 if (normalMode) { 4999 try { 5000 if (mStackSupervisor.attachApplicationLocked(app)) { 5001 didSomething = true; 5002 } 5003 } catch (Exception e) { 5004 badApp = true; 5005 } 5006 } 5007 5008 // Find any services that should be running in this process... 5009 if (!badApp) { 5010 try { 5011 didSomething |= mServices.attachApplicationLocked(app, processName); 5012 } catch (Exception e) { 5013 badApp = true; 5014 } 5015 } 5016 5017 // Check if a next-broadcast receiver is in this process... 5018 if (!badApp && isPendingBroadcastProcessLocked(pid)) { 5019 try { 5020 didSomething |= sendPendingBroadcastsLocked(app); 5021 } catch (Exception e) { 5022 // If the app died trying to launch the receiver we declare it 'bad' 5023 badApp = true; 5024 } 5025 } 5026 5027 // Check whether the next backup agent is in this process... 5028 if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) { 5029 if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app); 5030 ensurePackageDexOpt(mBackupTarget.appInfo.packageName); 5031 try { 5032 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo, 5033 compatibilityInfoForPackageLocked(mBackupTarget.appInfo), 5034 mBackupTarget.backupMode); 5035 } catch (Exception e) { 5036 Slog.w(TAG, "Exception scheduling backup agent creation: "); 5037 e.printStackTrace(); 5038 } 5039 } 5040 5041 if (badApp) { 5042 // todo: Also need to kill application to deal with all 5043 // kinds of exceptions. 5044 handleAppDiedLocked(app, false, true); 5045 return false; 5046 } 5047 5048 if (!didSomething) { 5049 updateOomAdjLocked(); 5050 } 5051 5052 return true; 5053 } 5054 5055 @Override 5056 public final void attachApplication(IApplicationThread thread) { 5057 synchronized (this) { 5058 int callingPid = Binder.getCallingPid(); 5059 final long origId = Binder.clearCallingIdentity(); 5060 attachApplicationLocked(thread, callingPid); 5061 Binder.restoreCallingIdentity(origId); 5062 } 5063 } 5064 5065 @Override 5066 public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) { 5067 final long origId = Binder.clearCallingIdentity(); 5068 synchronized (this) { 5069 ActivityStack stack = ActivityRecord.getStackLocked(token); 5070 if (stack != null) { 5071 ActivityRecord r = 5072 mStackSupervisor.activityIdleInternalLocked(token, false, config); 5073 if (stopProfiling) { 5074 if ((mProfileProc == r.app) && (mProfileFd != null)) { 5075 try { 5076 mProfileFd.close(); 5077 } catch (IOException e) { 5078 } 5079 clearProfilerLocked(); 5080 } 5081 } 5082 } 5083 } 5084 Binder.restoreCallingIdentity(origId); 5085 } 5086 5087 void enableScreenAfterBoot() { 5088 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN, 5089 SystemClock.uptimeMillis()); 5090 mWindowManager.enableScreenAfterBoot(); 5091 5092 synchronized (this) { 5093 updateEventDispatchingLocked(); 5094 } 5095 } 5096 5097 @Override 5098 public void showBootMessage(final CharSequence msg, final boolean always) { 5099 enforceNotIsolatedCaller("showBootMessage"); 5100 mWindowManager.showBootMessage(msg, always); 5101 } 5102 5103 @Override 5104 public void dismissKeyguardOnNextActivity() { 5105 enforceNotIsolatedCaller("dismissKeyguardOnNextActivity"); 5106 final long token = Binder.clearCallingIdentity(); 5107 try { 5108 synchronized (this) { 5109 if (DEBUG_LOCKSCREEN) logLockScreen(""); 5110 if (mLockScreenShown) { 5111 mLockScreenShown = false; 5112 comeOutOfSleepIfNeededLocked(); 5113 } 5114 mStackSupervisor.setDismissKeyguard(true); 5115 } 5116 } finally { 5117 Binder.restoreCallingIdentity(token); 5118 } 5119 } 5120 5121 final void finishBooting() { 5122 IntentFilter pkgFilter = new IntentFilter(); 5123 pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART); 5124 pkgFilter.addDataScheme("package"); 5125 mContext.registerReceiver(new BroadcastReceiver() { 5126 @Override 5127 public void onReceive(Context context, Intent intent) { 5128 String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES); 5129 if (pkgs != null) { 5130 for (String pkg : pkgs) { 5131 synchronized (ActivityManagerService.this) { 5132 if (forceStopPackageLocked(pkg, -1, false, false, false, false, false, 0, 5133 "finished booting")) { 5134 setResultCode(Activity.RESULT_OK); 5135 return; 5136 } 5137 } 5138 } 5139 } 5140 } 5141 }, pkgFilter); 5142 5143 synchronized (this) { 5144 // Ensure that any processes we had put on hold are now started 5145 // up. 5146 final int NP = mProcessesOnHold.size(); 5147 if (NP > 0) { 5148 ArrayList<ProcessRecord> procs = 5149 new ArrayList<ProcessRecord>(mProcessesOnHold); 5150 for (int ip=0; ip<NP; ip++) { 5151 if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: " 5152 + procs.get(ip)); 5153 startProcessLocked(procs.get(ip), "on-hold", null); 5154 } 5155 } 5156 5157 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 5158 // Start looking for apps that are abusing wake locks. 5159 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 5160 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 5161 // Tell anyone interested that we are done booting! 5162 SystemProperties.set("sys.boot_completed", "1"); 5163 SystemProperties.set("dev.bootcomplete", "1"); 5164 for (int i=0; i<mStartedUsers.size(); i++) { 5165 UserStartedState uss = mStartedUsers.valueAt(i); 5166 if (uss.mState == UserStartedState.STATE_BOOTING) { 5167 uss.mState = UserStartedState.STATE_RUNNING; 5168 final int userId = mStartedUsers.keyAt(i); 5169 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 5170 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 5171 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT); 5172 broadcastIntentLocked(null, null, intent, null, 5173 new IIntentReceiver.Stub() { 5174 @Override 5175 public void performReceive(Intent intent, int resultCode, 5176 String data, Bundle extras, boolean ordered, 5177 boolean sticky, int sendingUser) { 5178 synchronized (ActivityManagerService.this) { 5179 requestPssAllProcsLocked(SystemClock.uptimeMillis(), 5180 true, false); 5181 } 5182 } 5183 }, 5184 0, null, null, 5185 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, 5186 AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID, 5187 userId); 5188 } 5189 } 5190 scheduleStartRelatedUsersLocked(); 5191 } 5192 } 5193 } 5194 5195 final void ensureBootCompleted() { 5196 boolean booting; 5197 boolean enableScreen; 5198 synchronized (this) { 5199 booting = mBooting; 5200 mBooting = false; 5201 enableScreen = !mBooted; 5202 mBooted = true; 5203 } 5204 5205 if (booting) { 5206 finishBooting(); 5207 } 5208 5209 if (enableScreen) { 5210 enableScreenAfterBoot(); 5211 } 5212 } 5213 5214 @Override 5215 public final void activityResumed(IBinder token) { 5216 final long origId = Binder.clearCallingIdentity(); 5217 synchronized(this) { 5218 ActivityStack stack = ActivityRecord.getStackLocked(token); 5219 if (stack != null) { 5220 ActivityRecord.activityResumedLocked(token); 5221 } 5222 } 5223 Binder.restoreCallingIdentity(origId); 5224 } 5225 5226 @Override 5227 public final void activityPaused(IBinder token) { 5228 final long origId = Binder.clearCallingIdentity(); 5229 synchronized(this) { 5230 ActivityStack stack = ActivityRecord.getStackLocked(token); 5231 if (stack != null) { 5232 stack.activityPausedLocked(token, false); 5233 } 5234 } 5235 Binder.restoreCallingIdentity(origId); 5236 } 5237 5238 @Override 5239 public final void activityStopped(IBinder token, Bundle icicle, Bitmap thumbnail, 5240 CharSequence description) { 5241 if (localLOGV) Slog.v( 5242 TAG, "Activity stopped: token=" + token); 5243 5244 // Refuse possible leaked file descriptors 5245 if (icicle != null && icicle.hasFileDescriptors()) { 5246 throw new IllegalArgumentException("File descriptors passed in Bundle"); 5247 } 5248 5249 ActivityRecord r = null; 5250 5251 final long origId = Binder.clearCallingIdentity(); 5252 5253 synchronized (this) { 5254 r = ActivityRecord.isInStackLocked(token); 5255 if (r != null) { 5256 r.task.stack.activityStoppedLocked(r, icicle, thumbnail, description); 5257 } 5258 } 5259 5260 if (r != null) { 5261 sendPendingThumbnail(r, null, null, null, false); 5262 } 5263 5264 trimApplications(); 5265 5266 Binder.restoreCallingIdentity(origId); 5267 } 5268 5269 @Override 5270 public final void activityDestroyed(IBinder token) { 5271 if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token); 5272 synchronized (this) { 5273 ActivityStack stack = ActivityRecord.getStackLocked(token); 5274 if (stack != null) { 5275 stack.activityDestroyedLocked(token); 5276 } 5277 } 5278 } 5279 5280 @Override 5281 public String getCallingPackage(IBinder token) { 5282 synchronized (this) { 5283 ActivityRecord r = getCallingRecordLocked(token); 5284 return r != null ? r.info.packageName : null; 5285 } 5286 } 5287 5288 @Override 5289 public ComponentName getCallingActivity(IBinder token) { 5290 synchronized (this) { 5291 ActivityRecord r = getCallingRecordLocked(token); 5292 return r != null ? r.intent.getComponent() : null; 5293 } 5294 } 5295 5296 private ActivityRecord getCallingRecordLocked(IBinder token) { 5297 ActivityRecord r = ActivityRecord.isInStackLocked(token); 5298 if (r == null) { 5299 return null; 5300 } 5301 return r.resultTo; 5302 } 5303 5304 @Override 5305 public ComponentName getActivityClassForToken(IBinder token) { 5306 synchronized(this) { 5307 ActivityRecord r = ActivityRecord.isInStackLocked(token); 5308 if (r == null) { 5309 return null; 5310 } 5311 return r.intent.getComponent(); 5312 } 5313 } 5314 5315 @Override 5316 public String getPackageForToken(IBinder token) { 5317 synchronized(this) { 5318 ActivityRecord r = ActivityRecord.isInStackLocked(token); 5319 if (r == null) { 5320 return null; 5321 } 5322 return r.packageName; 5323 } 5324 } 5325 5326 @Override 5327 public IIntentSender getIntentSender(int type, 5328 String packageName, IBinder token, String resultWho, 5329 int requestCode, Intent[] intents, String[] resolvedTypes, 5330 int flags, Bundle options, int userId) { 5331 enforceNotIsolatedCaller("getIntentSender"); 5332 // Refuse possible leaked file descriptors 5333 if (intents != null) { 5334 if (intents.length < 1) { 5335 throw new IllegalArgumentException("Intents array length must be >= 1"); 5336 } 5337 for (int i=0; i<intents.length; i++) { 5338 Intent intent = intents[i]; 5339 if (intent != null) { 5340 if (intent.hasFileDescriptors()) { 5341 throw new IllegalArgumentException("File descriptors passed in Intent"); 5342 } 5343 if (type == ActivityManager.INTENT_SENDER_BROADCAST && 5344 (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 5345 throw new IllegalArgumentException( 5346 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 5347 } 5348 intents[i] = new Intent(intent); 5349 } 5350 } 5351 if (resolvedTypes != null && resolvedTypes.length != intents.length) { 5352 throw new IllegalArgumentException( 5353 "Intent array length does not match resolvedTypes length"); 5354 } 5355 } 5356 if (options != null) { 5357 if (options.hasFileDescriptors()) { 5358 throw new IllegalArgumentException("File descriptors passed in options"); 5359 } 5360 } 5361 5362 synchronized(this) { 5363 int callingUid = Binder.getCallingUid(); 5364 int origUserId = userId; 5365 userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId, 5366 type == ActivityManager.INTENT_SENDER_BROADCAST, false, 5367 "getIntentSender", null); 5368 if (origUserId == UserHandle.USER_CURRENT) { 5369 // We don't want to evaluate this until the pending intent is 5370 // actually executed. However, we do want to always do the 5371 // security checking for it above. 5372 userId = UserHandle.USER_CURRENT; 5373 } 5374 try { 5375 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 5376 int uid = AppGlobals.getPackageManager() 5377 .getPackageUid(packageName, UserHandle.getUserId(callingUid)); 5378 if (!UserHandle.isSameApp(callingUid, uid)) { 5379 String msg = "Permission Denial: getIntentSender() from pid=" 5380 + Binder.getCallingPid() 5381 + ", uid=" + Binder.getCallingUid() 5382 + ", (need uid=" + uid + ")" 5383 + " is not allowed to send as package " + packageName; 5384 Slog.w(TAG, msg); 5385 throw new SecurityException(msg); 5386 } 5387 } 5388 5389 return getIntentSenderLocked(type, packageName, callingUid, userId, 5390 token, resultWho, requestCode, intents, resolvedTypes, flags, options); 5391 5392 } catch (RemoteException e) { 5393 throw new SecurityException(e); 5394 } 5395 } 5396 } 5397 5398 IIntentSender getIntentSenderLocked(int type, String packageName, 5399 int callingUid, int userId, IBinder token, String resultWho, 5400 int requestCode, Intent[] intents, String[] resolvedTypes, int flags, 5401 Bundle options) { 5402 if (DEBUG_MU) 5403 Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid); 5404 ActivityRecord activity = null; 5405 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 5406 activity = ActivityRecord.isInStackLocked(token); 5407 if (activity == null) { 5408 return null; 5409 } 5410 if (activity.finishing) { 5411 return null; 5412 } 5413 } 5414 5415 final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0; 5416 final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0; 5417 final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0; 5418 flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT 5419 |PendingIntent.FLAG_UPDATE_CURRENT); 5420 5421 PendingIntentRecord.Key key = new PendingIntentRecord.Key( 5422 type, packageName, activity, resultWho, 5423 requestCode, intents, resolvedTypes, flags, options, userId); 5424 WeakReference<PendingIntentRecord> ref; 5425 ref = mIntentSenderRecords.get(key); 5426 PendingIntentRecord rec = ref != null ? ref.get() : null; 5427 if (rec != null) { 5428 if (!cancelCurrent) { 5429 if (updateCurrent) { 5430 if (rec.key.requestIntent != null) { 5431 rec.key.requestIntent.replaceExtras(intents != null ? 5432 intents[intents.length - 1] : null); 5433 } 5434 if (intents != null) { 5435 intents[intents.length-1] = rec.key.requestIntent; 5436 rec.key.allIntents = intents; 5437 rec.key.allResolvedTypes = resolvedTypes; 5438 } else { 5439 rec.key.allIntents = null; 5440 rec.key.allResolvedTypes = null; 5441 } 5442 } 5443 return rec; 5444 } 5445 rec.canceled = true; 5446 mIntentSenderRecords.remove(key); 5447 } 5448 if (noCreate) { 5449 return rec; 5450 } 5451 rec = new PendingIntentRecord(this, key, callingUid); 5452 mIntentSenderRecords.put(key, rec.ref); 5453 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 5454 if (activity.pendingResults == null) { 5455 activity.pendingResults 5456 = new HashSet<WeakReference<PendingIntentRecord>>(); 5457 } 5458 activity.pendingResults.add(rec.ref); 5459 } 5460 return rec; 5461 } 5462 5463 @Override 5464 public void cancelIntentSender(IIntentSender sender) { 5465 if (!(sender instanceof PendingIntentRecord)) { 5466 return; 5467 } 5468 synchronized(this) { 5469 PendingIntentRecord rec = (PendingIntentRecord)sender; 5470 try { 5471 int uid = AppGlobals.getPackageManager() 5472 .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId()); 5473 if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) { 5474 String msg = "Permission Denial: cancelIntentSender() from pid=" 5475 + Binder.getCallingPid() 5476 + ", uid=" + Binder.getCallingUid() 5477 + " is not allowed to cancel packges " 5478 + rec.key.packageName; 5479 Slog.w(TAG, msg); 5480 throw new SecurityException(msg); 5481 } 5482 } catch (RemoteException e) { 5483 throw new SecurityException(e); 5484 } 5485 cancelIntentSenderLocked(rec, true); 5486 } 5487 } 5488 5489 void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) { 5490 rec.canceled = true; 5491 mIntentSenderRecords.remove(rec.key); 5492 if (cleanActivity && rec.key.activity != null) { 5493 rec.key.activity.pendingResults.remove(rec.ref); 5494 } 5495 } 5496 5497 @Override 5498 public String getPackageForIntentSender(IIntentSender pendingResult) { 5499 if (!(pendingResult instanceof PendingIntentRecord)) { 5500 return null; 5501 } 5502 try { 5503 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5504 return res.key.packageName; 5505 } catch (ClassCastException e) { 5506 } 5507 return null; 5508 } 5509 5510 @Override 5511 public int getUidForIntentSender(IIntentSender sender) { 5512 if (sender instanceof PendingIntentRecord) { 5513 try { 5514 PendingIntentRecord res = (PendingIntentRecord)sender; 5515 return res.uid; 5516 } catch (ClassCastException e) { 5517 } 5518 } 5519 return -1; 5520 } 5521 5522 @Override 5523 public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) { 5524 if (!(pendingResult instanceof PendingIntentRecord)) { 5525 return false; 5526 } 5527 try { 5528 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5529 if (res.key.allIntents == null) { 5530 return false; 5531 } 5532 for (int i=0; i<res.key.allIntents.length; i++) { 5533 Intent intent = res.key.allIntents[i]; 5534 if (intent.getPackage() != null && intent.getComponent() != null) { 5535 return false; 5536 } 5537 } 5538 return true; 5539 } catch (ClassCastException e) { 5540 } 5541 return false; 5542 } 5543 5544 @Override 5545 public boolean isIntentSenderAnActivity(IIntentSender pendingResult) { 5546 if (!(pendingResult instanceof PendingIntentRecord)) { 5547 return false; 5548 } 5549 try { 5550 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5551 if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) { 5552 return true; 5553 } 5554 return false; 5555 } catch (ClassCastException e) { 5556 } 5557 return false; 5558 } 5559 5560 @Override 5561 public Intent getIntentForIntentSender(IIntentSender pendingResult) { 5562 if (!(pendingResult instanceof PendingIntentRecord)) { 5563 return null; 5564 } 5565 try { 5566 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5567 return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null; 5568 } catch (ClassCastException e) { 5569 } 5570 return null; 5571 } 5572 5573 @Override 5574 public String getTagForIntentSender(IIntentSender pendingResult, String prefix) { 5575 if (!(pendingResult instanceof PendingIntentRecord)) { 5576 return null; 5577 } 5578 try { 5579 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5580 Intent intent = res.key.requestIntent; 5581 if (intent != null) { 5582 if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null 5583 || res.lastTagPrefix.equals(prefix))) { 5584 return res.lastTag; 5585 } 5586 res.lastTagPrefix = prefix; 5587 StringBuilder sb = new StringBuilder(128); 5588 if (prefix != null) { 5589 sb.append(prefix); 5590 } 5591 if (intent.getAction() != null) { 5592 sb.append(intent.getAction()); 5593 } else if (intent.getComponent() != null) { 5594 intent.getComponent().appendShortString(sb); 5595 } else { 5596 sb.append("?"); 5597 } 5598 return res.lastTag = sb.toString(); 5599 } 5600 } catch (ClassCastException e) { 5601 } 5602 return null; 5603 } 5604 5605 @Override 5606 public void setProcessLimit(int max) { 5607 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 5608 "setProcessLimit()"); 5609 synchronized (this) { 5610 mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max; 5611 mProcessLimitOverride = max; 5612 } 5613 trimApplications(); 5614 } 5615 5616 @Override 5617 public int getProcessLimit() { 5618 synchronized (this) { 5619 return mProcessLimitOverride; 5620 } 5621 } 5622 5623 void foregroundTokenDied(ForegroundToken token) { 5624 synchronized (ActivityManagerService.this) { 5625 synchronized (mPidsSelfLocked) { 5626 ForegroundToken cur 5627 = mForegroundProcesses.get(token.pid); 5628 if (cur != token) { 5629 return; 5630 } 5631 mForegroundProcesses.remove(token.pid); 5632 ProcessRecord pr = mPidsSelfLocked.get(token.pid); 5633 if (pr == null) { 5634 return; 5635 } 5636 pr.forcingToForeground = null; 5637 updateProcessForegroundLocked(pr, false, false); 5638 } 5639 updateOomAdjLocked(); 5640 } 5641 } 5642 5643 @Override 5644 public void setProcessForeground(IBinder token, int pid, boolean isForeground) { 5645 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 5646 "setProcessForeground()"); 5647 synchronized(this) { 5648 boolean changed = false; 5649 5650 synchronized (mPidsSelfLocked) { 5651 ProcessRecord pr = mPidsSelfLocked.get(pid); 5652 if (pr == null && isForeground) { 5653 Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid); 5654 return; 5655 } 5656 ForegroundToken oldToken = mForegroundProcesses.get(pid); 5657 if (oldToken != null) { 5658 oldToken.token.unlinkToDeath(oldToken, 0); 5659 mForegroundProcesses.remove(pid); 5660 if (pr != null) { 5661 pr.forcingToForeground = null; 5662 } 5663 changed = true; 5664 } 5665 if (isForeground && token != null) { 5666 ForegroundToken newToken = new ForegroundToken() { 5667 @Override 5668 public void binderDied() { 5669 foregroundTokenDied(this); 5670 } 5671 }; 5672 newToken.pid = pid; 5673 newToken.token = token; 5674 try { 5675 token.linkToDeath(newToken, 0); 5676 mForegroundProcesses.put(pid, newToken); 5677 pr.forcingToForeground = token; 5678 changed = true; 5679 } catch (RemoteException e) { 5680 // If the process died while doing this, we will later 5681 // do the cleanup with the process death link. 5682 } 5683 } 5684 } 5685 5686 if (changed) { 5687 updateOomAdjLocked(); 5688 } 5689 } 5690 } 5691 5692 // ========================================================= 5693 // PERMISSIONS 5694 // ========================================================= 5695 5696 static class PermissionController extends IPermissionController.Stub { 5697 ActivityManagerService mActivityManagerService; 5698 PermissionController(ActivityManagerService activityManagerService) { 5699 mActivityManagerService = activityManagerService; 5700 } 5701 5702 @Override 5703 public boolean checkPermission(String permission, int pid, int uid) { 5704 return mActivityManagerService.checkPermission(permission, pid, 5705 uid) == PackageManager.PERMISSION_GRANTED; 5706 } 5707 } 5708 5709 class IntentFirewallInterface implements IntentFirewall.AMSInterface { 5710 @Override 5711 public int checkComponentPermission(String permission, int pid, int uid, 5712 int owningUid, boolean exported) { 5713 return ActivityManagerService.this.checkComponentPermission(permission, pid, uid, 5714 owningUid, exported); 5715 } 5716 5717 @Override 5718 public Object getAMSLock() { 5719 return ActivityManagerService.this; 5720 } 5721 } 5722 5723 /** 5724 * This can be called with or without the global lock held. 5725 */ 5726 int checkComponentPermission(String permission, int pid, int uid, 5727 int owningUid, boolean exported) { 5728 // We might be performing an operation on behalf of an indirect binder 5729 // invocation, e.g. via {@link #openContentUri}. Check and adjust the 5730 // client identity accordingly before proceeding. 5731 Identity tlsIdentity = sCallerIdentity.get(); 5732 if (tlsIdentity != null) { 5733 Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {" 5734 + tlsIdentity.pid + "," + tlsIdentity.uid + "}"); 5735 uid = tlsIdentity.uid; 5736 pid = tlsIdentity.pid; 5737 } 5738 5739 if (pid == MY_PID) { 5740 return PackageManager.PERMISSION_GRANTED; 5741 } 5742 5743 return ActivityManager.checkComponentPermission(permission, uid, 5744 owningUid, exported); 5745 } 5746 5747 /** 5748 * As the only public entry point for permissions checking, this method 5749 * can enforce the semantic that requesting a check on a null global 5750 * permission is automatically denied. (Internally a null permission 5751 * string is used when calling {@link #checkComponentPermission} in cases 5752 * when only uid-based security is needed.) 5753 * 5754 * This can be called with or without the global lock held. 5755 */ 5756 @Override 5757 public int checkPermission(String permission, int pid, int uid) { 5758 if (permission == null) { 5759 return PackageManager.PERMISSION_DENIED; 5760 } 5761 return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true); 5762 } 5763 5764 /** 5765 * Binder IPC calls go through the public entry point. 5766 * This can be called with or without the global lock held. 5767 */ 5768 int checkCallingPermission(String permission) { 5769 return checkPermission(permission, 5770 Binder.getCallingPid(), 5771 UserHandle.getAppId(Binder.getCallingUid())); 5772 } 5773 5774 /** 5775 * This can be called with or without the global lock held. 5776 */ 5777 void enforceCallingPermission(String permission, String func) { 5778 if (checkCallingPermission(permission) 5779 == PackageManager.PERMISSION_GRANTED) { 5780 return; 5781 } 5782 5783 String msg = "Permission Denial: " + func + " from pid=" 5784 + Binder.getCallingPid() 5785 + ", uid=" + Binder.getCallingUid() 5786 + " requires " + permission; 5787 Slog.w(TAG, msg); 5788 throw new SecurityException(msg); 5789 } 5790 5791 /** 5792 * Determine if UID is holding permissions required to access {@link Uri} in 5793 * the given {@link ProviderInfo}. Final permission checking is always done 5794 * in {@link ContentProvider}. 5795 */ 5796 private final boolean checkHoldingPermissionsLocked( 5797 IPackageManager pm, ProviderInfo pi, Uri uri, int uid, int modeFlags) { 5798 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5799 "checkHoldingPermissionsLocked: uri=" + uri + " uid=" + uid); 5800 5801 if (pi.applicationInfo.uid == uid) { 5802 return true; 5803 } else if (!pi.exported) { 5804 return false; 5805 } 5806 5807 boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0; 5808 boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0; 5809 try { 5810 // check if target holds top-level <provider> permissions 5811 if (!readMet && pi.readPermission != null 5812 && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) { 5813 readMet = true; 5814 } 5815 if (!writeMet && pi.writePermission != null 5816 && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) { 5817 writeMet = true; 5818 } 5819 5820 // track if unprotected read/write is allowed; any denied 5821 // <path-permission> below removes this ability 5822 boolean allowDefaultRead = pi.readPermission == null; 5823 boolean allowDefaultWrite = pi.writePermission == null; 5824 5825 // check if target holds any <path-permission> that match uri 5826 final PathPermission[] pps = pi.pathPermissions; 5827 if (pps != null) { 5828 final String path = uri.getPath(); 5829 int i = pps.length; 5830 while (i > 0 && (!readMet || !writeMet)) { 5831 i--; 5832 PathPermission pp = pps[i]; 5833 if (pp.match(path)) { 5834 if (!readMet) { 5835 final String pprperm = pp.getReadPermission(); 5836 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for " 5837 + pprperm + " for " + pp.getPath() 5838 + ": match=" + pp.match(path) 5839 + " check=" + pm.checkUidPermission(pprperm, uid)); 5840 if (pprperm != null) { 5841 if (pm.checkUidPermission(pprperm, uid) == PERMISSION_GRANTED) { 5842 readMet = true; 5843 } else { 5844 allowDefaultRead = false; 5845 } 5846 } 5847 } 5848 if (!writeMet) { 5849 final String ppwperm = pp.getWritePermission(); 5850 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm " 5851 + ppwperm + " for " + pp.getPath() 5852 + ": match=" + pp.match(path) 5853 + " check=" + pm.checkUidPermission(ppwperm, uid)); 5854 if (ppwperm != null) { 5855 if (pm.checkUidPermission(ppwperm, uid) == PERMISSION_GRANTED) { 5856 writeMet = true; 5857 } else { 5858 allowDefaultWrite = false; 5859 } 5860 } 5861 } 5862 } 5863 } 5864 } 5865 5866 // grant unprotected <provider> read/write, if not blocked by 5867 // <path-permission> above 5868 if (allowDefaultRead) readMet = true; 5869 if (allowDefaultWrite) writeMet = true; 5870 5871 } catch (RemoteException e) { 5872 return false; 5873 } 5874 5875 return readMet && writeMet; 5876 } 5877 5878 private ProviderInfo getProviderInfoLocked(String authority, int userHandle) { 5879 ProviderInfo pi = null; 5880 ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle); 5881 if (cpr != null) { 5882 pi = cpr.info; 5883 } else { 5884 try { 5885 pi = AppGlobals.getPackageManager().resolveContentProvider( 5886 authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle); 5887 } catch (RemoteException ex) { 5888 } 5889 } 5890 return pi; 5891 } 5892 5893 private UriPermission findUriPermissionLocked(int targetUid, Uri uri) { 5894 ArrayMap<Uri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid); 5895 if (targetUris != null) { 5896 return targetUris.get(uri); 5897 } else { 5898 return null; 5899 } 5900 } 5901 5902 private UriPermission findOrCreateUriPermissionLocked( 5903 String sourcePkg, String targetPkg, int targetUid, Uri uri) { 5904 ArrayMap<Uri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid); 5905 if (targetUris == null) { 5906 targetUris = Maps.newArrayMap(); 5907 mGrantedUriPermissions.put(targetUid, targetUris); 5908 } 5909 5910 UriPermission perm = targetUris.get(uri); 5911 if (perm == null) { 5912 perm = new UriPermission(sourcePkg, targetPkg, targetUid, uri); 5913 targetUris.put(uri, perm); 5914 } 5915 5916 return perm; 5917 } 5918 5919 private final boolean checkUriPermissionLocked( 5920 Uri uri, int uid, int modeFlags, int minStrength) { 5921 // Root gets to do everything. 5922 if (uid == 0) { 5923 return true; 5924 } 5925 ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(uid); 5926 if (perms == null) return false; 5927 UriPermission perm = perms.get(uri); 5928 if (perm == null) return false; 5929 return perm.getStrength(modeFlags) >= minStrength; 5930 } 5931 5932 @Override 5933 public int checkUriPermission(Uri uri, int pid, int uid, int modeFlags) { 5934 enforceNotIsolatedCaller("checkUriPermission"); 5935 5936 // Another redirected-binder-call permissions check as in 5937 // {@link checkComponentPermission}. 5938 Identity tlsIdentity = sCallerIdentity.get(); 5939 if (tlsIdentity != null) { 5940 uid = tlsIdentity.uid; 5941 pid = tlsIdentity.pid; 5942 } 5943 5944 // Our own process gets to do everything. 5945 if (pid == MY_PID) { 5946 return PackageManager.PERMISSION_GRANTED; 5947 } 5948 synchronized(this) { 5949 return checkUriPermissionLocked(uri, uid, modeFlags, UriPermission.STRENGTH_OWNED) 5950 ? PackageManager.PERMISSION_GRANTED 5951 : PackageManager.PERMISSION_DENIED; 5952 } 5953 } 5954 5955 /** 5956 * Check if the targetPkg can be granted permission to access uri by 5957 * the callingUid using the given modeFlags. Throws a security exception 5958 * if callingUid is not allowed to do this. Returns the uid of the target 5959 * if the URI permission grant should be performed; returns -1 if it is not 5960 * needed (for example targetPkg already has permission to access the URI). 5961 * If you already know the uid of the target, you can supply it in 5962 * lastTargetUid else set that to -1. 5963 */ 5964 int checkGrantUriPermissionLocked(int callingUid, String targetPkg, 5965 Uri uri, int modeFlags, int lastTargetUid) { 5966 final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0; 5967 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION 5968 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 5969 if (modeFlags == 0) { 5970 return -1; 5971 } 5972 5973 if (targetPkg != null) { 5974 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5975 "Checking grant " + targetPkg + " permission to " + uri); 5976 } 5977 5978 final IPackageManager pm = AppGlobals.getPackageManager(); 5979 5980 // If this is not a content: uri, we can't do anything with it. 5981 if (!ContentResolver.SCHEME_CONTENT.equals(uri.getScheme())) { 5982 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5983 "Can't grant URI permission for non-content URI: " + uri); 5984 return -1; 5985 } 5986 5987 final String authority = uri.getAuthority(); 5988 final ProviderInfo pi = getProviderInfoLocked(authority, UserHandle.getUserId(callingUid)); 5989 if (pi == null) { 5990 Slog.w(TAG, "No content provider found for permission check: " + uri.toSafeString()); 5991 return -1; 5992 } 5993 5994 int targetUid = lastTargetUid; 5995 if (targetUid < 0 && targetPkg != null) { 5996 try { 5997 targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid)); 5998 if (targetUid < 0) { 5999 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6000 "Can't grant URI permission no uid for: " + targetPkg); 6001 return -1; 6002 } 6003 } catch (RemoteException ex) { 6004 return -1; 6005 } 6006 } 6007 6008 if (targetUid >= 0) { 6009 // First... does the target actually need this permission? 6010 if (checkHoldingPermissionsLocked(pm, pi, uri, targetUid, modeFlags)) { 6011 // No need to grant the target this permission. 6012 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6013 "Target " + targetPkg + " already has full permission to " + uri); 6014 return -1; 6015 } 6016 } else { 6017 // First... there is no target package, so can anyone access it? 6018 boolean allowed = pi.exported; 6019 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) { 6020 if (pi.readPermission != null) { 6021 allowed = false; 6022 } 6023 } 6024 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) { 6025 if (pi.writePermission != null) { 6026 allowed = false; 6027 } 6028 } 6029 if (allowed) { 6030 return -1; 6031 } 6032 } 6033 6034 // Second... is the provider allowing granting of URI permissions? 6035 if (!pi.grantUriPermissions) { 6036 throw new SecurityException("Provider " + pi.packageName 6037 + "/" + pi.name 6038 + " does not allow granting of Uri permissions (uri " 6039 + uri + ")"); 6040 } 6041 if (pi.uriPermissionPatterns != null) { 6042 final int N = pi.uriPermissionPatterns.length; 6043 boolean allowed = false; 6044 for (int i=0; i<N; i++) { 6045 if (pi.uriPermissionPatterns[i] != null 6046 && pi.uriPermissionPatterns[i].match(uri.getPath())) { 6047 allowed = true; 6048 break; 6049 } 6050 } 6051 if (!allowed) { 6052 throw new SecurityException("Provider " + pi.packageName 6053 + "/" + pi.name 6054 + " does not allow granting of permission to path of Uri " 6055 + uri); 6056 } 6057 } 6058 6059 // Third... does the caller itself have permission to access 6060 // this uri? 6061 if (callingUid != Process.myUid()) { 6062 if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) { 6063 // Require they hold a strong enough Uri permission 6064 final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE 6065 : UriPermission.STRENGTH_OWNED; 6066 if (!checkUriPermissionLocked(uri, callingUid, modeFlags, minStrength)) { 6067 throw new SecurityException("Uid " + callingUid 6068 + " does not have permission to uri " + uri); 6069 } 6070 } 6071 } 6072 6073 return targetUid; 6074 } 6075 6076 @Override 6077 public int checkGrantUriPermission(int callingUid, String targetPkg, 6078 Uri uri, int modeFlags) { 6079 enforceNotIsolatedCaller("checkGrantUriPermission"); 6080 synchronized(this) { 6081 return checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1); 6082 } 6083 } 6084 6085 void grantUriPermissionUncheckedLocked( 6086 int targetUid, String targetPkg, Uri uri, int modeFlags, UriPermissionOwner owner) { 6087 final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0; 6088 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION 6089 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 6090 if (modeFlags == 0) { 6091 return; 6092 } 6093 6094 // So here we are: the caller has the assumed permission 6095 // to the uri, and the target doesn't. Let's now give this to 6096 // the target. 6097 6098 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6099 "Granting " + targetPkg + "/" + targetUid + " permission to " + uri); 6100 6101 final String authority = uri.getAuthority(); 6102 final ProviderInfo pi = getProviderInfoLocked(authority, UserHandle.getUserId(targetUid)); 6103 if (pi == null) { 6104 Slog.w(TAG, "No content provider found for grant: " + uri.toSafeString()); 6105 return; 6106 } 6107 6108 final UriPermission perm = findOrCreateUriPermissionLocked( 6109 pi.packageName, targetPkg, targetUid, uri); 6110 perm.grantModes(modeFlags, persistable, owner); 6111 } 6112 6113 void grantUriPermissionLocked(int callingUid, String targetPkg, Uri uri, 6114 int modeFlags, UriPermissionOwner owner) { 6115 if (targetPkg == null) { 6116 throw new NullPointerException("targetPkg"); 6117 } 6118 6119 int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1); 6120 if (targetUid < 0) { 6121 return; 6122 } 6123 6124 grantUriPermissionUncheckedLocked(targetUid, targetPkg, uri, modeFlags, owner); 6125 } 6126 6127 static class NeededUriGrants extends ArrayList<Uri> { 6128 final String targetPkg; 6129 final int targetUid; 6130 final int flags; 6131 6132 NeededUriGrants(String targetPkg, int targetUid, int flags) { 6133 this.targetPkg = targetPkg; 6134 this.targetUid = targetUid; 6135 this.flags = flags; 6136 } 6137 } 6138 6139 /** 6140 * Like checkGrantUriPermissionLocked, but takes an Intent. 6141 */ 6142 NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid, 6143 String targetPkg, Intent intent, int mode, NeededUriGrants needed) { 6144 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6145 "Checking URI perm to data=" + (intent != null ? intent.getData() : null) 6146 + " clip=" + (intent != null ? intent.getClipData() : null) 6147 + " from " + intent + "; flags=0x" 6148 + Integer.toHexString(intent != null ? intent.getFlags() : 0)); 6149 6150 if (targetPkg == null) { 6151 throw new NullPointerException("targetPkg"); 6152 } 6153 6154 if (intent == null) { 6155 return null; 6156 } 6157 Uri data = intent.getData(); 6158 ClipData clip = intent.getClipData(); 6159 if (data == null && clip == null) { 6160 return null; 6161 } 6162 6163 if (data != null) { 6164 int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, data, 6165 mode, needed != null ? needed.targetUid : -1); 6166 if (targetUid > 0) { 6167 if (needed == null) { 6168 needed = new NeededUriGrants(targetPkg, targetUid, mode); 6169 } 6170 needed.add(data); 6171 } 6172 } 6173 if (clip != null) { 6174 for (int i=0; i<clip.getItemCount(); i++) { 6175 Uri uri = clip.getItemAt(i).getUri(); 6176 if (uri != null) { 6177 int targetUid = -1; 6178 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri, 6179 mode, needed != null ? needed.targetUid : -1); 6180 if (targetUid > 0) { 6181 if (needed == null) { 6182 needed = new NeededUriGrants(targetPkg, targetUid, mode); 6183 } 6184 needed.add(uri); 6185 } 6186 } else { 6187 Intent clipIntent = clip.getItemAt(i).getIntent(); 6188 if (clipIntent != null) { 6189 NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked( 6190 callingUid, targetPkg, clipIntent, mode, needed); 6191 if (newNeeded != null) { 6192 needed = newNeeded; 6193 } 6194 } 6195 } 6196 } 6197 } 6198 6199 return needed; 6200 } 6201 6202 /** 6203 * Like grantUriPermissionUncheckedLocked, but takes an Intent. 6204 */ 6205 void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed, 6206 UriPermissionOwner owner) { 6207 if (needed != null) { 6208 for (int i=0; i<needed.size(); i++) { 6209 grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg, 6210 needed.get(i), needed.flags, owner); 6211 } 6212 } 6213 } 6214 6215 void grantUriPermissionFromIntentLocked(int callingUid, 6216 String targetPkg, Intent intent, UriPermissionOwner owner) { 6217 NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg, 6218 intent, intent != null ? intent.getFlags() : 0, null); 6219 if (needed == null) { 6220 return; 6221 } 6222 6223 grantUriPermissionUncheckedFromIntentLocked(needed, owner); 6224 } 6225 6226 @Override 6227 public void grantUriPermission(IApplicationThread caller, String targetPkg, 6228 Uri uri, int modeFlags) { 6229 enforceNotIsolatedCaller("grantUriPermission"); 6230 synchronized(this) { 6231 final ProcessRecord r = getRecordForAppLocked(caller); 6232 if (r == null) { 6233 throw new SecurityException("Unable to find app for caller " 6234 + caller 6235 + " when granting permission to uri " + uri); 6236 } 6237 if (targetPkg == null) { 6238 throw new IllegalArgumentException("null target"); 6239 } 6240 if (uri == null) { 6241 throw new IllegalArgumentException("null uri"); 6242 } 6243 6244 // Persistable only supported through Intents 6245 Preconditions.checkFlagsArgument(modeFlags, 6246 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 6247 6248 grantUriPermissionLocked(r.uid, targetPkg, uri, modeFlags, 6249 null); 6250 } 6251 } 6252 6253 void removeUriPermissionIfNeededLocked(UriPermission perm) { 6254 if ((perm.modeFlags&(Intent.FLAG_GRANT_READ_URI_PERMISSION 6255 |Intent.FLAG_GRANT_WRITE_URI_PERMISSION)) == 0) { 6256 ArrayMap<Uri, UriPermission> perms 6257 = mGrantedUriPermissions.get(perm.targetUid); 6258 if (perms != null) { 6259 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6260 "Removing " + perm.targetUid + " permission to " + perm.uri); 6261 perms.remove(perm.uri); 6262 if (perms.size() == 0) { 6263 mGrantedUriPermissions.remove(perm.targetUid); 6264 } 6265 } 6266 } 6267 } 6268 6269 private void revokeUriPermissionLocked(int callingUid, Uri uri, int modeFlags) { 6270 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + uri); 6271 6272 final IPackageManager pm = AppGlobals.getPackageManager(); 6273 final String authority = uri.getAuthority(); 6274 final ProviderInfo pi = getProviderInfoLocked(authority, UserHandle.getUserId(callingUid)); 6275 if (pi == null) { 6276 Slog.w(TAG, "No content provider found for permission revoke: " + uri.toSafeString()); 6277 return; 6278 } 6279 6280 // Does the caller have this permission on the URI? 6281 if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) { 6282 // Right now, if you are not the original owner of the permission, 6283 // you are not allowed to revoke it. 6284 //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) { 6285 throw new SecurityException("Uid " + callingUid 6286 + " does not have permission to uri " + uri); 6287 //} 6288 } 6289 6290 boolean persistChanged = false; 6291 6292 // Go through all of the permissions and remove any that match. 6293 final List<String> SEGMENTS = uri.getPathSegments(); 6294 if (SEGMENTS != null) { 6295 final int NS = SEGMENTS.size(); 6296 int N = mGrantedUriPermissions.size(); 6297 for (int i=0; i<N; i++) { 6298 ArrayMap<Uri, UriPermission> perms 6299 = mGrantedUriPermissions.valueAt(i); 6300 Iterator<UriPermission> it = perms.values().iterator(); 6301 toploop: 6302 while (it.hasNext()) { 6303 UriPermission perm = it.next(); 6304 Uri targetUri = perm.uri; 6305 if (!authority.equals(targetUri.getAuthority())) { 6306 continue; 6307 } 6308 List<String> targetSegments = targetUri.getPathSegments(); 6309 if (targetSegments == null) { 6310 continue; 6311 } 6312 if (targetSegments.size() < NS) { 6313 continue; 6314 } 6315 for (int j=0; j<NS; j++) { 6316 if (!SEGMENTS.get(j).equals(targetSegments.get(j))) { 6317 continue toploop; 6318 } 6319 } 6320 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6321 "Revoking " + perm.targetUid + " permission to " + perm.uri); 6322 persistChanged |= perm.clearModes(modeFlags, true); 6323 if (perm.modeFlags == 0) { 6324 it.remove(); 6325 } 6326 } 6327 if (perms.size() == 0) { 6328 mGrantedUriPermissions.remove( 6329 mGrantedUriPermissions.keyAt(i)); 6330 N--; 6331 i--; 6332 } 6333 } 6334 } 6335 6336 if (persistChanged) { 6337 schedulePersistUriGrants(); 6338 } 6339 } 6340 6341 @Override 6342 public void revokeUriPermission(IApplicationThread caller, Uri uri, 6343 int modeFlags) { 6344 enforceNotIsolatedCaller("revokeUriPermission"); 6345 synchronized(this) { 6346 final ProcessRecord r = getRecordForAppLocked(caller); 6347 if (r == null) { 6348 throw new SecurityException("Unable to find app for caller " 6349 + caller 6350 + " when revoking permission to uri " + uri); 6351 } 6352 if (uri == null) { 6353 Slog.w(TAG, "revokeUriPermission: null uri"); 6354 return; 6355 } 6356 6357 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION 6358 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 6359 if (modeFlags == 0) { 6360 return; 6361 } 6362 6363 final IPackageManager pm = AppGlobals.getPackageManager(); 6364 final String authority = uri.getAuthority(); 6365 final ProviderInfo pi = getProviderInfoLocked(authority, r.userId); 6366 if (pi == null) { 6367 Slog.w(TAG, "No content provider found for permission revoke: " 6368 + uri.toSafeString()); 6369 return; 6370 } 6371 6372 revokeUriPermissionLocked(r.uid, uri, modeFlags); 6373 } 6374 } 6375 6376 /** 6377 * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the 6378 * given package. 6379 * 6380 * @param packageName Package name to match, or {@code null} to apply to all 6381 * packages. 6382 * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply 6383 * to all users. 6384 * @param persistable If persistable grants should be removed. 6385 */ 6386 private void removeUriPermissionsForPackageLocked( 6387 String packageName, int userHandle, boolean persistable) { 6388 if (userHandle == UserHandle.USER_ALL && packageName == null) { 6389 throw new IllegalArgumentException("Must narrow by either package or user"); 6390 } 6391 6392 boolean persistChanged = false; 6393 6394 final int size = mGrantedUriPermissions.size(); 6395 for (int i = 0; i < size; i++) { 6396 // Only inspect grants matching user 6397 if (userHandle == UserHandle.USER_ALL 6398 || userHandle == UserHandle.getUserId(mGrantedUriPermissions.keyAt(i))) { 6399 final Iterator<UriPermission> it = mGrantedUriPermissions.valueAt(i) 6400 .values().iterator(); 6401 while (it.hasNext()) { 6402 final UriPermission perm = it.next(); 6403 6404 // Only inspect grants matching package 6405 if (packageName == null || perm.sourcePkg.equals(packageName) 6406 || perm.targetPkg.equals(packageName)) { 6407 persistChanged |= perm.clearModes(~0, persistable); 6408 6409 // Only remove when no modes remain; any persisted grants 6410 // will keep this alive. 6411 if (perm.modeFlags == 0) { 6412 it.remove(); 6413 } 6414 } 6415 } 6416 } 6417 } 6418 6419 if (persistChanged) { 6420 schedulePersistUriGrants(); 6421 } 6422 } 6423 6424 @Override 6425 public IBinder newUriPermissionOwner(String name) { 6426 enforceNotIsolatedCaller("newUriPermissionOwner"); 6427 synchronized(this) { 6428 UriPermissionOwner owner = new UriPermissionOwner(this, name); 6429 return owner.getExternalTokenLocked(); 6430 } 6431 } 6432 6433 @Override 6434 public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, 6435 Uri uri, int modeFlags) { 6436 synchronized(this) { 6437 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 6438 if (owner == null) { 6439 throw new IllegalArgumentException("Unknown owner: " + token); 6440 } 6441 if (fromUid != Binder.getCallingUid()) { 6442 if (Binder.getCallingUid() != Process.myUid()) { 6443 // Only system code can grant URI permissions on behalf 6444 // of other users. 6445 throw new SecurityException("nice try"); 6446 } 6447 } 6448 if (targetPkg == null) { 6449 throw new IllegalArgumentException("null target"); 6450 } 6451 if (uri == null) { 6452 throw new IllegalArgumentException("null uri"); 6453 } 6454 6455 grantUriPermissionLocked(fromUid, targetPkg, uri, modeFlags, owner); 6456 } 6457 } 6458 6459 @Override 6460 public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode) { 6461 synchronized(this) { 6462 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 6463 if (owner == null) { 6464 throw new IllegalArgumentException("Unknown owner: " + token); 6465 } 6466 6467 if (uri == null) { 6468 owner.removeUriPermissionsLocked(mode); 6469 } else { 6470 owner.removeUriPermissionLocked(uri, mode); 6471 } 6472 } 6473 } 6474 6475 private void schedulePersistUriGrants() { 6476 if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) { 6477 mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG), 6478 10 * DateUtils.SECOND_IN_MILLIS); 6479 } 6480 } 6481 6482 private void writeGrantedUriPermissions() { 6483 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()"); 6484 6485 // Snapshot permissions so we can persist without lock 6486 ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList(); 6487 synchronized (this) { 6488 final int size = mGrantedUriPermissions.size(); 6489 for (int i = 0 ; i < size; i++) { 6490 for (UriPermission perm : mGrantedUriPermissions.valueAt(i).values()) { 6491 if (perm.persistedModeFlags != 0) { 6492 persist.add(perm.snapshot()); 6493 } 6494 } 6495 } 6496 } 6497 6498 FileOutputStream fos = null; 6499 try { 6500 fos = mGrantFile.startWrite(); 6501 6502 XmlSerializer out = new FastXmlSerializer(); 6503 out.setOutput(fos, "utf-8"); 6504 out.startDocument(null, true); 6505 out.startTag(null, TAG_URI_GRANTS); 6506 for (UriPermission.Snapshot perm : persist) { 6507 out.startTag(null, TAG_URI_GRANT); 6508 writeIntAttribute(out, ATTR_USER_HANDLE, perm.userHandle); 6509 out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg); 6510 out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg); 6511 out.attribute(null, ATTR_URI, String.valueOf(perm.uri)); 6512 writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags); 6513 writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime); 6514 out.endTag(null, TAG_URI_GRANT); 6515 } 6516 out.endTag(null, TAG_URI_GRANTS); 6517 out.endDocument(); 6518 6519 mGrantFile.finishWrite(fos); 6520 } catch (IOException e) { 6521 if (fos != null) { 6522 mGrantFile.failWrite(fos); 6523 } 6524 } 6525 } 6526 6527 private void readGrantedUriPermissionsLocked() { 6528 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()"); 6529 6530 final long now = System.currentTimeMillis(); 6531 6532 FileInputStream fis = null; 6533 try { 6534 fis = mGrantFile.openRead(); 6535 final XmlPullParser in = Xml.newPullParser(); 6536 in.setInput(fis, null); 6537 6538 int type; 6539 while ((type = in.next()) != END_DOCUMENT) { 6540 final String tag = in.getName(); 6541 if (type == START_TAG) { 6542 if (TAG_URI_GRANT.equals(tag)) { 6543 final int userHandle = readIntAttribute(in, ATTR_USER_HANDLE); 6544 final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG); 6545 final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG); 6546 final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI)); 6547 final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS); 6548 final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now); 6549 6550 // Sanity check that provider still belongs to source package 6551 final ProviderInfo pi = getProviderInfoLocked( 6552 uri.getAuthority(), userHandle); 6553 if (pi != null && sourcePkg.equals(pi.packageName)) { 6554 int targetUid = -1; 6555 try { 6556 targetUid = AppGlobals.getPackageManager() 6557 .getPackageUid(targetPkg, userHandle); 6558 } catch (RemoteException e) { 6559 } 6560 if (targetUid != -1) { 6561 final UriPermission perm = findOrCreateUriPermissionLocked( 6562 sourcePkg, targetPkg, targetUid, uri); 6563 perm.initPersistedModes(modeFlags, createdTime); 6564 } 6565 } else { 6566 Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg 6567 + " but instead found " + pi); 6568 } 6569 } 6570 } 6571 } 6572 } catch (FileNotFoundException e) { 6573 // Missing grants is okay 6574 } catch (IOException e) { 6575 Log.wtf(TAG, "Failed reading Uri grants", e); 6576 } catch (XmlPullParserException e) { 6577 Log.wtf(TAG, "Failed reading Uri grants", e); 6578 } finally { 6579 IoUtils.closeQuietly(fis); 6580 } 6581 } 6582 6583 @Override 6584 public void takePersistableUriPermission(Uri uri, int modeFlags) { 6585 enforceNotIsolatedCaller("takePersistableUriPermission"); 6586 6587 Preconditions.checkFlagsArgument(modeFlags, 6588 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 6589 6590 synchronized (this) { 6591 final int callingUid = Binder.getCallingUid(); 6592 final UriPermission perm = findUriPermissionLocked(callingUid, uri); 6593 if (perm == null) { 6594 throw new SecurityException("No permission grant found for UID " + callingUid 6595 + " and Uri " + uri.toSafeString()); 6596 } 6597 6598 boolean persistChanged = perm.takePersistableModes(modeFlags); 6599 persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid); 6600 6601 if (persistChanged) { 6602 schedulePersistUriGrants(); 6603 } 6604 } 6605 } 6606 6607 @Override 6608 public void releasePersistableUriPermission(Uri uri, int modeFlags) { 6609 enforceNotIsolatedCaller("releasePersistableUriPermission"); 6610 6611 Preconditions.checkFlagsArgument(modeFlags, 6612 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 6613 6614 synchronized (this) { 6615 final int callingUid = Binder.getCallingUid(); 6616 6617 final UriPermission perm = findUriPermissionLocked(callingUid, uri); 6618 if (perm == null) { 6619 Slog.w(TAG, "No permission grant found for UID " + callingUid + " and Uri " 6620 + uri.toSafeString()); 6621 return; 6622 } 6623 6624 final boolean persistChanged = perm.releasePersistableModes(modeFlags); 6625 removeUriPermissionIfNeededLocked(perm); 6626 if (persistChanged) { 6627 schedulePersistUriGrants(); 6628 } 6629 } 6630 } 6631 6632 /** 6633 * Prune any older {@link UriPermission} for the given UID until outstanding 6634 * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}. 6635 * 6636 * @return if any mutations occured that require persisting. 6637 */ 6638 private boolean maybePrunePersistedUriGrantsLocked(int uid) { 6639 final ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(uid); 6640 if (perms == null) return false; 6641 if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false; 6642 6643 final ArrayList<UriPermission> persisted = Lists.newArrayList(); 6644 for (UriPermission perm : perms.values()) { 6645 if (perm.persistedModeFlags != 0) { 6646 persisted.add(perm); 6647 } 6648 } 6649 6650 final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS; 6651 if (trimCount <= 0) return false; 6652 6653 Collections.sort(persisted, new UriPermission.PersistedTimeComparator()); 6654 for (int i = 0; i < trimCount; i++) { 6655 final UriPermission perm = persisted.get(i); 6656 6657 if (DEBUG_URI_PERMISSION) { 6658 Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime); 6659 } 6660 6661 perm.releasePersistableModes(~0); 6662 removeUriPermissionIfNeededLocked(perm); 6663 } 6664 6665 return true; 6666 } 6667 6668 @Override 6669 public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions( 6670 String packageName, boolean incoming) { 6671 enforceNotIsolatedCaller("getPersistedUriPermissions"); 6672 Preconditions.checkNotNull(packageName, "packageName"); 6673 6674 final int callingUid = Binder.getCallingUid(); 6675 final IPackageManager pm = AppGlobals.getPackageManager(); 6676 try { 6677 final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid)); 6678 if (packageUid != callingUid) { 6679 throw new SecurityException( 6680 "Package " + packageName + " does not belong to calling UID " + callingUid); 6681 } 6682 } catch (RemoteException e) { 6683 throw new SecurityException("Failed to verify package name ownership"); 6684 } 6685 6686 final ArrayList<android.content.UriPermission> result = Lists.newArrayList(); 6687 synchronized (this) { 6688 if (incoming) { 6689 final ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(callingUid); 6690 if (perms == null) { 6691 Slog.w(TAG, "No permission grants found for " + packageName); 6692 } else { 6693 final int size = perms.size(); 6694 for (int i = 0; i < size; i++) { 6695 final UriPermission perm = perms.valueAt(i); 6696 if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) { 6697 result.add(perm.buildPersistedPublicApiObject()); 6698 } 6699 } 6700 } 6701 } else { 6702 final int size = mGrantedUriPermissions.size(); 6703 for (int i = 0; i < size; i++) { 6704 final ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 6705 final int permsSize = perms.size(); 6706 for (int j = 0; j < permsSize; j++) { 6707 final UriPermission perm = perms.valueAt(j); 6708 if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) { 6709 result.add(perm.buildPersistedPublicApiObject()); 6710 } 6711 } 6712 } 6713 } 6714 } 6715 return new ParceledListSlice<android.content.UriPermission>(result); 6716 } 6717 6718 @Override 6719 public void showWaitingForDebugger(IApplicationThread who, boolean waiting) { 6720 synchronized (this) { 6721 ProcessRecord app = 6722 who != null ? getRecordForAppLocked(who) : null; 6723 if (app == null) return; 6724 6725 Message msg = Message.obtain(); 6726 msg.what = WAIT_FOR_DEBUGGER_MSG; 6727 msg.obj = app; 6728 msg.arg1 = waiting ? 1 : 0; 6729 mHandler.sendMessage(msg); 6730 } 6731 } 6732 6733 @Override 6734 public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) { 6735 final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ); 6736 final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ); 6737 outInfo.availMem = Process.getFreeMemory(); 6738 outInfo.totalMem = Process.getTotalMemory(); 6739 outInfo.threshold = homeAppMem; 6740 outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2)); 6741 outInfo.hiddenAppThreshold = cachedAppMem; 6742 outInfo.secondaryServerThreshold = mProcessList.getMemLevel( 6743 ProcessList.SERVICE_ADJ); 6744 outInfo.visibleAppThreshold = mProcessList.getMemLevel( 6745 ProcessList.VISIBLE_APP_ADJ); 6746 outInfo.foregroundAppThreshold = mProcessList.getMemLevel( 6747 ProcessList.FOREGROUND_APP_ADJ); 6748 } 6749 6750 // ========================================================= 6751 // TASK MANAGEMENT 6752 // ========================================================= 6753 6754 @Override 6755 public List<RunningTaskInfo> getTasks(int maxNum, int flags, 6756 IThumbnailReceiver receiver) { 6757 ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>(); 6758 6759 PendingThumbnailsRecord pending = new PendingThumbnailsRecord(receiver); 6760 ActivityRecord topRecord = null; 6761 6762 synchronized(this) { 6763 if (localLOGV) Slog.v( 6764 TAG, "getTasks: max=" + maxNum + ", flags=" + flags 6765 + ", receiver=" + receiver); 6766 6767 if (checkCallingPermission(android.Manifest.permission.GET_TASKS) 6768 != PackageManager.PERMISSION_GRANTED) { 6769 if (receiver != null) { 6770 // If the caller wants to wait for pending thumbnails, 6771 // it ain't gonna get them. 6772 try { 6773 receiver.finished(); 6774 } catch (RemoteException ex) { 6775 } 6776 } 6777 String msg = "Permission Denial: getTasks() from pid=" 6778 + Binder.getCallingPid() 6779 + ", uid=" + Binder.getCallingUid() 6780 + " requires " + android.Manifest.permission.GET_TASKS; 6781 Slog.w(TAG, msg); 6782 throw new SecurityException(msg); 6783 } 6784 6785 // TODO: Improve with MRU list from all ActivityStacks. 6786 topRecord = mStackSupervisor.getTasksLocked(maxNum, receiver, pending, list); 6787 6788 if (!pending.pendingRecords.isEmpty()) { 6789 mPendingThumbnails.add(pending); 6790 } 6791 } 6792 6793 if (localLOGV) Slog.v(TAG, "We have pending thumbnails: " + pending); 6794 6795 if (topRecord != null) { 6796 if (localLOGV) Slog.v(TAG, "Requesting top thumbnail"); 6797 try { 6798 IApplicationThread topThumbnail = topRecord.app.thread; 6799 topThumbnail.requestThumbnail(topRecord.appToken); 6800 } catch (Exception e) { 6801 Slog.w(TAG, "Exception thrown when requesting thumbnail", e); 6802 sendPendingThumbnail(null, topRecord.appToken, null, null, true); 6803 } 6804 } 6805 6806 if (pending == null && receiver != null) { 6807 // In this case all thumbnails were available and the client 6808 // is being asked to be told when the remaining ones come in... 6809 // which is unusually, since the top-most currently running 6810 // activity should never have a canned thumbnail! Oh well. 6811 try { 6812 receiver.finished(); 6813 } catch (RemoteException ex) { 6814 } 6815 } 6816 6817 return list; 6818 } 6819 6820 TaskRecord getMostRecentTask() { 6821 return mRecentTasks.get(0); 6822 } 6823 6824 @Override 6825 public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, 6826 int flags, int userId) { 6827 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 6828 false, true, "getRecentTasks", null); 6829 6830 synchronized (this) { 6831 enforceCallingPermission(android.Manifest.permission.GET_TASKS, 6832 "getRecentTasks()"); 6833 final boolean detailed = checkCallingPermission( 6834 android.Manifest.permission.GET_DETAILED_TASKS) 6835 == PackageManager.PERMISSION_GRANTED; 6836 6837 IPackageManager pm = AppGlobals.getPackageManager(); 6838 6839 final int N = mRecentTasks.size(); 6840 ArrayList<ActivityManager.RecentTaskInfo> res 6841 = new ArrayList<ActivityManager.RecentTaskInfo>( 6842 maxNum < N ? maxNum : N); 6843 for (int i=0; i<N && maxNum > 0; i++) { 6844 TaskRecord tr = mRecentTasks.get(i); 6845 // Only add calling user's recent tasks 6846 if (tr.userId != userId) continue; 6847 // Return the entry if desired by the caller. We always return 6848 // the first entry, because callers always expect this to be the 6849 // foreground app. We may filter others if the caller has 6850 // not supplied RECENT_WITH_EXCLUDED and there is some reason 6851 // we should exclude the entry. 6852 6853 if (i == 0 6854 || ((flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0) 6855 || (tr.intent == null) 6856 || ((tr.intent.getFlags() 6857 &Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0)) { 6858 ActivityManager.RecentTaskInfo rti 6859 = new ActivityManager.RecentTaskInfo(); 6860 rti.id = tr.numActivities > 0 ? tr.taskId : -1; 6861 rti.persistentId = tr.taskId; 6862 rti.baseIntent = new Intent( 6863 tr.intent != null ? tr.intent : tr.affinityIntent); 6864 if (!detailed) { 6865 rti.baseIntent.replaceExtras((Bundle)null); 6866 } 6867 rti.origActivity = tr.origActivity; 6868 rti.description = tr.lastDescription; 6869 rti.stackId = tr.stack.mStackId; 6870 6871 if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) { 6872 // Check whether this activity is currently available. 6873 try { 6874 if (rti.origActivity != null) { 6875 if (pm.getActivityInfo(rti.origActivity, 0, userId) 6876 == null) { 6877 continue; 6878 } 6879 } else if (rti.baseIntent != null) { 6880 if (pm.queryIntentActivities(rti.baseIntent, 6881 null, 0, userId) == null) { 6882 continue; 6883 } 6884 } 6885 } catch (RemoteException e) { 6886 // Will never happen. 6887 } 6888 } 6889 6890 res.add(rti); 6891 maxNum--; 6892 } 6893 } 6894 return res; 6895 } 6896 } 6897 6898 private TaskRecord recentTaskForIdLocked(int id) { 6899 final int N = mRecentTasks.size(); 6900 for (int i=0; i<N; i++) { 6901 TaskRecord tr = mRecentTasks.get(i); 6902 if (tr.taskId == id) { 6903 return tr; 6904 } 6905 } 6906 return null; 6907 } 6908 6909 @Override 6910 public ActivityManager.TaskThumbnails getTaskThumbnails(int id) { 6911 synchronized (this) { 6912 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER, 6913 "getTaskThumbnails()"); 6914 TaskRecord tr = recentTaskForIdLocked(id); 6915 if (tr != null) { 6916 return tr.getTaskThumbnailsLocked(); 6917 } 6918 } 6919 return null; 6920 } 6921 6922 @Override 6923 public Bitmap getTaskTopThumbnail(int id) { 6924 synchronized (this) { 6925 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER, 6926 "getTaskTopThumbnail()"); 6927 TaskRecord tr = recentTaskForIdLocked(id); 6928 if (tr != null) { 6929 return tr.getTaskTopThumbnailLocked(); 6930 } 6931 } 6932 return null; 6933 } 6934 6935 @Override 6936 public boolean removeSubTask(int taskId, int subTaskIndex) { 6937 synchronized (this) { 6938 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, 6939 "removeSubTask()"); 6940 long ident = Binder.clearCallingIdentity(); 6941 try { 6942 TaskRecord tr = recentTaskForIdLocked(taskId); 6943 if (tr != null) { 6944 return tr.removeTaskActivitiesLocked(subTaskIndex, true) != null; 6945 } 6946 return false; 6947 } finally { 6948 Binder.restoreCallingIdentity(ident); 6949 } 6950 } 6951 } 6952 6953 private void killUnneededProcessLocked(ProcessRecord pr, String reason) { 6954 if (!pr.killedByAm) { 6955 Slog.i(TAG, "Killing " + pr.toShortString() + " (adj " + pr.setAdj + "): " + reason); 6956 EventLog.writeEvent(EventLogTags.AM_KILL, pr.userId, pr.pid, 6957 pr.processName, pr.setAdj, reason); 6958 pr.killedByAm = true; 6959 Process.killProcessQuiet(pr.pid); 6960 } 6961 } 6962 6963 private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) { 6964 tr.disposeThumbnail(); 6965 mRecentTasks.remove(tr); 6966 final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0; 6967 Intent baseIntent = new Intent( 6968 tr.intent != null ? tr.intent : tr.affinityIntent); 6969 ComponentName component = baseIntent.getComponent(); 6970 if (component == null) { 6971 Slog.w(TAG, "Now component for base intent of task: " + tr); 6972 return; 6973 } 6974 6975 // Find any running services associated with this app. 6976 mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent); 6977 6978 if (killProcesses) { 6979 // Find any running processes associated with this app. 6980 final String pkg = component.getPackageName(); 6981 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 6982 ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap(); 6983 for (int i=0; i<pmap.size(); i++) { 6984 SparseArray<ProcessRecord> uids = pmap.valueAt(i); 6985 for (int j=0; j<uids.size(); j++) { 6986 ProcessRecord proc = uids.valueAt(j); 6987 if (proc.userId != tr.userId) { 6988 continue; 6989 } 6990 if (!proc.pkgList.containsKey(pkg)) { 6991 continue; 6992 } 6993 procs.add(proc); 6994 } 6995 } 6996 6997 // Kill the running processes. 6998 for (int i=0; i<procs.size(); i++) { 6999 ProcessRecord pr = procs.get(i); 7000 if (pr == mHomeProcess) { 7001 // Don't kill the home process along with tasks from the same package. 7002 continue; 7003 } 7004 if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 7005 killUnneededProcessLocked(pr, "remove task"); 7006 } else { 7007 pr.waitingToKill = "remove task"; 7008 } 7009 } 7010 } 7011 } 7012 7013 @Override 7014 public boolean removeTask(int taskId, int flags) { 7015 synchronized (this) { 7016 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, 7017 "removeTask()"); 7018 long ident = Binder.clearCallingIdentity(); 7019 try { 7020 TaskRecord tr = recentTaskForIdLocked(taskId); 7021 if (tr != null) { 7022 ActivityRecord r = tr.removeTaskActivitiesLocked(-1, false); 7023 if (r != null) { 7024 cleanUpRemovedTaskLocked(tr, flags); 7025 return true; 7026 } 7027 if (tr.mActivities.size() == 0) { 7028 // Caller is just removing a recent task that is 7029 // not actively running. That is easy! 7030 cleanUpRemovedTaskLocked(tr, flags); 7031 return true; 7032 } 7033 Slog.w(TAG, "removeTask: task " + taskId 7034 + " does not have activities to remove, " 7035 + " but numActivities=" + tr.numActivities 7036 + ": " + tr); 7037 } 7038 } finally { 7039 Binder.restoreCallingIdentity(ident); 7040 } 7041 } 7042 return false; 7043 } 7044 7045 /** 7046 * TODO: Add mController hook 7047 */ 7048 @Override 7049 public void moveTaskToFront(int task, int flags, Bundle options) { 7050 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 7051 "moveTaskToFront()"); 7052 7053 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving task=" + task); 7054 synchronized(this) { 7055 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 7056 Binder.getCallingUid(), "Task to front")) { 7057 ActivityOptions.abort(options); 7058 return; 7059 } 7060 final long origId = Binder.clearCallingIdentity(); 7061 try { 7062 mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options); 7063 } finally { 7064 Binder.restoreCallingIdentity(origId); 7065 } 7066 ActivityOptions.abort(options); 7067 } 7068 } 7069 7070 @Override 7071 public void moveTaskToBack(int taskId) { 7072 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 7073 "moveTaskToBack()"); 7074 7075 synchronized(this) { 7076 TaskRecord tr = recentTaskForIdLocked(taskId); 7077 if (tr != null) { 7078 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr); 7079 ActivityStack stack = tr.stack; 7080 if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) { 7081 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 7082 Binder.getCallingUid(), "Task to back")) { 7083 return; 7084 } 7085 } 7086 final long origId = Binder.clearCallingIdentity(); 7087 try { 7088 stack.moveTaskToBackLocked(taskId, null); 7089 } finally { 7090 Binder.restoreCallingIdentity(origId); 7091 } 7092 } 7093 } 7094 } 7095 7096 /** 7097 * Moves an activity, and all of the other activities within the same task, to the bottom 7098 * of the history stack. The activity's order within the task is unchanged. 7099 * 7100 * @param token A reference to the activity we wish to move 7101 * @param nonRoot If false then this only works if the activity is the root 7102 * of a task; if true it will work for any activity in a task. 7103 * @return Returns true if the move completed, false if not. 7104 */ 7105 @Override 7106 public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) { 7107 enforceNotIsolatedCaller("moveActivityTaskToBack"); 7108 synchronized(this) { 7109 final long origId = Binder.clearCallingIdentity(); 7110 int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot); 7111 if (taskId >= 0) { 7112 return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null); 7113 } 7114 Binder.restoreCallingIdentity(origId); 7115 } 7116 return false; 7117 } 7118 7119 @Override 7120 public void moveTaskBackwards(int task) { 7121 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 7122 "moveTaskBackwards()"); 7123 7124 synchronized(this) { 7125 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 7126 Binder.getCallingUid(), "Task backwards")) { 7127 return; 7128 } 7129 final long origId = Binder.clearCallingIdentity(); 7130 moveTaskBackwardsLocked(task); 7131 Binder.restoreCallingIdentity(origId); 7132 } 7133 } 7134 7135 private final void moveTaskBackwardsLocked(int task) { 7136 Slog.e(TAG, "moveTaskBackwards not yet implemented!"); 7137 } 7138 7139 @Override 7140 public IBinder getHomeActivityToken() throws RemoteException { 7141 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7142 "getHomeActivityToken()"); 7143 synchronized (this) { 7144 return mStackSupervisor.getHomeActivityToken(); 7145 } 7146 } 7147 7148 @Override 7149 public IActivityContainer createActivityContainer(IBinder parentActivityToken, 7150 IActivityContainerCallback callback) throws RemoteException { 7151 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7152 "createActivityContainer()"); 7153 synchronized (this) { 7154 if (parentActivityToken == null) { 7155 throw new IllegalArgumentException("parent token must not be null"); 7156 } 7157 ActivityRecord r = ActivityRecord.forToken(parentActivityToken); 7158 if (r == null) { 7159 return null; 7160 } 7161 return mStackSupervisor.createActivityContainer(r, callback); 7162 } 7163 } 7164 7165 @Override 7166 public void deleteActivityContainer(IActivityContainer container) throws RemoteException { 7167 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7168 "deleteActivityContainer()"); 7169 synchronized (this) { 7170 mStackSupervisor.deleteActivityContainer(container); 7171 } 7172 } 7173 7174 @Override 7175 public IActivityContainer getEnclosingActivityContainer(IBinder activityToken) 7176 throws RemoteException { 7177 synchronized (this) { 7178 ActivityStack stack = ActivityRecord.getStackLocked(activityToken); 7179 if (stack != null) { 7180 return stack.mActivityContainer; 7181 } 7182 return null; 7183 } 7184 } 7185 7186 @Override 7187 public void moveTaskToStack(int taskId, int stackId, boolean toTop) { 7188 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7189 "moveTaskToStack()"); 7190 if (stackId == HOME_STACK_ID) { 7191 Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack", 7192 new RuntimeException("here").fillInStackTrace()); 7193 } 7194 synchronized (this) { 7195 long ident = Binder.clearCallingIdentity(); 7196 try { 7197 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId=" 7198 + stackId + " toTop=" + toTop); 7199 mStackSupervisor.moveTaskToStack(taskId, stackId, toTop); 7200 } finally { 7201 Binder.restoreCallingIdentity(ident); 7202 } 7203 } 7204 } 7205 7206 @Override 7207 public void resizeStack(int stackBoxId, Rect bounds) { 7208 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7209 "resizeStackBox()"); 7210 long ident = Binder.clearCallingIdentity(); 7211 try { 7212 mWindowManager.resizeStack(stackBoxId, bounds); 7213 } finally { 7214 Binder.restoreCallingIdentity(ident); 7215 } 7216 } 7217 7218 @Override 7219 public List<StackInfo> getAllStackInfos() { 7220 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7221 "getAllStackInfos()"); 7222 long ident = Binder.clearCallingIdentity(); 7223 try { 7224 synchronized (this) { 7225 return mStackSupervisor.getAllStackInfosLocked(); 7226 } 7227 } finally { 7228 Binder.restoreCallingIdentity(ident); 7229 } 7230 } 7231 7232 @Override 7233 public StackInfo getStackInfo(int stackId) { 7234 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7235 "getStackInfo()"); 7236 long ident = Binder.clearCallingIdentity(); 7237 try { 7238 synchronized (this) { 7239 return mStackSupervisor.getStackInfoLocked(stackId); 7240 } 7241 } finally { 7242 Binder.restoreCallingIdentity(ident); 7243 } 7244 } 7245 7246 @Override 7247 public int getTaskForActivity(IBinder token, boolean onlyRoot) { 7248 synchronized(this) { 7249 return ActivityRecord.getTaskForActivityLocked(token, onlyRoot); 7250 } 7251 } 7252 7253 // ========================================================= 7254 // THUMBNAILS 7255 // ========================================================= 7256 7257 public void reportThumbnail(IBinder token, 7258 Bitmap thumbnail, CharSequence description) { 7259 //System.out.println("Report thumbnail for " + token + ": " + thumbnail); 7260 final long origId = Binder.clearCallingIdentity(); 7261 sendPendingThumbnail(null, token, thumbnail, description, true); 7262 Binder.restoreCallingIdentity(origId); 7263 } 7264 7265 final void sendPendingThumbnail(ActivityRecord r, IBinder token, 7266 Bitmap thumbnail, CharSequence description, boolean always) { 7267 TaskRecord task; 7268 ArrayList<PendingThumbnailsRecord> receivers = null; 7269 7270 //System.out.println("Send pending thumbnail: " + r); 7271 7272 synchronized(this) { 7273 if (r == null) { 7274 r = ActivityRecord.isInStackLocked(token); 7275 if (r == null) { 7276 return; 7277 } 7278 } 7279 if (thumbnail == null && r.thumbHolder != null) { 7280 thumbnail = r.thumbHolder.lastThumbnail; 7281 description = r.thumbHolder.lastDescription; 7282 } 7283 if (thumbnail == null && !always) { 7284 // If there is no thumbnail, and this entry is not actually 7285 // going away, then abort for now and pick up the next 7286 // thumbnail we get. 7287 return; 7288 } 7289 task = r.task; 7290 7291 int N = mPendingThumbnails.size(); 7292 int i=0; 7293 while (i<N) { 7294 PendingThumbnailsRecord pr = mPendingThumbnails.get(i); 7295 //System.out.println("Looking in " + pr.pendingRecords); 7296 if (pr.pendingRecords.remove(r)) { 7297 if (receivers == null) { 7298 receivers = new ArrayList<PendingThumbnailsRecord>(); 7299 } 7300 receivers.add(pr); 7301 if (pr.pendingRecords.size() == 0) { 7302 pr.finished = true; 7303 mPendingThumbnails.remove(i); 7304 N--; 7305 continue; 7306 } 7307 } 7308 i++; 7309 } 7310 } 7311 7312 if (receivers != null) { 7313 final int N = receivers.size(); 7314 for (int i=0; i<N; i++) { 7315 try { 7316 PendingThumbnailsRecord pr = receivers.get(i); 7317 pr.receiver.newThumbnail( 7318 task != null ? task.taskId : -1, thumbnail, description); 7319 if (pr.finished) { 7320 pr.receiver.finished(); 7321 } 7322 } catch (Exception e) { 7323 Slog.w(TAG, "Exception thrown when sending thumbnail", e); 7324 } 7325 } 7326 } 7327 } 7328 7329 // ========================================================= 7330 // CONTENT PROVIDERS 7331 // ========================================================= 7332 7333 private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) { 7334 List<ProviderInfo> providers = null; 7335 try { 7336 providers = AppGlobals.getPackageManager(). 7337 queryContentProviders(app.processName, app.uid, 7338 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS); 7339 } catch (RemoteException ex) { 7340 } 7341 if (DEBUG_MU) 7342 Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid); 7343 int userId = app.userId; 7344 if (providers != null) { 7345 int N = providers.size(); 7346 app.pubProviders.ensureCapacity(N + app.pubProviders.size()); 7347 for (int i=0; i<N; i++) { 7348 ProviderInfo cpi = 7349 (ProviderInfo)providers.get(i); 7350 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo, 7351 cpi.name, cpi.flags); 7352 if (singleton && UserHandle.getUserId(app.uid) != 0) { 7353 // This is a singleton provider, but a user besides the 7354 // default user is asking to initialize a process it runs 7355 // in... well, no, it doesn't actually run in this process, 7356 // it runs in the process of the default user. Get rid of it. 7357 providers.remove(i); 7358 N--; 7359 i--; 7360 continue; 7361 } 7362 7363 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 7364 ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId); 7365 if (cpr == null) { 7366 cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton); 7367 mProviderMap.putProviderByClass(comp, cpr); 7368 } 7369 if (DEBUG_MU) 7370 Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid); 7371 app.pubProviders.put(cpi.name, cpr); 7372 if (!cpi.multiprocess || !"android".equals(cpi.packageName)) { 7373 // Don't add this if it is a platform component that is marked 7374 // to run in multiple processes, because this is actually 7375 // part of the framework so doesn't make sense to track as a 7376 // separate apk in the process. 7377 app.addPackage(cpi.applicationInfo.packageName, mProcessStats); 7378 } 7379 ensurePackageDexOpt(cpi.applicationInfo.packageName); 7380 } 7381 } 7382 return providers; 7383 } 7384 7385 /** 7386 * Check if {@link ProcessRecord} has a possible chance at accessing the 7387 * given {@link ProviderInfo}. Final permission checking is always done 7388 * in {@link ContentProvider}. 7389 */ 7390 private final String checkContentProviderPermissionLocked( 7391 ProviderInfo cpi, ProcessRecord r) { 7392 final int callingPid = (r != null) ? r.pid : Binder.getCallingPid(); 7393 final int callingUid = (r != null) ? r.uid : Binder.getCallingUid(); 7394 if (checkComponentPermission(cpi.readPermission, callingPid, callingUid, 7395 cpi.applicationInfo.uid, cpi.exported) 7396 == PackageManager.PERMISSION_GRANTED) { 7397 return null; 7398 } 7399 if (checkComponentPermission(cpi.writePermission, callingPid, callingUid, 7400 cpi.applicationInfo.uid, cpi.exported) 7401 == PackageManager.PERMISSION_GRANTED) { 7402 return null; 7403 } 7404 7405 PathPermission[] pps = cpi.pathPermissions; 7406 if (pps != null) { 7407 int i = pps.length; 7408 while (i > 0) { 7409 i--; 7410 PathPermission pp = pps[i]; 7411 if (checkComponentPermission(pp.getReadPermission(), callingPid, callingUid, 7412 cpi.applicationInfo.uid, cpi.exported) 7413 == PackageManager.PERMISSION_GRANTED) { 7414 return null; 7415 } 7416 if (checkComponentPermission(pp.getWritePermission(), callingPid, callingUid, 7417 cpi.applicationInfo.uid, cpi.exported) 7418 == PackageManager.PERMISSION_GRANTED) { 7419 return null; 7420 } 7421 } 7422 } 7423 7424 ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(callingUid); 7425 if (perms != null) { 7426 for (Map.Entry<Uri, UriPermission> uri : perms.entrySet()) { 7427 if (uri.getKey().getAuthority().equals(cpi.authority)) { 7428 return null; 7429 } 7430 } 7431 } 7432 7433 String msg; 7434 if (!cpi.exported) { 7435 msg = "Permission Denial: opening provider " + cpi.name 7436 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 7437 + ", uid=" + callingUid + ") that is not exported from uid " 7438 + cpi.applicationInfo.uid; 7439 } else { 7440 msg = "Permission Denial: opening provider " + cpi.name 7441 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 7442 + ", uid=" + callingUid + ") requires " 7443 + cpi.readPermission + " or " + cpi.writePermission; 7444 } 7445 Slog.w(TAG, msg); 7446 return msg; 7447 } 7448 7449 ContentProviderConnection incProviderCountLocked(ProcessRecord r, 7450 final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 7451 if (r != null) { 7452 for (int i=0; i<r.conProviders.size(); i++) { 7453 ContentProviderConnection conn = r.conProviders.get(i); 7454 if (conn.provider == cpr) { 7455 if (DEBUG_PROVIDER) Slog.v(TAG, 7456 "Adding provider requested by " 7457 + r.processName + " from process " 7458 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 7459 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 7460 if (stable) { 7461 conn.stableCount++; 7462 conn.numStableIncs++; 7463 } else { 7464 conn.unstableCount++; 7465 conn.numUnstableIncs++; 7466 } 7467 return conn; 7468 } 7469 } 7470 ContentProviderConnection conn = new ContentProviderConnection(cpr, r); 7471 if (stable) { 7472 conn.stableCount = 1; 7473 conn.numStableIncs = 1; 7474 } else { 7475 conn.unstableCount = 1; 7476 conn.numUnstableIncs = 1; 7477 } 7478 cpr.connections.add(conn); 7479 r.conProviders.add(conn); 7480 return conn; 7481 } 7482 cpr.addExternalProcessHandleLocked(externalProcessToken); 7483 return null; 7484 } 7485 7486 boolean decProviderCountLocked(ContentProviderConnection conn, 7487 ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 7488 if (conn != null) { 7489 cpr = conn.provider; 7490 if (DEBUG_PROVIDER) Slog.v(TAG, 7491 "Removing provider requested by " 7492 + conn.client.processName + " from process " 7493 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 7494 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 7495 if (stable) { 7496 conn.stableCount--; 7497 } else { 7498 conn.unstableCount--; 7499 } 7500 if (conn.stableCount == 0 && conn.unstableCount == 0) { 7501 cpr.connections.remove(conn); 7502 conn.client.conProviders.remove(conn); 7503 return true; 7504 } 7505 return false; 7506 } 7507 cpr.removeExternalProcessHandleLocked(externalProcessToken); 7508 return false; 7509 } 7510 7511 private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller, 7512 String name, IBinder token, boolean stable, int userId) { 7513 ContentProviderRecord cpr; 7514 ContentProviderConnection conn = null; 7515 ProviderInfo cpi = null; 7516 7517 synchronized(this) { 7518 ProcessRecord r = null; 7519 if (caller != null) { 7520 r = getRecordForAppLocked(caller); 7521 if (r == null) { 7522 throw new SecurityException( 7523 "Unable to find app for caller " + caller 7524 + " (pid=" + Binder.getCallingPid() 7525 + ") when getting content provider " + name); 7526 } 7527 } 7528 7529 // First check if this content provider has been published... 7530 cpr = mProviderMap.getProviderByName(name, userId); 7531 boolean providerRunning = cpr != null; 7532 if (providerRunning) { 7533 cpi = cpr.info; 7534 String msg; 7535 if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) { 7536 throw new SecurityException(msg); 7537 } 7538 7539 if (r != null && cpr.canRunHere(r)) { 7540 // This provider has been published or is in the process 7541 // of being published... but it is also allowed to run 7542 // in the caller's process, so don't make a connection 7543 // and just let the caller instantiate its own instance. 7544 ContentProviderHolder holder = cpr.newHolder(null); 7545 // don't give caller the provider object, it needs 7546 // to make its own. 7547 holder.provider = null; 7548 return holder; 7549 } 7550 7551 final long origId = Binder.clearCallingIdentity(); 7552 7553 // In this case the provider instance already exists, so we can 7554 // return it right away. 7555 conn = incProviderCountLocked(r, cpr, token, stable); 7556 if (conn != null && (conn.stableCount+conn.unstableCount) == 1) { 7557 if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 7558 // If this is a perceptible app accessing the provider, 7559 // make sure to count it as being accessed and thus 7560 // back up on the LRU list. This is good because 7561 // content providers are often expensive to start. 7562 updateLruProcessLocked(cpr.proc, false, null); 7563 } 7564 } 7565 7566 if (cpr.proc != null) { 7567 if (false) { 7568 if (cpr.name.flattenToShortString().equals( 7569 "com.android.providers.calendar/.CalendarProvider2")) { 7570 Slog.v(TAG, "****************** KILLING " 7571 + cpr.name.flattenToShortString()); 7572 Process.killProcess(cpr.proc.pid); 7573 } 7574 } 7575 boolean success = updateOomAdjLocked(cpr.proc); 7576 if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success); 7577 // NOTE: there is still a race here where a signal could be 7578 // pending on the process even though we managed to update its 7579 // adj level. Not sure what to do about this, but at least 7580 // the race is now smaller. 7581 if (!success) { 7582 // Uh oh... it looks like the provider's process 7583 // has been killed on us. We need to wait for a new 7584 // process to be started, and make sure its death 7585 // doesn't kill our process. 7586 Slog.i(TAG, 7587 "Existing provider " + cpr.name.flattenToShortString() 7588 + " is crashing; detaching " + r); 7589 boolean lastRef = decProviderCountLocked(conn, cpr, token, stable); 7590 appDiedLocked(cpr.proc, cpr.proc.pid, cpr.proc.thread); 7591 if (!lastRef) { 7592 // This wasn't the last ref our process had on 7593 // the provider... we have now been killed, bail. 7594 return null; 7595 } 7596 providerRunning = false; 7597 conn = null; 7598 } 7599 } 7600 7601 Binder.restoreCallingIdentity(origId); 7602 } 7603 7604 boolean singleton; 7605 if (!providerRunning) { 7606 try { 7607 cpi = AppGlobals.getPackageManager(). 7608 resolveContentProvider(name, 7609 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId); 7610 } catch (RemoteException ex) { 7611 } 7612 if (cpi == null) { 7613 return null; 7614 } 7615 singleton = isSingleton(cpi.processName, cpi.applicationInfo, 7616 cpi.name, cpi.flags); 7617 if (singleton) { 7618 userId = 0; 7619 } 7620 cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId); 7621 7622 String msg; 7623 if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) { 7624 throw new SecurityException(msg); 7625 } 7626 7627 if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate 7628 && !cpi.processName.equals("system")) { 7629 // If this content provider does not run in the system 7630 // process, and the system is not yet ready to run other 7631 // processes, then fail fast instead of hanging. 7632 throw new IllegalArgumentException( 7633 "Attempt to launch content provider before system ready"); 7634 } 7635 7636 // Make sure that the user who owns this provider is started. If not, 7637 // we don't want to allow it to run. 7638 if (mStartedUsers.get(userId) == null) { 7639 Slog.w(TAG, "Unable to launch app " 7640 + cpi.applicationInfo.packageName + "/" 7641 + cpi.applicationInfo.uid + " for provider " 7642 + name + ": user " + userId + " is stopped"); 7643 return null; 7644 } 7645 7646 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 7647 cpr = mProviderMap.getProviderByClass(comp, userId); 7648 final boolean firstClass = cpr == null; 7649 if (firstClass) { 7650 try { 7651 ApplicationInfo ai = 7652 AppGlobals.getPackageManager(). 7653 getApplicationInfo( 7654 cpi.applicationInfo.packageName, 7655 STOCK_PM_FLAGS, userId); 7656 if (ai == null) { 7657 Slog.w(TAG, "No package info for content provider " 7658 + cpi.name); 7659 return null; 7660 } 7661 ai = getAppInfoForUser(ai, userId); 7662 cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton); 7663 } catch (RemoteException ex) { 7664 // pm is in same process, this will never happen. 7665 } 7666 } 7667 7668 if (r != null && cpr.canRunHere(r)) { 7669 // If this is a multiprocess provider, then just return its 7670 // info and allow the caller to instantiate it. Only do 7671 // this if the provider is the same user as the caller's 7672 // process, or can run as root (so can be in any process). 7673 return cpr.newHolder(null); 7674 } 7675 7676 if (DEBUG_PROVIDER) { 7677 RuntimeException e = new RuntimeException("here"); 7678 Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null) 7679 + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e); 7680 } 7681 7682 // This is single process, and our app is now connecting to it. 7683 // See if we are already in the process of launching this 7684 // provider. 7685 final int N = mLaunchingProviders.size(); 7686 int i; 7687 for (i=0; i<N; i++) { 7688 if (mLaunchingProviders.get(i) == cpr) { 7689 break; 7690 } 7691 } 7692 7693 // If the provider is not already being launched, then get it 7694 // started. 7695 if (i >= N) { 7696 final long origId = Binder.clearCallingIdentity(); 7697 7698 try { 7699 // Content provider is now in use, its package can't be stopped. 7700 try { 7701 AppGlobals.getPackageManager().setPackageStoppedState( 7702 cpr.appInfo.packageName, false, userId); 7703 } catch (RemoteException e) { 7704 } catch (IllegalArgumentException e) { 7705 Slog.w(TAG, "Failed trying to unstop package " 7706 + cpr.appInfo.packageName + ": " + e); 7707 } 7708 7709 // Use existing process if already started 7710 ProcessRecord proc = getProcessRecordLocked( 7711 cpi.processName, cpr.appInfo.uid, false); 7712 if (proc != null && proc.thread != null) { 7713 if (DEBUG_PROVIDER) { 7714 Slog.d(TAG, "Installing in existing process " + proc); 7715 } 7716 proc.pubProviders.put(cpi.name, cpr); 7717 try { 7718 proc.thread.scheduleInstallProvider(cpi); 7719 } catch (RemoteException e) { 7720 } 7721 } else { 7722 proc = startProcessLocked(cpi.processName, 7723 cpr.appInfo, false, 0, "content provider", 7724 new ComponentName(cpi.applicationInfo.packageName, 7725 cpi.name), false, false, false); 7726 if (proc == null) { 7727 Slog.w(TAG, "Unable to launch app " 7728 + cpi.applicationInfo.packageName + "/" 7729 + cpi.applicationInfo.uid + " for provider " 7730 + name + ": process is bad"); 7731 return null; 7732 } 7733 } 7734 cpr.launchingApp = proc; 7735 mLaunchingProviders.add(cpr); 7736 } finally { 7737 Binder.restoreCallingIdentity(origId); 7738 } 7739 } 7740 7741 // Make sure the provider is published (the same provider class 7742 // may be published under multiple names). 7743 if (firstClass) { 7744 mProviderMap.putProviderByClass(comp, cpr); 7745 } 7746 7747 mProviderMap.putProviderByName(name, cpr); 7748 conn = incProviderCountLocked(r, cpr, token, stable); 7749 if (conn != null) { 7750 conn.waiting = true; 7751 } 7752 } 7753 } 7754 7755 // Wait for the provider to be published... 7756 synchronized (cpr) { 7757 while (cpr.provider == null) { 7758 if (cpr.launchingApp == null) { 7759 Slog.w(TAG, "Unable to launch app " 7760 + cpi.applicationInfo.packageName + "/" 7761 + cpi.applicationInfo.uid + " for provider " 7762 + name + ": launching app became null"); 7763 EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS, 7764 UserHandle.getUserId(cpi.applicationInfo.uid), 7765 cpi.applicationInfo.packageName, 7766 cpi.applicationInfo.uid, name); 7767 return null; 7768 } 7769 try { 7770 if (DEBUG_MU) { 7771 Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp=" 7772 + cpr.launchingApp); 7773 } 7774 if (conn != null) { 7775 conn.waiting = true; 7776 } 7777 cpr.wait(); 7778 } catch (InterruptedException ex) { 7779 } finally { 7780 if (conn != null) { 7781 conn.waiting = false; 7782 } 7783 } 7784 } 7785 } 7786 return cpr != null ? cpr.newHolder(conn) : null; 7787 } 7788 7789 public final ContentProviderHolder getContentProvider( 7790 IApplicationThread caller, String name, int userId, boolean stable) { 7791 enforceNotIsolatedCaller("getContentProvider"); 7792 if (caller == null) { 7793 String msg = "null IApplicationThread when getting content provider " 7794 + name; 7795 Slog.w(TAG, msg); 7796 throw new SecurityException(msg); 7797 } 7798 7799 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 7800 false, true, "getContentProvider", null); 7801 return getContentProviderImpl(caller, name, null, stable, userId); 7802 } 7803 7804 public ContentProviderHolder getContentProviderExternal( 7805 String name, int userId, IBinder token) { 7806 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 7807 "Do not have permission in call getContentProviderExternal()"); 7808 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 7809 false, true, "getContentProvider", null); 7810 return getContentProviderExternalUnchecked(name, token, userId); 7811 } 7812 7813 private ContentProviderHolder getContentProviderExternalUnchecked(String name, 7814 IBinder token, int userId) { 7815 return getContentProviderImpl(null, name, token, true, userId); 7816 } 7817 7818 /** 7819 * Drop a content provider from a ProcessRecord's bookkeeping 7820 */ 7821 public void removeContentProvider(IBinder connection, boolean stable) { 7822 enforceNotIsolatedCaller("removeContentProvider"); 7823 long ident = Binder.clearCallingIdentity(); 7824 try { 7825 synchronized (this) { 7826 ContentProviderConnection conn; 7827 try { 7828 conn = (ContentProviderConnection)connection; 7829 } catch (ClassCastException e) { 7830 String msg ="removeContentProvider: " + connection 7831 + " not a ContentProviderConnection"; 7832 Slog.w(TAG, msg); 7833 throw new IllegalArgumentException(msg); 7834 } 7835 if (conn == null) { 7836 throw new NullPointerException("connection is null"); 7837 } 7838 if (decProviderCountLocked(conn, null, null, stable)) { 7839 updateOomAdjLocked(); 7840 } 7841 } 7842 } finally { 7843 Binder.restoreCallingIdentity(ident); 7844 } 7845 } 7846 7847 public void removeContentProviderExternal(String name, IBinder token) { 7848 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 7849 "Do not have permission in call removeContentProviderExternal()"); 7850 removeContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId()); 7851 } 7852 7853 private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) { 7854 synchronized (this) { 7855 ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId); 7856 if(cpr == null) { 7857 //remove from mProvidersByClass 7858 if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list"); 7859 return; 7860 } 7861 7862 //update content provider record entry info 7863 ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name); 7864 ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId); 7865 if (localCpr.hasExternalProcessHandles()) { 7866 if (localCpr.removeExternalProcessHandleLocked(token)) { 7867 updateOomAdjLocked(); 7868 } else { 7869 Slog.e(TAG, "Attmpt to remove content provider " + localCpr 7870 + " with no external reference for token: " 7871 + token + "."); 7872 } 7873 } else { 7874 Slog.e(TAG, "Attmpt to remove content provider: " + localCpr 7875 + " with no external references."); 7876 } 7877 } 7878 } 7879 7880 public final void publishContentProviders(IApplicationThread caller, 7881 List<ContentProviderHolder> providers) { 7882 if (providers == null) { 7883 return; 7884 } 7885 7886 enforceNotIsolatedCaller("publishContentProviders"); 7887 synchronized (this) { 7888 final ProcessRecord r = getRecordForAppLocked(caller); 7889 if (DEBUG_MU) 7890 Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid); 7891 if (r == null) { 7892 throw new SecurityException( 7893 "Unable to find app for caller " + caller 7894 + " (pid=" + Binder.getCallingPid() 7895 + ") when publishing content providers"); 7896 } 7897 7898 final long origId = Binder.clearCallingIdentity(); 7899 7900 final int N = providers.size(); 7901 for (int i=0; i<N; i++) { 7902 ContentProviderHolder src = providers.get(i); 7903 if (src == null || src.info == null || src.provider == null) { 7904 continue; 7905 } 7906 ContentProviderRecord dst = r.pubProviders.get(src.info.name); 7907 if (DEBUG_MU) 7908 Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid); 7909 if (dst != null) { 7910 ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name); 7911 mProviderMap.putProviderByClass(comp, dst); 7912 String names[] = dst.info.authority.split(";"); 7913 for (int j = 0; j < names.length; j++) { 7914 mProviderMap.putProviderByName(names[j], dst); 7915 } 7916 7917 int NL = mLaunchingProviders.size(); 7918 int j; 7919 for (j=0; j<NL; j++) { 7920 if (mLaunchingProviders.get(j) == dst) { 7921 mLaunchingProviders.remove(j); 7922 j--; 7923 NL--; 7924 } 7925 } 7926 synchronized (dst) { 7927 dst.provider = src.provider; 7928 dst.proc = r; 7929 dst.notifyAll(); 7930 } 7931 updateOomAdjLocked(r); 7932 } 7933 } 7934 7935 Binder.restoreCallingIdentity(origId); 7936 } 7937 } 7938 7939 public boolean refContentProvider(IBinder connection, int stable, int unstable) { 7940 ContentProviderConnection conn; 7941 try { 7942 conn = (ContentProviderConnection)connection; 7943 } catch (ClassCastException e) { 7944 String msg ="refContentProvider: " + connection 7945 + " not a ContentProviderConnection"; 7946 Slog.w(TAG, msg); 7947 throw new IllegalArgumentException(msg); 7948 } 7949 if (conn == null) { 7950 throw new NullPointerException("connection is null"); 7951 } 7952 7953 synchronized (this) { 7954 if (stable > 0) { 7955 conn.numStableIncs += stable; 7956 } 7957 stable = conn.stableCount + stable; 7958 if (stable < 0) { 7959 throw new IllegalStateException("stableCount < 0: " + stable); 7960 } 7961 7962 if (unstable > 0) { 7963 conn.numUnstableIncs += unstable; 7964 } 7965 unstable = conn.unstableCount + unstable; 7966 if (unstable < 0) { 7967 throw new IllegalStateException("unstableCount < 0: " + unstable); 7968 } 7969 7970 if ((stable+unstable) <= 0) { 7971 throw new IllegalStateException("ref counts can't go to zero here: stable=" 7972 + stable + " unstable=" + unstable); 7973 } 7974 conn.stableCount = stable; 7975 conn.unstableCount = unstable; 7976 return !conn.dead; 7977 } 7978 } 7979 7980 public void unstableProviderDied(IBinder connection) { 7981 ContentProviderConnection conn; 7982 try { 7983 conn = (ContentProviderConnection)connection; 7984 } catch (ClassCastException e) { 7985 String msg ="refContentProvider: " + connection 7986 + " not a ContentProviderConnection"; 7987 Slog.w(TAG, msg); 7988 throw new IllegalArgumentException(msg); 7989 } 7990 if (conn == null) { 7991 throw new NullPointerException("connection is null"); 7992 } 7993 7994 // Safely retrieve the content provider associated with the connection. 7995 IContentProvider provider; 7996 synchronized (this) { 7997 provider = conn.provider.provider; 7998 } 7999 8000 if (provider == null) { 8001 // Um, yeah, we're way ahead of you. 8002 return; 8003 } 8004 8005 // Make sure the caller is being honest with us. 8006 if (provider.asBinder().pingBinder()) { 8007 // Er, no, still looks good to us. 8008 synchronized (this) { 8009 Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid() 8010 + " says " + conn + " died, but we don't agree"); 8011 return; 8012 } 8013 } 8014 8015 // Well look at that! It's dead! 8016 synchronized (this) { 8017 if (conn.provider.provider != provider) { 8018 // But something changed... good enough. 8019 return; 8020 } 8021 8022 ProcessRecord proc = conn.provider.proc; 8023 if (proc == null || proc.thread == null) { 8024 // Seems like the process is already cleaned up. 8025 return; 8026 } 8027 8028 // As far as we're concerned, this is just like receiving a 8029 // death notification... just a bit prematurely. 8030 Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid 8031 + ") early provider death"); 8032 final long ident = Binder.clearCallingIdentity(); 8033 try { 8034 appDiedLocked(proc, proc.pid, proc.thread); 8035 } finally { 8036 Binder.restoreCallingIdentity(ident); 8037 } 8038 } 8039 } 8040 8041 @Override 8042 public void appNotRespondingViaProvider(IBinder connection) { 8043 enforceCallingPermission( 8044 android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()"); 8045 8046 final ContentProviderConnection conn = (ContentProviderConnection) connection; 8047 if (conn == null) { 8048 Slog.w(TAG, "ContentProviderConnection is null"); 8049 return; 8050 } 8051 8052 final ProcessRecord host = conn.provider.proc; 8053 if (host == null) { 8054 Slog.w(TAG, "Failed to find hosting ProcessRecord"); 8055 return; 8056 } 8057 8058 final long token = Binder.clearCallingIdentity(); 8059 try { 8060 appNotResponding(host, null, null, false, "ContentProvider not responding"); 8061 } finally { 8062 Binder.restoreCallingIdentity(token); 8063 } 8064 } 8065 8066 public final void installSystemProviders() { 8067 List<ProviderInfo> providers; 8068 synchronized (this) { 8069 ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID); 8070 providers = generateApplicationProvidersLocked(app); 8071 if (providers != null) { 8072 for (int i=providers.size()-1; i>=0; i--) { 8073 ProviderInfo pi = (ProviderInfo)providers.get(i); 8074 if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) { 8075 Slog.w(TAG, "Not installing system proc provider " + pi.name 8076 + ": not system .apk"); 8077 providers.remove(i); 8078 } 8079 } 8080 } 8081 } 8082 if (providers != null) { 8083 mSystemThread.installSystemProviders(providers); 8084 } 8085 8086 mCoreSettingsObserver = new CoreSettingsObserver(this); 8087 8088 mUsageStatsService.monitorPackages(); 8089 } 8090 8091 /** 8092 * Allows app to retrieve the MIME type of a URI without having permission 8093 * to access its content provider. 8094 * 8095 * CTS tests for this functionality can be run with "runtest cts-appsecurity". 8096 * 8097 * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/ 8098 * src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java 8099 */ 8100 public String getProviderMimeType(Uri uri, int userId) { 8101 enforceNotIsolatedCaller("getProviderMimeType"); 8102 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 8103 userId, false, true, "getProviderMimeType", null); 8104 final String name = uri.getAuthority(); 8105 final long ident = Binder.clearCallingIdentity(); 8106 ContentProviderHolder holder = null; 8107 8108 try { 8109 holder = getContentProviderExternalUnchecked(name, null, userId); 8110 if (holder != null) { 8111 return holder.provider.getType(uri); 8112 } 8113 } catch (RemoteException e) { 8114 Log.w(TAG, "Content provider dead retrieving " + uri, e); 8115 return null; 8116 } finally { 8117 if (holder != null) { 8118 removeContentProviderExternalUnchecked(name, null, userId); 8119 } 8120 Binder.restoreCallingIdentity(ident); 8121 } 8122 8123 return null; 8124 } 8125 8126 // ========================================================= 8127 // GLOBAL MANAGEMENT 8128 // ========================================================= 8129 8130 final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess, 8131 boolean isolated) { 8132 String proc = customProcess != null ? customProcess : info.processName; 8133 BatteryStatsImpl.Uid.Proc ps = null; 8134 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 8135 int uid = info.uid; 8136 if (isolated) { 8137 int userId = UserHandle.getUserId(uid); 8138 int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1; 8139 while (true) { 8140 if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID 8141 || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) { 8142 mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID; 8143 } 8144 uid = UserHandle.getUid(userId, mNextIsolatedProcessUid); 8145 mNextIsolatedProcessUid++; 8146 if (mIsolatedProcesses.indexOfKey(uid) < 0) { 8147 // No process for this uid, use it. 8148 break; 8149 } 8150 stepsLeft--; 8151 if (stepsLeft <= 0) { 8152 return null; 8153 } 8154 } 8155 } 8156 return new ProcessRecord(stats, info, proc, uid); 8157 } 8158 8159 final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated) { 8160 ProcessRecord app; 8161 if (!isolated) { 8162 app = getProcessRecordLocked(info.processName, info.uid, true); 8163 } else { 8164 app = null; 8165 } 8166 8167 if (app == null) { 8168 app = newProcessRecordLocked(info, null, isolated); 8169 mProcessNames.put(info.processName, app.uid, app); 8170 if (isolated) { 8171 mIsolatedProcesses.put(app.uid, app); 8172 } 8173 updateLruProcessLocked(app, false, null); 8174 updateOomAdjLocked(); 8175 } 8176 8177 // This package really, really can not be stopped. 8178 try { 8179 AppGlobals.getPackageManager().setPackageStoppedState( 8180 info.packageName, false, UserHandle.getUserId(app.uid)); 8181 } catch (RemoteException e) { 8182 } catch (IllegalArgumentException e) { 8183 Slog.w(TAG, "Failed trying to unstop package " 8184 + info.packageName + ": " + e); 8185 } 8186 8187 if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) 8188 == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) { 8189 app.persistent = true; 8190 app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ; 8191 } 8192 if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) { 8193 mPersistentStartingProcesses.add(app); 8194 startProcessLocked(app, "added application", app.processName); 8195 } 8196 8197 return app; 8198 } 8199 8200 public void unhandledBack() { 8201 enforceCallingPermission(android.Manifest.permission.FORCE_BACK, 8202 "unhandledBack()"); 8203 8204 synchronized(this) { 8205 final long origId = Binder.clearCallingIdentity(); 8206 try { 8207 getFocusedStack().unhandledBackLocked(); 8208 } finally { 8209 Binder.restoreCallingIdentity(origId); 8210 } 8211 } 8212 } 8213 8214 public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException { 8215 enforceNotIsolatedCaller("openContentUri"); 8216 final int userId = UserHandle.getCallingUserId(); 8217 String name = uri.getAuthority(); 8218 ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId); 8219 ParcelFileDescriptor pfd = null; 8220 if (cph != null) { 8221 // We record the binder invoker's uid in thread-local storage before 8222 // going to the content provider to open the file. Later, in the code 8223 // that handles all permissions checks, we look for this uid and use 8224 // that rather than the Activity Manager's own uid. The effect is that 8225 // we do the check against the caller's permissions even though it looks 8226 // to the content provider like the Activity Manager itself is making 8227 // the request. 8228 sCallerIdentity.set(new Identity( 8229 Binder.getCallingPid(), Binder.getCallingUid())); 8230 try { 8231 pfd = cph.provider.openFile(null, uri, "r", null); 8232 } catch (FileNotFoundException e) { 8233 // do nothing; pfd will be returned null 8234 } finally { 8235 // Ensure that whatever happens, we clean up the identity state 8236 sCallerIdentity.remove(); 8237 } 8238 8239 // We've got the fd now, so we're done with the provider. 8240 removeContentProviderExternalUnchecked(name, null, userId); 8241 } else { 8242 Slog.d(TAG, "Failed to get provider for authority '" + name + "'"); 8243 } 8244 return pfd; 8245 } 8246 8247 // Actually is sleeping or shutting down or whatever else in the future 8248 // is an inactive state. 8249 public boolean isSleepingOrShuttingDown() { 8250 return mSleeping || mShuttingDown; 8251 } 8252 8253 public void goingToSleep() { 8254 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER) 8255 != PackageManager.PERMISSION_GRANTED) { 8256 throw new SecurityException("Requires permission " 8257 + android.Manifest.permission.DEVICE_POWER); 8258 } 8259 8260 synchronized(this) { 8261 mWentToSleep = true; 8262 updateEventDispatchingLocked(); 8263 8264 if (!mSleeping) { 8265 mSleeping = true; 8266 mStackSupervisor.goingToSleepLocked(); 8267 8268 // Initialize the wake times of all processes. 8269 checkExcessivePowerUsageLocked(false); 8270 mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 8271 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 8272 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 8273 } 8274 } 8275 } 8276 8277 @Override 8278 public boolean shutdown(int timeout) { 8279 if (checkCallingPermission(android.Manifest.permission.SHUTDOWN) 8280 != PackageManager.PERMISSION_GRANTED) { 8281 throw new SecurityException("Requires permission " 8282 + android.Manifest.permission.SHUTDOWN); 8283 } 8284 8285 boolean timedout = false; 8286 8287 synchronized(this) { 8288 mShuttingDown = true; 8289 updateEventDispatchingLocked(); 8290 timedout = mStackSupervisor.shutdownLocked(timeout); 8291 } 8292 8293 mAppOpsService.shutdown(); 8294 mUsageStatsService.shutdown(); 8295 mBatteryStatsService.shutdown(); 8296 synchronized (this) { 8297 mProcessStats.shutdownLocked(); 8298 } 8299 8300 return timedout; 8301 } 8302 8303 public final void activitySlept(IBinder token) { 8304 if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token); 8305 8306 final long origId = Binder.clearCallingIdentity(); 8307 8308 synchronized (this) { 8309 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 8310 if (r != null) { 8311 mStackSupervisor.activitySleptLocked(r); 8312 } 8313 } 8314 8315 Binder.restoreCallingIdentity(origId); 8316 } 8317 8318 void logLockScreen(String msg) { 8319 if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg + 8320 " mLockScreenShown=" + mLockScreenShown + " mWentToSleep=" + 8321 mWentToSleep + " mSleeping=" + mSleeping + " mDismissKeyguardOnNextActivity=" + 8322 mStackSupervisor.mDismissKeyguardOnNextActivity); 8323 } 8324 8325 private void comeOutOfSleepIfNeededLocked() { 8326 if (!mWentToSleep && !mLockScreenShown) { 8327 if (mSleeping) { 8328 mSleeping = false; 8329 mStackSupervisor.comeOutOfSleepIfNeededLocked(); 8330 } 8331 } 8332 } 8333 8334 public void wakingUp() { 8335 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER) 8336 != PackageManager.PERMISSION_GRANTED) { 8337 throw new SecurityException("Requires permission " 8338 + android.Manifest.permission.DEVICE_POWER); 8339 } 8340 8341 synchronized(this) { 8342 mWentToSleep = false; 8343 updateEventDispatchingLocked(); 8344 comeOutOfSleepIfNeededLocked(); 8345 } 8346 } 8347 8348 private void updateEventDispatchingLocked() { 8349 mWindowManager.setEventDispatching(mBooted && !mWentToSleep && !mShuttingDown); 8350 } 8351 8352 public void setLockScreenShown(boolean shown) { 8353 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER) 8354 != PackageManager.PERMISSION_GRANTED) { 8355 throw new SecurityException("Requires permission " 8356 + android.Manifest.permission.DEVICE_POWER); 8357 } 8358 8359 synchronized(this) { 8360 long ident = Binder.clearCallingIdentity(); 8361 try { 8362 if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown); 8363 mLockScreenShown = shown; 8364 comeOutOfSleepIfNeededLocked(); 8365 } finally { 8366 Binder.restoreCallingIdentity(ident); 8367 } 8368 } 8369 } 8370 8371 public void stopAppSwitches() { 8372 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 8373 != PackageManager.PERMISSION_GRANTED) { 8374 throw new SecurityException("Requires permission " 8375 + android.Manifest.permission.STOP_APP_SWITCHES); 8376 } 8377 8378 synchronized(this) { 8379 mAppSwitchesAllowedTime = SystemClock.uptimeMillis() 8380 + APP_SWITCH_DELAY_TIME; 8381 mDidAppSwitch = false; 8382 mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 8383 Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 8384 mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME); 8385 } 8386 } 8387 8388 public void resumeAppSwitches() { 8389 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 8390 != PackageManager.PERMISSION_GRANTED) { 8391 throw new SecurityException("Requires permission " 8392 + android.Manifest.permission.STOP_APP_SWITCHES); 8393 } 8394 8395 synchronized(this) { 8396 // Note that we don't execute any pending app switches... we will 8397 // let those wait until either the timeout, or the next start 8398 // activity request. 8399 mAppSwitchesAllowedTime = 0; 8400 } 8401 } 8402 8403 boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid, 8404 String name) { 8405 if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) { 8406 return true; 8407 } 8408 8409 final int perm = checkComponentPermission( 8410 android.Manifest.permission.STOP_APP_SWITCHES, callingPid, 8411 callingUid, -1, true); 8412 if (perm == PackageManager.PERMISSION_GRANTED) { 8413 return true; 8414 } 8415 8416 Slog.w(TAG, name + " request from " + callingUid + " stopped"); 8417 return false; 8418 } 8419 8420 public void setDebugApp(String packageName, boolean waitForDebugger, 8421 boolean persistent) { 8422 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP, 8423 "setDebugApp()"); 8424 8425 long ident = Binder.clearCallingIdentity(); 8426 try { 8427 // Note that this is not really thread safe if there are multiple 8428 // callers into it at the same time, but that's not a situation we 8429 // care about. 8430 if (persistent) { 8431 final ContentResolver resolver = mContext.getContentResolver(); 8432 Settings.Global.putString( 8433 resolver, Settings.Global.DEBUG_APP, 8434 packageName); 8435 Settings.Global.putInt( 8436 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 8437 waitForDebugger ? 1 : 0); 8438 } 8439 8440 synchronized (this) { 8441 if (!persistent) { 8442 mOrigDebugApp = mDebugApp; 8443 mOrigWaitForDebugger = mWaitForDebugger; 8444 } 8445 mDebugApp = packageName; 8446 mWaitForDebugger = waitForDebugger; 8447 mDebugTransient = !persistent; 8448 if (packageName != null) { 8449 forceStopPackageLocked(packageName, -1, false, false, true, true, 8450 false, UserHandle.USER_ALL, "set debug app"); 8451 } 8452 } 8453 } finally { 8454 Binder.restoreCallingIdentity(ident); 8455 } 8456 } 8457 8458 void setOpenGlTraceApp(ApplicationInfo app, String processName) { 8459 synchronized (this) { 8460 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 8461 if (!isDebuggable) { 8462 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 8463 throw new SecurityException("Process not debuggable: " + app.packageName); 8464 } 8465 } 8466 8467 mOpenGlTraceApp = processName; 8468 } 8469 } 8470 8471 void setProfileApp(ApplicationInfo app, String processName, String profileFile, 8472 ParcelFileDescriptor profileFd, boolean autoStopProfiler) { 8473 synchronized (this) { 8474 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 8475 if (!isDebuggable) { 8476 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 8477 throw new SecurityException("Process not debuggable: " + app.packageName); 8478 } 8479 } 8480 mProfileApp = processName; 8481 mProfileFile = profileFile; 8482 if (mProfileFd != null) { 8483 try { 8484 mProfileFd.close(); 8485 } catch (IOException e) { 8486 } 8487 mProfileFd = null; 8488 } 8489 mProfileFd = profileFd; 8490 mProfileType = 0; 8491 mAutoStopProfiler = autoStopProfiler; 8492 } 8493 } 8494 8495 @Override 8496 public void setAlwaysFinish(boolean enabled) { 8497 enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH, 8498 "setAlwaysFinish()"); 8499 8500 Settings.Global.putInt( 8501 mContext.getContentResolver(), 8502 Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0); 8503 8504 synchronized (this) { 8505 mAlwaysFinishActivities = enabled; 8506 } 8507 } 8508 8509 @Override 8510 public void setActivityController(IActivityController controller) { 8511 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 8512 "setActivityController()"); 8513 synchronized (this) { 8514 mController = controller; 8515 Watchdog.getInstance().setActivityController(controller); 8516 } 8517 } 8518 8519 @Override 8520 public void setUserIsMonkey(boolean userIsMonkey) { 8521 synchronized (this) { 8522 synchronized (mPidsSelfLocked) { 8523 final int callingPid = Binder.getCallingPid(); 8524 ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid); 8525 if (precessRecord == null) { 8526 throw new SecurityException("Unknown process: " + callingPid); 8527 } 8528 if (precessRecord.instrumentationUiAutomationConnection == null) { 8529 throw new SecurityException("Only an instrumentation process " 8530 + "with a UiAutomation can call setUserIsMonkey"); 8531 } 8532 } 8533 mUserIsMonkey = userIsMonkey; 8534 } 8535 } 8536 8537 @Override 8538 public boolean isUserAMonkey() { 8539 synchronized (this) { 8540 // If there is a controller also implies the user is a monkey. 8541 return (mUserIsMonkey || mController != null); 8542 } 8543 } 8544 8545 public void requestBugReport() { 8546 enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport"); 8547 SystemProperties.set("ctl.start", "bugreport"); 8548 } 8549 8550 public static long getInputDispatchingTimeoutLocked(ActivityRecord r) { 8551 return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT; 8552 } 8553 8554 public static long getInputDispatchingTimeoutLocked(ProcessRecord r) { 8555 if (r != null && (r.instrumentationClass != null || r.usingWrapper)) { 8556 return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT; 8557 } 8558 return KEY_DISPATCHING_TIMEOUT; 8559 } 8560 8561 @Override 8562 public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) { 8563 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS) 8564 != PackageManager.PERMISSION_GRANTED) { 8565 throw new SecurityException("Requires permission " 8566 + android.Manifest.permission.FILTER_EVENTS); 8567 } 8568 ProcessRecord proc; 8569 long timeout; 8570 synchronized (this) { 8571 synchronized (mPidsSelfLocked) { 8572 proc = mPidsSelfLocked.get(pid); 8573 } 8574 timeout = getInputDispatchingTimeoutLocked(proc); 8575 } 8576 8577 if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) { 8578 return -1; 8579 } 8580 8581 return timeout; 8582 } 8583 8584 /** 8585 * Handle input dispatching timeouts. 8586 * Returns whether input dispatching should be aborted or not. 8587 */ 8588 public boolean inputDispatchingTimedOut(final ProcessRecord proc, 8589 final ActivityRecord activity, final ActivityRecord parent, 8590 final boolean aboveSystem, String reason) { 8591 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS) 8592 != PackageManager.PERMISSION_GRANTED) { 8593 throw new SecurityException("Requires permission " 8594 + android.Manifest.permission.FILTER_EVENTS); 8595 } 8596 8597 final String annotation; 8598 if (reason == null) { 8599 annotation = "Input dispatching timed out"; 8600 } else { 8601 annotation = "Input dispatching timed out (" + reason + ")"; 8602 } 8603 8604 if (proc != null) { 8605 synchronized (this) { 8606 if (proc.debugging) { 8607 return false; 8608 } 8609 8610 if (mDidDexOpt) { 8611 // Give more time since we were dexopting. 8612 mDidDexOpt = false; 8613 return false; 8614 } 8615 8616 if (proc.instrumentationClass != null) { 8617 Bundle info = new Bundle(); 8618 info.putString("shortMsg", "keyDispatchingTimedOut"); 8619 info.putString("longMsg", annotation); 8620 finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info); 8621 return true; 8622 } 8623 } 8624 mHandler.post(new Runnable() { 8625 @Override 8626 public void run() { 8627 appNotResponding(proc, activity, parent, aboveSystem, annotation); 8628 } 8629 }); 8630 } 8631 8632 return true; 8633 } 8634 8635 public Bundle getAssistContextExtras(int requestType) { 8636 enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO, 8637 "getAssistContextExtras()"); 8638 PendingAssistExtras pae; 8639 Bundle extras = new Bundle(); 8640 synchronized (this) { 8641 ActivityRecord activity = getFocusedStack().mResumedActivity; 8642 if (activity == null) { 8643 Slog.w(TAG, "getAssistContextExtras failed: no resumed activity"); 8644 return null; 8645 } 8646 extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName); 8647 if (activity.app == null || activity.app.thread == null) { 8648 Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity); 8649 return extras; 8650 } 8651 if (activity.app.pid == Binder.getCallingPid()) { 8652 Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity); 8653 return extras; 8654 } 8655 pae = new PendingAssistExtras(activity); 8656 try { 8657 activity.app.thread.requestAssistContextExtras(activity.appToken, pae, 8658 requestType); 8659 mPendingAssistExtras.add(pae); 8660 mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT); 8661 } catch (RemoteException e) { 8662 Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity); 8663 return extras; 8664 } 8665 } 8666 synchronized (pae) { 8667 while (!pae.haveResult) { 8668 try { 8669 pae.wait(); 8670 } catch (InterruptedException e) { 8671 } 8672 } 8673 if (pae.result != null) { 8674 extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result); 8675 } 8676 } 8677 synchronized (this) { 8678 mPendingAssistExtras.remove(pae); 8679 mHandler.removeCallbacks(pae); 8680 } 8681 return extras; 8682 } 8683 8684 public void reportAssistContextExtras(IBinder token, Bundle extras) { 8685 PendingAssistExtras pae = (PendingAssistExtras)token; 8686 synchronized (pae) { 8687 pae.result = extras; 8688 pae.haveResult = true; 8689 pae.notifyAll(); 8690 } 8691 } 8692 8693 public void registerProcessObserver(IProcessObserver observer) { 8694 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 8695 "registerProcessObserver()"); 8696 synchronized (this) { 8697 mProcessObservers.register(observer); 8698 } 8699 } 8700 8701 @Override 8702 public void unregisterProcessObserver(IProcessObserver observer) { 8703 synchronized (this) { 8704 mProcessObservers.unregister(observer); 8705 } 8706 } 8707 8708 @Override 8709 public boolean convertFromTranslucent(IBinder token) { 8710 final long origId = Binder.clearCallingIdentity(); 8711 try { 8712 synchronized (this) { 8713 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 8714 if (r == null) { 8715 return false; 8716 } 8717 if (r.changeWindowTranslucency(true)) { 8718 mWindowManager.setAppFullscreen(token, true); 8719 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 8720 return true; 8721 } 8722 return false; 8723 } 8724 } finally { 8725 Binder.restoreCallingIdentity(origId); 8726 } 8727 } 8728 8729 @Override 8730 public boolean convertToTranslucent(IBinder token) { 8731 final long origId = Binder.clearCallingIdentity(); 8732 try { 8733 synchronized (this) { 8734 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 8735 if (r == null) { 8736 return false; 8737 } 8738 if (r.changeWindowTranslucency(false)) { 8739 r.task.stack.convertToTranslucent(r); 8740 mWindowManager.setAppFullscreen(token, false); 8741 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 8742 return true; 8743 } 8744 return false; 8745 } 8746 } finally { 8747 Binder.restoreCallingIdentity(origId); 8748 } 8749 } 8750 8751 @Override 8752 public void setImmersive(IBinder token, boolean immersive) { 8753 synchronized(this) { 8754 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 8755 if (r == null) { 8756 throw new IllegalArgumentException(); 8757 } 8758 r.immersive = immersive; 8759 8760 // update associated state if we're frontmost 8761 if (r == mFocusedActivity) { 8762 if (DEBUG_IMMERSIVE) { 8763 Slog.d(TAG, "Frontmost changed immersion: "+ r); 8764 } 8765 applyUpdateLockStateLocked(r); 8766 } 8767 } 8768 } 8769 8770 @Override 8771 public boolean isImmersive(IBinder token) { 8772 synchronized (this) { 8773 ActivityRecord r = ActivityRecord.isInStackLocked(token); 8774 if (r == null) { 8775 throw new IllegalArgumentException(); 8776 } 8777 return r.immersive; 8778 } 8779 } 8780 8781 public boolean isTopActivityImmersive() { 8782 enforceNotIsolatedCaller("startActivity"); 8783 synchronized (this) { 8784 ActivityRecord r = getFocusedStack().topRunningActivityLocked(null); 8785 return (r != null) ? r.immersive : false; 8786 } 8787 } 8788 8789 public final void enterSafeMode() { 8790 synchronized(this) { 8791 // It only makes sense to do this before the system is ready 8792 // and started launching other packages. 8793 if (!mSystemReady) { 8794 try { 8795 AppGlobals.getPackageManager().enterSafeMode(); 8796 } catch (RemoteException e) { 8797 } 8798 } 8799 } 8800 } 8801 8802 public final void showSafeModeOverlay() { 8803 View v = LayoutInflater.from(mContext).inflate( 8804 com.android.internal.R.layout.safe_mode, null); 8805 WindowManager.LayoutParams lp = new WindowManager.LayoutParams(); 8806 lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY; 8807 lp.width = WindowManager.LayoutParams.WRAP_CONTENT; 8808 lp.height = WindowManager.LayoutParams.WRAP_CONTENT; 8809 lp.gravity = Gravity.BOTTOM | Gravity.START; 8810 lp.format = v.getBackground().getOpacity(); 8811 lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE 8812 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE; 8813 lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS; 8814 ((WindowManager)mContext.getSystemService( 8815 Context.WINDOW_SERVICE)).addView(v, lp); 8816 } 8817 8818 public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) { 8819 if (!(sender instanceof PendingIntentRecord)) { 8820 return; 8821 } 8822 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 8823 synchronized (stats) { 8824 if (mBatteryStatsService.isOnBattery()) { 8825 mBatteryStatsService.enforceCallingPermission(); 8826 PendingIntentRecord rec = (PendingIntentRecord)sender; 8827 int MY_UID = Binder.getCallingUid(); 8828 int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid; 8829 BatteryStatsImpl.Uid.Pkg pkg = 8830 stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid, 8831 sourcePkg != null ? sourcePkg : rec.key.packageName); 8832 pkg.incWakeupsLocked(); 8833 } 8834 } 8835 } 8836 8837 public boolean killPids(int[] pids, String pReason, boolean secure) { 8838 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 8839 throw new SecurityException("killPids only available to the system"); 8840 } 8841 String reason = (pReason == null) ? "Unknown" : pReason; 8842 // XXX Note: don't acquire main activity lock here, because the window 8843 // manager calls in with its locks held. 8844 8845 boolean killed = false; 8846 synchronized (mPidsSelfLocked) { 8847 int[] types = new int[pids.length]; 8848 int worstType = 0; 8849 for (int i=0; i<pids.length; i++) { 8850 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 8851 if (proc != null) { 8852 int type = proc.setAdj; 8853 types[i] = type; 8854 if (type > worstType) { 8855 worstType = type; 8856 } 8857 } 8858 } 8859 8860 // If the worst oom_adj is somewhere in the cached proc LRU range, 8861 // then constrain it so we will kill all cached procs. 8862 if (worstType < ProcessList.CACHED_APP_MAX_ADJ 8863 && worstType > ProcessList.CACHED_APP_MIN_ADJ) { 8864 worstType = ProcessList.CACHED_APP_MIN_ADJ; 8865 } 8866 8867 // If this is not a secure call, don't let it kill processes that 8868 // are important. 8869 if (!secure && worstType < ProcessList.SERVICE_ADJ) { 8870 worstType = ProcessList.SERVICE_ADJ; 8871 } 8872 8873 Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType); 8874 for (int i=0; i<pids.length; i++) { 8875 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 8876 if (proc == null) { 8877 continue; 8878 } 8879 int adj = proc.setAdj; 8880 if (adj >= worstType && !proc.killedByAm) { 8881 killUnneededProcessLocked(proc, reason); 8882 killed = true; 8883 } 8884 } 8885 } 8886 return killed; 8887 } 8888 8889 @Override 8890 public void killUid(int uid, String reason) { 8891 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 8892 throw new SecurityException("killUid only available to the system"); 8893 } 8894 synchronized (this) { 8895 killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid), 8896 ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false, 8897 reason != null ? reason : "kill uid"); 8898 } 8899 } 8900 8901 @Override 8902 public boolean killProcessesBelowForeground(String reason) { 8903 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 8904 throw new SecurityException("killProcessesBelowForeground() only available to system"); 8905 } 8906 8907 return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason); 8908 } 8909 8910 private boolean killProcessesBelowAdj(int belowAdj, String reason) { 8911 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 8912 throw new SecurityException("killProcessesBelowAdj() only available to system"); 8913 } 8914 8915 boolean killed = false; 8916 synchronized (mPidsSelfLocked) { 8917 final int size = mPidsSelfLocked.size(); 8918 for (int i = 0; i < size; i++) { 8919 final int pid = mPidsSelfLocked.keyAt(i); 8920 final ProcessRecord proc = mPidsSelfLocked.valueAt(i); 8921 if (proc == null) continue; 8922 8923 final int adj = proc.setAdj; 8924 if (adj > belowAdj && !proc.killedByAm) { 8925 killUnneededProcessLocked(proc, reason); 8926 killed = true; 8927 } 8928 } 8929 } 8930 return killed; 8931 } 8932 8933 @Override 8934 public void hang(final IBinder who, boolean allowRestart) { 8935 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 8936 != PackageManager.PERMISSION_GRANTED) { 8937 throw new SecurityException("Requires permission " 8938 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 8939 } 8940 8941 final IBinder.DeathRecipient death = new DeathRecipient() { 8942 @Override 8943 public void binderDied() { 8944 synchronized (this) { 8945 notifyAll(); 8946 } 8947 } 8948 }; 8949 8950 try { 8951 who.linkToDeath(death, 0); 8952 } catch (RemoteException e) { 8953 Slog.w(TAG, "hang: given caller IBinder is already dead."); 8954 return; 8955 } 8956 8957 synchronized (this) { 8958 Watchdog.getInstance().setAllowRestart(allowRestart); 8959 Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid()); 8960 synchronized (death) { 8961 while (who.isBinderAlive()) { 8962 try { 8963 death.wait(); 8964 } catch (InterruptedException e) { 8965 } 8966 } 8967 } 8968 Watchdog.getInstance().setAllowRestart(true); 8969 } 8970 } 8971 8972 @Override 8973 public void restart() { 8974 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 8975 != PackageManager.PERMISSION_GRANTED) { 8976 throw new SecurityException("Requires permission " 8977 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 8978 } 8979 8980 Log.i(TAG, "Sending shutdown broadcast..."); 8981 8982 BroadcastReceiver br = new BroadcastReceiver() { 8983 @Override public void onReceive(Context context, Intent intent) { 8984 // Now the broadcast is done, finish up the low-level shutdown. 8985 Log.i(TAG, "Shutting down activity manager..."); 8986 shutdown(10000); 8987 Log.i(TAG, "Shutdown complete, restarting!"); 8988 Process.killProcess(Process.myPid()); 8989 System.exit(10); 8990 } 8991 }; 8992 8993 // First send the high-level shut down broadcast. 8994 Intent intent = new Intent(Intent.ACTION_SHUTDOWN); 8995 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 8996 intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true); 8997 /* For now we are not doing a clean shutdown, because things seem to get unhappy. 8998 mContext.sendOrderedBroadcastAsUser(intent, 8999 UserHandle.ALL, null, br, mHandler, 0, null, null); 9000 */ 9001 br.onReceive(mContext, intent); 9002 } 9003 9004 private long getLowRamTimeSinceIdle(long now) { 9005 return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0); 9006 } 9007 9008 @Override 9009 public void performIdleMaintenance() { 9010 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 9011 != PackageManager.PERMISSION_GRANTED) { 9012 throw new SecurityException("Requires permission " 9013 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 9014 } 9015 9016 synchronized (this) { 9017 final long now = SystemClock.uptimeMillis(); 9018 final long timeSinceLastIdle = now - mLastIdleTime; 9019 final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now); 9020 mLastIdleTime = now; 9021 mLowRamTimeSinceLastIdle = 0; 9022 if (mLowRamStartTime != 0) { 9023 mLowRamStartTime = now; 9024 } 9025 9026 StringBuilder sb = new StringBuilder(128); 9027 sb.append("Idle maintenance over "); 9028 TimeUtils.formatDuration(timeSinceLastIdle, sb); 9029 sb.append(" low RAM for "); 9030 TimeUtils.formatDuration(lowRamSinceLastIdle, sb); 9031 Slog.i(TAG, sb.toString()); 9032 9033 // If at least 1/3 of our time since the last idle period has been spent 9034 // with RAM low, then we want to kill processes. 9035 boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3); 9036 9037 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 9038 ProcessRecord proc = mLruProcesses.get(i); 9039 if (proc.notCachedSinceIdle) { 9040 if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP 9041 && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) { 9042 if (doKilling && proc.initialIdlePss != 0 9043 && proc.lastPss > ((proc.initialIdlePss*3)/2)) { 9044 killUnneededProcessLocked(proc, "idle maint (pss " + proc.lastPss 9045 + " from " + proc.initialIdlePss + ")"); 9046 } 9047 } 9048 } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) { 9049 proc.notCachedSinceIdle = true; 9050 proc.initialIdlePss = 0; 9051 proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true, 9052 mSleeping, now); 9053 } 9054 } 9055 9056 mHandler.removeMessages(REQUEST_ALL_PSS_MSG); 9057 mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000); 9058 } 9059 } 9060 9061 public final void startRunning(String pkg, String cls, String action, 9062 String data) { 9063 synchronized(this) { 9064 if (mStartRunning) { 9065 return; 9066 } 9067 mStartRunning = true; 9068 mTopComponent = pkg != null && cls != null 9069 ? new ComponentName(pkg, cls) : null; 9070 mTopAction = action != null ? action : Intent.ACTION_MAIN; 9071 mTopData = data; 9072 if (!mSystemReady) { 9073 return; 9074 } 9075 } 9076 9077 systemReady(null); 9078 } 9079 9080 private void retrieveSettings() { 9081 final ContentResolver resolver = mContext.getContentResolver(); 9082 String debugApp = Settings.Global.getString( 9083 resolver, Settings.Global.DEBUG_APP); 9084 boolean waitForDebugger = Settings.Global.getInt( 9085 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0; 9086 boolean alwaysFinishActivities = Settings.Global.getInt( 9087 resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0; 9088 boolean forceRtl = Settings.Global.getInt( 9089 resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0; 9090 // Transfer any global setting for forcing RTL layout, into a System Property 9091 SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0"); 9092 9093 Configuration configuration = new Configuration(); 9094 Settings.System.getConfiguration(resolver, configuration); 9095 if (forceRtl) { 9096 // This will take care of setting the correct layout direction flags 9097 configuration.setLayoutDirection(configuration.locale); 9098 } 9099 9100 synchronized (this) { 9101 mDebugApp = mOrigDebugApp = debugApp; 9102 mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger; 9103 mAlwaysFinishActivities = alwaysFinishActivities; 9104 // This happens before any activities are started, so we can 9105 // change mConfiguration in-place. 9106 updateConfigurationLocked(configuration, null, false, true); 9107 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration); 9108 } 9109 } 9110 9111 public boolean testIsSystemReady() { 9112 // no need to synchronize(this) just to read & return the value 9113 return mSystemReady; 9114 } 9115 9116 private static File getCalledPreBootReceiversFile() { 9117 File dataDir = Environment.getDataDirectory(); 9118 File systemDir = new File(dataDir, "system"); 9119 File fname = new File(systemDir, "called_pre_boots.dat"); 9120 return fname; 9121 } 9122 9123 static final int LAST_DONE_VERSION = 10000; 9124 9125 private static ArrayList<ComponentName> readLastDonePreBootReceivers() { 9126 ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>(); 9127 File file = getCalledPreBootReceiversFile(); 9128 FileInputStream fis = null; 9129 try { 9130 fis = new FileInputStream(file); 9131 DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048)); 9132 int fvers = dis.readInt(); 9133 if (fvers == LAST_DONE_VERSION) { 9134 String vers = dis.readUTF(); 9135 String codename = dis.readUTF(); 9136 String build = dis.readUTF(); 9137 if (android.os.Build.VERSION.RELEASE.equals(vers) 9138 && android.os.Build.VERSION.CODENAME.equals(codename) 9139 && android.os.Build.VERSION.INCREMENTAL.equals(build)) { 9140 int num = dis.readInt(); 9141 while (num > 0) { 9142 num--; 9143 String pkg = dis.readUTF(); 9144 String cls = dis.readUTF(); 9145 lastDoneReceivers.add(new ComponentName(pkg, cls)); 9146 } 9147 } 9148 } 9149 } catch (FileNotFoundException e) { 9150 } catch (IOException e) { 9151 Slog.w(TAG, "Failure reading last done pre-boot receivers", e); 9152 } finally { 9153 if (fis != null) { 9154 try { 9155 fis.close(); 9156 } catch (IOException e) { 9157 } 9158 } 9159 } 9160 return lastDoneReceivers; 9161 } 9162 9163 private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) { 9164 File file = getCalledPreBootReceiversFile(); 9165 FileOutputStream fos = null; 9166 DataOutputStream dos = null; 9167 try { 9168 Slog.i(TAG, "Writing new set of last done pre-boot receivers..."); 9169 fos = new FileOutputStream(file); 9170 dos = new DataOutputStream(new BufferedOutputStream(fos, 2048)); 9171 dos.writeInt(LAST_DONE_VERSION); 9172 dos.writeUTF(android.os.Build.VERSION.RELEASE); 9173 dos.writeUTF(android.os.Build.VERSION.CODENAME); 9174 dos.writeUTF(android.os.Build.VERSION.INCREMENTAL); 9175 dos.writeInt(list.size()); 9176 for (int i=0; i<list.size(); i++) { 9177 dos.writeUTF(list.get(i).getPackageName()); 9178 dos.writeUTF(list.get(i).getClassName()); 9179 } 9180 } catch (IOException e) { 9181 Slog.w(TAG, "Failure writing last done pre-boot receivers", e); 9182 file.delete(); 9183 } finally { 9184 FileUtils.sync(fos); 9185 if (dos != null) { 9186 try { 9187 dos.close(); 9188 } catch (IOException e) { 9189 // TODO Auto-generated catch block 9190 e.printStackTrace(); 9191 } 9192 } 9193 } 9194 } 9195 9196 public void systemReady(final Runnable goingCallback) { 9197 synchronized(this) { 9198 if (mSystemReady) { 9199 if (goingCallback != null) goingCallback.run(); 9200 return; 9201 } 9202 9203 // Check to see if there are any update receivers to run. 9204 if (!mDidUpdate) { 9205 if (mWaitingUpdate) { 9206 return; 9207 } 9208 Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED); 9209 List<ResolveInfo> ris = null; 9210 try { 9211 ris = AppGlobals.getPackageManager().queryIntentReceivers( 9212 intent, null, 0, 0); 9213 } catch (RemoteException e) { 9214 } 9215 if (ris != null) { 9216 for (int i=ris.size()-1; i>=0; i--) { 9217 if ((ris.get(i).activityInfo.applicationInfo.flags 9218 &ApplicationInfo.FLAG_SYSTEM) == 0) { 9219 ris.remove(i); 9220 } 9221 } 9222 intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE); 9223 9224 ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers(); 9225 9226 final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>(); 9227 for (int i=0; i<ris.size(); i++) { 9228 ActivityInfo ai = ris.get(i).activityInfo; 9229 ComponentName comp = new ComponentName(ai.packageName, ai.name); 9230 if (lastDoneReceivers.contains(comp)) { 9231 ris.remove(i); 9232 i--; 9233 } 9234 } 9235 9236 final int[] users = getUsersLocked(); 9237 for (int i=0; i<ris.size(); i++) { 9238 ActivityInfo ai = ris.get(i).activityInfo; 9239 ComponentName comp = new ComponentName(ai.packageName, ai.name); 9240 doneReceivers.add(comp); 9241 intent.setComponent(comp); 9242 for (int j=0; j<users.length; j++) { 9243 IIntentReceiver finisher = null; 9244 if (i == ris.size()-1 && j == users.length-1) { 9245 finisher = new IIntentReceiver.Stub() { 9246 public void performReceive(Intent intent, int resultCode, 9247 String data, Bundle extras, boolean ordered, 9248 boolean sticky, int sendingUser) { 9249 // The raw IIntentReceiver interface is called 9250 // with the AM lock held, so redispatch to 9251 // execute our code without the lock. 9252 mHandler.post(new Runnable() { 9253 public void run() { 9254 synchronized (ActivityManagerService.this) { 9255 mDidUpdate = true; 9256 } 9257 writeLastDonePreBootReceivers(doneReceivers); 9258 showBootMessage(mContext.getText( 9259 R.string.android_upgrading_complete), 9260 false); 9261 systemReady(goingCallback); 9262 } 9263 }); 9264 } 9265 }; 9266 } 9267 Slog.i(TAG, "Sending system update to " + intent.getComponent() 9268 + " for user " + users[j]); 9269 broadcastIntentLocked(null, null, intent, null, finisher, 9270 0, null, null, null, AppOpsManager.OP_NONE, 9271 true, false, MY_PID, Process.SYSTEM_UID, 9272 users[j]); 9273 if (finisher != null) { 9274 mWaitingUpdate = true; 9275 } 9276 } 9277 } 9278 } 9279 if (mWaitingUpdate) { 9280 return; 9281 } 9282 mDidUpdate = true; 9283 } 9284 9285 mAppOpsService.systemReady(); 9286 mSystemReady = true; 9287 if (!mStartRunning) { 9288 return; 9289 } 9290 } 9291 9292 ArrayList<ProcessRecord> procsToKill = null; 9293 synchronized(mPidsSelfLocked) { 9294 for (int i=mPidsSelfLocked.size()-1; i>=0; i--) { 9295 ProcessRecord proc = mPidsSelfLocked.valueAt(i); 9296 if (!isAllowedWhileBooting(proc.info)){ 9297 if (procsToKill == null) { 9298 procsToKill = new ArrayList<ProcessRecord>(); 9299 } 9300 procsToKill.add(proc); 9301 } 9302 } 9303 } 9304 9305 synchronized(this) { 9306 if (procsToKill != null) { 9307 for (int i=procsToKill.size()-1; i>=0; i--) { 9308 ProcessRecord proc = procsToKill.get(i); 9309 Slog.i(TAG, "Removing system update proc: " + proc); 9310 removeProcessLocked(proc, true, false, "system update done"); 9311 } 9312 } 9313 9314 // Now that we have cleaned up any update processes, we 9315 // are ready to start launching real processes and know that 9316 // we won't trample on them any more. 9317 mProcessesReady = true; 9318 } 9319 9320 Slog.i(TAG, "System now ready"); 9321 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY, 9322 SystemClock.uptimeMillis()); 9323 9324 synchronized(this) { 9325 // Make sure we have no pre-ready processes sitting around. 9326 9327 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) { 9328 ResolveInfo ri = mContext.getPackageManager() 9329 .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST), 9330 STOCK_PM_FLAGS); 9331 CharSequence errorMsg = null; 9332 if (ri != null) { 9333 ActivityInfo ai = ri.activityInfo; 9334 ApplicationInfo app = ai.applicationInfo; 9335 if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) { 9336 mTopAction = Intent.ACTION_FACTORY_TEST; 9337 mTopData = null; 9338 mTopComponent = new ComponentName(app.packageName, 9339 ai.name); 9340 } else { 9341 errorMsg = mContext.getResources().getText( 9342 com.android.internal.R.string.factorytest_not_system); 9343 } 9344 } else { 9345 errorMsg = mContext.getResources().getText( 9346 com.android.internal.R.string.factorytest_no_action); 9347 } 9348 if (errorMsg != null) { 9349 mTopAction = null; 9350 mTopData = null; 9351 mTopComponent = null; 9352 Message msg = Message.obtain(); 9353 msg.what = SHOW_FACTORY_ERROR_MSG; 9354 msg.getData().putCharSequence("msg", errorMsg); 9355 mHandler.sendMessage(msg); 9356 } 9357 } 9358 } 9359 9360 retrieveSettings(); 9361 9362 synchronized (this) { 9363 readGrantedUriPermissionsLocked(); 9364 } 9365 9366 if (goingCallback != null) goingCallback.run(); 9367 9368 synchronized (this) { 9369 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 9370 try { 9371 List apps = AppGlobals.getPackageManager(). 9372 getPersistentApplications(STOCK_PM_FLAGS); 9373 if (apps != null) { 9374 int N = apps.size(); 9375 int i; 9376 for (i=0; i<N; i++) { 9377 ApplicationInfo info 9378 = (ApplicationInfo)apps.get(i); 9379 if (info != null && 9380 !info.packageName.equals("android")) { 9381 addAppLocked(info, false); 9382 } 9383 } 9384 } 9385 } catch (RemoteException ex) { 9386 // pm is in same process, this will never happen. 9387 } 9388 } 9389 9390 // Start up initial activity. 9391 mBooting = true; 9392 9393 try { 9394 if (AppGlobals.getPackageManager().hasSystemUidErrors()) { 9395 Message msg = Message.obtain(); 9396 msg.what = SHOW_UID_ERROR_MSG; 9397 mHandler.sendMessage(msg); 9398 } 9399 } catch (RemoteException e) { 9400 } 9401 9402 long ident = Binder.clearCallingIdentity(); 9403 try { 9404 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 9405 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 9406 | Intent.FLAG_RECEIVER_FOREGROUND); 9407 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); 9408 broadcastIntentLocked(null, null, intent, 9409 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 9410 false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId); 9411 intent = new Intent(Intent.ACTION_USER_STARTING); 9412 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 9413 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); 9414 broadcastIntentLocked(null, null, intent, 9415 null, new IIntentReceiver.Stub() { 9416 @Override 9417 public void performReceive(Intent intent, int resultCode, String data, 9418 Bundle extras, boolean ordered, boolean sticky, int sendingUser) 9419 throws RemoteException { 9420 } 9421 }, 0, null, null, 9422 android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 9423 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 9424 } finally { 9425 Binder.restoreCallingIdentity(ident); 9426 } 9427 mStackSupervisor.resumeTopActivitiesLocked(); 9428 sendUserSwitchBroadcastsLocked(-1, mCurrentUserId); 9429 } 9430 } 9431 9432 private boolean makeAppCrashingLocked(ProcessRecord app, 9433 String shortMsg, String longMsg, String stackTrace) { 9434 app.crashing = true; 9435 app.crashingReport = generateProcessError(app, 9436 ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace); 9437 startAppProblemLocked(app); 9438 app.stopFreezingAllLocked(); 9439 return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace); 9440 } 9441 9442 private void makeAppNotRespondingLocked(ProcessRecord app, 9443 String activity, String shortMsg, String longMsg) { 9444 app.notResponding = true; 9445 app.notRespondingReport = generateProcessError(app, 9446 ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING, 9447 activity, shortMsg, longMsg, null); 9448 startAppProblemLocked(app); 9449 app.stopFreezingAllLocked(); 9450 } 9451 9452 /** 9453 * Generate a process error record, suitable for attachment to a ProcessRecord. 9454 * 9455 * @param app The ProcessRecord in which the error occurred. 9456 * @param condition Crashing, Application Not Responding, etc. Values are defined in 9457 * ActivityManager.AppErrorStateInfo 9458 * @param activity The activity associated with the crash, if known. 9459 * @param shortMsg Short message describing the crash. 9460 * @param longMsg Long message describing the crash. 9461 * @param stackTrace Full crash stack trace, may be null. 9462 * 9463 * @return Returns a fully-formed AppErrorStateInfo record. 9464 */ 9465 private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app, 9466 int condition, String activity, String shortMsg, String longMsg, String stackTrace) { 9467 ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo(); 9468 9469 report.condition = condition; 9470 report.processName = app.processName; 9471 report.pid = app.pid; 9472 report.uid = app.info.uid; 9473 report.tag = activity; 9474 report.shortMsg = shortMsg; 9475 report.longMsg = longMsg; 9476 report.stackTrace = stackTrace; 9477 9478 return report; 9479 } 9480 9481 void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) { 9482 synchronized (this) { 9483 app.crashing = false; 9484 app.crashingReport = null; 9485 app.notResponding = false; 9486 app.notRespondingReport = null; 9487 if (app.anrDialog == fromDialog) { 9488 app.anrDialog = null; 9489 } 9490 if (app.waitDialog == fromDialog) { 9491 app.waitDialog = null; 9492 } 9493 if (app.pid > 0 && app.pid != MY_PID) { 9494 handleAppCrashLocked(app, null, null, null); 9495 killUnneededProcessLocked(app, "user request after error"); 9496 } 9497 } 9498 } 9499 9500 private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg, 9501 String stackTrace) { 9502 long now = SystemClock.uptimeMillis(); 9503 9504 Long crashTime; 9505 if (!app.isolated) { 9506 crashTime = mProcessCrashTimes.get(app.info.processName, app.uid); 9507 } else { 9508 crashTime = null; 9509 } 9510 if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) { 9511 // This process loses! 9512 Slog.w(TAG, "Process " + app.info.processName 9513 + " has crashed too many times: killing!"); 9514 EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH, 9515 app.userId, app.info.processName, app.uid); 9516 mStackSupervisor.handleAppCrashLocked(app); 9517 if (!app.persistent) { 9518 // We don't want to start this process again until the user 9519 // explicitly does so... but for persistent process, we really 9520 // need to keep it running. If a persistent process is actually 9521 // repeatedly crashing, then badness for everyone. 9522 EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid, 9523 app.info.processName); 9524 if (!app.isolated) { 9525 // XXX We don't have a way to mark isolated processes 9526 // as bad, since they don't have a peristent identity. 9527 mBadProcesses.put(app.info.processName, app.uid, 9528 new BadProcessInfo(now, shortMsg, longMsg, stackTrace)); 9529 mProcessCrashTimes.remove(app.info.processName, app.uid); 9530 } 9531 app.bad = true; 9532 app.removed = true; 9533 // Don't let services in this process be restarted and potentially 9534 // annoy the user repeatedly. Unless it is persistent, since those 9535 // processes run critical code. 9536 removeProcessLocked(app, false, false, "crash"); 9537 mStackSupervisor.resumeTopActivitiesLocked(); 9538 return false; 9539 } 9540 mStackSupervisor.resumeTopActivitiesLocked(); 9541 } else { 9542 mStackSupervisor.finishTopRunningActivityLocked(app); 9543 } 9544 9545 // Bump up the crash count of any services currently running in the proc. 9546 for (int i=app.services.size()-1; i>=0; i--) { 9547 // Any services running in the application need to be placed 9548 // back in the pending list. 9549 ServiceRecord sr = app.services.valueAt(i); 9550 sr.crashCount++; 9551 } 9552 9553 // If the crashing process is what we consider to be the "home process" and it has been 9554 // replaced by a third-party app, clear the package preferred activities from packages 9555 // with a home activity running in the process to prevent a repeatedly crashing app 9556 // from blocking the user to manually clear the list. 9557 final ArrayList<ActivityRecord> activities = app.activities; 9558 if (app == mHomeProcess && activities.size() > 0 9559 && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) { 9560 for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) { 9561 final ActivityRecord r = activities.get(activityNdx); 9562 if (r.isHomeActivity()) { 9563 Log.i(TAG, "Clearing package preferred activities from " + r.packageName); 9564 try { 9565 ActivityThread.getPackageManager() 9566 .clearPackagePreferredActivities(r.packageName); 9567 } catch (RemoteException c) { 9568 // pm is in same process, this will never happen. 9569 } 9570 } 9571 } 9572 } 9573 9574 if (!app.isolated) { 9575 // XXX Can't keep track of crash times for isolated processes, 9576 // because they don't have a perisistent identity. 9577 mProcessCrashTimes.put(app.info.processName, app.uid, now); 9578 } 9579 9580 return true; 9581 } 9582 9583 void startAppProblemLocked(ProcessRecord app) { 9584 if (app.userId == mCurrentUserId) { 9585 app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver( 9586 mContext, app.info.packageName, app.info.flags); 9587 } else { 9588 // If this app is not running under the current user, then we 9589 // can't give it a report button because that would require 9590 // launching the report UI under a different user. 9591 app.errorReportReceiver = null; 9592 } 9593 skipCurrentReceiverLocked(app); 9594 } 9595 9596 void skipCurrentReceiverLocked(ProcessRecord app) { 9597 for (BroadcastQueue queue : mBroadcastQueues) { 9598 queue.skipCurrentReceiverLocked(app); 9599 } 9600 } 9601 9602 /** 9603 * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes. 9604 * The application process will exit immediately after this call returns. 9605 * @param app object of the crashing app, null for the system server 9606 * @param crashInfo describing the exception 9607 */ 9608 public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) { 9609 ProcessRecord r = findAppProcess(app, "Crash"); 9610 final String processName = app == null ? "system_server" 9611 : (r == null ? "unknown" : r.processName); 9612 9613 handleApplicationCrashInner("crash", r, processName, crashInfo); 9614 } 9615 9616 /* Native crash reporting uses this inner version because it needs to be somewhat 9617 * decoupled from the AM-managed cleanup lifecycle 9618 */ 9619 void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName, 9620 ApplicationErrorReport.CrashInfo crashInfo) { 9621 EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(), 9622 UserHandle.getUserId(Binder.getCallingUid()), processName, 9623 r == null ? -1 : r.info.flags, 9624 crashInfo.exceptionClassName, 9625 crashInfo.exceptionMessage, 9626 crashInfo.throwFileName, 9627 crashInfo.throwLineNumber); 9628 9629 addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo); 9630 9631 crashApplication(r, crashInfo); 9632 } 9633 9634 public void handleApplicationStrictModeViolation( 9635 IBinder app, 9636 int violationMask, 9637 StrictMode.ViolationInfo info) { 9638 ProcessRecord r = findAppProcess(app, "StrictMode"); 9639 if (r == null) { 9640 return; 9641 } 9642 9643 if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) { 9644 Integer stackFingerprint = info.hashCode(); 9645 boolean logIt = true; 9646 synchronized (mAlreadyLoggedViolatedStacks) { 9647 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) { 9648 logIt = false; 9649 // TODO: sub-sample into EventLog for these, with 9650 // the info.durationMillis? Then we'd get 9651 // the relative pain numbers, without logging all 9652 // the stack traces repeatedly. We'd want to do 9653 // likewise in the client code, which also does 9654 // dup suppression, before the Binder call. 9655 } else { 9656 if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) { 9657 mAlreadyLoggedViolatedStacks.clear(); 9658 } 9659 mAlreadyLoggedViolatedStacks.add(stackFingerprint); 9660 } 9661 } 9662 if (logIt) { 9663 logStrictModeViolationToDropBox(r, info); 9664 } 9665 } 9666 9667 if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) { 9668 AppErrorResult result = new AppErrorResult(); 9669 synchronized (this) { 9670 final long origId = Binder.clearCallingIdentity(); 9671 9672 Message msg = Message.obtain(); 9673 msg.what = SHOW_STRICT_MODE_VIOLATION_MSG; 9674 HashMap<String, Object> data = new HashMap<String, Object>(); 9675 data.put("result", result); 9676 data.put("app", r); 9677 data.put("violationMask", violationMask); 9678 data.put("info", info); 9679 msg.obj = data; 9680 mHandler.sendMessage(msg); 9681 9682 Binder.restoreCallingIdentity(origId); 9683 } 9684 int res = result.get(); 9685 Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res); 9686 } 9687 } 9688 9689 // Depending on the policy in effect, there could be a bunch of 9690 // these in quick succession so we try to batch these together to 9691 // minimize disk writes, number of dropbox entries, and maximize 9692 // compression, by having more fewer, larger records. 9693 private void logStrictModeViolationToDropBox( 9694 ProcessRecord process, 9695 StrictMode.ViolationInfo info) { 9696 if (info == null) { 9697 return; 9698 } 9699 final boolean isSystemApp = process == null || 9700 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM | 9701 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0; 9702 final String processName = process == null ? "unknown" : process.processName; 9703 final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode"; 9704 final DropBoxManager dbox = (DropBoxManager) 9705 mContext.getSystemService(Context.DROPBOX_SERVICE); 9706 9707 // Exit early if the dropbox isn't configured to accept this report type. 9708 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 9709 9710 boolean bufferWasEmpty; 9711 boolean needsFlush; 9712 final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024); 9713 synchronized (sb) { 9714 bufferWasEmpty = sb.length() == 0; 9715 appendDropBoxProcessHeaders(process, processName, sb); 9716 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 9717 sb.append("System-App: ").append(isSystemApp).append("\n"); 9718 sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n"); 9719 if (info.violationNumThisLoop != 0) { 9720 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n"); 9721 } 9722 if (info.numAnimationsRunning != 0) { 9723 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n"); 9724 } 9725 if (info.broadcastIntentAction != null) { 9726 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n"); 9727 } 9728 if (info.durationMillis != -1) { 9729 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n"); 9730 } 9731 if (info.numInstances != -1) { 9732 sb.append("Instance-Count: ").append(info.numInstances).append("\n"); 9733 } 9734 if (info.tags != null) { 9735 for (String tag : info.tags) { 9736 sb.append("Span-Tag: ").append(tag).append("\n"); 9737 } 9738 } 9739 sb.append("\n"); 9740 if (info.crashInfo != null && info.crashInfo.stackTrace != null) { 9741 sb.append(info.crashInfo.stackTrace); 9742 } 9743 sb.append("\n"); 9744 9745 // Only buffer up to ~64k. Various logging bits truncate 9746 // things at 128k. 9747 needsFlush = (sb.length() > 64 * 1024); 9748 } 9749 9750 // Flush immediately if the buffer's grown too large, or this 9751 // is a non-system app. Non-system apps are isolated with a 9752 // different tag & policy and not batched. 9753 // 9754 // Batching is useful during internal testing with 9755 // StrictMode settings turned up high. Without batching, 9756 // thousands of separate files could be created on boot. 9757 if (!isSystemApp || needsFlush) { 9758 new Thread("Error dump: " + dropboxTag) { 9759 @Override 9760 public void run() { 9761 String report; 9762 synchronized (sb) { 9763 report = sb.toString(); 9764 sb.delete(0, sb.length()); 9765 sb.trimToSize(); 9766 } 9767 if (report.length() != 0) { 9768 dbox.addText(dropboxTag, report); 9769 } 9770 } 9771 }.start(); 9772 return; 9773 } 9774 9775 // System app batching: 9776 if (!bufferWasEmpty) { 9777 // An existing dropbox-writing thread is outstanding, so 9778 // we don't need to start it up. The existing thread will 9779 // catch the buffer appends we just did. 9780 return; 9781 } 9782 9783 // Worker thread to both batch writes and to avoid blocking the caller on I/O. 9784 // (After this point, we shouldn't access AMS internal data structures.) 9785 new Thread("Error dump: " + dropboxTag) { 9786 @Override 9787 public void run() { 9788 // 5 second sleep to let stacks arrive and be batched together 9789 try { 9790 Thread.sleep(5000); // 5 seconds 9791 } catch (InterruptedException e) {} 9792 9793 String errorReport; 9794 synchronized (mStrictModeBuffer) { 9795 errorReport = mStrictModeBuffer.toString(); 9796 if (errorReport.length() == 0) { 9797 return; 9798 } 9799 mStrictModeBuffer.delete(0, mStrictModeBuffer.length()); 9800 mStrictModeBuffer.trimToSize(); 9801 } 9802 dbox.addText(dropboxTag, errorReport); 9803 } 9804 }.start(); 9805 } 9806 9807 /** 9808 * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors. 9809 * @param app object of the crashing app, null for the system server 9810 * @param tag reported by the caller 9811 * @param crashInfo describing the context of the error 9812 * @return true if the process should exit immediately (WTF is fatal) 9813 */ 9814 public boolean handleApplicationWtf(IBinder app, String tag, 9815 ApplicationErrorReport.CrashInfo crashInfo) { 9816 ProcessRecord r = findAppProcess(app, "WTF"); 9817 final String processName = app == null ? "system_server" 9818 : (r == null ? "unknown" : r.processName); 9819 9820 EventLog.writeEvent(EventLogTags.AM_WTF, 9821 UserHandle.getUserId(Binder.getCallingUid()), Binder.getCallingPid(), 9822 processName, 9823 r == null ? -1 : r.info.flags, 9824 tag, crashInfo.exceptionMessage); 9825 9826 addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo); 9827 9828 if (r != null && r.pid != Process.myPid() && 9829 Settings.Global.getInt(mContext.getContentResolver(), 9830 Settings.Global.WTF_IS_FATAL, 0) != 0) { 9831 crashApplication(r, crashInfo); 9832 return true; 9833 } else { 9834 return false; 9835 } 9836 } 9837 9838 /** 9839 * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit}) 9840 * @return the corresponding {@link ProcessRecord} object, or null if none could be found 9841 */ 9842 private ProcessRecord findAppProcess(IBinder app, String reason) { 9843 if (app == null) { 9844 return null; 9845 } 9846 9847 synchronized (this) { 9848 final int NP = mProcessNames.getMap().size(); 9849 for (int ip=0; ip<NP; ip++) { 9850 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 9851 final int NA = apps.size(); 9852 for (int ia=0; ia<NA; ia++) { 9853 ProcessRecord p = apps.valueAt(ia); 9854 if (p.thread != null && p.thread.asBinder() == app) { 9855 return p; 9856 } 9857 } 9858 } 9859 9860 Slog.w(TAG, "Can't find mystery application for " + reason 9861 + " from pid=" + Binder.getCallingPid() 9862 + " uid=" + Binder.getCallingUid() + ": " + app); 9863 return null; 9864 } 9865 } 9866 9867 /** 9868 * Utility function for addErrorToDropBox and handleStrictModeViolation's logging 9869 * to append various headers to the dropbox log text. 9870 */ 9871 private void appendDropBoxProcessHeaders(ProcessRecord process, String processName, 9872 StringBuilder sb) { 9873 // Watchdog thread ends up invoking this function (with 9874 // a null ProcessRecord) to add the stack file to dropbox. 9875 // Do not acquire a lock on this (am) in such cases, as it 9876 // could cause a potential deadlock, if and when watchdog 9877 // is invoked due to unavailability of lock on am and it 9878 // would prevent watchdog from killing system_server. 9879 if (process == null) { 9880 sb.append("Process: ").append(processName).append("\n"); 9881 return; 9882 } 9883 // Note: ProcessRecord 'process' is guarded by the service 9884 // instance. (notably process.pkgList, which could otherwise change 9885 // concurrently during execution of this method) 9886 synchronized (this) { 9887 sb.append("Process: ").append(processName).append("\n"); 9888 int flags = process.info.flags; 9889 IPackageManager pm = AppGlobals.getPackageManager(); 9890 sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n"); 9891 for (int ip=0; ip<process.pkgList.size(); ip++) { 9892 String pkg = process.pkgList.keyAt(ip); 9893 sb.append("Package: ").append(pkg); 9894 try { 9895 PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId()); 9896 if (pi != null) { 9897 sb.append(" v").append(pi.versionCode); 9898 if (pi.versionName != null) { 9899 sb.append(" (").append(pi.versionName).append(")"); 9900 } 9901 } 9902 } catch (RemoteException e) { 9903 Slog.e(TAG, "Error getting package info: " + pkg, e); 9904 } 9905 sb.append("\n"); 9906 } 9907 } 9908 } 9909 9910 private static String processClass(ProcessRecord process) { 9911 if (process == null || process.pid == MY_PID) { 9912 return "system_server"; 9913 } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) { 9914 return "system_app"; 9915 } else { 9916 return "data_app"; 9917 } 9918 } 9919 9920 /** 9921 * Write a description of an error (crash, WTF, ANR) to the drop box. 9922 * @param eventType to include in the drop box tag ("crash", "wtf", etc.) 9923 * @param process which caused the error, null means the system server 9924 * @param activity which triggered the error, null if unknown 9925 * @param parent activity related to the error, null if unknown 9926 * @param subject line related to the error, null if absent 9927 * @param report in long form describing the error, null if absent 9928 * @param logFile to include in the report, null if none 9929 * @param crashInfo giving an application stack trace, null if absent 9930 */ 9931 public void addErrorToDropBox(String eventType, 9932 ProcessRecord process, String processName, ActivityRecord activity, 9933 ActivityRecord parent, String subject, 9934 final String report, final File logFile, 9935 final ApplicationErrorReport.CrashInfo crashInfo) { 9936 // NOTE -- this must never acquire the ActivityManagerService lock, 9937 // otherwise the watchdog may be prevented from resetting the system. 9938 9939 final String dropboxTag = processClass(process) + "_" + eventType; 9940 final DropBoxManager dbox = (DropBoxManager) 9941 mContext.getSystemService(Context.DROPBOX_SERVICE); 9942 9943 // Exit early if the dropbox isn't configured to accept this report type. 9944 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 9945 9946 final StringBuilder sb = new StringBuilder(1024); 9947 appendDropBoxProcessHeaders(process, processName, sb); 9948 if (activity != null) { 9949 sb.append("Activity: ").append(activity.shortComponentName).append("\n"); 9950 } 9951 if (parent != null && parent.app != null && parent.app.pid != process.pid) { 9952 sb.append("Parent-Process: ").append(parent.app.processName).append("\n"); 9953 } 9954 if (parent != null && parent != activity) { 9955 sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n"); 9956 } 9957 if (subject != null) { 9958 sb.append("Subject: ").append(subject).append("\n"); 9959 } 9960 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 9961 if (Debug.isDebuggerConnected()) { 9962 sb.append("Debugger: Connected\n"); 9963 } 9964 sb.append("\n"); 9965 9966 // Do the rest in a worker thread to avoid blocking the caller on I/O 9967 // (After this point, we shouldn't access AMS internal data structures.) 9968 Thread worker = new Thread("Error dump: " + dropboxTag) { 9969 @Override 9970 public void run() { 9971 if (report != null) { 9972 sb.append(report); 9973 } 9974 if (logFile != null) { 9975 try { 9976 sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE, 9977 "\n\n[[TRUNCATED]]")); 9978 } catch (IOException e) { 9979 Slog.e(TAG, "Error reading " + logFile, e); 9980 } 9981 } 9982 if (crashInfo != null && crashInfo.stackTrace != null) { 9983 sb.append(crashInfo.stackTrace); 9984 } 9985 9986 String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag; 9987 int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0); 9988 if (lines > 0) { 9989 sb.append("\n"); 9990 9991 // Merge several logcat streams, and take the last N lines 9992 InputStreamReader input = null; 9993 try { 9994 java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat", 9995 "-v", "time", "-b", "events", "-b", "system", "-b", "main", 9996 "-t", String.valueOf(lines)).redirectErrorStream(true).start(); 9997 9998 try { logcat.getOutputStream().close(); } catch (IOException e) {} 9999 try { logcat.getErrorStream().close(); } catch (IOException e) {} 10000 input = new InputStreamReader(logcat.getInputStream()); 10001 10002 int num; 10003 char[] buf = new char[8192]; 10004 while ((num = input.read(buf)) > 0) sb.append(buf, 0, num); 10005 } catch (IOException e) { 10006 Slog.e(TAG, "Error running logcat", e); 10007 } finally { 10008 if (input != null) try { input.close(); } catch (IOException e) {} 10009 } 10010 } 10011 10012 dbox.addText(dropboxTag, sb.toString()); 10013 } 10014 }; 10015 10016 if (process == null) { 10017 // If process is null, we are being called from some internal code 10018 // and may be about to die -- run this synchronously. 10019 worker.run(); 10020 } else { 10021 worker.start(); 10022 } 10023 } 10024 10025 /** 10026 * Bring up the "unexpected error" dialog box for a crashing app. 10027 * Deal with edge cases (intercepts from instrumented applications, 10028 * ActivityController, error intent receivers, that sort of thing). 10029 * @param r the application crashing 10030 * @param crashInfo describing the failure 10031 */ 10032 private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) { 10033 long timeMillis = System.currentTimeMillis(); 10034 String shortMsg = crashInfo.exceptionClassName; 10035 String longMsg = crashInfo.exceptionMessage; 10036 String stackTrace = crashInfo.stackTrace; 10037 if (shortMsg != null && longMsg != null) { 10038 longMsg = shortMsg + ": " + longMsg; 10039 } else if (shortMsg != null) { 10040 longMsg = shortMsg; 10041 } 10042 10043 AppErrorResult result = new AppErrorResult(); 10044 synchronized (this) { 10045 if (mController != null) { 10046 try { 10047 String name = r != null ? r.processName : null; 10048 int pid = r != null ? r.pid : Binder.getCallingPid(); 10049 if (!mController.appCrashed(name, pid, 10050 shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) { 10051 Slog.w(TAG, "Force-killing crashed app " + name 10052 + " at watcher's request"); 10053 Process.killProcess(pid); 10054 return; 10055 } 10056 } catch (RemoteException e) { 10057 mController = null; 10058 Watchdog.getInstance().setActivityController(null); 10059 } 10060 } 10061 10062 final long origId = Binder.clearCallingIdentity(); 10063 10064 // If this process is running instrumentation, finish it. 10065 if (r != null && r.instrumentationClass != null) { 10066 Slog.w(TAG, "Error in app " + r.processName 10067 + " running instrumentation " + r.instrumentationClass + ":"); 10068 if (shortMsg != null) Slog.w(TAG, " " + shortMsg); 10069 if (longMsg != null) Slog.w(TAG, " " + longMsg); 10070 Bundle info = new Bundle(); 10071 info.putString("shortMsg", shortMsg); 10072 info.putString("longMsg", longMsg); 10073 finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info); 10074 Binder.restoreCallingIdentity(origId); 10075 return; 10076 } 10077 10078 // If we can't identify the process or it's already exceeded its crash quota, 10079 // quit right away without showing a crash dialog. 10080 if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) { 10081 Binder.restoreCallingIdentity(origId); 10082 return; 10083 } 10084 10085 Message msg = Message.obtain(); 10086 msg.what = SHOW_ERROR_MSG; 10087 HashMap data = new HashMap(); 10088 data.put("result", result); 10089 data.put("app", r); 10090 msg.obj = data; 10091 mHandler.sendMessage(msg); 10092 10093 Binder.restoreCallingIdentity(origId); 10094 } 10095 10096 int res = result.get(); 10097 10098 Intent appErrorIntent = null; 10099 synchronized (this) { 10100 if (r != null && !r.isolated) { 10101 // XXX Can't keep track of crash time for isolated processes, 10102 // since they don't have a persistent identity. 10103 mProcessCrashTimes.put(r.info.processName, r.uid, 10104 SystemClock.uptimeMillis()); 10105 } 10106 if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) { 10107 appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo); 10108 } 10109 } 10110 10111 if (appErrorIntent != null) { 10112 try { 10113 mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId)); 10114 } catch (ActivityNotFoundException e) { 10115 Slog.w(TAG, "bug report receiver dissappeared", e); 10116 } 10117 } 10118 } 10119 10120 Intent createAppErrorIntentLocked(ProcessRecord r, 10121 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 10122 ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo); 10123 if (report == null) { 10124 return null; 10125 } 10126 Intent result = new Intent(Intent.ACTION_APP_ERROR); 10127 result.setComponent(r.errorReportReceiver); 10128 result.putExtra(Intent.EXTRA_BUG_REPORT, report); 10129 result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 10130 return result; 10131 } 10132 10133 private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r, 10134 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 10135 if (r.errorReportReceiver == null) { 10136 return null; 10137 } 10138 10139 if (!r.crashing && !r.notResponding && !r.forceCrashReport) { 10140 return null; 10141 } 10142 10143 ApplicationErrorReport report = new ApplicationErrorReport(); 10144 report.packageName = r.info.packageName; 10145 report.installerPackageName = r.errorReportReceiver.getPackageName(); 10146 report.processName = r.processName; 10147 report.time = timeMillis; 10148 report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0; 10149 10150 if (r.crashing || r.forceCrashReport) { 10151 report.type = ApplicationErrorReport.TYPE_CRASH; 10152 report.crashInfo = crashInfo; 10153 } else if (r.notResponding) { 10154 report.type = ApplicationErrorReport.TYPE_ANR; 10155 report.anrInfo = new ApplicationErrorReport.AnrInfo(); 10156 10157 report.anrInfo.activity = r.notRespondingReport.tag; 10158 report.anrInfo.cause = r.notRespondingReport.shortMsg; 10159 report.anrInfo.info = r.notRespondingReport.longMsg; 10160 } 10161 10162 return report; 10163 } 10164 10165 public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() { 10166 enforceNotIsolatedCaller("getProcessesInErrorState"); 10167 // assume our apps are happy - lazy create the list 10168 List<ActivityManager.ProcessErrorStateInfo> errList = null; 10169 10170 final boolean allUsers = ActivityManager.checkUidPermission( 10171 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 10172 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 10173 int userId = UserHandle.getUserId(Binder.getCallingUid()); 10174 10175 synchronized (this) { 10176 10177 // iterate across all processes 10178 for (int i=mLruProcesses.size()-1; i>=0; i--) { 10179 ProcessRecord app = mLruProcesses.get(i); 10180 if (!allUsers && app.userId != userId) { 10181 continue; 10182 } 10183 if ((app.thread != null) && (app.crashing || app.notResponding)) { 10184 // This one's in trouble, so we'll generate a report for it 10185 // crashes are higher priority (in case there's a crash *and* an anr) 10186 ActivityManager.ProcessErrorStateInfo report = null; 10187 if (app.crashing) { 10188 report = app.crashingReport; 10189 } else if (app.notResponding) { 10190 report = app.notRespondingReport; 10191 } 10192 10193 if (report != null) { 10194 if (errList == null) { 10195 errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1); 10196 } 10197 errList.add(report); 10198 } else { 10199 Slog.w(TAG, "Missing app error report, app = " + app.processName + 10200 " crashing = " + app.crashing + 10201 " notResponding = " + app.notResponding); 10202 } 10203 } 10204 } 10205 } 10206 10207 return errList; 10208 } 10209 10210 static int oomAdjToImportance(int adj, ActivityManager.RunningAppProcessInfo currApp) { 10211 if (adj >= ProcessList.CACHED_APP_MIN_ADJ) { 10212 if (currApp != null) { 10213 currApp.lru = adj - ProcessList.CACHED_APP_MIN_ADJ + 1; 10214 } 10215 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 10216 } else if (adj >= ProcessList.SERVICE_B_ADJ) { 10217 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 10218 } else if (adj >= ProcessList.HOME_APP_ADJ) { 10219 if (currApp != null) { 10220 currApp.lru = 0; 10221 } 10222 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 10223 } else if (adj >= ProcessList.SERVICE_ADJ) { 10224 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 10225 } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 10226 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE; 10227 } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) { 10228 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE; 10229 } else if (adj >= ProcessList.VISIBLE_APP_ADJ) { 10230 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE; 10231 } else { 10232 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND; 10233 } 10234 } 10235 10236 private void fillInProcMemInfo(ProcessRecord app, 10237 ActivityManager.RunningAppProcessInfo outInfo) { 10238 outInfo.pid = app.pid; 10239 outInfo.uid = app.info.uid; 10240 if (mHeavyWeightProcess == app) { 10241 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE; 10242 } 10243 if (app.persistent) { 10244 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT; 10245 } 10246 if (app.activities.size() > 0) { 10247 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES; 10248 } 10249 outInfo.lastTrimLevel = app.trimMemoryLevel; 10250 int adj = app.curAdj; 10251 outInfo.importance = oomAdjToImportance(adj, outInfo); 10252 outInfo.importanceReasonCode = app.adjTypeCode; 10253 } 10254 10255 public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() { 10256 enforceNotIsolatedCaller("getRunningAppProcesses"); 10257 // Lazy instantiation of list 10258 List<ActivityManager.RunningAppProcessInfo> runList = null; 10259 final boolean allUsers = ActivityManager.checkUidPermission( 10260 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 10261 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 10262 int userId = UserHandle.getUserId(Binder.getCallingUid()); 10263 synchronized (this) { 10264 // Iterate across all processes 10265 for (int i=mLruProcesses.size()-1; i>=0; i--) { 10266 ProcessRecord app = mLruProcesses.get(i); 10267 if (!allUsers && app.userId != userId) { 10268 continue; 10269 } 10270 if ((app.thread != null) && (!app.crashing && !app.notResponding)) { 10271 // Generate process state info for running application 10272 ActivityManager.RunningAppProcessInfo currApp = 10273 new ActivityManager.RunningAppProcessInfo(app.processName, 10274 app.pid, app.getPackageList()); 10275 fillInProcMemInfo(app, currApp); 10276 if (app.adjSource instanceof ProcessRecord) { 10277 currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid; 10278 currApp.importanceReasonImportance = oomAdjToImportance( 10279 app.adjSourceOom, null); 10280 } else if (app.adjSource instanceof ActivityRecord) { 10281 ActivityRecord r = (ActivityRecord)app.adjSource; 10282 if (r.app != null) currApp.importanceReasonPid = r.app.pid; 10283 } 10284 if (app.adjTarget instanceof ComponentName) { 10285 currApp.importanceReasonComponent = (ComponentName)app.adjTarget; 10286 } 10287 //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance 10288 // + " lru=" + currApp.lru); 10289 if (runList == null) { 10290 runList = new ArrayList<ActivityManager.RunningAppProcessInfo>(); 10291 } 10292 runList.add(currApp); 10293 } 10294 } 10295 } 10296 return runList; 10297 } 10298 10299 public List<ApplicationInfo> getRunningExternalApplications() { 10300 enforceNotIsolatedCaller("getRunningExternalApplications"); 10301 List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses(); 10302 List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>(); 10303 if (runningApps != null && runningApps.size() > 0) { 10304 Set<String> extList = new HashSet<String>(); 10305 for (ActivityManager.RunningAppProcessInfo app : runningApps) { 10306 if (app.pkgList != null) { 10307 for (String pkg : app.pkgList) { 10308 extList.add(pkg); 10309 } 10310 } 10311 } 10312 IPackageManager pm = AppGlobals.getPackageManager(); 10313 for (String pkg : extList) { 10314 try { 10315 ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId()); 10316 if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) { 10317 retList.add(info); 10318 } 10319 } catch (RemoteException e) { 10320 } 10321 } 10322 } 10323 return retList; 10324 } 10325 10326 @Override 10327 public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) { 10328 enforceNotIsolatedCaller("getMyMemoryState"); 10329 synchronized (this) { 10330 ProcessRecord proc; 10331 synchronized (mPidsSelfLocked) { 10332 proc = mPidsSelfLocked.get(Binder.getCallingPid()); 10333 } 10334 fillInProcMemInfo(proc, outInfo); 10335 } 10336 } 10337 10338 @Override 10339 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 10340 if (checkCallingPermission(android.Manifest.permission.DUMP) 10341 != PackageManager.PERMISSION_GRANTED) { 10342 pw.println("Permission Denial: can't dump ActivityManager from from pid=" 10343 + Binder.getCallingPid() 10344 + ", uid=" + Binder.getCallingUid() 10345 + " without permission " 10346 + android.Manifest.permission.DUMP); 10347 return; 10348 } 10349 10350 boolean dumpAll = false; 10351 boolean dumpClient = false; 10352 String dumpPackage = null; 10353 10354 int opti = 0; 10355 while (opti < args.length) { 10356 String opt = args[opti]; 10357 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 10358 break; 10359 } 10360 opti++; 10361 if ("-a".equals(opt)) { 10362 dumpAll = true; 10363 } else if ("-c".equals(opt)) { 10364 dumpClient = true; 10365 } else if ("-h".equals(opt)) { 10366 pw.println("Activity manager dump options:"); 10367 pw.println(" [-a] [-c] [-h] [cmd] ..."); 10368 pw.println(" cmd may be one of:"); 10369 pw.println(" a[ctivities]: activity stack state"); 10370 pw.println(" b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state"); 10371 pw.println(" i[ntents] [PACKAGE_NAME]: pending intent state"); 10372 pw.println(" p[rocesses] [PACKAGE_NAME]: process state"); 10373 pw.println(" o[om]: out of memory management"); 10374 pw.println(" prov[iders] [COMP_SPEC ...]: content provider state"); 10375 pw.println(" provider [COMP_SPEC]: provider client-side state"); 10376 pw.println(" s[ervices] [COMP_SPEC ...]: service state"); 10377 pw.println(" service [COMP_SPEC]: service client-side state"); 10378 pw.println(" package [PACKAGE_NAME]: all state related to given package"); 10379 pw.println(" all: dump all activities"); 10380 pw.println(" top: dump the top activity"); 10381 pw.println(" cmd may also be a COMP_SPEC to dump activities."); 10382 pw.println(" COMP_SPEC may be a component name (com.foo/.myApp),"); 10383 pw.println(" a partial substring in a component name, a"); 10384 pw.println(" hex object identifier."); 10385 pw.println(" -a: include all available server state."); 10386 pw.println(" -c: include client state."); 10387 return; 10388 } else { 10389 pw.println("Unknown argument: " + opt + "; use -h for help"); 10390 } 10391 } 10392 10393 long origId = Binder.clearCallingIdentity(); 10394 boolean more = false; 10395 // Is the caller requesting to dump a particular piece of data? 10396 if (opti < args.length) { 10397 String cmd = args[opti]; 10398 opti++; 10399 if ("activities".equals(cmd) || "a".equals(cmd)) { 10400 synchronized (this) { 10401 dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null); 10402 } 10403 } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) { 10404 String[] newArgs; 10405 String name; 10406 if (opti >= args.length) { 10407 name = null; 10408 newArgs = EMPTY_STRING_ARRAY; 10409 } else { 10410 name = args[opti]; 10411 opti++; 10412 newArgs = new String[args.length - opti]; 10413 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 10414 args.length - opti); 10415 } 10416 synchronized (this) { 10417 dumpBroadcastsLocked(fd, pw, args, opti, true, name); 10418 } 10419 } else if ("intents".equals(cmd) || "i".equals(cmd)) { 10420 String[] newArgs; 10421 String name; 10422 if (opti >= args.length) { 10423 name = null; 10424 newArgs = EMPTY_STRING_ARRAY; 10425 } else { 10426 name = args[opti]; 10427 opti++; 10428 newArgs = new String[args.length - opti]; 10429 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 10430 args.length - opti); 10431 } 10432 synchronized (this) { 10433 dumpPendingIntentsLocked(fd, pw, args, opti, true, name); 10434 } 10435 } else if ("processes".equals(cmd) || "p".equals(cmd)) { 10436 String[] newArgs; 10437 String name; 10438 if (opti >= args.length) { 10439 name = null; 10440 newArgs = EMPTY_STRING_ARRAY; 10441 } else { 10442 name = args[opti]; 10443 opti++; 10444 newArgs = new String[args.length - opti]; 10445 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 10446 args.length - opti); 10447 } 10448 synchronized (this) { 10449 dumpProcessesLocked(fd, pw, args, opti, true, name); 10450 } 10451 } else if ("oom".equals(cmd) || "o".equals(cmd)) { 10452 synchronized (this) { 10453 dumpOomLocked(fd, pw, args, opti, true); 10454 } 10455 } else if ("provider".equals(cmd)) { 10456 String[] newArgs; 10457 String name; 10458 if (opti >= args.length) { 10459 name = null; 10460 newArgs = EMPTY_STRING_ARRAY; 10461 } else { 10462 name = args[opti]; 10463 opti++; 10464 newArgs = new String[args.length - opti]; 10465 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti); 10466 } 10467 if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) { 10468 pw.println("No providers match: " + name); 10469 pw.println("Use -h for help."); 10470 } 10471 } else if ("providers".equals(cmd) || "prov".equals(cmd)) { 10472 synchronized (this) { 10473 dumpProvidersLocked(fd, pw, args, opti, true, null); 10474 } 10475 } else if ("service".equals(cmd)) { 10476 String[] newArgs; 10477 String name; 10478 if (opti >= args.length) { 10479 name = null; 10480 newArgs = EMPTY_STRING_ARRAY; 10481 } else { 10482 name = args[opti]; 10483 opti++; 10484 newArgs = new String[args.length - opti]; 10485 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 10486 args.length - opti); 10487 } 10488 if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) { 10489 pw.println("No services match: " + name); 10490 pw.println("Use -h for help."); 10491 } 10492 } else if ("package".equals(cmd)) { 10493 String[] newArgs; 10494 if (opti >= args.length) { 10495 pw.println("package: no package name specified"); 10496 pw.println("Use -h for help."); 10497 } else { 10498 dumpPackage = args[opti]; 10499 opti++; 10500 newArgs = new String[args.length - opti]; 10501 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 10502 args.length - opti); 10503 args = newArgs; 10504 opti = 0; 10505 more = true; 10506 } 10507 } else if ("services".equals(cmd) || "s".equals(cmd)) { 10508 synchronized (this) { 10509 mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null); 10510 } 10511 } else { 10512 // Dumping a single activity? 10513 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) { 10514 pw.println("Bad activity command, or no activities match: " + cmd); 10515 pw.println("Use -h for help."); 10516 } 10517 } 10518 if (!more) { 10519 Binder.restoreCallingIdentity(origId); 10520 return; 10521 } 10522 } 10523 10524 // No piece of data specified, dump everything. 10525 synchronized (this) { 10526 dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 10527 pw.println(); 10528 if (dumpAll) { 10529 pw.println("-------------------------------------------------------------------------------"); 10530 } 10531 dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 10532 pw.println(); 10533 if (dumpAll) { 10534 pw.println("-------------------------------------------------------------------------------"); 10535 } 10536 dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage); 10537 pw.println(); 10538 if (dumpAll) { 10539 pw.println("-------------------------------------------------------------------------------"); 10540 } 10541 mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 10542 pw.println(); 10543 if (dumpAll) { 10544 pw.println("-------------------------------------------------------------------------------"); 10545 } 10546 dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 10547 pw.println(); 10548 if (dumpAll) { 10549 pw.println("-------------------------------------------------------------------------------"); 10550 } 10551 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage); 10552 } 10553 Binder.restoreCallingIdentity(origId); 10554 } 10555 10556 void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 10557 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) { 10558 pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)"); 10559 10560 boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient, 10561 dumpPackage); 10562 boolean needSep = printedAnything; 10563 10564 boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity, 10565 dumpPackage, needSep, " mFocusedActivity: "); 10566 if (printed) { 10567 printedAnything = true; 10568 needSep = false; 10569 } 10570 10571 if (dumpPackage == null) { 10572 if (needSep) { 10573 pw.println(); 10574 } 10575 needSep = true; 10576 printedAnything = true; 10577 mStackSupervisor.dump(pw, " "); 10578 } 10579 10580 if (mRecentTasks.size() > 0) { 10581 boolean printedHeader = false; 10582 10583 final int N = mRecentTasks.size(); 10584 for (int i=0; i<N; i++) { 10585 TaskRecord tr = mRecentTasks.get(i); 10586 if (dumpPackage != null) { 10587 if (tr.realActivity == null || 10588 !dumpPackage.equals(tr.realActivity)) { 10589 continue; 10590 } 10591 } 10592 if (!printedHeader) { 10593 if (needSep) { 10594 pw.println(); 10595 } 10596 pw.println(" Recent tasks:"); 10597 printedHeader = true; 10598 printedAnything = true; 10599 } 10600 pw.print(" * Recent #"); pw.print(i); pw.print(": "); 10601 pw.println(tr); 10602 if (dumpAll) { 10603 mRecentTasks.get(i).dump(pw, " "); 10604 } 10605 } 10606 } 10607 10608 if (!printedAnything) { 10609 pw.println(" (nothing)"); 10610 } 10611 } 10612 10613 void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 10614 int opti, boolean dumpAll, String dumpPackage) { 10615 boolean needSep = false; 10616 boolean printedAnything = false; 10617 int numPers = 0; 10618 10619 pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)"); 10620 10621 if (dumpAll) { 10622 final int NP = mProcessNames.getMap().size(); 10623 for (int ip=0; ip<NP; ip++) { 10624 SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip); 10625 final int NA = procs.size(); 10626 for (int ia=0; ia<NA; ia++) { 10627 ProcessRecord r = procs.valueAt(ia); 10628 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 10629 continue; 10630 } 10631 if (!needSep) { 10632 pw.println(" All known processes:"); 10633 needSep = true; 10634 printedAnything = true; 10635 } 10636 pw.print(r.persistent ? " *PERS*" : " *APP*"); 10637 pw.print(" UID "); pw.print(procs.keyAt(ia)); 10638 pw.print(" "); pw.println(r); 10639 r.dump(pw, " "); 10640 if (r.persistent) { 10641 numPers++; 10642 } 10643 } 10644 } 10645 } 10646 10647 if (mIsolatedProcesses.size() > 0) { 10648 boolean printed = false; 10649 for (int i=0; i<mIsolatedProcesses.size(); i++) { 10650 ProcessRecord r = mIsolatedProcesses.valueAt(i); 10651 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 10652 continue; 10653 } 10654 if (!printed) { 10655 if (needSep) { 10656 pw.println(); 10657 } 10658 pw.println(" Isolated process list (sorted by uid):"); 10659 printedAnything = true; 10660 printed = true; 10661 needSep = true; 10662 } 10663 pw.println(String.format("%sIsolated #%2d: %s", 10664 " ", i, r.toString())); 10665 } 10666 } 10667 10668 if (mLruProcesses.size() > 0) { 10669 if (needSep) { 10670 pw.println(); 10671 } 10672 pw.print(" Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size()); 10673 pw.print(" total, non-act at "); 10674 pw.print(mLruProcesses.size()-mLruProcessActivityStart); 10675 pw.print(", non-svc at "); 10676 pw.print(mLruProcesses.size()-mLruProcessServiceStart); 10677 pw.println("):"); 10678 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", false, dumpPackage); 10679 needSep = true; 10680 printedAnything = true; 10681 } 10682 10683 if (dumpAll || dumpPackage != null) { 10684 synchronized (mPidsSelfLocked) { 10685 boolean printed = false; 10686 for (int i=0; i<mPidsSelfLocked.size(); i++) { 10687 ProcessRecord r = mPidsSelfLocked.valueAt(i); 10688 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 10689 continue; 10690 } 10691 if (!printed) { 10692 if (needSep) pw.println(); 10693 needSep = true; 10694 pw.println(" PID mappings:"); 10695 printed = true; 10696 printedAnything = true; 10697 } 10698 pw.print(" PID #"); pw.print(mPidsSelfLocked.keyAt(i)); 10699 pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i)); 10700 } 10701 } 10702 } 10703 10704 if (mForegroundProcesses.size() > 0) { 10705 synchronized (mPidsSelfLocked) { 10706 boolean printed = false; 10707 for (int i=0; i<mForegroundProcesses.size(); i++) { 10708 ProcessRecord r = mPidsSelfLocked.get( 10709 mForegroundProcesses.valueAt(i).pid); 10710 if (dumpPackage != null && (r == null 10711 || !r.pkgList.containsKey(dumpPackage))) { 10712 continue; 10713 } 10714 if (!printed) { 10715 if (needSep) pw.println(); 10716 needSep = true; 10717 pw.println(" Foreground Processes:"); 10718 printed = true; 10719 printedAnything = true; 10720 } 10721 pw.print(" PID #"); pw.print(mForegroundProcesses.keyAt(i)); 10722 pw.print(": "); pw.println(mForegroundProcesses.valueAt(i)); 10723 } 10724 } 10725 } 10726 10727 if (mPersistentStartingProcesses.size() > 0) { 10728 if (needSep) pw.println(); 10729 needSep = true; 10730 printedAnything = true; 10731 pw.println(" Persisent processes that are starting:"); 10732 dumpProcessList(pw, this, mPersistentStartingProcesses, " ", 10733 "Starting Norm", "Restarting PERS", dumpPackage); 10734 } 10735 10736 if (mRemovedProcesses.size() > 0) { 10737 if (needSep) pw.println(); 10738 needSep = true; 10739 printedAnything = true; 10740 pw.println(" Processes that are being removed:"); 10741 dumpProcessList(pw, this, mRemovedProcesses, " ", 10742 "Removed Norm", "Removed PERS", dumpPackage); 10743 } 10744 10745 if (mProcessesOnHold.size() > 0) { 10746 if (needSep) pw.println(); 10747 needSep = true; 10748 printedAnything = true; 10749 pw.println(" Processes that are on old until the system is ready:"); 10750 dumpProcessList(pw, this, mProcessesOnHold, " ", 10751 "OnHold Norm", "OnHold PERS", dumpPackage); 10752 } 10753 10754 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage); 10755 10756 if (mProcessCrashTimes.getMap().size() > 0) { 10757 boolean printed = false; 10758 long now = SystemClock.uptimeMillis(); 10759 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap(); 10760 final int NP = pmap.size(); 10761 for (int ip=0; ip<NP; ip++) { 10762 String pname = pmap.keyAt(ip); 10763 SparseArray<Long> uids = pmap.valueAt(ip); 10764 final int N = uids.size(); 10765 for (int i=0; i<N; i++) { 10766 int puid = uids.keyAt(i); 10767 ProcessRecord r = mProcessNames.get(pname, puid); 10768 if (dumpPackage != null && (r == null 10769 || !r.pkgList.containsKey(dumpPackage))) { 10770 continue; 10771 } 10772 if (!printed) { 10773 if (needSep) pw.println(); 10774 needSep = true; 10775 pw.println(" Time since processes crashed:"); 10776 printed = true; 10777 printedAnything = true; 10778 } 10779 pw.print(" Process "); pw.print(pname); 10780 pw.print(" uid "); pw.print(puid); 10781 pw.print(": last crashed "); 10782 TimeUtils.formatDuration(now-uids.valueAt(i), pw); 10783 pw.println(" ago"); 10784 } 10785 } 10786 } 10787 10788 if (mBadProcesses.getMap().size() > 0) { 10789 boolean printed = false; 10790 final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap(); 10791 final int NP = pmap.size(); 10792 for (int ip=0; ip<NP; ip++) { 10793 String pname = pmap.keyAt(ip); 10794 SparseArray<BadProcessInfo> uids = pmap.valueAt(ip); 10795 final int N = uids.size(); 10796 for (int i=0; i<N; i++) { 10797 int puid = uids.keyAt(i); 10798 ProcessRecord r = mProcessNames.get(pname, puid); 10799 if (dumpPackage != null && (r == null 10800 || !r.pkgList.containsKey(dumpPackage))) { 10801 continue; 10802 } 10803 if (!printed) { 10804 if (needSep) pw.println(); 10805 needSep = true; 10806 pw.println(" Bad processes:"); 10807 printedAnything = true; 10808 } 10809 BadProcessInfo info = uids.valueAt(i); 10810 pw.print(" Bad process "); pw.print(pname); 10811 pw.print(" uid "); pw.print(puid); 10812 pw.print(": crashed at time "); pw.println(info.time); 10813 if (info.shortMsg != null) { 10814 pw.print(" Short msg: "); pw.println(info.shortMsg); 10815 } 10816 if (info.longMsg != null) { 10817 pw.print(" Long msg: "); pw.println(info.longMsg); 10818 } 10819 if (info.stack != null) { 10820 pw.println(" Stack:"); 10821 int lastPos = 0; 10822 for (int pos=0; pos<info.stack.length(); pos++) { 10823 if (info.stack.charAt(pos) == '\n') { 10824 pw.print(" "); 10825 pw.write(info.stack, lastPos, pos-lastPos); 10826 pw.println(); 10827 lastPos = pos+1; 10828 } 10829 } 10830 if (lastPos < info.stack.length()) { 10831 pw.print(" "); 10832 pw.write(info.stack, lastPos, info.stack.length()-lastPos); 10833 pw.println(); 10834 } 10835 } 10836 } 10837 } 10838 } 10839 10840 if (dumpPackage == null) { 10841 pw.println(); 10842 needSep = false; 10843 pw.println(" mStartedUsers:"); 10844 for (int i=0; i<mStartedUsers.size(); i++) { 10845 UserStartedState uss = mStartedUsers.valueAt(i); 10846 pw.print(" User #"); pw.print(uss.mHandle.getIdentifier()); 10847 pw.print(": "); uss.dump("", pw); 10848 } 10849 pw.print(" mStartedUserArray: ["); 10850 for (int i=0; i<mStartedUserArray.length; i++) { 10851 if (i > 0) pw.print(", "); 10852 pw.print(mStartedUserArray[i]); 10853 } 10854 pw.println("]"); 10855 pw.print(" mUserLru: ["); 10856 for (int i=0; i<mUserLru.size(); i++) { 10857 if (i > 0) pw.print(", "); 10858 pw.print(mUserLru.get(i)); 10859 } 10860 pw.println("]"); 10861 if (dumpAll) { 10862 pw.print(" mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray)); 10863 } 10864 } 10865 if (mHomeProcess != null && (dumpPackage == null 10866 || mHomeProcess.pkgList.containsKey(dumpPackage))) { 10867 if (needSep) { 10868 pw.println(); 10869 needSep = false; 10870 } 10871 pw.println(" mHomeProcess: " + mHomeProcess); 10872 } 10873 if (mPreviousProcess != null && (dumpPackage == null 10874 || mPreviousProcess.pkgList.containsKey(dumpPackage))) { 10875 if (needSep) { 10876 pw.println(); 10877 needSep = false; 10878 } 10879 pw.println(" mPreviousProcess: " + mPreviousProcess); 10880 } 10881 if (dumpAll) { 10882 StringBuilder sb = new StringBuilder(128); 10883 sb.append(" mPreviousProcessVisibleTime: "); 10884 TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb); 10885 pw.println(sb); 10886 } 10887 if (mHeavyWeightProcess != null && (dumpPackage == null 10888 || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) { 10889 if (needSep) { 10890 pw.println(); 10891 needSep = false; 10892 } 10893 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 10894 } 10895 if (dumpPackage == null) { 10896 pw.println(" mConfiguration: " + mConfiguration); 10897 } 10898 if (dumpAll) { 10899 pw.println(" mConfigWillChange: " + getFocusedStack().mConfigWillChange); 10900 if (mCompatModePackages.getPackages().size() > 0) { 10901 boolean printed = false; 10902 for (Map.Entry<String, Integer> entry 10903 : mCompatModePackages.getPackages().entrySet()) { 10904 String pkg = entry.getKey(); 10905 int mode = entry.getValue(); 10906 if (dumpPackage != null && !dumpPackage.equals(pkg)) { 10907 continue; 10908 } 10909 if (!printed) { 10910 pw.println(" mScreenCompatPackages:"); 10911 printed = true; 10912 } 10913 pw.print(" "); pw.print(pkg); pw.print(": "); 10914 pw.print(mode); pw.println(); 10915 } 10916 } 10917 } 10918 if (dumpPackage == null) { 10919 if (mSleeping || mWentToSleep || mLockScreenShown) { 10920 pw.println(" mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep 10921 + " mLockScreenShown " + mLockScreenShown); 10922 } 10923 if (mShuttingDown) { 10924 pw.println(" mShuttingDown=" + mShuttingDown); 10925 } 10926 } 10927 if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient 10928 || mOrigWaitForDebugger) { 10929 if (dumpPackage == null || dumpPackage.equals(mDebugApp) 10930 || dumpPackage.equals(mOrigDebugApp)) { 10931 if (needSep) { 10932 pw.println(); 10933 needSep = false; 10934 } 10935 pw.println(" mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp 10936 + " mDebugTransient=" + mDebugTransient 10937 + " mOrigWaitForDebugger=" + mOrigWaitForDebugger); 10938 } 10939 } 10940 if (mOpenGlTraceApp != null) { 10941 if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) { 10942 if (needSep) { 10943 pw.println(); 10944 needSep = false; 10945 } 10946 pw.println(" mOpenGlTraceApp=" + mOpenGlTraceApp); 10947 } 10948 } 10949 if (mProfileApp != null || mProfileProc != null || mProfileFile != null 10950 || mProfileFd != null) { 10951 if (dumpPackage == null || dumpPackage.equals(mProfileApp)) { 10952 if (needSep) { 10953 pw.println(); 10954 needSep = false; 10955 } 10956 pw.println(" mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc); 10957 pw.println(" mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd); 10958 pw.println(" mProfileType=" + mProfileType + " mAutoStopProfiler=" 10959 + mAutoStopProfiler); 10960 } 10961 } 10962 if (dumpPackage == null) { 10963 if (mAlwaysFinishActivities || mController != null) { 10964 pw.println(" mAlwaysFinishActivities=" + mAlwaysFinishActivities 10965 + " mController=" + mController); 10966 } 10967 if (dumpAll) { 10968 pw.println(" Total persistent processes: " + numPers); 10969 pw.println(" mStartRunning=" + mStartRunning 10970 + " mProcessesReady=" + mProcessesReady 10971 + " mSystemReady=" + mSystemReady); 10972 pw.println(" mBooting=" + mBooting 10973 + " mBooted=" + mBooted 10974 + " mFactoryTest=" + mFactoryTest); 10975 pw.print(" mLastPowerCheckRealtime="); 10976 TimeUtils.formatDuration(mLastPowerCheckRealtime, pw); 10977 pw.println(""); 10978 pw.print(" mLastPowerCheckUptime="); 10979 TimeUtils.formatDuration(mLastPowerCheckUptime, pw); 10980 pw.println(""); 10981 pw.println(" mGoingToSleep=" + mStackSupervisor.mGoingToSleep); 10982 pw.println(" mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity); 10983 pw.println(" mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq); 10984 pw.println(" mNumNonCachedProcs=" + mNumNonCachedProcs 10985 + " (" + mLruProcesses.size() + " total)" 10986 + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs 10987 + " mNumServiceProcs=" + mNumServiceProcs 10988 + " mNewNumServiceProcs=" + mNewNumServiceProcs); 10989 pw.println(" mAllowLowerMemLevel=" + mAllowLowerMemLevel 10990 + " mLastMemoryLevel" + mLastMemoryLevel 10991 + " mLastNumProcesses" + mLastNumProcesses); 10992 long now = SystemClock.uptimeMillis(); 10993 pw.print(" mLastIdleTime="); 10994 TimeUtils.formatDuration(now, mLastIdleTime, pw); 10995 pw.print(" mLowRamSinceLastIdle="); 10996 TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw); 10997 pw.println(); 10998 } 10999 } 11000 11001 if (!printedAnything) { 11002 pw.println(" (nothing)"); 11003 } 11004 } 11005 11006 boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args, 11007 int opti, boolean needSep, boolean dumpAll, String dumpPackage) { 11008 if (mProcessesToGc.size() > 0) { 11009 boolean printed = false; 11010 long now = SystemClock.uptimeMillis(); 11011 for (int i=0; i<mProcessesToGc.size(); i++) { 11012 ProcessRecord proc = mProcessesToGc.get(i); 11013 if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) { 11014 continue; 11015 } 11016 if (!printed) { 11017 if (needSep) pw.println(); 11018 needSep = true; 11019 pw.println(" Processes that are waiting to GC:"); 11020 printed = true; 11021 } 11022 pw.print(" Process "); pw.println(proc); 11023 pw.print(" lowMem="); pw.print(proc.reportLowMemory); 11024 pw.print(", last gced="); 11025 pw.print(now-proc.lastRequestedGc); 11026 pw.print(" ms ago, last lowMem="); 11027 pw.print(now-proc.lastLowMemory); 11028 pw.println(" ms ago"); 11029 11030 } 11031 } 11032 return needSep; 11033 } 11034 11035 void printOomLevel(PrintWriter pw, String name, int adj) { 11036 pw.print(" "); 11037 if (adj >= 0) { 11038 pw.print(' '); 11039 if (adj < 10) pw.print(' '); 11040 } else { 11041 if (adj > -10) pw.print(' '); 11042 } 11043 pw.print(adj); 11044 pw.print(": "); 11045 pw.print(name); 11046 pw.print(" ("); 11047 pw.print(mProcessList.getMemLevel(adj)/1024); 11048 pw.println(" kB)"); 11049 } 11050 11051 boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args, 11052 int opti, boolean dumpAll) { 11053 boolean needSep = false; 11054 11055 if (mLruProcesses.size() > 0) { 11056 if (needSep) pw.println(); 11057 needSep = true; 11058 pw.println(" OOM levels:"); 11059 printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ); 11060 printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ); 11061 printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ); 11062 printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ); 11063 printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ); 11064 printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ); 11065 printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ); 11066 printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ); 11067 printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ); 11068 printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ); 11069 printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ); 11070 printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ); 11071 printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ); 11072 11073 if (needSep) pw.println(); 11074 pw.print(" Process OOM control ("); pw.print(mLruProcesses.size()); 11075 pw.print(" total, non-act at "); 11076 pw.print(mLruProcesses.size()-mLruProcessActivityStart); 11077 pw.print(", non-svc at "); 11078 pw.print(mLruProcesses.size()-mLruProcessServiceStart); 11079 pw.println("):"); 11080 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", true, null); 11081 needSep = true; 11082 } 11083 11084 dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null); 11085 11086 pw.println(); 11087 pw.println(" mHomeProcess: " + mHomeProcess); 11088 pw.println(" mPreviousProcess: " + mPreviousProcess); 11089 if (mHeavyWeightProcess != null) { 11090 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 11091 } 11092 11093 return true; 11094 } 11095 11096 /** 11097 * There are three ways to call this: 11098 * - no provider specified: dump all the providers 11099 * - a flattened component name that matched an existing provider was specified as the 11100 * first arg: dump that one provider 11101 * - the first arg isn't the flattened component name of an existing provider: 11102 * dump all providers whose component contains the first arg as a substring 11103 */ 11104 protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args, 11105 int opti, boolean dumpAll) { 11106 return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll); 11107 } 11108 11109 static class ItemMatcher { 11110 ArrayList<ComponentName> components; 11111 ArrayList<String> strings; 11112 ArrayList<Integer> objects; 11113 boolean all; 11114 11115 ItemMatcher() { 11116 all = true; 11117 } 11118 11119 void build(String name) { 11120 ComponentName componentName = ComponentName.unflattenFromString(name); 11121 if (componentName != null) { 11122 if (components == null) { 11123 components = new ArrayList<ComponentName>(); 11124 } 11125 components.add(componentName); 11126 all = false; 11127 } else { 11128 int objectId = 0; 11129 // Not a '/' separated full component name; maybe an object ID? 11130 try { 11131 objectId = Integer.parseInt(name, 16); 11132 if (objects == null) { 11133 objects = new ArrayList<Integer>(); 11134 } 11135 objects.add(objectId); 11136 all = false; 11137 } catch (RuntimeException e) { 11138 // Not an integer; just do string match. 11139 if (strings == null) { 11140 strings = new ArrayList<String>(); 11141 } 11142 strings.add(name); 11143 all = false; 11144 } 11145 } 11146 } 11147 11148 int build(String[] args, int opti) { 11149 for (; opti<args.length; opti++) { 11150 String name = args[opti]; 11151 if ("--".equals(name)) { 11152 return opti+1; 11153 } 11154 build(name); 11155 } 11156 return opti; 11157 } 11158 11159 boolean match(Object object, ComponentName comp) { 11160 if (all) { 11161 return true; 11162 } 11163 if (components != null) { 11164 for (int i=0; i<components.size(); i++) { 11165 if (components.get(i).equals(comp)) { 11166 return true; 11167 } 11168 } 11169 } 11170 if (objects != null) { 11171 for (int i=0; i<objects.size(); i++) { 11172 if (System.identityHashCode(object) == objects.get(i)) { 11173 return true; 11174 } 11175 } 11176 } 11177 if (strings != null) { 11178 String flat = comp.flattenToString(); 11179 for (int i=0; i<strings.size(); i++) { 11180 if (flat.contains(strings.get(i))) { 11181 return true; 11182 } 11183 } 11184 } 11185 return false; 11186 } 11187 } 11188 11189 /** 11190 * There are three things that cmd can be: 11191 * - a flattened component name that matches an existing activity 11192 * - the cmd arg isn't the flattened component name of an existing activity: 11193 * dump all activity whose component contains the cmd as a substring 11194 * - A hex number of the ActivityRecord object instance. 11195 */ 11196 protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args, 11197 int opti, boolean dumpAll) { 11198 ArrayList<ActivityRecord> activities; 11199 11200 synchronized (this) { 11201 activities = mStackSupervisor.getDumpActivitiesLocked(name); 11202 } 11203 11204 if (activities.size() <= 0) { 11205 return false; 11206 } 11207 11208 String[] newArgs = new String[args.length - opti]; 11209 System.arraycopy(args, opti, newArgs, 0, args.length - opti); 11210 11211 TaskRecord lastTask = null; 11212 boolean needSep = false; 11213 for (int i=activities.size()-1; i>=0; i--) { 11214 ActivityRecord r = activities.get(i); 11215 if (needSep) { 11216 pw.println(); 11217 } 11218 needSep = true; 11219 synchronized (this) { 11220 if (lastTask != r.task) { 11221 lastTask = r.task; 11222 pw.print("TASK "); pw.print(lastTask.affinity); 11223 pw.print(" id="); pw.println(lastTask.taskId); 11224 if (dumpAll) { 11225 lastTask.dump(pw, " "); 11226 } 11227 } 11228 } 11229 dumpActivity(" ", fd, pw, activities.get(i), newArgs, dumpAll); 11230 } 11231 return true; 11232 } 11233 11234 /** 11235 * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if 11236 * there is a thread associated with the activity. 11237 */ 11238 private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw, 11239 final ActivityRecord r, String[] args, boolean dumpAll) { 11240 String innerPrefix = prefix + " "; 11241 synchronized (this) { 11242 pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName); 11243 pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r))); 11244 pw.print(" pid="); 11245 if (r.app != null) pw.println(r.app.pid); 11246 else pw.println("(not running)"); 11247 if (dumpAll) { 11248 r.dump(pw, innerPrefix); 11249 } 11250 } 11251 if (r.app != null && r.app.thread != null) { 11252 // flush anything that is already in the PrintWriter since the thread is going 11253 // to write to the file descriptor directly 11254 pw.flush(); 11255 try { 11256 TransferPipe tp = new TransferPipe(); 11257 try { 11258 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(), 11259 r.appToken, innerPrefix, args); 11260 tp.go(fd); 11261 } finally { 11262 tp.kill(); 11263 } 11264 } catch (IOException e) { 11265 pw.println(innerPrefix + "Failure while dumping the activity: " + e); 11266 } catch (RemoteException e) { 11267 pw.println(innerPrefix + "Got a RemoteException while dumping the activity"); 11268 } 11269 } 11270 } 11271 11272 void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 11273 int opti, boolean dumpAll, String dumpPackage) { 11274 boolean needSep = false; 11275 boolean onlyHistory = false; 11276 boolean printedAnything = false; 11277 11278 if ("history".equals(dumpPackage)) { 11279 if (opti < args.length && "-s".equals(args[opti])) { 11280 dumpAll = false; 11281 } 11282 onlyHistory = true; 11283 dumpPackage = null; 11284 } 11285 11286 pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)"); 11287 if (!onlyHistory && dumpAll) { 11288 if (mRegisteredReceivers.size() > 0) { 11289 boolean printed = false; 11290 Iterator it = mRegisteredReceivers.values().iterator(); 11291 while (it.hasNext()) { 11292 ReceiverList r = (ReceiverList)it.next(); 11293 if (dumpPackage != null && (r.app == null || 11294 !dumpPackage.equals(r.app.info.packageName))) { 11295 continue; 11296 } 11297 if (!printed) { 11298 pw.println(" Registered Receivers:"); 11299 needSep = true; 11300 printed = true; 11301 printedAnything = true; 11302 } 11303 pw.print(" * "); pw.println(r); 11304 r.dump(pw, " "); 11305 } 11306 } 11307 11308 if (mReceiverResolver.dump(pw, needSep ? 11309 "\n Receiver Resolver Table:" : " Receiver Resolver Table:", 11310 " ", dumpPackage, false)) { 11311 needSep = true; 11312 printedAnything = true; 11313 } 11314 } 11315 11316 for (BroadcastQueue q : mBroadcastQueues) { 11317 needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep); 11318 printedAnything |= needSep; 11319 } 11320 11321 needSep = true; 11322 11323 if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) { 11324 for (int user=0; user<mStickyBroadcasts.size(); user++) { 11325 if (needSep) { 11326 pw.println(); 11327 } 11328 needSep = true; 11329 printedAnything = true; 11330 pw.print(" Sticky broadcasts for user "); 11331 pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":"); 11332 StringBuilder sb = new StringBuilder(128); 11333 for (Map.Entry<String, ArrayList<Intent>> ent 11334 : mStickyBroadcasts.valueAt(user).entrySet()) { 11335 pw.print(" * Sticky action "); pw.print(ent.getKey()); 11336 if (dumpAll) { 11337 pw.println(":"); 11338 ArrayList<Intent> intents = ent.getValue(); 11339 final int N = intents.size(); 11340 for (int i=0; i<N; i++) { 11341 sb.setLength(0); 11342 sb.append(" Intent: "); 11343 intents.get(i).toShortString(sb, false, true, false, false); 11344 pw.println(sb.toString()); 11345 Bundle bundle = intents.get(i).getExtras(); 11346 if (bundle != null) { 11347 pw.print(" "); 11348 pw.println(bundle.toString()); 11349 } 11350 } 11351 } else { 11352 pw.println(""); 11353 } 11354 } 11355 } 11356 } 11357 11358 if (!onlyHistory && dumpAll) { 11359 pw.println(); 11360 for (BroadcastQueue queue : mBroadcastQueues) { 11361 pw.println(" mBroadcastsScheduled [" + queue.mQueueName + "]=" 11362 + queue.mBroadcastsScheduled); 11363 } 11364 pw.println(" mHandler:"); 11365 mHandler.dump(new PrintWriterPrinter(pw), " "); 11366 needSep = true; 11367 printedAnything = true; 11368 } 11369 11370 if (!printedAnything) { 11371 pw.println(" (nothing)"); 11372 } 11373 } 11374 11375 void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args, 11376 int opti, boolean dumpAll, String dumpPackage) { 11377 boolean needSep; 11378 boolean printedAnything = false; 11379 11380 ItemMatcher matcher = new ItemMatcher(); 11381 matcher.build(args, opti); 11382 11383 pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)"); 11384 11385 needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage); 11386 printedAnything |= needSep; 11387 11388 if (mLaunchingProviders.size() > 0) { 11389 boolean printed = false; 11390 for (int i=mLaunchingProviders.size()-1; i>=0; i--) { 11391 ContentProviderRecord r = mLaunchingProviders.get(i); 11392 if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) { 11393 continue; 11394 } 11395 if (!printed) { 11396 if (needSep) pw.println(); 11397 needSep = true; 11398 pw.println(" Launching content providers:"); 11399 printed = true; 11400 printedAnything = true; 11401 } 11402 pw.print(" Launching #"); pw.print(i); pw.print(": "); 11403 pw.println(r); 11404 } 11405 } 11406 11407 if (mGrantedUriPermissions.size() > 0) { 11408 boolean printed = false; 11409 int dumpUid = -2; 11410 if (dumpPackage != null) { 11411 try { 11412 dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0); 11413 } catch (NameNotFoundException e) { 11414 dumpUid = -1; 11415 } 11416 } 11417 for (int i=0; i<mGrantedUriPermissions.size(); i++) { 11418 int uid = mGrantedUriPermissions.keyAt(i); 11419 if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) { 11420 continue; 11421 } 11422 ArrayMap<Uri, UriPermission> perms 11423 = mGrantedUriPermissions.valueAt(i); 11424 if (!printed) { 11425 if (needSep) pw.println(); 11426 needSep = true; 11427 pw.println(" Granted Uri Permissions:"); 11428 printed = true; 11429 printedAnything = true; 11430 } 11431 pw.print(" * UID "); pw.print(uid); 11432 pw.println(" holds:"); 11433 for (UriPermission perm : perms.values()) { 11434 pw.print(" "); pw.println(perm); 11435 if (dumpAll) { 11436 perm.dump(pw, " "); 11437 } 11438 } 11439 } 11440 } 11441 11442 if (!printedAnything) { 11443 pw.println(" (nothing)"); 11444 } 11445 } 11446 11447 void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 11448 int opti, boolean dumpAll, String dumpPackage) { 11449 boolean printed = false; 11450 11451 pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)"); 11452 11453 if (mIntentSenderRecords.size() > 0) { 11454 Iterator<WeakReference<PendingIntentRecord>> it 11455 = mIntentSenderRecords.values().iterator(); 11456 while (it.hasNext()) { 11457 WeakReference<PendingIntentRecord> ref = it.next(); 11458 PendingIntentRecord rec = ref != null ? ref.get(): null; 11459 if (dumpPackage != null && (rec == null 11460 || !dumpPackage.equals(rec.key.packageName))) { 11461 continue; 11462 } 11463 printed = true; 11464 if (rec != null) { 11465 pw.print(" * "); pw.println(rec); 11466 if (dumpAll) { 11467 rec.dump(pw, " "); 11468 } 11469 } else { 11470 pw.print(" * "); pw.println(ref); 11471 } 11472 } 11473 } 11474 11475 if (!printed) { 11476 pw.println(" (nothing)"); 11477 } 11478 } 11479 11480 private static final int dumpProcessList(PrintWriter pw, 11481 ActivityManagerService service, List list, 11482 String prefix, String normalLabel, String persistentLabel, 11483 String dumpPackage) { 11484 int numPers = 0; 11485 final int N = list.size()-1; 11486 for (int i=N; i>=0; i--) { 11487 ProcessRecord r = (ProcessRecord)list.get(i); 11488 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 11489 continue; 11490 } 11491 pw.println(String.format("%s%s #%2d: %s", 11492 prefix, (r.persistent ? persistentLabel : normalLabel), 11493 i, r.toString())); 11494 if (r.persistent) { 11495 numPers++; 11496 } 11497 } 11498 return numPers; 11499 } 11500 11501 private static final boolean dumpProcessOomList(PrintWriter pw, 11502 ActivityManagerService service, List<ProcessRecord> origList, 11503 String prefix, String normalLabel, String persistentLabel, 11504 boolean inclDetails, String dumpPackage) { 11505 11506 ArrayList<Pair<ProcessRecord, Integer>> list 11507 = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size()); 11508 for (int i=0; i<origList.size(); i++) { 11509 ProcessRecord r = origList.get(i); 11510 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 11511 continue; 11512 } 11513 list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i)); 11514 } 11515 11516 if (list.size() <= 0) { 11517 return false; 11518 } 11519 11520 Comparator<Pair<ProcessRecord, Integer>> comparator 11521 = new Comparator<Pair<ProcessRecord, Integer>>() { 11522 @Override 11523 public int compare(Pair<ProcessRecord, Integer> object1, 11524 Pair<ProcessRecord, Integer> object2) { 11525 if (object1.first.setAdj != object2.first.setAdj) { 11526 return object1.first.setAdj > object2.first.setAdj ? -1 : 1; 11527 } 11528 if (object1.second.intValue() != object2.second.intValue()) { 11529 return object1.second.intValue() > object2.second.intValue() ? -1 : 1; 11530 } 11531 return 0; 11532 } 11533 }; 11534 11535 Collections.sort(list, comparator); 11536 11537 final long curRealtime = SystemClock.elapsedRealtime(); 11538 final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime; 11539 final long curUptime = SystemClock.uptimeMillis(); 11540 final long uptimeSince = curUptime - service.mLastPowerCheckUptime; 11541 11542 for (int i=list.size()-1; i>=0; i--) { 11543 ProcessRecord r = list.get(i).first; 11544 String oomAdj = ProcessList.makeOomAdjString(r.setAdj); 11545 char schedGroup; 11546 switch (r.setSchedGroup) { 11547 case Process.THREAD_GROUP_BG_NONINTERACTIVE: 11548 schedGroup = 'B'; 11549 break; 11550 case Process.THREAD_GROUP_DEFAULT: 11551 schedGroup = 'F'; 11552 break; 11553 default: 11554 schedGroup = '?'; 11555 break; 11556 } 11557 char foreground; 11558 if (r.foregroundActivities) { 11559 foreground = 'A'; 11560 } else if (r.foregroundServices) { 11561 foreground = 'S'; 11562 } else { 11563 foreground = ' '; 11564 } 11565 String procState = ProcessList.makeProcStateString(r.curProcState); 11566 pw.print(prefix); 11567 pw.print(r.persistent ? persistentLabel : normalLabel); 11568 pw.print(" #"); 11569 int num = (origList.size()-1)-list.get(i).second; 11570 if (num < 10) pw.print(' '); 11571 pw.print(num); 11572 pw.print(": "); 11573 pw.print(oomAdj); 11574 pw.print(' '); 11575 pw.print(schedGroup); 11576 pw.print('/'); 11577 pw.print(foreground); 11578 pw.print('/'); 11579 pw.print(procState); 11580 pw.print(" trm:"); 11581 if (r.trimMemoryLevel < 10) pw.print(' '); 11582 pw.print(r.trimMemoryLevel); 11583 pw.print(' '); 11584 pw.print(r.toShortString()); 11585 pw.print(" ("); 11586 pw.print(r.adjType); 11587 pw.println(')'); 11588 if (r.adjSource != null || r.adjTarget != null) { 11589 pw.print(prefix); 11590 pw.print(" "); 11591 if (r.adjTarget instanceof ComponentName) { 11592 pw.print(((ComponentName)r.adjTarget).flattenToShortString()); 11593 } else if (r.adjTarget != null) { 11594 pw.print(r.adjTarget.toString()); 11595 } else { 11596 pw.print("{null}"); 11597 } 11598 pw.print("<="); 11599 if (r.adjSource instanceof ProcessRecord) { 11600 pw.print("Proc{"); 11601 pw.print(((ProcessRecord)r.adjSource).toShortString()); 11602 pw.println("}"); 11603 } else if (r.adjSource != null) { 11604 pw.println(r.adjSource.toString()); 11605 } else { 11606 pw.println("{null}"); 11607 } 11608 } 11609 if (inclDetails) { 11610 pw.print(prefix); 11611 pw.print(" "); 11612 pw.print("oom: max="); pw.print(r.maxAdj); 11613 pw.print(" curRaw="); pw.print(r.curRawAdj); 11614 pw.print(" setRaw="); pw.print(r.setRawAdj); 11615 pw.print(" cur="); pw.print(r.curAdj); 11616 pw.print(" set="); pw.println(r.setAdj); 11617 pw.print(prefix); 11618 pw.print(" "); 11619 pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState)); 11620 pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState)); 11621 pw.print(" lastPss="); pw.print(r.lastPss); 11622 pw.print(" lastCachedPss="); pw.println(r.lastCachedPss); 11623 pw.print(prefix); 11624 pw.print(" "); 11625 pw.print("keeping="); pw.print(r.keeping); 11626 pw.print(" cached="); pw.print(r.cached); 11627 pw.print(" empty="); pw.print(r.empty); 11628 pw.print(" hasAboveClient="); pw.println(r.hasAboveClient); 11629 11630 if (!r.keeping) { 11631 if (r.lastWakeTime != 0) { 11632 long wtime; 11633 BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics(); 11634 synchronized (stats) { 11635 wtime = stats.getProcessWakeTime(r.info.uid, 11636 r.pid, curRealtime); 11637 } 11638 long timeUsed = wtime - r.lastWakeTime; 11639 pw.print(prefix); 11640 pw.print(" "); 11641 pw.print("keep awake over "); 11642 TimeUtils.formatDuration(realtimeSince, pw); 11643 pw.print(" used "); 11644 TimeUtils.formatDuration(timeUsed, pw); 11645 pw.print(" ("); 11646 pw.print((timeUsed*100)/realtimeSince); 11647 pw.println("%)"); 11648 } 11649 if (r.lastCpuTime != 0) { 11650 long timeUsed = r.curCpuTime - r.lastCpuTime; 11651 pw.print(prefix); 11652 pw.print(" "); 11653 pw.print("run cpu over "); 11654 TimeUtils.formatDuration(uptimeSince, pw); 11655 pw.print(" used "); 11656 TimeUtils.formatDuration(timeUsed, pw); 11657 pw.print(" ("); 11658 pw.print((timeUsed*100)/uptimeSince); 11659 pw.println("%)"); 11660 } 11661 } 11662 } 11663 } 11664 return true; 11665 } 11666 11667 ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) { 11668 ArrayList<ProcessRecord> procs; 11669 synchronized (this) { 11670 if (args != null && args.length > start 11671 && args[start].charAt(0) != '-') { 11672 procs = new ArrayList<ProcessRecord>(); 11673 int pid = -1; 11674 try { 11675 pid = Integer.parseInt(args[start]); 11676 } catch (NumberFormatException e) { 11677 } 11678 for (int i=mLruProcesses.size()-1; i>=0; i--) { 11679 ProcessRecord proc = mLruProcesses.get(i); 11680 if (proc.pid == pid) { 11681 procs.add(proc); 11682 } else if (proc.processName.equals(args[start])) { 11683 procs.add(proc); 11684 } 11685 } 11686 if (procs.size() <= 0) { 11687 return null; 11688 } 11689 } else { 11690 procs = new ArrayList<ProcessRecord>(mLruProcesses); 11691 } 11692 } 11693 return procs; 11694 } 11695 11696 final void dumpGraphicsHardwareUsage(FileDescriptor fd, 11697 PrintWriter pw, String[] args) { 11698 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args); 11699 if (procs == null) { 11700 pw.println("No process found for: " + args[0]); 11701 return; 11702 } 11703 11704 long uptime = SystemClock.uptimeMillis(); 11705 long realtime = SystemClock.elapsedRealtime(); 11706 pw.println("Applications Graphics Acceleration Info:"); 11707 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 11708 11709 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 11710 ProcessRecord r = procs.get(i); 11711 if (r.thread != null) { 11712 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **"); 11713 pw.flush(); 11714 try { 11715 TransferPipe tp = new TransferPipe(); 11716 try { 11717 r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args); 11718 tp.go(fd); 11719 } finally { 11720 tp.kill(); 11721 } 11722 } catch (IOException e) { 11723 pw.println("Failure while dumping the app: " + r); 11724 pw.flush(); 11725 } catch (RemoteException e) { 11726 pw.println("Got a RemoteException while dumping the app " + r); 11727 pw.flush(); 11728 } 11729 } 11730 } 11731 } 11732 11733 final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) { 11734 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args); 11735 if (procs == null) { 11736 pw.println("No process found for: " + args[0]); 11737 return; 11738 } 11739 11740 pw.println("Applications Database Info:"); 11741 11742 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 11743 ProcessRecord r = procs.get(i); 11744 if (r.thread != null) { 11745 pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **"); 11746 pw.flush(); 11747 try { 11748 TransferPipe tp = new TransferPipe(); 11749 try { 11750 r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args); 11751 tp.go(fd); 11752 } finally { 11753 tp.kill(); 11754 } 11755 } catch (IOException e) { 11756 pw.println("Failure while dumping the app: " + r); 11757 pw.flush(); 11758 } catch (RemoteException e) { 11759 pw.println("Got a RemoteException while dumping the app " + r); 11760 pw.flush(); 11761 } 11762 } 11763 } 11764 } 11765 11766 final static class MemItem { 11767 final boolean isProc; 11768 final String label; 11769 final String shortLabel; 11770 final long pss; 11771 final int id; 11772 final boolean hasActivities; 11773 ArrayList<MemItem> subitems; 11774 11775 public MemItem(String _label, String _shortLabel, long _pss, int _id, 11776 boolean _hasActivities) { 11777 isProc = true; 11778 label = _label; 11779 shortLabel = _shortLabel; 11780 pss = _pss; 11781 id = _id; 11782 hasActivities = _hasActivities; 11783 } 11784 11785 public MemItem(String _label, String _shortLabel, long _pss, int _id) { 11786 isProc = false; 11787 label = _label; 11788 shortLabel = _shortLabel; 11789 pss = _pss; 11790 id = _id; 11791 hasActivities = false; 11792 } 11793 } 11794 11795 static final void dumpMemItems(PrintWriter pw, String prefix, String tag, 11796 ArrayList<MemItem> items, boolean sort, boolean isCompact) { 11797 if (sort && !isCompact) { 11798 Collections.sort(items, new Comparator<MemItem>() { 11799 @Override 11800 public int compare(MemItem lhs, MemItem rhs) { 11801 if (lhs.pss < rhs.pss) { 11802 return 1; 11803 } else if (lhs.pss > rhs.pss) { 11804 return -1; 11805 } 11806 return 0; 11807 } 11808 }); 11809 } 11810 11811 for (int i=0; i<items.size(); i++) { 11812 MemItem mi = items.get(i); 11813 if (!isCompact) { 11814 pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label); 11815 } else if (mi.isProc) { 11816 pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel); 11817 pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss); 11818 pw.println(mi.hasActivities ? ",a" : ",e"); 11819 } else { 11820 pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(","); 11821 pw.println(mi.pss); 11822 } 11823 if (mi.subitems != null) { 11824 dumpMemItems(pw, prefix + " ", mi.shortLabel, mi.subitems, 11825 true, isCompact); 11826 } 11827 } 11828 } 11829 11830 // These are in KB. 11831 static final long[] DUMP_MEM_BUCKETS = new long[] { 11832 5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024, 11833 120*1024, 160*1024, 200*1024, 11834 250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024, 11835 1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024 11836 }; 11837 11838 static final void appendMemBucket(StringBuilder out, long memKB, String label, 11839 boolean stackLike) { 11840 int start = label.lastIndexOf('.'); 11841 if (start >= 0) start++; 11842 else start = 0; 11843 int end = label.length(); 11844 for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) { 11845 if (DUMP_MEM_BUCKETS[i] >= memKB) { 11846 long bucket = DUMP_MEM_BUCKETS[i]/1024; 11847 out.append(bucket); 11848 out.append(stackLike ? "MB." : "MB "); 11849 out.append(label, start, end); 11850 return; 11851 } 11852 } 11853 out.append(memKB/1024); 11854 out.append(stackLike ? "MB." : "MB "); 11855 out.append(label, start, end); 11856 } 11857 11858 static final int[] DUMP_MEM_OOM_ADJ = new int[] { 11859 ProcessList.NATIVE_ADJ, 11860 ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ, 11861 ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ, 11862 ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ, 11863 ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ, 11864 ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ 11865 }; 11866 static final String[] DUMP_MEM_OOM_LABEL = new String[] { 11867 "Native", 11868 "System", "Persistent", "Foreground", 11869 "Visible", "Perceptible", 11870 "Heavy Weight", "Backup", 11871 "A Services", "Home", 11872 "Previous", "B Services", "Cached" 11873 }; 11874 static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] { 11875 "native", 11876 "sys", "pers", "fore", 11877 "vis", "percept", 11878 "heavy", "backup", 11879 "servicea", "home", 11880 "prev", "serviceb", "cached" 11881 }; 11882 11883 private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime, 11884 long realtime, boolean isCheckinRequest, boolean isCompact) { 11885 if (isCheckinRequest || isCompact) { 11886 // short checkin version 11887 pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime); 11888 } else { 11889 pw.println("Applications Memory Usage (kB):"); 11890 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 11891 } 11892 } 11893 11894 final void dumpApplicationMemoryUsage(FileDescriptor fd, 11895 PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) { 11896 boolean dumpDetails = false; 11897 boolean dumpFullDetails = false; 11898 boolean dumpDalvik = false; 11899 boolean oomOnly = false; 11900 boolean isCompact = false; 11901 boolean localOnly = false; 11902 11903 int opti = 0; 11904 while (opti < args.length) { 11905 String opt = args[opti]; 11906 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 11907 break; 11908 } 11909 opti++; 11910 if ("-a".equals(opt)) { 11911 dumpDetails = true; 11912 dumpFullDetails = true; 11913 dumpDalvik = true; 11914 } else if ("-d".equals(opt)) { 11915 dumpDalvik = true; 11916 } else if ("-c".equals(opt)) { 11917 isCompact = true; 11918 } else if ("--oom".equals(opt)) { 11919 oomOnly = true; 11920 } else if ("--local".equals(opt)) { 11921 localOnly = true; 11922 } else if ("-h".equals(opt)) { 11923 pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]"); 11924 pw.println(" -a: include all available information for each process."); 11925 pw.println(" -d: include dalvik details when dumping process details."); 11926 pw.println(" -c: dump in a compact machine-parseable representation."); 11927 pw.println(" --oom: only show processes organized by oom adj."); 11928 pw.println(" --local: only collect details locally, don't call process."); 11929 pw.println("If [process] is specified it can be the name or "); 11930 pw.println("pid of a specific process to dump."); 11931 return; 11932 } else { 11933 pw.println("Unknown argument: " + opt + "; use -h for help"); 11934 } 11935 } 11936 11937 final boolean isCheckinRequest = scanArgs(args, "--checkin"); 11938 long uptime = SystemClock.uptimeMillis(); 11939 long realtime = SystemClock.elapsedRealtime(); 11940 final long[] tmpLong = new long[1]; 11941 11942 ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args); 11943 if (procs == null) { 11944 // No Java processes. Maybe they want to print a native process. 11945 if (args != null && args.length > opti 11946 && args[opti].charAt(0) != '-') { 11947 ArrayList<ProcessCpuTracker.Stats> nativeProcs 11948 = new ArrayList<ProcessCpuTracker.Stats>(); 11949 updateCpuStatsNow(); 11950 int findPid = -1; 11951 try { 11952 findPid = Integer.parseInt(args[opti]); 11953 } catch (NumberFormatException e) { 11954 } 11955 synchronized (mProcessCpuThread) { 11956 final int N = mProcessCpuTracker.countStats(); 11957 for (int i=0; i<N; i++) { 11958 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 11959 if (st.pid == findPid || (st.baseName != null 11960 && st.baseName.equals(args[opti]))) { 11961 nativeProcs.add(st); 11962 } 11963 } 11964 } 11965 if (nativeProcs.size() > 0) { 11966 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, 11967 isCompact); 11968 Debug.MemoryInfo mi = null; 11969 for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) { 11970 final ProcessCpuTracker.Stats r = nativeProcs.get(i); 11971 final int pid = r.pid; 11972 if (!isCheckinRequest && dumpDetails) { 11973 pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **"); 11974 } 11975 if (mi == null) { 11976 mi = new Debug.MemoryInfo(); 11977 } 11978 if (dumpDetails || (!brief && !oomOnly)) { 11979 Debug.getMemoryInfo(pid, mi); 11980 } else { 11981 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong); 11982 mi.dalvikPrivateDirty = (int)tmpLong[0]; 11983 } 11984 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails, 11985 dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0); 11986 if (isCheckinRequest) { 11987 pw.println(); 11988 } 11989 } 11990 return; 11991 } 11992 } 11993 pw.println("No process found for: " + args[opti]); 11994 return; 11995 } 11996 11997 if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest)) { 11998 dumpDetails = true; 11999 } 12000 12001 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact); 12002 12003 String[] innerArgs = new String[args.length-opti]; 12004 System.arraycopy(args, opti, innerArgs, 0, args.length-opti); 12005 12006 ArrayList<MemItem> procMems = new ArrayList<MemItem>(); 12007 final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>(); 12008 long nativePss=0, dalvikPss=0, otherPss=0; 12009 long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS]; 12010 12011 long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length]; 12012 ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[]) 12013 new ArrayList[DUMP_MEM_OOM_LABEL.length]; 12014 12015 long totalPss = 0; 12016 long cachedPss = 0; 12017 12018 Debug.MemoryInfo mi = null; 12019 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 12020 final ProcessRecord r = procs.get(i); 12021 final IApplicationThread thread; 12022 final int pid; 12023 final int oomAdj; 12024 final boolean hasActivities; 12025 synchronized (this) { 12026 thread = r.thread; 12027 pid = r.pid; 12028 oomAdj = r.getSetAdjWithServices(); 12029 hasActivities = r.activities.size() > 0; 12030 } 12031 if (thread != null) { 12032 if (!isCheckinRequest && dumpDetails) { 12033 pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **"); 12034 } 12035 if (mi == null) { 12036 mi = new Debug.MemoryInfo(); 12037 } 12038 if (dumpDetails || (!brief && !oomOnly)) { 12039 Debug.getMemoryInfo(pid, mi); 12040 } else { 12041 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong); 12042 mi.dalvikPrivateDirty = (int)tmpLong[0]; 12043 } 12044 if (dumpDetails) { 12045 if (localOnly) { 12046 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails, 12047 dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0); 12048 if (isCheckinRequest) { 12049 pw.println(); 12050 } 12051 } else { 12052 try { 12053 pw.flush(); 12054 thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails, 12055 dumpDalvik, innerArgs); 12056 } catch (RemoteException e) { 12057 if (!isCheckinRequest) { 12058 pw.println("Got RemoteException!"); 12059 pw.flush(); 12060 } 12061 } 12062 } 12063 } 12064 12065 final long myTotalPss = mi.getTotalPss(); 12066 final long myTotalUss = mi.getTotalUss(); 12067 12068 synchronized (this) { 12069 if (r.thread != null && oomAdj == r.getSetAdjWithServices()) { 12070 // Record this for posterity if the process has been stable. 12071 r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList); 12072 } 12073 } 12074 12075 if (!isCheckinRequest && mi != null) { 12076 totalPss += myTotalPss; 12077 MemItem pssItem = new MemItem(r.processName + " (pid " + pid + 12078 (hasActivities ? " / activities)" : ")"), 12079 r.processName, myTotalPss, pid, hasActivities); 12080 procMems.add(pssItem); 12081 procMemsMap.put(pid, pssItem); 12082 12083 nativePss += mi.nativePss; 12084 dalvikPss += mi.dalvikPss; 12085 otherPss += mi.otherPss; 12086 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 12087 long mem = mi.getOtherPss(j); 12088 miscPss[j] += mem; 12089 otherPss -= mem; 12090 } 12091 12092 if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 12093 cachedPss += myTotalPss; 12094 } 12095 12096 for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) { 12097 if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex] 12098 || oomIndex == (oomPss.length-1)) { 12099 oomPss[oomIndex] += myTotalPss; 12100 if (oomProcs[oomIndex] == null) { 12101 oomProcs[oomIndex] = new ArrayList<MemItem>(); 12102 } 12103 oomProcs[oomIndex].add(pssItem); 12104 break; 12105 } 12106 } 12107 } 12108 } 12109 } 12110 12111 if (!isCheckinRequest && procs.size() > 1) { 12112 // If we are showing aggregations, also look for native processes to 12113 // include so that our aggregations are more accurate. 12114 updateCpuStatsNow(); 12115 synchronized (mProcessCpuThread) { 12116 final int N = mProcessCpuTracker.countStats(); 12117 for (int i=0; i<N; i++) { 12118 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 12119 if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) { 12120 if (mi == null) { 12121 mi = new Debug.MemoryInfo(); 12122 } 12123 if (!brief && !oomOnly) { 12124 Debug.getMemoryInfo(st.pid, mi); 12125 } else { 12126 mi.nativePss = (int)Debug.getPss(st.pid, tmpLong); 12127 mi.nativePrivateDirty = (int)tmpLong[0]; 12128 } 12129 12130 final long myTotalPss = mi.getTotalPss(); 12131 totalPss += myTotalPss; 12132 12133 MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")", 12134 st.name, myTotalPss, st.pid, false); 12135 procMems.add(pssItem); 12136 12137 nativePss += mi.nativePss; 12138 dalvikPss += mi.dalvikPss; 12139 otherPss += mi.otherPss; 12140 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 12141 long mem = mi.getOtherPss(j); 12142 miscPss[j] += mem; 12143 otherPss -= mem; 12144 } 12145 oomPss[0] += myTotalPss; 12146 if (oomProcs[0] == null) { 12147 oomProcs[0] = new ArrayList<MemItem>(); 12148 } 12149 oomProcs[0].add(pssItem); 12150 } 12151 } 12152 } 12153 12154 ArrayList<MemItem> catMems = new ArrayList<MemItem>(); 12155 12156 catMems.add(new MemItem("Native", "Native", nativePss, -1)); 12157 catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2)); 12158 catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3)); 12159 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 12160 String label = Debug.MemoryInfo.getOtherLabel(j); 12161 catMems.add(new MemItem(label, label, miscPss[j], j)); 12162 } 12163 12164 ArrayList<MemItem> oomMems = new ArrayList<MemItem>(); 12165 for (int j=0; j<oomPss.length; j++) { 12166 if (oomPss[j] != 0) { 12167 String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j] 12168 : DUMP_MEM_OOM_LABEL[j]; 12169 MemItem item = new MemItem(label, label, oomPss[j], 12170 DUMP_MEM_OOM_ADJ[j]); 12171 item.subitems = oomProcs[j]; 12172 oomMems.add(item); 12173 } 12174 } 12175 12176 if (!brief && !oomOnly && !isCompact) { 12177 pw.println(); 12178 pw.println("Total PSS by process:"); 12179 dumpMemItems(pw, " ", "proc", procMems, true, isCompact); 12180 pw.println(); 12181 } 12182 if (!isCompact) { 12183 pw.println("Total PSS by OOM adjustment:"); 12184 } 12185 dumpMemItems(pw, " ", "oom", oomMems, false, isCompact); 12186 if (!brief && !oomOnly) { 12187 PrintWriter out = categoryPw != null ? categoryPw : pw; 12188 if (!isCompact) { 12189 out.println(); 12190 out.println("Total PSS by category:"); 12191 } 12192 dumpMemItems(out, " ", "cat", catMems, true, isCompact); 12193 } 12194 if (!isCompact) { 12195 pw.println(); 12196 } 12197 MemInfoReader memInfo = new MemInfoReader(); 12198 memInfo.readMemInfo(); 12199 if (!brief) { 12200 if (!isCompact) { 12201 pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb()); 12202 pw.print(" kB (status "); 12203 switch (mLastMemoryLevel) { 12204 case ProcessStats.ADJ_MEM_FACTOR_NORMAL: 12205 pw.println("normal)"); 12206 break; 12207 case ProcessStats.ADJ_MEM_FACTOR_MODERATE: 12208 pw.println("moderate)"); 12209 break; 12210 case ProcessStats.ADJ_MEM_FACTOR_LOW: 12211 pw.println("low)"); 12212 break; 12213 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL: 12214 pw.println("critical)"); 12215 break; 12216 default: 12217 pw.print(mLastMemoryLevel); 12218 pw.println(")"); 12219 break; 12220 } 12221 pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb() 12222 + memInfo.getFreeSizeKb()); pw.print(" kB ("); 12223 pw.print(cachedPss); pw.print(" cached pss + "); 12224 pw.print(memInfo.getCachedSizeKb()); pw.print(" cached + "); 12225 pw.print(memInfo.getFreeSizeKb()); pw.println(" free)"); 12226 } else { 12227 pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(","); 12228 pw.print(cachedPss + memInfo.getCachedSizeKb() 12229 + memInfo.getFreeSizeKb()); pw.print(","); 12230 pw.println(totalPss - cachedPss); 12231 } 12232 } 12233 if (!isCompact) { 12234 pw.print(" Used RAM: "); pw.print(totalPss - cachedPss 12235 + memInfo.getBuffersSizeKb() + memInfo.getShmemSizeKb() 12236 + memInfo.getSlabSizeKb()); pw.print(" kB ("); 12237 pw.print(totalPss - cachedPss); pw.print(" used pss + "); 12238 pw.print(memInfo.getBuffersSizeKb()); pw.print(" buffers + "); 12239 pw.print(memInfo.getShmemSizeKb()); pw.print(" shmem + "); 12240 pw.print(memInfo.getSlabSizeKb()); pw.println(" slab)"); 12241 pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb() 12242 - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb() 12243 - memInfo.getBuffersSizeKb() - memInfo.getShmemSizeKb() 12244 - memInfo.getSlabSizeKb()); pw.println(" kB"); 12245 } 12246 if (!brief) { 12247 if (memInfo.getZramTotalSizeKb() != 0) { 12248 if (!isCompact) { 12249 pw.print(" ZRAM: "); pw.print(memInfo.getZramTotalSizeKb()); 12250 pw.print(" kB physical used for "); 12251 pw.print(memInfo.getSwapTotalSizeKb() 12252 - memInfo.getSwapFreeSizeKb()); 12253 pw.print(" kB in swap ("); 12254 pw.print(memInfo.getSwapTotalSizeKb()); 12255 pw.println(" kB total swap)"); 12256 } else { 12257 pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(","); 12258 pw.print(memInfo.getSwapTotalSizeKb()); pw.print(","); 12259 pw.println(memInfo.getSwapFreeSizeKb()); 12260 } 12261 } 12262 final int[] SINGLE_LONG_FORMAT = new int[] { 12263 Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG 12264 }; 12265 long[] longOut = new long[1]; 12266 Process.readProcFile("/sys/kernel/mm/ksm/pages_shared", 12267 SINGLE_LONG_FORMAT, null, longOut, null); 12268 long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024; 12269 longOut[0] = 0; 12270 Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing", 12271 SINGLE_LONG_FORMAT, null, longOut, null); 12272 long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024; 12273 longOut[0] = 0; 12274 Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared", 12275 SINGLE_LONG_FORMAT, null, longOut, null); 12276 long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024; 12277 longOut[0] = 0; 12278 Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile", 12279 SINGLE_LONG_FORMAT, null, longOut, null); 12280 long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024; 12281 if (!isCompact) { 12282 if (sharing != 0 || shared != 0 || unshared != 0 || voltile != 0) { 12283 pw.print(" KSM: "); pw.print(sharing); 12284 pw.print(" kB saved from shared "); 12285 pw.print(shared); pw.println(" kB"); 12286 pw.print(" "); pw.print(unshared); pw.print(" kB unshared; "); 12287 pw.print(voltile); pw.println(" kB volatile"); 12288 } 12289 pw.print(" Tuning: "); 12290 pw.print(ActivityManager.staticGetMemoryClass()); 12291 pw.print(" (large "); 12292 pw.print(ActivityManager.staticGetLargeMemoryClass()); 12293 pw.print("), oom "); 12294 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024); 12295 pw.print(" kB"); 12296 pw.print(", restore limit "); 12297 pw.print(mProcessList.getCachedRestoreThresholdKb()); 12298 pw.print(" kB"); 12299 if (ActivityManager.isLowRamDeviceStatic()) { 12300 pw.print(" (low-ram)"); 12301 } 12302 if (ActivityManager.isHighEndGfx()) { 12303 pw.print(" (high-end-gfx)"); 12304 } 12305 pw.println(); 12306 } else { 12307 pw.print("ksm,"); pw.print(sharing); pw.print(","); 12308 pw.print(shared); pw.print(","); pw.print(unshared); pw.print(","); 12309 pw.println(voltile); 12310 pw.print("tuning,"); 12311 pw.print(ActivityManager.staticGetMemoryClass()); 12312 pw.print(','); 12313 pw.print(ActivityManager.staticGetLargeMemoryClass()); 12314 pw.print(','); 12315 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024); 12316 if (ActivityManager.isLowRamDeviceStatic()) { 12317 pw.print(",low-ram"); 12318 } 12319 if (ActivityManager.isHighEndGfx()) { 12320 pw.print(",high-end-gfx"); 12321 } 12322 pw.println(); 12323 } 12324 } 12325 } 12326 } 12327 12328 /** 12329 * Searches array of arguments for the specified string 12330 * @param args array of argument strings 12331 * @param value value to search for 12332 * @return true if the value is contained in the array 12333 */ 12334 private static boolean scanArgs(String[] args, String value) { 12335 if (args != null) { 12336 for (String arg : args) { 12337 if (value.equals(arg)) { 12338 return true; 12339 } 12340 } 12341 } 12342 return false; 12343 } 12344 12345 private final boolean removeDyingProviderLocked(ProcessRecord proc, 12346 ContentProviderRecord cpr, boolean always) { 12347 final boolean inLaunching = mLaunchingProviders.contains(cpr); 12348 12349 if (!inLaunching || always) { 12350 synchronized (cpr) { 12351 cpr.launchingApp = null; 12352 cpr.notifyAll(); 12353 } 12354 mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid)); 12355 String names[] = cpr.info.authority.split(";"); 12356 for (int j = 0; j < names.length; j++) { 12357 mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid)); 12358 } 12359 } 12360 12361 for (int i=0; i<cpr.connections.size(); i++) { 12362 ContentProviderConnection conn = cpr.connections.get(i); 12363 if (conn.waiting) { 12364 // If this connection is waiting for the provider, then we don't 12365 // need to mess with its process unless we are always removing 12366 // or for some reason the provider is not currently launching. 12367 if (inLaunching && !always) { 12368 continue; 12369 } 12370 } 12371 ProcessRecord capp = conn.client; 12372 conn.dead = true; 12373 if (conn.stableCount > 0) { 12374 if (!capp.persistent && capp.thread != null 12375 && capp.pid != 0 12376 && capp.pid != MY_PID) { 12377 killUnneededProcessLocked(capp, "depends on provider " 12378 + cpr.name.flattenToShortString() 12379 + " in dying proc " + (proc != null ? proc.processName : "??")); 12380 } 12381 } else if (capp.thread != null && conn.provider.provider != null) { 12382 try { 12383 capp.thread.unstableProviderDied(conn.provider.provider.asBinder()); 12384 } catch (RemoteException e) { 12385 } 12386 // In the protocol here, we don't expect the client to correctly 12387 // clean up this connection, we'll just remove it. 12388 cpr.connections.remove(i); 12389 conn.client.conProviders.remove(conn); 12390 } 12391 } 12392 12393 if (inLaunching && always) { 12394 mLaunchingProviders.remove(cpr); 12395 } 12396 return inLaunching; 12397 } 12398 12399 /** 12400 * Main code for cleaning up a process when it has gone away. This is 12401 * called both as a result of the process dying, or directly when stopping 12402 * a process when running in single process mode. 12403 */ 12404 private final void cleanUpApplicationRecordLocked(ProcessRecord app, 12405 boolean restarting, boolean allowRestart, int index) { 12406 if (index >= 0) { 12407 removeLruProcessLocked(app); 12408 ProcessList.remove(app.pid); 12409 } 12410 12411 mProcessesToGc.remove(app); 12412 mPendingPssProcesses.remove(app); 12413 12414 // Dismiss any open dialogs. 12415 if (app.crashDialog != null && !app.forceCrashReport) { 12416 app.crashDialog.dismiss(); 12417 app.crashDialog = null; 12418 } 12419 if (app.anrDialog != null) { 12420 app.anrDialog.dismiss(); 12421 app.anrDialog = null; 12422 } 12423 if (app.waitDialog != null) { 12424 app.waitDialog.dismiss(); 12425 app.waitDialog = null; 12426 } 12427 12428 app.crashing = false; 12429 app.notResponding = false; 12430 12431 app.resetPackageList(mProcessStats); 12432 app.unlinkDeathRecipient(); 12433 app.makeInactive(mProcessStats); 12434 app.forcingToForeground = null; 12435 updateProcessForegroundLocked(app, false, false); 12436 app.foregroundActivities = false; 12437 app.hasShownUi = false; 12438 app.hasAboveClient = false; 12439 12440 mServices.killServicesLocked(app, allowRestart); 12441 12442 boolean restart = false; 12443 12444 // Remove published content providers. 12445 for (int i=app.pubProviders.size()-1; i>=0; i--) { 12446 ContentProviderRecord cpr = app.pubProviders.valueAt(i); 12447 final boolean always = app.bad || !allowRestart; 12448 if (removeDyingProviderLocked(app, cpr, always) || always) { 12449 // We left the provider in the launching list, need to 12450 // restart it. 12451 restart = true; 12452 } 12453 12454 cpr.provider = null; 12455 cpr.proc = null; 12456 } 12457 app.pubProviders.clear(); 12458 12459 // Take care of any launching providers waiting for this process. 12460 if (checkAppInLaunchingProvidersLocked(app, false)) { 12461 restart = true; 12462 } 12463 12464 // Unregister from connected content providers. 12465 if (!app.conProviders.isEmpty()) { 12466 for (int i=0; i<app.conProviders.size(); i++) { 12467 ContentProviderConnection conn = app.conProviders.get(i); 12468 conn.provider.connections.remove(conn); 12469 } 12470 app.conProviders.clear(); 12471 } 12472 12473 // At this point there may be remaining entries in mLaunchingProviders 12474 // where we were the only one waiting, so they are no longer of use. 12475 // Look for these and clean up if found. 12476 // XXX Commented out for now. Trying to figure out a way to reproduce 12477 // the actual situation to identify what is actually going on. 12478 if (false) { 12479 for (int i=0; i<mLaunchingProviders.size(); i++) { 12480 ContentProviderRecord cpr = (ContentProviderRecord) 12481 mLaunchingProviders.get(i); 12482 if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) { 12483 synchronized (cpr) { 12484 cpr.launchingApp = null; 12485 cpr.notifyAll(); 12486 } 12487 } 12488 } 12489 } 12490 12491 skipCurrentReceiverLocked(app); 12492 12493 // Unregister any receivers. 12494 for (int i=app.receivers.size()-1; i>=0; i--) { 12495 removeReceiverLocked(app.receivers.valueAt(i)); 12496 } 12497 app.receivers.clear(); 12498 12499 // If the app is undergoing backup, tell the backup manager about it 12500 if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) { 12501 if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App " 12502 + mBackupTarget.appInfo + " died during backup"); 12503 try { 12504 IBackupManager bm = IBackupManager.Stub.asInterface( 12505 ServiceManager.getService(Context.BACKUP_SERVICE)); 12506 bm.agentDisconnected(app.info.packageName); 12507 } catch (RemoteException e) { 12508 // can't happen; backup manager is local 12509 } 12510 } 12511 12512 for (int i = mPendingProcessChanges.size()-1; i>=0; i--) { 12513 ProcessChangeItem item = mPendingProcessChanges.get(i); 12514 if (item.pid == app.pid) { 12515 mPendingProcessChanges.remove(i); 12516 mAvailProcessChanges.add(item); 12517 } 12518 } 12519 mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget(); 12520 12521 // If the caller is restarting this app, then leave it in its 12522 // current lists and let the caller take care of it. 12523 if (restarting) { 12524 return; 12525 } 12526 12527 if (!app.persistent || app.isolated) { 12528 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, 12529 "Removing non-persistent process during cleanup: " + app); 12530 mProcessNames.remove(app.processName, app.uid); 12531 mIsolatedProcesses.remove(app.uid); 12532 if (mHeavyWeightProcess == app) { 12533 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 12534 mHeavyWeightProcess.userId, 0)); 12535 mHeavyWeightProcess = null; 12536 } 12537 } else if (!app.removed) { 12538 // This app is persistent, so we need to keep its record around. 12539 // If it is not already on the pending app list, add it there 12540 // and start a new process for it. 12541 if (mPersistentStartingProcesses.indexOf(app) < 0) { 12542 mPersistentStartingProcesses.add(app); 12543 restart = true; 12544 } 12545 } 12546 if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG, 12547 "Clean-up removing on hold: " + app); 12548 mProcessesOnHold.remove(app); 12549 12550 if (app == mHomeProcess) { 12551 mHomeProcess = null; 12552 } 12553 if (app == mPreviousProcess) { 12554 mPreviousProcess = null; 12555 } 12556 12557 if (restart && !app.isolated) { 12558 // We have components that still need to be running in the 12559 // process, so re-launch it. 12560 mProcessNames.put(app.processName, app.uid, app); 12561 startProcessLocked(app, "restart", app.processName); 12562 } else if (app.pid > 0 && app.pid != MY_PID) { 12563 // Goodbye! 12564 boolean removed; 12565 synchronized (mPidsSelfLocked) { 12566 mPidsSelfLocked.remove(app.pid); 12567 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 12568 } 12569 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH, 12570 app.processName, app.info.uid); 12571 if (app.isolated) { 12572 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 12573 } 12574 app.setPid(0); 12575 } 12576 } 12577 12578 boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) { 12579 // Look through the content providers we are waiting to have launched, 12580 // and if any run in this process then either schedule a restart of 12581 // the process or kill the client waiting for it if this process has 12582 // gone bad. 12583 int NL = mLaunchingProviders.size(); 12584 boolean restart = false; 12585 for (int i=0; i<NL; i++) { 12586 ContentProviderRecord cpr = mLaunchingProviders.get(i); 12587 if (cpr.launchingApp == app) { 12588 if (!alwaysBad && !app.bad) { 12589 restart = true; 12590 } else { 12591 removeDyingProviderLocked(app, cpr, true); 12592 // cpr should have been removed from mLaunchingProviders 12593 NL = mLaunchingProviders.size(); 12594 i--; 12595 } 12596 } 12597 } 12598 return restart; 12599 } 12600 12601 // ========================================================= 12602 // SERVICES 12603 // ========================================================= 12604 12605 public List<ActivityManager.RunningServiceInfo> getServices(int maxNum, 12606 int flags) { 12607 enforceNotIsolatedCaller("getServices"); 12608 synchronized (this) { 12609 return mServices.getRunningServiceInfoLocked(maxNum, flags); 12610 } 12611 } 12612 12613 public PendingIntent getRunningServiceControlPanel(ComponentName name) { 12614 enforceNotIsolatedCaller("getRunningServiceControlPanel"); 12615 synchronized (this) { 12616 return mServices.getRunningServiceControlPanelLocked(name); 12617 } 12618 } 12619 12620 public ComponentName startService(IApplicationThread caller, Intent service, 12621 String resolvedType, int userId) { 12622 enforceNotIsolatedCaller("startService"); 12623 // Refuse possible leaked file descriptors 12624 if (service != null && service.hasFileDescriptors() == true) { 12625 throw new IllegalArgumentException("File descriptors passed in Intent"); 12626 } 12627 12628 if (DEBUG_SERVICE) 12629 Slog.v(TAG, "startService: " + service + " type=" + resolvedType); 12630 synchronized(this) { 12631 final int callingPid = Binder.getCallingPid(); 12632 final int callingUid = Binder.getCallingUid(); 12633 final long origId = Binder.clearCallingIdentity(); 12634 ComponentName res = mServices.startServiceLocked(caller, service, 12635 resolvedType, callingPid, callingUid, userId); 12636 Binder.restoreCallingIdentity(origId); 12637 return res; 12638 } 12639 } 12640 12641 ComponentName startServiceInPackage(int uid, 12642 Intent service, String resolvedType, int userId) { 12643 synchronized(this) { 12644 if (DEBUG_SERVICE) 12645 Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType); 12646 final long origId = Binder.clearCallingIdentity(); 12647 ComponentName res = mServices.startServiceLocked(null, service, 12648 resolvedType, -1, uid, userId); 12649 Binder.restoreCallingIdentity(origId); 12650 return res; 12651 } 12652 } 12653 12654 public int stopService(IApplicationThread caller, Intent service, 12655 String resolvedType, int userId) { 12656 enforceNotIsolatedCaller("stopService"); 12657 // Refuse possible leaked file descriptors 12658 if (service != null && service.hasFileDescriptors() == true) { 12659 throw new IllegalArgumentException("File descriptors passed in Intent"); 12660 } 12661 12662 synchronized(this) { 12663 return mServices.stopServiceLocked(caller, service, resolvedType, userId); 12664 } 12665 } 12666 12667 public IBinder peekService(Intent service, String resolvedType) { 12668 enforceNotIsolatedCaller("peekService"); 12669 // Refuse possible leaked file descriptors 12670 if (service != null && service.hasFileDescriptors() == true) { 12671 throw new IllegalArgumentException("File descriptors passed in Intent"); 12672 } 12673 synchronized(this) { 12674 return mServices.peekServiceLocked(service, resolvedType); 12675 } 12676 } 12677 12678 public boolean stopServiceToken(ComponentName className, IBinder token, 12679 int startId) { 12680 synchronized(this) { 12681 return mServices.stopServiceTokenLocked(className, token, startId); 12682 } 12683 } 12684 12685 public void setServiceForeground(ComponentName className, IBinder token, 12686 int id, Notification notification, boolean removeNotification) { 12687 synchronized(this) { 12688 mServices.setServiceForegroundLocked(className, token, id, notification, 12689 removeNotification); 12690 } 12691 } 12692 12693 public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll, 12694 boolean requireFull, String name, String callerPackage) { 12695 final int callingUserId = UserHandle.getUserId(callingUid); 12696 if (callingUserId != userId) { 12697 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 12698 if ((requireFull || checkComponentPermission( 12699 android.Manifest.permission.INTERACT_ACROSS_USERS, 12700 callingPid, callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) 12701 && checkComponentPermission( 12702 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 12703 callingPid, callingUid, -1, true) 12704 != PackageManager.PERMISSION_GRANTED) { 12705 if (userId == UserHandle.USER_CURRENT_OR_SELF) { 12706 // In this case, they would like to just execute as their 12707 // owner user instead of failing. 12708 userId = callingUserId; 12709 } else { 12710 StringBuilder builder = new StringBuilder(128); 12711 builder.append("Permission Denial: "); 12712 builder.append(name); 12713 if (callerPackage != null) { 12714 builder.append(" from "); 12715 builder.append(callerPackage); 12716 } 12717 builder.append(" asks to run as user "); 12718 builder.append(userId); 12719 builder.append(" but is calling from user "); 12720 builder.append(UserHandle.getUserId(callingUid)); 12721 builder.append("; this requires "); 12722 builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL); 12723 if (!requireFull) { 12724 builder.append(" or "); 12725 builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS); 12726 } 12727 String msg = builder.toString(); 12728 Slog.w(TAG, msg); 12729 throw new SecurityException(msg); 12730 } 12731 } 12732 } 12733 if (userId == UserHandle.USER_CURRENT 12734 || userId == UserHandle.USER_CURRENT_OR_SELF) { 12735 // Note that we may be accessing this outside of a lock... 12736 // shouldn't be a big deal, if this is being called outside 12737 // of a locked context there is intrinsically a race with 12738 // the value the caller will receive and someone else changing it. 12739 userId = mCurrentUserId; 12740 } 12741 if (!allowAll && userId < 0) { 12742 throw new IllegalArgumentException( 12743 "Call does not support special user #" + userId); 12744 } 12745 } 12746 return userId; 12747 } 12748 12749 boolean isSingleton(String componentProcessName, ApplicationInfo aInfo, 12750 String className, int flags) { 12751 boolean result = false; 12752 if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) { 12753 if ((flags&ServiceInfo.FLAG_SINGLE_USER) != 0) { 12754 if (ActivityManager.checkUidPermission( 12755 android.Manifest.permission.INTERACT_ACROSS_USERS, 12756 aInfo.uid) != PackageManager.PERMISSION_GRANTED) { 12757 ComponentName comp = new ComponentName(aInfo.packageName, className); 12758 String msg = "Permission Denial: Component " + comp.flattenToShortString() 12759 + " requests FLAG_SINGLE_USER, but app does not hold " 12760 + android.Manifest.permission.INTERACT_ACROSS_USERS; 12761 Slog.w(TAG, msg); 12762 throw new SecurityException(msg); 12763 } 12764 result = true; 12765 } 12766 } else if (componentProcessName == aInfo.packageName) { 12767 result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0; 12768 } else if ("system".equals(componentProcessName)) { 12769 result = true; 12770 } 12771 if (DEBUG_MU) { 12772 Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo 12773 + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result); 12774 } 12775 return result; 12776 } 12777 12778 public int bindService(IApplicationThread caller, IBinder token, 12779 Intent service, String resolvedType, 12780 IServiceConnection connection, int flags, int userId) { 12781 enforceNotIsolatedCaller("bindService"); 12782 // Refuse possible leaked file descriptors 12783 if (service != null && service.hasFileDescriptors() == true) { 12784 throw new IllegalArgumentException("File descriptors passed in Intent"); 12785 } 12786 12787 synchronized(this) { 12788 return mServices.bindServiceLocked(caller, token, service, resolvedType, 12789 connection, flags, userId); 12790 } 12791 } 12792 12793 public boolean unbindService(IServiceConnection connection) { 12794 synchronized (this) { 12795 return mServices.unbindServiceLocked(connection); 12796 } 12797 } 12798 12799 public void publishService(IBinder token, Intent intent, IBinder service) { 12800 // Refuse possible leaked file descriptors 12801 if (intent != null && intent.hasFileDescriptors() == true) { 12802 throw new IllegalArgumentException("File descriptors passed in Intent"); 12803 } 12804 12805 synchronized(this) { 12806 if (!(token instanceof ServiceRecord)) { 12807 throw new IllegalArgumentException("Invalid service token"); 12808 } 12809 mServices.publishServiceLocked((ServiceRecord)token, intent, service); 12810 } 12811 } 12812 12813 public void unbindFinished(IBinder token, Intent intent, boolean doRebind) { 12814 // Refuse possible leaked file descriptors 12815 if (intent != null && intent.hasFileDescriptors() == true) { 12816 throw new IllegalArgumentException("File descriptors passed in Intent"); 12817 } 12818 12819 synchronized(this) { 12820 mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind); 12821 } 12822 } 12823 12824 public void serviceDoneExecuting(IBinder token, int type, int startId, int res) { 12825 synchronized(this) { 12826 if (!(token instanceof ServiceRecord)) { 12827 throw new IllegalArgumentException("Invalid service token"); 12828 } 12829 mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res); 12830 } 12831 } 12832 12833 // ========================================================= 12834 // BACKUP AND RESTORE 12835 // ========================================================= 12836 12837 // Cause the target app to be launched if necessary and its backup agent 12838 // instantiated. The backup agent will invoke backupAgentCreated() on the 12839 // activity manager to announce its creation. 12840 public boolean bindBackupAgent(ApplicationInfo app, int backupMode) { 12841 if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode); 12842 enforceCallingPermission("android.permission.BACKUP", "bindBackupAgent"); 12843 12844 synchronized(this) { 12845 // !!! TODO: currently no check here that we're already bound 12846 BatteryStatsImpl.Uid.Pkg.Serv ss = null; 12847 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 12848 synchronized (stats) { 12849 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name); 12850 } 12851 12852 // Backup agent is now in use, its package can't be stopped. 12853 try { 12854 AppGlobals.getPackageManager().setPackageStoppedState( 12855 app.packageName, false, UserHandle.getUserId(app.uid)); 12856 } catch (RemoteException e) { 12857 } catch (IllegalArgumentException e) { 12858 Slog.w(TAG, "Failed trying to unstop package " 12859 + app.packageName + ": " + e); 12860 } 12861 12862 BackupRecord r = new BackupRecord(ss, app, backupMode); 12863 ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL) 12864 ? new ComponentName(app.packageName, app.backupAgentName) 12865 : new ComponentName("android", "FullBackupAgent"); 12866 // startProcessLocked() returns existing proc's record if it's already running 12867 ProcessRecord proc = startProcessLocked(app.processName, app, 12868 false, 0, "backup", hostingName, false, false, false); 12869 if (proc == null) { 12870 Slog.e(TAG, "Unable to start backup agent process " + r); 12871 return false; 12872 } 12873 12874 r.app = proc; 12875 mBackupTarget = r; 12876 mBackupAppName = app.packageName; 12877 12878 // Try not to kill the process during backup 12879 updateOomAdjLocked(proc); 12880 12881 // If the process is already attached, schedule the creation of the backup agent now. 12882 // If it is not yet live, this will be done when it attaches to the framework. 12883 if (proc.thread != null) { 12884 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc); 12885 try { 12886 proc.thread.scheduleCreateBackupAgent(app, 12887 compatibilityInfoForPackageLocked(app), backupMode); 12888 } catch (RemoteException e) { 12889 // Will time out on the backup manager side 12890 } 12891 } else { 12892 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach"); 12893 } 12894 // Invariants: at this point, the target app process exists and the application 12895 // is either already running or in the process of coming up. mBackupTarget and 12896 // mBackupAppName describe the app, so that when it binds back to the AM we 12897 // know that it's scheduled for a backup-agent operation. 12898 } 12899 12900 return true; 12901 } 12902 12903 @Override 12904 public void clearPendingBackup() { 12905 if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup"); 12906 enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup"); 12907 12908 synchronized (this) { 12909 mBackupTarget = null; 12910 mBackupAppName = null; 12911 } 12912 } 12913 12914 // A backup agent has just come up 12915 public void backupAgentCreated(String agentPackageName, IBinder agent) { 12916 if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName 12917 + " = " + agent); 12918 12919 synchronized(this) { 12920 if (!agentPackageName.equals(mBackupAppName)) { 12921 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!"); 12922 return; 12923 } 12924 } 12925 12926 long oldIdent = Binder.clearCallingIdentity(); 12927 try { 12928 IBackupManager bm = IBackupManager.Stub.asInterface( 12929 ServiceManager.getService(Context.BACKUP_SERVICE)); 12930 bm.agentConnected(agentPackageName, agent); 12931 } catch (RemoteException e) { 12932 // can't happen; the backup manager service is local 12933 } catch (Exception e) { 12934 Slog.w(TAG, "Exception trying to deliver BackupAgent binding: "); 12935 e.printStackTrace(); 12936 } finally { 12937 Binder.restoreCallingIdentity(oldIdent); 12938 } 12939 } 12940 12941 // done with this agent 12942 public void unbindBackupAgent(ApplicationInfo appInfo) { 12943 if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo); 12944 if (appInfo == null) { 12945 Slog.w(TAG, "unbind backup agent for null app"); 12946 return; 12947 } 12948 12949 synchronized(this) { 12950 try { 12951 if (mBackupAppName == null) { 12952 Slog.w(TAG, "Unbinding backup agent with no active backup"); 12953 return; 12954 } 12955 12956 if (!mBackupAppName.equals(appInfo.packageName)) { 12957 Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target"); 12958 return; 12959 } 12960 12961 // Not backing this app up any more; reset its OOM adjustment 12962 final ProcessRecord proc = mBackupTarget.app; 12963 updateOomAdjLocked(proc); 12964 12965 // If the app crashed during backup, 'thread' will be null here 12966 if (proc.thread != null) { 12967 try { 12968 proc.thread.scheduleDestroyBackupAgent(appInfo, 12969 compatibilityInfoForPackageLocked(appInfo)); 12970 } catch (Exception e) { 12971 Slog.e(TAG, "Exception when unbinding backup agent:"); 12972 e.printStackTrace(); 12973 } 12974 } 12975 } finally { 12976 mBackupTarget = null; 12977 mBackupAppName = null; 12978 } 12979 } 12980 } 12981 // ========================================================= 12982 // BROADCASTS 12983 // ========================================================= 12984 12985 private final List getStickiesLocked(String action, IntentFilter filter, 12986 List cur, int userId) { 12987 final ContentResolver resolver = mContext.getContentResolver(); 12988 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 12989 if (stickies == null) { 12990 return cur; 12991 } 12992 final ArrayList<Intent> list = stickies.get(action); 12993 if (list == null) { 12994 return cur; 12995 } 12996 int N = list.size(); 12997 for (int i=0; i<N; i++) { 12998 Intent intent = list.get(i); 12999 if (filter.match(resolver, intent, true, TAG) >= 0) { 13000 if (cur == null) { 13001 cur = new ArrayList<Intent>(); 13002 } 13003 cur.add(intent); 13004 } 13005 } 13006 return cur; 13007 } 13008 13009 boolean isPendingBroadcastProcessLocked(int pid) { 13010 return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid) 13011 || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid); 13012 } 13013 13014 void skipPendingBroadcastLocked(int pid) { 13015 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 13016 for (BroadcastQueue queue : mBroadcastQueues) { 13017 queue.skipPendingBroadcastLocked(pid); 13018 } 13019 } 13020 13021 // The app just attached; send any pending broadcasts that it should receive 13022 boolean sendPendingBroadcastsLocked(ProcessRecord app) { 13023 boolean didSomething = false; 13024 for (BroadcastQueue queue : mBroadcastQueues) { 13025 didSomething |= queue.sendPendingBroadcastsLocked(app); 13026 } 13027 return didSomething; 13028 } 13029 13030 public Intent registerReceiver(IApplicationThread caller, String callerPackage, 13031 IIntentReceiver receiver, IntentFilter filter, String permission, int userId) { 13032 enforceNotIsolatedCaller("registerReceiver"); 13033 int callingUid; 13034 int callingPid; 13035 synchronized(this) { 13036 ProcessRecord callerApp = null; 13037 if (caller != null) { 13038 callerApp = getRecordForAppLocked(caller); 13039 if (callerApp == null) { 13040 throw new SecurityException( 13041 "Unable to find app for caller " + caller 13042 + " (pid=" + Binder.getCallingPid() 13043 + ") when registering receiver " + receiver); 13044 } 13045 if (callerApp.info.uid != Process.SYSTEM_UID && 13046 !callerApp.pkgList.containsKey(callerPackage) && 13047 !"android".equals(callerPackage)) { 13048 throw new SecurityException("Given caller package " + callerPackage 13049 + " is not running in process " + callerApp); 13050 } 13051 callingUid = callerApp.info.uid; 13052 callingPid = callerApp.pid; 13053 } else { 13054 callerPackage = null; 13055 callingUid = Binder.getCallingUid(); 13056 callingPid = Binder.getCallingPid(); 13057 } 13058 13059 userId = this.handleIncomingUser(callingPid, callingUid, userId, 13060 true, true, "registerReceiver", callerPackage); 13061 13062 List allSticky = null; 13063 13064 // Look for any matching sticky broadcasts... 13065 Iterator actions = filter.actionsIterator(); 13066 if (actions != null) { 13067 while (actions.hasNext()) { 13068 String action = (String)actions.next(); 13069 allSticky = getStickiesLocked(action, filter, allSticky, 13070 UserHandle.USER_ALL); 13071 allSticky = getStickiesLocked(action, filter, allSticky, 13072 UserHandle.getUserId(callingUid)); 13073 } 13074 } else { 13075 allSticky = getStickiesLocked(null, filter, allSticky, 13076 UserHandle.USER_ALL); 13077 allSticky = getStickiesLocked(null, filter, allSticky, 13078 UserHandle.getUserId(callingUid)); 13079 } 13080 13081 // The first sticky in the list is returned directly back to 13082 // the client. 13083 Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null; 13084 13085 if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter 13086 + ": " + sticky); 13087 13088 if (receiver == null) { 13089 return sticky; 13090 } 13091 13092 ReceiverList rl 13093 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder()); 13094 if (rl == null) { 13095 rl = new ReceiverList(this, callerApp, callingPid, callingUid, 13096 userId, receiver); 13097 if (rl.app != null) { 13098 rl.app.receivers.add(rl); 13099 } else { 13100 try { 13101 receiver.asBinder().linkToDeath(rl, 0); 13102 } catch (RemoteException e) { 13103 return sticky; 13104 } 13105 rl.linkedToDeath = true; 13106 } 13107 mRegisteredReceivers.put(receiver.asBinder(), rl); 13108 } else if (rl.uid != callingUid) { 13109 throw new IllegalArgumentException( 13110 "Receiver requested to register for uid " + callingUid 13111 + " was previously registered for uid " + rl.uid); 13112 } else if (rl.pid != callingPid) { 13113 throw new IllegalArgumentException( 13114 "Receiver requested to register for pid " + callingPid 13115 + " was previously registered for pid " + rl.pid); 13116 } else if (rl.userId != userId) { 13117 throw new IllegalArgumentException( 13118 "Receiver requested to register for user " + userId 13119 + " was previously registered for user " + rl.userId); 13120 } 13121 BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage, 13122 permission, callingUid, userId); 13123 rl.add(bf); 13124 if (!bf.debugCheck()) { 13125 Slog.w(TAG, "==> For Dynamic broadast"); 13126 } 13127 mReceiverResolver.addFilter(bf); 13128 13129 // Enqueue broadcasts for all existing stickies that match 13130 // this filter. 13131 if (allSticky != null) { 13132 ArrayList receivers = new ArrayList(); 13133 receivers.add(bf); 13134 13135 int N = allSticky.size(); 13136 for (int i=0; i<N; i++) { 13137 Intent intent = (Intent)allSticky.get(i); 13138 BroadcastQueue queue = broadcastQueueForIntent(intent); 13139 BroadcastRecord r = new BroadcastRecord(queue, intent, null, 13140 null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0, 13141 null, null, false, true, true, -1); 13142 queue.enqueueParallelBroadcastLocked(r); 13143 queue.scheduleBroadcastsLocked(); 13144 } 13145 } 13146 13147 return sticky; 13148 } 13149 } 13150 13151 public void unregisterReceiver(IIntentReceiver receiver) { 13152 if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver); 13153 13154 final long origId = Binder.clearCallingIdentity(); 13155 try { 13156 boolean doTrim = false; 13157 13158 synchronized(this) { 13159 ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder()); 13160 if (rl != null) { 13161 if (rl.curBroadcast != null) { 13162 BroadcastRecord r = rl.curBroadcast; 13163 final boolean doNext = finishReceiverLocked( 13164 receiver.asBinder(), r.resultCode, r.resultData, 13165 r.resultExtras, r.resultAbort); 13166 if (doNext) { 13167 doTrim = true; 13168 r.queue.processNextBroadcast(false); 13169 } 13170 } 13171 13172 if (rl.app != null) { 13173 rl.app.receivers.remove(rl); 13174 } 13175 removeReceiverLocked(rl); 13176 if (rl.linkedToDeath) { 13177 rl.linkedToDeath = false; 13178 rl.receiver.asBinder().unlinkToDeath(rl, 0); 13179 } 13180 } 13181 } 13182 13183 // If we actually concluded any broadcasts, we might now be able 13184 // to trim the recipients' apps from our working set 13185 if (doTrim) { 13186 trimApplications(); 13187 return; 13188 } 13189 13190 } finally { 13191 Binder.restoreCallingIdentity(origId); 13192 } 13193 } 13194 13195 void removeReceiverLocked(ReceiverList rl) { 13196 mRegisteredReceivers.remove(rl.receiver.asBinder()); 13197 int N = rl.size(); 13198 for (int i=0; i<N; i++) { 13199 mReceiverResolver.removeFilter(rl.get(i)); 13200 } 13201 } 13202 13203 private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) { 13204 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 13205 ProcessRecord r = mLruProcesses.get(i); 13206 if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) { 13207 try { 13208 r.thread.dispatchPackageBroadcast(cmd, packages); 13209 } catch (RemoteException ex) { 13210 } 13211 } 13212 } 13213 } 13214 13215 private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType, 13216 int[] users) { 13217 List<ResolveInfo> receivers = null; 13218 try { 13219 HashSet<ComponentName> singleUserReceivers = null; 13220 boolean scannedFirstReceivers = false; 13221 for (int user : users) { 13222 List<ResolveInfo> newReceivers = AppGlobals.getPackageManager() 13223 .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user); 13224 if (user != 0 && newReceivers != null) { 13225 // If this is not the primary user, we need to check for 13226 // any receivers that should be filtered out. 13227 for (int i=0; i<newReceivers.size(); i++) { 13228 ResolveInfo ri = newReceivers.get(i); 13229 if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) { 13230 newReceivers.remove(i); 13231 i--; 13232 } 13233 } 13234 } 13235 if (newReceivers != null && newReceivers.size() == 0) { 13236 newReceivers = null; 13237 } 13238 if (receivers == null) { 13239 receivers = newReceivers; 13240 } else if (newReceivers != null) { 13241 // We need to concatenate the additional receivers 13242 // found with what we have do far. This would be easy, 13243 // but we also need to de-dup any receivers that are 13244 // singleUser. 13245 if (!scannedFirstReceivers) { 13246 // Collect any single user receivers we had already retrieved. 13247 scannedFirstReceivers = true; 13248 for (int i=0; i<receivers.size(); i++) { 13249 ResolveInfo ri = receivers.get(i); 13250 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 13251 ComponentName cn = new ComponentName( 13252 ri.activityInfo.packageName, ri.activityInfo.name); 13253 if (singleUserReceivers == null) { 13254 singleUserReceivers = new HashSet<ComponentName>(); 13255 } 13256 singleUserReceivers.add(cn); 13257 } 13258 } 13259 } 13260 // Add the new results to the existing results, tracking 13261 // and de-dupping single user receivers. 13262 for (int i=0; i<newReceivers.size(); i++) { 13263 ResolveInfo ri = newReceivers.get(i); 13264 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 13265 ComponentName cn = new ComponentName( 13266 ri.activityInfo.packageName, ri.activityInfo.name); 13267 if (singleUserReceivers == null) { 13268 singleUserReceivers = new HashSet<ComponentName>(); 13269 } 13270 if (!singleUserReceivers.contains(cn)) { 13271 singleUserReceivers.add(cn); 13272 receivers.add(ri); 13273 } 13274 } else { 13275 receivers.add(ri); 13276 } 13277 } 13278 } 13279 } 13280 } catch (RemoteException ex) { 13281 // pm is in same process, this will never happen. 13282 } 13283 return receivers; 13284 } 13285 13286 private final int broadcastIntentLocked(ProcessRecord callerApp, 13287 String callerPackage, Intent intent, String resolvedType, 13288 IIntentReceiver resultTo, int resultCode, String resultData, 13289 Bundle map, String requiredPermission, int appOp, 13290 boolean ordered, boolean sticky, int callingPid, int callingUid, 13291 int userId) { 13292 intent = new Intent(intent); 13293 13294 // By default broadcasts do not go to stopped apps. 13295 intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES); 13296 13297 if (DEBUG_BROADCAST_LIGHT) Slog.v( 13298 TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent 13299 + " ordered=" + ordered + " userid=" + userId); 13300 if ((resultTo != null) && !ordered) { 13301 Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!"); 13302 } 13303 13304 userId = handleIncomingUser(callingPid, callingUid, userId, 13305 true, false, "broadcast", callerPackage); 13306 13307 // Make sure that the user who is receiving this broadcast is started. 13308 // If not, we will just skip it. 13309 if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) { 13310 if (callingUid != Process.SYSTEM_UID || (intent.getFlags() 13311 & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) { 13312 Slog.w(TAG, "Skipping broadcast of " + intent 13313 + ": user " + userId + " is stopped"); 13314 return ActivityManager.BROADCAST_SUCCESS; 13315 } 13316 } 13317 13318 /* 13319 * Prevent non-system code (defined here to be non-persistent 13320 * processes) from sending protected broadcasts. 13321 */ 13322 int callingAppId = UserHandle.getAppId(callingUid); 13323 if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID 13324 || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID || 13325 callingUid == 0) { 13326 // Always okay. 13327 } else if (callerApp == null || !callerApp.persistent) { 13328 try { 13329 if (AppGlobals.getPackageManager().isProtectedBroadcast( 13330 intent.getAction())) { 13331 String msg = "Permission Denial: not allowed to send broadcast " 13332 + intent.getAction() + " from pid=" 13333 + callingPid + ", uid=" + callingUid; 13334 Slog.w(TAG, msg); 13335 throw new SecurityException(msg); 13336 } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) { 13337 // Special case for compatibility: we don't want apps to send this, 13338 // but historically it has not been protected and apps may be using it 13339 // to poke their own app widget. So, instead of making it protected, 13340 // just limit it to the caller. 13341 if (callerApp == null) { 13342 String msg = "Permission Denial: not allowed to send broadcast " 13343 + intent.getAction() + " from unknown caller."; 13344 Slog.w(TAG, msg); 13345 throw new SecurityException(msg); 13346 } else if (intent.getComponent() != null) { 13347 // They are good enough to send to an explicit component... verify 13348 // it is being sent to the calling app. 13349 if (!intent.getComponent().getPackageName().equals( 13350 callerApp.info.packageName)) { 13351 String msg = "Permission Denial: not allowed to send broadcast " 13352 + intent.getAction() + " to " 13353 + intent.getComponent().getPackageName() + " from " 13354 + callerApp.info.packageName; 13355 Slog.w(TAG, msg); 13356 throw new SecurityException(msg); 13357 } 13358 } else { 13359 // Limit broadcast to their own package. 13360 intent.setPackage(callerApp.info.packageName); 13361 } 13362 } 13363 } catch (RemoteException e) { 13364 Slog.w(TAG, "Remote exception", e); 13365 return ActivityManager.BROADCAST_SUCCESS; 13366 } 13367 } 13368 13369 // Handle special intents: if this broadcast is from the package 13370 // manager about a package being removed, we need to remove all of 13371 // its activities from the history stack. 13372 final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals( 13373 intent.getAction()); 13374 if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction()) 13375 || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction()) 13376 || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction()) 13377 || uidRemoved) { 13378 if (checkComponentPermission( 13379 android.Manifest.permission.BROADCAST_PACKAGE_REMOVED, 13380 callingPid, callingUid, -1, true) 13381 == PackageManager.PERMISSION_GRANTED) { 13382 if (uidRemoved) { 13383 final Bundle intentExtras = intent.getExtras(); 13384 final int uid = intentExtras != null 13385 ? intentExtras.getInt(Intent.EXTRA_UID) : -1; 13386 if (uid >= 0) { 13387 BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics(); 13388 synchronized (bs) { 13389 bs.removeUidStatsLocked(uid); 13390 } 13391 mAppOpsService.uidRemoved(uid); 13392 } 13393 } else { 13394 // If resources are unavailable just force stop all 13395 // those packages and flush the attribute cache as well. 13396 if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) { 13397 String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 13398 if (list != null && (list.length > 0)) { 13399 for (String pkg : list) { 13400 forceStopPackageLocked(pkg, -1, false, true, true, false, false, userId, 13401 "storage unmount"); 13402 } 13403 sendPackageBroadcastLocked( 13404 IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId); 13405 } 13406 } else { 13407 Uri data = intent.getData(); 13408 String ssp; 13409 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 13410 boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals( 13411 intent.getAction()); 13412 boolean fullUninstall = removed && 13413 !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false); 13414 if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) { 13415 forceStopPackageLocked(ssp, UserHandle.getAppId( 13416 intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true, 13417 false, fullUninstall, userId, 13418 removed ? "pkg removed" : "pkg changed"); 13419 } 13420 if (removed) { 13421 sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED, 13422 new String[] {ssp}, userId); 13423 if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) { 13424 mAppOpsService.packageRemoved( 13425 intent.getIntExtra(Intent.EXTRA_UID, -1), ssp); 13426 13427 // Remove all permissions granted from/to this package 13428 removeUriPermissionsForPackageLocked(ssp, userId, true); 13429 } 13430 } 13431 } 13432 } 13433 } 13434 } else { 13435 String msg = "Permission Denial: " + intent.getAction() 13436 + " broadcast from " + callerPackage + " (pid=" + callingPid 13437 + ", uid=" + callingUid + ")" 13438 + " requires " 13439 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED; 13440 Slog.w(TAG, msg); 13441 throw new SecurityException(msg); 13442 } 13443 13444 // Special case for adding a package: by default turn on compatibility 13445 // mode. 13446 } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) { 13447 Uri data = intent.getData(); 13448 String ssp; 13449 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 13450 mCompatModePackages.handlePackageAddedLocked(ssp, 13451 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)); 13452 } 13453 } 13454 13455 /* 13456 * If this is the time zone changed action, queue up a message that will reset the timezone 13457 * of all currently running processes. This message will get queued up before the broadcast 13458 * happens. 13459 */ 13460 if (Intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) { 13461 mHandler.sendEmptyMessage(UPDATE_TIME_ZONE); 13462 } 13463 13464 /* 13465 * If the user set the time, let all running processes know. 13466 */ 13467 if (Intent.ACTION_TIME_CHANGED.equals(intent.getAction())) { 13468 final int is24Hour = intent.getBooleanExtra( 13469 Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1 : 0; 13470 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0)); 13471 } 13472 13473 if (Intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) { 13474 mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG); 13475 } 13476 13477 if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) { 13478 ProxyProperties proxy = intent.getParcelableExtra("proxy"); 13479 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy)); 13480 } 13481 13482 // Add to the sticky list if requested. 13483 if (sticky) { 13484 if (checkPermission(android.Manifest.permission.BROADCAST_STICKY, 13485 callingPid, callingUid) 13486 != PackageManager.PERMISSION_GRANTED) { 13487 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid=" 13488 + callingPid + ", uid=" + callingUid 13489 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 13490 Slog.w(TAG, msg); 13491 throw new SecurityException(msg); 13492 } 13493 if (requiredPermission != null) { 13494 Slog.w(TAG, "Can't broadcast sticky intent " + intent 13495 + " and enforce permission " + requiredPermission); 13496 return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION; 13497 } 13498 if (intent.getComponent() != null) { 13499 throw new SecurityException( 13500 "Sticky broadcasts can't target a specific component"); 13501 } 13502 // We use userId directly here, since the "all" target is maintained 13503 // as a separate set of sticky broadcasts. 13504 if (userId != UserHandle.USER_ALL) { 13505 // But first, if this is not a broadcast to all users, then 13506 // make sure it doesn't conflict with an existing broadcast to 13507 // all users. 13508 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get( 13509 UserHandle.USER_ALL); 13510 if (stickies != null) { 13511 ArrayList<Intent> list = stickies.get(intent.getAction()); 13512 if (list != null) { 13513 int N = list.size(); 13514 int i; 13515 for (i=0; i<N; i++) { 13516 if (intent.filterEquals(list.get(i))) { 13517 throw new IllegalArgumentException( 13518 "Sticky broadcast " + intent + " for user " 13519 + userId + " conflicts with existing global broadcast"); 13520 } 13521 } 13522 } 13523 } 13524 } 13525 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 13526 if (stickies == null) { 13527 stickies = new ArrayMap<String, ArrayList<Intent>>(); 13528 mStickyBroadcasts.put(userId, stickies); 13529 } 13530 ArrayList<Intent> list = stickies.get(intent.getAction()); 13531 if (list == null) { 13532 list = new ArrayList<Intent>(); 13533 stickies.put(intent.getAction(), list); 13534 } 13535 int N = list.size(); 13536 int i; 13537 for (i=0; i<N; i++) { 13538 if (intent.filterEquals(list.get(i))) { 13539 // This sticky already exists, replace it. 13540 list.set(i, new Intent(intent)); 13541 break; 13542 } 13543 } 13544 if (i >= N) { 13545 list.add(new Intent(intent)); 13546 } 13547 } 13548 13549 int[] users; 13550 if (userId == UserHandle.USER_ALL) { 13551 // Caller wants broadcast to go to all started users. 13552 users = mStartedUserArray; 13553 } else { 13554 // Caller wants broadcast to go to one specific user. 13555 users = new int[] {userId}; 13556 } 13557 13558 // Figure out who all will receive this broadcast. 13559 List receivers = null; 13560 List<BroadcastFilter> registeredReceivers = null; 13561 // Need to resolve the intent to interested receivers... 13562 if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) 13563 == 0) { 13564 receivers = collectReceiverComponents(intent, resolvedType, users); 13565 } 13566 if (intent.getComponent() == null) { 13567 registeredReceivers = mReceiverResolver.queryIntent(intent, 13568 resolvedType, false, userId); 13569 } 13570 13571 final boolean replacePending = 13572 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0; 13573 13574 if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction() 13575 + " replacePending=" + replacePending); 13576 13577 int NR = registeredReceivers != null ? registeredReceivers.size() : 0; 13578 if (!ordered && NR > 0) { 13579 // If we are not serializing this broadcast, then send the 13580 // registered receivers separately so they don't wait for the 13581 // components to be launched. 13582 final BroadcastQueue queue = broadcastQueueForIntent(intent); 13583 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 13584 callerPackage, callingPid, callingUid, resolvedType, requiredPermission, 13585 appOp, registeredReceivers, resultTo, resultCode, resultData, map, 13586 ordered, sticky, false, userId); 13587 if (DEBUG_BROADCAST) Slog.v( 13588 TAG, "Enqueueing parallel broadcast " + r); 13589 final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r); 13590 if (!replaced) { 13591 queue.enqueueParallelBroadcastLocked(r); 13592 queue.scheduleBroadcastsLocked(); 13593 } 13594 registeredReceivers = null; 13595 NR = 0; 13596 } 13597 13598 // Merge into one list. 13599 int ir = 0; 13600 if (receivers != null) { 13601 // A special case for PACKAGE_ADDED: do not allow the package 13602 // being added to see this broadcast. This prevents them from 13603 // using this as a back door to get run as soon as they are 13604 // installed. Maybe in the future we want to have a special install 13605 // broadcast or such for apps, but we'd like to deliberately make 13606 // this decision. 13607 String skipPackages[] = null; 13608 if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction()) 13609 || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction()) 13610 || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) { 13611 Uri data = intent.getData(); 13612 if (data != null) { 13613 String pkgName = data.getSchemeSpecificPart(); 13614 if (pkgName != null) { 13615 skipPackages = new String[] { pkgName }; 13616 } 13617 } 13618 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) { 13619 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 13620 } 13621 if (skipPackages != null && (skipPackages.length > 0)) { 13622 for (String skipPackage : skipPackages) { 13623 if (skipPackage != null) { 13624 int NT = receivers.size(); 13625 for (int it=0; it<NT; it++) { 13626 ResolveInfo curt = (ResolveInfo)receivers.get(it); 13627 if (curt.activityInfo.packageName.equals(skipPackage)) { 13628 receivers.remove(it); 13629 it--; 13630 NT--; 13631 } 13632 } 13633 } 13634 } 13635 } 13636 13637 int NT = receivers != null ? receivers.size() : 0; 13638 int it = 0; 13639 ResolveInfo curt = null; 13640 BroadcastFilter curr = null; 13641 while (it < NT && ir < NR) { 13642 if (curt == null) { 13643 curt = (ResolveInfo)receivers.get(it); 13644 } 13645 if (curr == null) { 13646 curr = registeredReceivers.get(ir); 13647 } 13648 if (curr.getPriority() >= curt.priority) { 13649 // Insert this broadcast record into the final list. 13650 receivers.add(it, curr); 13651 ir++; 13652 curr = null; 13653 it++; 13654 NT++; 13655 } else { 13656 // Skip to the next ResolveInfo in the final list. 13657 it++; 13658 curt = null; 13659 } 13660 } 13661 } 13662 while (ir < NR) { 13663 if (receivers == null) { 13664 receivers = new ArrayList(); 13665 } 13666 receivers.add(registeredReceivers.get(ir)); 13667 ir++; 13668 } 13669 13670 if ((receivers != null && receivers.size() > 0) 13671 || resultTo != null) { 13672 BroadcastQueue queue = broadcastQueueForIntent(intent); 13673 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 13674 callerPackage, callingPid, callingUid, resolvedType, 13675 requiredPermission, appOp, receivers, resultTo, resultCode, 13676 resultData, map, ordered, sticky, false, userId); 13677 if (DEBUG_BROADCAST) Slog.v( 13678 TAG, "Enqueueing ordered broadcast " + r 13679 + ": prev had " + queue.mOrderedBroadcasts.size()); 13680 if (DEBUG_BROADCAST) { 13681 int seq = r.intent.getIntExtra("seq", -1); 13682 Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq); 13683 } 13684 boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r); 13685 if (!replaced) { 13686 queue.enqueueOrderedBroadcastLocked(r); 13687 queue.scheduleBroadcastsLocked(); 13688 } 13689 } 13690 13691 return ActivityManager.BROADCAST_SUCCESS; 13692 } 13693 13694 final Intent verifyBroadcastLocked(Intent intent) { 13695 // Refuse possible leaked file descriptors 13696 if (intent != null && intent.hasFileDescriptors() == true) { 13697 throw new IllegalArgumentException("File descriptors passed in Intent"); 13698 } 13699 13700 int flags = intent.getFlags(); 13701 13702 if (!mProcessesReady) { 13703 // if the caller really truly claims to know what they're doing, go 13704 // ahead and allow the broadcast without launching any receivers 13705 if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) { 13706 intent = new Intent(intent); 13707 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 13708 } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) { 13709 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent 13710 + " before boot completion"); 13711 throw new IllegalStateException("Cannot broadcast before boot completed"); 13712 } 13713 } 13714 13715 if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 13716 throw new IllegalArgumentException( 13717 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 13718 } 13719 13720 return intent; 13721 } 13722 13723 public final int broadcastIntent(IApplicationThread caller, 13724 Intent intent, String resolvedType, IIntentReceiver resultTo, 13725 int resultCode, String resultData, Bundle map, 13726 String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) { 13727 enforceNotIsolatedCaller("broadcastIntent"); 13728 synchronized(this) { 13729 intent = verifyBroadcastLocked(intent); 13730 13731 final ProcessRecord callerApp = getRecordForAppLocked(caller); 13732 final int callingPid = Binder.getCallingPid(); 13733 final int callingUid = Binder.getCallingUid(); 13734 final long origId = Binder.clearCallingIdentity(); 13735 int res = broadcastIntentLocked(callerApp, 13736 callerApp != null ? callerApp.info.packageName : null, 13737 intent, resolvedType, resultTo, 13738 resultCode, resultData, map, requiredPermission, appOp, serialized, sticky, 13739 callingPid, callingUid, userId); 13740 Binder.restoreCallingIdentity(origId); 13741 return res; 13742 } 13743 } 13744 13745 int broadcastIntentInPackage(String packageName, int uid, 13746 Intent intent, String resolvedType, IIntentReceiver resultTo, 13747 int resultCode, String resultData, Bundle map, 13748 String requiredPermission, boolean serialized, boolean sticky, int userId) { 13749 synchronized(this) { 13750 intent = verifyBroadcastLocked(intent); 13751 13752 final long origId = Binder.clearCallingIdentity(); 13753 int res = broadcastIntentLocked(null, packageName, intent, resolvedType, 13754 resultTo, resultCode, resultData, map, requiredPermission, 13755 AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId); 13756 Binder.restoreCallingIdentity(origId); 13757 return res; 13758 } 13759 } 13760 13761 public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) { 13762 // Refuse possible leaked file descriptors 13763 if (intent != null && intent.hasFileDescriptors() == true) { 13764 throw new IllegalArgumentException("File descriptors passed in Intent"); 13765 } 13766 13767 userId = handleIncomingUser(Binder.getCallingPid(), 13768 Binder.getCallingUid(), userId, true, false, "removeStickyBroadcast", null); 13769 13770 synchronized(this) { 13771 if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY) 13772 != PackageManager.PERMISSION_GRANTED) { 13773 String msg = "Permission Denial: unbroadcastIntent() from pid=" 13774 + Binder.getCallingPid() 13775 + ", uid=" + Binder.getCallingUid() 13776 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 13777 Slog.w(TAG, msg); 13778 throw new SecurityException(msg); 13779 } 13780 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 13781 if (stickies != null) { 13782 ArrayList<Intent> list = stickies.get(intent.getAction()); 13783 if (list != null) { 13784 int N = list.size(); 13785 int i; 13786 for (i=0; i<N; i++) { 13787 if (intent.filterEquals(list.get(i))) { 13788 list.remove(i); 13789 break; 13790 } 13791 } 13792 if (list.size() <= 0) { 13793 stickies.remove(intent.getAction()); 13794 } 13795 } 13796 if (stickies.size() <= 0) { 13797 mStickyBroadcasts.remove(userId); 13798 } 13799 } 13800 } 13801 } 13802 13803 private final boolean finishReceiverLocked(IBinder receiver, int resultCode, 13804 String resultData, Bundle resultExtras, boolean resultAbort) { 13805 final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver); 13806 if (r == null) { 13807 Slog.w(TAG, "finishReceiver called but not found on queue"); 13808 return false; 13809 } 13810 13811 return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false); 13812 } 13813 13814 void backgroundServicesFinishedLocked(int userId) { 13815 for (BroadcastQueue queue : mBroadcastQueues) { 13816 queue.backgroundServicesFinishedLocked(userId); 13817 } 13818 } 13819 13820 public void finishReceiver(IBinder who, int resultCode, String resultData, 13821 Bundle resultExtras, boolean resultAbort) { 13822 if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who); 13823 13824 // Refuse possible leaked file descriptors 13825 if (resultExtras != null && resultExtras.hasFileDescriptors()) { 13826 throw new IllegalArgumentException("File descriptors passed in Bundle"); 13827 } 13828 13829 final long origId = Binder.clearCallingIdentity(); 13830 try { 13831 boolean doNext = false; 13832 BroadcastRecord r; 13833 13834 synchronized(this) { 13835 r = broadcastRecordForReceiverLocked(who); 13836 if (r != null) { 13837 doNext = r.queue.finishReceiverLocked(r, resultCode, 13838 resultData, resultExtras, resultAbort, true); 13839 } 13840 } 13841 13842 if (doNext) { 13843 r.queue.processNextBroadcast(false); 13844 } 13845 trimApplications(); 13846 } finally { 13847 Binder.restoreCallingIdentity(origId); 13848 } 13849 } 13850 13851 // ========================================================= 13852 // INSTRUMENTATION 13853 // ========================================================= 13854 13855 public boolean startInstrumentation(ComponentName className, 13856 String profileFile, int flags, Bundle arguments, 13857 IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection, 13858 int userId) { 13859 enforceNotIsolatedCaller("startInstrumentation"); 13860 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 13861 userId, false, true, "startInstrumentation", null); 13862 // Refuse possible leaked file descriptors 13863 if (arguments != null && arguments.hasFileDescriptors()) { 13864 throw new IllegalArgumentException("File descriptors passed in Bundle"); 13865 } 13866 13867 synchronized(this) { 13868 InstrumentationInfo ii = null; 13869 ApplicationInfo ai = null; 13870 try { 13871 ii = mContext.getPackageManager().getInstrumentationInfo( 13872 className, STOCK_PM_FLAGS); 13873 ai = AppGlobals.getPackageManager().getApplicationInfo( 13874 ii.targetPackage, STOCK_PM_FLAGS, userId); 13875 } catch (PackageManager.NameNotFoundException e) { 13876 } catch (RemoteException e) { 13877 } 13878 if (ii == null) { 13879 reportStartInstrumentationFailure(watcher, className, 13880 "Unable to find instrumentation info for: " + className); 13881 return false; 13882 } 13883 if (ai == null) { 13884 reportStartInstrumentationFailure(watcher, className, 13885 "Unable to find instrumentation target package: " + ii.targetPackage); 13886 return false; 13887 } 13888 13889 int match = mContext.getPackageManager().checkSignatures( 13890 ii.targetPackage, ii.packageName); 13891 if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) { 13892 String msg = "Permission Denial: starting instrumentation " 13893 + className + " from pid=" 13894 + Binder.getCallingPid() 13895 + ", uid=" + Binder.getCallingPid() 13896 + " not allowed because package " + ii.packageName 13897 + " does not have a signature matching the target " 13898 + ii.targetPackage; 13899 reportStartInstrumentationFailure(watcher, className, msg); 13900 throw new SecurityException(msg); 13901 } 13902 13903 final long origId = Binder.clearCallingIdentity(); 13904 // Instrumentation can kill and relaunch even persistent processes 13905 forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId, 13906 "start instr"); 13907 ProcessRecord app = addAppLocked(ai, false); 13908 app.instrumentationClass = className; 13909 app.instrumentationInfo = ai; 13910 app.instrumentationProfileFile = profileFile; 13911 app.instrumentationArguments = arguments; 13912 app.instrumentationWatcher = watcher; 13913 app.instrumentationUiAutomationConnection = uiAutomationConnection; 13914 app.instrumentationResultClass = className; 13915 Binder.restoreCallingIdentity(origId); 13916 } 13917 13918 return true; 13919 } 13920 13921 /** 13922 * Report errors that occur while attempting to start Instrumentation. Always writes the 13923 * error to the logs, but if somebody is watching, send the report there too. This enables 13924 * the "am" command to report errors with more information. 13925 * 13926 * @param watcher The IInstrumentationWatcher. Null if there isn't one. 13927 * @param cn The component name of the instrumentation. 13928 * @param report The error report. 13929 */ 13930 private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher, 13931 ComponentName cn, String report) { 13932 Slog.w(TAG, report); 13933 try { 13934 if (watcher != null) { 13935 Bundle results = new Bundle(); 13936 results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService"); 13937 results.putString("Error", report); 13938 watcher.instrumentationStatus(cn, -1, results); 13939 } 13940 } catch (RemoteException e) { 13941 Slog.w(TAG, e); 13942 } 13943 } 13944 13945 void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) { 13946 if (app.instrumentationWatcher != null) { 13947 try { 13948 // NOTE: IInstrumentationWatcher *must* be oneway here 13949 app.instrumentationWatcher.instrumentationFinished( 13950 app.instrumentationClass, 13951 resultCode, 13952 results); 13953 } catch (RemoteException e) { 13954 } 13955 } 13956 if (app.instrumentationUiAutomationConnection != null) { 13957 try { 13958 app.instrumentationUiAutomationConnection.shutdown(); 13959 } catch (RemoteException re) { 13960 /* ignore */ 13961 } 13962 // Only a UiAutomation can set this flag and now that 13963 // it is finished we make sure it is reset to its default. 13964 mUserIsMonkey = false; 13965 } 13966 app.instrumentationWatcher = null; 13967 app.instrumentationUiAutomationConnection = null; 13968 app.instrumentationClass = null; 13969 app.instrumentationInfo = null; 13970 app.instrumentationProfileFile = null; 13971 app.instrumentationArguments = null; 13972 13973 forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId, 13974 "finished inst"); 13975 } 13976 13977 public void finishInstrumentation(IApplicationThread target, 13978 int resultCode, Bundle results) { 13979 int userId = UserHandle.getCallingUserId(); 13980 // Refuse possible leaked file descriptors 13981 if (results != null && results.hasFileDescriptors()) { 13982 throw new IllegalArgumentException("File descriptors passed in Intent"); 13983 } 13984 13985 synchronized(this) { 13986 ProcessRecord app = getRecordForAppLocked(target); 13987 if (app == null) { 13988 Slog.w(TAG, "finishInstrumentation: no app for " + target); 13989 return; 13990 } 13991 final long origId = Binder.clearCallingIdentity(); 13992 finishInstrumentationLocked(app, resultCode, results); 13993 Binder.restoreCallingIdentity(origId); 13994 } 13995 } 13996 13997 // ========================================================= 13998 // CONFIGURATION 13999 // ========================================================= 14000 14001 public ConfigurationInfo getDeviceConfigurationInfo() { 14002 ConfigurationInfo config = new ConfigurationInfo(); 14003 synchronized (this) { 14004 config.reqTouchScreen = mConfiguration.touchscreen; 14005 config.reqKeyboardType = mConfiguration.keyboard; 14006 config.reqNavigation = mConfiguration.navigation; 14007 if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD 14008 || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) { 14009 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV; 14010 } 14011 if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED 14012 && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) { 14013 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD; 14014 } 14015 config.reqGlEsVersion = GL_ES_VERSION; 14016 } 14017 return config; 14018 } 14019 14020 ActivityStack getFocusedStack() { 14021 return mStackSupervisor.getFocusedStack(); 14022 } 14023 14024 public Configuration getConfiguration() { 14025 Configuration ci; 14026 synchronized(this) { 14027 ci = new Configuration(mConfiguration); 14028 } 14029 return ci; 14030 } 14031 14032 public void updatePersistentConfiguration(Configuration values) { 14033 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 14034 "updateConfiguration()"); 14035 enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS, 14036 "updateConfiguration()"); 14037 if (values == null) { 14038 throw new NullPointerException("Configuration must not be null"); 14039 } 14040 14041 synchronized(this) { 14042 final long origId = Binder.clearCallingIdentity(); 14043 updateConfigurationLocked(values, null, true, false); 14044 Binder.restoreCallingIdentity(origId); 14045 } 14046 } 14047 14048 public void updateConfiguration(Configuration values) { 14049 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 14050 "updateConfiguration()"); 14051 14052 synchronized(this) { 14053 if (values == null && mWindowManager != null) { 14054 // sentinel: fetch the current configuration from the window manager 14055 values = mWindowManager.computeNewConfiguration(); 14056 } 14057 14058 if (mWindowManager != null) { 14059 mProcessList.applyDisplaySize(mWindowManager); 14060 } 14061 14062 final long origId = Binder.clearCallingIdentity(); 14063 if (values != null) { 14064 Settings.System.clearConfiguration(values); 14065 } 14066 updateConfigurationLocked(values, null, false, false); 14067 Binder.restoreCallingIdentity(origId); 14068 } 14069 } 14070 14071 /** 14072 * Do either or both things: (1) change the current configuration, and (2) 14073 * make sure the given activity is running with the (now) current 14074 * configuration. Returns true if the activity has been left running, or 14075 * false if <var>starting</var> is being destroyed to match the new 14076 * configuration. 14077 * @param persistent TODO 14078 */ 14079 boolean updateConfigurationLocked(Configuration values, 14080 ActivityRecord starting, boolean persistent, boolean initLocale) { 14081 int changes = 0; 14082 14083 if (values != null) { 14084 Configuration newConfig = new Configuration(mConfiguration); 14085 changes = newConfig.updateFrom(values); 14086 if (changes != 0) { 14087 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) { 14088 Slog.i(TAG, "Updating configuration to: " + values); 14089 } 14090 14091 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes); 14092 14093 if (values.locale != null && !initLocale) { 14094 saveLocaleLocked(values.locale, 14095 !values.locale.equals(mConfiguration.locale), 14096 values.userSetLocale); 14097 } 14098 14099 mConfigurationSeq++; 14100 if (mConfigurationSeq <= 0) { 14101 mConfigurationSeq = 1; 14102 } 14103 newConfig.seq = mConfigurationSeq; 14104 mConfiguration = newConfig; 14105 Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig); 14106 14107 final Configuration configCopy = new Configuration(mConfiguration); 14108 14109 // TODO: If our config changes, should we auto dismiss any currently 14110 // showing dialogs? 14111 mShowDialogs = shouldShowDialogs(newConfig); 14112 14113 AttributeCache ac = AttributeCache.instance(); 14114 if (ac != null) { 14115 ac.updateConfiguration(configCopy); 14116 } 14117 14118 // Make sure all resources in our process are updated 14119 // right now, so that anyone who is going to retrieve 14120 // resource values after we return will be sure to get 14121 // the new ones. This is especially important during 14122 // boot, where the first config change needs to guarantee 14123 // all resources have that config before following boot 14124 // code is executed. 14125 mSystemThread.applyConfigurationToResources(configCopy); 14126 14127 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) { 14128 Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG); 14129 msg.obj = new Configuration(configCopy); 14130 mHandler.sendMessage(msg); 14131 } 14132 14133 for (int i=mLruProcesses.size()-1; i>=0; i--) { 14134 ProcessRecord app = mLruProcesses.get(i); 14135 try { 14136 if (app.thread != null) { 14137 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc " 14138 + app.processName + " new config " + mConfiguration); 14139 app.thread.scheduleConfigurationChanged(configCopy); 14140 } 14141 } catch (Exception e) { 14142 } 14143 } 14144 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED); 14145 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 14146 | Intent.FLAG_RECEIVER_REPLACE_PENDING 14147 | Intent.FLAG_RECEIVER_FOREGROUND); 14148 broadcastIntentLocked(null, null, intent, null, null, 0, null, null, 14149 null, AppOpsManager.OP_NONE, false, false, MY_PID, 14150 Process.SYSTEM_UID, UserHandle.USER_ALL); 14151 if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) { 14152 intent = new Intent(Intent.ACTION_LOCALE_CHANGED); 14153 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 14154 broadcastIntentLocked(null, null, intent, 14155 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 14156 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 14157 } 14158 } 14159 } 14160 14161 boolean kept = true; 14162 final ActivityStack mainStack = mStackSupervisor.getFocusedStack(); 14163 // mainStack is null during startup. 14164 if (mainStack != null) { 14165 if (changes != 0 && starting == null) { 14166 // If the configuration changed, and the caller is not already 14167 // in the process of starting an activity, then find the top 14168 // activity to check if its configuration needs to change. 14169 starting = mainStack.topRunningActivityLocked(null); 14170 } 14171 14172 if (starting != null) { 14173 kept = mainStack.ensureActivityConfigurationLocked(starting, changes); 14174 // And we need to make sure at this point that all other activities 14175 // are made visible with the correct configuration. 14176 mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes); 14177 } 14178 } 14179 14180 if (values != null && mWindowManager != null) { 14181 mWindowManager.setNewConfiguration(mConfiguration); 14182 } 14183 14184 return kept; 14185 } 14186 14187 /** 14188 * Decide based on the configuration whether we should shouw the ANR, 14189 * crash, etc dialogs. The idea is that if there is no affordnace to 14190 * press the on-screen buttons, we shouldn't show the dialog. 14191 * 14192 * A thought: SystemUI might also want to get told about this, the Power 14193 * dialog / global actions also might want different behaviors. 14194 */ 14195 private static final boolean shouldShowDialogs(Configuration config) { 14196 return !(config.keyboard == Configuration.KEYBOARD_NOKEYS 14197 && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH); 14198 } 14199 14200 /** 14201 * Save the locale. You must be inside a synchronized (this) block. 14202 */ 14203 private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) { 14204 if(isDiff) { 14205 SystemProperties.set("user.language", l.getLanguage()); 14206 SystemProperties.set("user.region", l.getCountry()); 14207 } 14208 14209 if(isPersist) { 14210 SystemProperties.set("persist.sys.language", l.getLanguage()); 14211 SystemProperties.set("persist.sys.country", l.getCountry()); 14212 SystemProperties.set("persist.sys.localevar", l.getVariant()); 14213 } 14214 } 14215 14216 @Override 14217 public boolean targetTaskAffinityMatchesActivity(IBinder token, String destAffinity) { 14218 ActivityRecord srec = ActivityRecord.forToken(token); 14219 return srec != null && srec.task.affinity != null && 14220 srec.task.affinity.equals(destAffinity); 14221 } 14222 14223 public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode, 14224 Intent resultData) { 14225 14226 synchronized (this) { 14227 final ActivityStack stack = ActivityRecord.getStackLocked(token); 14228 if (stack != null) { 14229 return stack.navigateUpToLocked(token, destIntent, resultCode, resultData); 14230 } 14231 return false; 14232 } 14233 } 14234 14235 public int getLaunchedFromUid(IBinder activityToken) { 14236 ActivityRecord srec = ActivityRecord.forToken(activityToken); 14237 if (srec == null) { 14238 return -1; 14239 } 14240 return srec.launchedFromUid; 14241 } 14242 14243 public String getLaunchedFromPackage(IBinder activityToken) { 14244 ActivityRecord srec = ActivityRecord.forToken(activityToken); 14245 if (srec == null) { 14246 return null; 14247 } 14248 return srec.launchedFromPackage; 14249 } 14250 14251 // ========================================================= 14252 // LIFETIME MANAGEMENT 14253 // ========================================================= 14254 14255 // Returns which broadcast queue the app is the current [or imminent] receiver 14256 // on, or 'null' if the app is not an active broadcast recipient. 14257 private BroadcastQueue isReceivingBroadcast(ProcessRecord app) { 14258 BroadcastRecord r = app.curReceiver; 14259 if (r != null) { 14260 return r.queue; 14261 } 14262 14263 // It's not the current receiver, but it might be starting up to become one 14264 synchronized (this) { 14265 for (BroadcastQueue queue : mBroadcastQueues) { 14266 r = queue.mPendingBroadcast; 14267 if (r != null && r.curApp == app) { 14268 // found it; report which queue it's in 14269 return queue; 14270 } 14271 } 14272 } 14273 14274 return null; 14275 } 14276 14277 private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP, 14278 boolean doingAll, long now) { 14279 if (mAdjSeq == app.adjSeq) { 14280 // This adjustment has already been computed. 14281 return app.curRawAdj; 14282 } 14283 14284 if (app.thread == null) { 14285 app.adjSeq = mAdjSeq; 14286 app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 14287 app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 14288 return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ); 14289 } 14290 14291 app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN; 14292 app.adjSource = null; 14293 app.adjTarget = null; 14294 app.empty = false; 14295 app.cached = false; 14296 14297 final int activitiesSize = app.activities.size(); 14298 14299 if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) { 14300 // The max adjustment doesn't allow this app to be anything 14301 // below foreground, so it is not worth doing work for it. 14302 app.adjType = "fixed"; 14303 app.adjSeq = mAdjSeq; 14304 app.curRawAdj = app.maxAdj; 14305 app.foregroundActivities = false; 14306 app.keeping = true; 14307 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT; 14308 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT; 14309 // System process can do UI, and when they do we want to have 14310 // them trim their memory after the user leaves the UI. To 14311 // facilitate this, here we need to determine whether or not it 14312 // is currently showing UI. 14313 app.systemNoUi = true; 14314 if (app == TOP_APP) { 14315 app.systemNoUi = false; 14316 } else if (activitiesSize > 0) { 14317 for (int j = 0; j < activitiesSize; j++) { 14318 final ActivityRecord r = app.activities.get(j); 14319 if (r.visible) { 14320 app.systemNoUi = false; 14321 } 14322 } 14323 } 14324 if (!app.systemNoUi) { 14325 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI; 14326 } 14327 return (app.curAdj=app.maxAdj); 14328 } 14329 14330 app.keeping = false; 14331 app.systemNoUi = false; 14332 14333 // Determine the importance of the process, starting with most 14334 // important to least, and assign an appropriate OOM adjustment. 14335 int adj; 14336 int schedGroup; 14337 int procState; 14338 boolean foregroundActivities = false; 14339 boolean interesting = false; 14340 BroadcastQueue queue; 14341 if (app == TOP_APP) { 14342 // The last app on the list is the foreground app. 14343 adj = ProcessList.FOREGROUND_APP_ADJ; 14344 schedGroup = Process.THREAD_GROUP_DEFAULT; 14345 app.adjType = "top-activity"; 14346 foregroundActivities = true; 14347 interesting = true; 14348 procState = ActivityManager.PROCESS_STATE_TOP; 14349 } else if (app.instrumentationClass != null) { 14350 // Don't want to kill running instrumentation. 14351 adj = ProcessList.FOREGROUND_APP_ADJ; 14352 schedGroup = Process.THREAD_GROUP_DEFAULT; 14353 app.adjType = "instrumentation"; 14354 interesting = true; 14355 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14356 } else if ((queue = isReceivingBroadcast(app)) != null) { 14357 // An app that is currently receiving a broadcast also 14358 // counts as being in the foreground for OOM killer purposes. 14359 // It's placed in a sched group based on the nature of the 14360 // broadcast as reflected by which queue it's active in. 14361 adj = ProcessList.FOREGROUND_APP_ADJ; 14362 schedGroup = (queue == mFgBroadcastQueue) 14363 ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 14364 app.adjType = "broadcast"; 14365 procState = ActivityManager.PROCESS_STATE_RECEIVER; 14366 } else if (app.executingServices.size() > 0) { 14367 // An app that is currently executing a service callback also 14368 // counts as being in the foreground. 14369 adj = ProcessList.FOREGROUND_APP_ADJ; 14370 schedGroup = app.execServicesFg ? 14371 Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 14372 app.adjType = "exec-service"; 14373 procState = ActivityManager.PROCESS_STATE_SERVICE; 14374 //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app); 14375 } else { 14376 // As far as we know the process is empty. We may change our mind later. 14377 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 14378 // At this point we don't actually know the adjustment. Use the cached adj 14379 // value that the caller wants us to. 14380 adj = cachedAdj; 14381 procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 14382 app.cached = true; 14383 app.empty = true; 14384 app.adjType = "cch-empty"; 14385 } 14386 14387 // Examine all activities if not already foreground. 14388 if (!foregroundActivities && activitiesSize > 0) { 14389 for (int j = 0; j < activitiesSize; j++) { 14390 final ActivityRecord r = app.activities.get(j); 14391 if (r.app != app) { 14392 Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc " 14393 + app + "?!?"); 14394 continue; 14395 } 14396 if (r.visible) { 14397 // App has a visible activity; only upgrade adjustment. 14398 if (adj > ProcessList.VISIBLE_APP_ADJ) { 14399 adj = ProcessList.VISIBLE_APP_ADJ; 14400 app.adjType = "visible"; 14401 } 14402 if (procState > ActivityManager.PROCESS_STATE_TOP) { 14403 procState = ActivityManager.PROCESS_STATE_TOP; 14404 } 14405 schedGroup = Process.THREAD_GROUP_DEFAULT; 14406 app.cached = false; 14407 app.empty = false; 14408 foregroundActivities = true; 14409 break; 14410 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) { 14411 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14412 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 14413 app.adjType = "pausing"; 14414 } 14415 if (procState > ActivityManager.PROCESS_STATE_TOP) { 14416 procState = ActivityManager.PROCESS_STATE_TOP; 14417 } 14418 schedGroup = Process.THREAD_GROUP_DEFAULT; 14419 app.cached = false; 14420 app.empty = false; 14421 foregroundActivities = true; 14422 } else if (r.state == ActivityState.STOPPING) { 14423 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14424 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 14425 app.adjType = "stopping"; 14426 } 14427 // For the process state, we will at this point consider the 14428 // process to be cached. It will be cached either as an activity 14429 // or empty depending on whether the activity is finishing. We do 14430 // this so that we can treat the process as cached for purposes of 14431 // memory trimming (determing current memory level, trim command to 14432 // send to process) since there can be an arbitrary number of stopping 14433 // processes and they should soon all go into the cached state. 14434 if (!r.finishing) { 14435 if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 14436 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 14437 } 14438 } 14439 app.cached = false; 14440 app.empty = false; 14441 foregroundActivities = true; 14442 } else { 14443 if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 14444 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 14445 app.adjType = "cch-act"; 14446 } 14447 } 14448 } 14449 } 14450 14451 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14452 if (app.foregroundServices) { 14453 // The user is aware of this app, so make it visible. 14454 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 14455 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14456 app.cached = false; 14457 app.adjType = "fg-service"; 14458 schedGroup = Process.THREAD_GROUP_DEFAULT; 14459 } else if (app.forcingToForeground != null) { 14460 // The user is aware of this app, so make it visible. 14461 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 14462 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14463 app.cached = false; 14464 app.adjType = "force-fg"; 14465 app.adjSource = app.forcingToForeground; 14466 schedGroup = Process.THREAD_GROUP_DEFAULT; 14467 } 14468 } 14469 14470 if (app.foregroundServices) { 14471 interesting = true; 14472 } 14473 14474 if (app == mHeavyWeightProcess) { 14475 if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) { 14476 // We don't want to kill the current heavy-weight process. 14477 adj = ProcessList.HEAVY_WEIGHT_APP_ADJ; 14478 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 14479 app.cached = false; 14480 app.adjType = "heavy"; 14481 } 14482 if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) { 14483 procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT; 14484 } 14485 } 14486 14487 if (app == mHomeProcess) { 14488 if (adj > ProcessList.HOME_APP_ADJ) { 14489 // This process is hosting what we currently consider to be the 14490 // home app, so we don't want to let it go into the background. 14491 adj = ProcessList.HOME_APP_ADJ; 14492 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 14493 app.cached = false; 14494 app.adjType = "home"; 14495 } 14496 if (procState > ActivityManager.PROCESS_STATE_HOME) { 14497 procState = ActivityManager.PROCESS_STATE_HOME; 14498 } 14499 } 14500 14501 if (app == mPreviousProcess && app.activities.size() > 0) { 14502 if (adj > ProcessList.PREVIOUS_APP_ADJ) { 14503 // This was the previous process that showed UI to the user. 14504 // We want to try to keep it around more aggressively, to give 14505 // a good experience around switching between two apps. 14506 adj = ProcessList.PREVIOUS_APP_ADJ; 14507 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 14508 app.cached = false; 14509 app.adjType = "previous"; 14510 } 14511 if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) { 14512 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY; 14513 } 14514 } 14515 14516 if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj 14517 + " reason=" + app.adjType); 14518 14519 // By default, we use the computed adjustment. It may be changed if 14520 // there are applications dependent on our services or providers, but 14521 // this gives us a baseline and makes sure we don't get into an 14522 // infinite recursion. 14523 app.adjSeq = mAdjSeq; 14524 app.curRawAdj = adj; 14525 app.hasStartedServices = false; 14526 14527 if (mBackupTarget != null && app == mBackupTarget.app) { 14528 // If possible we want to avoid killing apps while they're being backed up 14529 if (adj > ProcessList.BACKUP_APP_ADJ) { 14530 if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app); 14531 adj = ProcessList.BACKUP_APP_ADJ; 14532 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) { 14533 procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND; 14534 } 14535 app.adjType = "backup"; 14536 app.cached = false; 14537 } 14538 if (procState > ActivityManager.PROCESS_STATE_BACKUP) { 14539 procState = ActivityManager.PROCESS_STATE_BACKUP; 14540 } 14541 } 14542 14543 boolean mayBeTop = false; 14544 14545 for (int is = app.services.size()-1; 14546 is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 14547 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 14548 || procState > ActivityManager.PROCESS_STATE_TOP); 14549 is--) { 14550 ServiceRecord s = app.services.valueAt(is); 14551 if (s.startRequested) { 14552 app.hasStartedServices = true; 14553 if (procState > ActivityManager.PROCESS_STATE_SERVICE) { 14554 procState = ActivityManager.PROCESS_STATE_SERVICE; 14555 } 14556 if (app.hasShownUi && app != mHomeProcess) { 14557 // If this process has shown some UI, let it immediately 14558 // go to the LRU list because it may be pretty heavy with 14559 // UI stuff. We'll tag it with a label just to help 14560 // debug and understand what is going on. 14561 if (adj > ProcessList.SERVICE_ADJ) { 14562 app.adjType = "cch-started-ui-services"; 14563 } 14564 } else { 14565 if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) { 14566 // This service has seen some activity within 14567 // recent memory, so we will keep its process ahead 14568 // of the background processes. 14569 if (adj > ProcessList.SERVICE_ADJ) { 14570 adj = ProcessList.SERVICE_ADJ; 14571 app.adjType = "started-services"; 14572 app.cached = false; 14573 } 14574 } 14575 // If we have let the service slide into the background 14576 // state, still have some text describing what it is doing 14577 // even though the service no longer has an impact. 14578 if (adj > ProcessList.SERVICE_ADJ) { 14579 app.adjType = "cch-started-services"; 14580 } 14581 } 14582 // Don't kill this process because it is doing work; it 14583 // has said it is doing work. 14584 app.keeping = true; 14585 } 14586 for (int conni = s.connections.size()-1; 14587 conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 14588 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 14589 || procState > ActivityManager.PROCESS_STATE_TOP); 14590 conni--) { 14591 ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni); 14592 for (int i = 0; 14593 i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ 14594 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 14595 || procState > ActivityManager.PROCESS_STATE_TOP); 14596 i++) { 14597 // XXX should compute this based on the max of 14598 // all connected clients. 14599 ConnectionRecord cr = clist.get(i); 14600 if (cr.binding.client == app) { 14601 // Binding to ourself is not interesting. 14602 continue; 14603 } 14604 if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) { 14605 ProcessRecord client = cr.binding.client; 14606 int clientAdj = computeOomAdjLocked(client, cachedAdj, 14607 TOP_APP, doingAll, now); 14608 int clientProcState = client.curProcState; 14609 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 14610 // If the other app is cached for any reason, for purposes here 14611 // we are going to consider it empty. The specific cached state 14612 // doesn't propagate except under certain conditions. 14613 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 14614 } 14615 String adjType = null; 14616 if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) { 14617 // Not doing bind OOM management, so treat 14618 // this guy more like a started service. 14619 if (app.hasShownUi && app != mHomeProcess) { 14620 // If this process has shown some UI, let it immediately 14621 // go to the LRU list because it may be pretty heavy with 14622 // UI stuff. We'll tag it with a label just to help 14623 // debug and understand what is going on. 14624 if (adj > clientAdj) { 14625 adjType = "cch-bound-ui-services"; 14626 } 14627 app.cached = false; 14628 clientAdj = adj; 14629 clientProcState = procState; 14630 } else { 14631 if (now >= (s.lastActivity 14632 + ActiveServices.MAX_SERVICE_INACTIVITY)) { 14633 // This service has not seen activity within 14634 // recent memory, so allow it to drop to the 14635 // LRU list if there is no other reason to keep 14636 // it around. We'll also tag it with a label just 14637 // to help debug and undertand what is going on. 14638 if (adj > clientAdj) { 14639 adjType = "cch-bound-services"; 14640 } 14641 clientAdj = adj; 14642 } 14643 } 14644 } 14645 if (adj > clientAdj) { 14646 // If this process has recently shown UI, and 14647 // the process that is binding to it is less 14648 // important than being visible, then we don't 14649 // care about the binding as much as we care 14650 // about letting this process get into the LRU 14651 // list to be killed and restarted if needed for 14652 // memory. 14653 if (app.hasShownUi && app != mHomeProcess 14654 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14655 adjType = "cch-bound-ui-services"; 14656 } else { 14657 if ((cr.flags&(Context.BIND_ABOVE_CLIENT 14658 |Context.BIND_IMPORTANT)) != 0) { 14659 adj = clientAdj; 14660 } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0 14661 && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ 14662 && adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14663 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 14664 } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) { 14665 adj = clientAdj; 14666 } else { 14667 if (adj > ProcessList.VISIBLE_APP_ADJ) { 14668 adj = ProcessList.VISIBLE_APP_ADJ; 14669 } 14670 } 14671 if (!client.cached) { 14672 app.cached = false; 14673 } 14674 if (client.keeping) { 14675 app.keeping = true; 14676 } 14677 adjType = "service"; 14678 } 14679 } 14680 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 14681 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 14682 schedGroup = Process.THREAD_GROUP_DEFAULT; 14683 } 14684 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) { 14685 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) { 14686 // Special handling of clients who are in the top state. 14687 // We *may* want to consider this process to be in the 14688 // top state as well, but only if there is not another 14689 // reason for it to be running. Being on the top is a 14690 // special state, meaning you are specifically running 14691 // for the current top app. If the process is already 14692 // running in the background for some other reason, it 14693 // is more important to continue considering it to be 14694 // in the background state. 14695 mayBeTop = true; 14696 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 14697 } else { 14698 // Special handling for above-top states (persistent 14699 // processes). These should not bring the current process 14700 // into the top state, since they are not on top. Instead 14701 // give them the best state after that. 14702 clientProcState = 14703 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14704 } 14705 } 14706 } else { 14707 if (clientProcState < 14708 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) { 14709 clientProcState = 14710 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND; 14711 } 14712 } 14713 if (procState > clientProcState) { 14714 procState = clientProcState; 14715 } 14716 if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 14717 && (cr.flags&Context.BIND_SHOWING_UI) != 0) { 14718 app.pendingUiClean = true; 14719 } 14720 if (adjType != null) { 14721 app.adjType = adjType; 14722 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 14723 .REASON_SERVICE_IN_USE; 14724 app.adjSource = cr.binding.client; 14725 app.adjSourceOom = clientAdj; 14726 app.adjTarget = s.name; 14727 } 14728 } 14729 final ActivityRecord a = cr.activity; 14730 if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) { 14731 if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ && 14732 (a.visible || a.state == ActivityState.RESUMED 14733 || a.state == ActivityState.PAUSING)) { 14734 adj = ProcessList.FOREGROUND_APP_ADJ; 14735 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 14736 schedGroup = Process.THREAD_GROUP_DEFAULT; 14737 } 14738 app.cached = false; 14739 app.adjType = "service"; 14740 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 14741 .REASON_SERVICE_IN_USE; 14742 app.adjSource = a; 14743 app.adjSourceOom = adj; 14744 app.adjTarget = s.name; 14745 } 14746 } 14747 } 14748 } 14749 } 14750 14751 for (int provi = app.pubProviders.size()-1; 14752 provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 14753 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 14754 || procState > ActivityManager.PROCESS_STATE_TOP); 14755 provi--) { 14756 ContentProviderRecord cpr = app.pubProviders.valueAt(provi); 14757 for (int i = cpr.connections.size()-1; 14758 i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 14759 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 14760 || procState > ActivityManager.PROCESS_STATE_TOP); 14761 i--) { 14762 ContentProviderConnection conn = cpr.connections.get(i); 14763 ProcessRecord client = conn.client; 14764 if (client == app) { 14765 // Being our own client is not interesting. 14766 continue; 14767 } 14768 int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now); 14769 int clientProcState = client.curProcState; 14770 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 14771 // If the other app is cached for any reason, for purposes here 14772 // we are going to consider it empty. 14773 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 14774 } 14775 if (adj > clientAdj) { 14776 if (app.hasShownUi && app != mHomeProcess 14777 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14778 app.adjType = "cch-ui-provider"; 14779 } else { 14780 adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ 14781 ? clientAdj : ProcessList.FOREGROUND_APP_ADJ; 14782 app.adjType = "provider"; 14783 } 14784 app.cached &= client.cached; 14785 app.keeping |= client.keeping; 14786 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 14787 .REASON_PROVIDER_IN_USE; 14788 app.adjSource = client; 14789 app.adjSourceOom = clientAdj; 14790 app.adjTarget = cpr.name; 14791 } 14792 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) { 14793 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) { 14794 // Special handling of clients who are in the top state. 14795 // We *may* want to consider this process to be in the 14796 // top state as well, but only if there is not another 14797 // reason for it to be running. Being on the top is a 14798 // special state, meaning you are specifically running 14799 // for the current top app. If the process is already 14800 // running in the background for some other reason, it 14801 // is more important to continue considering it to be 14802 // in the background state. 14803 mayBeTop = true; 14804 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 14805 } else { 14806 // Special handling for above-top states (persistent 14807 // processes). These should not bring the current process 14808 // into the top state, since they are not on top. Instead 14809 // give them the best state after that. 14810 clientProcState = 14811 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14812 } 14813 } 14814 if (procState > clientProcState) { 14815 procState = clientProcState; 14816 } 14817 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 14818 schedGroup = Process.THREAD_GROUP_DEFAULT; 14819 } 14820 } 14821 // If the provider has external (non-framework) process 14822 // dependencies, ensure that its adjustment is at least 14823 // FOREGROUND_APP_ADJ. 14824 if (cpr.hasExternalProcessHandles()) { 14825 if (adj > ProcessList.FOREGROUND_APP_ADJ) { 14826 adj = ProcessList.FOREGROUND_APP_ADJ; 14827 schedGroup = Process.THREAD_GROUP_DEFAULT; 14828 app.cached = false; 14829 app.keeping = true; 14830 app.adjType = "provider"; 14831 app.adjTarget = cpr.name; 14832 } 14833 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) { 14834 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14835 } 14836 } 14837 } 14838 14839 if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) { 14840 // A client of one of our services or providers is in the top state. We 14841 // *may* want to be in the top state, but not if we are already running in 14842 // the background for some other reason. For the decision here, we are going 14843 // to pick out a few specific states that we want to remain in when a client 14844 // is top (states that tend to be longer-term) and otherwise allow it to go 14845 // to the top state. 14846 switch (procState) { 14847 case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND: 14848 case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND: 14849 case ActivityManager.PROCESS_STATE_SERVICE: 14850 // These all are longer-term states, so pull them up to the top 14851 // of the background states, but not all the way to the top state. 14852 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14853 break; 14854 default: 14855 // Otherwise, top is a better choice, so take it. 14856 procState = ActivityManager.PROCESS_STATE_TOP; 14857 break; 14858 } 14859 } 14860 14861 if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY && app.hasClientActivities) { 14862 // This is a cached process, but with client activities. Mark it so. 14863 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT; 14864 app.adjType = "cch-client-act"; 14865 } 14866 14867 if (adj == ProcessList.SERVICE_ADJ) { 14868 if (doingAll) { 14869 app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3); 14870 mNewNumServiceProcs++; 14871 //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb); 14872 if (!app.serviceb) { 14873 // This service isn't far enough down on the LRU list to 14874 // normally be a B service, but if we are low on RAM and it 14875 // is large we want to force it down since we would prefer to 14876 // keep launcher over it. 14877 if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL 14878 && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) { 14879 app.serviceHighRam = true; 14880 app.serviceb = true; 14881 //Slog.i(TAG, "ADJ " + app + " high ram!"); 14882 } else { 14883 mNewNumAServiceProcs++; 14884 //Slog.i(TAG, "ADJ " + app + " not high ram!"); 14885 } 14886 } else { 14887 app.serviceHighRam = false; 14888 } 14889 } 14890 if (app.serviceb) { 14891 adj = ProcessList.SERVICE_B_ADJ; 14892 } 14893 } 14894 14895 app.curRawAdj = adj; 14896 14897 //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid + 14898 // " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj); 14899 if (adj > app.maxAdj) { 14900 adj = app.maxAdj; 14901 if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 14902 schedGroup = Process.THREAD_GROUP_DEFAULT; 14903 } 14904 } 14905 if (adj < ProcessList.CACHED_APP_MIN_ADJ) { 14906 app.keeping = true; 14907 } 14908 14909 // Do final modification to adj. Everything we do between here and applying 14910 // the final setAdj must be done in this function, because we will also use 14911 // it when computing the final cached adj later. Note that we don't need to 14912 // worry about this for max adj above, since max adj will always be used to 14913 // keep it out of the cached vaues. 14914 adj = app.modifyRawOomAdj(adj); 14915 14916 app.curProcState = procState; 14917 14918 int importance = app.memImportance; 14919 if (importance == 0 || adj != app.curAdj || schedGroup != app.curSchedGroup) { 14920 app.curAdj = adj; 14921 app.curSchedGroup = schedGroup; 14922 if (!interesting) { 14923 // For this reporting, if there is not something explicitly 14924 // interesting in this process then we will push it to the 14925 // background importance. 14926 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 14927 } else if (adj >= ProcessList.CACHED_APP_MIN_ADJ) { 14928 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 14929 } else if (adj >= ProcessList.SERVICE_B_ADJ) { 14930 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 14931 } else if (adj >= ProcessList.HOME_APP_ADJ) { 14932 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 14933 } else if (adj >= ProcessList.SERVICE_ADJ) { 14934 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 14935 } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 14936 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE; 14937 } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) { 14938 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE; 14939 } else if (adj >= ProcessList.VISIBLE_APP_ADJ) { 14940 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE; 14941 } else if (adj >= ProcessList.FOREGROUND_APP_ADJ) { 14942 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND; 14943 } else { 14944 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERSISTENT; 14945 } 14946 } 14947 14948 int changes = importance != app.memImportance ? ProcessChangeItem.CHANGE_IMPORTANCE : 0; 14949 if (foregroundActivities != app.foregroundActivities) { 14950 changes |= ProcessChangeItem.CHANGE_ACTIVITIES; 14951 } 14952 if (changes != 0) { 14953 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes); 14954 app.memImportance = importance; 14955 app.foregroundActivities = foregroundActivities; 14956 int i = mPendingProcessChanges.size()-1; 14957 ProcessChangeItem item = null; 14958 while (i >= 0) { 14959 item = mPendingProcessChanges.get(i); 14960 if (item.pid == app.pid) { 14961 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item); 14962 break; 14963 } 14964 i--; 14965 } 14966 if (i < 0) { 14967 // No existing item in pending changes; need a new one. 14968 final int NA = mAvailProcessChanges.size(); 14969 if (NA > 0) { 14970 item = mAvailProcessChanges.remove(NA-1); 14971 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item); 14972 } else { 14973 item = new ProcessChangeItem(); 14974 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item); 14975 } 14976 item.changes = 0; 14977 item.pid = app.pid; 14978 item.uid = app.info.uid; 14979 if (mPendingProcessChanges.size() == 0) { 14980 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, 14981 "*** Enqueueing dispatch processes changed!"); 14982 mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget(); 14983 } 14984 mPendingProcessChanges.add(item); 14985 } 14986 item.changes |= changes; 14987 item.importance = importance; 14988 item.foregroundActivities = foregroundActivities; 14989 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item " 14990 + Integer.toHexString(System.identityHashCode(item)) 14991 + " " + app.toShortString() + ": changes=" + item.changes 14992 + " importance=" + item.importance 14993 + " foreground=" + item.foregroundActivities 14994 + " type=" + app.adjType + " source=" + app.adjSource 14995 + " target=" + app.adjTarget); 14996 } 14997 14998 return app.curRawAdj; 14999 } 15000 15001 /** 15002 * Schedule PSS collection of a process. 15003 */ 15004 void requestPssLocked(ProcessRecord proc, int procState) { 15005 if (mPendingPssProcesses.contains(proc)) { 15006 return; 15007 } 15008 if (mPendingPssProcesses.size() == 0) { 15009 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG); 15010 } 15011 if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc); 15012 proc.pssProcState = procState; 15013 mPendingPssProcesses.add(proc); 15014 } 15015 15016 /** 15017 * Schedule PSS collection of all processes. 15018 */ 15019 void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) { 15020 if (!always) { 15021 if (now < (mLastFullPssTime + 15022 (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) { 15023 return; 15024 } 15025 } 15026 if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs! memLowered=" + memLowered); 15027 mLastFullPssTime = now; 15028 mPendingPssProcesses.ensureCapacity(mLruProcesses.size()); 15029 mPendingPssProcesses.clear(); 15030 for (int i=mLruProcesses.size()-1; i>=0; i--) { 15031 ProcessRecord app = mLruProcesses.get(i); 15032 if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) { 15033 app.pssProcState = app.setProcState; 15034 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true, 15035 mSleeping, now); 15036 mPendingPssProcesses.add(app); 15037 } 15038 } 15039 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG); 15040 } 15041 15042 /** 15043 * Ask a given process to GC right now. 15044 */ 15045 final void performAppGcLocked(ProcessRecord app) { 15046 try { 15047 app.lastRequestedGc = SystemClock.uptimeMillis(); 15048 if (app.thread != null) { 15049 if (app.reportLowMemory) { 15050 app.reportLowMemory = false; 15051 app.thread.scheduleLowMemory(); 15052 } else { 15053 app.thread.processInBackground(); 15054 } 15055 } 15056 } catch (Exception e) { 15057 // whatever. 15058 } 15059 } 15060 15061 /** 15062 * Returns true if things are idle enough to perform GCs. 15063 */ 15064 private final boolean canGcNowLocked() { 15065 boolean processingBroadcasts = false; 15066 for (BroadcastQueue q : mBroadcastQueues) { 15067 if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) { 15068 processingBroadcasts = true; 15069 } 15070 } 15071 return !processingBroadcasts 15072 && (mSleeping || mStackSupervisor.allResumedActivitiesIdle()); 15073 } 15074 15075 /** 15076 * Perform GCs on all processes that are waiting for it, but only 15077 * if things are idle. 15078 */ 15079 final void performAppGcsLocked() { 15080 final int N = mProcessesToGc.size(); 15081 if (N <= 0) { 15082 return; 15083 } 15084 if (canGcNowLocked()) { 15085 while (mProcessesToGc.size() > 0) { 15086 ProcessRecord proc = mProcessesToGc.remove(0); 15087 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) { 15088 if ((proc.lastRequestedGc+GC_MIN_INTERVAL) 15089 <= SystemClock.uptimeMillis()) { 15090 // To avoid spamming the system, we will GC processes one 15091 // at a time, waiting a few seconds between each. 15092 performAppGcLocked(proc); 15093 scheduleAppGcsLocked(); 15094 return; 15095 } else { 15096 // It hasn't been long enough since we last GCed this 15097 // process... put it in the list to wait for its time. 15098 addProcessToGcListLocked(proc); 15099 break; 15100 } 15101 } 15102 } 15103 15104 scheduleAppGcsLocked(); 15105 } 15106 } 15107 15108 /** 15109 * If all looks good, perform GCs on all processes waiting for them. 15110 */ 15111 final void performAppGcsIfAppropriateLocked() { 15112 if (canGcNowLocked()) { 15113 performAppGcsLocked(); 15114 return; 15115 } 15116 // Still not idle, wait some more. 15117 scheduleAppGcsLocked(); 15118 } 15119 15120 /** 15121 * Schedule the execution of all pending app GCs. 15122 */ 15123 final void scheduleAppGcsLocked() { 15124 mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG); 15125 15126 if (mProcessesToGc.size() > 0) { 15127 // Schedule a GC for the time to the next process. 15128 ProcessRecord proc = mProcessesToGc.get(0); 15129 Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG); 15130 15131 long when = proc.lastRequestedGc + GC_MIN_INTERVAL; 15132 long now = SystemClock.uptimeMillis(); 15133 if (when < (now+GC_TIMEOUT)) { 15134 when = now + GC_TIMEOUT; 15135 } 15136 mHandler.sendMessageAtTime(msg, when); 15137 } 15138 } 15139 15140 /** 15141 * Add a process to the array of processes waiting to be GCed. Keeps the 15142 * list in sorted order by the last GC time. The process can't already be 15143 * on the list. 15144 */ 15145 final void addProcessToGcListLocked(ProcessRecord proc) { 15146 boolean added = false; 15147 for (int i=mProcessesToGc.size()-1; i>=0; i--) { 15148 if (mProcessesToGc.get(i).lastRequestedGc < 15149 proc.lastRequestedGc) { 15150 added = true; 15151 mProcessesToGc.add(i+1, proc); 15152 break; 15153 } 15154 } 15155 if (!added) { 15156 mProcessesToGc.add(0, proc); 15157 } 15158 } 15159 15160 /** 15161 * Set up to ask a process to GC itself. This will either do it 15162 * immediately, or put it on the list of processes to gc the next 15163 * time things are idle. 15164 */ 15165 final void scheduleAppGcLocked(ProcessRecord app) { 15166 long now = SystemClock.uptimeMillis(); 15167 if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) { 15168 return; 15169 } 15170 if (!mProcessesToGc.contains(app)) { 15171 addProcessToGcListLocked(app); 15172 scheduleAppGcsLocked(); 15173 } 15174 } 15175 15176 final void checkExcessivePowerUsageLocked(boolean doKills) { 15177 updateCpuStatsNow(); 15178 15179 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 15180 boolean doWakeKills = doKills; 15181 boolean doCpuKills = doKills; 15182 if (mLastPowerCheckRealtime == 0) { 15183 doWakeKills = false; 15184 } 15185 if (mLastPowerCheckUptime == 0) { 15186 doCpuKills = false; 15187 } 15188 if (stats.isScreenOn()) { 15189 doWakeKills = false; 15190 } 15191 final long curRealtime = SystemClock.elapsedRealtime(); 15192 final long realtimeSince = curRealtime - mLastPowerCheckRealtime; 15193 final long curUptime = SystemClock.uptimeMillis(); 15194 final long uptimeSince = curUptime - mLastPowerCheckUptime; 15195 mLastPowerCheckRealtime = curRealtime; 15196 mLastPowerCheckUptime = curUptime; 15197 if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) { 15198 doWakeKills = false; 15199 } 15200 if (uptimeSince < CPU_MIN_CHECK_DURATION) { 15201 doCpuKills = false; 15202 } 15203 int i = mLruProcesses.size(); 15204 while (i > 0) { 15205 i--; 15206 ProcessRecord app = mLruProcesses.get(i); 15207 if (!app.keeping) { 15208 long wtime; 15209 synchronized (stats) { 15210 wtime = stats.getProcessWakeTime(app.info.uid, 15211 app.pid, curRealtime); 15212 } 15213 long wtimeUsed = wtime - app.lastWakeTime; 15214 long cputimeUsed = app.curCpuTime - app.lastCpuTime; 15215 if (DEBUG_POWER) { 15216 StringBuilder sb = new StringBuilder(128); 15217 sb.append("Wake for "); 15218 app.toShortString(sb); 15219 sb.append(": over "); 15220 TimeUtils.formatDuration(realtimeSince, sb); 15221 sb.append(" used "); 15222 TimeUtils.formatDuration(wtimeUsed, sb); 15223 sb.append(" ("); 15224 sb.append((wtimeUsed*100)/realtimeSince); 15225 sb.append("%)"); 15226 Slog.i(TAG, sb.toString()); 15227 sb.setLength(0); 15228 sb.append("CPU for "); 15229 app.toShortString(sb); 15230 sb.append(": over "); 15231 TimeUtils.formatDuration(uptimeSince, sb); 15232 sb.append(" used "); 15233 TimeUtils.formatDuration(cputimeUsed, sb); 15234 sb.append(" ("); 15235 sb.append((cputimeUsed*100)/uptimeSince); 15236 sb.append("%)"); 15237 Slog.i(TAG, sb.toString()); 15238 } 15239 // If a process has held a wake lock for more 15240 // than 50% of the time during this period, 15241 // that sounds bad. Kill! 15242 if (doWakeKills && realtimeSince > 0 15243 && ((wtimeUsed*100)/realtimeSince) >= 50) { 15244 synchronized (stats) { 15245 stats.reportExcessiveWakeLocked(app.info.uid, app.processName, 15246 realtimeSince, wtimeUsed); 15247 } 15248 killUnneededProcessLocked(app, "excessive wake held " + wtimeUsed 15249 + " during " + realtimeSince); 15250 app.baseProcessTracker.reportExcessiveWake(app.pkgList); 15251 } else if (doCpuKills && uptimeSince > 0 15252 && ((cputimeUsed*100)/uptimeSince) >= 50) { 15253 synchronized (stats) { 15254 stats.reportExcessiveCpuLocked(app.info.uid, app.processName, 15255 uptimeSince, cputimeUsed); 15256 } 15257 killUnneededProcessLocked(app, "excessive cpu " + cputimeUsed 15258 + " during " + uptimeSince); 15259 app.baseProcessTracker.reportExcessiveCpu(app.pkgList); 15260 } else { 15261 app.lastWakeTime = wtime; 15262 app.lastCpuTime = app.curCpuTime; 15263 } 15264 } 15265 } 15266 } 15267 15268 private final boolean applyOomAdjLocked(ProcessRecord app, boolean wasKeeping, 15269 ProcessRecord TOP_APP, boolean doingAll, boolean reportingProcessState, long now) { 15270 boolean success = true; 15271 15272 if (app.curRawAdj != app.setRawAdj) { 15273 if (wasKeeping && !app.keeping) { 15274 // This app is no longer something we want to keep. Note 15275 // its current wake lock time to later know to kill it if 15276 // it is not behaving well. 15277 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 15278 synchronized (stats) { 15279 app.lastWakeTime = stats.getProcessWakeTime(app.info.uid, 15280 app.pid, SystemClock.elapsedRealtime()); 15281 } 15282 app.lastCpuTime = app.curCpuTime; 15283 } 15284 15285 app.setRawAdj = app.curRawAdj; 15286 } 15287 15288 if (app.curAdj != app.setAdj) { 15289 ProcessList.setOomAdj(app.pid, app.curAdj); 15290 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v( 15291 TAG, "Set " + app.pid + " " + app.processName + 15292 " adj " + app.curAdj + ": " + app.adjType); 15293 app.setAdj = app.curAdj; 15294 } 15295 15296 if (app.setSchedGroup != app.curSchedGroup) { 15297 app.setSchedGroup = app.curSchedGroup; 15298 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 15299 "Setting process group of " + app.processName 15300 + " to " + app.curSchedGroup); 15301 if (app.waitingToKill != null && 15302 app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 15303 killUnneededProcessLocked(app, app.waitingToKill); 15304 success = false; 15305 } else { 15306 if (true) { 15307 long oldId = Binder.clearCallingIdentity(); 15308 try { 15309 Process.setProcessGroup(app.pid, app.curSchedGroup); 15310 } catch (Exception e) { 15311 Slog.w(TAG, "Failed setting process group of " + app.pid 15312 + " to " + app.curSchedGroup); 15313 e.printStackTrace(); 15314 } finally { 15315 Binder.restoreCallingIdentity(oldId); 15316 } 15317 } else { 15318 if (app.thread != null) { 15319 try { 15320 app.thread.setSchedulingGroup(app.curSchedGroup); 15321 } catch (RemoteException e) { 15322 } 15323 } 15324 } 15325 Process.setSwappiness(app.pid, 15326 app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE); 15327 } 15328 } 15329 if (app.repProcState != app.curProcState) { 15330 app.repProcState = app.curProcState; 15331 if (!reportingProcessState && app.thread != null) { 15332 try { 15333 if (false) { 15334 //RuntimeException h = new RuntimeException("here"); 15335 Slog.i(TAG, "Sending new process state " + app.repProcState 15336 + " to " + app /*, h*/); 15337 } 15338 app.thread.setProcessState(app.repProcState); 15339 } catch (RemoteException e) { 15340 } 15341 } 15342 } 15343 if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState, 15344 app.setProcState)) { 15345 app.lastStateTime = now; 15346 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true, 15347 mSleeping, now); 15348 if (DEBUG_PSS) Slog.d(TAG, "Process state change from " 15349 + ProcessList.makeProcStateString(app.setProcState) + " to " 15350 + ProcessList.makeProcStateString(app.curProcState) + " next pss in " 15351 + (app.nextPssTime-now) + ": " + app); 15352 } else { 15353 if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL) 15354 && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) { 15355 requestPssLocked(app, app.setProcState); 15356 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false, 15357 mSleeping, now); 15358 } else if (false && DEBUG_PSS) { 15359 Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now)); 15360 } 15361 } 15362 if (app.setProcState != app.curProcState) { 15363 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 15364 "Proc state change of " + app.processName 15365 + " to " + app.curProcState); 15366 app.setProcState = app.curProcState; 15367 if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) { 15368 app.notCachedSinceIdle = false; 15369 } 15370 if (!doingAll) { 15371 setProcessTrackerState(app, mProcessStats.getMemFactorLocked(), now); 15372 } else { 15373 app.procStateChanged = true; 15374 } 15375 } 15376 return success; 15377 } 15378 15379 private final void setProcessTrackerState(ProcessRecord proc, int memFactor, long now) { 15380 if (proc.thread != null && proc.baseProcessTracker != null) { 15381 proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList); 15382 } 15383 } 15384 15385 private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj, 15386 ProcessRecord TOP_APP, boolean doingAll, boolean reportingProcessState, long now) { 15387 if (app.thread == null) { 15388 return false; 15389 } 15390 15391 final boolean wasKeeping = app.keeping; 15392 15393 computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now); 15394 15395 return applyOomAdjLocked(app, wasKeeping, TOP_APP, doingAll, 15396 reportingProcessState, now); 15397 } 15398 15399 final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground, 15400 boolean oomAdj) { 15401 if (isForeground != proc.foregroundServices) { 15402 proc.foregroundServices = isForeground; 15403 ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName, 15404 proc.info.uid); 15405 if (isForeground) { 15406 if (curProcs == null) { 15407 curProcs = new ArrayList<ProcessRecord>(); 15408 mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs); 15409 } 15410 if (!curProcs.contains(proc)) { 15411 curProcs.add(proc); 15412 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START, 15413 proc.info.packageName, proc.info.uid); 15414 } 15415 } else { 15416 if (curProcs != null) { 15417 if (curProcs.remove(proc)) { 15418 mBatteryStatsService.noteEvent( 15419 BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH, 15420 proc.info.packageName, proc.info.uid); 15421 if (curProcs.size() <= 0) { 15422 mForegroundPackages.remove(proc.info.packageName, proc.info.uid); 15423 } 15424 } 15425 } 15426 } 15427 if (oomAdj) { 15428 updateOomAdjLocked(); 15429 } 15430 } 15431 } 15432 15433 private final ActivityRecord resumedAppLocked() { 15434 ActivityRecord act = mStackSupervisor.resumedAppLocked(); 15435 String pkg; 15436 int uid; 15437 if (act != null) { 15438 pkg = act.packageName; 15439 uid = act.info.applicationInfo.uid; 15440 } else { 15441 pkg = null; 15442 uid = -1; 15443 } 15444 // Has the UID or resumed package name changed? 15445 if (uid != mCurResumedUid || (pkg != mCurResumedPackage 15446 && (pkg == null || !pkg.equals(mCurResumedPackage)))) { 15447 if (mCurResumedPackage != null) { 15448 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH, 15449 mCurResumedPackage, mCurResumedUid); 15450 } 15451 mCurResumedPackage = pkg; 15452 mCurResumedUid = uid; 15453 if (mCurResumedPackage != null) { 15454 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START, 15455 mCurResumedPackage, mCurResumedUid); 15456 } 15457 } 15458 return act; 15459 } 15460 15461 final boolean updateOomAdjLocked(ProcessRecord app) { 15462 return updateOomAdjLocked(app, false); 15463 } 15464 15465 final boolean updateOomAdjLocked(ProcessRecord app, boolean doingProcessState) { 15466 final ActivityRecord TOP_ACT = resumedAppLocked(); 15467 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 15468 final boolean wasCached = app.cached; 15469 15470 mAdjSeq++; 15471 15472 // This is the desired cached adjusment we want to tell it to use. 15473 // If our app is currently cached, we know it, and that is it. Otherwise, 15474 // we don't know it yet, and it needs to now be cached we will then 15475 // need to do a complete oom adj. 15476 final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ 15477 ? app.curRawAdj : ProcessList.UNKNOWN_ADJ; 15478 boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false, doingProcessState, 15479 SystemClock.uptimeMillis()); 15480 if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) { 15481 // Changed to/from cached state, so apps after it in the LRU 15482 // list may also be changed. 15483 updateOomAdjLocked(); 15484 } 15485 return success; 15486 } 15487 15488 final void updateOomAdjLocked() { 15489 final ActivityRecord TOP_ACT = resumedAppLocked(); 15490 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 15491 final long now = SystemClock.uptimeMillis(); 15492 final long oldTime = now - ProcessList.MAX_EMPTY_TIME; 15493 final int N = mLruProcesses.size(); 15494 15495 if (false) { 15496 RuntimeException e = new RuntimeException(); 15497 e.fillInStackTrace(); 15498 Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e); 15499 } 15500 15501 mAdjSeq++; 15502 mNewNumServiceProcs = 0; 15503 mNewNumAServiceProcs = 0; 15504 15505 final int emptyProcessLimit; 15506 final int cachedProcessLimit; 15507 if (mProcessLimit <= 0) { 15508 emptyProcessLimit = cachedProcessLimit = 0; 15509 } else if (mProcessLimit == 1) { 15510 emptyProcessLimit = 1; 15511 cachedProcessLimit = 0; 15512 } else { 15513 emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit); 15514 cachedProcessLimit = mProcessLimit - emptyProcessLimit; 15515 } 15516 15517 // Let's determine how many processes we have running vs. 15518 // how many slots we have for background processes; we may want 15519 // to put multiple processes in a slot of there are enough of 15520 // them. 15521 int numSlots = (ProcessList.CACHED_APP_MAX_ADJ 15522 - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2; 15523 int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs; 15524 if (numEmptyProcs > cachedProcessLimit) { 15525 // If there are more empty processes than our limit on cached 15526 // processes, then use the cached process limit for the factor. 15527 // This ensures that the really old empty processes get pushed 15528 // down to the bottom, so if we are running low on memory we will 15529 // have a better chance at keeping around more cached processes 15530 // instead of a gazillion empty processes. 15531 numEmptyProcs = cachedProcessLimit; 15532 } 15533 int emptyFactor = numEmptyProcs/numSlots; 15534 if (emptyFactor < 1) emptyFactor = 1; 15535 int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots; 15536 if (cachedFactor < 1) cachedFactor = 1; 15537 int stepCached = 0; 15538 int stepEmpty = 0; 15539 int numCached = 0; 15540 int numEmpty = 0; 15541 int numTrimming = 0; 15542 15543 mNumNonCachedProcs = 0; 15544 mNumCachedHiddenProcs = 0; 15545 15546 // First update the OOM adjustment for each of the 15547 // application processes based on their current state. 15548 int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ; 15549 int nextCachedAdj = curCachedAdj+1; 15550 int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ; 15551 int nextEmptyAdj = curEmptyAdj+2; 15552 for (int i=N-1; i>=0; i--) { 15553 ProcessRecord app = mLruProcesses.get(i); 15554 if (!app.killedByAm && app.thread != null) { 15555 app.procStateChanged = false; 15556 final boolean wasKeeping = app.keeping; 15557 computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now); 15558 15559 // If we haven't yet assigned the final cached adj 15560 // to the process, do that now. 15561 if (app.curAdj >= ProcessList.UNKNOWN_ADJ) { 15562 switch (app.curProcState) { 15563 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY: 15564 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: 15565 // This process is a cached process holding activities... 15566 // assign it the next cached value for that type, and then 15567 // step that cached level. 15568 app.curRawAdj = curCachedAdj; 15569 app.curAdj = app.modifyRawOomAdj(curCachedAdj); 15570 if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i 15571 + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj 15572 + ")"); 15573 if (curCachedAdj != nextCachedAdj) { 15574 stepCached++; 15575 if (stepCached >= cachedFactor) { 15576 stepCached = 0; 15577 curCachedAdj = nextCachedAdj; 15578 nextCachedAdj += 2; 15579 if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) { 15580 nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ; 15581 } 15582 } 15583 } 15584 break; 15585 default: 15586 // For everything else, assign next empty cached process 15587 // level and bump that up. Note that this means that 15588 // long-running services that have dropped down to the 15589 // cached level will be treated as empty (since their process 15590 // state is still as a service), which is what we want. 15591 app.curRawAdj = curEmptyAdj; 15592 app.curAdj = app.modifyRawOomAdj(curEmptyAdj); 15593 if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i 15594 + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj 15595 + ")"); 15596 if (curEmptyAdj != nextEmptyAdj) { 15597 stepEmpty++; 15598 if (stepEmpty >= emptyFactor) { 15599 stepEmpty = 0; 15600 curEmptyAdj = nextEmptyAdj; 15601 nextEmptyAdj += 2; 15602 if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) { 15603 nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ; 15604 } 15605 } 15606 } 15607 break; 15608 } 15609 } 15610 15611 applyOomAdjLocked(app, wasKeeping, TOP_APP, true, false, now); 15612 15613 // Count the number of process types. 15614 switch (app.curProcState) { 15615 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY: 15616 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: 15617 mNumCachedHiddenProcs++; 15618 numCached++; 15619 if (numCached > cachedProcessLimit) { 15620 killUnneededProcessLocked(app, "cached #" + numCached); 15621 } 15622 break; 15623 case ActivityManager.PROCESS_STATE_CACHED_EMPTY: 15624 if (numEmpty > ProcessList.TRIM_EMPTY_APPS 15625 && app.lastActivityTime < oldTime) { 15626 killUnneededProcessLocked(app, "empty for " 15627 + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime) 15628 / 1000) + "s"); 15629 } else { 15630 numEmpty++; 15631 if (numEmpty > emptyProcessLimit) { 15632 killUnneededProcessLocked(app, "empty #" + numEmpty); 15633 } 15634 } 15635 break; 15636 default: 15637 mNumNonCachedProcs++; 15638 break; 15639 } 15640 15641 if (app.isolated && app.services.size() <= 0) { 15642 // If this is an isolated process, and there are no 15643 // services running in it, then the process is no longer 15644 // needed. We agressively kill these because we can by 15645 // definition not re-use the same process again, and it is 15646 // good to avoid having whatever code was running in them 15647 // left sitting around after no longer needed. 15648 killUnneededProcessLocked(app, "isolated not needed"); 15649 } 15650 15651 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME 15652 && !app.killedByAm) { 15653 numTrimming++; 15654 } 15655 } 15656 } 15657 15658 mNumServiceProcs = mNewNumServiceProcs; 15659 15660 // Now determine the memory trimming level of background processes. 15661 // Unfortunately we need to start at the back of the list to do this 15662 // properly. We only do this if the number of background apps we 15663 // are managing to keep around is less than half the maximum we desire; 15664 // if we are keeping a good number around, we'll let them use whatever 15665 // memory they want. 15666 final int numCachedAndEmpty = numCached + numEmpty; 15667 int memFactor; 15668 if (numCached <= ProcessList.TRIM_CACHED_APPS 15669 && numEmpty <= ProcessList.TRIM_EMPTY_APPS) { 15670 if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) { 15671 memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL; 15672 } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) { 15673 memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW; 15674 } else { 15675 memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE; 15676 } 15677 } else { 15678 memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL; 15679 } 15680 // We always allow the memory level to go up (better). We only allow it to go 15681 // down if we are in a state where that is allowed, *and* the total number of processes 15682 // has gone down since last time. 15683 if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel 15684 + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size() 15685 + " last=" + mLastNumProcesses); 15686 if (memFactor > mLastMemoryLevel) { 15687 if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) { 15688 memFactor = mLastMemoryLevel; 15689 if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!"); 15690 } 15691 } 15692 mLastMemoryLevel = memFactor; 15693 mLastNumProcesses = mLruProcesses.size(); 15694 boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !mSleeping, now); 15695 final int trackerMemFactor = mProcessStats.getMemFactorLocked(); 15696 if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) { 15697 if (mLowRamStartTime == 0) { 15698 mLowRamStartTime = now; 15699 } 15700 int step = 0; 15701 int fgTrimLevel; 15702 switch (memFactor) { 15703 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL: 15704 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL; 15705 break; 15706 case ProcessStats.ADJ_MEM_FACTOR_LOW: 15707 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW; 15708 break; 15709 default: 15710 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE; 15711 break; 15712 } 15713 int factor = numTrimming/3; 15714 int minFactor = 2; 15715 if (mHomeProcess != null) minFactor++; 15716 if (mPreviousProcess != null) minFactor++; 15717 if (factor < minFactor) factor = minFactor; 15718 int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE; 15719 for (int i=N-1; i>=0; i--) { 15720 ProcessRecord app = mLruProcesses.get(i); 15721 if (allChanged || app.procStateChanged) { 15722 setProcessTrackerState(app, trackerMemFactor, now); 15723 app.procStateChanged = false; 15724 } 15725 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME 15726 && !app.killedByAm) { 15727 if (app.trimMemoryLevel < curLevel && app.thread != null) { 15728 try { 15729 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 15730 "Trimming memory of " + app.processName 15731 + " to " + curLevel); 15732 app.thread.scheduleTrimMemory(curLevel); 15733 } catch (RemoteException e) { 15734 } 15735 if (false) { 15736 // For now we won't do this; our memory trimming seems 15737 // to be good enough at this point that destroying 15738 // activities causes more harm than good. 15739 if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE 15740 && app != mHomeProcess && app != mPreviousProcess) { 15741 // Need to do this on its own message because the stack may not 15742 // be in a consistent state at this point. 15743 // For these apps we will also finish their activities 15744 // to help them free memory. 15745 mStackSupervisor.scheduleDestroyAllActivities(app, "trim"); 15746 } 15747 } 15748 } 15749 app.trimMemoryLevel = curLevel; 15750 step++; 15751 if (step >= factor) { 15752 step = 0; 15753 switch (curLevel) { 15754 case ComponentCallbacks2.TRIM_MEMORY_COMPLETE: 15755 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE; 15756 break; 15757 case ComponentCallbacks2.TRIM_MEMORY_MODERATE: 15758 curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 15759 break; 15760 } 15761 } 15762 } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) { 15763 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND 15764 && app.thread != null) { 15765 try { 15766 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 15767 "Trimming memory of heavy-weight " + app.processName 15768 + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 15769 app.thread.scheduleTrimMemory( 15770 ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 15771 } catch (RemoteException e) { 15772 } 15773 } 15774 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 15775 } else { 15776 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 15777 || app.systemNoUi) && app.pendingUiClean) { 15778 // If this application is now in the background and it 15779 // had done UI, then give it the special trim level to 15780 // have it free UI resources. 15781 final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN; 15782 if (app.trimMemoryLevel < level && app.thread != null) { 15783 try { 15784 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 15785 "Trimming memory of bg-ui " + app.processName 15786 + " to " + level); 15787 app.thread.scheduleTrimMemory(level); 15788 } catch (RemoteException e) { 15789 } 15790 } 15791 app.pendingUiClean = false; 15792 } 15793 if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) { 15794 try { 15795 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 15796 "Trimming memory of fg " + app.processName 15797 + " to " + fgTrimLevel); 15798 app.thread.scheduleTrimMemory(fgTrimLevel); 15799 } catch (RemoteException e) { 15800 } 15801 } 15802 app.trimMemoryLevel = fgTrimLevel; 15803 } 15804 } 15805 } else { 15806 if (mLowRamStartTime != 0) { 15807 mLowRamTimeSinceLastIdle += now - mLowRamStartTime; 15808 mLowRamStartTime = 0; 15809 } 15810 for (int i=N-1; i>=0; i--) { 15811 ProcessRecord app = mLruProcesses.get(i); 15812 if (allChanged || app.procStateChanged) { 15813 setProcessTrackerState(app, trackerMemFactor, now); 15814 app.procStateChanged = false; 15815 } 15816 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 15817 || app.systemNoUi) && app.pendingUiClean) { 15818 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN 15819 && app.thread != null) { 15820 try { 15821 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 15822 "Trimming memory of ui hidden " + app.processName 15823 + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 15824 app.thread.scheduleTrimMemory( 15825 ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 15826 } catch (RemoteException e) { 15827 } 15828 } 15829 app.pendingUiClean = false; 15830 } 15831 app.trimMemoryLevel = 0; 15832 } 15833 } 15834 15835 if (mAlwaysFinishActivities) { 15836 // Need to do this on its own message because the stack may not 15837 // be in a consistent state at this point. 15838 mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish"); 15839 } 15840 15841 if (allChanged) { 15842 requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered()); 15843 } 15844 15845 if (mProcessStats.shouldWriteNowLocked(now)) { 15846 mHandler.post(new Runnable() { 15847 @Override public void run() { 15848 synchronized (ActivityManagerService.this) { 15849 mProcessStats.writeStateAsyncLocked(); 15850 } 15851 } 15852 }); 15853 } 15854 15855 if (DEBUG_OOM_ADJ) { 15856 Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms"); 15857 } 15858 } 15859 15860 final void trimApplications() { 15861 synchronized (this) { 15862 int i; 15863 15864 // First remove any unused application processes whose package 15865 // has been removed. 15866 for (i=mRemovedProcesses.size()-1; i>=0; i--) { 15867 final ProcessRecord app = mRemovedProcesses.get(i); 15868 if (app.activities.size() == 0 15869 && app.curReceiver == null && app.services.size() == 0) { 15870 Slog.i( 15871 TAG, "Exiting empty application process " 15872 + app.processName + " (" 15873 + (app.thread != null ? app.thread.asBinder() : null) 15874 + ")\n"); 15875 if (app.pid > 0 && app.pid != MY_PID) { 15876 EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid, 15877 app.processName, app.setAdj, "empty"); 15878 app.killedByAm = true; 15879 Process.killProcessQuiet(app.pid); 15880 } else { 15881 try { 15882 app.thread.scheduleExit(); 15883 } catch (Exception e) { 15884 // Ignore exceptions. 15885 } 15886 } 15887 cleanUpApplicationRecordLocked(app, false, true, -1); 15888 mRemovedProcesses.remove(i); 15889 15890 if (app.persistent) { 15891 if (app.persistent) { 15892 addAppLocked(app.info, false); 15893 } 15894 } 15895 } 15896 } 15897 15898 // Now update the oom adj for all processes. 15899 updateOomAdjLocked(); 15900 } 15901 } 15902 15903 /** This method sends the specified signal to each of the persistent apps */ 15904 public void signalPersistentProcesses(int sig) throws RemoteException { 15905 if (sig != Process.SIGNAL_USR1) { 15906 throw new SecurityException("Only SIGNAL_USR1 is allowed"); 15907 } 15908 15909 synchronized (this) { 15910 if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES) 15911 != PackageManager.PERMISSION_GRANTED) { 15912 throw new SecurityException("Requires permission " 15913 + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES); 15914 } 15915 15916 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 15917 ProcessRecord r = mLruProcesses.get(i); 15918 if (r.thread != null && r.persistent) { 15919 Process.sendSignal(r.pid, sig); 15920 } 15921 } 15922 } 15923 } 15924 15925 private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) { 15926 if (proc == null || proc == mProfileProc) { 15927 proc = mProfileProc; 15928 path = mProfileFile; 15929 profileType = mProfileType; 15930 clearProfilerLocked(); 15931 } 15932 if (proc == null) { 15933 return; 15934 } 15935 try { 15936 proc.thread.profilerControl(false, path, null, profileType); 15937 } catch (RemoteException e) { 15938 throw new IllegalStateException("Process disappeared"); 15939 } 15940 } 15941 15942 private void clearProfilerLocked() { 15943 if (mProfileFd != null) { 15944 try { 15945 mProfileFd.close(); 15946 } catch (IOException e) { 15947 } 15948 } 15949 mProfileApp = null; 15950 mProfileProc = null; 15951 mProfileFile = null; 15952 mProfileType = 0; 15953 mAutoStopProfiler = false; 15954 } 15955 15956 public boolean profileControl(String process, int userId, boolean start, 15957 String path, ParcelFileDescriptor fd, int profileType) throws RemoteException { 15958 15959 try { 15960 synchronized (this) { 15961 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 15962 // its own permission. 15963 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 15964 != PackageManager.PERMISSION_GRANTED) { 15965 throw new SecurityException("Requires permission " 15966 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 15967 } 15968 15969 if (start && fd == null) { 15970 throw new IllegalArgumentException("null fd"); 15971 } 15972 15973 ProcessRecord proc = null; 15974 if (process != null) { 15975 proc = findProcessLocked(process, userId, "profileControl"); 15976 } 15977 15978 if (start && (proc == null || proc.thread == null)) { 15979 throw new IllegalArgumentException("Unknown process: " + process); 15980 } 15981 15982 if (start) { 15983 stopProfilerLocked(null, null, 0); 15984 setProfileApp(proc.info, proc.processName, path, fd, false); 15985 mProfileProc = proc; 15986 mProfileType = profileType; 15987 try { 15988 fd = fd.dup(); 15989 } catch (IOException e) { 15990 fd = null; 15991 } 15992 proc.thread.profilerControl(start, path, fd, profileType); 15993 fd = null; 15994 mProfileFd = null; 15995 } else { 15996 stopProfilerLocked(proc, path, profileType); 15997 if (fd != null) { 15998 try { 15999 fd.close(); 16000 } catch (IOException e) { 16001 } 16002 } 16003 } 16004 16005 return true; 16006 } 16007 } catch (RemoteException e) { 16008 throw new IllegalStateException("Process disappeared"); 16009 } finally { 16010 if (fd != null) { 16011 try { 16012 fd.close(); 16013 } catch (IOException e) { 16014 } 16015 } 16016 } 16017 } 16018 16019 private ProcessRecord findProcessLocked(String process, int userId, String callName) { 16020 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 16021 userId, true, true, callName, null); 16022 ProcessRecord proc = null; 16023 try { 16024 int pid = Integer.parseInt(process); 16025 synchronized (mPidsSelfLocked) { 16026 proc = mPidsSelfLocked.get(pid); 16027 } 16028 } catch (NumberFormatException e) { 16029 } 16030 16031 if (proc == null) { 16032 ArrayMap<String, SparseArray<ProcessRecord>> all 16033 = mProcessNames.getMap(); 16034 SparseArray<ProcessRecord> procs = all.get(process); 16035 if (procs != null && procs.size() > 0) { 16036 proc = procs.valueAt(0); 16037 if (userId != UserHandle.USER_ALL && proc.userId != userId) { 16038 for (int i=1; i<procs.size(); i++) { 16039 ProcessRecord thisProc = procs.valueAt(i); 16040 if (thisProc.userId == userId) { 16041 proc = thisProc; 16042 break; 16043 } 16044 } 16045 } 16046 } 16047 } 16048 16049 return proc; 16050 } 16051 16052 public boolean dumpHeap(String process, int userId, boolean managed, 16053 String path, ParcelFileDescriptor fd) throws RemoteException { 16054 16055 try { 16056 synchronized (this) { 16057 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 16058 // its own permission (same as profileControl). 16059 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 16060 != PackageManager.PERMISSION_GRANTED) { 16061 throw new SecurityException("Requires permission " 16062 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 16063 } 16064 16065 if (fd == null) { 16066 throw new IllegalArgumentException("null fd"); 16067 } 16068 16069 ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap"); 16070 if (proc == null || proc.thread == null) { 16071 throw new IllegalArgumentException("Unknown process: " + process); 16072 } 16073 16074 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 16075 if (!isDebuggable) { 16076 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 16077 throw new SecurityException("Process not debuggable: " + proc); 16078 } 16079 } 16080 16081 proc.thread.dumpHeap(managed, path, fd); 16082 fd = null; 16083 return true; 16084 } 16085 } catch (RemoteException e) { 16086 throw new IllegalStateException("Process disappeared"); 16087 } finally { 16088 if (fd != null) { 16089 try { 16090 fd.close(); 16091 } catch (IOException e) { 16092 } 16093 } 16094 } 16095 } 16096 16097 /** In this method we try to acquire our lock to make sure that we have not deadlocked */ 16098 public void monitor() { 16099 synchronized (this) { } 16100 } 16101 16102 void onCoreSettingsChange(Bundle settings) { 16103 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 16104 ProcessRecord processRecord = mLruProcesses.get(i); 16105 try { 16106 if (processRecord.thread != null) { 16107 processRecord.thread.setCoreSettings(settings); 16108 } 16109 } catch (RemoteException re) { 16110 /* ignore */ 16111 } 16112 } 16113 } 16114 16115 // Multi-user methods 16116 16117 /** 16118 * Start user, if its not already running, but don't bring it to foreground. 16119 */ 16120 @Override 16121 public boolean startUserInBackground(final int userId) { 16122 return startUser(userId, /* foreground */ false); 16123 } 16124 16125 @Override 16126 public boolean switchUser(final int userId) { 16127 return startUser(userId, /* foregound */ true); 16128 } 16129 16130 private boolean startUser(final int userId, boolean foreground) { 16131 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 16132 != PackageManager.PERMISSION_GRANTED) { 16133 String msg = "Permission Denial: switchUser() from pid=" 16134 + Binder.getCallingPid() 16135 + ", uid=" + Binder.getCallingUid() 16136 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 16137 Slog.w(TAG, msg); 16138 throw new SecurityException(msg); 16139 } 16140 16141 if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground); 16142 16143 final long ident = Binder.clearCallingIdentity(); 16144 try { 16145 synchronized (this) { 16146 final int oldUserId = mCurrentUserId; 16147 if (oldUserId == userId) { 16148 return true; 16149 } 16150 16151 final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId); 16152 if (userInfo == null) { 16153 Slog.w(TAG, "No user info for user #" + userId); 16154 return false; 16155 } 16156 16157 if (foreground) { 16158 mWindowManager.startFreezingScreen(R.anim.screen_user_exit, 16159 R.anim.screen_user_enter); 16160 } 16161 16162 boolean needStart = false; 16163 16164 // If the user we are switching to is not currently started, then 16165 // we need to start it now. 16166 if (mStartedUsers.get(userId) == null) { 16167 mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false)); 16168 updateStartedUserArrayLocked(); 16169 needStart = true; 16170 } 16171 16172 final Integer userIdInt = Integer.valueOf(userId); 16173 mUserLru.remove(userIdInt); 16174 mUserLru.add(userIdInt); 16175 16176 if (foreground) { 16177 mCurrentUserId = userId; 16178 mWindowManager.setCurrentUser(userId); 16179 // Once the internal notion of the active user has switched, we lock the device 16180 // with the option to show the user switcher on the keyguard. 16181 mWindowManager.lockNow(null); 16182 } else { 16183 final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId); 16184 mUserLru.remove(currentUserIdInt); 16185 mUserLru.add(currentUserIdInt); 16186 } 16187 16188 final UserStartedState uss = mStartedUsers.get(userId); 16189 16190 // Make sure user is in the started state. If it is currently 16191 // stopping, we need to knock that off. 16192 if (uss.mState == UserStartedState.STATE_STOPPING) { 16193 // If we are stopping, we haven't sent ACTION_SHUTDOWN, 16194 // so we can just fairly silently bring the user back from 16195 // the almost-dead. 16196 uss.mState = UserStartedState.STATE_RUNNING; 16197 updateStartedUserArrayLocked(); 16198 needStart = true; 16199 } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) { 16200 // This means ACTION_SHUTDOWN has been sent, so we will 16201 // need to treat this as a new boot of the user. 16202 uss.mState = UserStartedState.STATE_BOOTING; 16203 updateStartedUserArrayLocked(); 16204 needStart = true; 16205 } 16206 16207 if (foreground) { 16208 mHandler.removeMessages(REPORT_USER_SWITCH_MSG); 16209 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 16210 mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG, 16211 oldUserId, userId, uss)); 16212 mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG, 16213 oldUserId, userId, uss), USER_SWITCH_TIMEOUT); 16214 } 16215 16216 if (needStart) { 16217 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 16218 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16219 | Intent.FLAG_RECEIVER_FOREGROUND); 16220 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 16221 broadcastIntentLocked(null, null, intent, 16222 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 16223 false, false, MY_PID, Process.SYSTEM_UID, userId); 16224 } 16225 16226 if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) { 16227 if (userId != 0) { 16228 Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE); 16229 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 16230 broadcastIntentLocked(null, null, intent, null, 16231 new IIntentReceiver.Stub() { 16232 public void performReceive(Intent intent, int resultCode, 16233 String data, Bundle extras, boolean ordered, 16234 boolean sticky, int sendingUser) { 16235 userInitialized(uss, userId); 16236 } 16237 }, 0, null, null, null, AppOpsManager.OP_NONE, 16238 true, false, MY_PID, Process.SYSTEM_UID, 16239 userId); 16240 uss.initializing = true; 16241 } else { 16242 getUserManagerLocked().makeInitialized(userInfo.id); 16243 } 16244 } 16245 16246 if (foreground) { 16247 boolean homeInFront = mStackSupervisor.switchUserLocked(userId, uss); 16248 if (homeInFront) { 16249 startHomeActivityLocked(userId); 16250 } else { 16251 mStackSupervisor.resumeTopActivitiesLocked(); 16252 } 16253 EventLogTags.writeAmSwitchUser(userId); 16254 getUserManagerLocked().userForeground(userId); 16255 sendUserSwitchBroadcastsLocked(oldUserId, userId); 16256 } 16257 16258 if (needStart) { 16259 Intent intent = new Intent(Intent.ACTION_USER_STARTING); 16260 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 16261 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 16262 broadcastIntentLocked(null, null, intent, 16263 null, new IIntentReceiver.Stub() { 16264 @Override 16265 public void performReceive(Intent intent, int resultCode, String data, 16266 Bundle extras, boolean ordered, boolean sticky, int sendingUser) 16267 throws RemoteException { 16268 } 16269 }, 0, null, null, 16270 android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 16271 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 16272 } 16273 } 16274 } finally { 16275 Binder.restoreCallingIdentity(ident); 16276 } 16277 16278 return true; 16279 } 16280 16281 void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) { 16282 long ident = Binder.clearCallingIdentity(); 16283 try { 16284 Intent intent; 16285 if (oldUserId >= 0) { 16286 intent = new Intent(Intent.ACTION_USER_BACKGROUND); 16287 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16288 | Intent.FLAG_RECEIVER_FOREGROUND); 16289 intent.putExtra(Intent.EXTRA_USER_HANDLE, oldUserId); 16290 broadcastIntentLocked(null, null, intent, 16291 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 16292 false, false, MY_PID, Process.SYSTEM_UID, oldUserId); 16293 } 16294 if (newUserId >= 0) { 16295 intent = new Intent(Intent.ACTION_USER_FOREGROUND); 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, null, AppOpsManager.OP_NONE, 16301 false, false, MY_PID, Process.SYSTEM_UID, newUserId); 16302 intent = new Intent(Intent.ACTION_USER_SWITCHED); 16303 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16304 | Intent.FLAG_RECEIVER_FOREGROUND); 16305 intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId); 16306 broadcastIntentLocked(null, null, intent, 16307 null, null, 0, null, null, 16308 android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE, 16309 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 16310 } 16311 } finally { 16312 Binder.restoreCallingIdentity(ident); 16313 } 16314 } 16315 16316 void dispatchUserSwitch(final UserStartedState uss, final int oldUserId, 16317 final int newUserId) { 16318 final int N = mUserSwitchObservers.beginBroadcast(); 16319 if (N > 0) { 16320 final IRemoteCallback callback = new IRemoteCallback.Stub() { 16321 int mCount = 0; 16322 @Override 16323 public void sendResult(Bundle data) throws RemoteException { 16324 synchronized (ActivityManagerService.this) { 16325 if (mCurUserSwitchCallback == this) { 16326 mCount++; 16327 if (mCount == N) { 16328 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 16329 } 16330 } 16331 } 16332 } 16333 }; 16334 synchronized (this) { 16335 uss.switching = true; 16336 mCurUserSwitchCallback = callback; 16337 } 16338 for (int i=0; i<N; i++) { 16339 try { 16340 mUserSwitchObservers.getBroadcastItem(i).onUserSwitching( 16341 newUserId, callback); 16342 } catch (RemoteException e) { 16343 } 16344 } 16345 } else { 16346 synchronized (this) { 16347 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 16348 } 16349 } 16350 mUserSwitchObservers.finishBroadcast(); 16351 } 16352 16353 void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 16354 synchronized (this) { 16355 Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId); 16356 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 16357 } 16358 } 16359 16360 void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) { 16361 mCurUserSwitchCallback = null; 16362 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 16363 mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG, 16364 oldUserId, newUserId, uss)); 16365 } 16366 16367 void userInitialized(UserStartedState uss, int newUserId) { 16368 completeSwitchAndInitalize(uss, newUserId, true, false); 16369 } 16370 16371 void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 16372 completeSwitchAndInitalize(uss, newUserId, false, true); 16373 } 16374 16375 void completeSwitchAndInitalize(UserStartedState uss, int newUserId, 16376 boolean clearInitializing, boolean clearSwitching) { 16377 boolean unfrozen = false; 16378 synchronized (this) { 16379 if (clearInitializing) { 16380 uss.initializing = false; 16381 getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier()); 16382 } 16383 if (clearSwitching) { 16384 uss.switching = false; 16385 } 16386 if (!uss.switching && !uss.initializing) { 16387 mWindowManager.stopFreezingScreen(); 16388 unfrozen = true; 16389 } 16390 } 16391 if (unfrozen) { 16392 final int N = mUserSwitchObservers.beginBroadcast(); 16393 for (int i=0; i<N; i++) { 16394 try { 16395 mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId); 16396 } catch (RemoteException e) { 16397 } 16398 } 16399 mUserSwitchObservers.finishBroadcast(); 16400 } 16401 } 16402 16403 void scheduleStartRelatedUsersLocked() { 16404 if (!mHandler.hasMessages(START_RELATED_USERS_MSG)) { 16405 mHandler.sendMessageDelayed(mHandler.obtainMessage(START_RELATED_USERS_MSG), 16406 DateUtils.SECOND_IN_MILLIS); 16407 } 16408 } 16409 16410 void startRelatedUsersLocked() { 16411 if (DEBUG_MU) Slog.i(TAG_MU, "startRelatedUsersLocked"); 16412 List<UserInfo> relatedUsers = getUserManagerLocked().getRelatedUsers(mCurrentUserId); 16413 List<UserInfo> toStart = new ArrayList<UserInfo>(relatedUsers.size()); 16414 for (UserInfo relatedUser : relatedUsers) { 16415 if ((relatedUser.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED) { 16416 toStart.add(relatedUser); 16417 } 16418 } 16419 final int n = toStart.size(); 16420 int i = 0; 16421 for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) { 16422 startUserInBackground(toStart.get(i).id); 16423 } 16424 if (i < n) { 16425 Slog.w(TAG_MU, "More related users than MAX_RUNNING_USERS"); 16426 } 16427 } 16428 16429 void finishUserSwitch(UserStartedState uss) { 16430 synchronized (this) { 16431 if (uss.mState == UserStartedState.STATE_BOOTING 16432 && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) { 16433 uss.mState = UserStartedState.STATE_RUNNING; 16434 final int userId = uss.mHandle.getIdentifier(); 16435 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 16436 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 16437 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT); 16438 broadcastIntentLocked(null, null, intent, 16439 null, null, 0, null, null, 16440 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE, 16441 true, false, MY_PID, Process.SYSTEM_UID, userId); 16442 } 16443 16444 startRelatedUsersLocked(); 16445 16446 int num = mUserLru.size(); 16447 int i = 0; 16448 while (num > MAX_RUNNING_USERS && i < mUserLru.size()) { 16449 Integer oldUserId = mUserLru.get(i); 16450 UserStartedState oldUss = mStartedUsers.get(oldUserId); 16451 if (oldUss == null) { 16452 // Shouldn't happen, but be sane if it does. 16453 mUserLru.remove(i); 16454 num--; 16455 continue; 16456 } 16457 if (oldUss.mState == UserStartedState.STATE_STOPPING 16458 || oldUss.mState == UserStartedState.STATE_SHUTDOWN) { 16459 // This user is already stopping, doesn't count. 16460 num--; 16461 i++; 16462 continue; 16463 } 16464 if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) { 16465 // Owner and current can't be stopped, but count as running. 16466 i++; 16467 continue; 16468 } 16469 // This is a user to be stopped. 16470 stopUserLocked(oldUserId, null); 16471 num--; 16472 i++; 16473 } 16474 } 16475 } 16476 16477 @Override 16478 public int stopUser(final int userId, final IStopUserCallback callback) { 16479 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 16480 != PackageManager.PERMISSION_GRANTED) { 16481 String msg = "Permission Denial: switchUser() from pid=" 16482 + Binder.getCallingPid() 16483 + ", uid=" + Binder.getCallingUid() 16484 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 16485 Slog.w(TAG, msg); 16486 throw new SecurityException(msg); 16487 } 16488 if (userId <= 0) { 16489 throw new IllegalArgumentException("Can't stop primary user " + userId); 16490 } 16491 synchronized (this) { 16492 return stopUserLocked(userId, callback); 16493 } 16494 } 16495 16496 private int stopUserLocked(final int userId, final IStopUserCallback callback) { 16497 if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId); 16498 if (mCurrentUserId == userId) { 16499 return ActivityManager.USER_OP_IS_CURRENT; 16500 } 16501 16502 final UserStartedState uss = mStartedUsers.get(userId); 16503 if (uss == null) { 16504 // User is not started, nothing to do... but we do need to 16505 // callback if requested. 16506 if (callback != null) { 16507 mHandler.post(new Runnable() { 16508 @Override 16509 public void run() { 16510 try { 16511 callback.userStopped(userId); 16512 } catch (RemoteException e) { 16513 } 16514 } 16515 }); 16516 } 16517 return ActivityManager.USER_OP_SUCCESS; 16518 } 16519 16520 if (callback != null) { 16521 uss.mStopCallbacks.add(callback); 16522 } 16523 16524 if (uss.mState != UserStartedState.STATE_STOPPING 16525 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 16526 uss.mState = UserStartedState.STATE_STOPPING; 16527 updateStartedUserArrayLocked(); 16528 16529 long ident = Binder.clearCallingIdentity(); 16530 try { 16531 // We are going to broadcast ACTION_USER_STOPPING and then 16532 // once that is done send a final ACTION_SHUTDOWN and then 16533 // stop the user. 16534 final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING); 16535 stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 16536 stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 16537 stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true); 16538 final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN); 16539 // This is the result receiver for the final shutdown broadcast. 16540 final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() { 16541 @Override 16542 public void performReceive(Intent intent, int resultCode, String data, 16543 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 16544 finishUserStop(uss); 16545 } 16546 }; 16547 // This is the result receiver for the initial stopping broadcast. 16548 final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() { 16549 @Override 16550 public void performReceive(Intent intent, int resultCode, String data, 16551 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 16552 // On to the next. 16553 synchronized (ActivityManagerService.this) { 16554 if (uss.mState != UserStartedState.STATE_STOPPING) { 16555 // Whoops, we are being started back up. Abort, abort! 16556 return; 16557 } 16558 uss.mState = UserStartedState.STATE_SHUTDOWN; 16559 } 16560 broadcastIntentLocked(null, null, shutdownIntent, 16561 null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE, 16562 true, false, MY_PID, Process.SYSTEM_UID, userId); 16563 } 16564 }; 16565 // Kick things off. 16566 broadcastIntentLocked(null, null, stoppingIntent, 16567 null, stoppingReceiver, 0, null, null, 16568 android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 16569 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 16570 } finally { 16571 Binder.restoreCallingIdentity(ident); 16572 } 16573 } 16574 16575 return ActivityManager.USER_OP_SUCCESS; 16576 } 16577 16578 void finishUserStop(UserStartedState uss) { 16579 final int userId = uss.mHandle.getIdentifier(); 16580 boolean stopped; 16581 ArrayList<IStopUserCallback> callbacks; 16582 synchronized (this) { 16583 callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks); 16584 if (mStartedUsers.get(userId) != uss) { 16585 stopped = false; 16586 } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) { 16587 stopped = false; 16588 } else { 16589 stopped = true; 16590 // User can no longer run. 16591 mStartedUsers.remove(userId); 16592 mUserLru.remove(Integer.valueOf(userId)); 16593 updateStartedUserArrayLocked(); 16594 16595 // Clean up all state and processes associated with the user. 16596 // Kill all the processes for the user. 16597 forceStopUserLocked(userId, "finish user"); 16598 } 16599 } 16600 16601 for (int i=0; i<callbacks.size(); i++) { 16602 try { 16603 if (stopped) callbacks.get(i).userStopped(userId); 16604 else callbacks.get(i).userStopAborted(userId); 16605 } catch (RemoteException e) { 16606 } 16607 } 16608 16609 mStackSupervisor.removeUserLocked(userId); 16610 } 16611 16612 @Override 16613 public UserInfo getCurrentUser() { 16614 if ((checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) 16615 != PackageManager.PERMISSION_GRANTED) && ( 16616 checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 16617 != PackageManager.PERMISSION_GRANTED)) { 16618 String msg = "Permission Denial: getCurrentUser() from pid=" 16619 + Binder.getCallingPid() 16620 + ", uid=" + Binder.getCallingUid() 16621 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS; 16622 Slog.w(TAG, msg); 16623 throw new SecurityException(msg); 16624 } 16625 synchronized (this) { 16626 return getUserManagerLocked().getUserInfo(mCurrentUserId); 16627 } 16628 } 16629 16630 int getCurrentUserIdLocked() { 16631 return mCurrentUserId; 16632 } 16633 16634 @Override 16635 public boolean isUserRunning(int userId, boolean orStopped) { 16636 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) 16637 != PackageManager.PERMISSION_GRANTED) { 16638 String msg = "Permission Denial: isUserRunning() from pid=" 16639 + Binder.getCallingPid() 16640 + ", uid=" + Binder.getCallingUid() 16641 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS; 16642 Slog.w(TAG, msg); 16643 throw new SecurityException(msg); 16644 } 16645 synchronized (this) { 16646 return isUserRunningLocked(userId, orStopped); 16647 } 16648 } 16649 16650 boolean isUserRunningLocked(int userId, boolean orStopped) { 16651 UserStartedState state = mStartedUsers.get(userId); 16652 if (state == null) { 16653 return false; 16654 } 16655 if (orStopped) { 16656 return true; 16657 } 16658 return state.mState != UserStartedState.STATE_STOPPING 16659 && state.mState != UserStartedState.STATE_SHUTDOWN; 16660 } 16661 16662 @Override 16663 public int[] getRunningUserIds() { 16664 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) 16665 != PackageManager.PERMISSION_GRANTED) { 16666 String msg = "Permission Denial: isUserRunning() from pid=" 16667 + Binder.getCallingPid() 16668 + ", uid=" + Binder.getCallingUid() 16669 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS; 16670 Slog.w(TAG, msg); 16671 throw new SecurityException(msg); 16672 } 16673 synchronized (this) { 16674 return mStartedUserArray; 16675 } 16676 } 16677 16678 private void updateStartedUserArrayLocked() { 16679 int num = 0; 16680 for (int i=0; i<mStartedUsers.size(); i++) { 16681 UserStartedState uss = mStartedUsers.valueAt(i); 16682 // This list does not include stopping users. 16683 if (uss.mState != UserStartedState.STATE_STOPPING 16684 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 16685 num++; 16686 } 16687 } 16688 mStartedUserArray = new int[num]; 16689 num = 0; 16690 for (int i=0; i<mStartedUsers.size(); i++) { 16691 UserStartedState uss = mStartedUsers.valueAt(i); 16692 if (uss.mState != UserStartedState.STATE_STOPPING 16693 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 16694 mStartedUserArray[num] = mStartedUsers.keyAt(i); 16695 num++; 16696 } 16697 } 16698 } 16699 16700 @Override 16701 public void registerUserSwitchObserver(IUserSwitchObserver observer) { 16702 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 16703 != PackageManager.PERMISSION_GRANTED) { 16704 String msg = "Permission Denial: registerUserSwitchObserver() from pid=" 16705 + Binder.getCallingPid() 16706 + ", uid=" + Binder.getCallingUid() 16707 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 16708 Slog.w(TAG, msg); 16709 throw new SecurityException(msg); 16710 } 16711 16712 mUserSwitchObservers.register(observer); 16713 } 16714 16715 @Override 16716 public void unregisterUserSwitchObserver(IUserSwitchObserver observer) { 16717 mUserSwitchObservers.unregister(observer); 16718 } 16719 16720 private boolean userExists(int userId) { 16721 if (userId == 0) { 16722 return true; 16723 } 16724 UserManagerService ums = getUserManagerLocked(); 16725 return ums != null ? (ums.getUserInfo(userId) != null) : false; 16726 } 16727 16728 int[] getUsersLocked() { 16729 UserManagerService ums = getUserManagerLocked(); 16730 return ums != null ? ums.getUserIds() : new int[] { 0 }; 16731 } 16732 16733 UserManagerService getUserManagerLocked() { 16734 if (mUserManager == null) { 16735 IBinder b = ServiceManager.getService(Context.USER_SERVICE); 16736 mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b); 16737 } 16738 return mUserManager; 16739 } 16740 16741 private int applyUserId(int uid, int userId) { 16742 return UserHandle.getUid(userId, uid); 16743 } 16744 16745 ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) { 16746 if (info == null) return null; 16747 ApplicationInfo newInfo = new ApplicationInfo(info); 16748 newInfo.uid = applyUserId(info.uid, userId); 16749 newInfo.dataDir = USER_DATA_DIR + userId + "/" 16750 + info.packageName; 16751 return newInfo; 16752 } 16753 16754 ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) { 16755 if (aInfo == null 16756 || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) { 16757 return aInfo; 16758 } 16759 16760 ActivityInfo info = new ActivityInfo(aInfo); 16761 info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId); 16762 return info; 16763 } 16764} 16765