ActivityManagerService.java revision dca272b8c21f2910424496b97cd9b7a558008876
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; 27import static com.android.server.am.ActivityStackSupervisor.HOME_STACK_ID; 28 29import android.app.AppOpsManager; 30import android.app.IActivityContainer; 31import android.app.IActivityContainerCallback; 32import android.appwidget.AppWidgetManager; 33import android.graphics.Rect; 34import android.util.ArrayMap; 35 36import com.android.internal.R; 37import com.android.internal.annotations.GuardedBy; 38import com.android.internal.app.IAppOpsService; 39import com.android.internal.app.ProcessMap; 40import com.android.internal.app.ProcessStats; 41import com.android.internal.os.BackgroundThread; 42import com.android.internal.os.BatteryStatsImpl; 43import com.android.internal.os.ProcessCpuTracker; 44import com.android.internal.os.TransferPipe; 45import com.android.internal.os.Zygote; 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.LocalServices; 54import com.android.server.ServiceThread; 55import com.android.server.SystemService; 56import com.android.server.Watchdog; 57import com.android.server.am.ActivityStack.ActivityState; 58import com.android.server.firewall.IntentFirewall; 59import com.android.server.pm.UserManagerService; 60import com.android.server.wm.AppTransition; 61import com.android.server.wm.WindowManagerService; 62import com.google.android.collect.Lists; 63import com.google.android.collect.Maps; 64 65import libcore.io.IoUtils; 66 67import org.xmlpull.v1.XmlPullParser; 68import org.xmlpull.v1.XmlPullParserException; 69import org.xmlpull.v1.XmlSerializer; 70 71import android.app.Activity; 72import android.app.ActivityManager; 73import android.app.ActivityManager.RunningTaskInfo; 74import android.app.ActivityManager.StackInfo; 75import android.app.ActivityManagerInternal; 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 = 1200*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 ComponentName mTopComponent; 803 String mTopAction = Intent.ACTION_MAIN; 804 String mTopData; 805 boolean mProcessesReady = false; 806 boolean mSystemReady = false; 807 boolean mBooting = false; 808 boolean mWaitingUpdate = false; 809 boolean mDidUpdate = false; 810 boolean mOnBattery = false; 811 boolean mLaunchWarningShown = false; 812 813 Context mContext; 814 815 int mFactoryTest; 816 817 boolean mCheckedForSetup; 818 819 /** 820 * The time at which we will allow normal application switches again, 821 * after a call to {@link #stopAppSwitches()}. 822 */ 823 long mAppSwitchesAllowedTime; 824 825 /** 826 * This is set to true after the first switch after mAppSwitchesAllowedTime 827 * is set; any switches after that will clear the time. 828 */ 829 boolean mDidAppSwitch; 830 831 /** 832 * Last time (in realtime) at which we checked for power usage. 833 */ 834 long mLastPowerCheckRealtime; 835 836 /** 837 * Last time (in uptime) at which we checked for power usage. 838 */ 839 long mLastPowerCheckUptime; 840 841 /** 842 * Set while we are wanting to sleep, to prevent any 843 * activities from being started/resumed. 844 */ 845 boolean mSleeping = false; 846 847 /** 848 * State of external calls telling us if the device is asleep. 849 */ 850 boolean mWentToSleep = false; 851 852 /** 853 * State of external call telling us if the lock screen is shown. 854 */ 855 boolean mLockScreenShown = false; 856 857 /** 858 * Set if we are shutting down the system, similar to sleeping. 859 */ 860 boolean mShuttingDown = false; 861 862 /** 863 * Current sequence id for oom_adj computation traversal. 864 */ 865 int mAdjSeq = 0; 866 867 /** 868 * Current sequence id for process LRU updating. 869 */ 870 int mLruSeq = 0; 871 872 /** 873 * Keep track of the non-cached/empty process we last found, to help 874 * determine how to distribute cached/empty processes next time. 875 */ 876 int mNumNonCachedProcs = 0; 877 878 /** 879 * Keep track of the number of cached hidden procs, to balance oom adj 880 * distribution between those and empty procs. 881 */ 882 int mNumCachedHiddenProcs = 0; 883 884 /** 885 * Keep track of the number of service processes we last found, to 886 * determine on the next iteration which should be B services. 887 */ 888 int mNumServiceProcs = 0; 889 int mNewNumAServiceProcs = 0; 890 int mNewNumServiceProcs = 0; 891 892 /** 893 * Allow the current computed overall memory level of the system to go down? 894 * This is set to false when we are killing processes for reasons other than 895 * memory management, so that the now smaller process list will not be taken as 896 * an indication that memory is tighter. 897 */ 898 boolean mAllowLowerMemLevel = false; 899 900 /** 901 * The last computed memory level, for holding when we are in a state that 902 * processes are going away for other reasons. 903 */ 904 int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL; 905 906 /** 907 * The last total number of process we have, to determine if changes actually look 908 * like a shrinking number of process due to lower RAM. 909 */ 910 int mLastNumProcesses; 911 912 /** 913 * The uptime of the last time we performed idle maintenance. 914 */ 915 long mLastIdleTime = SystemClock.uptimeMillis(); 916 917 /** 918 * Total time spent with RAM that has been added in the past since the last idle time. 919 */ 920 long mLowRamTimeSinceLastIdle = 0; 921 922 /** 923 * If RAM is currently low, when that horrible situatin started. 924 */ 925 long mLowRamStartTime = 0; 926 927 /** 928 * This is set if we had to do a delayed dexopt of an app before launching 929 * it, to increase the ANR timeouts in that case. 930 */ 931 boolean mDidDexOpt; 932 933 /** 934 * Set if the systemServer made a call to enterSafeMode. 935 */ 936 boolean mSafeMode; 937 938 String mDebugApp = null; 939 boolean mWaitForDebugger = false; 940 boolean mDebugTransient = false; 941 String mOrigDebugApp = null; 942 boolean mOrigWaitForDebugger = false; 943 boolean mAlwaysFinishActivities = false; 944 IActivityController mController = null; 945 String mProfileApp = null; 946 ProcessRecord mProfileProc = null; 947 String mProfileFile; 948 ParcelFileDescriptor mProfileFd; 949 int mProfileType = 0; 950 boolean mAutoStopProfiler = false; 951 String mOpenGlTraceApp = null; 952 953 static class ProcessChangeItem { 954 static final int CHANGE_ACTIVITIES = 1<<0; 955 static final int CHANGE_IMPORTANCE= 1<<1; 956 int changes; 957 int uid; 958 int pid; 959 int importance; 960 boolean foregroundActivities; 961 } 962 963 final RemoteCallbackList<IProcessObserver> mProcessObservers 964 = new RemoteCallbackList<IProcessObserver>(); 965 ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5]; 966 967 final ArrayList<ProcessChangeItem> mPendingProcessChanges 968 = new ArrayList<ProcessChangeItem>(); 969 final ArrayList<ProcessChangeItem> mAvailProcessChanges 970 = new ArrayList<ProcessChangeItem>(); 971 972 /** 973 * Runtime CPU use collection thread. This object's lock is used to 974 * protect all related state. 975 */ 976 final Thread mProcessCpuThread; 977 978 /** 979 * Used to collect process stats when showing not responding dialog. 980 * Protected by mProcessCpuThread. 981 */ 982 final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker( 983 MONITOR_THREAD_CPU_USAGE); 984 final AtomicLong mLastCpuTime = new AtomicLong(0); 985 final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true); 986 987 long mLastWriteTime = 0; 988 989 /** 990 * Used to retain an update lock when the foreground activity is in 991 * immersive mode. 992 */ 993 final UpdateLock mUpdateLock = new UpdateLock("immersive"); 994 995 /** 996 * Set to true after the system has finished booting. 997 */ 998 boolean mBooted = false; 999 1000 int mProcessLimit = ProcessList.MAX_CACHED_APPS; 1001 int mProcessLimitOverride = -1; 1002 1003 WindowManagerService mWindowManager; 1004 1005 final ActivityThread mSystemThread; 1006 1007 int mCurrentUserId = 0; 1008 private UserManagerService mUserManager; 1009 1010 private final class AppDeathRecipient implements IBinder.DeathRecipient { 1011 final ProcessRecord mApp; 1012 final int mPid; 1013 final IApplicationThread mAppThread; 1014 1015 AppDeathRecipient(ProcessRecord app, int pid, 1016 IApplicationThread thread) { 1017 if (localLOGV) Slog.v( 1018 TAG, "New death recipient " + this 1019 + " for thread " + thread.asBinder()); 1020 mApp = app; 1021 mPid = pid; 1022 mAppThread = thread; 1023 } 1024 1025 @Override 1026 public void binderDied() { 1027 if (localLOGV) Slog.v( 1028 TAG, "Death received in " + this 1029 + " for thread " + mAppThread.asBinder()); 1030 synchronized(ActivityManagerService.this) { 1031 appDiedLocked(mApp, mPid, mAppThread); 1032 } 1033 } 1034 } 1035 1036 static final int SHOW_ERROR_MSG = 1; 1037 static final int SHOW_NOT_RESPONDING_MSG = 2; 1038 static final int SHOW_FACTORY_ERROR_MSG = 3; 1039 static final int UPDATE_CONFIGURATION_MSG = 4; 1040 static final int GC_BACKGROUND_PROCESSES_MSG = 5; 1041 static final int WAIT_FOR_DEBUGGER_MSG = 6; 1042 static final int SERVICE_TIMEOUT_MSG = 12; 1043 static final int UPDATE_TIME_ZONE = 13; 1044 static final int SHOW_UID_ERROR_MSG = 14; 1045 static final int IM_FEELING_LUCKY_MSG = 15; 1046 static final int PROC_START_TIMEOUT_MSG = 20; 1047 static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21; 1048 static final int KILL_APPLICATION_MSG = 22; 1049 static final int FINALIZE_PENDING_INTENT_MSG = 23; 1050 static final int POST_HEAVY_NOTIFICATION_MSG = 24; 1051 static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25; 1052 static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26; 1053 static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27; 1054 static final int CLEAR_DNS_CACHE_MSG = 28; 1055 static final int UPDATE_HTTP_PROXY_MSG = 29; 1056 static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30; 1057 static final int DISPATCH_PROCESSES_CHANGED = 31; 1058 static final int DISPATCH_PROCESS_DIED = 32; 1059 static final int REPORT_MEM_USAGE_MSG = 33; 1060 static final int REPORT_USER_SWITCH_MSG = 34; 1061 static final int CONTINUE_USER_SWITCH_MSG = 35; 1062 static final int USER_SWITCH_TIMEOUT_MSG = 36; 1063 static final int IMMERSIVE_MODE_LOCK_MSG = 37; 1064 static final int PERSIST_URI_GRANTS_MSG = 38; 1065 static final int REQUEST_ALL_PSS_MSG = 39; 1066 static final int UPDATE_TIME = 40; 1067 1068 static final int FIRST_ACTIVITY_STACK_MSG = 100; 1069 static final int FIRST_BROADCAST_QUEUE_MSG = 200; 1070 static final int FIRST_COMPAT_MODE_MSG = 300; 1071 static final int FIRST_SUPERVISOR_STACK_MSG = 100; 1072 1073 AlertDialog mUidAlert; 1074 CompatModeDialog mCompatModeDialog; 1075 long mLastMemUsageReportTime = 0; 1076 1077 /** 1078 * Flag whether the current user is a "monkey", i.e. whether 1079 * the UI is driven by a UI automation tool. 1080 */ 1081 private boolean mUserIsMonkey; 1082 1083 /** Flag whether the device has a recents UI */ 1084 final boolean mHasRecents; 1085 1086 final ServiceThread mHandlerThread; 1087 final MainHandler mHandler; 1088 1089 final class MainHandler extends Handler { 1090 public MainHandler(Looper looper) { 1091 super(looper, null, true); 1092 } 1093 1094 @Override 1095 public void handleMessage(Message msg) { 1096 switch (msg.what) { 1097 case SHOW_ERROR_MSG: { 1098 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1099 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), 1100 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; 1101 synchronized (ActivityManagerService.this) { 1102 ProcessRecord proc = (ProcessRecord)data.get("app"); 1103 AppErrorResult res = (AppErrorResult) data.get("result"); 1104 if (proc != null && proc.crashDialog != null) { 1105 Slog.e(TAG, "App already has crash dialog: " + proc); 1106 if (res != null) { 1107 res.set(0); 1108 } 1109 return; 1110 } 1111 if (!showBackground && UserHandle.getAppId(proc.uid) 1112 >= Process.FIRST_APPLICATION_UID && proc.userId != mCurrentUserId 1113 && proc.pid != MY_PID) { 1114 Slog.w(TAG, "Skipping crash dialog of " + proc + ": background"); 1115 if (res != null) { 1116 res.set(0); 1117 } 1118 return; 1119 } 1120 if (mShowDialogs && !mSleeping && !mShuttingDown) { 1121 Dialog d = new AppErrorDialog(mContext, 1122 ActivityManagerService.this, res, proc); 1123 d.show(); 1124 proc.crashDialog = d; 1125 } else { 1126 // The device is asleep, so just pretend that the user 1127 // saw a crash dialog and hit "force quit". 1128 if (res != null) { 1129 res.set(0); 1130 } 1131 } 1132 } 1133 1134 ensureBootCompleted(); 1135 } break; 1136 case SHOW_NOT_RESPONDING_MSG: { 1137 synchronized (ActivityManagerService.this) { 1138 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1139 ProcessRecord proc = (ProcessRecord)data.get("app"); 1140 if (proc != null && proc.anrDialog != null) { 1141 Slog.e(TAG, "App already has anr dialog: " + proc); 1142 return; 1143 } 1144 1145 Intent intent = new Intent("android.intent.action.ANR"); 1146 if (!mProcessesReady) { 1147 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 1148 | Intent.FLAG_RECEIVER_FOREGROUND); 1149 } 1150 broadcastIntentLocked(null, null, intent, 1151 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 1152 false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */); 1153 1154 if (mShowDialogs) { 1155 Dialog d = new AppNotRespondingDialog(ActivityManagerService.this, 1156 mContext, proc, (ActivityRecord)data.get("activity"), 1157 msg.arg1 != 0); 1158 d.show(); 1159 proc.anrDialog = d; 1160 } else { 1161 // Just kill the app if there is no dialog to be shown. 1162 killAppAtUsersRequest(proc, null); 1163 } 1164 } 1165 1166 ensureBootCompleted(); 1167 } break; 1168 case SHOW_STRICT_MODE_VIOLATION_MSG: { 1169 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1170 synchronized (ActivityManagerService.this) { 1171 ProcessRecord proc = (ProcessRecord) data.get("app"); 1172 if (proc == null) { 1173 Slog.e(TAG, "App not found when showing strict mode dialog."); 1174 break; 1175 } 1176 if (proc.crashDialog != null) { 1177 Slog.e(TAG, "App already has strict mode dialog: " + proc); 1178 return; 1179 } 1180 AppErrorResult res = (AppErrorResult) data.get("result"); 1181 if (mShowDialogs && !mSleeping && !mShuttingDown) { 1182 Dialog d = new StrictModeViolationDialog(mContext, 1183 ActivityManagerService.this, res, proc); 1184 d.show(); 1185 proc.crashDialog = d; 1186 } else { 1187 // The device is asleep, so just pretend that the user 1188 // saw a crash dialog and hit "force quit". 1189 res.set(0); 1190 } 1191 } 1192 ensureBootCompleted(); 1193 } break; 1194 case SHOW_FACTORY_ERROR_MSG: { 1195 Dialog d = new FactoryErrorDialog( 1196 mContext, msg.getData().getCharSequence("msg")); 1197 d.show(); 1198 ensureBootCompleted(); 1199 } break; 1200 case UPDATE_CONFIGURATION_MSG: { 1201 final ContentResolver resolver = mContext.getContentResolver(); 1202 Settings.System.putConfiguration(resolver, (Configuration)msg.obj); 1203 } break; 1204 case GC_BACKGROUND_PROCESSES_MSG: { 1205 synchronized (ActivityManagerService.this) { 1206 performAppGcsIfAppropriateLocked(); 1207 } 1208 } break; 1209 case WAIT_FOR_DEBUGGER_MSG: { 1210 synchronized (ActivityManagerService.this) { 1211 ProcessRecord app = (ProcessRecord)msg.obj; 1212 if (msg.arg1 != 0) { 1213 if (!app.waitedForDebugger) { 1214 Dialog d = new AppWaitingForDebuggerDialog( 1215 ActivityManagerService.this, 1216 mContext, app); 1217 app.waitDialog = d; 1218 app.waitedForDebugger = true; 1219 d.show(); 1220 } 1221 } else { 1222 if (app.waitDialog != null) { 1223 app.waitDialog.dismiss(); 1224 app.waitDialog = null; 1225 } 1226 } 1227 } 1228 } break; 1229 case SERVICE_TIMEOUT_MSG: { 1230 if (mDidDexOpt) { 1231 mDidDexOpt = false; 1232 Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG); 1233 nmsg.obj = msg.obj; 1234 mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT); 1235 return; 1236 } 1237 mServices.serviceTimeout((ProcessRecord)msg.obj); 1238 } break; 1239 case UPDATE_TIME_ZONE: { 1240 synchronized (ActivityManagerService.this) { 1241 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1242 ProcessRecord r = mLruProcesses.get(i); 1243 if (r.thread != null) { 1244 try { 1245 r.thread.updateTimeZone(); 1246 } catch (RemoteException ex) { 1247 Slog.w(TAG, "Failed to update time zone for: " + r.info.processName); 1248 } 1249 } 1250 } 1251 } 1252 } break; 1253 case CLEAR_DNS_CACHE_MSG: { 1254 synchronized (ActivityManagerService.this) { 1255 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1256 ProcessRecord r = mLruProcesses.get(i); 1257 if (r.thread != null) { 1258 try { 1259 r.thread.clearDnsCache(); 1260 } catch (RemoteException ex) { 1261 Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName); 1262 } 1263 } 1264 } 1265 } 1266 } break; 1267 case UPDATE_HTTP_PROXY_MSG: { 1268 ProxyProperties proxy = (ProxyProperties)msg.obj; 1269 String host = ""; 1270 String port = ""; 1271 String exclList = ""; 1272 String pacFileUrl = null; 1273 if (proxy != null) { 1274 host = proxy.getHost(); 1275 port = Integer.toString(proxy.getPort()); 1276 exclList = proxy.getExclusionList(); 1277 pacFileUrl = proxy.getPacFileUrl(); 1278 } 1279 synchronized (ActivityManagerService.this) { 1280 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1281 ProcessRecord r = mLruProcesses.get(i); 1282 if (r.thread != null) { 1283 try { 1284 r.thread.setHttpProxy(host, port, exclList, pacFileUrl); 1285 } catch (RemoteException ex) { 1286 Slog.w(TAG, "Failed to update http proxy for: " + 1287 r.info.processName); 1288 } 1289 } 1290 } 1291 } 1292 } break; 1293 case SHOW_UID_ERROR_MSG: { 1294 String title = "System UIDs Inconsistent"; 1295 String text = "UIDs on the system are inconsistent, you need to wipe your" 1296 + " data partition or your device will be unstable."; 1297 Log.e(TAG, title + ": " + text); 1298 if (mShowDialogs) { 1299 // XXX This is a temporary dialog, no need to localize. 1300 AlertDialog d = new BaseErrorDialog(mContext); 1301 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR); 1302 d.setCancelable(false); 1303 d.setTitle(title); 1304 d.setMessage(text); 1305 d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky", 1306 mHandler.obtainMessage(IM_FEELING_LUCKY_MSG)); 1307 mUidAlert = d; 1308 d.show(); 1309 } 1310 } break; 1311 case IM_FEELING_LUCKY_MSG: { 1312 if (mUidAlert != null) { 1313 mUidAlert.dismiss(); 1314 mUidAlert = null; 1315 } 1316 } break; 1317 case PROC_START_TIMEOUT_MSG: { 1318 if (mDidDexOpt) { 1319 mDidDexOpt = false; 1320 Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 1321 nmsg.obj = msg.obj; 1322 mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT); 1323 return; 1324 } 1325 ProcessRecord app = (ProcessRecord)msg.obj; 1326 synchronized (ActivityManagerService.this) { 1327 processStartTimedOutLocked(app); 1328 } 1329 } break; 1330 case DO_PENDING_ACTIVITY_LAUNCHES_MSG: { 1331 synchronized (ActivityManagerService.this) { 1332 doPendingActivityLaunchesLocked(true); 1333 } 1334 } break; 1335 case KILL_APPLICATION_MSG: { 1336 synchronized (ActivityManagerService.this) { 1337 int appid = msg.arg1; 1338 boolean restart = (msg.arg2 == 1); 1339 Bundle bundle = (Bundle)msg.obj; 1340 String pkg = bundle.getString("pkg"); 1341 String reason = bundle.getString("reason"); 1342 forceStopPackageLocked(pkg, appid, restart, false, true, false, 1343 UserHandle.USER_ALL, reason); 1344 } 1345 } break; 1346 case FINALIZE_PENDING_INTENT_MSG: { 1347 ((PendingIntentRecord)msg.obj).completeFinalize(); 1348 } break; 1349 case POST_HEAVY_NOTIFICATION_MSG: { 1350 INotificationManager inm = NotificationManager.getService(); 1351 if (inm == null) { 1352 return; 1353 } 1354 1355 ActivityRecord root = (ActivityRecord)msg.obj; 1356 ProcessRecord process = root.app; 1357 if (process == null) { 1358 return; 1359 } 1360 1361 try { 1362 Context context = mContext.createPackageContext(process.info.packageName, 0); 1363 String text = mContext.getString(R.string.heavy_weight_notification, 1364 context.getApplicationInfo().loadLabel(context.getPackageManager())); 1365 Notification notification = new Notification(); 1366 notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon; 1367 notification.when = 0; 1368 notification.flags = Notification.FLAG_ONGOING_EVENT; 1369 notification.tickerText = text; 1370 notification.defaults = 0; // please be quiet 1371 notification.sound = null; 1372 notification.vibrate = null; 1373 notification.setLatestEventInfo(context, text, 1374 mContext.getText(R.string.heavy_weight_notification_detail), 1375 PendingIntent.getActivityAsUser(mContext, 0, root.intent, 1376 PendingIntent.FLAG_CANCEL_CURRENT, null, 1377 new UserHandle(root.userId))); 1378 1379 try { 1380 int[] outId = new int[1]; 1381 inm.enqueueNotificationWithTag("android", "android", null, 1382 R.string.heavy_weight_notification, 1383 notification, outId, root.userId); 1384 } catch (RuntimeException e) { 1385 Slog.w(ActivityManagerService.TAG, 1386 "Error showing notification for heavy-weight app", e); 1387 } catch (RemoteException e) { 1388 } 1389 } catch (NameNotFoundException e) { 1390 Slog.w(TAG, "Unable to create context for heavy notification", e); 1391 } 1392 } break; 1393 case CANCEL_HEAVY_NOTIFICATION_MSG: { 1394 INotificationManager inm = NotificationManager.getService(); 1395 if (inm == null) { 1396 return; 1397 } 1398 try { 1399 inm.cancelNotificationWithTag("android", null, 1400 R.string.heavy_weight_notification, msg.arg1); 1401 } catch (RuntimeException e) { 1402 Slog.w(ActivityManagerService.TAG, 1403 "Error canceling notification for service", e); 1404 } catch (RemoteException e) { 1405 } 1406 } break; 1407 case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: { 1408 synchronized (ActivityManagerService.this) { 1409 checkExcessivePowerUsageLocked(true); 1410 removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1411 Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1412 sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 1413 } 1414 } break; 1415 case SHOW_COMPAT_MODE_DIALOG_MSG: { 1416 synchronized (ActivityManagerService.this) { 1417 ActivityRecord ar = (ActivityRecord)msg.obj; 1418 if (mCompatModeDialog != null) { 1419 if (mCompatModeDialog.mAppInfo.packageName.equals( 1420 ar.info.applicationInfo.packageName)) { 1421 return; 1422 } 1423 mCompatModeDialog.dismiss(); 1424 mCompatModeDialog = null; 1425 } 1426 if (ar != null && false) { 1427 if (mCompatModePackages.getPackageAskCompatModeLocked( 1428 ar.packageName)) { 1429 int mode = mCompatModePackages.computeCompatModeLocked( 1430 ar.info.applicationInfo); 1431 if (mode == ActivityManager.COMPAT_MODE_DISABLED 1432 || mode == ActivityManager.COMPAT_MODE_ENABLED) { 1433 mCompatModeDialog = new CompatModeDialog( 1434 ActivityManagerService.this, mContext, 1435 ar.info.applicationInfo); 1436 mCompatModeDialog.show(); 1437 } 1438 } 1439 } 1440 } 1441 break; 1442 } 1443 case DISPATCH_PROCESSES_CHANGED: { 1444 dispatchProcessesChanged(); 1445 break; 1446 } 1447 case DISPATCH_PROCESS_DIED: { 1448 final int pid = msg.arg1; 1449 final int uid = msg.arg2; 1450 dispatchProcessDied(pid, uid); 1451 break; 1452 } 1453 case REPORT_MEM_USAGE_MSG: { 1454 final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj; 1455 Thread thread = new Thread() { 1456 @Override public void run() { 1457 final SparseArray<ProcessMemInfo> infoMap 1458 = new SparseArray<ProcessMemInfo>(memInfos.size()); 1459 for (int i=0, N=memInfos.size(); i<N; i++) { 1460 ProcessMemInfo mi = memInfos.get(i); 1461 infoMap.put(mi.pid, mi); 1462 } 1463 updateCpuStatsNow(); 1464 synchronized (mProcessCpuThread) { 1465 final int N = mProcessCpuTracker.countStats(); 1466 for (int i=0; i<N; i++) { 1467 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 1468 if (st.vsize > 0) { 1469 long pss = Debug.getPss(st.pid, null); 1470 if (pss > 0) { 1471 if (infoMap.indexOfKey(st.pid) < 0) { 1472 ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid, 1473 ProcessList.NATIVE_ADJ, -1, "native", null); 1474 mi.pss = pss; 1475 memInfos.add(mi); 1476 } 1477 } 1478 } 1479 } 1480 } 1481 1482 long totalPss = 0; 1483 for (int i=0, N=memInfos.size(); i<N; i++) { 1484 ProcessMemInfo mi = memInfos.get(i); 1485 if (mi.pss == 0) { 1486 mi.pss = Debug.getPss(mi.pid, null); 1487 } 1488 totalPss += mi.pss; 1489 } 1490 Collections.sort(memInfos, new Comparator<ProcessMemInfo>() { 1491 @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) { 1492 if (lhs.oomAdj != rhs.oomAdj) { 1493 return lhs.oomAdj < rhs.oomAdj ? -1 : 1; 1494 } 1495 if (lhs.pss != rhs.pss) { 1496 return lhs.pss < rhs.pss ? 1 : -1; 1497 } 1498 return 0; 1499 } 1500 }); 1501 1502 StringBuilder tag = new StringBuilder(128); 1503 StringBuilder stack = new StringBuilder(128); 1504 tag.append("Low on memory -- "); 1505 appendMemBucket(tag, totalPss, "total", false); 1506 appendMemBucket(stack, totalPss, "total", true); 1507 1508 StringBuilder logBuilder = new StringBuilder(1024); 1509 logBuilder.append("Low on memory:\n"); 1510 1511 boolean firstLine = true; 1512 int lastOomAdj = Integer.MIN_VALUE; 1513 for (int i=0, N=memInfos.size(); i<N; i++) { 1514 ProcessMemInfo mi = memInfos.get(i); 1515 1516 if (mi.oomAdj != ProcessList.NATIVE_ADJ 1517 && (mi.oomAdj < ProcessList.SERVICE_ADJ 1518 || mi.oomAdj == ProcessList.HOME_APP_ADJ 1519 || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) { 1520 if (lastOomAdj != mi.oomAdj) { 1521 lastOomAdj = mi.oomAdj; 1522 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) { 1523 tag.append(" / "); 1524 } 1525 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) { 1526 if (firstLine) { 1527 stack.append(":"); 1528 firstLine = false; 1529 } 1530 stack.append("\n\t at "); 1531 } else { 1532 stack.append("$"); 1533 } 1534 } else { 1535 tag.append(" "); 1536 stack.append("$"); 1537 } 1538 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) { 1539 appendMemBucket(tag, mi.pss, mi.name, false); 1540 } 1541 appendMemBucket(stack, mi.pss, mi.name, true); 1542 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ 1543 && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) { 1544 stack.append("("); 1545 for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) { 1546 if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) { 1547 stack.append(DUMP_MEM_OOM_LABEL[k]); 1548 stack.append(":"); 1549 stack.append(DUMP_MEM_OOM_ADJ[k]); 1550 } 1551 } 1552 stack.append(")"); 1553 } 1554 } 1555 1556 logBuilder.append(" "); 1557 logBuilder.append(ProcessList.makeOomAdjString(mi.oomAdj)); 1558 logBuilder.append(' '); 1559 logBuilder.append(ProcessList.makeProcStateString(mi.procState)); 1560 logBuilder.append(' '); 1561 ProcessList.appendRamKb(logBuilder, mi.pss); 1562 logBuilder.append(" kB: "); 1563 logBuilder.append(mi.name); 1564 logBuilder.append(" ("); 1565 logBuilder.append(mi.pid); 1566 logBuilder.append(") "); 1567 logBuilder.append(mi.adjType); 1568 logBuilder.append('\n'); 1569 if (mi.adjReason != null) { 1570 logBuilder.append(" "); 1571 logBuilder.append(mi.adjReason); 1572 logBuilder.append('\n'); 1573 } 1574 } 1575 1576 logBuilder.append(" "); 1577 ProcessList.appendRamKb(logBuilder, totalPss); 1578 logBuilder.append(" kB: TOTAL\n"); 1579 1580 long[] infos = new long[Debug.MEMINFO_COUNT]; 1581 Debug.getMemInfo(infos); 1582 logBuilder.append(" MemInfo: "); 1583 logBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, "); 1584 logBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, "); 1585 logBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, "); 1586 logBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, "); 1587 logBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n"); 1588 if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) { 1589 logBuilder.append(" ZRAM: "); 1590 logBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]); 1591 logBuilder.append(" kB RAM, "); 1592 logBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]); 1593 logBuilder.append(" kB swap total, "); 1594 logBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]); 1595 logBuilder.append(" kB swap free\n"); 1596 } 1597 Slog.i(TAG, logBuilder.toString()); 1598 1599 StringBuilder dropBuilder = new StringBuilder(1024); 1600 /* 1601 StringWriter oomSw = new StringWriter(); 1602 PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256); 1603 StringWriter catSw = new StringWriter(); 1604 PrintWriter catPw = new FastPrintWriter(catSw, false, 256); 1605 String[] emptyArgs = new String[] { }; 1606 dumpApplicationMemoryUsage(null, oomPw, " ", emptyArgs, true, catPw); 1607 oomPw.flush(); 1608 String oomString = oomSw.toString(); 1609 */ 1610 dropBuilder.append(stack); 1611 dropBuilder.append('\n'); 1612 dropBuilder.append('\n'); 1613 dropBuilder.append(logBuilder); 1614 dropBuilder.append('\n'); 1615 /* 1616 dropBuilder.append(oomString); 1617 dropBuilder.append('\n'); 1618 */ 1619 StringWriter catSw = new StringWriter(); 1620 synchronized (ActivityManagerService.this) { 1621 PrintWriter catPw = new FastPrintWriter(catSw, false, 256); 1622 String[] emptyArgs = new String[] { }; 1623 catPw.println(); 1624 dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null); 1625 catPw.println(); 1626 mServices.dumpServicesLocked(null, catPw, emptyArgs, 0, 1627 false, false, null); 1628 catPw.println(); 1629 dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null); 1630 catPw.flush(); 1631 } 1632 dropBuilder.append(catSw.toString()); 1633 addErrorToDropBox("lowmem", null, "system_server", null, 1634 null, tag.toString(), dropBuilder.toString(), null, null); 1635 //Slog.i(TAG, "Sent to dropbox:"); 1636 //Slog.i(TAG, dropBuilder.toString()); 1637 synchronized (ActivityManagerService.this) { 1638 long now = SystemClock.uptimeMillis(); 1639 if (mLastMemUsageReportTime < now) { 1640 mLastMemUsageReportTime = now; 1641 } 1642 } 1643 } 1644 }; 1645 thread.start(); 1646 break; 1647 } 1648 case REPORT_USER_SWITCH_MSG: { 1649 dispatchUserSwitch((UserStartedState)msg.obj, msg.arg1, msg.arg2); 1650 break; 1651 } 1652 case CONTINUE_USER_SWITCH_MSG: { 1653 continueUserSwitch((UserStartedState)msg.obj, msg.arg1, msg.arg2); 1654 break; 1655 } 1656 case USER_SWITCH_TIMEOUT_MSG: { 1657 timeoutUserSwitch((UserStartedState)msg.obj, msg.arg1, msg.arg2); 1658 break; 1659 } 1660 case IMMERSIVE_MODE_LOCK_MSG: { 1661 final boolean nextState = (msg.arg1 != 0); 1662 if (mUpdateLock.isHeld() != nextState) { 1663 if (DEBUG_IMMERSIVE) { 1664 final ActivityRecord r = (ActivityRecord) msg.obj; 1665 Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r); 1666 } 1667 if (nextState) { 1668 mUpdateLock.acquire(); 1669 } else { 1670 mUpdateLock.release(); 1671 } 1672 } 1673 break; 1674 } 1675 case PERSIST_URI_GRANTS_MSG: { 1676 writeGrantedUriPermissions(); 1677 break; 1678 } 1679 case REQUEST_ALL_PSS_MSG: { 1680 requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false); 1681 break; 1682 } 1683 case UPDATE_TIME: { 1684 synchronized (ActivityManagerService.this) { 1685 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1686 ProcessRecord r = mLruProcesses.get(i); 1687 if (r.thread != null) { 1688 try { 1689 r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true); 1690 } catch (RemoteException ex) { 1691 Slog.w(TAG, "Failed to update preferences for: " + r.info.processName); 1692 } 1693 } 1694 } 1695 } 1696 1697 break; 1698 } 1699 } 1700 } 1701 }; 1702 1703 static final int COLLECT_PSS_BG_MSG = 1; 1704 1705 final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) { 1706 @Override 1707 public void handleMessage(Message msg) { 1708 switch (msg.what) { 1709 case COLLECT_PSS_BG_MSG: { 1710 int i=0, num=0; 1711 long start = SystemClock.uptimeMillis(); 1712 long[] tmp = new long[1]; 1713 do { 1714 ProcessRecord proc; 1715 int procState; 1716 int pid; 1717 synchronized (ActivityManagerService.this) { 1718 if (i >= mPendingPssProcesses.size()) { 1719 if (DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num + " of " + i 1720 + " processes in " + (SystemClock.uptimeMillis()-start) + "ms"); 1721 mPendingPssProcesses.clear(); 1722 return; 1723 } 1724 proc = mPendingPssProcesses.get(i); 1725 procState = proc.pssProcState; 1726 if (proc.thread != null && procState == proc.setProcState) { 1727 pid = proc.pid; 1728 } else { 1729 proc = null; 1730 pid = 0; 1731 } 1732 i++; 1733 } 1734 if (proc != null) { 1735 long pss = Debug.getPss(pid, tmp); 1736 synchronized (ActivityManagerService.this) { 1737 if (proc.thread != null && proc.setProcState == procState 1738 && proc.pid == pid) { 1739 num++; 1740 proc.lastPssTime = SystemClock.uptimeMillis(); 1741 proc.baseProcessTracker.addPss(pss, tmp[0], true, proc.pkgList); 1742 if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString() 1743 + ": " + pss + " lastPss=" + proc.lastPss 1744 + " state=" + ProcessList.makeProcStateString(procState)); 1745 if (proc.initialIdlePss == 0) { 1746 proc.initialIdlePss = pss; 1747 } 1748 proc.lastPss = pss; 1749 if (procState >= ActivityManager.PROCESS_STATE_HOME) { 1750 proc.lastCachedPss = pss; 1751 } 1752 } 1753 } 1754 } 1755 } while (true); 1756 } 1757 } 1758 } 1759 }; 1760 1761 public void setSystemProcess() { 1762 try { 1763 ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true); 1764 ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats); 1765 ServiceManager.addService("meminfo", new MemBinder(this)); 1766 ServiceManager.addService("gfxinfo", new GraphicsBinder(this)); 1767 ServiceManager.addService("dbinfo", new DbBinder(this)); 1768 if (MONITOR_CPU_USAGE) { 1769 ServiceManager.addService("cpuinfo", new CpuBinder(this)); 1770 } 1771 ServiceManager.addService("permission", new PermissionController(this)); 1772 1773 ApplicationInfo info = mContext.getPackageManager().getApplicationInfo( 1774 "android", STOCK_PM_FLAGS); 1775 mSystemThread.installSystemApplicationInfo(info); 1776 1777 synchronized (this) { 1778 ProcessRecord app = newProcessRecordLocked(info, info.processName, false); 1779 app.persistent = true; 1780 app.pid = MY_PID; 1781 app.maxAdj = ProcessList.SYSTEM_ADJ; 1782 app.makeActive(mSystemThread.getApplicationThread(), mProcessStats); 1783 mProcessNames.put(app.processName, app.uid, app); 1784 synchronized (mPidsSelfLocked) { 1785 mPidsSelfLocked.put(app.pid, app); 1786 } 1787 updateLruProcessLocked(app, false, null); 1788 updateOomAdjLocked(); 1789 } 1790 } catch (PackageManager.NameNotFoundException e) { 1791 throw new RuntimeException( 1792 "Unable to find android system package", e); 1793 } 1794 } 1795 1796 public void setWindowManager(WindowManagerService wm) { 1797 mWindowManager = wm; 1798 mStackSupervisor.setWindowManager(wm); 1799 } 1800 1801 public void startObservingNativeCrashes() { 1802 final NativeCrashListener ncl = new NativeCrashListener(this); 1803 ncl.start(); 1804 } 1805 1806 public IAppOpsService getAppOpsService() { 1807 return mAppOpsService; 1808 } 1809 1810 static class MemBinder extends Binder { 1811 ActivityManagerService mActivityManagerService; 1812 MemBinder(ActivityManagerService activityManagerService) { 1813 mActivityManagerService = activityManagerService; 1814 } 1815 1816 @Override 1817 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1818 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1819 != PackageManager.PERMISSION_GRANTED) { 1820 pw.println("Permission Denial: can't dump meminfo from from pid=" 1821 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1822 + " without permission " + android.Manifest.permission.DUMP); 1823 return; 1824 } 1825 1826 mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, " ", args, false, null); 1827 } 1828 } 1829 1830 static class GraphicsBinder extends Binder { 1831 ActivityManagerService mActivityManagerService; 1832 GraphicsBinder(ActivityManagerService activityManagerService) { 1833 mActivityManagerService = activityManagerService; 1834 } 1835 1836 @Override 1837 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1838 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1839 != PackageManager.PERMISSION_GRANTED) { 1840 pw.println("Permission Denial: can't dump gfxinfo from from pid=" 1841 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1842 + " without permission " + android.Manifest.permission.DUMP); 1843 return; 1844 } 1845 1846 mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args); 1847 } 1848 } 1849 1850 static class DbBinder extends Binder { 1851 ActivityManagerService mActivityManagerService; 1852 DbBinder(ActivityManagerService activityManagerService) { 1853 mActivityManagerService = activityManagerService; 1854 } 1855 1856 @Override 1857 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1858 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1859 != PackageManager.PERMISSION_GRANTED) { 1860 pw.println("Permission Denial: can't dump dbinfo from from pid=" 1861 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1862 + " without permission " + android.Manifest.permission.DUMP); 1863 return; 1864 } 1865 1866 mActivityManagerService.dumpDbInfo(fd, pw, args); 1867 } 1868 } 1869 1870 static class CpuBinder extends Binder { 1871 ActivityManagerService mActivityManagerService; 1872 CpuBinder(ActivityManagerService activityManagerService) { 1873 mActivityManagerService = activityManagerService; 1874 } 1875 1876 @Override 1877 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1878 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1879 != PackageManager.PERMISSION_GRANTED) { 1880 pw.println("Permission Denial: can't dump cpuinfo from from pid=" 1881 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1882 + " without permission " + android.Manifest.permission.DUMP); 1883 return; 1884 } 1885 1886 synchronized (mActivityManagerService.mProcessCpuThread) { 1887 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad()); 1888 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState( 1889 SystemClock.uptimeMillis())); 1890 } 1891 } 1892 } 1893 1894 public static final class Lifecycle extends SystemService { 1895 private final ActivityManagerService mService; 1896 1897 public Lifecycle(Context context) { 1898 super(context); 1899 mService = new ActivityManagerService(context); 1900 } 1901 1902 @Override 1903 public void onStart() { 1904 mService.start(); 1905 } 1906 1907 public ActivityManagerService getService() { 1908 return mService; 1909 } 1910 } 1911 1912 // Note: This method is invoked on the main thread but may need to attach various 1913 // handlers to other threads. So take care to be explicit about the looper. 1914 public ActivityManagerService(Context systemContext) { 1915 mContext = systemContext; 1916 mFactoryTest = FactoryTest.getMode(); 1917 mSystemThread = ActivityThread.currentActivityThread(); 1918 1919 Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass()); 1920 1921 mHandlerThread = new ServiceThread(TAG, 1922 android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/); 1923 mHandlerThread.start(); 1924 mHandler = new MainHandler(mHandlerThread.getLooper()); 1925 1926 mFgBroadcastQueue = new BroadcastQueue(this, mHandler, 1927 "foreground", BROADCAST_FG_TIMEOUT, false); 1928 mBgBroadcastQueue = new BroadcastQueue(this, mHandler, 1929 "background", BROADCAST_BG_TIMEOUT, true); 1930 mBroadcastQueues[0] = mFgBroadcastQueue; 1931 mBroadcastQueues[1] = mBgBroadcastQueue; 1932 1933 mServices = new ActiveServices(this); 1934 mProviderMap = new ProviderMap(this); 1935 1936 // TODO: Move creation of battery stats service outside of activity manager service. 1937 File dataDir = Environment.getDataDirectory(); 1938 File systemDir = new File(dataDir, "system"); 1939 systemDir.mkdirs(); 1940 mBatteryStatsService = new BatteryStatsService(new File( 1941 systemDir, "batterystats.bin").toString(), mHandler); 1942 mBatteryStatsService.getActiveStatistics().readLocked(); 1943 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 1944 mOnBattery = DEBUG_POWER ? true 1945 : mBatteryStatsService.getActiveStatistics().getIsOnBattery(); 1946 mBatteryStatsService.getActiveStatistics().setCallback(this); 1947 1948 mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats")); 1949 1950 mUsageStatsService = new UsageStatsService(new File(systemDir, "usagestats").toString()); 1951 mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler); 1952 1953 mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml")); 1954 1955 // User 0 is the first and only user that runs at boot. 1956 mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true)); 1957 mUserLru.add(Integer.valueOf(0)); 1958 updateStartedUserArrayLocked(); 1959 1960 GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version", 1961 ConfigurationInfo.GL_ES_VERSION_UNDEFINED); 1962 1963 mConfiguration.setToDefaults(); 1964 mConfiguration.setLocale(Locale.getDefault()); 1965 1966 mConfigurationSeq = mConfiguration.seq = 1; 1967 mProcessCpuTracker.init(); 1968 1969 mHasRecents = mContext.getResources().getBoolean( 1970 com.android.internal.R.bool.config_hasRecents); 1971 1972 mCompatModePackages = new CompatModePackages(this, systemDir, mHandler); 1973 mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler); 1974 mStackSupervisor = new ActivityStackSupervisor(this); 1975 1976 mProcessCpuThread = new Thread("CpuTracker") { 1977 @Override 1978 public void run() { 1979 while (true) { 1980 try { 1981 try { 1982 synchronized(this) { 1983 final long now = SystemClock.uptimeMillis(); 1984 long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now; 1985 long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now; 1986 //Slog.i(TAG, "Cpu delay=" + nextCpuDelay 1987 // + ", write delay=" + nextWriteDelay); 1988 if (nextWriteDelay < nextCpuDelay) { 1989 nextCpuDelay = nextWriteDelay; 1990 } 1991 if (nextCpuDelay > 0) { 1992 mProcessCpuMutexFree.set(true); 1993 this.wait(nextCpuDelay); 1994 } 1995 } 1996 } catch (InterruptedException e) { 1997 } 1998 updateCpuStatsNow(); 1999 } catch (Exception e) { 2000 Slog.e(TAG, "Unexpected exception collecting process stats", e); 2001 } 2002 } 2003 } 2004 }; 2005 2006 Watchdog.getInstance().addMonitor(this); 2007 Watchdog.getInstance().addThread(mHandler); 2008 } 2009 2010 private void start() { 2011 mProcessCpuThread.start(); 2012 2013 mBatteryStatsService.publish(mContext); 2014 mUsageStatsService.publish(mContext); 2015 mAppOpsService.publish(mContext); 2016 2017 LocalServices.addService(ActivityManagerInternal.class, new LocalService()); 2018 } 2019 2020 @Override 2021 public boolean onTransact(int code, Parcel data, Parcel reply, int flags) 2022 throws RemoteException { 2023 if (code == SYSPROPS_TRANSACTION) { 2024 // We need to tell all apps about the system property change. 2025 ArrayList<IBinder> procs = new ArrayList<IBinder>(); 2026 synchronized(this) { 2027 final int NP = mProcessNames.getMap().size(); 2028 for (int ip=0; ip<NP; ip++) { 2029 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 2030 final int NA = apps.size(); 2031 for (int ia=0; ia<NA; ia++) { 2032 ProcessRecord app = apps.valueAt(ia); 2033 if (app.thread != null) { 2034 procs.add(app.thread.asBinder()); 2035 } 2036 } 2037 } 2038 } 2039 2040 int N = procs.size(); 2041 for (int i=0; i<N; i++) { 2042 Parcel data2 = Parcel.obtain(); 2043 try { 2044 procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0); 2045 } catch (RemoteException e) { 2046 } 2047 data2.recycle(); 2048 } 2049 } 2050 try { 2051 return super.onTransact(code, data, reply, flags); 2052 } catch (RuntimeException e) { 2053 // The activity manager only throws security exceptions, so let's 2054 // log all others. 2055 if (!(e instanceof SecurityException)) { 2056 Slog.wtf(TAG, "Activity Manager Crash", e); 2057 } 2058 throw e; 2059 } 2060 } 2061 2062 void updateCpuStats() { 2063 final long now = SystemClock.uptimeMillis(); 2064 if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) { 2065 return; 2066 } 2067 if (mProcessCpuMutexFree.compareAndSet(true, false)) { 2068 synchronized (mProcessCpuThread) { 2069 mProcessCpuThread.notify(); 2070 } 2071 } 2072 } 2073 2074 void updateCpuStatsNow() { 2075 synchronized (mProcessCpuThread) { 2076 mProcessCpuMutexFree.set(false); 2077 final long now = SystemClock.uptimeMillis(); 2078 boolean haveNewCpuStats = false; 2079 2080 if (MONITOR_CPU_USAGE && 2081 mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) { 2082 mLastCpuTime.set(now); 2083 haveNewCpuStats = true; 2084 mProcessCpuTracker.update(); 2085 //Slog.i(TAG, mProcessCpu.printCurrentState()); 2086 //Slog.i(TAG, "Total CPU usage: " 2087 // + mProcessCpu.getTotalCpuPercent() + "%"); 2088 2089 // Slog the cpu usage if the property is set. 2090 if ("true".equals(SystemProperties.get("events.cpu"))) { 2091 int user = mProcessCpuTracker.getLastUserTime(); 2092 int system = mProcessCpuTracker.getLastSystemTime(); 2093 int iowait = mProcessCpuTracker.getLastIoWaitTime(); 2094 int irq = mProcessCpuTracker.getLastIrqTime(); 2095 int softIrq = mProcessCpuTracker.getLastSoftIrqTime(); 2096 int idle = mProcessCpuTracker.getLastIdleTime(); 2097 2098 int total = user + system + iowait + irq + softIrq + idle; 2099 if (total == 0) total = 1; 2100 2101 EventLog.writeEvent(EventLogTags.CPU, 2102 ((user+system+iowait+irq+softIrq) * 100) / total, 2103 (user * 100) / total, 2104 (system * 100) / total, 2105 (iowait * 100) / total, 2106 (irq * 100) / total, 2107 (softIrq * 100) / total); 2108 } 2109 } 2110 2111 long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes(); 2112 final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics(); 2113 synchronized(bstats) { 2114 synchronized(mPidsSelfLocked) { 2115 if (haveNewCpuStats) { 2116 if (mOnBattery) { 2117 int perc = bstats.startAddingCpuLocked(); 2118 int totalUTime = 0; 2119 int totalSTime = 0; 2120 final int N = mProcessCpuTracker.countStats(); 2121 for (int i=0; i<N; i++) { 2122 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 2123 if (!st.working) { 2124 continue; 2125 } 2126 ProcessRecord pr = mPidsSelfLocked.get(st.pid); 2127 int otherUTime = (st.rel_utime*perc)/100; 2128 int otherSTime = (st.rel_stime*perc)/100; 2129 totalUTime += otherUTime; 2130 totalSTime += otherSTime; 2131 if (pr != null) { 2132 BatteryStatsImpl.Uid.Proc ps = bstats.getProcessStatsLocked( 2133 st.name, st.pid); 2134 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 2135 st.rel_stime-otherSTime); 2136 ps.addSpeedStepTimes(cpuSpeedTimes); 2137 pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10; 2138 } else if (st.uid >= Process.FIRST_APPLICATION_UID) { 2139 BatteryStatsImpl.Uid.Proc ps = st.batteryStats; 2140 if (ps == null) { 2141 st.batteryStats = ps = bstats.getProcessStatsLocked(st.uid, 2142 "(Unknown)"); 2143 } 2144 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 2145 st.rel_stime-otherSTime); 2146 ps.addSpeedStepTimes(cpuSpeedTimes); 2147 } else { 2148 BatteryStatsImpl.Uid.Proc ps = 2149 bstats.getProcessStatsLocked(st.name, st.pid); 2150 if (ps != null) { 2151 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 2152 st.rel_stime-otherSTime); 2153 ps.addSpeedStepTimes(cpuSpeedTimes); 2154 } 2155 } 2156 } 2157 bstats.finishAddingCpuLocked(perc, totalUTime, 2158 totalSTime, cpuSpeedTimes); 2159 } 2160 } 2161 } 2162 2163 if (mLastWriteTime < (now-BATTERY_STATS_TIME)) { 2164 mLastWriteTime = now; 2165 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 2166 } 2167 } 2168 } 2169 } 2170 2171 @Override 2172 public void batteryNeedsCpuUpdate() { 2173 updateCpuStatsNow(); 2174 } 2175 2176 @Override 2177 public void batteryPowerChanged(boolean onBattery) { 2178 // When plugging in, update the CPU stats first before changing 2179 // the plug state. 2180 updateCpuStatsNow(); 2181 synchronized (this) { 2182 synchronized(mPidsSelfLocked) { 2183 mOnBattery = DEBUG_POWER ? true : onBattery; 2184 } 2185 } 2186 } 2187 2188 /** 2189 * Initialize the application bind args. These are passed to each 2190 * process when the bindApplication() IPC is sent to the process. They're 2191 * lazily setup to make sure the services are running when they're asked for. 2192 */ 2193 private HashMap<String, IBinder> getCommonServicesLocked() { 2194 if (mAppBindArgs == null) { 2195 mAppBindArgs = new HashMap<String, IBinder>(); 2196 2197 // Setup the application init args 2198 mAppBindArgs.put("package", ServiceManager.getService("package")); 2199 mAppBindArgs.put("window", ServiceManager.getService("window")); 2200 mAppBindArgs.put(Context.ALARM_SERVICE, 2201 ServiceManager.getService(Context.ALARM_SERVICE)); 2202 } 2203 return mAppBindArgs; 2204 } 2205 2206 final void setFocusedActivityLocked(ActivityRecord r) { 2207 if (mFocusedActivity != r) { 2208 if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r); 2209 mFocusedActivity = r; 2210 mStackSupervisor.setFocusedStack(r); 2211 if (r != null) { 2212 mWindowManager.setFocusedApp(r.appToken, true); 2213 } 2214 applyUpdateLockStateLocked(r); 2215 } 2216 } 2217 2218 @Override 2219 public void setFocusedStack(int stackId) { 2220 if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId); 2221 synchronized (ActivityManagerService.this) { 2222 ActivityStack stack = mStackSupervisor.getStack(stackId); 2223 if (stack != null) { 2224 ActivityRecord r = stack.topRunningActivityLocked(null); 2225 if (r != null) { 2226 setFocusedActivityLocked(r); 2227 } 2228 } 2229 } 2230 } 2231 2232 @Override 2233 public void notifyActivityDrawn(IBinder token) { 2234 if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token); 2235 synchronized (this) { 2236 ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token); 2237 if (r != null) { 2238 r.task.stack.notifyActivityDrawnLocked(r); 2239 } 2240 } 2241 } 2242 2243 final void applyUpdateLockStateLocked(ActivityRecord r) { 2244 // Modifications to the UpdateLock state are done on our handler, outside 2245 // the activity manager's locks. The new state is determined based on the 2246 // state *now* of the relevant activity record. The object is passed to 2247 // the handler solely for logging detail, not to be consulted/modified. 2248 final boolean nextState = r != null && r.immersive; 2249 mHandler.sendMessage( 2250 mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r)); 2251 } 2252 2253 final void showAskCompatModeDialogLocked(ActivityRecord r) { 2254 Message msg = Message.obtain(); 2255 msg.what = SHOW_COMPAT_MODE_DIALOG_MSG; 2256 msg.obj = r.task.askedCompatMode ? null : r; 2257 mHandler.sendMessage(msg); 2258 } 2259 2260 private final int updateLruProcessInternalLocked(ProcessRecord app, long now, int index, 2261 String what, Object obj, ProcessRecord srcApp) { 2262 app.lastActivityTime = now; 2263 2264 if (app.activities.size() > 0) { 2265 // Don't want to touch dependent processes that are hosting activities. 2266 return index; 2267 } 2268 2269 int lrui = mLruProcesses.lastIndexOf(app); 2270 if (lrui < 0) { 2271 Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: " 2272 + what + " " + obj + " from " + srcApp); 2273 return index; 2274 } 2275 2276 if (lrui >= index) { 2277 // Don't want to cause this to move dependent processes *back* in the 2278 // list as if they were less frequently used. 2279 return index; 2280 } 2281 2282 if (lrui >= mLruProcessActivityStart) { 2283 // Don't want to touch dependent processes that are hosting activities. 2284 return index; 2285 } 2286 2287 mLruProcesses.remove(lrui); 2288 if (index > 0) { 2289 index--; 2290 } 2291 if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index 2292 + " in LRU list: " + app); 2293 mLruProcesses.add(index, app); 2294 return index; 2295 } 2296 2297 final void removeLruProcessLocked(ProcessRecord app) { 2298 int lrui = mLruProcesses.lastIndexOf(app); 2299 if (lrui >= 0) { 2300 if (lrui <= mLruProcessActivityStart) { 2301 mLruProcessActivityStart--; 2302 } 2303 if (lrui <= mLruProcessServiceStart) { 2304 mLruProcessServiceStart--; 2305 } 2306 mLruProcesses.remove(lrui); 2307 } 2308 } 2309 2310 final void updateLruProcessLocked(ProcessRecord app, boolean activityChange, 2311 ProcessRecord client) { 2312 final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities; 2313 final boolean hasService = false; // not impl yet. app.services.size() > 0; 2314 if (!activityChange && hasActivity) { 2315 // The process has activties, so we are only going to allow activity-based 2316 // adjustments move it. It should be kept in the front of the list with other 2317 // processes that have activities, and we don't want those to change their 2318 // order except due to activity operations. 2319 return; 2320 } 2321 2322 mLruSeq++; 2323 final long now = SystemClock.uptimeMillis(); 2324 app.lastActivityTime = now; 2325 2326 // First a quick reject: if the app is already at the position we will 2327 // put it, then there is nothing to do. 2328 if (hasActivity) { 2329 final int N = mLruProcesses.size(); 2330 if (N > 0 && mLruProcesses.get(N-1) == app) { 2331 if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app); 2332 return; 2333 } 2334 } else { 2335 if (mLruProcessServiceStart > 0 2336 && mLruProcesses.get(mLruProcessServiceStart-1) == app) { 2337 if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app); 2338 return; 2339 } 2340 } 2341 2342 int lrui = mLruProcesses.lastIndexOf(app); 2343 2344 if (app.persistent && lrui >= 0) { 2345 // We don't care about the position of persistent processes, as long as 2346 // they are in the list. 2347 if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app); 2348 return; 2349 } 2350 2351 /* In progress: compute new position first, so we can avoid doing work 2352 if the process is not actually going to move. Not yet working. 2353 int addIndex; 2354 int nextIndex; 2355 boolean inActivity = false, inService = false; 2356 if (hasActivity) { 2357 // Process has activities, put it at the very tipsy-top. 2358 addIndex = mLruProcesses.size(); 2359 nextIndex = mLruProcessServiceStart; 2360 inActivity = true; 2361 } else if (hasService) { 2362 // Process has services, put it at the top of the service list. 2363 addIndex = mLruProcessActivityStart; 2364 nextIndex = mLruProcessServiceStart; 2365 inActivity = true; 2366 inService = true; 2367 } else { 2368 // Process not otherwise of interest, it goes to the top of the non-service area. 2369 addIndex = mLruProcessServiceStart; 2370 if (client != null) { 2371 int clientIndex = mLruProcesses.lastIndexOf(client); 2372 if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating " 2373 + app); 2374 if (clientIndex >= 0 && addIndex > clientIndex) { 2375 addIndex = clientIndex; 2376 } 2377 } 2378 nextIndex = addIndex > 0 ? addIndex-1 : addIndex; 2379 } 2380 2381 Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act=" 2382 + mLruProcessActivityStart + "): " + app); 2383 */ 2384 2385 if (lrui >= 0) { 2386 if (lrui < mLruProcessActivityStart) { 2387 mLruProcessActivityStart--; 2388 } 2389 if (lrui < mLruProcessServiceStart) { 2390 mLruProcessServiceStart--; 2391 } 2392 /* 2393 if (addIndex > lrui) { 2394 addIndex--; 2395 } 2396 if (nextIndex > lrui) { 2397 nextIndex--; 2398 } 2399 */ 2400 mLruProcesses.remove(lrui); 2401 } 2402 2403 /* 2404 mLruProcesses.add(addIndex, app); 2405 if (inActivity) { 2406 mLruProcessActivityStart++; 2407 } 2408 if (inService) { 2409 mLruProcessActivityStart++; 2410 } 2411 */ 2412 2413 int nextIndex; 2414 if (hasActivity) { 2415 final int N = mLruProcesses.size(); 2416 if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) { 2417 // Process doesn't have activities, but has clients with 2418 // activities... move it up, but one below the top (the top 2419 // should always have a real activity). 2420 if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app); 2421 mLruProcesses.add(N-1, app); 2422 // To keep it from spamming the LRU list (by making a bunch of clients), 2423 // we will push down any other entries owned by the app. 2424 final int uid = app.info.uid; 2425 for (int i=N-2; i>mLruProcessActivityStart; i--) { 2426 ProcessRecord subProc = mLruProcesses.get(i); 2427 if (subProc.info.uid == uid) { 2428 // We want to push this one down the list. If the process after 2429 // it is for the same uid, however, don't do so, because we don't 2430 // want them internally to be re-ordered. 2431 if (mLruProcesses.get(i-1).info.uid != uid) { 2432 if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i 2433 + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1)); 2434 ProcessRecord tmp = mLruProcesses.get(i); 2435 mLruProcesses.set(i, mLruProcesses.get(i-1)); 2436 mLruProcesses.set(i-1, tmp); 2437 i--; 2438 } 2439 } else { 2440 // A gap, we can stop here. 2441 break; 2442 } 2443 } 2444 } else { 2445 // Process has activities, put it at the very tipsy-top. 2446 if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app); 2447 mLruProcesses.add(app); 2448 } 2449 nextIndex = mLruProcessServiceStart; 2450 } else if (hasService) { 2451 // Process has services, put it at the top of the service list. 2452 if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app); 2453 mLruProcesses.add(mLruProcessActivityStart, app); 2454 nextIndex = mLruProcessServiceStart; 2455 mLruProcessActivityStart++; 2456 } else { 2457 // Process not otherwise of interest, it goes to the top of the non-service area. 2458 int index = mLruProcessServiceStart; 2459 if (client != null) { 2460 // If there is a client, don't allow the process to be moved up higher 2461 // in the list than that client. 2462 int clientIndex = mLruProcesses.lastIndexOf(client); 2463 if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client 2464 + " when updating " + app); 2465 if (clientIndex <= lrui) { 2466 // Don't allow the client index restriction to push it down farther in the 2467 // list than it already is. 2468 clientIndex = lrui; 2469 } 2470 if (clientIndex >= 0 && index > clientIndex) { 2471 index = clientIndex; 2472 } 2473 } 2474 if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app); 2475 mLruProcesses.add(index, app); 2476 nextIndex = index-1; 2477 mLruProcessActivityStart++; 2478 mLruProcessServiceStart++; 2479 } 2480 2481 // If the app is currently using a content provider or service, 2482 // bump those processes as well. 2483 for (int j=app.connections.size()-1; j>=0; j--) { 2484 ConnectionRecord cr = app.connections.valueAt(j); 2485 if (cr.binding != null && !cr.serviceDead && cr.binding.service != null 2486 && cr.binding.service.app != null 2487 && cr.binding.service.app.lruSeq != mLruSeq 2488 && !cr.binding.service.app.persistent) { 2489 nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex, 2490 "service connection", cr, app); 2491 } 2492 } 2493 for (int j=app.conProviders.size()-1; j>=0; j--) { 2494 ContentProviderRecord cpr = app.conProviders.get(j).provider; 2495 if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) { 2496 nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex, 2497 "provider reference", cpr, app); 2498 } 2499 } 2500 } 2501 2502 final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) { 2503 if (uid == Process.SYSTEM_UID) { 2504 // The system gets to run in any process. If there are multiple 2505 // processes with the same uid, just pick the first (this 2506 // should never happen). 2507 SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName); 2508 if (procs == null) return null; 2509 final int N = procs.size(); 2510 for (int i = 0; i < N; i++) { 2511 if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i); 2512 } 2513 } 2514 ProcessRecord proc = mProcessNames.get(processName, uid); 2515 if (false && proc != null && !keepIfLarge 2516 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY 2517 && proc.lastCachedPss >= 4000) { 2518 // Turn this condition on to cause killing to happen regularly, for testing. 2519 if (proc.baseProcessTracker != null) { 2520 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss); 2521 } 2522 killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss) 2523 + "k from cached"); 2524 } else if (proc != null && !keepIfLarge 2525 && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL 2526 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) { 2527 if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss); 2528 if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) { 2529 if (proc.baseProcessTracker != null) { 2530 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss); 2531 } 2532 killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss) 2533 + "k from cached"); 2534 } 2535 } 2536 return proc; 2537 } 2538 2539 void ensurePackageDexOpt(String packageName) { 2540 IPackageManager pm = AppGlobals.getPackageManager(); 2541 try { 2542 if (pm.performDexOpt(packageName)) { 2543 mDidDexOpt = true; 2544 } 2545 } catch (RemoteException e) { 2546 } 2547 } 2548 2549 boolean isNextTransitionForward() { 2550 int transit = mWindowManager.getPendingAppTransition(); 2551 return transit == AppTransition.TRANSIT_ACTIVITY_OPEN 2552 || transit == AppTransition.TRANSIT_TASK_OPEN 2553 || transit == AppTransition.TRANSIT_TASK_TO_FRONT; 2554 } 2555 2556 final ProcessRecord startProcessLocked(String processName, 2557 ApplicationInfo info, boolean knownToBeDead, int intentFlags, 2558 String hostingType, ComponentName hostingName, boolean allowWhileBooting, 2559 boolean isolated, boolean keepIfLarge) { 2560 ProcessRecord app; 2561 if (!isolated) { 2562 app = getProcessRecordLocked(processName, info.uid, keepIfLarge); 2563 } else { 2564 // If this is an isolated process, it can't re-use an existing process. 2565 app = null; 2566 } 2567 // We don't have to do anything more if: 2568 // (1) There is an existing application record; and 2569 // (2) The caller doesn't think it is dead, OR there is no thread 2570 // object attached to it so we know it couldn't have crashed; and 2571 // (3) There is a pid assigned to it, so it is either starting or 2572 // already running. 2573 if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName 2574 + " app=" + app + " knownToBeDead=" + knownToBeDead 2575 + " thread=" + (app != null ? app.thread : null) 2576 + " pid=" + (app != null ? app.pid : -1)); 2577 if (app != null && app.pid > 0) { 2578 if (!knownToBeDead || app.thread == null) { 2579 // We already have the app running, or are waiting for it to 2580 // come up (we have a pid but not yet its thread), so keep it. 2581 if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app); 2582 // If this is a new package in the process, add the package to the list 2583 app.addPackage(info.packageName, mProcessStats); 2584 return app; 2585 } 2586 2587 // An application record is attached to a previous process, 2588 // clean it up now. 2589 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app); 2590 handleAppDiedLocked(app, true, true); 2591 } 2592 2593 String hostingNameStr = hostingName != null 2594 ? hostingName.flattenToShortString() : null; 2595 2596 if (!isolated) { 2597 if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) { 2598 // If we are in the background, then check to see if this process 2599 // is bad. If so, we will just silently fail. 2600 if (mBadProcesses.get(info.processName, info.uid) != null) { 2601 if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid 2602 + "/" + info.processName); 2603 return null; 2604 } 2605 } else { 2606 // When the user is explicitly starting a process, then clear its 2607 // crash count so that we won't make it bad until they see at 2608 // least one crash dialog again, and make the process good again 2609 // if it had been bad. 2610 if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid 2611 + "/" + info.processName); 2612 mProcessCrashTimes.remove(info.processName, info.uid); 2613 if (mBadProcesses.get(info.processName, info.uid) != null) { 2614 EventLog.writeEvent(EventLogTags.AM_PROC_GOOD, 2615 UserHandle.getUserId(info.uid), info.uid, 2616 info.processName); 2617 mBadProcesses.remove(info.processName, info.uid); 2618 if (app != null) { 2619 app.bad = false; 2620 } 2621 } 2622 } 2623 } 2624 2625 if (app == null) { 2626 app = newProcessRecordLocked(info, processName, isolated); 2627 if (app == null) { 2628 Slog.w(TAG, "Failed making new process record for " 2629 + processName + "/" + info.uid + " isolated=" + isolated); 2630 return null; 2631 } 2632 mProcessNames.put(processName, app.uid, app); 2633 if (isolated) { 2634 mIsolatedProcesses.put(app.uid, app); 2635 } 2636 } else { 2637 // If this is a new package in the process, add the package to the list 2638 app.addPackage(info.packageName, mProcessStats); 2639 } 2640 2641 // If the system is not ready yet, then hold off on starting this 2642 // process until it is. 2643 if (!mProcessesReady 2644 && !isAllowedWhileBooting(info) 2645 && !allowWhileBooting) { 2646 if (!mProcessesOnHold.contains(app)) { 2647 mProcessesOnHold.add(app); 2648 } 2649 if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app); 2650 return app; 2651 } 2652 2653 startProcessLocked(app, hostingType, hostingNameStr, null /* ABI override */); 2654 return (app.pid != 0) ? app : null; 2655 } 2656 2657 boolean isAllowedWhileBooting(ApplicationInfo ai) { 2658 return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0; 2659 } 2660 2661 private final void startProcessLocked(ProcessRecord app, 2662 String hostingType, String hostingNameStr, String abiOverride) { 2663 if (app.pid > 0 && app.pid != MY_PID) { 2664 synchronized (mPidsSelfLocked) { 2665 mPidsSelfLocked.remove(app.pid); 2666 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 2667 } 2668 app.setPid(0); 2669 } 2670 2671 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 2672 "startProcessLocked removing on hold: " + app); 2673 mProcessesOnHold.remove(app); 2674 2675 updateCpuStats(); 2676 2677 try { 2678 int uid = app.uid; 2679 2680 int[] gids = null; 2681 int mountExternal = Zygote.MOUNT_EXTERNAL_NONE; 2682 if (!app.isolated) { 2683 int[] permGids = null; 2684 try { 2685 final PackageManager pm = mContext.getPackageManager(); 2686 permGids = pm.getPackageGids(app.info.packageName); 2687 2688 if (Environment.isExternalStorageEmulated()) { 2689 if (pm.checkPermission( 2690 android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE, 2691 app.info.packageName) == PERMISSION_GRANTED) { 2692 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL; 2693 } else { 2694 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER; 2695 } 2696 } 2697 } catch (PackageManager.NameNotFoundException e) { 2698 Slog.w(TAG, "Unable to retrieve gids", e); 2699 } 2700 2701 /* 2702 * Add shared application and profile GIDs so applications can share some 2703 * resources like shared libraries and access user-wide resources 2704 */ 2705 if (permGids == null) { 2706 gids = new int[2]; 2707 } else { 2708 gids = new int[permGids.length + 2]; 2709 System.arraycopy(permGids, 0, gids, 2, permGids.length); 2710 } 2711 gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid)); 2712 gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid)); 2713 } 2714 if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) { 2715 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL 2716 && mTopComponent != null 2717 && app.processName.equals(mTopComponent.getPackageName())) { 2718 uid = 0; 2719 } 2720 if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL 2721 && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) { 2722 uid = 0; 2723 } 2724 } 2725 int debugFlags = 0; 2726 if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) { 2727 debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER; 2728 // Also turn on CheckJNI for debuggable apps. It's quite 2729 // awkward to turn on otherwise. 2730 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 2731 } 2732 // Run the app in safe mode if its manifest requests so or the 2733 // system is booted in safe mode. 2734 if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 || 2735 mSafeMode == true) { 2736 debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE; 2737 } 2738 if ("1".equals(SystemProperties.get("debug.checkjni"))) { 2739 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 2740 } 2741 if ("1".equals(SystemProperties.get("debug.jni.logging"))) { 2742 debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING; 2743 } 2744 if ("1".equals(SystemProperties.get("debug.assert"))) { 2745 debugFlags |= Zygote.DEBUG_ENABLE_ASSERT; 2746 } 2747 2748 String requiredAbi = (abiOverride != null) ? abiOverride : app.info.cpuAbi; 2749 if (requiredAbi == null) { 2750 requiredAbi = Build.SUPPORTED_ABIS[0]; 2751 } 2752 2753 // Start the process. It will either succeed and return a result containing 2754 // the PID of the new process, or else throw a RuntimeException. 2755 Process.ProcessStartResult startResult = Process.start("android.app.ActivityThread", 2756 app.processName, uid, uid, gids, debugFlags, mountExternal, 2757 app.info.targetSdkVersion, app.info.seinfo, requiredAbi, null); 2758 2759 BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics(); 2760 synchronized (bs) { 2761 if (bs.isOnBattery()) { 2762 bs.getProcessStatsLocked(app.uid, app.processName).incStartsLocked(); 2763 } 2764 } 2765 2766 EventLog.writeEvent(EventLogTags.AM_PROC_START, 2767 UserHandle.getUserId(uid), startResult.pid, uid, 2768 app.processName, hostingType, 2769 hostingNameStr != null ? hostingNameStr : ""); 2770 2771 if (app.persistent) { 2772 Watchdog.getInstance().processStarted(app.processName, startResult.pid); 2773 } 2774 2775 StringBuilder buf = mStringBuilder; 2776 buf.setLength(0); 2777 buf.append("Start proc "); 2778 buf.append(app.processName); 2779 buf.append(" for "); 2780 buf.append(hostingType); 2781 if (hostingNameStr != null) { 2782 buf.append(" "); 2783 buf.append(hostingNameStr); 2784 } 2785 buf.append(": pid="); 2786 buf.append(startResult.pid); 2787 buf.append(" uid="); 2788 buf.append(uid); 2789 buf.append(" gids={"); 2790 if (gids != null) { 2791 for (int gi=0; gi<gids.length; gi++) { 2792 if (gi != 0) buf.append(", "); 2793 buf.append(gids[gi]); 2794 2795 } 2796 } 2797 buf.append("}"); 2798 if (requiredAbi != null) { 2799 buf.append(" abi="); 2800 buf.append(requiredAbi); 2801 } 2802 Slog.i(TAG, buf.toString()); 2803 app.setPid(startResult.pid); 2804 app.usingWrapper = startResult.usingWrapper; 2805 app.removed = false; 2806 app.killedByAm = false; 2807 synchronized (mPidsSelfLocked) { 2808 this.mPidsSelfLocked.put(startResult.pid, app); 2809 Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 2810 msg.obj = app; 2811 mHandler.sendMessageDelayed(msg, startResult.usingWrapper 2812 ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT); 2813 } 2814 } catch (RuntimeException e) { 2815 // XXX do better error recovery. 2816 app.setPid(0); 2817 Slog.e(TAG, "Failure starting process " + app.processName, e); 2818 } 2819 } 2820 2821 void updateUsageStats(ActivityRecord component, boolean resumed) { 2822 if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed); 2823 final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 2824 if (resumed) { 2825 mUsageStatsService.noteResumeComponent(component.realActivity); 2826 synchronized (stats) { 2827 stats.noteActivityResumedLocked(component.app.uid); 2828 } 2829 } else { 2830 mUsageStatsService.notePauseComponent(component.realActivity); 2831 synchronized (stats) { 2832 stats.noteActivityPausedLocked(component.app.uid); 2833 } 2834 } 2835 } 2836 2837 Intent getHomeIntent() { 2838 Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null); 2839 intent.setComponent(mTopComponent); 2840 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 2841 intent.addCategory(Intent.CATEGORY_HOME); 2842 } 2843 return intent; 2844 } 2845 2846 boolean startHomeActivityLocked(int userId) { 2847 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL 2848 && mTopAction == null) { 2849 // We are running in factory test mode, but unable to find 2850 // the factory test app, so just sit around displaying the 2851 // error message and don't try to start anything. 2852 return false; 2853 } 2854 Intent intent = getHomeIntent(); 2855 ActivityInfo aInfo = 2856 resolveActivityInfo(intent, STOCK_PM_FLAGS, userId); 2857 if (aInfo != null) { 2858 intent.setComponent(new ComponentName( 2859 aInfo.applicationInfo.packageName, aInfo.name)); 2860 // Don't do this if the home app is currently being 2861 // instrumented. 2862 aInfo = new ActivityInfo(aInfo); 2863 aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId); 2864 ProcessRecord app = getProcessRecordLocked(aInfo.processName, 2865 aInfo.applicationInfo.uid, true); 2866 if (app == null || app.instrumentationClass == null) { 2867 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK); 2868 mStackSupervisor.startHomeActivity(intent, aInfo); 2869 } 2870 } 2871 2872 return true; 2873 } 2874 2875 private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) { 2876 ActivityInfo ai = null; 2877 ComponentName comp = intent.getComponent(); 2878 try { 2879 if (comp != null) { 2880 ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId); 2881 } else { 2882 ResolveInfo info = AppGlobals.getPackageManager().resolveIntent( 2883 intent, 2884 intent.resolveTypeIfNeeded(mContext.getContentResolver()), 2885 flags, userId); 2886 2887 if (info != null) { 2888 ai = info.activityInfo; 2889 } 2890 } 2891 } catch (RemoteException e) { 2892 // ignore 2893 } 2894 2895 return ai; 2896 } 2897 2898 /** 2899 * Starts the "new version setup screen" if appropriate. 2900 */ 2901 void startSetupActivityLocked() { 2902 // Only do this once per boot. 2903 if (mCheckedForSetup) { 2904 return; 2905 } 2906 2907 // We will show this screen if the current one is a different 2908 // version than the last one shown, and we are not running in 2909 // low-level factory test mode. 2910 final ContentResolver resolver = mContext.getContentResolver(); 2911 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL && 2912 Settings.Global.getInt(resolver, 2913 Settings.Global.DEVICE_PROVISIONED, 0) != 0) { 2914 mCheckedForSetup = true; 2915 2916 // See if we should be showing the platform update setup UI. 2917 Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP); 2918 List<ResolveInfo> ris = mContext.getPackageManager() 2919 .queryIntentActivities(intent, PackageManager.GET_META_DATA); 2920 2921 // We don't allow third party apps to replace this. 2922 ResolveInfo ri = null; 2923 for (int i=0; ris != null && i<ris.size(); i++) { 2924 if ((ris.get(i).activityInfo.applicationInfo.flags 2925 & ApplicationInfo.FLAG_SYSTEM) != 0) { 2926 ri = ris.get(i); 2927 break; 2928 } 2929 } 2930 2931 if (ri != null) { 2932 String vers = ri.activityInfo.metaData != null 2933 ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION) 2934 : null; 2935 if (vers == null && ri.activityInfo.applicationInfo.metaData != null) { 2936 vers = ri.activityInfo.applicationInfo.metaData.getString( 2937 Intent.METADATA_SETUP_VERSION); 2938 } 2939 String lastVers = Settings.Secure.getString( 2940 resolver, Settings.Secure.LAST_SETUP_SHOWN); 2941 if (vers != null && !vers.equals(lastVers)) { 2942 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 2943 intent.setComponent(new ComponentName( 2944 ri.activityInfo.packageName, ri.activityInfo.name)); 2945 mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo, 2946 null, null, 0, 0, 0, null, 0, null, false, null, null); 2947 } 2948 } 2949 } 2950 } 2951 2952 CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) { 2953 return mCompatModePackages.compatibilityInfoForPackageLocked(ai); 2954 } 2955 2956 void enforceNotIsolatedCaller(String caller) { 2957 if (UserHandle.isIsolated(Binder.getCallingUid())) { 2958 throw new SecurityException("Isolated process not allowed to call " + caller); 2959 } 2960 } 2961 2962 @Override 2963 public int getFrontActivityScreenCompatMode() { 2964 enforceNotIsolatedCaller("getFrontActivityScreenCompatMode"); 2965 synchronized (this) { 2966 return mCompatModePackages.getFrontActivityScreenCompatModeLocked(); 2967 } 2968 } 2969 2970 @Override 2971 public void setFrontActivityScreenCompatMode(int mode) { 2972 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 2973 "setFrontActivityScreenCompatMode"); 2974 synchronized (this) { 2975 mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode); 2976 } 2977 } 2978 2979 @Override 2980 public int getPackageScreenCompatMode(String packageName) { 2981 enforceNotIsolatedCaller("getPackageScreenCompatMode"); 2982 synchronized (this) { 2983 return mCompatModePackages.getPackageScreenCompatModeLocked(packageName); 2984 } 2985 } 2986 2987 @Override 2988 public void setPackageScreenCompatMode(String packageName, int mode) { 2989 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 2990 "setPackageScreenCompatMode"); 2991 synchronized (this) { 2992 mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode); 2993 } 2994 } 2995 2996 @Override 2997 public boolean getPackageAskScreenCompat(String packageName) { 2998 enforceNotIsolatedCaller("getPackageAskScreenCompat"); 2999 synchronized (this) { 3000 return mCompatModePackages.getPackageAskCompatModeLocked(packageName); 3001 } 3002 } 3003 3004 @Override 3005 public void setPackageAskScreenCompat(String packageName, boolean ask) { 3006 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3007 "setPackageAskScreenCompat"); 3008 synchronized (this) { 3009 mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask); 3010 } 3011 } 3012 3013 private void dispatchProcessesChanged() { 3014 int N; 3015 synchronized (this) { 3016 N = mPendingProcessChanges.size(); 3017 if (mActiveProcessChanges.length < N) { 3018 mActiveProcessChanges = new ProcessChangeItem[N]; 3019 } 3020 mPendingProcessChanges.toArray(mActiveProcessChanges); 3021 mAvailProcessChanges.addAll(mPendingProcessChanges); 3022 mPendingProcessChanges.clear(); 3023 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes"); 3024 } 3025 3026 int i = mProcessObservers.beginBroadcast(); 3027 while (i > 0) { 3028 i--; 3029 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 3030 if (observer != null) { 3031 try { 3032 for (int j=0; j<N; j++) { 3033 ProcessChangeItem item = mActiveProcessChanges[j]; 3034 if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) { 3035 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid=" 3036 + item.pid + " uid=" + item.uid + ": " 3037 + item.foregroundActivities); 3038 observer.onForegroundActivitiesChanged(item.pid, item.uid, 3039 item.foregroundActivities); 3040 } 3041 if ((item.changes&ProcessChangeItem.CHANGE_IMPORTANCE) != 0) { 3042 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "IMPORTANCE CHANGED pid=" 3043 + item.pid + " uid=" + item.uid + ": " + item.importance); 3044 observer.onImportanceChanged(item.pid, item.uid, 3045 item.importance); 3046 } 3047 } 3048 } catch (RemoteException e) { 3049 } 3050 } 3051 } 3052 mProcessObservers.finishBroadcast(); 3053 } 3054 3055 private void dispatchProcessDied(int pid, int uid) { 3056 int i = mProcessObservers.beginBroadcast(); 3057 while (i > 0) { 3058 i--; 3059 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 3060 if (observer != null) { 3061 try { 3062 observer.onProcessDied(pid, uid); 3063 } catch (RemoteException e) { 3064 } 3065 } 3066 } 3067 mProcessObservers.finishBroadcast(); 3068 } 3069 3070 final void doPendingActivityLaunchesLocked(boolean doResume) { 3071 final int N = mPendingActivityLaunches.size(); 3072 if (N <= 0) { 3073 return; 3074 } 3075 for (int i=0; i<N; i++) { 3076 PendingActivityLaunch pal = mPendingActivityLaunches.get(i); 3077 mStackSupervisor.startActivityUncheckedLocked(pal.r, pal.sourceRecord, pal.startFlags, 3078 doResume && i == (N-1), null); 3079 } 3080 mPendingActivityLaunches.clear(); 3081 } 3082 3083 @Override 3084 public final int startActivity(IApplicationThread caller, String callingPackage, 3085 Intent intent, String resolvedType, IBinder resultTo, 3086 String resultWho, int requestCode, int startFlags, 3087 String profileFile, ParcelFileDescriptor profileFd, Bundle options) { 3088 return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo, 3089 resultWho, requestCode, 3090 startFlags, profileFile, profileFd, options, UserHandle.getCallingUserId()); 3091 } 3092 3093 @Override 3094 public final int startActivityAsUser(IApplicationThread caller, String callingPackage, 3095 Intent intent, String resolvedType, IBinder resultTo, 3096 String resultWho, int requestCode, int startFlags, 3097 String profileFile, ParcelFileDescriptor profileFd, Bundle options, int userId) { 3098 enforceNotIsolatedCaller("startActivity"); 3099 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3100 false, true, "startActivity", null); 3101 // TODO: Switch to user app stacks here. 3102 return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType, 3103 resultTo, resultWho, requestCode, startFlags, profileFile, profileFd, 3104 null, null, options, userId, null); 3105 } 3106 3107 @Override 3108 public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage, 3109 Intent intent, String resolvedType, IBinder resultTo, 3110 String resultWho, int requestCode, int startFlags, String profileFile, 3111 ParcelFileDescriptor profileFd, Bundle options, int userId) { 3112 enforceNotIsolatedCaller("startActivityAndWait"); 3113 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3114 false, true, "startActivityAndWait", null); 3115 WaitResult res = new WaitResult(); 3116 // TODO: Switch to user app stacks here. 3117 mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType, 3118 resultTo, resultWho, requestCode, startFlags, profileFile, profileFd, 3119 res, null, options, UserHandle.getCallingUserId(), null); 3120 return res; 3121 } 3122 3123 @Override 3124 public final int startActivityWithConfig(IApplicationThread caller, String callingPackage, 3125 Intent intent, String resolvedType, IBinder resultTo, 3126 String resultWho, int requestCode, int startFlags, Configuration config, 3127 Bundle options, int userId) { 3128 enforceNotIsolatedCaller("startActivityWithConfig"); 3129 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3130 false, true, "startActivityWithConfig", null); 3131 // TODO: Switch to user app stacks here. 3132 int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, 3133 resolvedType, resultTo, resultWho, requestCode, startFlags, 3134 null, null, null, config, options, userId, null); 3135 return ret; 3136 } 3137 3138 @Override 3139 public int startActivityIntentSender(IApplicationThread caller, 3140 IntentSender intent, Intent fillInIntent, String resolvedType, 3141 IBinder resultTo, String resultWho, int requestCode, 3142 int flagsMask, int flagsValues, Bundle options) { 3143 enforceNotIsolatedCaller("startActivityIntentSender"); 3144 // Refuse possible leaked file descriptors 3145 if (fillInIntent != null && fillInIntent.hasFileDescriptors()) { 3146 throw new IllegalArgumentException("File descriptors passed in Intent"); 3147 } 3148 3149 IIntentSender sender = intent.getTarget(); 3150 if (!(sender instanceof PendingIntentRecord)) { 3151 throw new IllegalArgumentException("Bad PendingIntent object"); 3152 } 3153 3154 PendingIntentRecord pir = (PendingIntentRecord)sender; 3155 3156 synchronized (this) { 3157 // If this is coming from the currently resumed activity, it is 3158 // effectively saying that app switches are allowed at this point. 3159 final ActivityStack stack = getFocusedStack(); 3160 if (stack.mResumedActivity != null && 3161 stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) { 3162 mAppSwitchesAllowedTime = 0; 3163 } 3164 } 3165 int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null, 3166 resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null); 3167 return ret; 3168 } 3169 3170 @Override 3171 public boolean startNextMatchingActivity(IBinder callingActivity, 3172 Intent intent, Bundle options) { 3173 // Refuse possible leaked file descriptors 3174 if (intent != null && intent.hasFileDescriptors() == true) { 3175 throw new IllegalArgumentException("File descriptors passed in Intent"); 3176 } 3177 3178 synchronized (this) { 3179 final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity); 3180 if (r == null) { 3181 ActivityOptions.abort(options); 3182 return false; 3183 } 3184 if (r.app == null || r.app.thread == null) { 3185 // The caller is not running... d'oh! 3186 ActivityOptions.abort(options); 3187 return false; 3188 } 3189 intent = new Intent(intent); 3190 // The caller is not allowed to change the data. 3191 intent.setDataAndType(r.intent.getData(), r.intent.getType()); 3192 // And we are resetting to find the next component... 3193 intent.setComponent(null); 3194 3195 final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0); 3196 3197 ActivityInfo aInfo = null; 3198 try { 3199 List<ResolveInfo> resolves = 3200 AppGlobals.getPackageManager().queryIntentActivities( 3201 intent, r.resolvedType, 3202 PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS, 3203 UserHandle.getCallingUserId()); 3204 3205 // Look for the original activity in the list... 3206 final int N = resolves != null ? resolves.size() : 0; 3207 for (int i=0; i<N; i++) { 3208 ResolveInfo rInfo = resolves.get(i); 3209 if (rInfo.activityInfo.packageName.equals(r.packageName) 3210 && rInfo.activityInfo.name.equals(r.info.name)) { 3211 // We found the current one... the next matching is 3212 // after it. 3213 i++; 3214 if (i<N) { 3215 aInfo = resolves.get(i).activityInfo; 3216 } 3217 if (debug) { 3218 Slog.v(TAG, "Next matching activity: found current " + r.packageName 3219 + "/" + r.info.name); 3220 Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName 3221 + "/" + aInfo.name); 3222 } 3223 break; 3224 } 3225 } 3226 } catch (RemoteException e) { 3227 } 3228 3229 if (aInfo == null) { 3230 // Nobody who is next! 3231 ActivityOptions.abort(options); 3232 if (debug) Slog.d(TAG, "Next matching activity: nothing found"); 3233 return false; 3234 } 3235 3236 intent.setComponent(new ComponentName( 3237 aInfo.applicationInfo.packageName, aInfo.name)); 3238 intent.setFlags(intent.getFlags()&~( 3239 Intent.FLAG_ACTIVITY_FORWARD_RESULT| 3240 Intent.FLAG_ACTIVITY_CLEAR_TOP| 3241 Intent.FLAG_ACTIVITY_MULTIPLE_TASK| 3242 Intent.FLAG_ACTIVITY_NEW_TASK)); 3243 3244 // Okay now we need to start the new activity, replacing the 3245 // currently running activity. This is a little tricky because 3246 // we want to start the new one as if the current one is finished, 3247 // but not finish the current one first so that there is no flicker. 3248 // And thus... 3249 final boolean wasFinishing = r.finishing; 3250 r.finishing = true; 3251 3252 // Propagate reply information over to the new activity. 3253 final ActivityRecord resultTo = r.resultTo; 3254 final String resultWho = r.resultWho; 3255 final int requestCode = r.requestCode; 3256 r.resultTo = null; 3257 if (resultTo != null) { 3258 resultTo.removeResultsLocked(r, resultWho, requestCode); 3259 } 3260 3261 final long origId = Binder.clearCallingIdentity(); 3262 int res = mStackSupervisor.startActivityLocked(r.app.thread, intent, 3263 r.resolvedType, aInfo, resultTo != null ? resultTo.appToken : null, 3264 resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage, 0, 3265 options, false, null, null); 3266 Binder.restoreCallingIdentity(origId); 3267 3268 r.finishing = wasFinishing; 3269 if (res != ActivityManager.START_SUCCESS) { 3270 return false; 3271 } 3272 return true; 3273 } 3274 } 3275 3276 final int startActivityInPackage(int uid, String callingPackage, 3277 Intent intent, String resolvedType, IBinder resultTo, 3278 String resultWho, int requestCode, int startFlags, Bundle options, int userId, 3279 IActivityContainer container) { 3280 3281 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3282 false, true, "startActivityInPackage", null); 3283 3284 // TODO: Switch to user app stacks here. 3285 int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent, resolvedType, 3286 resultTo, resultWho, requestCode, startFlags, 3287 null, null, null, null, options, userId, container); 3288 return ret; 3289 } 3290 3291 @Override 3292 public final int startActivities(IApplicationThread caller, String callingPackage, 3293 Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options, 3294 int userId) { 3295 enforceNotIsolatedCaller("startActivities"); 3296 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3297 false, true, "startActivity", null); 3298 // TODO: Switch to user app stacks here. 3299 int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents, 3300 resolvedTypes, resultTo, options, userId); 3301 return ret; 3302 } 3303 3304 final int startActivitiesInPackage(int uid, String callingPackage, 3305 Intent[] intents, String[] resolvedTypes, IBinder resultTo, 3306 Bundle options, int userId) { 3307 3308 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3309 false, true, "startActivityInPackage", null); 3310 // TODO: Switch to user app stacks here. 3311 int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes, 3312 resultTo, options, userId); 3313 return ret; 3314 } 3315 3316 final void addRecentTaskLocked(TaskRecord task) { 3317 int N = mRecentTasks.size(); 3318 // Quick case: check if the top-most recent task is the same. 3319 if (N > 0 && mRecentTasks.get(0) == task) { 3320 return; 3321 } 3322 // Remove any existing entries that are the same kind of task. 3323 for (int i=0; i<N; i++) { 3324 TaskRecord tr = mRecentTasks.get(i); 3325 if (task.userId == tr.userId 3326 && ((task.affinity != null && task.affinity.equals(tr.affinity)) 3327 || (task.intent != null && task.intent.filterEquals(tr.intent)))) { 3328 tr.disposeThumbnail(); 3329 mRecentTasks.remove(i); 3330 i--; 3331 N--; 3332 if (task.intent == null) { 3333 // If the new recent task we are adding is not fully 3334 // specified, then replace it with the existing recent task. 3335 task = tr; 3336 } 3337 } 3338 } 3339 if (N >= MAX_RECENT_TASKS) { 3340 mRecentTasks.remove(N-1).disposeThumbnail(); 3341 } 3342 mRecentTasks.add(0, task); 3343 } 3344 3345 @Override 3346 public void reportActivityFullyDrawn(IBinder token) { 3347 synchronized (this) { 3348 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3349 if (r == null) { 3350 return; 3351 } 3352 r.reportFullyDrawnLocked(); 3353 } 3354 } 3355 3356 @Override 3357 public void setRequestedOrientation(IBinder token, int requestedOrientation) { 3358 synchronized (this) { 3359 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3360 if (r == null) { 3361 return; 3362 } 3363 final long origId = Binder.clearCallingIdentity(); 3364 mWindowManager.setAppOrientation(r.appToken, requestedOrientation); 3365 Configuration config = mWindowManager.updateOrientationFromAppTokens( 3366 mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null); 3367 if (config != null) { 3368 r.frozenBeforeDestroy = true; 3369 if (!updateConfigurationLocked(config, r, false, false)) { 3370 mStackSupervisor.resumeTopActivitiesLocked(); 3371 } 3372 } 3373 Binder.restoreCallingIdentity(origId); 3374 } 3375 } 3376 3377 @Override 3378 public int getRequestedOrientation(IBinder token) { 3379 synchronized (this) { 3380 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3381 if (r == null) { 3382 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; 3383 } 3384 return mWindowManager.getAppOrientation(r.appToken); 3385 } 3386 } 3387 3388 /** 3389 * This is the internal entry point for handling Activity.finish(). 3390 * 3391 * @param token The Binder token referencing the Activity we want to finish. 3392 * @param resultCode Result code, if any, from this Activity. 3393 * @param resultData Result data (Intent), if any, from this Activity. 3394 * 3395 * @return Returns true if the activity successfully finished, or false if it is still running. 3396 */ 3397 @Override 3398 public final boolean finishActivity(IBinder token, int resultCode, Intent resultData) { 3399 // Refuse possible leaked file descriptors 3400 if (resultData != null && resultData.hasFileDescriptors() == true) { 3401 throw new IllegalArgumentException("File descriptors passed in Intent"); 3402 } 3403 3404 synchronized(this) { 3405 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3406 if (r == null) { 3407 return true; 3408 } 3409 if (mController != null) { 3410 // Find the first activity that is not finishing. 3411 ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0); 3412 if (next != null) { 3413 // ask watcher if this is allowed 3414 boolean resumeOK = true; 3415 try { 3416 resumeOK = mController.activityResuming(next.packageName); 3417 } catch (RemoteException e) { 3418 mController = null; 3419 Watchdog.getInstance().setActivityController(null); 3420 } 3421 3422 if (!resumeOK) { 3423 return false; 3424 } 3425 } 3426 } 3427 final long origId = Binder.clearCallingIdentity(); 3428 boolean res = r.task.stack.requestFinishActivityLocked(token, resultCode, 3429 resultData, "app-request", true); 3430 Binder.restoreCallingIdentity(origId); 3431 return res; 3432 } 3433 } 3434 3435 @Override 3436 public final void finishHeavyWeightApp() { 3437 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 3438 != PackageManager.PERMISSION_GRANTED) { 3439 String msg = "Permission Denial: finishHeavyWeightApp() from pid=" 3440 + Binder.getCallingPid() 3441 + ", uid=" + Binder.getCallingUid() 3442 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 3443 Slog.w(TAG, msg); 3444 throw new SecurityException(msg); 3445 } 3446 3447 synchronized(this) { 3448 if (mHeavyWeightProcess == null) { 3449 return; 3450 } 3451 3452 ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>( 3453 mHeavyWeightProcess.activities); 3454 for (int i=0; i<activities.size(); i++) { 3455 ActivityRecord r = activities.get(i); 3456 if (!r.finishing) { 3457 r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED, 3458 null, "finish-heavy", true); 3459 } 3460 } 3461 3462 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 3463 mHeavyWeightProcess.userId, 0)); 3464 mHeavyWeightProcess = null; 3465 } 3466 } 3467 3468 @Override 3469 public void crashApplication(int uid, int initialPid, String packageName, 3470 String message) { 3471 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 3472 != PackageManager.PERMISSION_GRANTED) { 3473 String msg = "Permission Denial: crashApplication() from pid=" 3474 + Binder.getCallingPid() 3475 + ", uid=" + Binder.getCallingUid() 3476 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 3477 Slog.w(TAG, msg); 3478 throw new SecurityException(msg); 3479 } 3480 3481 synchronized(this) { 3482 ProcessRecord proc = null; 3483 3484 // Figure out which process to kill. We don't trust that initialPid 3485 // still has any relation to current pids, so must scan through the 3486 // list. 3487 synchronized (mPidsSelfLocked) { 3488 for (int i=0; i<mPidsSelfLocked.size(); i++) { 3489 ProcessRecord p = mPidsSelfLocked.valueAt(i); 3490 if (p.uid != uid) { 3491 continue; 3492 } 3493 if (p.pid == initialPid) { 3494 proc = p; 3495 break; 3496 } 3497 if (p.pkgList.containsKey(packageName)) { 3498 proc = p; 3499 } 3500 } 3501 } 3502 3503 if (proc == null) { 3504 Slog.w(TAG, "crashApplication: nothing for uid=" + uid 3505 + " initialPid=" + initialPid 3506 + " packageName=" + packageName); 3507 return; 3508 } 3509 3510 if (proc.thread != null) { 3511 if (proc.pid == Process.myPid()) { 3512 Log.w(TAG, "crashApplication: trying to crash self!"); 3513 return; 3514 } 3515 long ident = Binder.clearCallingIdentity(); 3516 try { 3517 proc.thread.scheduleCrash(message); 3518 } catch (RemoteException e) { 3519 } 3520 Binder.restoreCallingIdentity(ident); 3521 } 3522 } 3523 } 3524 3525 @Override 3526 public final void finishSubActivity(IBinder token, String resultWho, 3527 int requestCode) { 3528 synchronized(this) { 3529 final long origId = Binder.clearCallingIdentity(); 3530 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3531 if (r != null) { 3532 r.task.stack.finishSubActivityLocked(r, resultWho, requestCode); 3533 } 3534 Binder.restoreCallingIdentity(origId); 3535 } 3536 } 3537 3538 @Override 3539 public boolean finishActivityAffinity(IBinder token) { 3540 synchronized(this) { 3541 final long origId = Binder.clearCallingIdentity(); 3542 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3543 boolean res = false; 3544 if (r != null) { 3545 res = r.task.stack.finishActivityAffinityLocked(r); 3546 } 3547 Binder.restoreCallingIdentity(origId); 3548 return res; 3549 } 3550 } 3551 3552 @Override 3553 public boolean willActivityBeVisible(IBinder token) { 3554 synchronized(this) { 3555 ActivityStack stack = ActivityRecord.getStackLocked(token); 3556 if (stack != null) { 3557 return stack.willActivityBeVisibleLocked(token); 3558 } 3559 return false; 3560 } 3561 } 3562 3563 @Override 3564 public void overridePendingTransition(IBinder token, String packageName, 3565 int enterAnim, int exitAnim) { 3566 synchronized(this) { 3567 ActivityRecord self = ActivityRecord.isInStackLocked(token); 3568 if (self == null) { 3569 return; 3570 } 3571 3572 final long origId = Binder.clearCallingIdentity(); 3573 3574 if (self.state == ActivityState.RESUMED 3575 || self.state == ActivityState.PAUSING) { 3576 mWindowManager.overridePendingAppTransition(packageName, 3577 enterAnim, exitAnim, null); 3578 } 3579 3580 Binder.restoreCallingIdentity(origId); 3581 } 3582 } 3583 3584 /** 3585 * Main function for removing an existing process from the activity manager 3586 * as a result of that process going away. Clears out all connections 3587 * to the process. 3588 */ 3589 private final void handleAppDiedLocked(ProcessRecord app, 3590 boolean restarting, boolean allowRestart) { 3591 int pid = app.pid; 3592 cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1); 3593 if (!restarting) { 3594 removeLruProcessLocked(app); 3595 if (pid > 0) { 3596 ProcessList.remove(pid); 3597 } 3598 } 3599 3600 if (mProfileProc == app) { 3601 clearProfilerLocked(); 3602 } 3603 3604 // Remove this application's activities from active lists. 3605 boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app); 3606 3607 app.activities.clear(); 3608 3609 if (app.instrumentationClass != null) { 3610 Slog.w(TAG, "Crash of app " + app.processName 3611 + " running instrumentation " + app.instrumentationClass); 3612 Bundle info = new Bundle(); 3613 info.putString("shortMsg", "Process crashed."); 3614 finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info); 3615 } 3616 3617 if (!restarting) { 3618 if (!mStackSupervisor.resumeTopActivitiesLocked()) { 3619 // If there was nothing to resume, and we are not already 3620 // restarting this process, but there is a visible activity that 3621 // is hosted by the process... then make sure all visible 3622 // activities are running, taking care of restarting this 3623 // process. 3624 if (hasVisibleActivities) { 3625 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 3626 } 3627 } 3628 } 3629 } 3630 3631 private final int getLRURecordIndexForAppLocked(IApplicationThread thread) { 3632 IBinder threadBinder = thread.asBinder(); 3633 // Find the application record. 3634 for (int i=mLruProcesses.size()-1; i>=0; i--) { 3635 ProcessRecord rec = mLruProcesses.get(i); 3636 if (rec.thread != null && rec.thread.asBinder() == threadBinder) { 3637 return i; 3638 } 3639 } 3640 return -1; 3641 } 3642 3643 final ProcessRecord getRecordForAppLocked( 3644 IApplicationThread thread) { 3645 if (thread == null) { 3646 return null; 3647 } 3648 3649 int appIndex = getLRURecordIndexForAppLocked(thread); 3650 return appIndex >= 0 ? mLruProcesses.get(appIndex) : null; 3651 } 3652 3653 final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) { 3654 // If there are no longer any background processes running, 3655 // and the app that died was not running instrumentation, 3656 // then tell everyone we are now low on memory. 3657 boolean haveBg = false; 3658 for (int i=mLruProcesses.size()-1; i>=0; i--) { 3659 ProcessRecord rec = mLruProcesses.get(i); 3660 if (rec.thread != null 3661 && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 3662 haveBg = true; 3663 break; 3664 } 3665 } 3666 3667 if (!haveBg) { 3668 boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 3669 if (doReport) { 3670 long now = SystemClock.uptimeMillis(); 3671 if (now < (mLastMemUsageReportTime+5*60*1000)) { 3672 doReport = false; 3673 } else { 3674 mLastMemUsageReportTime = now; 3675 } 3676 } 3677 final ArrayList<ProcessMemInfo> memInfos 3678 = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null; 3679 EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size()); 3680 long now = SystemClock.uptimeMillis(); 3681 for (int i=mLruProcesses.size()-1; i>=0; i--) { 3682 ProcessRecord rec = mLruProcesses.get(i); 3683 if (rec == dyingProc || rec.thread == null) { 3684 continue; 3685 } 3686 if (doReport) { 3687 memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj, 3688 rec.setProcState, rec.adjType, rec.makeAdjReason())); 3689 } 3690 if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) { 3691 // The low memory report is overriding any current 3692 // state for a GC request. Make sure to do 3693 // heavy/important/visible/foreground processes first. 3694 if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 3695 rec.lastRequestedGc = 0; 3696 } else { 3697 rec.lastRequestedGc = rec.lastLowMemory; 3698 } 3699 rec.reportLowMemory = true; 3700 rec.lastLowMemory = now; 3701 mProcessesToGc.remove(rec); 3702 addProcessToGcListLocked(rec); 3703 } 3704 } 3705 if (doReport) { 3706 Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos); 3707 mHandler.sendMessage(msg); 3708 } 3709 scheduleAppGcsLocked(); 3710 } 3711 } 3712 3713 final void appDiedLocked(ProcessRecord app, int pid, 3714 IApplicationThread thread) { 3715 3716 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 3717 synchronized (stats) { 3718 stats.noteProcessDiedLocked(app.info.uid, pid); 3719 } 3720 3721 // Clean up already done if the process has been re-started. 3722 if (app.pid == pid && app.thread != null && 3723 app.thread.asBinder() == thread.asBinder()) { 3724 boolean doLowMem = app.instrumentationClass == null; 3725 boolean doOomAdj = doLowMem; 3726 if (!app.killedByAm) { 3727 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 3728 + ") has died."); 3729 mAllowLowerMemLevel = true; 3730 } else { 3731 // Note that we always want to do oom adj to update our state with the 3732 // new number of procs. 3733 mAllowLowerMemLevel = false; 3734 doLowMem = false; 3735 } 3736 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName); 3737 if (DEBUG_CLEANUP) Slog.v( 3738 TAG, "Dying app: " + app + ", pid: " + pid 3739 + ", thread: " + thread.asBinder()); 3740 handleAppDiedLocked(app, false, true); 3741 3742 if (doOomAdj) { 3743 updateOomAdjLocked(); 3744 } 3745 if (doLowMem) { 3746 doLowMemReportIfNeededLocked(app); 3747 } 3748 } else if (app.pid != pid) { 3749 // A new process has already been started. 3750 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 3751 + ") has died and restarted (pid " + app.pid + ")."); 3752 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName); 3753 } else if (DEBUG_PROCESSES) { 3754 Slog.d(TAG, "Received spurious death notification for thread " 3755 + thread.asBinder()); 3756 } 3757 } 3758 3759 /** 3760 * If a stack trace dump file is configured, dump process stack traces. 3761 * @param clearTraces causes the dump file to be erased prior to the new 3762 * traces being written, if true; when false, the new traces will be 3763 * appended to any existing file content. 3764 * @param firstPids of dalvik VM processes to dump stack traces for first 3765 * @param lastPids of dalvik VM processes to dump stack traces for last 3766 * @param nativeProcs optional list of native process names to dump stack crawls 3767 * @return file containing stack traces, or null if no dump file is configured 3768 */ 3769 public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids, 3770 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) { 3771 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 3772 if (tracesPath == null || tracesPath.length() == 0) { 3773 return null; 3774 } 3775 3776 File tracesFile = new File(tracesPath); 3777 try { 3778 File tracesDir = tracesFile.getParentFile(); 3779 if (!tracesDir.exists()) { 3780 tracesFile.mkdirs(); 3781 if (!SELinux.restorecon(tracesDir)) { 3782 return null; 3783 } 3784 } 3785 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 3786 3787 if (clearTraces && tracesFile.exists()) tracesFile.delete(); 3788 tracesFile.createNewFile(); 3789 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 3790 } catch (IOException e) { 3791 Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e); 3792 return null; 3793 } 3794 3795 dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs); 3796 return tracesFile; 3797 } 3798 3799 private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids, 3800 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) { 3801 // Use a FileObserver to detect when traces finish writing. 3802 // The order of traces is considered important to maintain for legibility. 3803 FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) { 3804 @Override 3805 public synchronized void onEvent(int event, String path) { notify(); } 3806 }; 3807 3808 try { 3809 observer.startWatching(); 3810 3811 // First collect all of the stacks of the most important pids. 3812 if (firstPids != null) { 3813 try { 3814 int num = firstPids.size(); 3815 for (int i = 0; i < num; i++) { 3816 synchronized (observer) { 3817 Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT); 3818 observer.wait(200); // Wait for write-close, give up after 200msec 3819 } 3820 } 3821 } catch (InterruptedException e) { 3822 Log.wtf(TAG, e); 3823 } 3824 } 3825 3826 // Next collect the stacks of the native pids 3827 if (nativeProcs != null) { 3828 int[] pids = Process.getPidsForCommands(nativeProcs); 3829 if (pids != null) { 3830 for (int pid : pids) { 3831 Debug.dumpNativeBacktraceToFile(pid, tracesPath); 3832 } 3833 } 3834 } 3835 3836 // Lastly, measure CPU usage. 3837 if (processCpuTracker != null) { 3838 processCpuTracker.init(); 3839 System.gc(); 3840 processCpuTracker.update(); 3841 try { 3842 synchronized (processCpuTracker) { 3843 processCpuTracker.wait(500); // measure over 1/2 second. 3844 } 3845 } catch (InterruptedException e) { 3846 } 3847 processCpuTracker.update(); 3848 3849 // We'll take the stack crawls of just the top apps using CPU. 3850 final int N = processCpuTracker.countWorkingStats(); 3851 int numProcs = 0; 3852 for (int i=0; i<N && numProcs<5; i++) { 3853 ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i); 3854 if (lastPids.indexOfKey(stats.pid) >= 0) { 3855 numProcs++; 3856 try { 3857 synchronized (observer) { 3858 Process.sendSignal(stats.pid, Process.SIGNAL_QUIT); 3859 observer.wait(200); // Wait for write-close, give up after 200msec 3860 } 3861 } catch (InterruptedException e) { 3862 Log.wtf(TAG, e); 3863 } 3864 3865 } 3866 } 3867 } 3868 } finally { 3869 observer.stopWatching(); 3870 } 3871 } 3872 3873 final void logAppTooSlow(ProcessRecord app, long startTime, String msg) { 3874 if (true || IS_USER_BUILD) { 3875 return; 3876 } 3877 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 3878 if (tracesPath == null || tracesPath.length() == 0) { 3879 return; 3880 } 3881 3882 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads(); 3883 StrictMode.allowThreadDiskWrites(); 3884 try { 3885 final File tracesFile = new File(tracesPath); 3886 final File tracesDir = tracesFile.getParentFile(); 3887 final File tracesTmp = new File(tracesDir, "__tmp__"); 3888 try { 3889 if (!tracesDir.exists()) { 3890 tracesFile.mkdirs(); 3891 if (!SELinux.restorecon(tracesDir.getPath())) { 3892 return; 3893 } 3894 } 3895 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 3896 3897 if (tracesFile.exists()) { 3898 tracesTmp.delete(); 3899 tracesFile.renameTo(tracesTmp); 3900 } 3901 StringBuilder sb = new StringBuilder(); 3902 Time tobj = new Time(); 3903 tobj.set(System.currentTimeMillis()); 3904 sb.append(tobj.format("%Y-%m-%d %H:%M:%S")); 3905 sb.append(": "); 3906 TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb); 3907 sb.append(" since "); 3908 sb.append(msg); 3909 FileOutputStream fos = new FileOutputStream(tracesFile); 3910 fos.write(sb.toString().getBytes()); 3911 if (app == null) { 3912 fos.write("\n*** No application process!".getBytes()); 3913 } 3914 fos.close(); 3915 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 3916 } catch (IOException e) { 3917 Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e); 3918 return; 3919 } 3920 3921 if (app != null) { 3922 ArrayList<Integer> firstPids = new ArrayList<Integer>(); 3923 firstPids.add(app.pid); 3924 dumpStackTraces(tracesPath, firstPids, null, null, null); 3925 } 3926 3927 File lastTracesFile = null; 3928 File curTracesFile = null; 3929 for (int i=9; i>=0; i--) { 3930 String name = String.format(Locale.US, "slow%02d.txt", i); 3931 curTracesFile = new File(tracesDir, name); 3932 if (curTracesFile.exists()) { 3933 if (lastTracesFile != null) { 3934 curTracesFile.renameTo(lastTracesFile); 3935 } else { 3936 curTracesFile.delete(); 3937 } 3938 } 3939 lastTracesFile = curTracesFile; 3940 } 3941 tracesFile.renameTo(curTracesFile); 3942 if (tracesTmp.exists()) { 3943 tracesTmp.renameTo(tracesFile); 3944 } 3945 } finally { 3946 StrictMode.setThreadPolicy(oldPolicy); 3947 } 3948 } 3949 3950 final void appNotResponding(ProcessRecord app, ActivityRecord activity, 3951 ActivityRecord parent, boolean aboveSystem, final String annotation) { 3952 ArrayList<Integer> firstPids = new ArrayList<Integer>(5); 3953 SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20); 3954 3955 if (mController != null) { 3956 try { 3957 // 0 == continue, -1 = kill process immediately 3958 int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation); 3959 if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid); 3960 } catch (RemoteException e) { 3961 mController = null; 3962 Watchdog.getInstance().setActivityController(null); 3963 } 3964 } 3965 3966 long anrTime = SystemClock.uptimeMillis(); 3967 if (MONITOR_CPU_USAGE) { 3968 updateCpuStatsNow(); 3969 } 3970 3971 synchronized (this) { 3972 // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down. 3973 if (mShuttingDown) { 3974 Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation); 3975 return; 3976 } else if (app.notResponding) { 3977 Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation); 3978 return; 3979 } else if (app.crashing) { 3980 Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation); 3981 return; 3982 } 3983 3984 // In case we come through here for the same app before completing 3985 // this one, mark as anring now so we will bail out. 3986 app.notResponding = true; 3987 3988 // Log the ANR to the event log. 3989 EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid, 3990 app.processName, app.info.flags, annotation); 3991 3992 // Dump thread traces as quickly as we can, starting with "interesting" processes. 3993 firstPids.add(app.pid); 3994 3995 int parentPid = app.pid; 3996 if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid; 3997 if (parentPid != app.pid) firstPids.add(parentPid); 3998 3999 if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID); 4000 4001 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 4002 ProcessRecord r = mLruProcesses.get(i); 4003 if (r != null && r.thread != null) { 4004 int pid = r.pid; 4005 if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) { 4006 if (r.persistent) { 4007 firstPids.add(pid); 4008 } else { 4009 lastPids.put(pid, Boolean.TRUE); 4010 } 4011 } 4012 } 4013 } 4014 } 4015 4016 // Log the ANR to the main log. 4017 StringBuilder info = new StringBuilder(); 4018 info.setLength(0); 4019 info.append("ANR in ").append(app.processName); 4020 if (activity != null && activity.shortComponentName != null) { 4021 info.append(" (").append(activity.shortComponentName).append(")"); 4022 } 4023 info.append("\n"); 4024 info.append("PID: ").append(app.pid).append("\n"); 4025 if (annotation != null) { 4026 info.append("Reason: ").append(annotation).append("\n"); 4027 } 4028 if (parent != null && parent != activity) { 4029 info.append("Parent: ").append(parent.shortComponentName).append("\n"); 4030 } 4031 4032 final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true); 4033 4034 File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids, 4035 NATIVE_STACKS_OF_INTEREST); 4036 4037 String cpuInfo = null; 4038 if (MONITOR_CPU_USAGE) { 4039 updateCpuStatsNow(); 4040 synchronized (mProcessCpuThread) { 4041 cpuInfo = mProcessCpuTracker.printCurrentState(anrTime); 4042 } 4043 info.append(processCpuTracker.printCurrentLoad()); 4044 info.append(cpuInfo); 4045 } 4046 4047 info.append(processCpuTracker.printCurrentState(anrTime)); 4048 4049 Slog.e(TAG, info.toString()); 4050 if (tracesFile == null) { 4051 // There is no trace file, so dump (only) the alleged culprit's threads to the log 4052 Process.sendSignal(app.pid, Process.SIGNAL_QUIT); 4053 } 4054 4055 addErrorToDropBox("anr", app, app.processName, activity, parent, annotation, 4056 cpuInfo, tracesFile, null); 4057 4058 if (mController != null) { 4059 try { 4060 // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately 4061 int res = mController.appNotResponding(app.processName, app.pid, info.toString()); 4062 if (res != 0) { 4063 if (res < 0 && app.pid != MY_PID) { 4064 Process.killProcess(app.pid); 4065 } else { 4066 synchronized (this) { 4067 mServices.scheduleServiceTimeoutLocked(app); 4068 } 4069 } 4070 return; 4071 } 4072 } catch (RemoteException e) { 4073 mController = null; 4074 Watchdog.getInstance().setActivityController(null); 4075 } 4076 } 4077 4078 // Unless configured otherwise, swallow ANRs in background processes & kill the process. 4079 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), 4080 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; 4081 4082 synchronized (this) { 4083 if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) { 4084 killUnneededProcessLocked(app, "background ANR"); 4085 return; 4086 } 4087 4088 // Set the app's notResponding state, and look up the errorReportReceiver 4089 makeAppNotRespondingLocked(app, 4090 activity != null ? activity.shortComponentName : null, 4091 annotation != null ? "ANR " + annotation : "ANR", 4092 info.toString()); 4093 4094 // Bring up the infamous App Not Responding dialog 4095 Message msg = Message.obtain(); 4096 HashMap<String, Object> map = new HashMap<String, Object>(); 4097 msg.what = SHOW_NOT_RESPONDING_MSG; 4098 msg.obj = map; 4099 msg.arg1 = aboveSystem ? 1 : 0; 4100 map.put("app", app); 4101 if (activity != null) { 4102 map.put("activity", activity); 4103 } 4104 4105 mHandler.sendMessage(msg); 4106 } 4107 } 4108 4109 final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) { 4110 if (!mLaunchWarningShown) { 4111 mLaunchWarningShown = true; 4112 mHandler.post(new Runnable() { 4113 @Override 4114 public void run() { 4115 synchronized (ActivityManagerService.this) { 4116 final Dialog d = new LaunchWarningWindow(mContext, cur, next); 4117 d.show(); 4118 mHandler.postDelayed(new Runnable() { 4119 @Override 4120 public void run() { 4121 synchronized (ActivityManagerService.this) { 4122 d.dismiss(); 4123 mLaunchWarningShown = false; 4124 } 4125 } 4126 }, 4000); 4127 } 4128 } 4129 }); 4130 } 4131 } 4132 4133 @Override 4134 public boolean clearApplicationUserData(final String packageName, 4135 final IPackageDataObserver observer, int userId) { 4136 enforceNotIsolatedCaller("clearApplicationUserData"); 4137 int uid = Binder.getCallingUid(); 4138 int pid = Binder.getCallingPid(); 4139 userId = handleIncomingUser(pid, uid, 4140 userId, false, true, "clearApplicationUserData", null); 4141 long callingId = Binder.clearCallingIdentity(); 4142 try { 4143 IPackageManager pm = AppGlobals.getPackageManager(); 4144 int pkgUid = -1; 4145 synchronized(this) { 4146 try { 4147 pkgUid = pm.getPackageUid(packageName, userId); 4148 } catch (RemoteException e) { 4149 } 4150 if (pkgUid == -1) { 4151 Slog.w(TAG, "Invalid packageName: " + packageName); 4152 if (observer != null) { 4153 try { 4154 observer.onRemoveCompleted(packageName, false); 4155 } catch (RemoteException e) { 4156 Slog.i(TAG, "Observer no longer exists."); 4157 } 4158 } 4159 return false; 4160 } 4161 if (uid == pkgUid || checkComponentPermission( 4162 android.Manifest.permission.CLEAR_APP_USER_DATA, 4163 pid, uid, -1, true) 4164 == PackageManager.PERMISSION_GRANTED) { 4165 forceStopPackageLocked(packageName, pkgUid, "clear data"); 4166 } else { 4167 throw new SecurityException("PID " + pid + " does not have permission " 4168 + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data" 4169 + " of package " + packageName); 4170 } 4171 } 4172 4173 try { 4174 // Clear application user data 4175 pm.clearApplicationUserData(packageName, observer, userId); 4176 4177 // Remove all permissions granted from/to this package 4178 removeUriPermissionsForPackageLocked(packageName, userId, true); 4179 4180 Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED, 4181 Uri.fromParts("package", packageName, null)); 4182 intent.putExtra(Intent.EXTRA_UID, pkgUid); 4183 broadcastIntentInPackage("android", Process.SYSTEM_UID, intent, 4184 null, null, 0, null, null, null, false, false, userId); 4185 } catch (RemoteException e) { 4186 } 4187 } finally { 4188 Binder.restoreCallingIdentity(callingId); 4189 } 4190 return true; 4191 } 4192 4193 @Override 4194 public void killBackgroundProcesses(final String packageName, int userId) { 4195 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 4196 != PackageManager.PERMISSION_GRANTED && 4197 checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES) 4198 != PackageManager.PERMISSION_GRANTED) { 4199 String msg = "Permission Denial: killBackgroundProcesses() from pid=" 4200 + Binder.getCallingPid() 4201 + ", uid=" + Binder.getCallingUid() 4202 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 4203 Slog.w(TAG, msg); 4204 throw new SecurityException(msg); 4205 } 4206 4207 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 4208 userId, true, true, "killBackgroundProcesses", null); 4209 long callingId = Binder.clearCallingIdentity(); 4210 try { 4211 IPackageManager pm = AppGlobals.getPackageManager(); 4212 synchronized(this) { 4213 int appId = -1; 4214 try { 4215 appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0)); 4216 } catch (RemoteException e) { 4217 } 4218 if (appId == -1) { 4219 Slog.w(TAG, "Invalid packageName: " + packageName); 4220 return; 4221 } 4222 killPackageProcessesLocked(packageName, appId, userId, 4223 ProcessList.SERVICE_ADJ, false, true, true, false, "kill background"); 4224 } 4225 } finally { 4226 Binder.restoreCallingIdentity(callingId); 4227 } 4228 } 4229 4230 @Override 4231 public void killAllBackgroundProcesses() { 4232 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 4233 != PackageManager.PERMISSION_GRANTED) { 4234 String msg = "Permission Denial: killAllBackgroundProcesses() from pid=" 4235 + Binder.getCallingPid() 4236 + ", uid=" + Binder.getCallingUid() 4237 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 4238 Slog.w(TAG, msg); 4239 throw new SecurityException(msg); 4240 } 4241 4242 long callingId = Binder.clearCallingIdentity(); 4243 try { 4244 synchronized(this) { 4245 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 4246 final int NP = mProcessNames.getMap().size(); 4247 for (int ip=0; ip<NP; ip++) { 4248 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 4249 final int NA = apps.size(); 4250 for (int ia=0; ia<NA; ia++) { 4251 ProcessRecord app = apps.valueAt(ia); 4252 if (app.persistent) { 4253 // we don't kill persistent processes 4254 continue; 4255 } 4256 if (app.removed) { 4257 procs.add(app); 4258 } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 4259 app.removed = true; 4260 procs.add(app); 4261 } 4262 } 4263 } 4264 4265 int N = procs.size(); 4266 for (int i=0; i<N; i++) { 4267 removeProcessLocked(procs.get(i), false, true, "kill all background"); 4268 } 4269 mAllowLowerMemLevel = true; 4270 updateOomAdjLocked(); 4271 doLowMemReportIfNeededLocked(null); 4272 } 4273 } finally { 4274 Binder.restoreCallingIdentity(callingId); 4275 } 4276 } 4277 4278 @Override 4279 public void forceStopPackage(final String packageName, int userId) { 4280 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 4281 != PackageManager.PERMISSION_GRANTED) { 4282 String msg = "Permission Denial: forceStopPackage() from pid=" 4283 + Binder.getCallingPid() 4284 + ", uid=" + Binder.getCallingUid() 4285 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 4286 Slog.w(TAG, msg); 4287 throw new SecurityException(msg); 4288 } 4289 final int callingPid = Binder.getCallingPid(); 4290 userId = handleIncomingUser(callingPid, Binder.getCallingUid(), 4291 userId, true, true, "forceStopPackage", null); 4292 long callingId = Binder.clearCallingIdentity(); 4293 try { 4294 IPackageManager pm = AppGlobals.getPackageManager(); 4295 synchronized(this) { 4296 int[] users = userId == UserHandle.USER_ALL 4297 ? getUsersLocked() : new int[] { userId }; 4298 for (int user : users) { 4299 int pkgUid = -1; 4300 try { 4301 pkgUid = pm.getPackageUid(packageName, user); 4302 } catch (RemoteException e) { 4303 } 4304 if (pkgUid == -1) { 4305 Slog.w(TAG, "Invalid packageName: " + packageName); 4306 continue; 4307 } 4308 try { 4309 pm.setPackageStoppedState(packageName, true, user); 4310 } catch (RemoteException e) { 4311 } catch (IllegalArgumentException e) { 4312 Slog.w(TAG, "Failed trying to unstop package " 4313 + packageName + ": " + e); 4314 } 4315 if (isUserRunningLocked(user, false)) { 4316 forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid); 4317 } 4318 } 4319 } 4320 } finally { 4321 Binder.restoreCallingIdentity(callingId); 4322 } 4323 } 4324 4325 /* 4326 * The pkg name and app id have to be specified. 4327 */ 4328 @Override 4329 public void killApplicationWithAppId(String pkg, int appid, String reason) { 4330 if (pkg == null) { 4331 return; 4332 } 4333 // Make sure the uid is valid. 4334 if (appid < 0) { 4335 Slog.w(TAG, "Invalid appid specified for pkg : " + pkg); 4336 return; 4337 } 4338 int callerUid = Binder.getCallingUid(); 4339 // Only the system server can kill an application 4340 if (callerUid == Process.SYSTEM_UID) { 4341 // Post an aysnc message to kill the application 4342 Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG); 4343 msg.arg1 = appid; 4344 msg.arg2 = 0; 4345 Bundle bundle = new Bundle(); 4346 bundle.putString("pkg", pkg); 4347 bundle.putString("reason", reason); 4348 msg.obj = bundle; 4349 mHandler.sendMessage(msg); 4350 } else { 4351 throw new SecurityException(callerUid + " cannot kill pkg: " + 4352 pkg); 4353 } 4354 } 4355 4356 @Override 4357 public void closeSystemDialogs(String reason) { 4358 enforceNotIsolatedCaller("closeSystemDialogs"); 4359 4360 final int pid = Binder.getCallingPid(); 4361 final int uid = Binder.getCallingUid(); 4362 final long origId = Binder.clearCallingIdentity(); 4363 try { 4364 synchronized (this) { 4365 // Only allow this from foreground processes, so that background 4366 // applications can't abuse it to prevent system UI from being shown. 4367 if (uid >= Process.FIRST_APPLICATION_UID) { 4368 ProcessRecord proc; 4369 synchronized (mPidsSelfLocked) { 4370 proc = mPidsSelfLocked.get(pid); 4371 } 4372 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 4373 Slog.w(TAG, "Ignoring closeSystemDialogs " + reason 4374 + " from background process " + proc); 4375 return; 4376 } 4377 } 4378 closeSystemDialogsLocked(reason); 4379 } 4380 } finally { 4381 Binder.restoreCallingIdentity(origId); 4382 } 4383 } 4384 4385 void closeSystemDialogsLocked(String reason) { 4386 Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS); 4387 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 4388 | Intent.FLAG_RECEIVER_FOREGROUND); 4389 if (reason != null) { 4390 intent.putExtra("reason", reason); 4391 } 4392 mWindowManager.closeSystemDialogs(reason); 4393 4394 mStackSupervisor.closeSystemDialogsLocked(); 4395 4396 broadcastIntentLocked(null, null, intent, null, 4397 null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1, 4398 Process.SYSTEM_UID, UserHandle.USER_ALL); 4399 } 4400 4401 @Override 4402 public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) { 4403 enforceNotIsolatedCaller("getProcessMemoryInfo"); 4404 Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length]; 4405 for (int i=pids.length-1; i>=0; i--) { 4406 ProcessRecord proc; 4407 int oomAdj; 4408 synchronized (this) { 4409 synchronized (mPidsSelfLocked) { 4410 proc = mPidsSelfLocked.get(pids[i]); 4411 oomAdj = proc != null ? proc.setAdj : 0; 4412 } 4413 } 4414 infos[i] = new Debug.MemoryInfo(); 4415 Debug.getMemoryInfo(pids[i], infos[i]); 4416 if (proc != null) { 4417 synchronized (this) { 4418 if (proc.thread != null && proc.setAdj == oomAdj) { 4419 // Record this for posterity if the process has been stable. 4420 proc.baseProcessTracker.addPss(infos[i].getTotalPss(), 4421 infos[i].getTotalUss(), false, proc.pkgList); 4422 } 4423 } 4424 } 4425 } 4426 return infos; 4427 } 4428 4429 @Override 4430 public long[] getProcessPss(int[] pids) { 4431 enforceNotIsolatedCaller("getProcessPss"); 4432 long[] pss = new long[pids.length]; 4433 for (int i=pids.length-1; i>=0; i--) { 4434 ProcessRecord proc; 4435 int oomAdj; 4436 synchronized (this) { 4437 synchronized (mPidsSelfLocked) { 4438 proc = mPidsSelfLocked.get(pids[i]); 4439 oomAdj = proc != null ? proc.setAdj : 0; 4440 } 4441 } 4442 long[] tmpUss = new long[1]; 4443 pss[i] = Debug.getPss(pids[i], tmpUss); 4444 if (proc != null) { 4445 synchronized (this) { 4446 if (proc.thread != null && proc.setAdj == oomAdj) { 4447 // Record this for posterity if the process has been stable. 4448 proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList); 4449 } 4450 } 4451 } 4452 } 4453 return pss; 4454 } 4455 4456 @Override 4457 public void killApplicationProcess(String processName, int uid) { 4458 if (processName == null) { 4459 return; 4460 } 4461 4462 int callerUid = Binder.getCallingUid(); 4463 // Only the system server can kill an application 4464 if (callerUid == Process.SYSTEM_UID) { 4465 synchronized (this) { 4466 ProcessRecord app = getProcessRecordLocked(processName, uid, true); 4467 if (app != null && app.thread != null) { 4468 try { 4469 app.thread.scheduleSuicide(); 4470 } catch (RemoteException e) { 4471 // If the other end already died, then our work here is done. 4472 } 4473 } else { 4474 Slog.w(TAG, "Process/uid not found attempting kill of " 4475 + processName + " / " + uid); 4476 } 4477 } 4478 } else { 4479 throw new SecurityException(callerUid + " cannot kill app process: " + 4480 processName); 4481 } 4482 } 4483 4484 private void forceStopPackageLocked(final String packageName, int uid, String reason) { 4485 forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false, 4486 false, true, false, UserHandle.getUserId(uid), reason); 4487 Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED, 4488 Uri.fromParts("package", packageName, null)); 4489 if (!mProcessesReady) { 4490 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 4491 | Intent.FLAG_RECEIVER_FOREGROUND); 4492 } 4493 intent.putExtra(Intent.EXTRA_UID, uid); 4494 intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid)); 4495 broadcastIntentLocked(null, null, intent, 4496 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 4497 false, false, 4498 MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid)); 4499 } 4500 4501 private void forceStopUserLocked(int userId, String reason) { 4502 forceStopPackageLocked(null, -1, false, false, true, false, userId, reason); 4503 Intent intent = new Intent(Intent.ACTION_USER_STOPPED); 4504 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 4505 | Intent.FLAG_RECEIVER_FOREGROUND); 4506 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 4507 broadcastIntentLocked(null, null, intent, 4508 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 4509 false, false, 4510 MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 4511 } 4512 4513 private final boolean killPackageProcessesLocked(String packageName, int appId, 4514 int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart, 4515 boolean doit, boolean evenPersistent, String reason) { 4516 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 4517 4518 // Remove all processes this package may have touched: all with the 4519 // same UID (except for the system or root user), and all whose name 4520 // matches the package name. 4521 final String procNamePrefix = packageName != null ? (packageName + ":") : null; 4522 final int NP = mProcessNames.getMap().size(); 4523 for (int ip=0; ip<NP; ip++) { 4524 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 4525 final int NA = apps.size(); 4526 for (int ia=0; ia<NA; ia++) { 4527 ProcessRecord app = apps.valueAt(ia); 4528 if (app.persistent && !evenPersistent) { 4529 // we don't kill persistent processes 4530 continue; 4531 } 4532 if (app.removed) { 4533 if (doit) { 4534 procs.add(app); 4535 } 4536 continue; 4537 } 4538 4539 // Skip process if it doesn't meet our oom adj requirement. 4540 if (app.setAdj < minOomAdj) { 4541 continue; 4542 } 4543 4544 // If no package is specified, we call all processes under the 4545 // give user id. 4546 if (packageName == null) { 4547 if (app.userId != userId) { 4548 continue; 4549 } 4550 if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) { 4551 continue; 4552 } 4553 // Package has been specified, we want to hit all processes 4554 // that match it. We need to qualify this by the processes 4555 // that are running under the specified app and user ID. 4556 } else { 4557 if (UserHandle.getAppId(app.uid) != appId) { 4558 continue; 4559 } 4560 if (userId != UserHandle.USER_ALL && app.userId != userId) { 4561 continue; 4562 } 4563 if (!app.pkgList.containsKey(packageName)) { 4564 continue; 4565 } 4566 } 4567 4568 // Process has passed all conditions, kill it! 4569 if (!doit) { 4570 return true; 4571 } 4572 app.removed = true; 4573 procs.add(app); 4574 } 4575 } 4576 4577 int N = procs.size(); 4578 for (int i=0; i<N; i++) { 4579 removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason); 4580 } 4581 updateOomAdjLocked(); 4582 return N > 0; 4583 } 4584 4585 private final boolean forceStopPackageLocked(String name, int appId, 4586 boolean callerWillRestart, boolean purgeCache, boolean doit, 4587 boolean evenPersistent, int userId, String reason) { 4588 int i; 4589 int N; 4590 4591 if (userId == UserHandle.USER_ALL && name == null) { 4592 Slog.w(TAG, "Can't force stop all processes of all users, that is insane!"); 4593 } 4594 4595 if (appId < 0 && name != null) { 4596 try { 4597 appId = UserHandle.getAppId( 4598 AppGlobals.getPackageManager().getPackageUid(name, 0)); 4599 } catch (RemoteException e) { 4600 } 4601 } 4602 4603 if (doit) { 4604 if (name != null) { 4605 Slog.i(TAG, "Force stopping " + name + " appid=" + appId 4606 + " user=" + userId + ": " + reason); 4607 } else { 4608 Slog.i(TAG, "Force stopping u" + userId + ": " + reason); 4609 } 4610 4611 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap(); 4612 for (int ip=pmap.size()-1; ip>=0; ip--) { 4613 SparseArray<Long> ba = pmap.valueAt(ip); 4614 for (i=ba.size()-1; i>=0; i--) { 4615 boolean remove = false; 4616 final int entUid = ba.keyAt(i); 4617 if (name != null) { 4618 if (userId == UserHandle.USER_ALL) { 4619 if (UserHandle.getAppId(entUid) == appId) { 4620 remove = true; 4621 } 4622 } else { 4623 if (entUid == UserHandle.getUid(userId, appId)) { 4624 remove = true; 4625 } 4626 } 4627 } else if (UserHandle.getUserId(entUid) == userId) { 4628 remove = true; 4629 } 4630 if (remove) { 4631 ba.removeAt(i); 4632 } 4633 } 4634 if (ba.size() == 0) { 4635 pmap.removeAt(ip); 4636 } 4637 } 4638 } 4639 4640 boolean didSomething = killPackageProcessesLocked(name, appId, userId, 4641 -100, callerWillRestart, true, doit, evenPersistent, 4642 name == null ? ("stop user " + userId) : ("stop " + name)); 4643 4644 if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) { 4645 if (!doit) { 4646 return true; 4647 } 4648 didSomething = true; 4649 } 4650 4651 if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) { 4652 if (!doit) { 4653 return true; 4654 } 4655 didSomething = true; 4656 } 4657 4658 if (name == null) { 4659 // Remove all sticky broadcasts from this user. 4660 mStickyBroadcasts.remove(userId); 4661 } 4662 4663 ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>(); 4664 if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent, 4665 userId, providers)) { 4666 if (!doit) { 4667 return true; 4668 } 4669 didSomething = true; 4670 } 4671 N = providers.size(); 4672 for (i=0; i<N; i++) { 4673 removeDyingProviderLocked(null, providers.get(i), true); 4674 } 4675 4676 // Remove transient permissions granted from/to this package/user 4677 removeUriPermissionsForPackageLocked(name, userId, false); 4678 4679 if (name == null) { 4680 // Remove pending intents. For now we only do this when force 4681 // stopping users, because we have some problems when doing this 4682 // for packages -- app widgets are not currently cleaned up for 4683 // such packages, so they can be left with bad pending intents. 4684 if (mIntentSenderRecords.size() > 0) { 4685 Iterator<WeakReference<PendingIntentRecord>> it 4686 = mIntentSenderRecords.values().iterator(); 4687 while (it.hasNext()) { 4688 WeakReference<PendingIntentRecord> wpir = it.next(); 4689 if (wpir == null) { 4690 it.remove(); 4691 continue; 4692 } 4693 PendingIntentRecord pir = wpir.get(); 4694 if (pir == null) { 4695 it.remove(); 4696 continue; 4697 } 4698 if (name == null) { 4699 // Stopping user, remove all objects for the user. 4700 if (pir.key.userId != userId) { 4701 // Not the same user, skip it. 4702 continue; 4703 } 4704 } else { 4705 if (UserHandle.getAppId(pir.uid) != appId) { 4706 // Different app id, skip it. 4707 continue; 4708 } 4709 if (userId != UserHandle.USER_ALL && pir.key.userId != userId) { 4710 // Different user, skip it. 4711 continue; 4712 } 4713 if (!pir.key.packageName.equals(name)) { 4714 // Different package, skip it. 4715 continue; 4716 } 4717 } 4718 if (!doit) { 4719 return true; 4720 } 4721 didSomething = true; 4722 it.remove(); 4723 pir.canceled = true; 4724 if (pir.key.activity != null) { 4725 pir.key.activity.pendingResults.remove(pir.ref); 4726 } 4727 } 4728 } 4729 } 4730 4731 if (doit) { 4732 if (purgeCache && name != null) { 4733 AttributeCache ac = AttributeCache.instance(); 4734 if (ac != null) { 4735 ac.removePackage(name); 4736 } 4737 } 4738 if (mBooted) { 4739 mStackSupervisor.resumeTopActivitiesLocked(); 4740 mStackSupervisor.scheduleIdleLocked(); 4741 } 4742 } 4743 4744 return didSomething; 4745 } 4746 4747 private final boolean removeProcessLocked(ProcessRecord app, 4748 boolean callerWillRestart, boolean allowRestart, String reason) { 4749 final String name = app.processName; 4750 final int uid = app.uid; 4751 if (DEBUG_PROCESSES) Slog.d( 4752 TAG, "Force removing proc " + app.toShortString() + " (" + name 4753 + "/" + uid + ")"); 4754 4755 mProcessNames.remove(name, uid); 4756 mIsolatedProcesses.remove(app.uid); 4757 if (mHeavyWeightProcess == app) { 4758 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 4759 mHeavyWeightProcess.userId, 0)); 4760 mHeavyWeightProcess = null; 4761 } 4762 boolean needRestart = false; 4763 if (app.pid > 0 && app.pid != MY_PID) { 4764 int pid = app.pid; 4765 synchronized (mPidsSelfLocked) { 4766 mPidsSelfLocked.remove(pid); 4767 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 4768 } 4769 killUnneededProcessLocked(app, reason); 4770 handleAppDiedLocked(app, true, allowRestart); 4771 removeLruProcessLocked(app); 4772 4773 if (app.persistent && !app.isolated) { 4774 if (!callerWillRestart) { 4775 addAppLocked(app.info, false, null /* ABI override */); 4776 } else { 4777 needRestart = true; 4778 } 4779 } 4780 } else { 4781 mRemovedProcesses.add(app); 4782 } 4783 4784 return needRestart; 4785 } 4786 4787 private final void processStartTimedOutLocked(ProcessRecord app) { 4788 final int pid = app.pid; 4789 boolean gone = false; 4790 synchronized (mPidsSelfLocked) { 4791 ProcessRecord knownApp = mPidsSelfLocked.get(pid); 4792 if (knownApp != null && knownApp.thread == null) { 4793 mPidsSelfLocked.remove(pid); 4794 gone = true; 4795 } 4796 } 4797 4798 if (gone) { 4799 Slog.w(TAG, "Process " + app + " failed to attach"); 4800 EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId, 4801 pid, app.uid, app.processName); 4802 mProcessNames.remove(app.processName, app.uid); 4803 mIsolatedProcesses.remove(app.uid); 4804 if (mHeavyWeightProcess == app) { 4805 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 4806 mHeavyWeightProcess.userId, 0)); 4807 mHeavyWeightProcess = null; 4808 } 4809 // Take care of any launching providers waiting for this process. 4810 checkAppInLaunchingProvidersLocked(app, true); 4811 // Take care of any services that are waiting for the process. 4812 mServices.processStartTimedOutLocked(app); 4813 killUnneededProcessLocked(app, "start timeout"); 4814 if (mBackupTarget != null && mBackupTarget.app.pid == pid) { 4815 Slog.w(TAG, "Unattached app died before backup, skipping"); 4816 try { 4817 IBackupManager bm = IBackupManager.Stub.asInterface( 4818 ServiceManager.getService(Context.BACKUP_SERVICE)); 4819 bm.agentDisconnected(app.info.packageName); 4820 } catch (RemoteException e) { 4821 // Can't happen; the backup manager is local 4822 } 4823 } 4824 if (isPendingBroadcastProcessLocked(pid)) { 4825 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 4826 skipPendingBroadcastLocked(pid); 4827 } 4828 } else { 4829 Slog.w(TAG, "Spurious process start timeout - pid not known for " + app); 4830 } 4831 } 4832 4833 private final boolean attachApplicationLocked(IApplicationThread thread, 4834 int pid) { 4835 4836 // Find the application record that is being attached... either via 4837 // the pid if we are running in multiple processes, or just pull the 4838 // next app record if we are emulating process with anonymous threads. 4839 ProcessRecord app; 4840 if (pid != MY_PID && pid >= 0) { 4841 synchronized (mPidsSelfLocked) { 4842 app = mPidsSelfLocked.get(pid); 4843 } 4844 } else { 4845 app = null; 4846 } 4847 4848 if (app == null) { 4849 Slog.w(TAG, "No pending application record for pid " + pid 4850 + " (IApplicationThread " + thread + "); dropping process"); 4851 EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid); 4852 if (pid > 0 && pid != MY_PID) { 4853 Process.killProcessQuiet(pid); 4854 } else { 4855 try { 4856 thread.scheduleExit(); 4857 } catch (Exception e) { 4858 // Ignore exceptions. 4859 } 4860 } 4861 return false; 4862 } 4863 4864 // If this application record is still attached to a previous 4865 // process, clean it up now. 4866 if (app.thread != null) { 4867 handleAppDiedLocked(app, true, true); 4868 } 4869 4870 // Tell the process all about itself. 4871 4872 if (localLOGV) Slog.v( 4873 TAG, "Binding process pid " + pid + " to record " + app); 4874 4875 final String processName = app.processName; 4876 try { 4877 AppDeathRecipient adr = new AppDeathRecipient( 4878 app, pid, thread); 4879 thread.asBinder().linkToDeath(adr, 0); 4880 app.deathRecipient = adr; 4881 } catch (RemoteException e) { 4882 app.resetPackageList(mProcessStats); 4883 startProcessLocked(app, "link fail", processName, null /* ABI override */); 4884 return false; 4885 } 4886 4887 EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName); 4888 4889 app.makeActive(thread, mProcessStats); 4890 app.curAdj = app.setAdj = -100; 4891 app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT; 4892 app.forcingToForeground = null; 4893 app.foregroundServices = false; 4894 app.hasShownUi = false; 4895 app.debugging = false; 4896 app.cached = false; 4897 4898 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 4899 4900 boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info); 4901 List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null; 4902 4903 if (!normalMode) { 4904 Slog.i(TAG, "Launching preboot mode app: " + app); 4905 } 4906 4907 if (localLOGV) Slog.v( 4908 TAG, "New app record " + app 4909 + " thread=" + thread.asBinder() + " pid=" + pid); 4910 try { 4911 int testMode = IApplicationThread.DEBUG_OFF; 4912 if (mDebugApp != null && mDebugApp.equals(processName)) { 4913 testMode = mWaitForDebugger 4914 ? IApplicationThread.DEBUG_WAIT 4915 : IApplicationThread.DEBUG_ON; 4916 app.debugging = true; 4917 if (mDebugTransient) { 4918 mDebugApp = mOrigDebugApp; 4919 mWaitForDebugger = mOrigWaitForDebugger; 4920 } 4921 } 4922 String profileFile = app.instrumentationProfileFile; 4923 ParcelFileDescriptor profileFd = null; 4924 boolean profileAutoStop = false; 4925 if (mProfileApp != null && mProfileApp.equals(processName)) { 4926 mProfileProc = app; 4927 profileFile = mProfileFile; 4928 profileFd = mProfileFd; 4929 profileAutoStop = mAutoStopProfiler; 4930 } 4931 boolean enableOpenGlTrace = false; 4932 if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) { 4933 enableOpenGlTrace = true; 4934 mOpenGlTraceApp = null; 4935 } 4936 4937 // If the app is being launched for restore or full backup, set it up specially 4938 boolean isRestrictedBackupMode = false; 4939 if (mBackupTarget != null && mBackupAppName.equals(processName)) { 4940 isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE) 4941 || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL) 4942 || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL); 4943 } 4944 4945 ensurePackageDexOpt(app.instrumentationInfo != null 4946 ? app.instrumentationInfo.packageName 4947 : app.info.packageName); 4948 if (app.instrumentationClass != null) { 4949 ensurePackageDexOpt(app.instrumentationClass.getPackageName()); 4950 } 4951 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc " 4952 + processName + " with config " + mConfiguration); 4953 ApplicationInfo appInfo = app.instrumentationInfo != null 4954 ? app.instrumentationInfo : app.info; 4955 app.compat = compatibilityInfoForPackageLocked(appInfo); 4956 if (profileFd != null) { 4957 profileFd = profileFd.dup(); 4958 } 4959 thread.bindApplication(processName, appInfo, providers, 4960 app.instrumentationClass, profileFile, profileFd, profileAutoStop, 4961 app.instrumentationArguments, app.instrumentationWatcher, 4962 app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace, 4963 isRestrictedBackupMode || !normalMode, app.persistent, 4964 new Configuration(mConfiguration), app.compat, getCommonServicesLocked(), 4965 mCoreSettingsObserver.getCoreSettingsLocked()); 4966 updateLruProcessLocked(app, false, null); 4967 app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis(); 4968 } catch (Exception e) { 4969 // todo: Yikes! What should we do? For now we will try to 4970 // start another process, but that could easily get us in 4971 // an infinite loop of restarting processes... 4972 Slog.w(TAG, "Exception thrown during bind!", e); 4973 4974 app.resetPackageList(mProcessStats); 4975 app.unlinkDeathRecipient(); 4976 startProcessLocked(app, "bind fail", processName, null /* ABI override */); 4977 return false; 4978 } 4979 4980 // Remove this record from the list of starting applications. 4981 mPersistentStartingProcesses.remove(app); 4982 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 4983 "Attach application locked removing on hold: " + app); 4984 mProcessesOnHold.remove(app); 4985 4986 boolean badApp = false; 4987 boolean didSomething = false; 4988 4989 // See if the top visible activity is waiting to run in this process... 4990 if (normalMode) { 4991 try { 4992 if (mStackSupervisor.attachApplicationLocked(app)) { 4993 didSomething = true; 4994 } 4995 } catch (Exception e) { 4996 badApp = true; 4997 } 4998 } 4999 5000 // Find any services that should be running in this process... 5001 if (!badApp) { 5002 try { 5003 didSomething |= mServices.attachApplicationLocked(app, processName); 5004 } catch (Exception e) { 5005 badApp = true; 5006 } 5007 } 5008 5009 // Check if a next-broadcast receiver is in this process... 5010 if (!badApp && isPendingBroadcastProcessLocked(pid)) { 5011 try { 5012 didSomething |= sendPendingBroadcastsLocked(app); 5013 } catch (Exception e) { 5014 // If the app died trying to launch the receiver we declare it 'bad' 5015 badApp = true; 5016 } 5017 } 5018 5019 // Check whether the next backup agent is in this process... 5020 if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) { 5021 if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app); 5022 ensurePackageDexOpt(mBackupTarget.appInfo.packageName); 5023 try { 5024 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo, 5025 compatibilityInfoForPackageLocked(mBackupTarget.appInfo), 5026 mBackupTarget.backupMode); 5027 } catch (Exception e) { 5028 Slog.w(TAG, "Exception scheduling backup agent creation: "); 5029 e.printStackTrace(); 5030 } 5031 } 5032 5033 if (badApp) { 5034 // todo: Also need to kill application to deal with all 5035 // kinds of exceptions. 5036 handleAppDiedLocked(app, false, true); 5037 return false; 5038 } 5039 5040 if (!didSomething) { 5041 updateOomAdjLocked(); 5042 } 5043 5044 return true; 5045 } 5046 5047 @Override 5048 public final void attachApplication(IApplicationThread thread) { 5049 synchronized (this) { 5050 int callingPid = Binder.getCallingPid(); 5051 final long origId = Binder.clearCallingIdentity(); 5052 attachApplicationLocked(thread, callingPid); 5053 Binder.restoreCallingIdentity(origId); 5054 } 5055 } 5056 5057 @Override 5058 public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) { 5059 final long origId = Binder.clearCallingIdentity(); 5060 synchronized (this) { 5061 ActivityStack stack = ActivityRecord.getStackLocked(token); 5062 if (stack != null) { 5063 ActivityRecord r = 5064 mStackSupervisor.activityIdleInternalLocked(token, false, config); 5065 if (stopProfiling) { 5066 if ((mProfileProc == r.app) && (mProfileFd != null)) { 5067 try { 5068 mProfileFd.close(); 5069 } catch (IOException e) { 5070 } 5071 clearProfilerLocked(); 5072 } 5073 } 5074 } 5075 } 5076 Binder.restoreCallingIdentity(origId); 5077 } 5078 5079 void enableScreenAfterBoot() { 5080 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN, 5081 SystemClock.uptimeMillis()); 5082 mWindowManager.enableScreenAfterBoot(); 5083 5084 synchronized (this) { 5085 updateEventDispatchingLocked(); 5086 } 5087 } 5088 5089 @Override 5090 public void showBootMessage(final CharSequence msg, final boolean always) { 5091 enforceNotIsolatedCaller("showBootMessage"); 5092 mWindowManager.showBootMessage(msg, always); 5093 } 5094 5095 @Override 5096 public void dismissKeyguardOnNextActivity() { 5097 enforceNotIsolatedCaller("dismissKeyguardOnNextActivity"); 5098 final long token = Binder.clearCallingIdentity(); 5099 try { 5100 synchronized (this) { 5101 if (DEBUG_LOCKSCREEN) logLockScreen(""); 5102 if (mLockScreenShown) { 5103 mLockScreenShown = false; 5104 comeOutOfSleepIfNeededLocked(); 5105 } 5106 mStackSupervisor.setDismissKeyguard(true); 5107 } 5108 } finally { 5109 Binder.restoreCallingIdentity(token); 5110 } 5111 } 5112 5113 final void finishBooting() { 5114 IntentFilter pkgFilter = new IntentFilter(); 5115 pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART); 5116 pkgFilter.addDataScheme("package"); 5117 mContext.registerReceiver(new BroadcastReceiver() { 5118 @Override 5119 public void onReceive(Context context, Intent intent) { 5120 String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES); 5121 if (pkgs != null) { 5122 for (String pkg : pkgs) { 5123 synchronized (ActivityManagerService.this) { 5124 if (forceStopPackageLocked(pkg, -1, false, false, false, false, 0, 5125 "finished booting")) { 5126 setResultCode(Activity.RESULT_OK); 5127 return; 5128 } 5129 } 5130 } 5131 } 5132 } 5133 }, pkgFilter); 5134 5135 synchronized (this) { 5136 // Ensure that any processes we had put on hold are now started 5137 // up. 5138 final int NP = mProcessesOnHold.size(); 5139 if (NP > 0) { 5140 ArrayList<ProcessRecord> procs = 5141 new ArrayList<ProcessRecord>(mProcessesOnHold); 5142 for (int ip=0; ip<NP; ip++) { 5143 if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: " 5144 + procs.get(ip)); 5145 startProcessLocked(procs.get(ip), "on-hold", null, null /* ABI override */); 5146 } 5147 } 5148 5149 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 5150 // Start looking for apps that are abusing wake locks. 5151 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 5152 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 5153 // Tell anyone interested that we are done booting! 5154 SystemProperties.set("sys.boot_completed", "1"); 5155 SystemProperties.set("dev.bootcomplete", "1"); 5156 for (int i=0; i<mStartedUsers.size(); i++) { 5157 UserStartedState uss = mStartedUsers.valueAt(i); 5158 if (uss.mState == UserStartedState.STATE_BOOTING) { 5159 uss.mState = UserStartedState.STATE_RUNNING; 5160 final int userId = mStartedUsers.keyAt(i); 5161 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 5162 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 5163 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT); 5164 broadcastIntentLocked(null, null, intent, null, 5165 new IIntentReceiver.Stub() { 5166 @Override 5167 public void performReceive(Intent intent, int resultCode, 5168 String data, Bundle extras, boolean ordered, 5169 boolean sticky, int sendingUser) { 5170 synchronized (ActivityManagerService.this) { 5171 requestPssAllProcsLocked(SystemClock.uptimeMillis(), 5172 true, false); 5173 } 5174 } 5175 }, 5176 0, null, null, 5177 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, 5178 AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID, 5179 userId); 5180 } 5181 } 5182 } 5183 } 5184 } 5185 5186 final void ensureBootCompleted() { 5187 boolean booting; 5188 boolean enableScreen; 5189 synchronized (this) { 5190 booting = mBooting; 5191 mBooting = false; 5192 enableScreen = !mBooted; 5193 mBooted = true; 5194 } 5195 5196 if (booting) { 5197 finishBooting(); 5198 } 5199 5200 if (enableScreen) { 5201 enableScreenAfterBoot(); 5202 } 5203 } 5204 5205 @Override 5206 public final void activityResumed(IBinder token) { 5207 final long origId = Binder.clearCallingIdentity(); 5208 synchronized(this) { 5209 ActivityStack stack = ActivityRecord.getStackLocked(token); 5210 if (stack != null) { 5211 ActivityRecord.activityResumedLocked(token); 5212 } 5213 } 5214 Binder.restoreCallingIdentity(origId); 5215 } 5216 5217 @Override 5218 public final void activityPaused(IBinder token) { 5219 final long origId = Binder.clearCallingIdentity(); 5220 synchronized(this) { 5221 ActivityStack stack = ActivityRecord.getStackLocked(token); 5222 if (stack != null) { 5223 stack.activityPausedLocked(token, false); 5224 } 5225 } 5226 Binder.restoreCallingIdentity(origId); 5227 } 5228 5229 @Override 5230 public final void activityStopped(IBinder token, Bundle icicle, Bitmap thumbnail, 5231 CharSequence description) { 5232 if (localLOGV) Slog.v( 5233 TAG, "Activity stopped: token=" + token); 5234 5235 // Refuse possible leaked file descriptors 5236 if (icicle != null && icicle.hasFileDescriptors()) { 5237 throw new IllegalArgumentException("File descriptors passed in Bundle"); 5238 } 5239 5240 ActivityRecord r = null; 5241 5242 final long origId = Binder.clearCallingIdentity(); 5243 5244 synchronized (this) { 5245 r = ActivityRecord.isInStackLocked(token); 5246 if (r != null) { 5247 r.task.stack.activityStoppedLocked(r, icicle, thumbnail, description); 5248 } 5249 } 5250 5251 if (r != null) { 5252 sendPendingThumbnail(r, null, null, null, false); 5253 } 5254 5255 trimApplications(); 5256 5257 Binder.restoreCallingIdentity(origId); 5258 } 5259 5260 @Override 5261 public final void activityDestroyed(IBinder token) { 5262 if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token); 5263 synchronized (this) { 5264 ActivityStack stack = ActivityRecord.getStackLocked(token); 5265 if (stack != null) { 5266 stack.activityDestroyedLocked(token); 5267 } 5268 } 5269 } 5270 5271 @Override 5272 public String getCallingPackage(IBinder token) { 5273 synchronized (this) { 5274 ActivityRecord r = getCallingRecordLocked(token); 5275 return r != null ? r.info.packageName : null; 5276 } 5277 } 5278 5279 @Override 5280 public ComponentName getCallingActivity(IBinder token) { 5281 synchronized (this) { 5282 ActivityRecord r = getCallingRecordLocked(token); 5283 return r != null ? r.intent.getComponent() : null; 5284 } 5285 } 5286 5287 private ActivityRecord getCallingRecordLocked(IBinder token) { 5288 ActivityRecord r = ActivityRecord.isInStackLocked(token); 5289 if (r == null) { 5290 return null; 5291 } 5292 return r.resultTo; 5293 } 5294 5295 @Override 5296 public ComponentName getActivityClassForToken(IBinder token) { 5297 synchronized(this) { 5298 ActivityRecord r = ActivityRecord.isInStackLocked(token); 5299 if (r == null) { 5300 return null; 5301 } 5302 return r.intent.getComponent(); 5303 } 5304 } 5305 5306 @Override 5307 public String getPackageForToken(IBinder token) { 5308 synchronized(this) { 5309 ActivityRecord r = ActivityRecord.isInStackLocked(token); 5310 if (r == null) { 5311 return null; 5312 } 5313 return r.packageName; 5314 } 5315 } 5316 5317 @Override 5318 public IIntentSender getIntentSender(int type, 5319 String packageName, IBinder token, String resultWho, 5320 int requestCode, Intent[] intents, String[] resolvedTypes, 5321 int flags, Bundle options, int userId) { 5322 enforceNotIsolatedCaller("getIntentSender"); 5323 // Refuse possible leaked file descriptors 5324 if (intents != null) { 5325 if (intents.length < 1) { 5326 throw new IllegalArgumentException("Intents array length must be >= 1"); 5327 } 5328 for (int i=0; i<intents.length; i++) { 5329 Intent intent = intents[i]; 5330 if (intent != null) { 5331 if (intent.hasFileDescriptors()) { 5332 throw new IllegalArgumentException("File descriptors passed in Intent"); 5333 } 5334 if (type == ActivityManager.INTENT_SENDER_BROADCAST && 5335 (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 5336 throw new IllegalArgumentException( 5337 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 5338 } 5339 intents[i] = new Intent(intent); 5340 } 5341 } 5342 if (resolvedTypes != null && resolvedTypes.length != intents.length) { 5343 throw new IllegalArgumentException( 5344 "Intent array length does not match resolvedTypes length"); 5345 } 5346 } 5347 if (options != null) { 5348 if (options.hasFileDescriptors()) { 5349 throw new IllegalArgumentException("File descriptors passed in options"); 5350 } 5351 } 5352 5353 synchronized(this) { 5354 int callingUid = Binder.getCallingUid(); 5355 int origUserId = userId; 5356 userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId, 5357 type == ActivityManager.INTENT_SENDER_BROADCAST, false, 5358 "getIntentSender", null); 5359 if (origUserId == UserHandle.USER_CURRENT) { 5360 // We don't want to evaluate this until the pending intent is 5361 // actually executed. However, we do want to always do the 5362 // security checking for it above. 5363 userId = UserHandle.USER_CURRENT; 5364 } 5365 try { 5366 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 5367 int uid = AppGlobals.getPackageManager() 5368 .getPackageUid(packageName, UserHandle.getUserId(callingUid)); 5369 if (!UserHandle.isSameApp(callingUid, uid)) { 5370 String msg = "Permission Denial: getIntentSender() from pid=" 5371 + Binder.getCallingPid() 5372 + ", uid=" + Binder.getCallingUid() 5373 + ", (need uid=" + uid + ")" 5374 + " is not allowed to send as package " + packageName; 5375 Slog.w(TAG, msg); 5376 throw new SecurityException(msg); 5377 } 5378 } 5379 5380 return getIntentSenderLocked(type, packageName, callingUid, userId, 5381 token, resultWho, requestCode, intents, resolvedTypes, flags, options); 5382 5383 } catch (RemoteException e) { 5384 throw new SecurityException(e); 5385 } 5386 } 5387 } 5388 5389 IIntentSender getIntentSenderLocked(int type, String packageName, 5390 int callingUid, int userId, IBinder token, String resultWho, 5391 int requestCode, Intent[] intents, String[] resolvedTypes, int flags, 5392 Bundle options) { 5393 if (DEBUG_MU) 5394 Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid); 5395 ActivityRecord activity = null; 5396 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 5397 activity = ActivityRecord.isInStackLocked(token); 5398 if (activity == null) { 5399 return null; 5400 } 5401 if (activity.finishing) { 5402 return null; 5403 } 5404 } 5405 5406 final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0; 5407 final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0; 5408 final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0; 5409 flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT 5410 |PendingIntent.FLAG_UPDATE_CURRENT); 5411 5412 PendingIntentRecord.Key key = new PendingIntentRecord.Key( 5413 type, packageName, activity, resultWho, 5414 requestCode, intents, resolvedTypes, flags, options, userId); 5415 WeakReference<PendingIntentRecord> ref; 5416 ref = mIntentSenderRecords.get(key); 5417 PendingIntentRecord rec = ref != null ? ref.get() : null; 5418 if (rec != null) { 5419 if (!cancelCurrent) { 5420 if (updateCurrent) { 5421 if (rec.key.requestIntent != null) { 5422 rec.key.requestIntent.replaceExtras(intents != null ? 5423 intents[intents.length - 1] : null); 5424 } 5425 if (intents != null) { 5426 intents[intents.length-1] = rec.key.requestIntent; 5427 rec.key.allIntents = intents; 5428 rec.key.allResolvedTypes = resolvedTypes; 5429 } else { 5430 rec.key.allIntents = null; 5431 rec.key.allResolvedTypes = null; 5432 } 5433 } 5434 return rec; 5435 } 5436 rec.canceled = true; 5437 mIntentSenderRecords.remove(key); 5438 } 5439 if (noCreate) { 5440 return rec; 5441 } 5442 rec = new PendingIntentRecord(this, key, callingUid); 5443 mIntentSenderRecords.put(key, rec.ref); 5444 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 5445 if (activity.pendingResults == null) { 5446 activity.pendingResults 5447 = new HashSet<WeakReference<PendingIntentRecord>>(); 5448 } 5449 activity.pendingResults.add(rec.ref); 5450 } 5451 return rec; 5452 } 5453 5454 @Override 5455 public void cancelIntentSender(IIntentSender sender) { 5456 if (!(sender instanceof PendingIntentRecord)) { 5457 return; 5458 } 5459 synchronized(this) { 5460 PendingIntentRecord rec = (PendingIntentRecord)sender; 5461 try { 5462 int uid = AppGlobals.getPackageManager() 5463 .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId()); 5464 if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) { 5465 String msg = "Permission Denial: cancelIntentSender() from pid=" 5466 + Binder.getCallingPid() 5467 + ", uid=" + Binder.getCallingUid() 5468 + " is not allowed to cancel packges " 5469 + rec.key.packageName; 5470 Slog.w(TAG, msg); 5471 throw new SecurityException(msg); 5472 } 5473 } catch (RemoteException e) { 5474 throw new SecurityException(e); 5475 } 5476 cancelIntentSenderLocked(rec, true); 5477 } 5478 } 5479 5480 void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) { 5481 rec.canceled = true; 5482 mIntentSenderRecords.remove(rec.key); 5483 if (cleanActivity && rec.key.activity != null) { 5484 rec.key.activity.pendingResults.remove(rec.ref); 5485 } 5486 } 5487 5488 @Override 5489 public String getPackageForIntentSender(IIntentSender pendingResult) { 5490 if (!(pendingResult instanceof PendingIntentRecord)) { 5491 return null; 5492 } 5493 try { 5494 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5495 return res.key.packageName; 5496 } catch (ClassCastException e) { 5497 } 5498 return null; 5499 } 5500 5501 @Override 5502 public int getUidForIntentSender(IIntentSender sender) { 5503 if (sender instanceof PendingIntentRecord) { 5504 try { 5505 PendingIntentRecord res = (PendingIntentRecord)sender; 5506 return res.uid; 5507 } catch (ClassCastException e) { 5508 } 5509 } 5510 return -1; 5511 } 5512 5513 @Override 5514 public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) { 5515 if (!(pendingResult instanceof PendingIntentRecord)) { 5516 return false; 5517 } 5518 try { 5519 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5520 if (res.key.allIntents == null) { 5521 return false; 5522 } 5523 for (int i=0; i<res.key.allIntents.length; i++) { 5524 Intent intent = res.key.allIntents[i]; 5525 if (intent.getPackage() != null && intent.getComponent() != null) { 5526 return false; 5527 } 5528 } 5529 return true; 5530 } catch (ClassCastException e) { 5531 } 5532 return false; 5533 } 5534 5535 @Override 5536 public boolean isIntentSenderAnActivity(IIntentSender pendingResult) { 5537 if (!(pendingResult instanceof PendingIntentRecord)) { 5538 return false; 5539 } 5540 try { 5541 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5542 if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) { 5543 return true; 5544 } 5545 return false; 5546 } catch (ClassCastException e) { 5547 } 5548 return false; 5549 } 5550 5551 @Override 5552 public Intent getIntentForIntentSender(IIntentSender pendingResult) { 5553 if (!(pendingResult instanceof PendingIntentRecord)) { 5554 return null; 5555 } 5556 try { 5557 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5558 return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null; 5559 } catch (ClassCastException e) { 5560 } 5561 return null; 5562 } 5563 5564 @Override 5565 public void setProcessLimit(int max) { 5566 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 5567 "setProcessLimit()"); 5568 synchronized (this) { 5569 mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max; 5570 mProcessLimitOverride = max; 5571 } 5572 trimApplications(); 5573 } 5574 5575 @Override 5576 public int getProcessLimit() { 5577 synchronized (this) { 5578 return mProcessLimitOverride; 5579 } 5580 } 5581 5582 void foregroundTokenDied(ForegroundToken token) { 5583 synchronized (ActivityManagerService.this) { 5584 synchronized (mPidsSelfLocked) { 5585 ForegroundToken cur 5586 = mForegroundProcesses.get(token.pid); 5587 if (cur != token) { 5588 return; 5589 } 5590 mForegroundProcesses.remove(token.pid); 5591 ProcessRecord pr = mPidsSelfLocked.get(token.pid); 5592 if (pr == null) { 5593 return; 5594 } 5595 pr.forcingToForeground = null; 5596 pr.foregroundServices = false; 5597 } 5598 updateOomAdjLocked(); 5599 } 5600 } 5601 5602 @Override 5603 public void setProcessForeground(IBinder token, int pid, boolean isForeground) { 5604 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 5605 "setProcessForeground()"); 5606 synchronized(this) { 5607 boolean changed = false; 5608 5609 synchronized (mPidsSelfLocked) { 5610 ProcessRecord pr = mPidsSelfLocked.get(pid); 5611 if (pr == null && isForeground) { 5612 Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid); 5613 return; 5614 } 5615 ForegroundToken oldToken = mForegroundProcesses.get(pid); 5616 if (oldToken != null) { 5617 oldToken.token.unlinkToDeath(oldToken, 0); 5618 mForegroundProcesses.remove(pid); 5619 if (pr != null) { 5620 pr.forcingToForeground = null; 5621 } 5622 changed = true; 5623 } 5624 if (isForeground && token != null) { 5625 ForegroundToken newToken = new ForegroundToken() { 5626 @Override 5627 public void binderDied() { 5628 foregroundTokenDied(this); 5629 } 5630 }; 5631 newToken.pid = pid; 5632 newToken.token = token; 5633 try { 5634 token.linkToDeath(newToken, 0); 5635 mForegroundProcesses.put(pid, newToken); 5636 pr.forcingToForeground = token; 5637 changed = true; 5638 } catch (RemoteException e) { 5639 // If the process died while doing this, we will later 5640 // do the cleanup with the process death link. 5641 } 5642 } 5643 } 5644 5645 if (changed) { 5646 updateOomAdjLocked(); 5647 } 5648 } 5649 } 5650 5651 // ========================================================= 5652 // PERMISSIONS 5653 // ========================================================= 5654 5655 static class PermissionController extends IPermissionController.Stub { 5656 ActivityManagerService mActivityManagerService; 5657 PermissionController(ActivityManagerService activityManagerService) { 5658 mActivityManagerService = activityManagerService; 5659 } 5660 5661 @Override 5662 public boolean checkPermission(String permission, int pid, int uid) { 5663 return mActivityManagerService.checkPermission(permission, pid, 5664 uid) == PackageManager.PERMISSION_GRANTED; 5665 } 5666 } 5667 5668 class IntentFirewallInterface implements IntentFirewall.AMSInterface { 5669 @Override 5670 public int checkComponentPermission(String permission, int pid, int uid, 5671 int owningUid, boolean exported) { 5672 return ActivityManagerService.this.checkComponentPermission(permission, pid, uid, 5673 owningUid, exported); 5674 } 5675 5676 @Override 5677 public Object getAMSLock() { 5678 return ActivityManagerService.this; 5679 } 5680 } 5681 5682 /** 5683 * This can be called with or without the global lock held. 5684 */ 5685 int checkComponentPermission(String permission, int pid, int uid, 5686 int owningUid, boolean exported) { 5687 // We might be performing an operation on behalf of an indirect binder 5688 // invocation, e.g. via {@link #openContentUri}. Check and adjust the 5689 // client identity accordingly before proceeding. 5690 Identity tlsIdentity = sCallerIdentity.get(); 5691 if (tlsIdentity != null) { 5692 Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {" 5693 + tlsIdentity.pid + "," + tlsIdentity.uid + "}"); 5694 uid = tlsIdentity.uid; 5695 pid = tlsIdentity.pid; 5696 } 5697 5698 if (pid == MY_PID) { 5699 return PackageManager.PERMISSION_GRANTED; 5700 } 5701 5702 return ActivityManager.checkComponentPermission(permission, uid, 5703 owningUid, exported); 5704 } 5705 5706 /** 5707 * As the only public entry point for permissions checking, this method 5708 * can enforce the semantic that requesting a check on a null global 5709 * permission is automatically denied. (Internally a null permission 5710 * string is used when calling {@link #checkComponentPermission} in cases 5711 * when only uid-based security is needed.) 5712 * 5713 * This can be called with or without the global lock held. 5714 */ 5715 @Override 5716 public int checkPermission(String permission, int pid, int uid) { 5717 if (permission == null) { 5718 return PackageManager.PERMISSION_DENIED; 5719 } 5720 return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true); 5721 } 5722 5723 /** 5724 * Binder IPC calls go through the public entry point. 5725 * This can be called with or without the global lock held. 5726 */ 5727 int checkCallingPermission(String permission) { 5728 return checkPermission(permission, 5729 Binder.getCallingPid(), 5730 UserHandle.getAppId(Binder.getCallingUid())); 5731 } 5732 5733 /** 5734 * This can be called with or without the global lock held. 5735 */ 5736 void enforceCallingPermission(String permission, String func) { 5737 if (checkCallingPermission(permission) 5738 == PackageManager.PERMISSION_GRANTED) { 5739 return; 5740 } 5741 5742 String msg = "Permission Denial: " + func + " from pid=" 5743 + Binder.getCallingPid() 5744 + ", uid=" + Binder.getCallingUid() 5745 + " requires " + permission; 5746 Slog.w(TAG, msg); 5747 throw new SecurityException(msg); 5748 } 5749 5750 /** 5751 * Determine if UID is holding permissions required to access {@link Uri} in 5752 * the given {@link ProviderInfo}. Final permission checking is always done 5753 * in {@link ContentProvider}. 5754 */ 5755 private final boolean checkHoldingPermissionsLocked( 5756 IPackageManager pm, ProviderInfo pi, Uri uri, int uid, int modeFlags) { 5757 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5758 "checkHoldingPermissionsLocked: uri=" + uri + " uid=" + uid); 5759 5760 if (pi.applicationInfo.uid == uid) { 5761 return true; 5762 } else if (!pi.exported) { 5763 return false; 5764 } 5765 5766 boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0; 5767 boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0; 5768 try { 5769 // check if target holds top-level <provider> permissions 5770 if (!readMet && pi.readPermission != null 5771 && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) { 5772 readMet = true; 5773 } 5774 if (!writeMet && pi.writePermission != null 5775 && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) { 5776 writeMet = true; 5777 } 5778 5779 // track if unprotected read/write is allowed; any denied 5780 // <path-permission> below removes this ability 5781 boolean allowDefaultRead = pi.readPermission == null; 5782 boolean allowDefaultWrite = pi.writePermission == null; 5783 5784 // check if target holds any <path-permission> that match uri 5785 final PathPermission[] pps = pi.pathPermissions; 5786 if (pps != null) { 5787 final String path = uri.getPath(); 5788 int i = pps.length; 5789 while (i > 0 && (!readMet || !writeMet)) { 5790 i--; 5791 PathPermission pp = pps[i]; 5792 if (pp.match(path)) { 5793 if (!readMet) { 5794 final String pprperm = pp.getReadPermission(); 5795 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for " 5796 + pprperm + " for " + pp.getPath() 5797 + ": match=" + pp.match(path) 5798 + " check=" + pm.checkUidPermission(pprperm, uid)); 5799 if (pprperm != null) { 5800 if (pm.checkUidPermission(pprperm, uid) == PERMISSION_GRANTED) { 5801 readMet = true; 5802 } else { 5803 allowDefaultRead = false; 5804 } 5805 } 5806 } 5807 if (!writeMet) { 5808 final String ppwperm = pp.getWritePermission(); 5809 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm " 5810 + ppwperm + " for " + pp.getPath() 5811 + ": match=" + pp.match(path) 5812 + " check=" + pm.checkUidPermission(ppwperm, uid)); 5813 if (ppwperm != null) { 5814 if (pm.checkUidPermission(ppwperm, uid) == PERMISSION_GRANTED) { 5815 writeMet = true; 5816 } else { 5817 allowDefaultWrite = false; 5818 } 5819 } 5820 } 5821 } 5822 } 5823 } 5824 5825 // grant unprotected <provider> read/write, if not blocked by 5826 // <path-permission> above 5827 if (allowDefaultRead) readMet = true; 5828 if (allowDefaultWrite) writeMet = true; 5829 5830 } catch (RemoteException e) { 5831 return false; 5832 } 5833 5834 return readMet && writeMet; 5835 } 5836 5837 private ProviderInfo getProviderInfoLocked(String authority, int userHandle) { 5838 ProviderInfo pi = null; 5839 ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle); 5840 if (cpr != null) { 5841 pi = cpr.info; 5842 } else { 5843 try { 5844 pi = AppGlobals.getPackageManager().resolveContentProvider( 5845 authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle); 5846 } catch (RemoteException ex) { 5847 } 5848 } 5849 return pi; 5850 } 5851 5852 private UriPermission findUriPermissionLocked(int targetUid, Uri uri) { 5853 ArrayMap<Uri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid); 5854 if (targetUris != null) { 5855 return targetUris.get(uri); 5856 } else { 5857 return null; 5858 } 5859 } 5860 5861 private UriPermission findOrCreateUriPermissionLocked( 5862 String sourcePkg, String targetPkg, int targetUid, Uri uri) { 5863 ArrayMap<Uri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid); 5864 if (targetUris == null) { 5865 targetUris = Maps.newArrayMap(); 5866 mGrantedUriPermissions.put(targetUid, targetUris); 5867 } 5868 5869 UriPermission perm = targetUris.get(uri); 5870 if (perm == null) { 5871 perm = new UriPermission(sourcePkg, targetPkg, targetUid, uri); 5872 targetUris.put(uri, perm); 5873 } 5874 5875 return perm; 5876 } 5877 5878 private final boolean checkUriPermissionLocked( 5879 Uri uri, int uid, int modeFlags, int minStrength) { 5880 // Root gets to do everything. 5881 if (uid == 0) { 5882 return true; 5883 } 5884 ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(uid); 5885 if (perms == null) return false; 5886 UriPermission perm = perms.get(uri); 5887 if (perm == null) return false; 5888 return perm.getStrength(modeFlags) >= minStrength; 5889 } 5890 5891 @Override 5892 public int checkUriPermission(Uri uri, int pid, int uid, int modeFlags) { 5893 enforceNotIsolatedCaller("checkUriPermission"); 5894 5895 // Another redirected-binder-call permissions check as in 5896 // {@link checkComponentPermission}. 5897 Identity tlsIdentity = sCallerIdentity.get(); 5898 if (tlsIdentity != null) { 5899 uid = tlsIdentity.uid; 5900 pid = tlsIdentity.pid; 5901 } 5902 5903 // Our own process gets to do everything. 5904 if (pid == MY_PID) { 5905 return PackageManager.PERMISSION_GRANTED; 5906 } 5907 synchronized(this) { 5908 return checkUriPermissionLocked(uri, uid, modeFlags, UriPermission.STRENGTH_OWNED) 5909 ? PackageManager.PERMISSION_GRANTED 5910 : PackageManager.PERMISSION_DENIED; 5911 } 5912 } 5913 5914 /** 5915 * Check if the targetPkg can be granted permission to access uri by 5916 * the callingUid using the given modeFlags. Throws a security exception 5917 * if callingUid is not allowed to do this. Returns the uid of the target 5918 * if the URI permission grant should be performed; returns -1 if it is not 5919 * needed (for example targetPkg already has permission to access the URI). 5920 * If you already know the uid of the target, you can supply it in 5921 * lastTargetUid else set that to -1. 5922 */ 5923 int checkGrantUriPermissionLocked(int callingUid, String targetPkg, 5924 Uri uri, int modeFlags, int lastTargetUid) { 5925 final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0; 5926 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION 5927 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 5928 if (modeFlags == 0) { 5929 return -1; 5930 } 5931 5932 if (targetPkg != null) { 5933 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5934 "Checking grant " + targetPkg + " permission to " + uri); 5935 } 5936 5937 final IPackageManager pm = AppGlobals.getPackageManager(); 5938 5939 // If this is not a content: uri, we can't do anything with it. 5940 if (!ContentResolver.SCHEME_CONTENT.equals(uri.getScheme())) { 5941 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5942 "Can't grant URI permission for non-content URI: " + uri); 5943 return -1; 5944 } 5945 5946 final String authority = uri.getAuthority(); 5947 final ProviderInfo pi = getProviderInfoLocked(authority, UserHandle.getUserId(callingUid)); 5948 if (pi == null) { 5949 Slog.w(TAG, "No content provider found for permission check: " + uri.toSafeString()); 5950 return -1; 5951 } 5952 5953 int targetUid = lastTargetUid; 5954 if (targetUid < 0 && targetPkg != null) { 5955 try { 5956 targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid)); 5957 if (targetUid < 0) { 5958 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5959 "Can't grant URI permission no uid for: " + targetPkg); 5960 return -1; 5961 } 5962 } catch (RemoteException ex) { 5963 return -1; 5964 } 5965 } 5966 5967 if (targetUid >= 0) { 5968 // First... does the target actually need this permission? 5969 if (checkHoldingPermissionsLocked(pm, pi, uri, targetUid, modeFlags)) { 5970 // No need to grant the target this permission. 5971 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5972 "Target " + targetPkg + " already has full permission to " + uri); 5973 return -1; 5974 } 5975 } else { 5976 // First... there is no target package, so can anyone access it? 5977 boolean allowed = pi.exported; 5978 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) { 5979 if (pi.readPermission != null) { 5980 allowed = false; 5981 } 5982 } 5983 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) { 5984 if (pi.writePermission != null) { 5985 allowed = false; 5986 } 5987 } 5988 if (allowed) { 5989 return -1; 5990 } 5991 } 5992 5993 // Second... is the provider allowing granting of URI permissions? 5994 if (!pi.grantUriPermissions) { 5995 throw new SecurityException("Provider " + pi.packageName 5996 + "/" + pi.name 5997 + " does not allow granting of Uri permissions (uri " 5998 + uri + ")"); 5999 } 6000 if (pi.uriPermissionPatterns != null) { 6001 final int N = pi.uriPermissionPatterns.length; 6002 boolean allowed = false; 6003 for (int i=0; i<N; i++) { 6004 if (pi.uriPermissionPatterns[i] != null 6005 && pi.uriPermissionPatterns[i].match(uri.getPath())) { 6006 allowed = true; 6007 break; 6008 } 6009 } 6010 if (!allowed) { 6011 throw new SecurityException("Provider " + pi.packageName 6012 + "/" + pi.name 6013 + " does not allow granting of permission to path of Uri " 6014 + uri); 6015 } 6016 } 6017 6018 // Third... does the caller itself have permission to access 6019 // this uri? 6020 if (callingUid != Process.myUid()) { 6021 if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) { 6022 // Require they hold a strong enough Uri permission 6023 final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE 6024 : UriPermission.STRENGTH_OWNED; 6025 if (!checkUriPermissionLocked(uri, callingUid, modeFlags, minStrength)) { 6026 throw new SecurityException("Uid " + callingUid 6027 + " does not have permission to uri " + uri); 6028 } 6029 } 6030 } 6031 6032 return targetUid; 6033 } 6034 6035 @Override 6036 public int checkGrantUriPermission(int callingUid, String targetPkg, 6037 Uri uri, int modeFlags) { 6038 enforceNotIsolatedCaller("checkGrantUriPermission"); 6039 synchronized(this) { 6040 return checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1); 6041 } 6042 } 6043 6044 void grantUriPermissionUncheckedLocked( 6045 int targetUid, String targetPkg, Uri uri, int modeFlags, UriPermissionOwner owner) { 6046 final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0; 6047 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION 6048 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 6049 if (modeFlags == 0) { 6050 return; 6051 } 6052 6053 // So here we are: the caller has the assumed permission 6054 // to the uri, and the target doesn't. Let's now give this to 6055 // the target. 6056 6057 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6058 "Granting " + targetPkg + "/" + targetUid + " permission to " + uri); 6059 6060 final String authority = uri.getAuthority(); 6061 final ProviderInfo pi = getProviderInfoLocked(authority, UserHandle.getUserId(targetUid)); 6062 if (pi == null) { 6063 Slog.w(TAG, "No content provider found for grant: " + uri.toSafeString()); 6064 return; 6065 } 6066 6067 final UriPermission perm = findOrCreateUriPermissionLocked( 6068 pi.packageName, targetPkg, targetUid, uri); 6069 perm.grantModes(modeFlags, persistable, owner); 6070 } 6071 6072 void grantUriPermissionLocked(int callingUid, String targetPkg, Uri uri, 6073 int modeFlags, UriPermissionOwner owner) { 6074 if (targetPkg == null) { 6075 throw new NullPointerException("targetPkg"); 6076 } 6077 6078 int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1); 6079 if (targetUid < 0) { 6080 return; 6081 } 6082 6083 grantUriPermissionUncheckedLocked(targetUid, targetPkg, uri, modeFlags, owner); 6084 } 6085 6086 static class NeededUriGrants extends ArrayList<Uri> { 6087 final String targetPkg; 6088 final int targetUid; 6089 final int flags; 6090 6091 NeededUriGrants(String targetPkg, int targetUid, int flags) { 6092 this.targetPkg = targetPkg; 6093 this.targetUid = targetUid; 6094 this.flags = flags; 6095 } 6096 } 6097 6098 /** 6099 * Like checkGrantUriPermissionLocked, but takes an Intent. 6100 */ 6101 NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid, 6102 String targetPkg, Intent intent, int mode, NeededUriGrants needed) { 6103 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6104 "Checking URI perm to data=" + (intent != null ? intent.getData() : null) 6105 + " clip=" + (intent != null ? intent.getClipData() : null) 6106 + " from " + intent + "; flags=0x" 6107 + Integer.toHexString(intent != null ? intent.getFlags() : 0)); 6108 6109 if (targetPkg == null) { 6110 throw new NullPointerException("targetPkg"); 6111 } 6112 6113 if (intent == null) { 6114 return null; 6115 } 6116 Uri data = intent.getData(); 6117 ClipData clip = intent.getClipData(); 6118 if (data == null && clip == null) { 6119 return null; 6120 } 6121 6122 if (data != null) { 6123 int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, data, 6124 mode, needed != null ? needed.targetUid : -1); 6125 if (targetUid > 0) { 6126 if (needed == null) { 6127 needed = new NeededUriGrants(targetPkg, targetUid, mode); 6128 } 6129 needed.add(data); 6130 } 6131 } 6132 if (clip != null) { 6133 for (int i=0; i<clip.getItemCount(); i++) { 6134 Uri uri = clip.getItemAt(i).getUri(); 6135 if (uri != null) { 6136 int targetUid = -1; 6137 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri, 6138 mode, needed != null ? needed.targetUid : -1); 6139 if (targetUid > 0) { 6140 if (needed == null) { 6141 needed = new NeededUriGrants(targetPkg, targetUid, mode); 6142 } 6143 needed.add(uri); 6144 } 6145 } else { 6146 Intent clipIntent = clip.getItemAt(i).getIntent(); 6147 if (clipIntent != null) { 6148 NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked( 6149 callingUid, targetPkg, clipIntent, mode, needed); 6150 if (newNeeded != null) { 6151 needed = newNeeded; 6152 } 6153 } 6154 } 6155 } 6156 } 6157 6158 return needed; 6159 } 6160 6161 /** 6162 * Like grantUriPermissionUncheckedLocked, but takes an Intent. 6163 */ 6164 void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed, 6165 UriPermissionOwner owner) { 6166 if (needed != null) { 6167 for (int i=0; i<needed.size(); i++) { 6168 grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg, 6169 needed.get(i), needed.flags, owner); 6170 } 6171 } 6172 } 6173 6174 void grantUriPermissionFromIntentLocked(int callingUid, 6175 String targetPkg, Intent intent, UriPermissionOwner owner) { 6176 NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg, 6177 intent, intent != null ? intent.getFlags() : 0, null); 6178 if (needed == null) { 6179 return; 6180 } 6181 6182 grantUriPermissionUncheckedFromIntentLocked(needed, owner); 6183 } 6184 6185 @Override 6186 public void grantUriPermission(IApplicationThread caller, String targetPkg, 6187 Uri uri, int modeFlags) { 6188 enforceNotIsolatedCaller("grantUriPermission"); 6189 synchronized(this) { 6190 final ProcessRecord r = getRecordForAppLocked(caller); 6191 if (r == null) { 6192 throw new SecurityException("Unable to find app for caller " 6193 + caller 6194 + " when granting permission to uri " + uri); 6195 } 6196 if (targetPkg == null) { 6197 throw new IllegalArgumentException("null target"); 6198 } 6199 if (uri == null) { 6200 throw new IllegalArgumentException("null uri"); 6201 } 6202 6203 // Persistable only supported through Intents 6204 Preconditions.checkFlagsArgument(modeFlags, 6205 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 6206 6207 grantUriPermissionLocked(r.uid, targetPkg, uri, modeFlags, 6208 null); 6209 } 6210 } 6211 6212 void removeUriPermissionIfNeededLocked(UriPermission perm) { 6213 if ((perm.modeFlags&(Intent.FLAG_GRANT_READ_URI_PERMISSION 6214 |Intent.FLAG_GRANT_WRITE_URI_PERMISSION)) == 0) { 6215 ArrayMap<Uri, UriPermission> perms 6216 = mGrantedUriPermissions.get(perm.targetUid); 6217 if (perms != null) { 6218 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6219 "Removing " + perm.targetUid + " permission to " + perm.uri); 6220 perms.remove(perm.uri); 6221 if (perms.size() == 0) { 6222 mGrantedUriPermissions.remove(perm.targetUid); 6223 } 6224 } 6225 } 6226 } 6227 6228 private void revokeUriPermissionLocked(int callingUid, Uri uri, int modeFlags) { 6229 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + uri); 6230 6231 final IPackageManager pm = AppGlobals.getPackageManager(); 6232 final String authority = uri.getAuthority(); 6233 final ProviderInfo pi = getProviderInfoLocked(authority, UserHandle.getUserId(callingUid)); 6234 if (pi == null) { 6235 Slog.w(TAG, "No content provider found for permission revoke: " + uri.toSafeString()); 6236 return; 6237 } 6238 6239 // Does the caller have this permission on the URI? 6240 if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) { 6241 // Right now, if you are not the original owner of the permission, 6242 // you are not allowed to revoke it. 6243 //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) { 6244 throw new SecurityException("Uid " + callingUid 6245 + " does not have permission to uri " + uri); 6246 //} 6247 } 6248 6249 boolean persistChanged = false; 6250 6251 // Go through all of the permissions and remove any that match. 6252 final List<String> SEGMENTS = uri.getPathSegments(); 6253 if (SEGMENTS != null) { 6254 final int NS = SEGMENTS.size(); 6255 int N = mGrantedUriPermissions.size(); 6256 for (int i=0; i<N; i++) { 6257 ArrayMap<Uri, UriPermission> perms 6258 = mGrantedUriPermissions.valueAt(i); 6259 Iterator<UriPermission> it = perms.values().iterator(); 6260 toploop: 6261 while (it.hasNext()) { 6262 UriPermission perm = it.next(); 6263 Uri targetUri = perm.uri; 6264 if (!authority.equals(targetUri.getAuthority())) { 6265 continue; 6266 } 6267 List<String> targetSegments = targetUri.getPathSegments(); 6268 if (targetSegments == null) { 6269 continue; 6270 } 6271 if (targetSegments.size() < NS) { 6272 continue; 6273 } 6274 for (int j=0; j<NS; j++) { 6275 if (!SEGMENTS.get(j).equals(targetSegments.get(j))) { 6276 continue toploop; 6277 } 6278 } 6279 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6280 "Revoking " + perm.targetUid + " permission to " + perm.uri); 6281 persistChanged |= perm.clearModes(modeFlags, true); 6282 if (perm.modeFlags == 0) { 6283 it.remove(); 6284 } 6285 } 6286 if (perms.size() == 0) { 6287 mGrantedUriPermissions.remove( 6288 mGrantedUriPermissions.keyAt(i)); 6289 N--; 6290 i--; 6291 } 6292 } 6293 } 6294 6295 if (persistChanged) { 6296 schedulePersistUriGrants(); 6297 } 6298 } 6299 6300 @Override 6301 public void revokeUriPermission(IApplicationThread caller, Uri uri, 6302 int modeFlags) { 6303 enforceNotIsolatedCaller("revokeUriPermission"); 6304 synchronized(this) { 6305 final ProcessRecord r = getRecordForAppLocked(caller); 6306 if (r == null) { 6307 throw new SecurityException("Unable to find app for caller " 6308 + caller 6309 + " when revoking permission to uri " + uri); 6310 } 6311 if (uri == null) { 6312 Slog.w(TAG, "revokeUriPermission: null uri"); 6313 return; 6314 } 6315 6316 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION 6317 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 6318 if (modeFlags == 0) { 6319 return; 6320 } 6321 6322 final IPackageManager pm = AppGlobals.getPackageManager(); 6323 final String authority = uri.getAuthority(); 6324 final ProviderInfo pi = getProviderInfoLocked(authority, r.userId); 6325 if (pi == null) { 6326 Slog.w(TAG, "No content provider found for permission revoke: " 6327 + uri.toSafeString()); 6328 return; 6329 } 6330 6331 revokeUriPermissionLocked(r.uid, uri, modeFlags); 6332 } 6333 } 6334 6335 /** 6336 * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the 6337 * given package. 6338 * 6339 * @param packageName Package name to match, or {@code null} to apply to all 6340 * packages. 6341 * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply 6342 * to all users. 6343 * @param persistable If persistable grants should be removed. 6344 */ 6345 private void removeUriPermissionsForPackageLocked( 6346 String packageName, int userHandle, boolean persistable) { 6347 if (userHandle == UserHandle.USER_ALL && packageName == null) { 6348 throw new IllegalArgumentException("Must narrow by either package or user"); 6349 } 6350 6351 boolean persistChanged = false; 6352 6353 final int size = mGrantedUriPermissions.size(); 6354 for (int i = 0; i < size; i++) { 6355 // Only inspect grants matching user 6356 if (userHandle == UserHandle.USER_ALL 6357 || userHandle == UserHandle.getUserId(mGrantedUriPermissions.keyAt(i))) { 6358 final Iterator<UriPermission> it = mGrantedUriPermissions.valueAt(i) 6359 .values().iterator(); 6360 while (it.hasNext()) { 6361 final UriPermission perm = it.next(); 6362 6363 // Only inspect grants matching package 6364 if (packageName == null || perm.sourcePkg.equals(packageName) 6365 || perm.targetPkg.equals(packageName)) { 6366 persistChanged |= perm.clearModes(~0, persistable); 6367 6368 // Only remove when no modes remain; any persisted grants 6369 // will keep this alive. 6370 if (perm.modeFlags == 0) { 6371 it.remove(); 6372 } 6373 } 6374 } 6375 } 6376 } 6377 6378 if (persistChanged) { 6379 schedulePersistUriGrants(); 6380 } 6381 } 6382 6383 @Override 6384 public IBinder newUriPermissionOwner(String name) { 6385 enforceNotIsolatedCaller("newUriPermissionOwner"); 6386 synchronized(this) { 6387 UriPermissionOwner owner = new UriPermissionOwner(this, name); 6388 return owner.getExternalTokenLocked(); 6389 } 6390 } 6391 6392 @Override 6393 public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, 6394 Uri uri, int modeFlags) { 6395 synchronized(this) { 6396 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 6397 if (owner == null) { 6398 throw new IllegalArgumentException("Unknown owner: " + token); 6399 } 6400 if (fromUid != Binder.getCallingUid()) { 6401 if (Binder.getCallingUid() != Process.myUid()) { 6402 // Only system code can grant URI permissions on behalf 6403 // of other users. 6404 throw new SecurityException("nice try"); 6405 } 6406 } 6407 if (targetPkg == null) { 6408 throw new IllegalArgumentException("null target"); 6409 } 6410 if (uri == null) { 6411 throw new IllegalArgumentException("null uri"); 6412 } 6413 6414 grantUriPermissionLocked(fromUid, targetPkg, uri, modeFlags, owner); 6415 } 6416 } 6417 6418 @Override 6419 public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode) { 6420 synchronized(this) { 6421 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 6422 if (owner == null) { 6423 throw new IllegalArgumentException("Unknown owner: " + token); 6424 } 6425 6426 if (uri == null) { 6427 owner.removeUriPermissionsLocked(mode); 6428 } else { 6429 owner.removeUriPermissionLocked(uri, mode); 6430 } 6431 } 6432 } 6433 6434 private void schedulePersistUriGrants() { 6435 if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) { 6436 mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG), 6437 10 * DateUtils.SECOND_IN_MILLIS); 6438 } 6439 } 6440 6441 private void writeGrantedUriPermissions() { 6442 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()"); 6443 6444 // Snapshot permissions so we can persist without lock 6445 ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList(); 6446 synchronized (this) { 6447 final int size = mGrantedUriPermissions.size(); 6448 for (int i = 0 ; i < size; i++) { 6449 for (UriPermission perm : mGrantedUriPermissions.valueAt(i).values()) { 6450 if (perm.persistedModeFlags != 0) { 6451 persist.add(perm.snapshot()); 6452 } 6453 } 6454 } 6455 } 6456 6457 FileOutputStream fos = null; 6458 try { 6459 fos = mGrantFile.startWrite(); 6460 6461 XmlSerializer out = new FastXmlSerializer(); 6462 out.setOutput(fos, "utf-8"); 6463 out.startDocument(null, true); 6464 out.startTag(null, TAG_URI_GRANTS); 6465 for (UriPermission.Snapshot perm : persist) { 6466 out.startTag(null, TAG_URI_GRANT); 6467 writeIntAttribute(out, ATTR_USER_HANDLE, perm.userHandle); 6468 out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg); 6469 out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg); 6470 out.attribute(null, ATTR_URI, String.valueOf(perm.uri)); 6471 writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags); 6472 writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime); 6473 out.endTag(null, TAG_URI_GRANT); 6474 } 6475 out.endTag(null, TAG_URI_GRANTS); 6476 out.endDocument(); 6477 6478 mGrantFile.finishWrite(fos); 6479 } catch (IOException e) { 6480 if (fos != null) { 6481 mGrantFile.failWrite(fos); 6482 } 6483 } 6484 } 6485 6486 private void readGrantedUriPermissionsLocked() { 6487 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()"); 6488 6489 final long now = System.currentTimeMillis(); 6490 6491 FileInputStream fis = null; 6492 try { 6493 fis = mGrantFile.openRead(); 6494 final XmlPullParser in = Xml.newPullParser(); 6495 in.setInput(fis, null); 6496 6497 int type; 6498 while ((type = in.next()) != END_DOCUMENT) { 6499 final String tag = in.getName(); 6500 if (type == START_TAG) { 6501 if (TAG_URI_GRANT.equals(tag)) { 6502 final int userHandle = readIntAttribute(in, ATTR_USER_HANDLE); 6503 final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG); 6504 final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG); 6505 final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI)); 6506 final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS); 6507 final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now); 6508 6509 // Sanity check that provider still belongs to source package 6510 final ProviderInfo pi = getProviderInfoLocked( 6511 uri.getAuthority(), userHandle); 6512 if (pi != null && sourcePkg.equals(pi.packageName)) { 6513 int targetUid = -1; 6514 try { 6515 targetUid = AppGlobals.getPackageManager() 6516 .getPackageUid(targetPkg, userHandle); 6517 } catch (RemoteException e) { 6518 } 6519 if (targetUid != -1) { 6520 final UriPermission perm = findOrCreateUriPermissionLocked( 6521 sourcePkg, targetPkg, targetUid, uri); 6522 perm.initPersistedModes(modeFlags, createdTime); 6523 } 6524 } else { 6525 Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg 6526 + " but instead found " + pi); 6527 } 6528 } 6529 } 6530 } 6531 } catch (FileNotFoundException e) { 6532 // Missing grants is okay 6533 } catch (IOException e) { 6534 Log.wtf(TAG, "Failed reading Uri grants", e); 6535 } catch (XmlPullParserException e) { 6536 Log.wtf(TAG, "Failed reading Uri grants", e); 6537 } finally { 6538 IoUtils.closeQuietly(fis); 6539 } 6540 } 6541 6542 @Override 6543 public void takePersistableUriPermission(Uri uri, int modeFlags) { 6544 enforceNotIsolatedCaller("takePersistableUriPermission"); 6545 6546 Preconditions.checkFlagsArgument(modeFlags, 6547 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 6548 6549 synchronized (this) { 6550 final int callingUid = Binder.getCallingUid(); 6551 final UriPermission perm = findUriPermissionLocked(callingUid, uri); 6552 if (perm == null) { 6553 throw new SecurityException("No permission grant found for UID " + callingUid 6554 + " and Uri " + uri.toSafeString()); 6555 } 6556 6557 boolean persistChanged = perm.takePersistableModes(modeFlags); 6558 persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid); 6559 6560 if (persistChanged) { 6561 schedulePersistUriGrants(); 6562 } 6563 } 6564 } 6565 6566 @Override 6567 public void releasePersistableUriPermission(Uri uri, int modeFlags) { 6568 enforceNotIsolatedCaller("releasePersistableUriPermission"); 6569 6570 Preconditions.checkFlagsArgument(modeFlags, 6571 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 6572 6573 synchronized (this) { 6574 final int callingUid = Binder.getCallingUid(); 6575 6576 final UriPermission perm = findUriPermissionLocked(callingUid, uri); 6577 if (perm == null) { 6578 Slog.w(TAG, "No permission grant found for UID " + callingUid + " and Uri " 6579 + uri.toSafeString()); 6580 return; 6581 } 6582 6583 final boolean persistChanged = perm.releasePersistableModes(modeFlags); 6584 removeUriPermissionIfNeededLocked(perm); 6585 if (persistChanged) { 6586 schedulePersistUriGrants(); 6587 } 6588 } 6589 } 6590 6591 /** 6592 * Prune any older {@link UriPermission} for the given UID until outstanding 6593 * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}. 6594 * 6595 * @return if any mutations occured that require persisting. 6596 */ 6597 private boolean maybePrunePersistedUriGrantsLocked(int uid) { 6598 final ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(uid); 6599 if (perms == null) return false; 6600 if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false; 6601 6602 final ArrayList<UriPermission> persisted = Lists.newArrayList(); 6603 for (UriPermission perm : perms.values()) { 6604 if (perm.persistedModeFlags != 0) { 6605 persisted.add(perm); 6606 } 6607 } 6608 6609 final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS; 6610 if (trimCount <= 0) return false; 6611 6612 Collections.sort(persisted, new UriPermission.PersistedTimeComparator()); 6613 for (int i = 0; i < trimCount; i++) { 6614 final UriPermission perm = persisted.get(i); 6615 6616 if (DEBUG_URI_PERMISSION) { 6617 Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime); 6618 } 6619 6620 perm.releasePersistableModes(~0); 6621 removeUriPermissionIfNeededLocked(perm); 6622 } 6623 6624 return true; 6625 } 6626 6627 @Override 6628 public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions( 6629 String packageName, boolean incoming) { 6630 enforceNotIsolatedCaller("getPersistedUriPermissions"); 6631 Preconditions.checkNotNull(packageName, "packageName"); 6632 6633 final int callingUid = Binder.getCallingUid(); 6634 final IPackageManager pm = AppGlobals.getPackageManager(); 6635 try { 6636 final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid)); 6637 if (packageUid != callingUid) { 6638 throw new SecurityException( 6639 "Package " + packageName + " does not belong to calling UID " + callingUid); 6640 } 6641 } catch (RemoteException e) { 6642 throw new SecurityException("Failed to verify package name ownership"); 6643 } 6644 6645 final ArrayList<android.content.UriPermission> result = Lists.newArrayList(); 6646 synchronized (this) { 6647 if (incoming) { 6648 final ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(callingUid); 6649 if (perms == null) { 6650 Slog.w(TAG, "No permission grants found for " + packageName); 6651 } else { 6652 final int size = perms.size(); 6653 for (int i = 0; i < size; i++) { 6654 final UriPermission perm = perms.valueAt(i); 6655 if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) { 6656 result.add(perm.buildPersistedPublicApiObject()); 6657 } 6658 } 6659 } 6660 } else { 6661 final int size = mGrantedUriPermissions.size(); 6662 for (int i = 0; i < size; i++) { 6663 final ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 6664 final int permsSize = perms.size(); 6665 for (int j = 0; j < permsSize; j++) { 6666 final UriPermission perm = perms.valueAt(j); 6667 if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) { 6668 result.add(perm.buildPersistedPublicApiObject()); 6669 } 6670 } 6671 } 6672 } 6673 } 6674 return new ParceledListSlice<android.content.UriPermission>(result); 6675 } 6676 6677 @Override 6678 public void showWaitingForDebugger(IApplicationThread who, boolean waiting) { 6679 synchronized (this) { 6680 ProcessRecord app = 6681 who != null ? getRecordForAppLocked(who) : null; 6682 if (app == null) return; 6683 6684 Message msg = Message.obtain(); 6685 msg.what = WAIT_FOR_DEBUGGER_MSG; 6686 msg.obj = app; 6687 msg.arg1 = waiting ? 1 : 0; 6688 mHandler.sendMessage(msg); 6689 } 6690 } 6691 6692 @Override 6693 public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) { 6694 final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ); 6695 final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ); 6696 outInfo.availMem = Process.getFreeMemory(); 6697 outInfo.totalMem = Process.getTotalMemory(); 6698 outInfo.threshold = homeAppMem; 6699 outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2)); 6700 outInfo.hiddenAppThreshold = cachedAppMem; 6701 outInfo.secondaryServerThreshold = mProcessList.getMemLevel( 6702 ProcessList.SERVICE_ADJ); 6703 outInfo.visibleAppThreshold = mProcessList.getMemLevel( 6704 ProcessList.VISIBLE_APP_ADJ); 6705 outInfo.foregroundAppThreshold = mProcessList.getMemLevel( 6706 ProcessList.FOREGROUND_APP_ADJ); 6707 } 6708 6709 // ========================================================= 6710 // TASK MANAGEMENT 6711 // ========================================================= 6712 6713 @Override 6714 public List<RunningTaskInfo> getTasks(int maxNum, int flags, 6715 IThumbnailReceiver receiver) { 6716 ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>(); 6717 6718 PendingThumbnailsRecord pending = new PendingThumbnailsRecord(receiver); 6719 ActivityRecord topRecord = null; 6720 6721 synchronized(this) { 6722 if (localLOGV) Slog.v( 6723 TAG, "getTasks: max=" + maxNum + ", flags=" + flags 6724 + ", receiver=" + receiver); 6725 6726 if (checkCallingPermission(android.Manifest.permission.GET_TASKS) 6727 != PackageManager.PERMISSION_GRANTED) { 6728 if (receiver != null) { 6729 // If the caller wants to wait for pending thumbnails, 6730 // it ain't gonna get them. 6731 try { 6732 receiver.finished(); 6733 } catch (RemoteException ex) { 6734 } 6735 } 6736 String msg = "Permission Denial: getTasks() from pid=" 6737 + Binder.getCallingPid() 6738 + ", uid=" + Binder.getCallingUid() 6739 + " requires " + android.Manifest.permission.GET_TASKS; 6740 Slog.w(TAG, msg); 6741 throw new SecurityException(msg); 6742 } 6743 6744 // TODO: Improve with MRU list from all ActivityStacks. 6745 topRecord = mStackSupervisor.getTasksLocked(maxNum, receiver, pending, list); 6746 6747 if (!pending.pendingRecords.isEmpty()) { 6748 mPendingThumbnails.add(pending); 6749 } 6750 } 6751 6752 if (localLOGV) Slog.v(TAG, "We have pending thumbnails: " + pending); 6753 6754 if (topRecord != null) { 6755 if (localLOGV) Slog.v(TAG, "Requesting top thumbnail"); 6756 try { 6757 IApplicationThread topThumbnail = topRecord.app.thread; 6758 topThumbnail.requestThumbnail(topRecord.appToken); 6759 } catch (Exception e) { 6760 Slog.w(TAG, "Exception thrown when requesting thumbnail", e); 6761 sendPendingThumbnail(null, topRecord.appToken, null, null, true); 6762 } 6763 } 6764 6765 if (pending == null && receiver != null) { 6766 // In this case all thumbnails were available and the client 6767 // is being asked to be told when the remaining ones come in... 6768 // which is unusually, since the top-most currently running 6769 // activity should never have a canned thumbnail! Oh well. 6770 try { 6771 receiver.finished(); 6772 } catch (RemoteException ex) { 6773 } 6774 } 6775 6776 return list; 6777 } 6778 6779 TaskRecord getMostRecentTask() { 6780 return mRecentTasks.get(0); 6781 } 6782 6783 @Override 6784 public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, 6785 int flags, int userId) { 6786 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 6787 false, true, "getRecentTasks", null); 6788 6789 synchronized (this) { 6790 enforceCallingPermission(android.Manifest.permission.GET_TASKS, 6791 "getRecentTasks()"); 6792 final boolean detailed = checkCallingPermission( 6793 android.Manifest.permission.GET_DETAILED_TASKS) 6794 == PackageManager.PERMISSION_GRANTED; 6795 6796 IPackageManager pm = AppGlobals.getPackageManager(); 6797 6798 final int N = mRecentTasks.size(); 6799 ArrayList<ActivityManager.RecentTaskInfo> res 6800 = new ArrayList<ActivityManager.RecentTaskInfo>( 6801 maxNum < N ? maxNum : N); 6802 for (int i=0; i<N && maxNum > 0; i++) { 6803 TaskRecord tr = mRecentTasks.get(i); 6804 // Only add calling user's recent tasks 6805 if (tr.userId != userId) continue; 6806 // Return the entry if desired by the caller. We always return 6807 // the first entry, because callers always expect this to be the 6808 // foreground app. We may filter others if the caller has 6809 // not supplied RECENT_WITH_EXCLUDED and there is some reason 6810 // we should exclude the entry. 6811 6812 if (i == 0 6813 || ((flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0) 6814 || (tr.intent == null) 6815 || ((tr.intent.getFlags() 6816 &Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0)) { 6817 ActivityManager.RecentTaskInfo rti 6818 = new ActivityManager.RecentTaskInfo(); 6819 rti.id = tr.numActivities > 0 ? tr.taskId : -1; 6820 rti.persistentId = tr.taskId; 6821 rti.baseIntent = new Intent( 6822 tr.intent != null ? tr.intent : tr.affinityIntent); 6823 if (!detailed) { 6824 rti.baseIntent.replaceExtras((Bundle)null); 6825 } 6826 rti.origActivity = tr.origActivity; 6827 rti.description = tr.lastDescription; 6828 rti.stackId = tr.stack.mStackId; 6829 6830 if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) { 6831 // Check whether this activity is currently available. 6832 try { 6833 if (rti.origActivity != null) { 6834 if (pm.getActivityInfo(rti.origActivity, 0, userId) 6835 == null) { 6836 continue; 6837 } 6838 } else if (rti.baseIntent != null) { 6839 if (pm.queryIntentActivities(rti.baseIntent, 6840 null, 0, userId) == null) { 6841 continue; 6842 } 6843 } 6844 } catch (RemoteException e) { 6845 // Will never happen. 6846 } 6847 } 6848 6849 res.add(rti); 6850 maxNum--; 6851 } 6852 } 6853 return res; 6854 } 6855 } 6856 6857 private TaskRecord recentTaskForIdLocked(int id) { 6858 final int N = mRecentTasks.size(); 6859 for (int i=0; i<N; i++) { 6860 TaskRecord tr = mRecentTasks.get(i); 6861 if (tr.taskId == id) { 6862 return tr; 6863 } 6864 } 6865 return null; 6866 } 6867 6868 @Override 6869 public ActivityManager.TaskThumbnails getTaskThumbnails(int id) { 6870 synchronized (this) { 6871 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER, 6872 "getTaskThumbnails()"); 6873 TaskRecord tr = recentTaskForIdLocked(id); 6874 if (tr != null) { 6875 return tr.getTaskThumbnailsLocked(); 6876 } 6877 } 6878 return null; 6879 } 6880 6881 @Override 6882 public Bitmap getTaskTopThumbnail(int id) { 6883 synchronized (this) { 6884 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER, 6885 "getTaskTopThumbnail()"); 6886 TaskRecord tr = recentTaskForIdLocked(id); 6887 if (tr != null) { 6888 return tr.getTaskTopThumbnailLocked(); 6889 } 6890 } 6891 return null; 6892 } 6893 6894 @Override 6895 public boolean removeSubTask(int taskId, int subTaskIndex) { 6896 synchronized (this) { 6897 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, 6898 "removeSubTask()"); 6899 long ident = Binder.clearCallingIdentity(); 6900 try { 6901 TaskRecord tr = recentTaskForIdLocked(taskId); 6902 if (tr != null) { 6903 return tr.removeTaskActivitiesLocked(subTaskIndex, true) != null; 6904 } 6905 return false; 6906 } finally { 6907 Binder.restoreCallingIdentity(ident); 6908 } 6909 } 6910 } 6911 6912 private void killUnneededProcessLocked(ProcessRecord pr, String reason) { 6913 if (!pr.killedByAm) { 6914 Slog.i(TAG, "Killing " + pr.toShortString() + " (adj " + pr.setAdj + "): " + reason); 6915 EventLog.writeEvent(EventLogTags.AM_KILL, pr.userId, pr.pid, 6916 pr.processName, pr.setAdj, reason); 6917 pr.killedByAm = true; 6918 Process.killProcessQuiet(pr.pid); 6919 } 6920 } 6921 6922 private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) { 6923 tr.disposeThumbnail(); 6924 mRecentTasks.remove(tr); 6925 final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0; 6926 Intent baseIntent = new Intent( 6927 tr.intent != null ? tr.intent : tr.affinityIntent); 6928 ComponentName component = baseIntent.getComponent(); 6929 if (component == null) { 6930 Slog.w(TAG, "Now component for base intent of task: " + tr); 6931 return; 6932 } 6933 6934 // Find any running services associated with this app. 6935 mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent); 6936 6937 if (killProcesses) { 6938 // Find any running processes associated with this app. 6939 final String pkg = component.getPackageName(); 6940 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 6941 ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap(); 6942 for (int i=0; i<pmap.size(); i++) { 6943 SparseArray<ProcessRecord> uids = pmap.valueAt(i); 6944 for (int j=0; j<uids.size(); j++) { 6945 ProcessRecord proc = uids.valueAt(j); 6946 if (proc.userId != tr.userId) { 6947 continue; 6948 } 6949 if (!proc.pkgList.containsKey(pkg)) { 6950 continue; 6951 } 6952 procs.add(proc); 6953 } 6954 } 6955 6956 // Kill the running processes. 6957 for (int i=0; i<procs.size(); i++) { 6958 ProcessRecord pr = procs.get(i); 6959 if (pr == mHomeProcess) { 6960 // Don't kill the home process along with tasks from the same package. 6961 continue; 6962 } 6963 if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 6964 killUnneededProcessLocked(pr, "remove task"); 6965 } else { 6966 pr.waitingToKill = "remove task"; 6967 } 6968 } 6969 } 6970 } 6971 6972 @Override 6973 public boolean removeTask(int taskId, int flags) { 6974 synchronized (this) { 6975 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, 6976 "removeTask()"); 6977 long ident = Binder.clearCallingIdentity(); 6978 try { 6979 TaskRecord tr = recentTaskForIdLocked(taskId); 6980 if (tr != null) { 6981 ActivityRecord r = tr.removeTaskActivitiesLocked(-1, false); 6982 if (r != null) { 6983 cleanUpRemovedTaskLocked(tr, flags); 6984 return true; 6985 } 6986 if (tr.mActivities.size() == 0) { 6987 // Caller is just removing a recent task that is 6988 // not actively running. That is easy! 6989 cleanUpRemovedTaskLocked(tr, flags); 6990 return true; 6991 } 6992 Slog.w(TAG, "removeTask: task " + taskId 6993 + " does not have activities to remove, " 6994 + " but numActivities=" + tr.numActivities 6995 + ": " + tr); 6996 } 6997 } finally { 6998 Binder.restoreCallingIdentity(ident); 6999 } 7000 } 7001 return false; 7002 } 7003 7004 /** 7005 * TODO: Add mController hook 7006 */ 7007 @Override 7008 public void moveTaskToFront(int task, int flags, Bundle options) { 7009 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 7010 "moveTaskToFront()"); 7011 7012 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving task=" + task); 7013 synchronized(this) { 7014 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 7015 Binder.getCallingUid(), "Task to front")) { 7016 ActivityOptions.abort(options); 7017 return; 7018 } 7019 final long origId = Binder.clearCallingIdentity(); 7020 try { 7021 mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options); 7022 } finally { 7023 Binder.restoreCallingIdentity(origId); 7024 } 7025 ActivityOptions.abort(options); 7026 } 7027 } 7028 7029 @Override 7030 public void moveTaskToBack(int taskId) { 7031 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 7032 "moveTaskToBack()"); 7033 7034 synchronized(this) { 7035 TaskRecord tr = recentTaskForIdLocked(taskId); 7036 if (tr != null) { 7037 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr); 7038 ActivityStack stack = tr.stack; 7039 if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) { 7040 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 7041 Binder.getCallingUid(), "Task to back")) { 7042 return; 7043 } 7044 } 7045 final long origId = Binder.clearCallingIdentity(); 7046 try { 7047 stack.moveTaskToBackLocked(taskId, null); 7048 } finally { 7049 Binder.restoreCallingIdentity(origId); 7050 } 7051 } 7052 } 7053 } 7054 7055 /** 7056 * Moves an activity, and all of the other activities within the same task, to the bottom 7057 * of the history stack. The activity's order within the task is unchanged. 7058 * 7059 * @param token A reference to the activity we wish to move 7060 * @param nonRoot If false then this only works if the activity is the root 7061 * of a task; if true it will work for any activity in a task. 7062 * @return Returns true if the move completed, false if not. 7063 */ 7064 @Override 7065 public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) { 7066 enforceNotIsolatedCaller("moveActivityTaskToBack"); 7067 synchronized(this) { 7068 final long origId = Binder.clearCallingIdentity(); 7069 int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot); 7070 if (taskId >= 0) { 7071 return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null); 7072 } 7073 Binder.restoreCallingIdentity(origId); 7074 } 7075 return false; 7076 } 7077 7078 @Override 7079 public void moveTaskBackwards(int task) { 7080 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 7081 "moveTaskBackwards()"); 7082 7083 synchronized(this) { 7084 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 7085 Binder.getCallingUid(), "Task backwards")) { 7086 return; 7087 } 7088 final long origId = Binder.clearCallingIdentity(); 7089 moveTaskBackwardsLocked(task); 7090 Binder.restoreCallingIdentity(origId); 7091 } 7092 } 7093 7094 private final void moveTaskBackwardsLocked(int task) { 7095 Slog.e(TAG, "moveTaskBackwards not yet implemented!"); 7096 } 7097 7098 @Override 7099 public IBinder getHomeActivityToken() throws RemoteException { 7100 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7101 "getHomeActivityToken()"); 7102 synchronized (this) { 7103 return mStackSupervisor.getHomeActivityToken(); 7104 } 7105 } 7106 7107 @Override 7108 public IActivityContainer createActivityContainer(IBinder parentActivityToken, 7109 IActivityContainerCallback callback) throws RemoteException { 7110 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7111 "createActivityContainer()"); 7112 synchronized (this) { 7113 if (parentActivityToken == null) { 7114 throw new IllegalArgumentException("parent token must not be null"); 7115 } 7116 ActivityRecord r = ActivityRecord.forToken(parentActivityToken); 7117 if (r == null) { 7118 return null; 7119 } 7120 if (callback == null) { 7121 throw new IllegalArgumentException("callback must not be null"); 7122 } 7123 return mStackSupervisor.createActivityContainer(r, callback); 7124 } 7125 } 7126 7127 @Override 7128 public void deleteActivityContainer(IActivityContainer container) throws RemoteException { 7129 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7130 "deleteActivityContainer()"); 7131 synchronized (this) { 7132 mStackSupervisor.deleteActivityContainer(container); 7133 } 7134 } 7135 7136 @Override 7137 public IActivityContainer getEnclosingActivityContainer(IBinder activityToken) 7138 throws RemoteException { 7139 synchronized (this) { 7140 ActivityStack stack = ActivityRecord.getStackLocked(activityToken); 7141 if (stack != null) { 7142 return stack.mActivityContainer; 7143 } 7144 return null; 7145 } 7146 } 7147 7148 @Override 7149 public void moveTaskToStack(int taskId, int stackId, boolean toTop) { 7150 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7151 "moveTaskToStack()"); 7152 if (stackId == HOME_STACK_ID) { 7153 Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack", 7154 new RuntimeException("here").fillInStackTrace()); 7155 } 7156 synchronized (this) { 7157 long ident = Binder.clearCallingIdentity(); 7158 try { 7159 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId=" 7160 + stackId + " toTop=" + toTop); 7161 mStackSupervisor.moveTaskToStack(taskId, stackId, toTop); 7162 } finally { 7163 Binder.restoreCallingIdentity(ident); 7164 } 7165 } 7166 } 7167 7168 @Override 7169 public void resizeStack(int stackBoxId, Rect bounds) { 7170 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7171 "resizeStackBox()"); 7172 long ident = Binder.clearCallingIdentity(); 7173 try { 7174 mWindowManager.resizeStack(stackBoxId, bounds); 7175 } finally { 7176 Binder.restoreCallingIdentity(ident); 7177 } 7178 } 7179 7180 @Override 7181 public List<StackInfo> getAllStackInfos() { 7182 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7183 "getAllStackInfos()"); 7184 long ident = Binder.clearCallingIdentity(); 7185 try { 7186 synchronized (this) { 7187 return mStackSupervisor.getAllStackInfosLocked(); 7188 } 7189 } finally { 7190 Binder.restoreCallingIdentity(ident); 7191 } 7192 } 7193 7194 @Override 7195 public StackInfo getStackInfo(int stackId) { 7196 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7197 "getStackInfo()"); 7198 long ident = Binder.clearCallingIdentity(); 7199 try { 7200 synchronized (this) { 7201 return mStackSupervisor.getStackInfoLocked(stackId); 7202 } 7203 } finally { 7204 Binder.restoreCallingIdentity(ident); 7205 } 7206 } 7207 7208 @Override 7209 public int getTaskForActivity(IBinder token, boolean onlyRoot) { 7210 synchronized(this) { 7211 return ActivityRecord.getTaskForActivityLocked(token, onlyRoot); 7212 } 7213 } 7214 7215 // ========================================================= 7216 // THUMBNAILS 7217 // ========================================================= 7218 7219 public void reportThumbnail(IBinder token, 7220 Bitmap thumbnail, CharSequence description) { 7221 //System.out.println("Report thumbnail for " + token + ": " + thumbnail); 7222 final long origId = Binder.clearCallingIdentity(); 7223 sendPendingThumbnail(null, token, thumbnail, description, true); 7224 Binder.restoreCallingIdentity(origId); 7225 } 7226 7227 final void sendPendingThumbnail(ActivityRecord r, IBinder token, 7228 Bitmap thumbnail, CharSequence description, boolean always) { 7229 TaskRecord task; 7230 ArrayList<PendingThumbnailsRecord> receivers = null; 7231 7232 //System.out.println("Send pending thumbnail: " + r); 7233 7234 synchronized(this) { 7235 if (r == null) { 7236 r = ActivityRecord.isInStackLocked(token); 7237 if (r == null) { 7238 return; 7239 } 7240 } 7241 if (thumbnail == null && r.thumbHolder != null) { 7242 thumbnail = r.thumbHolder.lastThumbnail; 7243 description = r.thumbHolder.lastDescription; 7244 } 7245 if (thumbnail == null && !always) { 7246 // If there is no thumbnail, and this entry is not actually 7247 // going away, then abort for now and pick up the next 7248 // thumbnail we get. 7249 return; 7250 } 7251 task = r.task; 7252 7253 int N = mPendingThumbnails.size(); 7254 int i=0; 7255 while (i<N) { 7256 PendingThumbnailsRecord pr = mPendingThumbnails.get(i); 7257 //System.out.println("Looking in " + pr.pendingRecords); 7258 if (pr.pendingRecords.remove(r)) { 7259 if (receivers == null) { 7260 receivers = new ArrayList<PendingThumbnailsRecord>(); 7261 } 7262 receivers.add(pr); 7263 if (pr.pendingRecords.size() == 0) { 7264 pr.finished = true; 7265 mPendingThumbnails.remove(i); 7266 N--; 7267 continue; 7268 } 7269 } 7270 i++; 7271 } 7272 } 7273 7274 if (receivers != null) { 7275 final int N = receivers.size(); 7276 for (int i=0; i<N; i++) { 7277 try { 7278 PendingThumbnailsRecord pr = receivers.get(i); 7279 pr.receiver.newThumbnail( 7280 task != null ? task.taskId : -1, thumbnail, description); 7281 if (pr.finished) { 7282 pr.receiver.finished(); 7283 } 7284 } catch (Exception e) { 7285 Slog.w(TAG, "Exception thrown when sending thumbnail", e); 7286 } 7287 } 7288 } 7289 } 7290 7291 // ========================================================= 7292 // CONTENT PROVIDERS 7293 // ========================================================= 7294 7295 private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) { 7296 List<ProviderInfo> providers = null; 7297 try { 7298 providers = AppGlobals.getPackageManager(). 7299 queryContentProviders(app.processName, app.uid, 7300 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS); 7301 } catch (RemoteException ex) { 7302 } 7303 if (DEBUG_MU) 7304 Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid); 7305 int userId = app.userId; 7306 if (providers != null) { 7307 int N = providers.size(); 7308 app.pubProviders.ensureCapacity(N + app.pubProviders.size()); 7309 for (int i=0; i<N; i++) { 7310 ProviderInfo cpi = 7311 (ProviderInfo)providers.get(i); 7312 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo, 7313 cpi.name, cpi.flags); 7314 if (singleton && UserHandle.getUserId(app.uid) != 0) { 7315 // This is a singleton provider, but a user besides the 7316 // default user is asking to initialize a process it runs 7317 // in... well, no, it doesn't actually run in this process, 7318 // it runs in the process of the default user. Get rid of it. 7319 providers.remove(i); 7320 N--; 7321 i--; 7322 continue; 7323 } 7324 7325 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 7326 ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId); 7327 if (cpr == null) { 7328 cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton); 7329 mProviderMap.putProviderByClass(comp, cpr); 7330 } 7331 if (DEBUG_MU) 7332 Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid); 7333 app.pubProviders.put(cpi.name, cpr); 7334 if (!cpi.multiprocess || !"android".equals(cpi.packageName)) { 7335 // Don't add this if it is a platform component that is marked 7336 // to run in multiple processes, because this is actually 7337 // part of the framework so doesn't make sense to track as a 7338 // separate apk in the process. 7339 app.addPackage(cpi.applicationInfo.packageName, mProcessStats); 7340 } 7341 ensurePackageDexOpt(cpi.applicationInfo.packageName); 7342 } 7343 } 7344 return providers; 7345 } 7346 7347 /** 7348 * Check if {@link ProcessRecord} has a possible chance at accessing the 7349 * given {@link ProviderInfo}. Final permission checking is always done 7350 * in {@link ContentProvider}. 7351 */ 7352 private final String checkContentProviderPermissionLocked( 7353 ProviderInfo cpi, ProcessRecord r) { 7354 final int callingPid = (r != null) ? r.pid : Binder.getCallingPid(); 7355 final int callingUid = (r != null) ? r.uid : Binder.getCallingUid(); 7356 if (checkComponentPermission(cpi.readPermission, callingPid, callingUid, 7357 cpi.applicationInfo.uid, cpi.exported) 7358 == PackageManager.PERMISSION_GRANTED) { 7359 return null; 7360 } 7361 if (checkComponentPermission(cpi.writePermission, callingPid, callingUid, 7362 cpi.applicationInfo.uid, cpi.exported) 7363 == PackageManager.PERMISSION_GRANTED) { 7364 return null; 7365 } 7366 7367 PathPermission[] pps = cpi.pathPermissions; 7368 if (pps != null) { 7369 int i = pps.length; 7370 while (i > 0) { 7371 i--; 7372 PathPermission pp = pps[i]; 7373 if (checkComponentPermission(pp.getReadPermission(), callingPid, callingUid, 7374 cpi.applicationInfo.uid, cpi.exported) 7375 == PackageManager.PERMISSION_GRANTED) { 7376 return null; 7377 } 7378 if (checkComponentPermission(pp.getWritePermission(), callingPid, callingUid, 7379 cpi.applicationInfo.uid, cpi.exported) 7380 == PackageManager.PERMISSION_GRANTED) { 7381 return null; 7382 } 7383 } 7384 } 7385 7386 ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(callingUid); 7387 if (perms != null) { 7388 for (Map.Entry<Uri, UriPermission> uri : perms.entrySet()) { 7389 if (uri.getKey().getAuthority().equals(cpi.authority)) { 7390 return null; 7391 } 7392 } 7393 } 7394 7395 String msg; 7396 if (!cpi.exported) { 7397 msg = "Permission Denial: opening provider " + cpi.name 7398 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 7399 + ", uid=" + callingUid + ") that is not exported from uid " 7400 + cpi.applicationInfo.uid; 7401 } else { 7402 msg = "Permission Denial: opening provider " + cpi.name 7403 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 7404 + ", uid=" + callingUid + ") requires " 7405 + cpi.readPermission + " or " + cpi.writePermission; 7406 } 7407 Slog.w(TAG, msg); 7408 return msg; 7409 } 7410 7411 ContentProviderConnection incProviderCountLocked(ProcessRecord r, 7412 final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 7413 if (r != null) { 7414 for (int i=0; i<r.conProviders.size(); i++) { 7415 ContentProviderConnection conn = r.conProviders.get(i); 7416 if (conn.provider == cpr) { 7417 if (DEBUG_PROVIDER) Slog.v(TAG, 7418 "Adding provider requested by " 7419 + r.processName + " from process " 7420 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 7421 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 7422 if (stable) { 7423 conn.stableCount++; 7424 conn.numStableIncs++; 7425 } else { 7426 conn.unstableCount++; 7427 conn.numUnstableIncs++; 7428 } 7429 return conn; 7430 } 7431 } 7432 ContentProviderConnection conn = new ContentProviderConnection(cpr, r); 7433 if (stable) { 7434 conn.stableCount = 1; 7435 conn.numStableIncs = 1; 7436 } else { 7437 conn.unstableCount = 1; 7438 conn.numUnstableIncs = 1; 7439 } 7440 cpr.connections.add(conn); 7441 r.conProviders.add(conn); 7442 return conn; 7443 } 7444 cpr.addExternalProcessHandleLocked(externalProcessToken); 7445 return null; 7446 } 7447 7448 boolean decProviderCountLocked(ContentProviderConnection conn, 7449 ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 7450 if (conn != null) { 7451 cpr = conn.provider; 7452 if (DEBUG_PROVIDER) Slog.v(TAG, 7453 "Removing provider requested by " 7454 + conn.client.processName + " from process " 7455 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 7456 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 7457 if (stable) { 7458 conn.stableCount--; 7459 } else { 7460 conn.unstableCount--; 7461 } 7462 if (conn.stableCount == 0 && conn.unstableCount == 0) { 7463 cpr.connections.remove(conn); 7464 conn.client.conProviders.remove(conn); 7465 return true; 7466 } 7467 return false; 7468 } 7469 cpr.removeExternalProcessHandleLocked(externalProcessToken); 7470 return false; 7471 } 7472 7473 private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller, 7474 String name, IBinder token, boolean stable, int userId) { 7475 ContentProviderRecord cpr; 7476 ContentProviderConnection conn = null; 7477 ProviderInfo cpi = null; 7478 7479 synchronized(this) { 7480 ProcessRecord r = null; 7481 if (caller != null) { 7482 r = getRecordForAppLocked(caller); 7483 if (r == null) { 7484 throw new SecurityException( 7485 "Unable to find app for caller " + caller 7486 + " (pid=" + Binder.getCallingPid() 7487 + ") when getting content provider " + name); 7488 } 7489 } 7490 7491 // First check if this content provider has been published... 7492 cpr = mProviderMap.getProviderByName(name, userId); 7493 boolean providerRunning = cpr != null; 7494 if (providerRunning) { 7495 cpi = cpr.info; 7496 String msg; 7497 if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) { 7498 throw new SecurityException(msg); 7499 } 7500 7501 if (r != null && cpr.canRunHere(r)) { 7502 // This provider has been published or is in the process 7503 // of being published... but it is also allowed to run 7504 // in the caller's process, so don't make a connection 7505 // and just let the caller instantiate its own instance. 7506 ContentProviderHolder holder = cpr.newHolder(null); 7507 // don't give caller the provider object, it needs 7508 // to make its own. 7509 holder.provider = null; 7510 return holder; 7511 } 7512 7513 final long origId = Binder.clearCallingIdentity(); 7514 7515 // In this case the provider instance already exists, so we can 7516 // return it right away. 7517 conn = incProviderCountLocked(r, cpr, token, stable); 7518 if (conn != null && (conn.stableCount+conn.unstableCount) == 1) { 7519 if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 7520 // If this is a perceptible app accessing the provider, 7521 // make sure to count it as being accessed and thus 7522 // back up on the LRU list. This is good because 7523 // content providers are often expensive to start. 7524 updateLruProcessLocked(cpr.proc, false, null); 7525 } 7526 } 7527 7528 if (cpr.proc != null) { 7529 if (false) { 7530 if (cpr.name.flattenToShortString().equals( 7531 "com.android.providers.calendar/.CalendarProvider2")) { 7532 Slog.v(TAG, "****************** KILLING " 7533 + cpr.name.flattenToShortString()); 7534 Process.killProcess(cpr.proc.pid); 7535 } 7536 } 7537 boolean success = updateOomAdjLocked(cpr.proc); 7538 if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success); 7539 // NOTE: there is still a race here where a signal could be 7540 // pending on the process even though we managed to update its 7541 // adj level. Not sure what to do about this, but at least 7542 // the race is now smaller. 7543 if (!success) { 7544 // Uh oh... it looks like the provider's process 7545 // has been killed on us. We need to wait for a new 7546 // process to be started, and make sure its death 7547 // doesn't kill our process. 7548 Slog.i(TAG, 7549 "Existing provider " + cpr.name.flattenToShortString() 7550 + " is crashing; detaching " + r); 7551 boolean lastRef = decProviderCountLocked(conn, cpr, token, stable); 7552 appDiedLocked(cpr.proc, cpr.proc.pid, cpr.proc.thread); 7553 if (!lastRef) { 7554 // This wasn't the last ref our process had on 7555 // the provider... we have now been killed, bail. 7556 return null; 7557 } 7558 providerRunning = false; 7559 conn = null; 7560 } 7561 } 7562 7563 Binder.restoreCallingIdentity(origId); 7564 } 7565 7566 boolean singleton; 7567 if (!providerRunning) { 7568 try { 7569 cpi = AppGlobals.getPackageManager(). 7570 resolveContentProvider(name, 7571 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId); 7572 } catch (RemoteException ex) { 7573 } 7574 if (cpi == null) { 7575 return null; 7576 } 7577 singleton = isSingleton(cpi.processName, cpi.applicationInfo, 7578 cpi.name, cpi.flags); 7579 if (singleton) { 7580 userId = 0; 7581 } 7582 cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId); 7583 7584 String msg; 7585 if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) { 7586 throw new SecurityException(msg); 7587 } 7588 7589 if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate 7590 && !cpi.processName.equals("system")) { 7591 // If this content provider does not run in the system 7592 // process, and the system is not yet ready to run other 7593 // processes, then fail fast instead of hanging. 7594 throw new IllegalArgumentException( 7595 "Attempt to launch content provider before system ready"); 7596 } 7597 7598 // Make sure that the user who owns this provider is started. If not, 7599 // we don't want to allow it to run. 7600 if (mStartedUsers.get(userId) == null) { 7601 Slog.w(TAG, "Unable to launch app " 7602 + cpi.applicationInfo.packageName + "/" 7603 + cpi.applicationInfo.uid + " for provider " 7604 + name + ": user " + userId + " is stopped"); 7605 return null; 7606 } 7607 7608 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 7609 cpr = mProviderMap.getProviderByClass(comp, userId); 7610 final boolean firstClass = cpr == null; 7611 if (firstClass) { 7612 try { 7613 ApplicationInfo ai = 7614 AppGlobals.getPackageManager(). 7615 getApplicationInfo( 7616 cpi.applicationInfo.packageName, 7617 STOCK_PM_FLAGS, userId); 7618 if (ai == null) { 7619 Slog.w(TAG, "No package info for content provider " 7620 + cpi.name); 7621 return null; 7622 } 7623 ai = getAppInfoForUser(ai, userId); 7624 cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton); 7625 } catch (RemoteException ex) { 7626 // pm is in same process, this will never happen. 7627 } 7628 } 7629 7630 if (r != null && cpr.canRunHere(r)) { 7631 // If this is a multiprocess provider, then just return its 7632 // info and allow the caller to instantiate it. Only do 7633 // this if the provider is the same user as the caller's 7634 // process, or can run as root (so can be in any process). 7635 return cpr.newHolder(null); 7636 } 7637 7638 if (DEBUG_PROVIDER) { 7639 RuntimeException e = new RuntimeException("here"); 7640 Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null) 7641 + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e); 7642 } 7643 7644 // This is single process, and our app is now connecting to it. 7645 // See if we are already in the process of launching this 7646 // provider. 7647 final int N = mLaunchingProviders.size(); 7648 int i; 7649 for (i=0; i<N; i++) { 7650 if (mLaunchingProviders.get(i) == cpr) { 7651 break; 7652 } 7653 } 7654 7655 // If the provider is not already being launched, then get it 7656 // started. 7657 if (i >= N) { 7658 final long origId = Binder.clearCallingIdentity(); 7659 7660 try { 7661 // Content provider is now in use, its package can't be stopped. 7662 try { 7663 AppGlobals.getPackageManager().setPackageStoppedState( 7664 cpr.appInfo.packageName, false, userId); 7665 } catch (RemoteException e) { 7666 } catch (IllegalArgumentException e) { 7667 Slog.w(TAG, "Failed trying to unstop package " 7668 + cpr.appInfo.packageName + ": " + e); 7669 } 7670 7671 // Use existing process if already started 7672 ProcessRecord proc = getProcessRecordLocked( 7673 cpi.processName, cpr.appInfo.uid, false); 7674 if (proc != null && proc.thread != null) { 7675 if (DEBUG_PROVIDER) { 7676 Slog.d(TAG, "Installing in existing process " + proc); 7677 } 7678 proc.pubProviders.put(cpi.name, cpr); 7679 try { 7680 proc.thread.scheduleInstallProvider(cpi); 7681 } catch (RemoteException e) { 7682 } 7683 } else { 7684 proc = startProcessLocked(cpi.processName, 7685 cpr.appInfo, false, 0, "content provider", 7686 new ComponentName(cpi.applicationInfo.packageName, 7687 cpi.name), false, false, false); 7688 if (proc == null) { 7689 Slog.w(TAG, "Unable to launch app " 7690 + cpi.applicationInfo.packageName + "/" 7691 + cpi.applicationInfo.uid + " for provider " 7692 + name + ": process is bad"); 7693 return null; 7694 } 7695 } 7696 cpr.launchingApp = proc; 7697 mLaunchingProviders.add(cpr); 7698 } finally { 7699 Binder.restoreCallingIdentity(origId); 7700 } 7701 } 7702 7703 // Make sure the provider is published (the same provider class 7704 // may be published under multiple names). 7705 if (firstClass) { 7706 mProviderMap.putProviderByClass(comp, cpr); 7707 } 7708 7709 mProviderMap.putProviderByName(name, cpr); 7710 conn = incProviderCountLocked(r, cpr, token, stable); 7711 if (conn != null) { 7712 conn.waiting = true; 7713 } 7714 } 7715 } 7716 7717 // Wait for the provider to be published... 7718 synchronized (cpr) { 7719 while (cpr.provider == null) { 7720 if (cpr.launchingApp == null) { 7721 Slog.w(TAG, "Unable to launch app " 7722 + cpi.applicationInfo.packageName + "/" 7723 + cpi.applicationInfo.uid + " for provider " 7724 + name + ": launching app became null"); 7725 EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS, 7726 UserHandle.getUserId(cpi.applicationInfo.uid), 7727 cpi.applicationInfo.packageName, 7728 cpi.applicationInfo.uid, name); 7729 return null; 7730 } 7731 try { 7732 if (DEBUG_MU) { 7733 Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp=" 7734 + cpr.launchingApp); 7735 } 7736 if (conn != null) { 7737 conn.waiting = true; 7738 } 7739 cpr.wait(); 7740 } catch (InterruptedException ex) { 7741 } finally { 7742 if (conn != null) { 7743 conn.waiting = false; 7744 } 7745 } 7746 } 7747 } 7748 return cpr != null ? cpr.newHolder(conn) : null; 7749 } 7750 7751 public final ContentProviderHolder getContentProvider( 7752 IApplicationThread caller, String name, int userId, boolean stable) { 7753 enforceNotIsolatedCaller("getContentProvider"); 7754 if (caller == null) { 7755 String msg = "null IApplicationThread when getting content provider " 7756 + name; 7757 Slog.w(TAG, msg); 7758 throw new SecurityException(msg); 7759 } 7760 7761 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 7762 false, true, "getContentProvider", null); 7763 return getContentProviderImpl(caller, name, null, stable, userId); 7764 } 7765 7766 public ContentProviderHolder getContentProviderExternal( 7767 String name, int userId, IBinder token) { 7768 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 7769 "Do not have permission in call getContentProviderExternal()"); 7770 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 7771 false, true, "getContentProvider", null); 7772 return getContentProviderExternalUnchecked(name, token, userId); 7773 } 7774 7775 private ContentProviderHolder getContentProviderExternalUnchecked(String name, 7776 IBinder token, int userId) { 7777 return getContentProviderImpl(null, name, token, true, userId); 7778 } 7779 7780 /** 7781 * Drop a content provider from a ProcessRecord's bookkeeping 7782 */ 7783 public void removeContentProvider(IBinder connection, boolean stable) { 7784 enforceNotIsolatedCaller("removeContentProvider"); 7785 synchronized (this) { 7786 ContentProviderConnection conn; 7787 try { 7788 conn = (ContentProviderConnection)connection; 7789 } catch (ClassCastException e) { 7790 String msg ="removeContentProvider: " + connection 7791 + " not a ContentProviderConnection"; 7792 Slog.w(TAG, msg); 7793 throw new IllegalArgumentException(msg); 7794 } 7795 if (conn == null) { 7796 throw new NullPointerException("connection is null"); 7797 } 7798 if (decProviderCountLocked(conn, null, null, stable)) { 7799 updateOomAdjLocked(); 7800 } 7801 } 7802 } 7803 7804 public void removeContentProviderExternal(String name, IBinder token) { 7805 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 7806 "Do not have permission in call removeContentProviderExternal()"); 7807 removeContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId()); 7808 } 7809 7810 private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) { 7811 synchronized (this) { 7812 ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId); 7813 if(cpr == null) { 7814 //remove from mProvidersByClass 7815 if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list"); 7816 return; 7817 } 7818 7819 //update content provider record entry info 7820 ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name); 7821 ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId); 7822 if (localCpr.hasExternalProcessHandles()) { 7823 if (localCpr.removeExternalProcessHandleLocked(token)) { 7824 updateOomAdjLocked(); 7825 } else { 7826 Slog.e(TAG, "Attmpt to remove content provider " + localCpr 7827 + " with no external reference for token: " 7828 + token + "."); 7829 } 7830 } else { 7831 Slog.e(TAG, "Attmpt to remove content provider: " + localCpr 7832 + " with no external references."); 7833 } 7834 } 7835 } 7836 7837 public final void publishContentProviders(IApplicationThread caller, 7838 List<ContentProviderHolder> providers) { 7839 if (providers == null) { 7840 return; 7841 } 7842 7843 enforceNotIsolatedCaller("publishContentProviders"); 7844 synchronized (this) { 7845 final ProcessRecord r = getRecordForAppLocked(caller); 7846 if (DEBUG_MU) 7847 Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid); 7848 if (r == null) { 7849 throw new SecurityException( 7850 "Unable to find app for caller " + caller 7851 + " (pid=" + Binder.getCallingPid() 7852 + ") when publishing content providers"); 7853 } 7854 7855 final long origId = Binder.clearCallingIdentity(); 7856 7857 final int N = providers.size(); 7858 for (int i=0; i<N; i++) { 7859 ContentProviderHolder src = providers.get(i); 7860 if (src == null || src.info == null || src.provider == null) { 7861 continue; 7862 } 7863 ContentProviderRecord dst = r.pubProviders.get(src.info.name); 7864 if (DEBUG_MU) 7865 Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid); 7866 if (dst != null) { 7867 ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name); 7868 mProviderMap.putProviderByClass(comp, dst); 7869 String names[] = dst.info.authority.split(";"); 7870 for (int j = 0; j < names.length; j++) { 7871 mProviderMap.putProviderByName(names[j], dst); 7872 } 7873 7874 int NL = mLaunchingProviders.size(); 7875 int j; 7876 for (j=0; j<NL; j++) { 7877 if (mLaunchingProviders.get(j) == dst) { 7878 mLaunchingProviders.remove(j); 7879 j--; 7880 NL--; 7881 } 7882 } 7883 synchronized (dst) { 7884 dst.provider = src.provider; 7885 dst.proc = r; 7886 dst.notifyAll(); 7887 } 7888 updateOomAdjLocked(r); 7889 } 7890 } 7891 7892 Binder.restoreCallingIdentity(origId); 7893 } 7894 } 7895 7896 public boolean refContentProvider(IBinder connection, int stable, int unstable) { 7897 ContentProviderConnection conn; 7898 try { 7899 conn = (ContentProviderConnection)connection; 7900 } catch (ClassCastException e) { 7901 String msg ="refContentProvider: " + connection 7902 + " not a ContentProviderConnection"; 7903 Slog.w(TAG, msg); 7904 throw new IllegalArgumentException(msg); 7905 } 7906 if (conn == null) { 7907 throw new NullPointerException("connection is null"); 7908 } 7909 7910 synchronized (this) { 7911 if (stable > 0) { 7912 conn.numStableIncs += stable; 7913 } 7914 stable = conn.stableCount + stable; 7915 if (stable < 0) { 7916 throw new IllegalStateException("stableCount < 0: " + stable); 7917 } 7918 7919 if (unstable > 0) { 7920 conn.numUnstableIncs += unstable; 7921 } 7922 unstable = conn.unstableCount + unstable; 7923 if (unstable < 0) { 7924 throw new IllegalStateException("unstableCount < 0: " + unstable); 7925 } 7926 7927 if ((stable+unstable) <= 0) { 7928 throw new IllegalStateException("ref counts can't go to zero here: stable=" 7929 + stable + " unstable=" + unstable); 7930 } 7931 conn.stableCount = stable; 7932 conn.unstableCount = unstable; 7933 return !conn.dead; 7934 } 7935 } 7936 7937 public void unstableProviderDied(IBinder connection) { 7938 ContentProviderConnection conn; 7939 try { 7940 conn = (ContentProviderConnection)connection; 7941 } catch (ClassCastException e) { 7942 String msg ="refContentProvider: " + connection 7943 + " not a ContentProviderConnection"; 7944 Slog.w(TAG, msg); 7945 throw new IllegalArgumentException(msg); 7946 } 7947 if (conn == null) { 7948 throw new NullPointerException("connection is null"); 7949 } 7950 7951 // Safely retrieve the content provider associated with the connection. 7952 IContentProvider provider; 7953 synchronized (this) { 7954 provider = conn.provider.provider; 7955 } 7956 7957 if (provider == null) { 7958 // Um, yeah, we're way ahead of you. 7959 return; 7960 } 7961 7962 // Make sure the caller is being honest with us. 7963 if (provider.asBinder().pingBinder()) { 7964 // Er, no, still looks good to us. 7965 synchronized (this) { 7966 Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid() 7967 + " says " + conn + " died, but we don't agree"); 7968 return; 7969 } 7970 } 7971 7972 // Well look at that! It's dead! 7973 synchronized (this) { 7974 if (conn.provider.provider != provider) { 7975 // But something changed... good enough. 7976 return; 7977 } 7978 7979 ProcessRecord proc = conn.provider.proc; 7980 if (proc == null || proc.thread == null) { 7981 // Seems like the process is already cleaned up. 7982 return; 7983 } 7984 7985 // As far as we're concerned, this is just like receiving a 7986 // death notification... just a bit prematurely. 7987 Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid 7988 + ") early provider death"); 7989 final long ident = Binder.clearCallingIdentity(); 7990 try { 7991 appDiedLocked(proc, proc.pid, proc.thread); 7992 } finally { 7993 Binder.restoreCallingIdentity(ident); 7994 } 7995 } 7996 } 7997 7998 @Override 7999 public void appNotRespondingViaProvider(IBinder connection) { 8000 enforceCallingPermission( 8001 android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()"); 8002 8003 final ContentProviderConnection conn = (ContentProviderConnection) connection; 8004 if (conn == null) { 8005 Slog.w(TAG, "ContentProviderConnection is null"); 8006 return; 8007 } 8008 8009 final ProcessRecord host = conn.provider.proc; 8010 if (host == null) { 8011 Slog.w(TAG, "Failed to find hosting ProcessRecord"); 8012 return; 8013 } 8014 8015 final long token = Binder.clearCallingIdentity(); 8016 try { 8017 appNotResponding(host, null, null, false, "ContentProvider not responding"); 8018 } finally { 8019 Binder.restoreCallingIdentity(token); 8020 } 8021 } 8022 8023 public final void installSystemProviders() { 8024 List<ProviderInfo> providers; 8025 synchronized (this) { 8026 ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID); 8027 providers = generateApplicationProvidersLocked(app); 8028 if (providers != null) { 8029 for (int i=providers.size()-1; i>=0; i--) { 8030 ProviderInfo pi = (ProviderInfo)providers.get(i); 8031 if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) { 8032 Slog.w(TAG, "Not installing system proc provider " + pi.name 8033 + ": not system .apk"); 8034 providers.remove(i); 8035 } 8036 } 8037 } 8038 } 8039 if (providers != null) { 8040 mSystemThread.installSystemProviders(providers); 8041 } 8042 8043 mCoreSettingsObserver = new CoreSettingsObserver(this); 8044 8045 mUsageStatsService.monitorPackages(); 8046 } 8047 8048 /** 8049 * Allows app to retrieve the MIME type of a URI without having permission 8050 * to access its content provider. 8051 * 8052 * CTS tests for this functionality can be run with "runtest cts-appsecurity". 8053 * 8054 * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/ 8055 * src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java 8056 */ 8057 public String getProviderMimeType(Uri uri, int userId) { 8058 enforceNotIsolatedCaller("getProviderMimeType"); 8059 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 8060 userId, false, true, "getProviderMimeType", null); 8061 final String name = uri.getAuthority(); 8062 final long ident = Binder.clearCallingIdentity(); 8063 ContentProviderHolder holder = null; 8064 8065 try { 8066 holder = getContentProviderExternalUnchecked(name, null, userId); 8067 if (holder != null) { 8068 return holder.provider.getType(uri); 8069 } 8070 } catch (RemoteException e) { 8071 Log.w(TAG, "Content provider dead retrieving " + uri, e); 8072 return null; 8073 } finally { 8074 if (holder != null) { 8075 removeContentProviderExternalUnchecked(name, null, userId); 8076 } 8077 Binder.restoreCallingIdentity(ident); 8078 } 8079 8080 return null; 8081 } 8082 8083 // ========================================================= 8084 // GLOBAL MANAGEMENT 8085 // ========================================================= 8086 8087 final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess, 8088 boolean isolated) { 8089 String proc = customProcess != null ? customProcess : info.processName; 8090 BatteryStatsImpl.Uid.Proc ps = null; 8091 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 8092 int uid = info.uid; 8093 if (isolated) { 8094 int userId = UserHandle.getUserId(uid); 8095 int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1; 8096 while (true) { 8097 if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID 8098 || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) { 8099 mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID; 8100 } 8101 uid = UserHandle.getUid(userId, mNextIsolatedProcessUid); 8102 mNextIsolatedProcessUid++; 8103 if (mIsolatedProcesses.indexOfKey(uid) < 0) { 8104 // No process for this uid, use it. 8105 break; 8106 } 8107 stepsLeft--; 8108 if (stepsLeft <= 0) { 8109 return null; 8110 } 8111 } 8112 } 8113 return new ProcessRecord(stats, info, proc, uid); 8114 } 8115 8116 final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated, 8117 String abiOverride) { 8118 ProcessRecord app; 8119 if (!isolated) { 8120 app = getProcessRecordLocked(info.processName, info.uid, true); 8121 } else { 8122 app = null; 8123 } 8124 8125 if (app == null) { 8126 app = newProcessRecordLocked(info, null, isolated); 8127 mProcessNames.put(info.processName, app.uid, app); 8128 if (isolated) { 8129 mIsolatedProcesses.put(app.uid, app); 8130 } 8131 updateLruProcessLocked(app, false, null); 8132 updateOomAdjLocked(); 8133 } 8134 8135 // This package really, really can not be stopped. 8136 try { 8137 AppGlobals.getPackageManager().setPackageStoppedState( 8138 info.packageName, false, UserHandle.getUserId(app.uid)); 8139 } catch (RemoteException e) { 8140 } catch (IllegalArgumentException e) { 8141 Slog.w(TAG, "Failed trying to unstop package " 8142 + info.packageName + ": " + e); 8143 } 8144 8145 if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) 8146 == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) { 8147 app.persistent = true; 8148 app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ; 8149 } 8150 if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) { 8151 mPersistentStartingProcesses.add(app); 8152 startProcessLocked(app, "added application", app.processName, 8153 abiOverride); 8154 } 8155 8156 return app; 8157 } 8158 8159 public void unhandledBack() { 8160 enforceCallingPermission(android.Manifest.permission.FORCE_BACK, 8161 "unhandledBack()"); 8162 8163 synchronized(this) { 8164 final long origId = Binder.clearCallingIdentity(); 8165 try { 8166 getFocusedStack().unhandledBackLocked(); 8167 } finally { 8168 Binder.restoreCallingIdentity(origId); 8169 } 8170 } 8171 } 8172 8173 public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException { 8174 enforceNotIsolatedCaller("openContentUri"); 8175 final int userId = UserHandle.getCallingUserId(); 8176 String name = uri.getAuthority(); 8177 ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId); 8178 ParcelFileDescriptor pfd = null; 8179 if (cph != null) { 8180 // We record the binder invoker's uid in thread-local storage before 8181 // going to the content provider to open the file. Later, in the code 8182 // that handles all permissions checks, we look for this uid and use 8183 // that rather than the Activity Manager's own uid. The effect is that 8184 // we do the check against the caller's permissions even though it looks 8185 // to the content provider like the Activity Manager itself is making 8186 // the request. 8187 sCallerIdentity.set(new Identity( 8188 Binder.getCallingPid(), Binder.getCallingUid())); 8189 try { 8190 pfd = cph.provider.openFile(null, uri, "r", null); 8191 } catch (FileNotFoundException e) { 8192 // do nothing; pfd will be returned null 8193 } finally { 8194 // Ensure that whatever happens, we clean up the identity state 8195 sCallerIdentity.remove(); 8196 } 8197 8198 // We've got the fd now, so we're done with the provider. 8199 removeContentProviderExternalUnchecked(name, null, userId); 8200 } else { 8201 Slog.d(TAG, "Failed to get provider for authority '" + name + "'"); 8202 } 8203 return pfd; 8204 } 8205 8206 // Actually is sleeping or shutting down or whatever else in the future 8207 // is an inactive state. 8208 public boolean isSleepingOrShuttingDown() { 8209 return mSleeping || mShuttingDown; 8210 } 8211 8212 void goingToSleep() { 8213 synchronized(this) { 8214 mWentToSleep = true; 8215 updateEventDispatchingLocked(); 8216 8217 if (!mSleeping) { 8218 mSleeping = true; 8219 mStackSupervisor.goingToSleepLocked(); 8220 8221 // Initialize the wake times of all processes. 8222 checkExcessivePowerUsageLocked(false); 8223 mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 8224 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 8225 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 8226 } 8227 } 8228 } 8229 8230 @Override 8231 public boolean shutdown(int timeout) { 8232 if (checkCallingPermission(android.Manifest.permission.SHUTDOWN) 8233 != PackageManager.PERMISSION_GRANTED) { 8234 throw new SecurityException("Requires permission " 8235 + android.Manifest.permission.SHUTDOWN); 8236 } 8237 8238 boolean timedout = false; 8239 8240 synchronized(this) { 8241 mShuttingDown = true; 8242 updateEventDispatchingLocked(); 8243 timedout = mStackSupervisor.shutdownLocked(timeout); 8244 } 8245 8246 mAppOpsService.shutdown(); 8247 mUsageStatsService.shutdown(); 8248 mBatteryStatsService.shutdown(); 8249 synchronized (this) { 8250 mProcessStats.shutdownLocked(); 8251 } 8252 8253 return timedout; 8254 } 8255 8256 public final void activitySlept(IBinder token) { 8257 if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token); 8258 8259 final long origId = Binder.clearCallingIdentity(); 8260 8261 synchronized (this) { 8262 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 8263 if (r != null) { 8264 mStackSupervisor.activitySleptLocked(r); 8265 } 8266 } 8267 8268 Binder.restoreCallingIdentity(origId); 8269 } 8270 8271 void logLockScreen(String msg) { 8272 if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg + 8273 " mLockScreenShown=" + mLockScreenShown + " mWentToSleep=" + 8274 mWentToSleep + " mSleeping=" + mSleeping + " mDismissKeyguardOnNextActivity=" + 8275 mStackSupervisor.mDismissKeyguardOnNextActivity); 8276 } 8277 8278 private void comeOutOfSleepIfNeededLocked() { 8279 if (!mWentToSleep && !mLockScreenShown) { 8280 if (mSleeping) { 8281 mSleeping = false; 8282 mStackSupervisor.comeOutOfSleepIfNeededLocked(); 8283 } 8284 } 8285 } 8286 8287 void wakingUp() { 8288 synchronized(this) { 8289 mWentToSleep = false; 8290 updateEventDispatchingLocked(); 8291 comeOutOfSleepIfNeededLocked(); 8292 } 8293 } 8294 8295 private void updateEventDispatchingLocked() { 8296 mWindowManager.setEventDispatching(mBooted && !mWentToSleep && !mShuttingDown); 8297 } 8298 8299 public void setLockScreenShown(boolean shown) { 8300 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER) 8301 != PackageManager.PERMISSION_GRANTED) { 8302 throw new SecurityException("Requires permission " 8303 + android.Manifest.permission.DEVICE_POWER); 8304 } 8305 8306 synchronized(this) { 8307 long ident = Binder.clearCallingIdentity(); 8308 try { 8309 if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown); 8310 mLockScreenShown = shown; 8311 comeOutOfSleepIfNeededLocked(); 8312 } finally { 8313 Binder.restoreCallingIdentity(ident); 8314 } 8315 } 8316 } 8317 8318 public void stopAppSwitches() { 8319 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 8320 != PackageManager.PERMISSION_GRANTED) { 8321 throw new SecurityException("Requires permission " 8322 + android.Manifest.permission.STOP_APP_SWITCHES); 8323 } 8324 8325 synchronized(this) { 8326 mAppSwitchesAllowedTime = SystemClock.uptimeMillis() 8327 + APP_SWITCH_DELAY_TIME; 8328 mDidAppSwitch = false; 8329 mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 8330 Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 8331 mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME); 8332 } 8333 } 8334 8335 public void resumeAppSwitches() { 8336 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 8337 != PackageManager.PERMISSION_GRANTED) { 8338 throw new SecurityException("Requires permission " 8339 + android.Manifest.permission.STOP_APP_SWITCHES); 8340 } 8341 8342 synchronized(this) { 8343 // Note that we don't execute any pending app switches... we will 8344 // let those wait until either the timeout, or the next start 8345 // activity request. 8346 mAppSwitchesAllowedTime = 0; 8347 } 8348 } 8349 8350 boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid, 8351 String name) { 8352 if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) { 8353 return true; 8354 } 8355 8356 final int perm = checkComponentPermission( 8357 android.Manifest.permission.STOP_APP_SWITCHES, callingPid, 8358 callingUid, -1, true); 8359 if (perm == PackageManager.PERMISSION_GRANTED) { 8360 return true; 8361 } 8362 8363 Slog.w(TAG, name + " request from " + callingUid + " stopped"); 8364 return false; 8365 } 8366 8367 public void setDebugApp(String packageName, boolean waitForDebugger, 8368 boolean persistent) { 8369 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP, 8370 "setDebugApp()"); 8371 8372 long ident = Binder.clearCallingIdentity(); 8373 try { 8374 // Note that this is not really thread safe if there are multiple 8375 // callers into it at the same time, but that's not a situation we 8376 // care about. 8377 if (persistent) { 8378 final ContentResolver resolver = mContext.getContentResolver(); 8379 Settings.Global.putString( 8380 resolver, Settings.Global.DEBUG_APP, 8381 packageName); 8382 Settings.Global.putInt( 8383 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 8384 waitForDebugger ? 1 : 0); 8385 } 8386 8387 synchronized (this) { 8388 if (!persistent) { 8389 mOrigDebugApp = mDebugApp; 8390 mOrigWaitForDebugger = mWaitForDebugger; 8391 } 8392 mDebugApp = packageName; 8393 mWaitForDebugger = waitForDebugger; 8394 mDebugTransient = !persistent; 8395 if (packageName != null) { 8396 forceStopPackageLocked(packageName, -1, false, false, true, true, 8397 UserHandle.USER_ALL, "set debug app"); 8398 } 8399 } 8400 } finally { 8401 Binder.restoreCallingIdentity(ident); 8402 } 8403 } 8404 8405 void setOpenGlTraceApp(ApplicationInfo app, String processName) { 8406 synchronized (this) { 8407 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 8408 if (!isDebuggable) { 8409 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 8410 throw new SecurityException("Process not debuggable: " + app.packageName); 8411 } 8412 } 8413 8414 mOpenGlTraceApp = processName; 8415 } 8416 } 8417 8418 void setProfileApp(ApplicationInfo app, String processName, String profileFile, 8419 ParcelFileDescriptor profileFd, boolean autoStopProfiler) { 8420 synchronized (this) { 8421 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 8422 if (!isDebuggable) { 8423 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 8424 throw new SecurityException("Process not debuggable: " + app.packageName); 8425 } 8426 } 8427 mProfileApp = processName; 8428 mProfileFile = profileFile; 8429 if (mProfileFd != null) { 8430 try { 8431 mProfileFd.close(); 8432 } catch (IOException e) { 8433 } 8434 mProfileFd = null; 8435 } 8436 mProfileFd = profileFd; 8437 mProfileType = 0; 8438 mAutoStopProfiler = autoStopProfiler; 8439 } 8440 } 8441 8442 @Override 8443 public void setAlwaysFinish(boolean enabled) { 8444 enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH, 8445 "setAlwaysFinish()"); 8446 8447 Settings.Global.putInt( 8448 mContext.getContentResolver(), 8449 Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0); 8450 8451 synchronized (this) { 8452 mAlwaysFinishActivities = enabled; 8453 } 8454 } 8455 8456 @Override 8457 public void setActivityController(IActivityController controller) { 8458 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 8459 "setActivityController()"); 8460 synchronized (this) { 8461 mController = controller; 8462 Watchdog.getInstance().setActivityController(controller); 8463 } 8464 } 8465 8466 @Override 8467 public void setUserIsMonkey(boolean userIsMonkey) { 8468 synchronized (this) { 8469 synchronized (mPidsSelfLocked) { 8470 final int callingPid = Binder.getCallingPid(); 8471 ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid); 8472 if (precessRecord == null) { 8473 throw new SecurityException("Unknown process: " + callingPid); 8474 } 8475 if (precessRecord.instrumentationUiAutomationConnection == null) { 8476 throw new SecurityException("Only an instrumentation process " 8477 + "with a UiAutomation can call setUserIsMonkey"); 8478 } 8479 } 8480 mUserIsMonkey = userIsMonkey; 8481 } 8482 } 8483 8484 @Override 8485 public boolean isUserAMonkey() { 8486 synchronized (this) { 8487 // If there is a controller also implies the user is a monkey. 8488 return (mUserIsMonkey || mController != null); 8489 } 8490 } 8491 8492 public void requestBugReport() { 8493 enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport"); 8494 SystemProperties.set("ctl.start", "bugreport"); 8495 } 8496 8497 public static long getInputDispatchingTimeoutLocked(ActivityRecord r) { 8498 return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT; 8499 } 8500 8501 public static long getInputDispatchingTimeoutLocked(ProcessRecord r) { 8502 if (r != null && (r.instrumentationClass != null || r.usingWrapper)) { 8503 return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT; 8504 } 8505 return KEY_DISPATCHING_TIMEOUT; 8506 } 8507 8508 @Override 8509 public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) { 8510 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS) 8511 != PackageManager.PERMISSION_GRANTED) { 8512 throw new SecurityException("Requires permission " 8513 + android.Manifest.permission.FILTER_EVENTS); 8514 } 8515 ProcessRecord proc; 8516 long timeout; 8517 synchronized (this) { 8518 synchronized (mPidsSelfLocked) { 8519 proc = mPidsSelfLocked.get(pid); 8520 } 8521 timeout = getInputDispatchingTimeoutLocked(proc); 8522 } 8523 8524 if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) { 8525 return -1; 8526 } 8527 8528 return timeout; 8529 } 8530 8531 /** 8532 * Handle input dispatching timeouts. 8533 * Returns whether input dispatching should be aborted or not. 8534 */ 8535 public boolean inputDispatchingTimedOut(final ProcessRecord proc, 8536 final ActivityRecord activity, final ActivityRecord parent, 8537 final boolean aboveSystem, String reason) { 8538 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS) 8539 != PackageManager.PERMISSION_GRANTED) { 8540 throw new SecurityException("Requires permission " 8541 + android.Manifest.permission.FILTER_EVENTS); 8542 } 8543 8544 final String annotation; 8545 if (reason == null) { 8546 annotation = "Input dispatching timed out"; 8547 } else { 8548 annotation = "Input dispatching timed out (" + reason + ")"; 8549 } 8550 8551 if (proc != null) { 8552 synchronized (this) { 8553 if (proc.debugging) { 8554 return false; 8555 } 8556 8557 if (mDidDexOpt) { 8558 // Give more time since we were dexopting. 8559 mDidDexOpt = false; 8560 return false; 8561 } 8562 8563 if (proc.instrumentationClass != null) { 8564 Bundle info = new Bundle(); 8565 info.putString("shortMsg", "keyDispatchingTimedOut"); 8566 info.putString("longMsg", annotation); 8567 finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info); 8568 return true; 8569 } 8570 } 8571 mHandler.post(new Runnable() { 8572 @Override 8573 public void run() { 8574 appNotResponding(proc, activity, parent, aboveSystem, annotation); 8575 } 8576 }); 8577 } 8578 8579 return true; 8580 } 8581 8582 public Bundle getAssistContextExtras(int requestType) { 8583 enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO, 8584 "getAssistContextExtras()"); 8585 PendingAssistExtras pae; 8586 Bundle extras = new Bundle(); 8587 synchronized (this) { 8588 ActivityRecord activity = getFocusedStack().mResumedActivity; 8589 if (activity == null) { 8590 Slog.w(TAG, "getAssistContextExtras failed: no resumed activity"); 8591 return null; 8592 } 8593 extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName); 8594 if (activity.app == null || activity.app.thread == null) { 8595 Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity); 8596 return extras; 8597 } 8598 if (activity.app.pid == Binder.getCallingPid()) { 8599 Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity); 8600 return extras; 8601 } 8602 pae = new PendingAssistExtras(activity); 8603 try { 8604 activity.app.thread.requestAssistContextExtras(activity.appToken, pae, 8605 requestType); 8606 mPendingAssistExtras.add(pae); 8607 mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT); 8608 } catch (RemoteException e) { 8609 Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity); 8610 return extras; 8611 } 8612 } 8613 synchronized (pae) { 8614 while (!pae.haveResult) { 8615 try { 8616 pae.wait(); 8617 } catch (InterruptedException e) { 8618 } 8619 } 8620 if (pae.result != null) { 8621 extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result); 8622 } 8623 } 8624 synchronized (this) { 8625 mPendingAssistExtras.remove(pae); 8626 mHandler.removeCallbacks(pae); 8627 } 8628 return extras; 8629 } 8630 8631 public void reportAssistContextExtras(IBinder token, Bundle extras) { 8632 PendingAssistExtras pae = (PendingAssistExtras)token; 8633 synchronized (pae) { 8634 pae.result = extras; 8635 pae.haveResult = true; 8636 pae.notifyAll(); 8637 } 8638 } 8639 8640 public void registerProcessObserver(IProcessObserver observer) { 8641 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 8642 "registerProcessObserver()"); 8643 synchronized (this) { 8644 mProcessObservers.register(observer); 8645 } 8646 } 8647 8648 @Override 8649 public void unregisterProcessObserver(IProcessObserver observer) { 8650 synchronized (this) { 8651 mProcessObservers.unregister(observer); 8652 } 8653 } 8654 8655 @Override 8656 public boolean convertFromTranslucent(IBinder token) { 8657 final long origId = Binder.clearCallingIdentity(); 8658 try { 8659 synchronized (this) { 8660 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 8661 if (r == null) { 8662 return false; 8663 } 8664 if (r.changeWindowTranslucency(true)) { 8665 mWindowManager.setAppFullscreen(token, true); 8666 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 8667 return true; 8668 } 8669 return false; 8670 } 8671 } finally { 8672 Binder.restoreCallingIdentity(origId); 8673 } 8674 } 8675 8676 @Override 8677 public boolean convertToTranslucent(IBinder token) { 8678 final long origId = Binder.clearCallingIdentity(); 8679 try { 8680 synchronized (this) { 8681 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 8682 if (r == null) { 8683 return false; 8684 } 8685 if (r.changeWindowTranslucency(false)) { 8686 r.task.stack.convertToTranslucent(r); 8687 mWindowManager.setAppFullscreen(token, false); 8688 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 8689 return true; 8690 } 8691 return false; 8692 } 8693 } finally { 8694 Binder.restoreCallingIdentity(origId); 8695 } 8696 } 8697 8698 @Override 8699 public void setImmersive(IBinder token, boolean immersive) { 8700 synchronized(this) { 8701 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 8702 if (r == null) { 8703 throw new IllegalArgumentException(); 8704 } 8705 r.immersive = immersive; 8706 8707 // update associated state if we're frontmost 8708 if (r == mFocusedActivity) { 8709 if (DEBUG_IMMERSIVE) { 8710 Slog.d(TAG, "Frontmost changed immersion: "+ r); 8711 } 8712 applyUpdateLockStateLocked(r); 8713 } 8714 } 8715 } 8716 8717 @Override 8718 public boolean isImmersive(IBinder token) { 8719 synchronized (this) { 8720 ActivityRecord r = ActivityRecord.isInStackLocked(token); 8721 if (r == null) { 8722 throw new IllegalArgumentException(); 8723 } 8724 return r.immersive; 8725 } 8726 } 8727 8728 public boolean isTopActivityImmersive() { 8729 enforceNotIsolatedCaller("startActivity"); 8730 synchronized (this) { 8731 ActivityRecord r = getFocusedStack().topRunningActivityLocked(null); 8732 return (r != null) ? r.immersive : false; 8733 } 8734 } 8735 8736 public final void enterSafeMode() { 8737 synchronized(this) { 8738 // It only makes sense to do this before the system is ready 8739 // and started launching other packages. 8740 if (!mSystemReady) { 8741 try { 8742 AppGlobals.getPackageManager().enterSafeMode(); 8743 } catch (RemoteException e) { 8744 } 8745 } 8746 8747 mSafeMode = true; 8748 } 8749 } 8750 8751 public final void showSafeModeOverlay() { 8752 View v = LayoutInflater.from(mContext).inflate( 8753 com.android.internal.R.layout.safe_mode, null); 8754 WindowManager.LayoutParams lp = new WindowManager.LayoutParams(); 8755 lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY; 8756 lp.width = WindowManager.LayoutParams.WRAP_CONTENT; 8757 lp.height = WindowManager.LayoutParams.WRAP_CONTENT; 8758 lp.gravity = Gravity.BOTTOM | Gravity.START; 8759 lp.format = v.getBackground().getOpacity(); 8760 lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE 8761 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE; 8762 lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS; 8763 ((WindowManager)mContext.getSystemService( 8764 Context.WINDOW_SERVICE)).addView(v, lp); 8765 } 8766 8767 public void noteWakeupAlarm(IIntentSender sender) { 8768 if (!(sender instanceof PendingIntentRecord)) { 8769 return; 8770 } 8771 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 8772 synchronized (stats) { 8773 if (mBatteryStatsService.isOnBattery()) { 8774 mBatteryStatsService.enforceCallingPermission(); 8775 PendingIntentRecord rec = (PendingIntentRecord)sender; 8776 int MY_UID = Binder.getCallingUid(); 8777 int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid; 8778 BatteryStatsImpl.Uid.Pkg pkg = 8779 stats.getPackageStatsLocked(uid, rec.key.packageName); 8780 pkg.incWakeupsLocked(); 8781 } 8782 } 8783 } 8784 8785 public boolean killPids(int[] pids, String pReason, boolean secure) { 8786 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 8787 throw new SecurityException("killPids only available to the system"); 8788 } 8789 String reason = (pReason == null) ? "Unknown" : pReason; 8790 // XXX Note: don't acquire main activity lock here, because the window 8791 // manager calls in with its locks held. 8792 8793 boolean killed = false; 8794 synchronized (mPidsSelfLocked) { 8795 int[] types = new int[pids.length]; 8796 int worstType = 0; 8797 for (int i=0; i<pids.length; i++) { 8798 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 8799 if (proc != null) { 8800 int type = proc.setAdj; 8801 types[i] = type; 8802 if (type > worstType) { 8803 worstType = type; 8804 } 8805 } 8806 } 8807 8808 // If the worst oom_adj is somewhere in the cached proc LRU range, 8809 // then constrain it so we will kill all cached procs. 8810 if (worstType < ProcessList.CACHED_APP_MAX_ADJ 8811 && worstType > ProcessList.CACHED_APP_MIN_ADJ) { 8812 worstType = ProcessList.CACHED_APP_MIN_ADJ; 8813 } 8814 8815 // If this is not a secure call, don't let it kill processes that 8816 // are important. 8817 if (!secure && worstType < ProcessList.SERVICE_ADJ) { 8818 worstType = ProcessList.SERVICE_ADJ; 8819 } 8820 8821 Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType); 8822 for (int i=0; i<pids.length; i++) { 8823 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 8824 if (proc == null) { 8825 continue; 8826 } 8827 int adj = proc.setAdj; 8828 if (adj >= worstType && !proc.killedByAm) { 8829 killUnneededProcessLocked(proc, reason); 8830 killed = true; 8831 } 8832 } 8833 } 8834 return killed; 8835 } 8836 8837 @Override 8838 public void killUid(int uid, String reason) { 8839 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 8840 throw new SecurityException("killUid only available to the system"); 8841 } 8842 synchronized (this) { 8843 killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid), 8844 ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false, 8845 reason != null ? reason : "kill uid"); 8846 } 8847 } 8848 8849 @Override 8850 public boolean killProcessesBelowForeground(String reason) { 8851 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 8852 throw new SecurityException("killProcessesBelowForeground() only available to system"); 8853 } 8854 8855 return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason); 8856 } 8857 8858 private boolean killProcessesBelowAdj(int belowAdj, String reason) { 8859 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 8860 throw new SecurityException("killProcessesBelowAdj() only available to system"); 8861 } 8862 8863 boolean killed = false; 8864 synchronized (mPidsSelfLocked) { 8865 final int size = mPidsSelfLocked.size(); 8866 for (int i = 0; i < size; i++) { 8867 final int pid = mPidsSelfLocked.keyAt(i); 8868 final ProcessRecord proc = mPidsSelfLocked.valueAt(i); 8869 if (proc == null) continue; 8870 8871 final int adj = proc.setAdj; 8872 if (adj > belowAdj && !proc.killedByAm) { 8873 killUnneededProcessLocked(proc, reason); 8874 killed = true; 8875 } 8876 } 8877 } 8878 return killed; 8879 } 8880 8881 @Override 8882 public void hang(final IBinder who, boolean allowRestart) { 8883 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 8884 != PackageManager.PERMISSION_GRANTED) { 8885 throw new SecurityException("Requires permission " 8886 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 8887 } 8888 8889 final IBinder.DeathRecipient death = new DeathRecipient() { 8890 @Override 8891 public void binderDied() { 8892 synchronized (this) { 8893 notifyAll(); 8894 } 8895 } 8896 }; 8897 8898 try { 8899 who.linkToDeath(death, 0); 8900 } catch (RemoteException e) { 8901 Slog.w(TAG, "hang: given caller IBinder is already dead."); 8902 return; 8903 } 8904 8905 synchronized (this) { 8906 Watchdog.getInstance().setAllowRestart(allowRestart); 8907 Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid()); 8908 synchronized (death) { 8909 while (who.isBinderAlive()) { 8910 try { 8911 death.wait(); 8912 } catch (InterruptedException e) { 8913 } 8914 } 8915 } 8916 Watchdog.getInstance().setAllowRestart(true); 8917 } 8918 } 8919 8920 @Override 8921 public void restart() { 8922 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 8923 != PackageManager.PERMISSION_GRANTED) { 8924 throw new SecurityException("Requires permission " 8925 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 8926 } 8927 8928 Log.i(TAG, "Sending shutdown broadcast..."); 8929 8930 BroadcastReceiver br = new BroadcastReceiver() { 8931 @Override public void onReceive(Context context, Intent intent) { 8932 // Now the broadcast is done, finish up the low-level shutdown. 8933 Log.i(TAG, "Shutting down activity manager..."); 8934 shutdown(10000); 8935 Log.i(TAG, "Shutdown complete, restarting!"); 8936 Process.killProcess(Process.myPid()); 8937 System.exit(10); 8938 } 8939 }; 8940 8941 // First send the high-level shut down broadcast. 8942 Intent intent = new Intent(Intent.ACTION_SHUTDOWN); 8943 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 8944 intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true); 8945 /* For now we are not doing a clean shutdown, because things seem to get unhappy. 8946 mContext.sendOrderedBroadcastAsUser(intent, 8947 UserHandle.ALL, null, br, mHandler, 0, null, null); 8948 */ 8949 br.onReceive(mContext, intent); 8950 } 8951 8952 private long getLowRamTimeSinceIdle(long now) { 8953 return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0); 8954 } 8955 8956 @Override 8957 public void performIdleMaintenance() { 8958 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 8959 != PackageManager.PERMISSION_GRANTED) { 8960 throw new SecurityException("Requires permission " 8961 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 8962 } 8963 8964 synchronized (this) { 8965 final long now = SystemClock.uptimeMillis(); 8966 final long timeSinceLastIdle = now - mLastIdleTime; 8967 final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now); 8968 mLastIdleTime = now; 8969 mLowRamTimeSinceLastIdle = 0; 8970 if (mLowRamStartTime != 0) { 8971 mLowRamStartTime = now; 8972 } 8973 8974 StringBuilder sb = new StringBuilder(128); 8975 sb.append("Idle maintenance over "); 8976 TimeUtils.formatDuration(timeSinceLastIdle, sb); 8977 sb.append(" low RAM for "); 8978 TimeUtils.formatDuration(lowRamSinceLastIdle, sb); 8979 Slog.i(TAG, sb.toString()); 8980 8981 // If at least 1/3 of our time since the last idle period has been spent 8982 // with RAM low, then we want to kill processes. 8983 boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3); 8984 8985 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 8986 ProcessRecord proc = mLruProcesses.get(i); 8987 if (proc.notCachedSinceIdle) { 8988 if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP 8989 && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) { 8990 if (doKilling && proc.initialIdlePss != 0 8991 && proc.lastPss > ((proc.initialIdlePss*3)/2)) { 8992 killUnneededProcessLocked(proc, "idle maint (pss " + proc.lastPss 8993 + " from " + proc.initialIdlePss + ")"); 8994 } 8995 } 8996 } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) { 8997 proc.notCachedSinceIdle = true; 8998 proc.initialIdlePss = 0; 8999 proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true, 9000 mSleeping, now); 9001 } 9002 } 9003 9004 mHandler.removeMessages(REQUEST_ALL_PSS_MSG); 9005 mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000); 9006 } 9007 } 9008 9009 private void retrieveSettings() { 9010 final ContentResolver resolver = mContext.getContentResolver(); 9011 String debugApp = Settings.Global.getString( 9012 resolver, Settings.Global.DEBUG_APP); 9013 boolean waitForDebugger = Settings.Global.getInt( 9014 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0; 9015 boolean alwaysFinishActivities = Settings.Global.getInt( 9016 resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0; 9017 boolean forceRtl = Settings.Global.getInt( 9018 resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0; 9019 // Transfer any global setting for forcing RTL layout, into a System Property 9020 SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0"); 9021 9022 Configuration configuration = new Configuration(); 9023 Settings.System.getConfiguration(resolver, configuration); 9024 if (forceRtl) { 9025 // This will take care of setting the correct layout direction flags 9026 configuration.setLayoutDirection(configuration.locale); 9027 } 9028 9029 synchronized (this) { 9030 mDebugApp = mOrigDebugApp = debugApp; 9031 mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger; 9032 mAlwaysFinishActivities = alwaysFinishActivities; 9033 // This happens before any activities are started, so we can 9034 // change mConfiguration in-place. 9035 updateConfigurationLocked(configuration, null, false, true); 9036 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration); 9037 } 9038 } 9039 9040 public boolean testIsSystemReady() { 9041 // no need to synchronize(this) just to read & return the value 9042 return mSystemReady; 9043 } 9044 9045 private static File getCalledPreBootReceiversFile() { 9046 File dataDir = Environment.getDataDirectory(); 9047 File systemDir = new File(dataDir, "system"); 9048 File fname = new File(systemDir, "called_pre_boots.dat"); 9049 return fname; 9050 } 9051 9052 static final int LAST_DONE_VERSION = 10000; 9053 9054 private static ArrayList<ComponentName> readLastDonePreBootReceivers() { 9055 ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>(); 9056 File file = getCalledPreBootReceiversFile(); 9057 FileInputStream fis = null; 9058 try { 9059 fis = new FileInputStream(file); 9060 DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048)); 9061 int fvers = dis.readInt(); 9062 if (fvers == LAST_DONE_VERSION) { 9063 String vers = dis.readUTF(); 9064 String codename = dis.readUTF(); 9065 String build = dis.readUTF(); 9066 if (android.os.Build.VERSION.RELEASE.equals(vers) 9067 && android.os.Build.VERSION.CODENAME.equals(codename) 9068 && android.os.Build.VERSION.INCREMENTAL.equals(build)) { 9069 int num = dis.readInt(); 9070 while (num > 0) { 9071 num--; 9072 String pkg = dis.readUTF(); 9073 String cls = dis.readUTF(); 9074 lastDoneReceivers.add(new ComponentName(pkg, cls)); 9075 } 9076 } 9077 } 9078 } catch (FileNotFoundException e) { 9079 } catch (IOException e) { 9080 Slog.w(TAG, "Failure reading last done pre-boot receivers", e); 9081 } finally { 9082 if (fis != null) { 9083 try { 9084 fis.close(); 9085 } catch (IOException e) { 9086 } 9087 } 9088 } 9089 return lastDoneReceivers; 9090 } 9091 9092 private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) { 9093 File file = getCalledPreBootReceiversFile(); 9094 FileOutputStream fos = null; 9095 DataOutputStream dos = null; 9096 try { 9097 Slog.i(TAG, "Writing new set of last done pre-boot receivers..."); 9098 fos = new FileOutputStream(file); 9099 dos = new DataOutputStream(new BufferedOutputStream(fos, 2048)); 9100 dos.writeInt(LAST_DONE_VERSION); 9101 dos.writeUTF(android.os.Build.VERSION.RELEASE); 9102 dos.writeUTF(android.os.Build.VERSION.CODENAME); 9103 dos.writeUTF(android.os.Build.VERSION.INCREMENTAL); 9104 dos.writeInt(list.size()); 9105 for (int i=0; i<list.size(); i++) { 9106 dos.writeUTF(list.get(i).getPackageName()); 9107 dos.writeUTF(list.get(i).getClassName()); 9108 } 9109 } catch (IOException e) { 9110 Slog.w(TAG, "Failure writing last done pre-boot receivers", e); 9111 file.delete(); 9112 } finally { 9113 FileUtils.sync(fos); 9114 if (dos != null) { 9115 try { 9116 dos.close(); 9117 } catch (IOException e) { 9118 // TODO Auto-generated catch block 9119 e.printStackTrace(); 9120 } 9121 } 9122 } 9123 } 9124 9125 public void systemReady(final Runnable goingCallback) { 9126 synchronized(this) { 9127 if (mSystemReady) { 9128 if (goingCallback != null) goingCallback.run(); 9129 return; 9130 } 9131 9132 // Check to see if there are any update receivers to run. 9133 if (!mDidUpdate) { 9134 if (mWaitingUpdate) { 9135 return; 9136 } 9137 Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED); 9138 List<ResolveInfo> ris = null; 9139 try { 9140 ris = AppGlobals.getPackageManager().queryIntentReceivers( 9141 intent, null, 0, 0); 9142 } catch (RemoteException e) { 9143 } 9144 if (ris != null) { 9145 for (int i=ris.size()-1; i>=0; i--) { 9146 if ((ris.get(i).activityInfo.applicationInfo.flags 9147 &ApplicationInfo.FLAG_SYSTEM) == 0) { 9148 ris.remove(i); 9149 } 9150 } 9151 intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE); 9152 9153 ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers(); 9154 9155 final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>(); 9156 for (int i=0; i<ris.size(); i++) { 9157 ActivityInfo ai = ris.get(i).activityInfo; 9158 ComponentName comp = new ComponentName(ai.packageName, ai.name); 9159 if (lastDoneReceivers.contains(comp)) { 9160 // We already did the pre boot receiver for this app with the current 9161 // platform version, so don't do it again... 9162 ris.remove(i); 9163 i--; 9164 // ...however, do keep it as one that has been done, so we don't 9165 // forget about it when rewriting the file of last done receivers. 9166 doneReceivers.add(comp); 9167 } 9168 } 9169 9170 final int[] users = getUsersLocked(); 9171 for (int i=0; i<ris.size(); i++) { 9172 ActivityInfo ai = ris.get(i).activityInfo; 9173 ComponentName comp = new ComponentName(ai.packageName, ai.name); 9174 doneReceivers.add(comp); 9175 intent.setComponent(comp); 9176 for (int j=0; j<users.length; j++) { 9177 IIntentReceiver finisher = null; 9178 if (i == ris.size()-1 && j == users.length-1) { 9179 finisher = new IIntentReceiver.Stub() { 9180 public void performReceive(Intent intent, int resultCode, 9181 String data, Bundle extras, boolean ordered, 9182 boolean sticky, int sendingUser) { 9183 // The raw IIntentReceiver interface is called 9184 // with the AM lock held, so redispatch to 9185 // execute our code without the lock. 9186 mHandler.post(new Runnable() { 9187 public void run() { 9188 synchronized (ActivityManagerService.this) { 9189 mDidUpdate = true; 9190 } 9191 writeLastDonePreBootReceivers(doneReceivers); 9192 showBootMessage(mContext.getText( 9193 R.string.android_upgrading_complete), 9194 false); 9195 systemReady(goingCallback); 9196 } 9197 }); 9198 } 9199 }; 9200 } 9201 Slog.i(TAG, "Sending system update to " + intent.getComponent() 9202 + " for user " + users[j]); 9203 broadcastIntentLocked(null, null, intent, null, finisher, 9204 0, null, null, null, AppOpsManager.OP_NONE, 9205 true, false, MY_PID, Process.SYSTEM_UID, 9206 users[j]); 9207 if (finisher != null) { 9208 mWaitingUpdate = true; 9209 } 9210 } 9211 } 9212 } 9213 if (mWaitingUpdate) { 9214 return; 9215 } 9216 mDidUpdate = true; 9217 } 9218 9219 mAppOpsService.systemReady(); 9220 mSystemReady = true; 9221 } 9222 9223 ArrayList<ProcessRecord> procsToKill = null; 9224 synchronized(mPidsSelfLocked) { 9225 for (int i=mPidsSelfLocked.size()-1; i>=0; i--) { 9226 ProcessRecord proc = mPidsSelfLocked.valueAt(i); 9227 if (!isAllowedWhileBooting(proc.info)){ 9228 if (procsToKill == null) { 9229 procsToKill = new ArrayList<ProcessRecord>(); 9230 } 9231 procsToKill.add(proc); 9232 } 9233 } 9234 } 9235 9236 synchronized(this) { 9237 if (procsToKill != null) { 9238 for (int i=procsToKill.size()-1; i>=0; i--) { 9239 ProcessRecord proc = procsToKill.get(i); 9240 Slog.i(TAG, "Removing system update proc: " + proc); 9241 removeProcessLocked(proc, true, false, "system update done"); 9242 } 9243 } 9244 9245 // Now that we have cleaned up any update processes, we 9246 // are ready to start launching real processes and know that 9247 // we won't trample on them any more. 9248 mProcessesReady = true; 9249 } 9250 9251 Slog.i(TAG, "System now ready"); 9252 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY, 9253 SystemClock.uptimeMillis()); 9254 9255 synchronized(this) { 9256 // Make sure we have no pre-ready processes sitting around. 9257 9258 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) { 9259 ResolveInfo ri = mContext.getPackageManager() 9260 .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST), 9261 STOCK_PM_FLAGS); 9262 CharSequence errorMsg = null; 9263 if (ri != null) { 9264 ActivityInfo ai = ri.activityInfo; 9265 ApplicationInfo app = ai.applicationInfo; 9266 if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) { 9267 mTopAction = Intent.ACTION_FACTORY_TEST; 9268 mTopData = null; 9269 mTopComponent = new ComponentName(app.packageName, 9270 ai.name); 9271 } else { 9272 errorMsg = mContext.getResources().getText( 9273 com.android.internal.R.string.factorytest_not_system); 9274 } 9275 } else { 9276 errorMsg = mContext.getResources().getText( 9277 com.android.internal.R.string.factorytest_no_action); 9278 } 9279 if (errorMsg != null) { 9280 mTopAction = null; 9281 mTopData = null; 9282 mTopComponent = null; 9283 Message msg = Message.obtain(); 9284 msg.what = SHOW_FACTORY_ERROR_MSG; 9285 msg.getData().putCharSequence("msg", errorMsg); 9286 mHandler.sendMessage(msg); 9287 } 9288 } 9289 } 9290 9291 retrieveSettings(); 9292 9293 synchronized (this) { 9294 readGrantedUriPermissionsLocked(); 9295 } 9296 9297 if (goingCallback != null) goingCallback.run(); 9298 9299 synchronized (this) { 9300 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 9301 try { 9302 List apps = AppGlobals.getPackageManager(). 9303 getPersistentApplications(STOCK_PM_FLAGS); 9304 if (apps != null) { 9305 int N = apps.size(); 9306 int i; 9307 for (i=0; i<N; i++) { 9308 ApplicationInfo info 9309 = (ApplicationInfo)apps.get(i); 9310 if (info != null && 9311 !info.packageName.equals("android")) { 9312 addAppLocked(info, false, null /* ABI override */); 9313 } 9314 } 9315 } 9316 } catch (RemoteException ex) { 9317 // pm is in same process, this will never happen. 9318 } 9319 } 9320 9321 // Start up initial activity. 9322 mBooting = true; 9323 9324 try { 9325 if (AppGlobals.getPackageManager().hasSystemUidErrors()) { 9326 Message msg = Message.obtain(); 9327 msg.what = SHOW_UID_ERROR_MSG; 9328 mHandler.sendMessage(msg); 9329 } 9330 } catch (RemoteException e) { 9331 } 9332 9333 long ident = Binder.clearCallingIdentity(); 9334 try { 9335 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 9336 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 9337 | Intent.FLAG_RECEIVER_FOREGROUND); 9338 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); 9339 broadcastIntentLocked(null, null, intent, 9340 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 9341 false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId); 9342 intent = new Intent(Intent.ACTION_USER_STARTING); 9343 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 9344 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); 9345 broadcastIntentLocked(null, null, intent, 9346 null, new IIntentReceiver.Stub() { 9347 @Override 9348 public void performReceive(Intent intent, int resultCode, String data, 9349 Bundle extras, boolean ordered, boolean sticky, int sendingUser) 9350 throws RemoteException { 9351 } 9352 }, 0, null, null, 9353 android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 9354 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 9355 } finally { 9356 Binder.restoreCallingIdentity(ident); 9357 } 9358 mStackSupervisor.resumeTopActivitiesLocked(); 9359 sendUserSwitchBroadcastsLocked(-1, mCurrentUserId); 9360 } 9361 } 9362 9363 private boolean makeAppCrashingLocked(ProcessRecord app, 9364 String shortMsg, String longMsg, String stackTrace) { 9365 app.crashing = true; 9366 app.crashingReport = generateProcessError(app, 9367 ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace); 9368 startAppProblemLocked(app); 9369 app.stopFreezingAllLocked(); 9370 return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace); 9371 } 9372 9373 private void makeAppNotRespondingLocked(ProcessRecord app, 9374 String activity, String shortMsg, String longMsg) { 9375 app.notResponding = true; 9376 app.notRespondingReport = generateProcessError(app, 9377 ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING, 9378 activity, shortMsg, longMsg, null); 9379 startAppProblemLocked(app); 9380 app.stopFreezingAllLocked(); 9381 } 9382 9383 /** 9384 * Generate a process error record, suitable for attachment to a ProcessRecord. 9385 * 9386 * @param app The ProcessRecord in which the error occurred. 9387 * @param condition Crashing, Application Not Responding, etc. Values are defined in 9388 * ActivityManager.AppErrorStateInfo 9389 * @param activity The activity associated with the crash, if known. 9390 * @param shortMsg Short message describing the crash. 9391 * @param longMsg Long message describing the crash. 9392 * @param stackTrace Full crash stack trace, may be null. 9393 * 9394 * @return Returns a fully-formed AppErrorStateInfo record. 9395 */ 9396 private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app, 9397 int condition, String activity, String shortMsg, String longMsg, String stackTrace) { 9398 ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo(); 9399 9400 report.condition = condition; 9401 report.processName = app.processName; 9402 report.pid = app.pid; 9403 report.uid = app.info.uid; 9404 report.tag = activity; 9405 report.shortMsg = shortMsg; 9406 report.longMsg = longMsg; 9407 report.stackTrace = stackTrace; 9408 9409 return report; 9410 } 9411 9412 void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) { 9413 synchronized (this) { 9414 app.crashing = false; 9415 app.crashingReport = null; 9416 app.notResponding = false; 9417 app.notRespondingReport = null; 9418 if (app.anrDialog == fromDialog) { 9419 app.anrDialog = null; 9420 } 9421 if (app.waitDialog == fromDialog) { 9422 app.waitDialog = null; 9423 } 9424 if (app.pid > 0 && app.pid != MY_PID) { 9425 handleAppCrashLocked(app, null, null, null); 9426 killUnneededProcessLocked(app, "user request after error"); 9427 } 9428 } 9429 } 9430 9431 private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg, 9432 String stackTrace) { 9433 long now = SystemClock.uptimeMillis(); 9434 9435 Long crashTime; 9436 if (!app.isolated) { 9437 crashTime = mProcessCrashTimes.get(app.info.processName, app.uid); 9438 } else { 9439 crashTime = null; 9440 } 9441 if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) { 9442 // This process loses! 9443 Slog.w(TAG, "Process " + app.info.processName 9444 + " has crashed too many times: killing!"); 9445 EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH, 9446 app.userId, app.info.processName, app.uid); 9447 mStackSupervisor.handleAppCrashLocked(app); 9448 if (!app.persistent) { 9449 // We don't want to start this process again until the user 9450 // explicitly does so... but for persistent process, we really 9451 // need to keep it running. If a persistent process is actually 9452 // repeatedly crashing, then badness for everyone. 9453 EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid, 9454 app.info.processName); 9455 if (!app.isolated) { 9456 // XXX We don't have a way to mark isolated processes 9457 // as bad, since they don't have a peristent identity. 9458 mBadProcesses.put(app.info.processName, app.uid, 9459 new BadProcessInfo(now, shortMsg, longMsg, stackTrace)); 9460 mProcessCrashTimes.remove(app.info.processName, app.uid); 9461 } 9462 app.bad = true; 9463 app.removed = true; 9464 // Don't let services in this process be restarted and potentially 9465 // annoy the user repeatedly. Unless it is persistent, since those 9466 // processes run critical code. 9467 removeProcessLocked(app, false, false, "crash"); 9468 mStackSupervisor.resumeTopActivitiesLocked(); 9469 return false; 9470 } 9471 mStackSupervisor.resumeTopActivitiesLocked(); 9472 } else { 9473 mStackSupervisor.finishTopRunningActivityLocked(app); 9474 } 9475 9476 // Bump up the crash count of any services currently running in the proc. 9477 for (int i=app.services.size()-1; i>=0; i--) { 9478 // Any services running in the application need to be placed 9479 // back in the pending list. 9480 ServiceRecord sr = app.services.valueAt(i); 9481 sr.crashCount++; 9482 } 9483 9484 // If the crashing process is what we consider to be the "home process" and it has been 9485 // replaced by a third-party app, clear the package preferred activities from packages 9486 // with a home activity running in the process to prevent a repeatedly crashing app 9487 // from blocking the user to manually clear the list. 9488 final ArrayList<ActivityRecord> activities = app.activities; 9489 if (app == mHomeProcess && activities.size() > 0 9490 && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) { 9491 for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) { 9492 final ActivityRecord r = activities.get(activityNdx); 9493 if (r.isHomeActivity()) { 9494 Log.i(TAG, "Clearing package preferred activities from " + r.packageName); 9495 try { 9496 ActivityThread.getPackageManager() 9497 .clearPackagePreferredActivities(r.packageName); 9498 } catch (RemoteException c) { 9499 // pm is in same process, this will never happen. 9500 } 9501 } 9502 } 9503 } 9504 9505 if (!app.isolated) { 9506 // XXX Can't keep track of crash times for isolated processes, 9507 // because they don't have a perisistent identity. 9508 mProcessCrashTimes.put(app.info.processName, app.uid, now); 9509 } 9510 9511 return true; 9512 } 9513 9514 void startAppProblemLocked(ProcessRecord app) { 9515 if (app.userId == mCurrentUserId) { 9516 app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver( 9517 mContext, app.info.packageName, app.info.flags); 9518 } else { 9519 // If this app is not running under the current user, then we 9520 // can't give it a report button because that would require 9521 // launching the report UI under a different user. 9522 app.errorReportReceiver = null; 9523 } 9524 skipCurrentReceiverLocked(app); 9525 } 9526 9527 void skipCurrentReceiverLocked(ProcessRecord app) { 9528 for (BroadcastQueue queue : mBroadcastQueues) { 9529 queue.skipCurrentReceiverLocked(app); 9530 } 9531 } 9532 9533 /** 9534 * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes. 9535 * The application process will exit immediately after this call returns. 9536 * @param app object of the crashing app, null for the system server 9537 * @param crashInfo describing the exception 9538 */ 9539 public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) { 9540 ProcessRecord r = findAppProcess(app, "Crash"); 9541 final String processName = app == null ? "system_server" 9542 : (r == null ? "unknown" : r.processName); 9543 9544 handleApplicationCrashInner("crash", r, processName, crashInfo); 9545 } 9546 9547 /* Native crash reporting uses this inner version because it needs to be somewhat 9548 * decoupled from the AM-managed cleanup lifecycle 9549 */ 9550 void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName, 9551 ApplicationErrorReport.CrashInfo crashInfo) { 9552 EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(), 9553 UserHandle.getUserId(Binder.getCallingUid()), processName, 9554 r == null ? -1 : r.info.flags, 9555 crashInfo.exceptionClassName, 9556 crashInfo.exceptionMessage, 9557 crashInfo.throwFileName, 9558 crashInfo.throwLineNumber); 9559 9560 addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo); 9561 9562 crashApplication(r, crashInfo); 9563 } 9564 9565 public void handleApplicationStrictModeViolation( 9566 IBinder app, 9567 int violationMask, 9568 StrictMode.ViolationInfo info) { 9569 ProcessRecord r = findAppProcess(app, "StrictMode"); 9570 if (r == null) { 9571 return; 9572 } 9573 9574 if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) { 9575 Integer stackFingerprint = info.hashCode(); 9576 boolean logIt = true; 9577 synchronized (mAlreadyLoggedViolatedStacks) { 9578 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) { 9579 logIt = false; 9580 // TODO: sub-sample into EventLog for these, with 9581 // the info.durationMillis? Then we'd get 9582 // the relative pain numbers, without logging all 9583 // the stack traces repeatedly. We'd want to do 9584 // likewise in the client code, which also does 9585 // dup suppression, before the Binder call. 9586 } else { 9587 if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) { 9588 mAlreadyLoggedViolatedStacks.clear(); 9589 } 9590 mAlreadyLoggedViolatedStacks.add(stackFingerprint); 9591 } 9592 } 9593 if (logIt) { 9594 logStrictModeViolationToDropBox(r, info); 9595 } 9596 } 9597 9598 if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) { 9599 AppErrorResult result = new AppErrorResult(); 9600 synchronized (this) { 9601 final long origId = Binder.clearCallingIdentity(); 9602 9603 Message msg = Message.obtain(); 9604 msg.what = SHOW_STRICT_MODE_VIOLATION_MSG; 9605 HashMap<String, Object> data = new HashMap<String, Object>(); 9606 data.put("result", result); 9607 data.put("app", r); 9608 data.put("violationMask", violationMask); 9609 data.put("info", info); 9610 msg.obj = data; 9611 mHandler.sendMessage(msg); 9612 9613 Binder.restoreCallingIdentity(origId); 9614 } 9615 int res = result.get(); 9616 Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res); 9617 } 9618 } 9619 9620 // Depending on the policy in effect, there could be a bunch of 9621 // these in quick succession so we try to batch these together to 9622 // minimize disk writes, number of dropbox entries, and maximize 9623 // compression, by having more fewer, larger records. 9624 private void logStrictModeViolationToDropBox( 9625 ProcessRecord process, 9626 StrictMode.ViolationInfo info) { 9627 if (info == null) { 9628 return; 9629 } 9630 final boolean isSystemApp = process == null || 9631 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM | 9632 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0; 9633 final String processName = process == null ? "unknown" : process.processName; 9634 final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode"; 9635 final DropBoxManager dbox = (DropBoxManager) 9636 mContext.getSystemService(Context.DROPBOX_SERVICE); 9637 9638 // Exit early if the dropbox isn't configured to accept this report type. 9639 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 9640 9641 boolean bufferWasEmpty; 9642 boolean needsFlush; 9643 final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024); 9644 synchronized (sb) { 9645 bufferWasEmpty = sb.length() == 0; 9646 appendDropBoxProcessHeaders(process, processName, sb); 9647 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 9648 sb.append("System-App: ").append(isSystemApp).append("\n"); 9649 sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n"); 9650 if (info.violationNumThisLoop != 0) { 9651 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n"); 9652 } 9653 if (info.numAnimationsRunning != 0) { 9654 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n"); 9655 } 9656 if (info.broadcastIntentAction != null) { 9657 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n"); 9658 } 9659 if (info.durationMillis != -1) { 9660 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n"); 9661 } 9662 if (info.numInstances != -1) { 9663 sb.append("Instance-Count: ").append(info.numInstances).append("\n"); 9664 } 9665 if (info.tags != null) { 9666 for (String tag : info.tags) { 9667 sb.append("Span-Tag: ").append(tag).append("\n"); 9668 } 9669 } 9670 sb.append("\n"); 9671 if (info.crashInfo != null && info.crashInfo.stackTrace != null) { 9672 sb.append(info.crashInfo.stackTrace); 9673 } 9674 sb.append("\n"); 9675 9676 // Only buffer up to ~64k. Various logging bits truncate 9677 // things at 128k. 9678 needsFlush = (sb.length() > 64 * 1024); 9679 } 9680 9681 // Flush immediately if the buffer's grown too large, or this 9682 // is a non-system app. Non-system apps are isolated with a 9683 // different tag & policy and not batched. 9684 // 9685 // Batching is useful during internal testing with 9686 // StrictMode settings turned up high. Without batching, 9687 // thousands of separate files could be created on boot. 9688 if (!isSystemApp || needsFlush) { 9689 new Thread("Error dump: " + dropboxTag) { 9690 @Override 9691 public void run() { 9692 String report; 9693 synchronized (sb) { 9694 report = sb.toString(); 9695 sb.delete(0, sb.length()); 9696 sb.trimToSize(); 9697 } 9698 if (report.length() != 0) { 9699 dbox.addText(dropboxTag, report); 9700 } 9701 } 9702 }.start(); 9703 return; 9704 } 9705 9706 // System app batching: 9707 if (!bufferWasEmpty) { 9708 // An existing dropbox-writing thread is outstanding, so 9709 // we don't need to start it up. The existing thread will 9710 // catch the buffer appends we just did. 9711 return; 9712 } 9713 9714 // Worker thread to both batch writes and to avoid blocking the caller on I/O. 9715 // (After this point, we shouldn't access AMS internal data structures.) 9716 new Thread("Error dump: " + dropboxTag) { 9717 @Override 9718 public void run() { 9719 // 5 second sleep to let stacks arrive and be batched together 9720 try { 9721 Thread.sleep(5000); // 5 seconds 9722 } catch (InterruptedException e) {} 9723 9724 String errorReport; 9725 synchronized (mStrictModeBuffer) { 9726 errorReport = mStrictModeBuffer.toString(); 9727 if (errorReport.length() == 0) { 9728 return; 9729 } 9730 mStrictModeBuffer.delete(0, mStrictModeBuffer.length()); 9731 mStrictModeBuffer.trimToSize(); 9732 } 9733 dbox.addText(dropboxTag, errorReport); 9734 } 9735 }.start(); 9736 } 9737 9738 /** 9739 * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors. 9740 * @param app object of the crashing app, null for the system server 9741 * @param tag reported by the caller 9742 * @param crashInfo describing the context of the error 9743 * @return true if the process should exit immediately (WTF is fatal) 9744 */ 9745 public boolean handleApplicationWtf(IBinder app, String tag, 9746 ApplicationErrorReport.CrashInfo crashInfo) { 9747 ProcessRecord r = findAppProcess(app, "WTF"); 9748 final String processName = app == null ? "system_server" 9749 : (r == null ? "unknown" : r.processName); 9750 9751 EventLog.writeEvent(EventLogTags.AM_WTF, 9752 UserHandle.getUserId(Binder.getCallingUid()), Binder.getCallingPid(), 9753 processName, 9754 r == null ? -1 : r.info.flags, 9755 tag, crashInfo.exceptionMessage); 9756 9757 addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo); 9758 9759 if (r != null && r.pid != Process.myPid() && 9760 Settings.Global.getInt(mContext.getContentResolver(), 9761 Settings.Global.WTF_IS_FATAL, 0) != 0) { 9762 crashApplication(r, crashInfo); 9763 return true; 9764 } else { 9765 return false; 9766 } 9767 } 9768 9769 /** 9770 * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit}) 9771 * @return the corresponding {@link ProcessRecord} object, or null if none could be found 9772 */ 9773 private ProcessRecord findAppProcess(IBinder app, String reason) { 9774 if (app == null) { 9775 return null; 9776 } 9777 9778 synchronized (this) { 9779 final int NP = mProcessNames.getMap().size(); 9780 for (int ip=0; ip<NP; ip++) { 9781 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 9782 final int NA = apps.size(); 9783 for (int ia=0; ia<NA; ia++) { 9784 ProcessRecord p = apps.valueAt(ia); 9785 if (p.thread != null && p.thread.asBinder() == app) { 9786 return p; 9787 } 9788 } 9789 } 9790 9791 Slog.w(TAG, "Can't find mystery application for " + reason 9792 + " from pid=" + Binder.getCallingPid() 9793 + " uid=" + Binder.getCallingUid() + ": " + app); 9794 return null; 9795 } 9796 } 9797 9798 /** 9799 * Utility function for addErrorToDropBox and handleStrictModeViolation's logging 9800 * to append various headers to the dropbox log text. 9801 */ 9802 private void appendDropBoxProcessHeaders(ProcessRecord process, String processName, 9803 StringBuilder sb) { 9804 // Watchdog thread ends up invoking this function (with 9805 // a null ProcessRecord) to add the stack file to dropbox. 9806 // Do not acquire a lock on this (am) in such cases, as it 9807 // could cause a potential deadlock, if and when watchdog 9808 // is invoked due to unavailability of lock on am and it 9809 // would prevent watchdog from killing system_server. 9810 if (process == null) { 9811 sb.append("Process: ").append(processName).append("\n"); 9812 return; 9813 } 9814 // Note: ProcessRecord 'process' is guarded by the service 9815 // instance. (notably process.pkgList, which could otherwise change 9816 // concurrently during execution of this method) 9817 synchronized (this) { 9818 sb.append("Process: ").append(processName).append("\n"); 9819 int flags = process.info.flags; 9820 IPackageManager pm = AppGlobals.getPackageManager(); 9821 sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n"); 9822 for (int ip=0; ip<process.pkgList.size(); ip++) { 9823 String pkg = process.pkgList.keyAt(ip); 9824 sb.append("Package: ").append(pkg); 9825 try { 9826 PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId()); 9827 if (pi != null) { 9828 sb.append(" v").append(pi.versionCode); 9829 if (pi.versionName != null) { 9830 sb.append(" (").append(pi.versionName).append(")"); 9831 } 9832 } 9833 } catch (RemoteException e) { 9834 Slog.e(TAG, "Error getting package info: " + pkg, e); 9835 } 9836 sb.append("\n"); 9837 } 9838 } 9839 } 9840 9841 private static String processClass(ProcessRecord process) { 9842 if (process == null || process.pid == MY_PID) { 9843 return "system_server"; 9844 } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) { 9845 return "system_app"; 9846 } else { 9847 return "data_app"; 9848 } 9849 } 9850 9851 /** 9852 * Write a description of an error (crash, WTF, ANR) to the drop box. 9853 * @param eventType to include in the drop box tag ("crash", "wtf", etc.) 9854 * @param process which caused the error, null means the system server 9855 * @param activity which triggered the error, null if unknown 9856 * @param parent activity related to the error, null if unknown 9857 * @param subject line related to the error, null if absent 9858 * @param report in long form describing the error, null if absent 9859 * @param logFile to include in the report, null if none 9860 * @param crashInfo giving an application stack trace, null if absent 9861 */ 9862 public void addErrorToDropBox(String eventType, 9863 ProcessRecord process, String processName, ActivityRecord activity, 9864 ActivityRecord parent, String subject, 9865 final String report, final File logFile, 9866 final ApplicationErrorReport.CrashInfo crashInfo) { 9867 // NOTE -- this must never acquire the ActivityManagerService lock, 9868 // otherwise the watchdog may be prevented from resetting the system. 9869 9870 final String dropboxTag = processClass(process) + "_" + eventType; 9871 final DropBoxManager dbox = (DropBoxManager) 9872 mContext.getSystemService(Context.DROPBOX_SERVICE); 9873 9874 // Exit early if the dropbox isn't configured to accept this report type. 9875 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 9876 9877 final StringBuilder sb = new StringBuilder(1024); 9878 appendDropBoxProcessHeaders(process, processName, sb); 9879 if (activity != null) { 9880 sb.append("Activity: ").append(activity.shortComponentName).append("\n"); 9881 } 9882 if (parent != null && parent.app != null && parent.app.pid != process.pid) { 9883 sb.append("Parent-Process: ").append(parent.app.processName).append("\n"); 9884 } 9885 if (parent != null && parent != activity) { 9886 sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n"); 9887 } 9888 if (subject != null) { 9889 sb.append("Subject: ").append(subject).append("\n"); 9890 } 9891 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 9892 if (Debug.isDebuggerConnected()) { 9893 sb.append("Debugger: Connected\n"); 9894 } 9895 sb.append("\n"); 9896 9897 // Do the rest in a worker thread to avoid blocking the caller on I/O 9898 // (After this point, we shouldn't access AMS internal data structures.) 9899 Thread worker = new Thread("Error dump: " + dropboxTag) { 9900 @Override 9901 public void run() { 9902 if (report != null) { 9903 sb.append(report); 9904 } 9905 if (logFile != null) { 9906 try { 9907 sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE, 9908 "\n\n[[TRUNCATED]]")); 9909 } catch (IOException e) { 9910 Slog.e(TAG, "Error reading " + logFile, e); 9911 } 9912 } 9913 if (crashInfo != null && crashInfo.stackTrace != null) { 9914 sb.append(crashInfo.stackTrace); 9915 } 9916 9917 String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag; 9918 int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0); 9919 if (lines > 0) { 9920 sb.append("\n"); 9921 9922 // Merge several logcat streams, and take the last N lines 9923 InputStreamReader input = null; 9924 try { 9925 java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat", 9926 "-v", "time", "-b", "events", "-b", "system", "-b", "main", 9927 "-t", String.valueOf(lines)).redirectErrorStream(true).start(); 9928 9929 try { logcat.getOutputStream().close(); } catch (IOException e) {} 9930 try { logcat.getErrorStream().close(); } catch (IOException e) {} 9931 input = new InputStreamReader(logcat.getInputStream()); 9932 9933 int num; 9934 char[] buf = new char[8192]; 9935 while ((num = input.read(buf)) > 0) sb.append(buf, 0, num); 9936 } catch (IOException e) { 9937 Slog.e(TAG, "Error running logcat", e); 9938 } finally { 9939 if (input != null) try { input.close(); } catch (IOException e) {} 9940 } 9941 } 9942 9943 dbox.addText(dropboxTag, sb.toString()); 9944 } 9945 }; 9946 9947 if (process == null) { 9948 // If process is null, we are being called from some internal code 9949 // and may be about to die -- run this synchronously. 9950 worker.run(); 9951 } else { 9952 worker.start(); 9953 } 9954 } 9955 9956 /** 9957 * Bring up the "unexpected error" dialog box for a crashing app. 9958 * Deal with edge cases (intercepts from instrumented applications, 9959 * ActivityController, error intent receivers, that sort of thing). 9960 * @param r the application crashing 9961 * @param crashInfo describing the failure 9962 */ 9963 private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) { 9964 long timeMillis = System.currentTimeMillis(); 9965 String shortMsg = crashInfo.exceptionClassName; 9966 String longMsg = crashInfo.exceptionMessage; 9967 String stackTrace = crashInfo.stackTrace; 9968 if (shortMsg != null && longMsg != null) { 9969 longMsg = shortMsg + ": " + longMsg; 9970 } else if (shortMsg != null) { 9971 longMsg = shortMsg; 9972 } 9973 9974 AppErrorResult result = new AppErrorResult(); 9975 synchronized (this) { 9976 if (mController != null) { 9977 try { 9978 String name = r != null ? r.processName : null; 9979 int pid = r != null ? r.pid : Binder.getCallingPid(); 9980 if (!mController.appCrashed(name, pid, 9981 shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) { 9982 Slog.w(TAG, "Force-killing crashed app " + name 9983 + " at watcher's request"); 9984 Process.killProcess(pid); 9985 return; 9986 } 9987 } catch (RemoteException e) { 9988 mController = null; 9989 Watchdog.getInstance().setActivityController(null); 9990 } 9991 } 9992 9993 final long origId = Binder.clearCallingIdentity(); 9994 9995 // If this process is running instrumentation, finish it. 9996 if (r != null && r.instrumentationClass != null) { 9997 Slog.w(TAG, "Error in app " + r.processName 9998 + " running instrumentation " + r.instrumentationClass + ":"); 9999 if (shortMsg != null) Slog.w(TAG, " " + shortMsg); 10000 if (longMsg != null) Slog.w(TAG, " " + longMsg); 10001 Bundle info = new Bundle(); 10002 info.putString("shortMsg", shortMsg); 10003 info.putString("longMsg", longMsg); 10004 finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info); 10005 Binder.restoreCallingIdentity(origId); 10006 return; 10007 } 10008 10009 // If we can't identify the process or it's already exceeded its crash quota, 10010 // quit right away without showing a crash dialog. 10011 if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) { 10012 Binder.restoreCallingIdentity(origId); 10013 return; 10014 } 10015 10016 Message msg = Message.obtain(); 10017 msg.what = SHOW_ERROR_MSG; 10018 HashMap data = new HashMap(); 10019 data.put("result", result); 10020 data.put("app", r); 10021 msg.obj = data; 10022 mHandler.sendMessage(msg); 10023 10024 Binder.restoreCallingIdentity(origId); 10025 } 10026 10027 int res = result.get(); 10028 10029 Intent appErrorIntent = null; 10030 synchronized (this) { 10031 if (r != null && !r.isolated) { 10032 // XXX Can't keep track of crash time for isolated processes, 10033 // since they don't have a persistent identity. 10034 mProcessCrashTimes.put(r.info.processName, r.uid, 10035 SystemClock.uptimeMillis()); 10036 } 10037 if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) { 10038 appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo); 10039 } 10040 } 10041 10042 if (appErrorIntent != null) { 10043 try { 10044 mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId)); 10045 } catch (ActivityNotFoundException e) { 10046 Slog.w(TAG, "bug report receiver dissappeared", e); 10047 } 10048 } 10049 } 10050 10051 Intent createAppErrorIntentLocked(ProcessRecord r, 10052 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 10053 ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo); 10054 if (report == null) { 10055 return null; 10056 } 10057 Intent result = new Intent(Intent.ACTION_APP_ERROR); 10058 result.setComponent(r.errorReportReceiver); 10059 result.putExtra(Intent.EXTRA_BUG_REPORT, report); 10060 result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 10061 return result; 10062 } 10063 10064 private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r, 10065 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 10066 if (r.errorReportReceiver == null) { 10067 return null; 10068 } 10069 10070 if (!r.crashing && !r.notResponding && !r.forceCrashReport) { 10071 return null; 10072 } 10073 10074 ApplicationErrorReport report = new ApplicationErrorReport(); 10075 report.packageName = r.info.packageName; 10076 report.installerPackageName = r.errorReportReceiver.getPackageName(); 10077 report.processName = r.processName; 10078 report.time = timeMillis; 10079 report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0; 10080 10081 if (r.crashing || r.forceCrashReport) { 10082 report.type = ApplicationErrorReport.TYPE_CRASH; 10083 report.crashInfo = crashInfo; 10084 } else if (r.notResponding) { 10085 report.type = ApplicationErrorReport.TYPE_ANR; 10086 report.anrInfo = new ApplicationErrorReport.AnrInfo(); 10087 10088 report.anrInfo.activity = r.notRespondingReport.tag; 10089 report.anrInfo.cause = r.notRespondingReport.shortMsg; 10090 report.anrInfo.info = r.notRespondingReport.longMsg; 10091 } 10092 10093 return report; 10094 } 10095 10096 public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() { 10097 enforceNotIsolatedCaller("getProcessesInErrorState"); 10098 // assume our apps are happy - lazy create the list 10099 List<ActivityManager.ProcessErrorStateInfo> errList = null; 10100 10101 final boolean allUsers = ActivityManager.checkUidPermission( 10102 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 10103 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 10104 int userId = UserHandle.getUserId(Binder.getCallingUid()); 10105 10106 synchronized (this) { 10107 10108 // iterate across all processes 10109 for (int i=mLruProcesses.size()-1; i>=0; i--) { 10110 ProcessRecord app = mLruProcesses.get(i); 10111 if (!allUsers && app.userId != userId) { 10112 continue; 10113 } 10114 if ((app.thread != null) && (app.crashing || app.notResponding)) { 10115 // This one's in trouble, so we'll generate a report for it 10116 // crashes are higher priority (in case there's a crash *and* an anr) 10117 ActivityManager.ProcessErrorStateInfo report = null; 10118 if (app.crashing) { 10119 report = app.crashingReport; 10120 } else if (app.notResponding) { 10121 report = app.notRespondingReport; 10122 } 10123 10124 if (report != null) { 10125 if (errList == null) { 10126 errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1); 10127 } 10128 errList.add(report); 10129 } else { 10130 Slog.w(TAG, "Missing app error report, app = " + app.processName + 10131 " crashing = " + app.crashing + 10132 " notResponding = " + app.notResponding); 10133 } 10134 } 10135 } 10136 } 10137 10138 return errList; 10139 } 10140 10141 static int oomAdjToImportance(int adj, ActivityManager.RunningAppProcessInfo currApp) { 10142 if (adj >= ProcessList.CACHED_APP_MIN_ADJ) { 10143 if (currApp != null) { 10144 currApp.lru = adj - ProcessList.CACHED_APP_MIN_ADJ + 1; 10145 } 10146 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 10147 } else if (adj >= ProcessList.SERVICE_B_ADJ) { 10148 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 10149 } else if (adj >= ProcessList.HOME_APP_ADJ) { 10150 if (currApp != null) { 10151 currApp.lru = 0; 10152 } 10153 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 10154 } else if (adj >= ProcessList.SERVICE_ADJ) { 10155 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 10156 } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 10157 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE; 10158 } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) { 10159 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE; 10160 } else if (adj >= ProcessList.VISIBLE_APP_ADJ) { 10161 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE; 10162 } else { 10163 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND; 10164 } 10165 } 10166 10167 private void fillInProcMemInfo(ProcessRecord app, 10168 ActivityManager.RunningAppProcessInfo outInfo) { 10169 outInfo.pid = app.pid; 10170 outInfo.uid = app.info.uid; 10171 if (mHeavyWeightProcess == app) { 10172 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE; 10173 } 10174 if (app.persistent) { 10175 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT; 10176 } 10177 if (app.activities.size() > 0) { 10178 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES; 10179 } 10180 outInfo.lastTrimLevel = app.trimMemoryLevel; 10181 int adj = app.curAdj; 10182 outInfo.importance = oomAdjToImportance(adj, outInfo); 10183 outInfo.importanceReasonCode = app.adjTypeCode; 10184 } 10185 10186 public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() { 10187 enforceNotIsolatedCaller("getRunningAppProcesses"); 10188 // Lazy instantiation of list 10189 List<ActivityManager.RunningAppProcessInfo> runList = null; 10190 final boolean allUsers = ActivityManager.checkUidPermission( 10191 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 10192 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 10193 int userId = UserHandle.getUserId(Binder.getCallingUid()); 10194 synchronized (this) { 10195 // Iterate across all processes 10196 for (int i=mLruProcesses.size()-1; i>=0; i--) { 10197 ProcessRecord app = mLruProcesses.get(i); 10198 if (!allUsers && app.userId != userId) { 10199 continue; 10200 } 10201 if ((app.thread != null) && (!app.crashing && !app.notResponding)) { 10202 // Generate process state info for running application 10203 ActivityManager.RunningAppProcessInfo currApp = 10204 new ActivityManager.RunningAppProcessInfo(app.processName, 10205 app.pid, app.getPackageList()); 10206 fillInProcMemInfo(app, currApp); 10207 if (app.adjSource instanceof ProcessRecord) { 10208 currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid; 10209 currApp.importanceReasonImportance = oomAdjToImportance( 10210 app.adjSourceOom, null); 10211 } else if (app.adjSource instanceof ActivityRecord) { 10212 ActivityRecord r = (ActivityRecord)app.adjSource; 10213 if (r.app != null) currApp.importanceReasonPid = r.app.pid; 10214 } 10215 if (app.adjTarget instanceof ComponentName) { 10216 currApp.importanceReasonComponent = (ComponentName)app.adjTarget; 10217 } 10218 //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance 10219 // + " lru=" + currApp.lru); 10220 if (runList == null) { 10221 runList = new ArrayList<ActivityManager.RunningAppProcessInfo>(); 10222 } 10223 runList.add(currApp); 10224 } 10225 } 10226 } 10227 return runList; 10228 } 10229 10230 public List<ApplicationInfo> getRunningExternalApplications() { 10231 enforceNotIsolatedCaller("getRunningExternalApplications"); 10232 List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses(); 10233 List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>(); 10234 if (runningApps != null && runningApps.size() > 0) { 10235 Set<String> extList = new HashSet<String>(); 10236 for (ActivityManager.RunningAppProcessInfo app : runningApps) { 10237 if (app.pkgList != null) { 10238 for (String pkg : app.pkgList) { 10239 extList.add(pkg); 10240 } 10241 } 10242 } 10243 IPackageManager pm = AppGlobals.getPackageManager(); 10244 for (String pkg : extList) { 10245 try { 10246 ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId()); 10247 if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) { 10248 retList.add(info); 10249 } 10250 } catch (RemoteException e) { 10251 } 10252 } 10253 } 10254 return retList; 10255 } 10256 10257 @Override 10258 public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) { 10259 enforceNotIsolatedCaller("getMyMemoryState"); 10260 synchronized (this) { 10261 ProcessRecord proc; 10262 synchronized (mPidsSelfLocked) { 10263 proc = mPidsSelfLocked.get(Binder.getCallingPid()); 10264 } 10265 fillInProcMemInfo(proc, outInfo); 10266 } 10267 } 10268 10269 @Override 10270 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 10271 if (checkCallingPermission(android.Manifest.permission.DUMP) 10272 != PackageManager.PERMISSION_GRANTED) { 10273 pw.println("Permission Denial: can't dump ActivityManager from from pid=" 10274 + Binder.getCallingPid() 10275 + ", uid=" + Binder.getCallingUid() 10276 + " without permission " 10277 + android.Manifest.permission.DUMP); 10278 return; 10279 } 10280 10281 boolean dumpAll = false; 10282 boolean dumpClient = false; 10283 String dumpPackage = null; 10284 10285 int opti = 0; 10286 while (opti < args.length) { 10287 String opt = args[opti]; 10288 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 10289 break; 10290 } 10291 opti++; 10292 if ("-a".equals(opt)) { 10293 dumpAll = true; 10294 } else if ("-c".equals(opt)) { 10295 dumpClient = true; 10296 } else if ("-h".equals(opt)) { 10297 pw.println("Activity manager dump options:"); 10298 pw.println(" [-a] [-c] [-h] [cmd] ..."); 10299 pw.println(" cmd may be one of:"); 10300 pw.println(" a[ctivities]: activity stack state"); 10301 pw.println(" b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state"); 10302 pw.println(" i[ntents] [PACKAGE_NAME]: pending intent state"); 10303 pw.println(" p[rocesses] [PACKAGE_NAME]: process state"); 10304 pw.println(" o[om]: out of memory management"); 10305 pw.println(" prov[iders] [COMP_SPEC ...]: content provider state"); 10306 pw.println(" provider [COMP_SPEC]: provider client-side state"); 10307 pw.println(" s[ervices] [COMP_SPEC ...]: service state"); 10308 pw.println(" service [COMP_SPEC]: service client-side state"); 10309 pw.println(" package [PACKAGE_NAME]: all state related to given package"); 10310 pw.println(" all: dump all activities"); 10311 pw.println(" top: dump the top activity"); 10312 pw.println(" cmd may also be a COMP_SPEC to dump activities."); 10313 pw.println(" COMP_SPEC may be a component name (com.foo/.myApp),"); 10314 pw.println(" a partial substring in a component name, a"); 10315 pw.println(" hex object identifier."); 10316 pw.println(" -a: include all available server state."); 10317 pw.println(" -c: include client state."); 10318 return; 10319 } else { 10320 pw.println("Unknown argument: " + opt + "; use -h for help"); 10321 } 10322 } 10323 10324 long origId = Binder.clearCallingIdentity(); 10325 boolean more = false; 10326 // Is the caller requesting to dump a particular piece of data? 10327 if (opti < args.length) { 10328 String cmd = args[opti]; 10329 opti++; 10330 if ("activities".equals(cmd) || "a".equals(cmd)) { 10331 synchronized (this) { 10332 dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null); 10333 } 10334 } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) { 10335 String[] newArgs; 10336 String name; 10337 if (opti >= args.length) { 10338 name = null; 10339 newArgs = EMPTY_STRING_ARRAY; 10340 } else { 10341 name = args[opti]; 10342 opti++; 10343 newArgs = new String[args.length - opti]; 10344 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 10345 args.length - opti); 10346 } 10347 synchronized (this) { 10348 dumpBroadcastsLocked(fd, pw, args, opti, true, name); 10349 } 10350 } else if ("intents".equals(cmd) || "i".equals(cmd)) { 10351 String[] newArgs; 10352 String name; 10353 if (opti >= args.length) { 10354 name = null; 10355 newArgs = EMPTY_STRING_ARRAY; 10356 } else { 10357 name = args[opti]; 10358 opti++; 10359 newArgs = new String[args.length - opti]; 10360 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 10361 args.length - opti); 10362 } 10363 synchronized (this) { 10364 dumpPendingIntentsLocked(fd, pw, args, opti, true, name); 10365 } 10366 } else if ("processes".equals(cmd) || "p".equals(cmd)) { 10367 String[] newArgs; 10368 String name; 10369 if (opti >= args.length) { 10370 name = null; 10371 newArgs = EMPTY_STRING_ARRAY; 10372 } else { 10373 name = args[opti]; 10374 opti++; 10375 newArgs = new String[args.length - opti]; 10376 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 10377 args.length - opti); 10378 } 10379 synchronized (this) { 10380 dumpProcessesLocked(fd, pw, args, opti, true, name); 10381 } 10382 } else if ("oom".equals(cmd) || "o".equals(cmd)) { 10383 synchronized (this) { 10384 dumpOomLocked(fd, pw, args, opti, true); 10385 } 10386 } else if ("provider".equals(cmd)) { 10387 String[] newArgs; 10388 String name; 10389 if (opti >= args.length) { 10390 name = null; 10391 newArgs = EMPTY_STRING_ARRAY; 10392 } else { 10393 name = args[opti]; 10394 opti++; 10395 newArgs = new String[args.length - opti]; 10396 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti); 10397 } 10398 if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) { 10399 pw.println("No providers match: " + name); 10400 pw.println("Use -h for help."); 10401 } 10402 } else if ("providers".equals(cmd) || "prov".equals(cmd)) { 10403 synchronized (this) { 10404 dumpProvidersLocked(fd, pw, args, opti, true, null); 10405 } 10406 } else if ("service".equals(cmd)) { 10407 String[] newArgs; 10408 String name; 10409 if (opti >= args.length) { 10410 name = null; 10411 newArgs = EMPTY_STRING_ARRAY; 10412 } else { 10413 name = args[opti]; 10414 opti++; 10415 newArgs = new String[args.length - opti]; 10416 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 10417 args.length - opti); 10418 } 10419 if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) { 10420 pw.println("No services match: " + name); 10421 pw.println("Use -h for help."); 10422 } 10423 } else if ("package".equals(cmd)) { 10424 String[] newArgs; 10425 if (opti >= args.length) { 10426 pw.println("package: no package name specified"); 10427 pw.println("Use -h for help."); 10428 } else { 10429 dumpPackage = args[opti]; 10430 opti++; 10431 newArgs = new String[args.length - opti]; 10432 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 10433 args.length - opti); 10434 args = newArgs; 10435 opti = 0; 10436 more = true; 10437 } 10438 } else if ("services".equals(cmd) || "s".equals(cmd)) { 10439 synchronized (this) { 10440 mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null); 10441 } 10442 } else { 10443 // Dumping a single activity? 10444 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) { 10445 pw.println("Bad activity command, or no activities match: " + cmd); 10446 pw.println("Use -h for help."); 10447 } 10448 } 10449 if (!more) { 10450 Binder.restoreCallingIdentity(origId); 10451 return; 10452 } 10453 } 10454 10455 // No piece of data specified, dump everything. 10456 synchronized (this) { 10457 dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 10458 pw.println(); 10459 if (dumpAll) { 10460 pw.println("-------------------------------------------------------------------------------"); 10461 } 10462 dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 10463 pw.println(); 10464 if (dumpAll) { 10465 pw.println("-------------------------------------------------------------------------------"); 10466 } 10467 dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage); 10468 pw.println(); 10469 if (dumpAll) { 10470 pw.println("-------------------------------------------------------------------------------"); 10471 } 10472 mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 10473 pw.println(); 10474 if (dumpAll) { 10475 pw.println("-------------------------------------------------------------------------------"); 10476 } 10477 dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 10478 pw.println(); 10479 if (dumpAll) { 10480 pw.println("-------------------------------------------------------------------------------"); 10481 } 10482 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage); 10483 } 10484 Binder.restoreCallingIdentity(origId); 10485 } 10486 10487 void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 10488 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) { 10489 pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)"); 10490 10491 boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient, 10492 dumpPackage); 10493 boolean needSep = printedAnything; 10494 10495 boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity, 10496 dumpPackage, needSep, " mFocusedActivity: "); 10497 if (printed) { 10498 printedAnything = true; 10499 needSep = false; 10500 } 10501 10502 if (dumpPackage == null) { 10503 if (needSep) { 10504 pw.println(); 10505 } 10506 needSep = true; 10507 printedAnything = true; 10508 mStackSupervisor.dump(pw, " "); 10509 } 10510 10511 if (mRecentTasks.size() > 0) { 10512 boolean printedHeader = false; 10513 10514 final int N = mRecentTasks.size(); 10515 for (int i=0; i<N; i++) { 10516 TaskRecord tr = mRecentTasks.get(i); 10517 if (dumpPackage != null) { 10518 if (tr.realActivity == null || 10519 !dumpPackage.equals(tr.realActivity)) { 10520 continue; 10521 } 10522 } 10523 if (!printedHeader) { 10524 if (needSep) { 10525 pw.println(); 10526 } 10527 pw.println(" Recent tasks:"); 10528 printedHeader = true; 10529 printedAnything = true; 10530 } 10531 pw.print(" * Recent #"); pw.print(i); pw.print(": "); 10532 pw.println(tr); 10533 if (dumpAll) { 10534 mRecentTasks.get(i).dump(pw, " "); 10535 } 10536 } 10537 } 10538 10539 if (!printedAnything) { 10540 pw.println(" (nothing)"); 10541 } 10542 } 10543 10544 void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 10545 int opti, boolean dumpAll, String dumpPackage) { 10546 boolean needSep = false; 10547 boolean printedAnything = false; 10548 int numPers = 0; 10549 10550 pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)"); 10551 10552 if (dumpAll) { 10553 final int NP = mProcessNames.getMap().size(); 10554 for (int ip=0; ip<NP; ip++) { 10555 SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip); 10556 final int NA = procs.size(); 10557 for (int ia=0; ia<NA; ia++) { 10558 ProcessRecord r = procs.valueAt(ia); 10559 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 10560 continue; 10561 } 10562 if (!needSep) { 10563 pw.println(" All known processes:"); 10564 needSep = true; 10565 printedAnything = true; 10566 } 10567 pw.print(r.persistent ? " *PERS*" : " *APP*"); 10568 pw.print(" UID "); pw.print(procs.keyAt(ia)); 10569 pw.print(" "); pw.println(r); 10570 r.dump(pw, " "); 10571 if (r.persistent) { 10572 numPers++; 10573 } 10574 } 10575 } 10576 } 10577 10578 if (mIsolatedProcesses.size() > 0) { 10579 boolean printed = false; 10580 for (int i=0; i<mIsolatedProcesses.size(); i++) { 10581 ProcessRecord r = mIsolatedProcesses.valueAt(i); 10582 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 10583 continue; 10584 } 10585 if (!printed) { 10586 if (needSep) { 10587 pw.println(); 10588 } 10589 pw.println(" Isolated process list (sorted by uid):"); 10590 printedAnything = true; 10591 printed = true; 10592 needSep = true; 10593 } 10594 pw.println(String.format("%sIsolated #%2d: %s", 10595 " ", i, r.toString())); 10596 } 10597 } 10598 10599 if (mLruProcesses.size() > 0) { 10600 if (needSep) { 10601 pw.println(); 10602 } 10603 pw.print(" Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size()); 10604 pw.print(" total, non-act at "); 10605 pw.print(mLruProcesses.size()-mLruProcessActivityStart); 10606 pw.print(", non-svc at "); 10607 pw.print(mLruProcesses.size()-mLruProcessServiceStart); 10608 pw.println("):"); 10609 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", false, dumpPackage); 10610 needSep = true; 10611 printedAnything = true; 10612 } 10613 10614 if (dumpAll || dumpPackage != null) { 10615 synchronized (mPidsSelfLocked) { 10616 boolean printed = false; 10617 for (int i=0; i<mPidsSelfLocked.size(); i++) { 10618 ProcessRecord r = mPidsSelfLocked.valueAt(i); 10619 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 10620 continue; 10621 } 10622 if (!printed) { 10623 if (needSep) pw.println(); 10624 needSep = true; 10625 pw.println(" PID mappings:"); 10626 printed = true; 10627 printedAnything = true; 10628 } 10629 pw.print(" PID #"); pw.print(mPidsSelfLocked.keyAt(i)); 10630 pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i)); 10631 } 10632 } 10633 } 10634 10635 if (mForegroundProcesses.size() > 0) { 10636 synchronized (mPidsSelfLocked) { 10637 boolean printed = false; 10638 for (int i=0; i<mForegroundProcesses.size(); i++) { 10639 ProcessRecord r = mPidsSelfLocked.get( 10640 mForegroundProcesses.valueAt(i).pid); 10641 if (dumpPackage != null && (r == null 10642 || !r.pkgList.containsKey(dumpPackage))) { 10643 continue; 10644 } 10645 if (!printed) { 10646 if (needSep) pw.println(); 10647 needSep = true; 10648 pw.println(" Foreground Processes:"); 10649 printed = true; 10650 printedAnything = true; 10651 } 10652 pw.print(" PID #"); pw.print(mForegroundProcesses.keyAt(i)); 10653 pw.print(": "); pw.println(mForegroundProcesses.valueAt(i)); 10654 } 10655 } 10656 } 10657 10658 if (mPersistentStartingProcesses.size() > 0) { 10659 if (needSep) pw.println(); 10660 needSep = true; 10661 printedAnything = true; 10662 pw.println(" Persisent processes that are starting:"); 10663 dumpProcessList(pw, this, mPersistentStartingProcesses, " ", 10664 "Starting Norm", "Restarting PERS", dumpPackage); 10665 } 10666 10667 if (mRemovedProcesses.size() > 0) { 10668 if (needSep) pw.println(); 10669 needSep = true; 10670 printedAnything = true; 10671 pw.println(" Processes that are being removed:"); 10672 dumpProcessList(pw, this, mRemovedProcesses, " ", 10673 "Removed Norm", "Removed PERS", dumpPackage); 10674 } 10675 10676 if (mProcessesOnHold.size() > 0) { 10677 if (needSep) pw.println(); 10678 needSep = true; 10679 printedAnything = true; 10680 pw.println(" Processes that are on old until the system is ready:"); 10681 dumpProcessList(pw, this, mProcessesOnHold, " ", 10682 "OnHold Norm", "OnHold PERS", dumpPackage); 10683 } 10684 10685 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage); 10686 10687 if (mProcessCrashTimes.getMap().size() > 0) { 10688 boolean printed = false; 10689 long now = SystemClock.uptimeMillis(); 10690 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap(); 10691 final int NP = pmap.size(); 10692 for (int ip=0; ip<NP; ip++) { 10693 String pname = pmap.keyAt(ip); 10694 SparseArray<Long> uids = pmap.valueAt(ip); 10695 final int N = uids.size(); 10696 for (int i=0; i<N; i++) { 10697 int puid = uids.keyAt(i); 10698 ProcessRecord r = mProcessNames.get(pname, puid); 10699 if (dumpPackage != null && (r == null 10700 || !r.pkgList.containsKey(dumpPackage))) { 10701 continue; 10702 } 10703 if (!printed) { 10704 if (needSep) pw.println(); 10705 needSep = true; 10706 pw.println(" Time since processes crashed:"); 10707 printed = true; 10708 printedAnything = true; 10709 } 10710 pw.print(" Process "); pw.print(pname); 10711 pw.print(" uid "); pw.print(puid); 10712 pw.print(": last crashed "); 10713 TimeUtils.formatDuration(now-uids.valueAt(i), pw); 10714 pw.println(" ago"); 10715 } 10716 } 10717 } 10718 10719 if (mBadProcesses.getMap().size() > 0) { 10720 boolean printed = false; 10721 final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap(); 10722 final int NP = pmap.size(); 10723 for (int ip=0; ip<NP; ip++) { 10724 String pname = pmap.keyAt(ip); 10725 SparseArray<BadProcessInfo> uids = pmap.valueAt(ip); 10726 final int N = uids.size(); 10727 for (int i=0; i<N; i++) { 10728 int puid = uids.keyAt(i); 10729 ProcessRecord r = mProcessNames.get(pname, puid); 10730 if (dumpPackage != null && (r == null 10731 || !r.pkgList.containsKey(dumpPackage))) { 10732 continue; 10733 } 10734 if (!printed) { 10735 if (needSep) pw.println(); 10736 needSep = true; 10737 pw.println(" Bad processes:"); 10738 printedAnything = true; 10739 } 10740 BadProcessInfo info = uids.valueAt(i); 10741 pw.print(" Bad process "); pw.print(pname); 10742 pw.print(" uid "); pw.print(puid); 10743 pw.print(": crashed at time "); pw.println(info.time); 10744 if (info.shortMsg != null) { 10745 pw.print(" Short msg: "); pw.println(info.shortMsg); 10746 } 10747 if (info.longMsg != null) { 10748 pw.print(" Long msg: "); pw.println(info.longMsg); 10749 } 10750 if (info.stack != null) { 10751 pw.println(" Stack:"); 10752 int lastPos = 0; 10753 for (int pos=0; pos<info.stack.length(); pos++) { 10754 if (info.stack.charAt(pos) == '\n') { 10755 pw.print(" "); 10756 pw.write(info.stack, lastPos, pos-lastPos); 10757 pw.println(); 10758 lastPos = pos+1; 10759 } 10760 } 10761 if (lastPos < info.stack.length()) { 10762 pw.print(" "); 10763 pw.write(info.stack, lastPos, info.stack.length()-lastPos); 10764 pw.println(); 10765 } 10766 } 10767 } 10768 } 10769 } 10770 10771 if (dumpPackage == null) { 10772 pw.println(); 10773 needSep = false; 10774 pw.println(" mStartedUsers:"); 10775 for (int i=0; i<mStartedUsers.size(); i++) { 10776 UserStartedState uss = mStartedUsers.valueAt(i); 10777 pw.print(" User #"); pw.print(uss.mHandle.getIdentifier()); 10778 pw.print(": "); uss.dump("", pw); 10779 } 10780 pw.print(" mStartedUserArray: ["); 10781 for (int i=0; i<mStartedUserArray.length; i++) { 10782 if (i > 0) pw.print(", "); 10783 pw.print(mStartedUserArray[i]); 10784 } 10785 pw.println("]"); 10786 pw.print(" mUserLru: ["); 10787 for (int i=0; i<mUserLru.size(); i++) { 10788 if (i > 0) pw.print(", "); 10789 pw.print(mUserLru.get(i)); 10790 } 10791 pw.println("]"); 10792 if (dumpAll) { 10793 pw.print(" mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray)); 10794 } 10795 } 10796 if (mHomeProcess != null && (dumpPackage == null 10797 || mHomeProcess.pkgList.containsKey(dumpPackage))) { 10798 if (needSep) { 10799 pw.println(); 10800 needSep = false; 10801 } 10802 pw.println(" mHomeProcess: " + mHomeProcess); 10803 } 10804 if (mPreviousProcess != null && (dumpPackage == null 10805 || mPreviousProcess.pkgList.containsKey(dumpPackage))) { 10806 if (needSep) { 10807 pw.println(); 10808 needSep = false; 10809 } 10810 pw.println(" mPreviousProcess: " + mPreviousProcess); 10811 } 10812 if (dumpAll) { 10813 StringBuilder sb = new StringBuilder(128); 10814 sb.append(" mPreviousProcessVisibleTime: "); 10815 TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb); 10816 pw.println(sb); 10817 } 10818 if (mHeavyWeightProcess != null && (dumpPackage == null 10819 || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) { 10820 if (needSep) { 10821 pw.println(); 10822 needSep = false; 10823 } 10824 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 10825 } 10826 if (dumpPackage == null) { 10827 pw.println(" mConfiguration: " + mConfiguration); 10828 } 10829 if (dumpAll) { 10830 pw.println(" mConfigWillChange: " + getFocusedStack().mConfigWillChange); 10831 if (mCompatModePackages.getPackages().size() > 0) { 10832 boolean printed = false; 10833 for (Map.Entry<String, Integer> entry 10834 : mCompatModePackages.getPackages().entrySet()) { 10835 String pkg = entry.getKey(); 10836 int mode = entry.getValue(); 10837 if (dumpPackage != null && !dumpPackage.equals(pkg)) { 10838 continue; 10839 } 10840 if (!printed) { 10841 pw.println(" mScreenCompatPackages:"); 10842 printed = true; 10843 } 10844 pw.print(" "); pw.print(pkg); pw.print(": "); 10845 pw.print(mode); pw.println(); 10846 } 10847 } 10848 } 10849 if (dumpPackage == null) { 10850 if (mSleeping || mWentToSleep || mLockScreenShown) { 10851 pw.println(" mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep 10852 + " mLockScreenShown " + mLockScreenShown); 10853 } 10854 if (mShuttingDown) { 10855 pw.println(" mShuttingDown=" + mShuttingDown); 10856 } 10857 } 10858 if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient 10859 || mOrigWaitForDebugger) { 10860 if (dumpPackage == null || dumpPackage.equals(mDebugApp) 10861 || dumpPackage.equals(mOrigDebugApp)) { 10862 if (needSep) { 10863 pw.println(); 10864 needSep = false; 10865 } 10866 pw.println(" mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp 10867 + " mDebugTransient=" + mDebugTransient 10868 + " mOrigWaitForDebugger=" + mOrigWaitForDebugger); 10869 } 10870 } 10871 if (mOpenGlTraceApp != null) { 10872 if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) { 10873 if (needSep) { 10874 pw.println(); 10875 needSep = false; 10876 } 10877 pw.println(" mOpenGlTraceApp=" + mOpenGlTraceApp); 10878 } 10879 } 10880 if (mProfileApp != null || mProfileProc != null || mProfileFile != null 10881 || mProfileFd != null) { 10882 if (dumpPackage == null || dumpPackage.equals(mProfileApp)) { 10883 if (needSep) { 10884 pw.println(); 10885 needSep = false; 10886 } 10887 pw.println(" mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc); 10888 pw.println(" mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd); 10889 pw.println(" mProfileType=" + mProfileType + " mAutoStopProfiler=" 10890 + mAutoStopProfiler); 10891 } 10892 } 10893 if (dumpPackage == null) { 10894 if (mAlwaysFinishActivities || mController != null) { 10895 pw.println(" mAlwaysFinishActivities=" + mAlwaysFinishActivities 10896 + " mController=" + mController); 10897 } 10898 if (dumpAll) { 10899 pw.println(" Total persistent processes: " + numPers); 10900 pw.println(" mProcessesReady=" + mProcessesReady 10901 + " mSystemReady=" + mSystemReady); 10902 pw.println(" mBooting=" + mBooting 10903 + " mBooted=" + mBooted 10904 + " mFactoryTest=" + mFactoryTest); 10905 pw.print(" mLastPowerCheckRealtime="); 10906 TimeUtils.formatDuration(mLastPowerCheckRealtime, pw); 10907 pw.println(""); 10908 pw.print(" mLastPowerCheckUptime="); 10909 TimeUtils.formatDuration(mLastPowerCheckUptime, pw); 10910 pw.println(""); 10911 pw.println(" mGoingToSleep=" + mStackSupervisor.mGoingToSleep); 10912 pw.println(" mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity); 10913 pw.println(" mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq); 10914 pw.println(" mNumNonCachedProcs=" + mNumNonCachedProcs 10915 + " (" + mLruProcesses.size() + " total)" 10916 + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs 10917 + " mNumServiceProcs=" + mNumServiceProcs 10918 + " mNewNumServiceProcs=" + mNewNumServiceProcs); 10919 pw.println(" mAllowLowerMemLevel=" + mAllowLowerMemLevel 10920 + " mLastMemoryLevel" + mLastMemoryLevel 10921 + " mLastNumProcesses" + mLastNumProcesses); 10922 long now = SystemClock.uptimeMillis(); 10923 pw.print(" mLastIdleTime="); 10924 TimeUtils.formatDuration(now, mLastIdleTime, pw); 10925 pw.print(" mLowRamSinceLastIdle="); 10926 TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw); 10927 pw.println(); 10928 } 10929 } 10930 10931 if (!printedAnything) { 10932 pw.println(" (nothing)"); 10933 } 10934 } 10935 10936 boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args, 10937 int opti, boolean needSep, boolean dumpAll, String dumpPackage) { 10938 if (mProcessesToGc.size() > 0) { 10939 boolean printed = false; 10940 long now = SystemClock.uptimeMillis(); 10941 for (int i=0; i<mProcessesToGc.size(); i++) { 10942 ProcessRecord proc = mProcessesToGc.get(i); 10943 if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) { 10944 continue; 10945 } 10946 if (!printed) { 10947 if (needSep) pw.println(); 10948 needSep = true; 10949 pw.println(" Processes that are waiting to GC:"); 10950 printed = true; 10951 } 10952 pw.print(" Process "); pw.println(proc); 10953 pw.print(" lowMem="); pw.print(proc.reportLowMemory); 10954 pw.print(", last gced="); 10955 pw.print(now-proc.lastRequestedGc); 10956 pw.print(" ms ago, last lowMem="); 10957 pw.print(now-proc.lastLowMemory); 10958 pw.println(" ms ago"); 10959 10960 } 10961 } 10962 return needSep; 10963 } 10964 10965 void printOomLevel(PrintWriter pw, String name, int adj) { 10966 pw.print(" "); 10967 if (adj >= 0) { 10968 pw.print(' '); 10969 if (adj < 10) pw.print(' '); 10970 } else { 10971 if (adj > -10) pw.print(' '); 10972 } 10973 pw.print(adj); 10974 pw.print(": "); 10975 pw.print(name); 10976 pw.print(" ("); 10977 pw.print(mProcessList.getMemLevel(adj)/1024); 10978 pw.println(" kB)"); 10979 } 10980 10981 boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args, 10982 int opti, boolean dumpAll) { 10983 boolean needSep = false; 10984 10985 if (mLruProcesses.size() > 0) { 10986 if (needSep) pw.println(); 10987 needSep = true; 10988 pw.println(" OOM levels:"); 10989 printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ); 10990 printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ); 10991 printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ); 10992 printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ); 10993 printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ); 10994 printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ); 10995 printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ); 10996 printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ); 10997 printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ); 10998 printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ); 10999 printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ); 11000 printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ); 11001 printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ); 11002 11003 if (needSep) pw.println(); 11004 pw.print(" Process OOM control ("); pw.print(mLruProcesses.size()); 11005 pw.print(" total, non-act at "); 11006 pw.print(mLruProcesses.size()-mLruProcessActivityStart); 11007 pw.print(", non-svc at "); 11008 pw.print(mLruProcesses.size()-mLruProcessServiceStart); 11009 pw.println("):"); 11010 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", true, null); 11011 needSep = true; 11012 } 11013 11014 dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null); 11015 11016 pw.println(); 11017 pw.println(" mHomeProcess: " + mHomeProcess); 11018 pw.println(" mPreviousProcess: " + mPreviousProcess); 11019 if (mHeavyWeightProcess != null) { 11020 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 11021 } 11022 11023 return true; 11024 } 11025 11026 /** 11027 * There are three ways to call this: 11028 * - no provider specified: dump all the providers 11029 * - a flattened component name that matched an existing provider was specified as the 11030 * first arg: dump that one provider 11031 * - the first arg isn't the flattened component name of an existing provider: 11032 * dump all providers whose component contains the first arg as a substring 11033 */ 11034 protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args, 11035 int opti, boolean dumpAll) { 11036 return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll); 11037 } 11038 11039 static class ItemMatcher { 11040 ArrayList<ComponentName> components; 11041 ArrayList<String> strings; 11042 ArrayList<Integer> objects; 11043 boolean all; 11044 11045 ItemMatcher() { 11046 all = true; 11047 } 11048 11049 void build(String name) { 11050 ComponentName componentName = ComponentName.unflattenFromString(name); 11051 if (componentName != null) { 11052 if (components == null) { 11053 components = new ArrayList<ComponentName>(); 11054 } 11055 components.add(componentName); 11056 all = false; 11057 } else { 11058 int objectId = 0; 11059 // Not a '/' separated full component name; maybe an object ID? 11060 try { 11061 objectId = Integer.parseInt(name, 16); 11062 if (objects == null) { 11063 objects = new ArrayList<Integer>(); 11064 } 11065 objects.add(objectId); 11066 all = false; 11067 } catch (RuntimeException e) { 11068 // Not an integer; just do string match. 11069 if (strings == null) { 11070 strings = new ArrayList<String>(); 11071 } 11072 strings.add(name); 11073 all = false; 11074 } 11075 } 11076 } 11077 11078 int build(String[] args, int opti) { 11079 for (; opti<args.length; opti++) { 11080 String name = args[opti]; 11081 if ("--".equals(name)) { 11082 return opti+1; 11083 } 11084 build(name); 11085 } 11086 return opti; 11087 } 11088 11089 boolean match(Object object, ComponentName comp) { 11090 if (all) { 11091 return true; 11092 } 11093 if (components != null) { 11094 for (int i=0; i<components.size(); i++) { 11095 if (components.get(i).equals(comp)) { 11096 return true; 11097 } 11098 } 11099 } 11100 if (objects != null) { 11101 for (int i=0; i<objects.size(); i++) { 11102 if (System.identityHashCode(object) == objects.get(i)) { 11103 return true; 11104 } 11105 } 11106 } 11107 if (strings != null) { 11108 String flat = comp.flattenToString(); 11109 for (int i=0; i<strings.size(); i++) { 11110 if (flat.contains(strings.get(i))) { 11111 return true; 11112 } 11113 } 11114 } 11115 return false; 11116 } 11117 } 11118 11119 /** 11120 * There are three things that cmd can be: 11121 * - a flattened component name that matches an existing activity 11122 * - the cmd arg isn't the flattened component name of an existing activity: 11123 * dump all activity whose component contains the cmd as a substring 11124 * - A hex number of the ActivityRecord object instance. 11125 */ 11126 protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args, 11127 int opti, boolean dumpAll) { 11128 ArrayList<ActivityRecord> activities; 11129 11130 synchronized (this) { 11131 activities = mStackSupervisor.getDumpActivitiesLocked(name); 11132 } 11133 11134 if (activities.size() <= 0) { 11135 return false; 11136 } 11137 11138 String[] newArgs = new String[args.length - opti]; 11139 System.arraycopy(args, opti, newArgs, 0, args.length - opti); 11140 11141 TaskRecord lastTask = null; 11142 boolean needSep = false; 11143 for (int i=activities.size()-1; i>=0; i--) { 11144 ActivityRecord r = activities.get(i); 11145 if (needSep) { 11146 pw.println(); 11147 } 11148 needSep = true; 11149 synchronized (this) { 11150 if (lastTask != r.task) { 11151 lastTask = r.task; 11152 pw.print("TASK "); pw.print(lastTask.affinity); 11153 pw.print(" id="); pw.println(lastTask.taskId); 11154 if (dumpAll) { 11155 lastTask.dump(pw, " "); 11156 } 11157 } 11158 } 11159 dumpActivity(" ", fd, pw, activities.get(i), newArgs, dumpAll); 11160 } 11161 return true; 11162 } 11163 11164 /** 11165 * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if 11166 * there is a thread associated with the activity. 11167 */ 11168 private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw, 11169 final ActivityRecord r, String[] args, boolean dumpAll) { 11170 String innerPrefix = prefix + " "; 11171 synchronized (this) { 11172 pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName); 11173 pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r))); 11174 pw.print(" pid="); 11175 if (r.app != null) pw.println(r.app.pid); 11176 else pw.println("(not running)"); 11177 if (dumpAll) { 11178 r.dump(pw, innerPrefix); 11179 } 11180 } 11181 if (r.app != null && r.app.thread != null) { 11182 // flush anything that is already in the PrintWriter since the thread is going 11183 // to write to the file descriptor directly 11184 pw.flush(); 11185 try { 11186 TransferPipe tp = new TransferPipe(); 11187 try { 11188 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(), 11189 r.appToken, innerPrefix, args); 11190 tp.go(fd); 11191 } finally { 11192 tp.kill(); 11193 } 11194 } catch (IOException e) { 11195 pw.println(innerPrefix + "Failure while dumping the activity: " + e); 11196 } catch (RemoteException e) { 11197 pw.println(innerPrefix + "Got a RemoteException while dumping the activity"); 11198 } 11199 } 11200 } 11201 11202 void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 11203 int opti, boolean dumpAll, String dumpPackage) { 11204 boolean needSep = false; 11205 boolean onlyHistory = false; 11206 boolean printedAnything = false; 11207 11208 if ("history".equals(dumpPackage)) { 11209 if (opti < args.length && "-s".equals(args[opti])) { 11210 dumpAll = false; 11211 } 11212 onlyHistory = true; 11213 dumpPackage = null; 11214 } 11215 11216 pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)"); 11217 if (!onlyHistory && dumpAll) { 11218 if (mRegisteredReceivers.size() > 0) { 11219 boolean printed = false; 11220 Iterator it = mRegisteredReceivers.values().iterator(); 11221 while (it.hasNext()) { 11222 ReceiverList r = (ReceiverList)it.next(); 11223 if (dumpPackage != null && (r.app == null || 11224 !dumpPackage.equals(r.app.info.packageName))) { 11225 continue; 11226 } 11227 if (!printed) { 11228 pw.println(" Registered Receivers:"); 11229 needSep = true; 11230 printed = true; 11231 printedAnything = true; 11232 } 11233 pw.print(" * "); pw.println(r); 11234 r.dump(pw, " "); 11235 } 11236 } 11237 11238 if (mReceiverResolver.dump(pw, needSep ? 11239 "\n Receiver Resolver Table:" : " Receiver Resolver Table:", 11240 " ", dumpPackage, false)) { 11241 needSep = true; 11242 printedAnything = true; 11243 } 11244 } 11245 11246 for (BroadcastQueue q : mBroadcastQueues) { 11247 needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep); 11248 printedAnything |= needSep; 11249 } 11250 11251 needSep = true; 11252 11253 if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) { 11254 for (int user=0; user<mStickyBroadcasts.size(); user++) { 11255 if (needSep) { 11256 pw.println(); 11257 } 11258 needSep = true; 11259 printedAnything = true; 11260 pw.print(" Sticky broadcasts for user "); 11261 pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":"); 11262 StringBuilder sb = new StringBuilder(128); 11263 for (Map.Entry<String, ArrayList<Intent>> ent 11264 : mStickyBroadcasts.valueAt(user).entrySet()) { 11265 pw.print(" * Sticky action "); pw.print(ent.getKey()); 11266 if (dumpAll) { 11267 pw.println(":"); 11268 ArrayList<Intent> intents = ent.getValue(); 11269 final int N = intents.size(); 11270 for (int i=0; i<N; i++) { 11271 sb.setLength(0); 11272 sb.append(" Intent: "); 11273 intents.get(i).toShortString(sb, false, true, false, false); 11274 pw.println(sb.toString()); 11275 Bundle bundle = intents.get(i).getExtras(); 11276 if (bundle != null) { 11277 pw.print(" "); 11278 pw.println(bundle.toString()); 11279 } 11280 } 11281 } else { 11282 pw.println(""); 11283 } 11284 } 11285 } 11286 } 11287 11288 if (!onlyHistory && dumpAll) { 11289 pw.println(); 11290 for (BroadcastQueue queue : mBroadcastQueues) { 11291 pw.println(" mBroadcastsScheduled [" + queue.mQueueName + "]=" 11292 + queue.mBroadcastsScheduled); 11293 } 11294 pw.println(" mHandler:"); 11295 mHandler.dump(new PrintWriterPrinter(pw), " "); 11296 needSep = true; 11297 printedAnything = true; 11298 } 11299 11300 if (!printedAnything) { 11301 pw.println(" (nothing)"); 11302 } 11303 } 11304 11305 void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args, 11306 int opti, boolean dumpAll, String dumpPackage) { 11307 boolean needSep; 11308 boolean printedAnything = false; 11309 11310 ItemMatcher matcher = new ItemMatcher(); 11311 matcher.build(args, opti); 11312 11313 pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)"); 11314 11315 needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage); 11316 printedAnything |= needSep; 11317 11318 if (mLaunchingProviders.size() > 0) { 11319 boolean printed = false; 11320 for (int i=mLaunchingProviders.size()-1; i>=0; i--) { 11321 ContentProviderRecord r = mLaunchingProviders.get(i); 11322 if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) { 11323 continue; 11324 } 11325 if (!printed) { 11326 if (needSep) pw.println(); 11327 needSep = true; 11328 pw.println(" Launching content providers:"); 11329 printed = true; 11330 printedAnything = true; 11331 } 11332 pw.print(" Launching #"); pw.print(i); pw.print(": "); 11333 pw.println(r); 11334 } 11335 } 11336 11337 if (mGrantedUriPermissions.size() > 0) { 11338 boolean printed = false; 11339 int dumpUid = -2; 11340 if (dumpPackage != null) { 11341 try { 11342 dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0); 11343 } catch (NameNotFoundException e) { 11344 dumpUid = -1; 11345 } 11346 } 11347 for (int i=0; i<mGrantedUriPermissions.size(); i++) { 11348 int uid = mGrantedUriPermissions.keyAt(i); 11349 if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) { 11350 continue; 11351 } 11352 ArrayMap<Uri, UriPermission> perms 11353 = mGrantedUriPermissions.valueAt(i); 11354 if (!printed) { 11355 if (needSep) pw.println(); 11356 needSep = true; 11357 pw.println(" Granted Uri Permissions:"); 11358 printed = true; 11359 printedAnything = true; 11360 } 11361 pw.print(" * UID "); pw.print(uid); 11362 pw.println(" holds:"); 11363 for (UriPermission perm : perms.values()) { 11364 pw.print(" "); pw.println(perm); 11365 if (dumpAll) { 11366 perm.dump(pw, " "); 11367 } 11368 } 11369 } 11370 } 11371 11372 if (!printedAnything) { 11373 pw.println(" (nothing)"); 11374 } 11375 } 11376 11377 void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 11378 int opti, boolean dumpAll, String dumpPackage) { 11379 boolean printed = false; 11380 11381 pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)"); 11382 11383 if (mIntentSenderRecords.size() > 0) { 11384 Iterator<WeakReference<PendingIntentRecord>> it 11385 = mIntentSenderRecords.values().iterator(); 11386 while (it.hasNext()) { 11387 WeakReference<PendingIntentRecord> ref = it.next(); 11388 PendingIntentRecord rec = ref != null ? ref.get(): null; 11389 if (dumpPackage != null && (rec == null 11390 || !dumpPackage.equals(rec.key.packageName))) { 11391 continue; 11392 } 11393 printed = true; 11394 if (rec != null) { 11395 pw.print(" * "); pw.println(rec); 11396 if (dumpAll) { 11397 rec.dump(pw, " "); 11398 } 11399 } else { 11400 pw.print(" * "); pw.println(ref); 11401 } 11402 } 11403 } 11404 11405 if (!printed) { 11406 pw.println(" (nothing)"); 11407 } 11408 } 11409 11410 private static final int dumpProcessList(PrintWriter pw, 11411 ActivityManagerService service, List list, 11412 String prefix, String normalLabel, String persistentLabel, 11413 String dumpPackage) { 11414 int numPers = 0; 11415 final int N = list.size()-1; 11416 for (int i=N; i>=0; i--) { 11417 ProcessRecord r = (ProcessRecord)list.get(i); 11418 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 11419 continue; 11420 } 11421 pw.println(String.format("%s%s #%2d: %s", 11422 prefix, (r.persistent ? persistentLabel : normalLabel), 11423 i, r.toString())); 11424 if (r.persistent) { 11425 numPers++; 11426 } 11427 } 11428 return numPers; 11429 } 11430 11431 private static final boolean dumpProcessOomList(PrintWriter pw, 11432 ActivityManagerService service, List<ProcessRecord> origList, 11433 String prefix, String normalLabel, String persistentLabel, 11434 boolean inclDetails, String dumpPackage) { 11435 11436 ArrayList<Pair<ProcessRecord, Integer>> list 11437 = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size()); 11438 for (int i=0; i<origList.size(); i++) { 11439 ProcessRecord r = origList.get(i); 11440 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 11441 continue; 11442 } 11443 list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i)); 11444 } 11445 11446 if (list.size() <= 0) { 11447 return false; 11448 } 11449 11450 Comparator<Pair<ProcessRecord, Integer>> comparator 11451 = new Comparator<Pair<ProcessRecord, Integer>>() { 11452 @Override 11453 public int compare(Pair<ProcessRecord, Integer> object1, 11454 Pair<ProcessRecord, Integer> object2) { 11455 if (object1.first.setAdj != object2.first.setAdj) { 11456 return object1.first.setAdj > object2.first.setAdj ? -1 : 1; 11457 } 11458 if (object1.second.intValue() != object2.second.intValue()) { 11459 return object1.second.intValue() > object2.second.intValue() ? -1 : 1; 11460 } 11461 return 0; 11462 } 11463 }; 11464 11465 Collections.sort(list, comparator); 11466 11467 final long curRealtime = SystemClock.elapsedRealtime(); 11468 final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime; 11469 final long curUptime = SystemClock.uptimeMillis(); 11470 final long uptimeSince = curUptime - service.mLastPowerCheckUptime; 11471 11472 for (int i=list.size()-1; i>=0; i--) { 11473 ProcessRecord r = list.get(i).first; 11474 String oomAdj = ProcessList.makeOomAdjString(r.setAdj); 11475 char schedGroup; 11476 switch (r.setSchedGroup) { 11477 case Process.THREAD_GROUP_BG_NONINTERACTIVE: 11478 schedGroup = 'B'; 11479 break; 11480 case Process.THREAD_GROUP_DEFAULT: 11481 schedGroup = 'F'; 11482 break; 11483 default: 11484 schedGroup = '?'; 11485 break; 11486 } 11487 char foreground; 11488 if (r.foregroundActivities) { 11489 foreground = 'A'; 11490 } else if (r.foregroundServices) { 11491 foreground = 'S'; 11492 } else { 11493 foreground = ' '; 11494 } 11495 String procState = ProcessList.makeProcStateString(r.curProcState); 11496 pw.print(prefix); 11497 pw.print(r.persistent ? persistentLabel : normalLabel); 11498 pw.print(" #"); 11499 int num = (origList.size()-1)-list.get(i).second; 11500 if (num < 10) pw.print(' '); 11501 pw.print(num); 11502 pw.print(": "); 11503 pw.print(oomAdj); 11504 pw.print(' '); 11505 pw.print(schedGroup); 11506 pw.print('/'); 11507 pw.print(foreground); 11508 pw.print('/'); 11509 pw.print(procState); 11510 pw.print(" trm:"); 11511 if (r.trimMemoryLevel < 10) pw.print(' '); 11512 pw.print(r.trimMemoryLevel); 11513 pw.print(' '); 11514 pw.print(r.toShortString()); 11515 pw.print(" ("); 11516 pw.print(r.adjType); 11517 pw.println(')'); 11518 if (r.adjSource != null || r.adjTarget != null) { 11519 pw.print(prefix); 11520 pw.print(" "); 11521 if (r.adjTarget instanceof ComponentName) { 11522 pw.print(((ComponentName)r.adjTarget).flattenToShortString()); 11523 } else if (r.adjTarget != null) { 11524 pw.print(r.adjTarget.toString()); 11525 } else { 11526 pw.print("{null}"); 11527 } 11528 pw.print("<="); 11529 if (r.adjSource instanceof ProcessRecord) { 11530 pw.print("Proc{"); 11531 pw.print(((ProcessRecord)r.adjSource).toShortString()); 11532 pw.println("}"); 11533 } else if (r.adjSource != null) { 11534 pw.println(r.adjSource.toString()); 11535 } else { 11536 pw.println("{null}"); 11537 } 11538 } 11539 if (inclDetails) { 11540 pw.print(prefix); 11541 pw.print(" "); 11542 pw.print("oom: max="); pw.print(r.maxAdj); 11543 pw.print(" curRaw="); pw.print(r.curRawAdj); 11544 pw.print(" setRaw="); pw.print(r.setRawAdj); 11545 pw.print(" cur="); pw.print(r.curAdj); 11546 pw.print(" set="); pw.println(r.setAdj); 11547 pw.print(prefix); 11548 pw.print(" "); 11549 pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState)); 11550 pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState)); 11551 pw.print(" lastPss="); pw.print(r.lastPss); 11552 pw.print(" lastCachedPss="); pw.println(r.lastCachedPss); 11553 pw.print(prefix); 11554 pw.print(" "); 11555 pw.print("keeping="); pw.print(r.keeping); 11556 pw.print(" cached="); pw.print(r.cached); 11557 pw.print(" empty="); pw.print(r.empty); 11558 pw.print(" hasAboveClient="); pw.println(r.hasAboveClient); 11559 11560 if (!r.keeping) { 11561 if (r.lastWakeTime != 0) { 11562 long wtime; 11563 BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics(); 11564 synchronized (stats) { 11565 wtime = stats.getProcessWakeTime(r.info.uid, 11566 r.pid, curRealtime); 11567 } 11568 long timeUsed = wtime - r.lastWakeTime; 11569 pw.print(prefix); 11570 pw.print(" "); 11571 pw.print("keep awake over "); 11572 TimeUtils.formatDuration(realtimeSince, pw); 11573 pw.print(" used "); 11574 TimeUtils.formatDuration(timeUsed, pw); 11575 pw.print(" ("); 11576 pw.print((timeUsed*100)/realtimeSince); 11577 pw.println("%)"); 11578 } 11579 if (r.lastCpuTime != 0) { 11580 long timeUsed = r.curCpuTime - r.lastCpuTime; 11581 pw.print(prefix); 11582 pw.print(" "); 11583 pw.print("run cpu over "); 11584 TimeUtils.formatDuration(uptimeSince, pw); 11585 pw.print(" used "); 11586 TimeUtils.formatDuration(timeUsed, pw); 11587 pw.print(" ("); 11588 pw.print((timeUsed*100)/uptimeSince); 11589 pw.println("%)"); 11590 } 11591 } 11592 } 11593 } 11594 return true; 11595 } 11596 11597 ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) { 11598 ArrayList<ProcessRecord> procs; 11599 synchronized (this) { 11600 if (args != null && args.length > start 11601 && args[start].charAt(0) != '-') { 11602 procs = new ArrayList<ProcessRecord>(); 11603 int pid = -1; 11604 try { 11605 pid = Integer.parseInt(args[start]); 11606 } catch (NumberFormatException e) { 11607 } 11608 for (int i=mLruProcesses.size()-1; i>=0; i--) { 11609 ProcessRecord proc = mLruProcesses.get(i); 11610 if (proc.pid == pid) { 11611 procs.add(proc); 11612 } else if (proc.processName.equals(args[start])) { 11613 procs.add(proc); 11614 } 11615 } 11616 if (procs.size() <= 0) { 11617 return null; 11618 } 11619 } else { 11620 procs = new ArrayList<ProcessRecord>(mLruProcesses); 11621 } 11622 } 11623 return procs; 11624 } 11625 11626 final void dumpGraphicsHardwareUsage(FileDescriptor fd, 11627 PrintWriter pw, String[] args) { 11628 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args); 11629 if (procs == null) { 11630 pw.println("No process found for: " + args[0]); 11631 return; 11632 } 11633 11634 long uptime = SystemClock.uptimeMillis(); 11635 long realtime = SystemClock.elapsedRealtime(); 11636 pw.println("Applications Graphics Acceleration Info:"); 11637 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 11638 11639 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 11640 ProcessRecord r = procs.get(i); 11641 if (r.thread != null) { 11642 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **"); 11643 pw.flush(); 11644 try { 11645 TransferPipe tp = new TransferPipe(); 11646 try { 11647 r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args); 11648 tp.go(fd); 11649 } finally { 11650 tp.kill(); 11651 } 11652 } catch (IOException e) { 11653 pw.println("Failure while dumping the app: " + r); 11654 pw.flush(); 11655 } catch (RemoteException e) { 11656 pw.println("Got a RemoteException while dumping the app " + r); 11657 pw.flush(); 11658 } 11659 } 11660 } 11661 } 11662 11663 final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) { 11664 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args); 11665 if (procs == null) { 11666 pw.println("No process found for: " + args[0]); 11667 return; 11668 } 11669 11670 pw.println("Applications Database Info:"); 11671 11672 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 11673 ProcessRecord r = procs.get(i); 11674 if (r.thread != null) { 11675 pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **"); 11676 pw.flush(); 11677 try { 11678 TransferPipe tp = new TransferPipe(); 11679 try { 11680 r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args); 11681 tp.go(fd); 11682 } finally { 11683 tp.kill(); 11684 } 11685 } catch (IOException e) { 11686 pw.println("Failure while dumping the app: " + r); 11687 pw.flush(); 11688 } catch (RemoteException e) { 11689 pw.println("Got a RemoteException while dumping the app " + r); 11690 pw.flush(); 11691 } 11692 } 11693 } 11694 } 11695 11696 final static class MemItem { 11697 final boolean isProc; 11698 final String label; 11699 final String shortLabel; 11700 final long pss; 11701 final int id; 11702 final boolean hasActivities; 11703 ArrayList<MemItem> subitems; 11704 11705 public MemItem(String _label, String _shortLabel, long _pss, int _id, 11706 boolean _hasActivities) { 11707 isProc = true; 11708 label = _label; 11709 shortLabel = _shortLabel; 11710 pss = _pss; 11711 id = _id; 11712 hasActivities = _hasActivities; 11713 } 11714 11715 public MemItem(String _label, String _shortLabel, long _pss, int _id) { 11716 isProc = false; 11717 label = _label; 11718 shortLabel = _shortLabel; 11719 pss = _pss; 11720 id = _id; 11721 hasActivities = false; 11722 } 11723 } 11724 11725 static final void dumpMemItems(PrintWriter pw, String prefix, String tag, 11726 ArrayList<MemItem> items, boolean sort, boolean isCompact) { 11727 if (sort && !isCompact) { 11728 Collections.sort(items, new Comparator<MemItem>() { 11729 @Override 11730 public int compare(MemItem lhs, MemItem rhs) { 11731 if (lhs.pss < rhs.pss) { 11732 return 1; 11733 } else if (lhs.pss > rhs.pss) { 11734 return -1; 11735 } 11736 return 0; 11737 } 11738 }); 11739 } 11740 11741 for (int i=0; i<items.size(); i++) { 11742 MemItem mi = items.get(i); 11743 if (!isCompact) { 11744 pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label); 11745 } else if (mi.isProc) { 11746 pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel); 11747 pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss); 11748 pw.println(mi.hasActivities ? ",a" : ",e"); 11749 } else { 11750 pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(","); 11751 pw.println(mi.pss); 11752 } 11753 if (mi.subitems != null) { 11754 dumpMemItems(pw, prefix + " ", mi.shortLabel, mi.subitems, 11755 true, isCompact); 11756 } 11757 } 11758 } 11759 11760 // These are in KB. 11761 static final long[] DUMP_MEM_BUCKETS = new long[] { 11762 5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024, 11763 120*1024, 160*1024, 200*1024, 11764 250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024, 11765 1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024 11766 }; 11767 11768 static final void appendMemBucket(StringBuilder out, long memKB, String label, 11769 boolean stackLike) { 11770 int start = label.lastIndexOf('.'); 11771 if (start >= 0) start++; 11772 else start = 0; 11773 int end = label.length(); 11774 for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) { 11775 if (DUMP_MEM_BUCKETS[i] >= memKB) { 11776 long bucket = DUMP_MEM_BUCKETS[i]/1024; 11777 out.append(bucket); 11778 out.append(stackLike ? "MB." : "MB "); 11779 out.append(label, start, end); 11780 return; 11781 } 11782 } 11783 out.append(memKB/1024); 11784 out.append(stackLike ? "MB." : "MB "); 11785 out.append(label, start, end); 11786 } 11787 11788 static final int[] DUMP_MEM_OOM_ADJ = new int[] { 11789 ProcessList.NATIVE_ADJ, 11790 ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ, 11791 ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ, 11792 ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ, 11793 ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ, 11794 ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ 11795 }; 11796 static final String[] DUMP_MEM_OOM_LABEL = new String[] { 11797 "Native", 11798 "System", "Persistent", "Foreground", 11799 "Visible", "Perceptible", 11800 "Heavy Weight", "Backup", 11801 "A Services", "Home", 11802 "Previous", "B Services", "Cached" 11803 }; 11804 static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] { 11805 "native", 11806 "sys", "pers", "fore", 11807 "vis", "percept", 11808 "heavy", "backup", 11809 "servicea", "home", 11810 "prev", "serviceb", "cached" 11811 }; 11812 11813 private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime, 11814 long realtime, boolean isCheckinRequest, boolean isCompact) { 11815 if (isCheckinRequest || isCompact) { 11816 // short checkin version 11817 pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime); 11818 } else { 11819 pw.println("Applications Memory Usage (kB):"); 11820 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 11821 } 11822 } 11823 11824 final void dumpApplicationMemoryUsage(FileDescriptor fd, 11825 PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) { 11826 boolean dumpDetails = false; 11827 boolean dumpFullDetails = false; 11828 boolean dumpDalvik = false; 11829 boolean oomOnly = false; 11830 boolean isCompact = false; 11831 boolean localOnly = false; 11832 11833 int opti = 0; 11834 while (opti < args.length) { 11835 String opt = args[opti]; 11836 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 11837 break; 11838 } 11839 opti++; 11840 if ("-a".equals(opt)) { 11841 dumpDetails = true; 11842 dumpFullDetails = true; 11843 dumpDalvik = true; 11844 } else if ("-d".equals(opt)) { 11845 dumpDalvik = true; 11846 } else if ("-c".equals(opt)) { 11847 isCompact = true; 11848 } else if ("--oom".equals(opt)) { 11849 oomOnly = true; 11850 } else if ("--local".equals(opt)) { 11851 localOnly = true; 11852 } else if ("-h".equals(opt)) { 11853 pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]"); 11854 pw.println(" -a: include all available information for each process."); 11855 pw.println(" -d: include dalvik details when dumping process details."); 11856 pw.println(" -c: dump in a compact machine-parseable representation."); 11857 pw.println(" --oom: only show processes organized by oom adj."); 11858 pw.println(" --local: only collect details locally, don't call process."); 11859 pw.println("If [process] is specified it can be the name or "); 11860 pw.println("pid of a specific process to dump."); 11861 return; 11862 } else { 11863 pw.println("Unknown argument: " + opt + "; use -h for help"); 11864 } 11865 } 11866 11867 final boolean isCheckinRequest = scanArgs(args, "--checkin"); 11868 long uptime = SystemClock.uptimeMillis(); 11869 long realtime = SystemClock.elapsedRealtime(); 11870 final long[] tmpLong = new long[1]; 11871 11872 ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args); 11873 if (procs == null) { 11874 // No Java processes. Maybe they want to print a native process. 11875 if (args != null && args.length > opti 11876 && args[opti].charAt(0) != '-') { 11877 ArrayList<ProcessCpuTracker.Stats> nativeProcs 11878 = new ArrayList<ProcessCpuTracker.Stats>(); 11879 updateCpuStatsNow(); 11880 int findPid = -1; 11881 try { 11882 findPid = Integer.parseInt(args[opti]); 11883 } catch (NumberFormatException e) { 11884 } 11885 synchronized (mProcessCpuThread) { 11886 final int N = mProcessCpuTracker.countStats(); 11887 for (int i=0; i<N; i++) { 11888 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 11889 if (st.pid == findPid || (st.baseName != null 11890 && st.baseName.equals(args[opti]))) { 11891 nativeProcs.add(st); 11892 } 11893 } 11894 } 11895 if (nativeProcs.size() > 0) { 11896 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, 11897 isCompact); 11898 Debug.MemoryInfo mi = null; 11899 for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) { 11900 final ProcessCpuTracker.Stats r = nativeProcs.get(i); 11901 final int pid = r.pid; 11902 if (!isCheckinRequest && dumpDetails) { 11903 pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **"); 11904 } 11905 if (mi == null) { 11906 mi = new Debug.MemoryInfo(); 11907 } 11908 if (dumpDetails || (!brief && !oomOnly)) { 11909 Debug.getMemoryInfo(pid, mi); 11910 } else { 11911 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong); 11912 mi.dalvikPrivateDirty = (int)tmpLong[0]; 11913 } 11914 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails, 11915 dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0); 11916 if (isCheckinRequest) { 11917 pw.println(); 11918 } 11919 } 11920 return; 11921 } 11922 } 11923 pw.println("No process found for: " + args[opti]); 11924 return; 11925 } 11926 11927 if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest)) { 11928 dumpDetails = true; 11929 } 11930 11931 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact); 11932 11933 String[] innerArgs = new String[args.length-opti]; 11934 System.arraycopy(args, opti, innerArgs, 0, args.length-opti); 11935 11936 ArrayList<MemItem> procMems = new ArrayList<MemItem>(); 11937 final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>(); 11938 long nativePss=0, dalvikPss=0, otherPss=0; 11939 long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS]; 11940 11941 long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length]; 11942 ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[]) 11943 new ArrayList[DUMP_MEM_OOM_LABEL.length]; 11944 11945 long totalPss = 0; 11946 long cachedPss = 0; 11947 11948 Debug.MemoryInfo mi = null; 11949 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 11950 final ProcessRecord r = procs.get(i); 11951 final IApplicationThread thread; 11952 final int pid; 11953 final int oomAdj; 11954 final boolean hasActivities; 11955 synchronized (this) { 11956 thread = r.thread; 11957 pid = r.pid; 11958 oomAdj = r.getSetAdjWithServices(); 11959 hasActivities = r.activities.size() > 0; 11960 } 11961 if (thread != null) { 11962 if (!isCheckinRequest && dumpDetails) { 11963 pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **"); 11964 } 11965 if (mi == null) { 11966 mi = new Debug.MemoryInfo(); 11967 } 11968 if (dumpDetails || (!brief && !oomOnly)) { 11969 Debug.getMemoryInfo(pid, mi); 11970 } else { 11971 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong); 11972 mi.dalvikPrivateDirty = (int)tmpLong[0]; 11973 } 11974 if (dumpDetails) { 11975 if (localOnly) { 11976 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails, 11977 dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0); 11978 if (isCheckinRequest) { 11979 pw.println(); 11980 } 11981 } else { 11982 try { 11983 pw.flush(); 11984 thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails, 11985 dumpDalvik, innerArgs); 11986 } catch (RemoteException e) { 11987 if (!isCheckinRequest) { 11988 pw.println("Got RemoteException!"); 11989 pw.flush(); 11990 } 11991 } 11992 } 11993 } 11994 11995 final long myTotalPss = mi.getTotalPss(); 11996 final long myTotalUss = mi.getTotalUss(); 11997 11998 synchronized (this) { 11999 if (r.thread != null && oomAdj == r.getSetAdjWithServices()) { 12000 // Record this for posterity if the process has been stable. 12001 r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList); 12002 } 12003 } 12004 12005 if (!isCheckinRequest && mi != null) { 12006 totalPss += myTotalPss; 12007 MemItem pssItem = new MemItem(r.processName + " (pid " + pid + 12008 (hasActivities ? " / activities)" : ")"), 12009 r.processName, myTotalPss, pid, hasActivities); 12010 procMems.add(pssItem); 12011 procMemsMap.put(pid, pssItem); 12012 12013 nativePss += mi.nativePss; 12014 dalvikPss += mi.dalvikPss; 12015 otherPss += mi.otherPss; 12016 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 12017 long mem = mi.getOtherPss(j); 12018 miscPss[j] += mem; 12019 otherPss -= mem; 12020 } 12021 12022 if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 12023 cachedPss += myTotalPss; 12024 } 12025 12026 for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) { 12027 if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex] 12028 || oomIndex == (oomPss.length-1)) { 12029 oomPss[oomIndex] += myTotalPss; 12030 if (oomProcs[oomIndex] == null) { 12031 oomProcs[oomIndex] = new ArrayList<MemItem>(); 12032 } 12033 oomProcs[oomIndex].add(pssItem); 12034 break; 12035 } 12036 } 12037 } 12038 } 12039 } 12040 12041 if (!isCheckinRequest && procs.size() > 1) { 12042 // If we are showing aggregations, also look for native processes to 12043 // include so that our aggregations are more accurate. 12044 updateCpuStatsNow(); 12045 synchronized (mProcessCpuThread) { 12046 final int N = mProcessCpuTracker.countStats(); 12047 for (int i=0; i<N; i++) { 12048 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 12049 if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) { 12050 if (mi == null) { 12051 mi = new Debug.MemoryInfo(); 12052 } 12053 if (!brief && !oomOnly) { 12054 Debug.getMemoryInfo(st.pid, mi); 12055 } else { 12056 mi.nativePss = (int)Debug.getPss(st.pid, tmpLong); 12057 mi.nativePrivateDirty = (int)tmpLong[0]; 12058 } 12059 12060 final long myTotalPss = mi.getTotalPss(); 12061 totalPss += myTotalPss; 12062 12063 MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")", 12064 st.name, myTotalPss, st.pid, false); 12065 procMems.add(pssItem); 12066 12067 nativePss += mi.nativePss; 12068 dalvikPss += mi.dalvikPss; 12069 otherPss += mi.otherPss; 12070 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 12071 long mem = mi.getOtherPss(j); 12072 miscPss[j] += mem; 12073 otherPss -= mem; 12074 } 12075 oomPss[0] += myTotalPss; 12076 if (oomProcs[0] == null) { 12077 oomProcs[0] = new ArrayList<MemItem>(); 12078 } 12079 oomProcs[0].add(pssItem); 12080 } 12081 } 12082 } 12083 12084 ArrayList<MemItem> catMems = new ArrayList<MemItem>(); 12085 12086 catMems.add(new MemItem("Native", "Native", nativePss, -1)); 12087 catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2)); 12088 catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3)); 12089 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 12090 String label = Debug.MemoryInfo.getOtherLabel(j); 12091 catMems.add(new MemItem(label, label, miscPss[j], j)); 12092 } 12093 12094 ArrayList<MemItem> oomMems = new ArrayList<MemItem>(); 12095 for (int j=0; j<oomPss.length; j++) { 12096 if (oomPss[j] != 0) { 12097 String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j] 12098 : DUMP_MEM_OOM_LABEL[j]; 12099 MemItem item = new MemItem(label, label, oomPss[j], 12100 DUMP_MEM_OOM_ADJ[j]); 12101 item.subitems = oomProcs[j]; 12102 oomMems.add(item); 12103 } 12104 } 12105 12106 if (!brief && !oomOnly && !isCompact) { 12107 pw.println(); 12108 pw.println("Total PSS by process:"); 12109 dumpMemItems(pw, " ", "proc", procMems, true, isCompact); 12110 pw.println(); 12111 } 12112 if (!isCompact) { 12113 pw.println("Total PSS by OOM adjustment:"); 12114 } 12115 dumpMemItems(pw, " ", "oom", oomMems, false, isCompact); 12116 if (!brief && !oomOnly) { 12117 PrintWriter out = categoryPw != null ? categoryPw : pw; 12118 if (!isCompact) { 12119 out.println(); 12120 out.println("Total PSS by category:"); 12121 } 12122 dumpMemItems(out, " ", "cat", catMems, true, isCompact); 12123 } 12124 if (!isCompact) { 12125 pw.println(); 12126 } 12127 MemInfoReader memInfo = new MemInfoReader(); 12128 memInfo.readMemInfo(); 12129 if (!brief) { 12130 if (!isCompact) { 12131 pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb()); 12132 pw.println(" kB"); 12133 pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb() 12134 + memInfo.getFreeSizeKb()); pw.print(" kB ("); 12135 pw.print(cachedPss); pw.print(" cached pss + "); 12136 pw.print(memInfo.getCachedSizeKb()); pw.print(" cached + "); 12137 pw.print(memInfo.getFreeSizeKb()); pw.println(" free)"); 12138 } else { 12139 pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(","); 12140 pw.print(cachedPss + memInfo.getCachedSizeKb() 12141 + memInfo.getFreeSizeKb()); pw.print(","); 12142 pw.println(totalPss - cachedPss); 12143 } 12144 } 12145 if (!isCompact) { 12146 pw.print(" Used RAM: "); pw.print(totalPss - cachedPss 12147 + memInfo.getBuffersSizeKb() + memInfo.getShmemSizeKb() 12148 + memInfo.getSlabSizeKb()); pw.print(" kB ("); 12149 pw.print(totalPss - cachedPss); pw.print(" used pss + "); 12150 pw.print(memInfo.getBuffersSizeKb()); pw.print(" buffers + "); 12151 pw.print(memInfo.getShmemSizeKb()); pw.print(" shmem + "); 12152 pw.print(memInfo.getSlabSizeKb()); pw.println(" slab)"); 12153 pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb() 12154 - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb() 12155 - memInfo.getBuffersSizeKb() - memInfo.getShmemSizeKb() 12156 - memInfo.getSlabSizeKb()); pw.println(" kB"); 12157 } 12158 if (!brief) { 12159 if (memInfo.getZramTotalSizeKb() != 0) { 12160 if (!isCompact) { 12161 pw.print(" ZRAM: "); pw.print(memInfo.getZramTotalSizeKb()); 12162 pw.print(" kB physical used for "); 12163 pw.print(memInfo.getSwapTotalSizeKb() 12164 - memInfo.getSwapFreeSizeKb()); 12165 pw.print(" kB in swap ("); 12166 pw.print(memInfo.getSwapTotalSizeKb()); 12167 pw.println(" kB total swap)"); 12168 } else { 12169 pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(","); 12170 pw.print(memInfo.getSwapTotalSizeKb()); pw.print(","); 12171 pw.println(memInfo.getSwapFreeSizeKb()); 12172 } 12173 } 12174 final int[] SINGLE_LONG_FORMAT = new int[] { 12175 Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG 12176 }; 12177 long[] longOut = new long[1]; 12178 Process.readProcFile("/sys/kernel/mm/ksm/pages_shared", 12179 SINGLE_LONG_FORMAT, null, longOut, null); 12180 long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024; 12181 longOut[0] = 0; 12182 Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing", 12183 SINGLE_LONG_FORMAT, null, longOut, null); 12184 long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024; 12185 longOut[0] = 0; 12186 Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared", 12187 SINGLE_LONG_FORMAT, null, longOut, null); 12188 long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024; 12189 longOut[0] = 0; 12190 Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile", 12191 SINGLE_LONG_FORMAT, null, longOut, null); 12192 long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024; 12193 if (!isCompact) { 12194 if (sharing != 0 || shared != 0 || unshared != 0 || voltile != 0) { 12195 pw.print(" KSM: "); pw.print(sharing); 12196 pw.print(" kB saved from shared "); 12197 pw.print(shared); pw.println(" kB"); 12198 pw.print(" "); pw.print(unshared); pw.print(" kB unshared; "); 12199 pw.print(voltile); pw.println(" kB volatile"); 12200 } 12201 pw.print(" Tuning: "); 12202 pw.print(ActivityManager.staticGetMemoryClass()); 12203 pw.print(" (large "); 12204 pw.print(ActivityManager.staticGetLargeMemoryClass()); 12205 pw.print("), oom "); 12206 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024); 12207 pw.print(" kB"); 12208 pw.print(", restore limit "); 12209 pw.print(mProcessList.getCachedRestoreThresholdKb()); 12210 pw.print(" kB"); 12211 if (ActivityManager.isLowRamDeviceStatic()) { 12212 pw.print(" (low-ram)"); 12213 } 12214 if (ActivityManager.isHighEndGfx()) { 12215 pw.print(" (high-end-gfx)"); 12216 } 12217 pw.println(); 12218 } else { 12219 pw.print("ksm,"); pw.print(sharing); pw.print(","); 12220 pw.print(shared); pw.print(","); pw.print(unshared); pw.print(","); 12221 pw.println(voltile); 12222 pw.print("tuning,"); 12223 pw.print(ActivityManager.staticGetMemoryClass()); 12224 pw.print(','); 12225 pw.print(ActivityManager.staticGetLargeMemoryClass()); 12226 pw.print(','); 12227 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024); 12228 if (ActivityManager.isLowRamDeviceStatic()) { 12229 pw.print(",low-ram"); 12230 } 12231 if (ActivityManager.isHighEndGfx()) { 12232 pw.print(",high-end-gfx"); 12233 } 12234 pw.println(); 12235 } 12236 } 12237 } 12238 } 12239 12240 /** 12241 * Searches array of arguments for the specified string 12242 * @param args array of argument strings 12243 * @param value value to search for 12244 * @return true if the value is contained in the array 12245 */ 12246 private static boolean scanArgs(String[] args, String value) { 12247 if (args != null) { 12248 for (String arg : args) { 12249 if (value.equals(arg)) { 12250 return true; 12251 } 12252 } 12253 } 12254 return false; 12255 } 12256 12257 private final boolean removeDyingProviderLocked(ProcessRecord proc, 12258 ContentProviderRecord cpr, boolean always) { 12259 final boolean inLaunching = mLaunchingProviders.contains(cpr); 12260 12261 if (!inLaunching || always) { 12262 synchronized (cpr) { 12263 cpr.launchingApp = null; 12264 cpr.notifyAll(); 12265 } 12266 mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid)); 12267 String names[] = cpr.info.authority.split(";"); 12268 for (int j = 0; j < names.length; j++) { 12269 mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid)); 12270 } 12271 } 12272 12273 for (int i=0; i<cpr.connections.size(); i++) { 12274 ContentProviderConnection conn = cpr.connections.get(i); 12275 if (conn.waiting) { 12276 // If this connection is waiting for the provider, then we don't 12277 // need to mess with its process unless we are always removing 12278 // or for some reason the provider is not currently launching. 12279 if (inLaunching && !always) { 12280 continue; 12281 } 12282 } 12283 ProcessRecord capp = conn.client; 12284 conn.dead = true; 12285 if (conn.stableCount > 0) { 12286 if (!capp.persistent && capp.thread != null 12287 && capp.pid != 0 12288 && capp.pid != MY_PID) { 12289 killUnneededProcessLocked(capp, "depends on provider " 12290 + cpr.name.flattenToShortString() 12291 + " in dying proc " + (proc != null ? proc.processName : "??")); 12292 } 12293 } else if (capp.thread != null && conn.provider.provider != null) { 12294 try { 12295 capp.thread.unstableProviderDied(conn.provider.provider.asBinder()); 12296 } catch (RemoteException e) { 12297 } 12298 // In the protocol here, we don't expect the client to correctly 12299 // clean up this connection, we'll just remove it. 12300 cpr.connections.remove(i); 12301 conn.client.conProviders.remove(conn); 12302 } 12303 } 12304 12305 if (inLaunching && always) { 12306 mLaunchingProviders.remove(cpr); 12307 } 12308 return inLaunching; 12309 } 12310 12311 /** 12312 * Main code for cleaning up a process when it has gone away. This is 12313 * called both as a result of the process dying, or directly when stopping 12314 * a process when running in single process mode. 12315 */ 12316 private final void cleanUpApplicationRecordLocked(ProcessRecord app, 12317 boolean restarting, boolean allowRestart, int index) { 12318 if (index >= 0) { 12319 removeLruProcessLocked(app); 12320 ProcessList.remove(app.pid); 12321 } 12322 12323 mProcessesToGc.remove(app); 12324 mPendingPssProcesses.remove(app); 12325 12326 // Dismiss any open dialogs. 12327 if (app.crashDialog != null && !app.forceCrashReport) { 12328 app.crashDialog.dismiss(); 12329 app.crashDialog = null; 12330 } 12331 if (app.anrDialog != null) { 12332 app.anrDialog.dismiss(); 12333 app.anrDialog = null; 12334 } 12335 if (app.waitDialog != null) { 12336 app.waitDialog.dismiss(); 12337 app.waitDialog = null; 12338 } 12339 12340 app.crashing = false; 12341 app.notResponding = false; 12342 12343 app.resetPackageList(mProcessStats); 12344 app.unlinkDeathRecipient(); 12345 app.makeInactive(mProcessStats); 12346 app.waitingToKill = null; 12347 app.forcingToForeground = null; 12348 app.foregroundServices = false; 12349 app.foregroundActivities = false; 12350 app.hasShownUi = false; 12351 app.hasAboveClient = false; 12352 app.hasClientActivities = false; 12353 12354 mServices.killServicesLocked(app, allowRestart); 12355 12356 boolean restart = false; 12357 12358 // Remove published content providers. 12359 for (int i=app.pubProviders.size()-1; i>=0; i--) { 12360 ContentProviderRecord cpr = app.pubProviders.valueAt(i); 12361 final boolean always = app.bad || !allowRestart; 12362 if (removeDyingProviderLocked(app, cpr, always) || always) { 12363 // We left the provider in the launching list, need to 12364 // restart it. 12365 restart = true; 12366 } 12367 12368 cpr.provider = null; 12369 cpr.proc = null; 12370 } 12371 app.pubProviders.clear(); 12372 12373 // Take care of any launching providers waiting for this process. 12374 if (checkAppInLaunchingProvidersLocked(app, false)) { 12375 restart = true; 12376 } 12377 12378 // Unregister from connected content providers. 12379 if (!app.conProviders.isEmpty()) { 12380 for (int i=0; i<app.conProviders.size(); i++) { 12381 ContentProviderConnection conn = app.conProviders.get(i); 12382 conn.provider.connections.remove(conn); 12383 } 12384 app.conProviders.clear(); 12385 } 12386 12387 // At this point there may be remaining entries in mLaunchingProviders 12388 // where we were the only one waiting, so they are no longer of use. 12389 // Look for these and clean up if found. 12390 // XXX Commented out for now. Trying to figure out a way to reproduce 12391 // the actual situation to identify what is actually going on. 12392 if (false) { 12393 for (int i=0; i<mLaunchingProviders.size(); i++) { 12394 ContentProviderRecord cpr = (ContentProviderRecord) 12395 mLaunchingProviders.get(i); 12396 if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) { 12397 synchronized (cpr) { 12398 cpr.launchingApp = null; 12399 cpr.notifyAll(); 12400 } 12401 } 12402 } 12403 } 12404 12405 skipCurrentReceiverLocked(app); 12406 12407 // Unregister any receivers. 12408 for (int i=app.receivers.size()-1; i>=0; i--) { 12409 removeReceiverLocked(app.receivers.valueAt(i)); 12410 } 12411 app.receivers.clear(); 12412 12413 // If the app is undergoing backup, tell the backup manager about it 12414 if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) { 12415 if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App " 12416 + mBackupTarget.appInfo + " died during backup"); 12417 try { 12418 IBackupManager bm = IBackupManager.Stub.asInterface( 12419 ServiceManager.getService(Context.BACKUP_SERVICE)); 12420 bm.agentDisconnected(app.info.packageName); 12421 } catch (RemoteException e) { 12422 // can't happen; backup manager is local 12423 } 12424 } 12425 12426 for (int i = mPendingProcessChanges.size()-1; i>=0; i--) { 12427 ProcessChangeItem item = mPendingProcessChanges.get(i); 12428 if (item.pid == app.pid) { 12429 mPendingProcessChanges.remove(i); 12430 mAvailProcessChanges.add(item); 12431 } 12432 } 12433 mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget(); 12434 12435 // If the caller is restarting this app, then leave it in its 12436 // current lists and let the caller take care of it. 12437 if (restarting) { 12438 return; 12439 } 12440 12441 if (!app.persistent || app.isolated) { 12442 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, 12443 "Removing non-persistent process during cleanup: " + app); 12444 mProcessNames.remove(app.processName, app.uid); 12445 mIsolatedProcesses.remove(app.uid); 12446 if (mHeavyWeightProcess == app) { 12447 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 12448 mHeavyWeightProcess.userId, 0)); 12449 mHeavyWeightProcess = null; 12450 } 12451 } else if (!app.removed) { 12452 // This app is persistent, so we need to keep its record around. 12453 // If it is not already on the pending app list, add it there 12454 // and start a new process for it. 12455 if (mPersistentStartingProcesses.indexOf(app) < 0) { 12456 mPersistentStartingProcesses.add(app); 12457 restart = true; 12458 } 12459 } 12460 if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG, 12461 "Clean-up removing on hold: " + app); 12462 mProcessesOnHold.remove(app); 12463 12464 if (app == mHomeProcess) { 12465 mHomeProcess = null; 12466 } 12467 if (app == mPreviousProcess) { 12468 mPreviousProcess = null; 12469 } 12470 12471 if (restart && !app.isolated) { 12472 // We have components that still need to be running in the 12473 // process, so re-launch it. 12474 mProcessNames.put(app.processName, app.uid, app); 12475 startProcessLocked(app, "restart", app.processName, null /* ABI override */); 12476 } else if (app.pid > 0 && app.pid != MY_PID) { 12477 // Goodbye! 12478 synchronized (mPidsSelfLocked) { 12479 mPidsSelfLocked.remove(app.pid); 12480 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 12481 } 12482 app.setPid(0); 12483 } 12484 } 12485 12486 boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) { 12487 // Look through the content providers we are waiting to have launched, 12488 // and if any run in this process then either schedule a restart of 12489 // the process or kill the client waiting for it if this process has 12490 // gone bad. 12491 int NL = mLaunchingProviders.size(); 12492 boolean restart = false; 12493 for (int i=0; i<NL; i++) { 12494 ContentProviderRecord cpr = mLaunchingProviders.get(i); 12495 if (cpr.launchingApp == app) { 12496 if (!alwaysBad && !app.bad) { 12497 restart = true; 12498 } else { 12499 removeDyingProviderLocked(app, cpr, true); 12500 // cpr should have been removed from mLaunchingProviders 12501 NL = mLaunchingProviders.size(); 12502 i--; 12503 } 12504 } 12505 } 12506 return restart; 12507 } 12508 12509 // ========================================================= 12510 // SERVICES 12511 // ========================================================= 12512 12513 public List<ActivityManager.RunningServiceInfo> getServices(int maxNum, 12514 int flags) { 12515 enforceNotIsolatedCaller("getServices"); 12516 synchronized (this) { 12517 return mServices.getRunningServiceInfoLocked(maxNum, flags); 12518 } 12519 } 12520 12521 public PendingIntent getRunningServiceControlPanel(ComponentName name) { 12522 enforceNotIsolatedCaller("getRunningServiceControlPanel"); 12523 synchronized (this) { 12524 return mServices.getRunningServiceControlPanelLocked(name); 12525 } 12526 } 12527 12528 public ComponentName startService(IApplicationThread caller, Intent service, 12529 String resolvedType, int userId) { 12530 enforceNotIsolatedCaller("startService"); 12531 // Refuse possible leaked file descriptors 12532 if (service != null && service.hasFileDescriptors() == true) { 12533 throw new IllegalArgumentException("File descriptors passed in Intent"); 12534 } 12535 12536 if (DEBUG_SERVICE) 12537 Slog.v(TAG, "startService: " + service + " type=" + resolvedType); 12538 synchronized(this) { 12539 final int callingPid = Binder.getCallingPid(); 12540 final int callingUid = Binder.getCallingUid(); 12541 final long origId = Binder.clearCallingIdentity(); 12542 ComponentName res = mServices.startServiceLocked(caller, service, 12543 resolvedType, callingPid, callingUid, userId); 12544 Binder.restoreCallingIdentity(origId); 12545 return res; 12546 } 12547 } 12548 12549 ComponentName startServiceInPackage(int uid, 12550 Intent service, String resolvedType, int userId) { 12551 synchronized(this) { 12552 if (DEBUG_SERVICE) 12553 Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType); 12554 final long origId = Binder.clearCallingIdentity(); 12555 ComponentName res = mServices.startServiceLocked(null, service, 12556 resolvedType, -1, uid, userId); 12557 Binder.restoreCallingIdentity(origId); 12558 return res; 12559 } 12560 } 12561 12562 public int stopService(IApplicationThread caller, Intent service, 12563 String resolvedType, int userId) { 12564 enforceNotIsolatedCaller("stopService"); 12565 // Refuse possible leaked file descriptors 12566 if (service != null && service.hasFileDescriptors() == true) { 12567 throw new IllegalArgumentException("File descriptors passed in Intent"); 12568 } 12569 12570 synchronized(this) { 12571 return mServices.stopServiceLocked(caller, service, resolvedType, userId); 12572 } 12573 } 12574 12575 public IBinder peekService(Intent service, String resolvedType) { 12576 enforceNotIsolatedCaller("peekService"); 12577 // Refuse possible leaked file descriptors 12578 if (service != null && service.hasFileDescriptors() == true) { 12579 throw new IllegalArgumentException("File descriptors passed in Intent"); 12580 } 12581 synchronized(this) { 12582 return mServices.peekServiceLocked(service, resolvedType); 12583 } 12584 } 12585 12586 public boolean stopServiceToken(ComponentName className, IBinder token, 12587 int startId) { 12588 synchronized(this) { 12589 return mServices.stopServiceTokenLocked(className, token, startId); 12590 } 12591 } 12592 12593 public void setServiceForeground(ComponentName className, IBinder token, 12594 int id, Notification notification, boolean removeNotification) { 12595 synchronized(this) { 12596 mServices.setServiceForegroundLocked(className, token, id, notification, 12597 removeNotification); 12598 } 12599 } 12600 12601 public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll, 12602 boolean requireFull, String name, String callerPackage) { 12603 final int callingUserId = UserHandle.getUserId(callingUid); 12604 if (callingUserId != userId) { 12605 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 12606 if ((requireFull || checkComponentPermission( 12607 android.Manifest.permission.INTERACT_ACROSS_USERS, 12608 callingPid, callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) 12609 && checkComponentPermission( 12610 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 12611 callingPid, callingUid, -1, true) 12612 != PackageManager.PERMISSION_GRANTED) { 12613 if (userId == UserHandle.USER_CURRENT_OR_SELF) { 12614 // In this case, they would like to just execute as their 12615 // owner user instead of failing. 12616 userId = callingUserId; 12617 } else { 12618 StringBuilder builder = new StringBuilder(128); 12619 builder.append("Permission Denial: "); 12620 builder.append(name); 12621 if (callerPackage != null) { 12622 builder.append(" from "); 12623 builder.append(callerPackage); 12624 } 12625 builder.append(" asks to run as user "); 12626 builder.append(userId); 12627 builder.append(" but is calling from user "); 12628 builder.append(UserHandle.getUserId(callingUid)); 12629 builder.append("; this requires "); 12630 builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL); 12631 if (!requireFull) { 12632 builder.append(" or "); 12633 builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS); 12634 } 12635 String msg = builder.toString(); 12636 Slog.w(TAG, msg); 12637 throw new SecurityException(msg); 12638 } 12639 } 12640 } 12641 if (userId == UserHandle.USER_CURRENT 12642 || userId == UserHandle.USER_CURRENT_OR_SELF) { 12643 // Note that we may be accessing this outside of a lock... 12644 // shouldn't be a big deal, if this is being called outside 12645 // of a locked context there is intrinsically a race with 12646 // the value the caller will receive and someone else changing it. 12647 userId = mCurrentUserId; 12648 } 12649 if (!allowAll && userId < 0) { 12650 throw new IllegalArgumentException( 12651 "Call does not support special user #" + userId); 12652 } 12653 } 12654 return userId; 12655 } 12656 12657 boolean isSingleton(String componentProcessName, ApplicationInfo aInfo, 12658 String className, int flags) { 12659 boolean result = false; 12660 if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) { 12661 if ((flags&ServiceInfo.FLAG_SINGLE_USER) != 0) { 12662 if (ActivityManager.checkUidPermission( 12663 android.Manifest.permission.INTERACT_ACROSS_USERS, 12664 aInfo.uid) != PackageManager.PERMISSION_GRANTED) { 12665 ComponentName comp = new ComponentName(aInfo.packageName, className); 12666 String msg = "Permission Denial: Component " + comp.flattenToShortString() 12667 + " requests FLAG_SINGLE_USER, but app does not hold " 12668 + android.Manifest.permission.INTERACT_ACROSS_USERS; 12669 Slog.w(TAG, msg); 12670 throw new SecurityException(msg); 12671 } 12672 result = true; 12673 } 12674 } else if (componentProcessName == aInfo.packageName) { 12675 result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0; 12676 } else if ("system".equals(componentProcessName)) { 12677 result = true; 12678 } 12679 if (DEBUG_MU) { 12680 Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo 12681 + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result); 12682 } 12683 return result; 12684 } 12685 12686 public int bindService(IApplicationThread caller, IBinder token, 12687 Intent service, String resolvedType, 12688 IServiceConnection connection, int flags, int userId) { 12689 enforceNotIsolatedCaller("bindService"); 12690 // Refuse possible leaked file descriptors 12691 if (service != null && service.hasFileDescriptors() == true) { 12692 throw new IllegalArgumentException("File descriptors passed in Intent"); 12693 } 12694 12695 synchronized(this) { 12696 return mServices.bindServiceLocked(caller, token, service, resolvedType, 12697 connection, flags, userId); 12698 } 12699 } 12700 12701 public boolean unbindService(IServiceConnection connection) { 12702 synchronized (this) { 12703 return mServices.unbindServiceLocked(connection); 12704 } 12705 } 12706 12707 public void publishService(IBinder token, Intent intent, IBinder service) { 12708 // Refuse possible leaked file descriptors 12709 if (intent != null && intent.hasFileDescriptors() == true) { 12710 throw new IllegalArgumentException("File descriptors passed in Intent"); 12711 } 12712 12713 synchronized(this) { 12714 if (!(token instanceof ServiceRecord)) { 12715 throw new IllegalArgumentException("Invalid service token"); 12716 } 12717 mServices.publishServiceLocked((ServiceRecord)token, intent, service); 12718 } 12719 } 12720 12721 public void unbindFinished(IBinder token, Intent intent, boolean doRebind) { 12722 // Refuse possible leaked file descriptors 12723 if (intent != null && intent.hasFileDescriptors() == true) { 12724 throw new IllegalArgumentException("File descriptors passed in Intent"); 12725 } 12726 12727 synchronized(this) { 12728 mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind); 12729 } 12730 } 12731 12732 public void serviceDoneExecuting(IBinder token, int type, int startId, int res) { 12733 synchronized(this) { 12734 if (!(token instanceof ServiceRecord)) { 12735 throw new IllegalArgumentException("Invalid service token"); 12736 } 12737 mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res); 12738 } 12739 } 12740 12741 // ========================================================= 12742 // BACKUP AND RESTORE 12743 // ========================================================= 12744 12745 // Cause the target app to be launched if necessary and its backup agent 12746 // instantiated. The backup agent will invoke backupAgentCreated() on the 12747 // activity manager to announce its creation. 12748 public boolean bindBackupAgent(ApplicationInfo app, int backupMode) { 12749 if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode); 12750 enforceCallingPermission("android.permission.BACKUP", "bindBackupAgent"); 12751 12752 synchronized(this) { 12753 // !!! TODO: currently no check here that we're already bound 12754 BatteryStatsImpl.Uid.Pkg.Serv ss = null; 12755 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 12756 synchronized (stats) { 12757 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name); 12758 } 12759 12760 // Backup agent is now in use, its package can't be stopped. 12761 try { 12762 AppGlobals.getPackageManager().setPackageStoppedState( 12763 app.packageName, false, UserHandle.getUserId(app.uid)); 12764 } catch (RemoteException e) { 12765 } catch (IllegalArgumentException e) { 12766 Slog.w(TAG, "Failed trying to unstop package " 12767 + app.packageName + ": " + e); 12768 } 12769 12770 BackupRecord r = new BackupRecord(ss, app, backupMode); 12771 ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL) 12772 ? new ComponentName(app.packageName, app.backupAgentName) 12773 : new ComponentName("android", "FullBackupAgent"); 12774 // startProcessLocked() returns existing proc's record if it's already running 12775 ProcessRecord proc = startProcessLocked(app.processName, app, 12776 false, 0, "backup", hostingName, false, false, false); 12777 if (proc == null) { 12778 Slog.e(TAG, "Unable to start backup agent process " + r); 12779 return false; 12780 } 12781 12782 r.app = proc; 12783 mBackupTarget = r; 12784 mBackupAppName = app.packageName; 12785 12786 // Try not to kill the process during backup 12787 updateOomAdjLocked(proc); 12788 12789 // If the process is already attached, schedule the creation of the backup agent now. 12790 // If it is not yet live, this will be done when it attaches to the framework. 12791 if (proc.thread != null) { 12792 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc); 12793 try { 12794 proc.thread.scheduleCreateBackupAgent(app, 12795 compatibilityInfoForPackageLocked(app), backupMode); 12796 } catch (RemoteException e) { 12797 // Will time out on the backup manager side 12798 } 12799 } else { 12800 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach"); 12801 } 12802 // Invariants: at this point, the target app process exists and the application 12803 // is either already running or in the process of coming up. mBackupTarget and 12804 // mBackupAppName describe the app, so that when it binds back to the AM we 12805 // know that it's scheduled for a backup-agent operation. 12806 } 12807 12808 return true; 12809 } 12810 12811 @Override 12812 public void clearPendingBackup() { 12813 if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup"); 12814 enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup"); 12815 12816 synchronized (this) { 12817 mBackupTarget = null; 12818 mBackupAppName = null; 12819 } 12820 } 12821 12822 // A backup agent has just come up 12823 public void backupAgentCreated(String agentPackageName, IBinder agent) { 12824 if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName 12825 + " = " + agent); 12826 12827 synchronized(this) { 12828 if (!agentPackageName.equals(mBackupAppName)) { 12829 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!"); 12830 return; 12831 } 12832 } 12833 12834 long oldIdent = Binder.clearCallingIdentity(); 12835 try { 12836 IBackupManager bm = IBackupManager.Stub.asInterface( 12837 ServiceManager.getService(Context.BACKUP_SERVICE)); 12838 bm.agentConnected(agentPackageName, agent); 12839 } catch (RemoteException e) { 12840 // can't happen; the backup manager service is local 12841 } catch (Exception e) { 12842 Slog.w(TAG, "Exception trying to deliver BackupAgent binding: "); 12843 e.printStackTrace(); 12844 } finally { 12845 Binder.restoreCallingIdentity(oldIdent); 12846 } 12847 } 12848 12849 // done with this agent 12850 public void unbindBackupAgent(ApplicationInfo appInfo) { 12851 if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo); 12852 if (appInfo == null) { 12853 Slog.w(TAG, "unbind backup agent for null app"); 12854 return; 12855 } 12856 12857 synchronized(this) { 12858 try { 12859 if (mBackupAppName == null) { 12860 Slog.w(TAG, "Unbinding backup agent with no active backup"); 12861 return; 12862 } 12863 12864 if (!mBackupAppName.equals(appInfo.packageName)) { 12865 Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target"); 12866 return; 12867 } 12868 12869 // Not backing this app up any more; reset its OOM adjustment 12870 final ProcessRecord proc = mBackupTarget.app; 12871 updateOomAdjLocked(proc); 12872 12873 // If the app crashed during backup, 'thread' will be null here 12874 if (proc.thread != null) { 12875 try { 12876 proc.thread.scheduleDestroyBackupAgent(appInfo, 12877 compatibilityInfoForPackageLocked(appInfo)); 12878 } catch (Exception e) { 12879 Slog.e(TAG, "Exception when unbinding backup agent:"); 12880 e.printStackTrace(); 12881 } 12882 } 12883 } finally { 12884 mBackupTarget = null; 12885 mBackupAppName = null; 12886 } 12887 } 12888 } 12889 // ========================================================= 12890 // BROADCASTS 12891 // ========================================================= 12892 12893 private final List getStickiesLocked(String action, IntentFilter filter, 12894 List cur, int userId) { 12895 final ContentResolver resolver = mContext.getContentResolver(); 12896 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 12897 if (stickies == null) { 12898 return cur; 12899 } 12900 final ArrayList<Intent> list = stickies.get(action); 12901 if (list == null) { 12902 return cur; 12903 } 12904 int N = list.size(); 12905 for (int i=0; i<N; i++) { 12906 Intent intent = list.get(i); 12907 if (filter.match(resolver, intent, true, TAG) >= 0) { 12908 if (cur == null) { 12909 cur = new ArrayList<Intent>(); 12910 } 12911 cur.add(intent); 12912 } 12913 } 12914 return cur; 12915 } 12916 12917 boolean isPendingBroadcastProcessLocked(int pid) { 12918 return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid) 12919 || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid); 12920 } 12921 12922 void skipPendingBroadcastLocked(int pid) { 12923 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 12924 for (BroadcastQueue queue : mBroadcastQueues) { 12925 queue.skipPendingBroadcastLocked(pid); 12926 } 12927 } 12928 12929 // The app just attached; send any pending broadcasts that it should receive 12930 boolean sendPendingBroadcastsLocked(ProcessRecord app) { 12931 boolean didSomething = false; 12932 for (BroadcastQueue queue : mBroadcastQueues) { 12933 didSomething |= queue.sendPendingBroadcastsLocked(app); 12934 } 12935 return didSomething; 12936 } 12937 12938 public Intent registerReceiver(IApplicationThread caller, String callerPackage, 12939 IIntentReceiver receiver, IntentFilter filter, String permission, int userId) { 12940 enforceNotIsolatedCaller("registerReceiver"); 12941 int callingUid; 12942 int callingPid; 12943 synchronized(this) { 12944 ProcessRecord callerApp = null; 12945 if (caller != null) { 12946 callerApp = getRecordForAppLocked(caller); 12947 if (callerApp == null) { 12948 throw new SecurityException( 12949 "Unable to find app for caller " + caller 12950 + " (pid=" + Binder.getCallingPid() 12951 + ") when registering receiver " + receiver); 12952 } 12953 if (callerApp.info.uid != Process.SYSTEM_UID && 12954 !callerApp.pkgList.containsKey(callerPackage) && 12955 !"android".equals(callerPackage)) { 12956 throw new SecurityException("Given caller package " + callerPackage 12957 + " is not running in process " + callerApp); 12958 } 12959 callingUid = callerApp.info.uid; 12960 callingPid = callerApp.pid; 12961 } else { 12962 callerPackage = null; 12963 callingUid = Binder.getCallingUid(); 12964 callingPid = Binder.getCallingPid(); 12965 } 12966 12967 userId = this.handleIncomingUser(callingPid, callingUid, userId, 12968 true, true, "registerReceiver", callerPackage); 12969 12970 List allSticky = null; 12971 12972 // Look for any matching sticky broadcasts... 12973 Iterator actions = filter.actionsIterator(); 12974 if (actions != null) { 12975 while (actions.hasNext()) { 12976 String action = (String)actions.next(); 12977 allSticky = getStickiesLocked(action, filter, allSticky, 12978 UserHandle.USER_ALL); 12979 allSticky = getStickiesLocked(action, filter, allSticky, 12980 UserHandle.getUserId(callingUid)); 12981 } 12982 } else { 12983 allSticky = getStickiesLocked(null, filter, allSticky, 12984 UserHandle.USER_ALL); 12985 allSticky = getStickiesLocked(null, filter, allSticky, 12986 UserHandle.getUserId(callingUid)); 12987 } 12988 12989 // The first sticky in the list is returned directly back to 12990 // the client. 12991 Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null; 12992 12993 if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter 12994 + ": " + sticky); 12995 12996 if (receiver == null) { 12997 return sticky; 12998 } 12999 13000 ReceiverList rl 13001 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder()); 13002 if (rl == null) { 13003 rl = new ReceiverList(this, callerApp, callingPid, callingUid, 13004 userId, receiver); 13005 if (rl.app != null) { 13006 rl.app.receivers.add(rl); 13007 } else { 13008 try { 13009 receiver.asBinder().linkToDeath(rl, 0); 13010 } catch (RemoteException e) { 13011 return sticky; 13012 } 13013 rl.linkedToDeath = true; 13014 } 13015 mRegisteredReceivers.put(receiver.asBinder(), rl); 13016 } else if (rl.uid != callingUid) { 13017 throw new IllegalArgumentException( 13018 "Receiver requested to register for uid " + callingUid 13019 + " was previously registered for uid " + rl.uid); 13020 } else if (rl.pid != callingPid) { 13021 throw new IllegalArgumentException( 13022 "Receiver requested to register for pid " + callingPid 13023 + " was previously registered for pid " + rl.pid); 13024 } else if (rl.userId != userId) { 13025 throw new IllegalArgumentException( 13026 "Receiver requested to register for user " + userId 13027 + " was previously registered for user " + rl.userId); 13028 } 13029 BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage, 13030 permission, callingUid, userId); 13031 rl.add(bf); 13032 if (!bf.debugCheck()) { 13033 Slog.w(TAG, "==> For Dynamic broadast"); 13034 } 13035 mReceiverResolver.addFilter(bf); 13036 13037 // Enqueue broadcasts for all existing stickies that match 13038 // this filter. 13039 if (allSticky != null) { 13040 ArrayList receivers = new ArrayList(); 13041 receivers.add(bf); 13042 13043 int N = allSticky.size(); 13044 for (int i=0; i<N; i++) { 13045 Intent intent = (Intent)allSticky.get(i); 13046 BroadcastQueue queue = broadcastQueueForIntent(intent); 13047 BroadcastRecord r = new BroadcastRecord(queue, intent, null, 13048 null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0, 13049 null, null, false, true, true, -1); 13050 queue.enqueueParallelBroadcastLocked(r); 13051 queue.scheduleBroadcastsLocked(); 13052 } 13053 } 13054 13055 return sticky; 13056 } 13057 } 13058 13059 public void unregisterReceiver(IIntentReceiver receiver) { 13060 if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver); 13061 13062 final long origId = Binder.clearCallingIdentity(); 13063 try { 13064 boolean doTrim = false; 13065 13066 synchronized(this) { 13067 ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder()); 13068 if (rl != null) { 13069 if (rl.curBroadcast != null) { 13070 BroadcastRecord r = rl.curBroadcast; 13071 final boolean doNext = finishReceiverLocked( 13072 receiver.asBinder(), r.resultCode, r.resultData, 13073 r.resultExtras, r.resultAbort); 13074 if (doNext) { 13075 doTrim = true; 13076 r.queue.processNextBroadcast(false); 13077 } 13078 } 13079 13080 if (rl.app != null) { 13081 rl.app.receivers.remove(rl); 13082 } 13083 removeReceiverLocked(rl); 13084 if (rl.linkedToDeath) { 13085 rl.linkedToDeath = false; 13086 rl.receiver.asBinder().unlinkToDeath(rl, 0); 13087 } 13088 } 13089 } 13090 13091 // If we actually concluded any broadcasts, we might now be able 13092 // to trim the recipients' apps from our working set 13093 if (doTrim) { 13094 trimApplications(); 13095 return; 13096 } 13097 13098 } finally { 13099 Binder.restoreCallingIdentity(origId); 13100 } 13101 } 13102 13103 void removeReceiverLocked(ReceiverList rl) { 13104 mRegisteredReceivers.remove(rl.receiver.asBinder()); 13105 int N = rl.size(); 13106 for (int i=0; i<N; i++) { 13107 mReceiverResolver.removeFilter(rl.get(i)); 13108 } 13109 } 13110 13111 private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) { 13112 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 13113 ProcessRecord r = mLruProcesses.get(i); 13114 if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) { 13115 try { 13116 r.thread.dispatchPackageBroadcast(cmd, packages); 13117 } catch (RemoteException ex) { 13118 } 13119 } 13120 } 13121 } 13122 13123 private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType, 13124 int[] users) { 13125 List<ResolveInfo> receivers = null; 13126 try { 13127 HashSet<ComponentName> singleUserReceivers = null; 13128 boolean scannedFirstReceivers = false; 13129 for (int user : users) { 13130 List<ResolveInfo> newReceivers = AppGlobals.getPackageManager() 13131 .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user); 13132 if (user != 0 && newReceivers != null) { 13133 // If this is not the primary user, we need to check for 13134 // any receivers that should be filtered out. 13135 for (int i=0; i<newReceivers.size(); i++) { 13136 ResolveInfo ri = newReceivers.get(i); 13137 if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) { 13138 newReceivers.remove(i); 13139 i--; 13140 } 13141 } 13142 } 13143 if (newReceivers != null && newReceivers.size() == 0) { 13144 newReceivers = null; 13145 } 13146 if (receivers == null) { 13147 receivers = newReceivers; 13148 } else if (newReceivers != null) { 13149 // We need to concatenate the additional receivers 13150 // found with what we have do far. This would be easy, 13151 // but we also need to de-dup any receivers that are 13152 // singleUser. 13153 if (!scannedFirstReceivers) { 13154 // Collect any single user receivers we had already retrieved. 13155 scannedFirstReceivers = true; 13156 for (int i=0; i<receivers.size(); i++) { 13157 ResolveInfo ri = receivers.get(i); 13158 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 13159 ComponentName cn = new ComponentName( 13160 ri.activityInfo.packageName, ri.activityInfo.name); 13161 if (singleUserReceivers == null) { 13162 singleUserReceivers = new HashSet<ComponentName>(); 13163 } 13164 singleUserReceivers.add(cn); 13165 } 13166 } 13167 } 13168 // Add the new results to the existing results, tracking 13169 // and de-dupping single user receivers. 13170 for (int i=0; i<newReceivers.size(); i++) { 13171 ResolveInfo ri = newReceivers.get(i); 13172 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 13173 ComponentName cn = new ComponentName( 13174 ri.activityInfo.packageName, ri.activityInfo.name); 13175 if (singleUserReceivers == null) { 13176 singleUserReceivers = new HashSet<ComponentName>(); 13177 } 13178 if (!singleUserReceivers.contains(cn)) { 13179 singleUserReceivers.add(cn); 13180 receivers.add(ri); 13181 } 13182 } else { 13183 receivers.add(ri); 13184 } 13185 } 13186 } 13187 } 13188 } catch (RemoteException ex) { 13189 // pm is in same process, this will never happen. 13190 } 13191 return receivers; 13192 } 13193 13194 private final int broadcastIntentLocked(ProcessRecord callerApp, 13195 String callerPackage, Intent intent, String resolvedType, 13196 IIntentReceiver resultTo, int resultCode, String resultData, 13197 Bundle map, String requiredPermission, int appOp, 13198 boolean ordered, boolean sticky, int callingPid, int callingUid, 13199 int userId) { 13200 intent = new Intent(intent); 13201 13202 // By default broadcasts do not go to stopped apps. 13203 intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES); 13204 13205 if (DEBUG_BROADCAST_LIGHT) Slog.v( 13206 TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent 13207 + " ordered=" + ordered + " userid=" + userId); 13208 if ((resultTo != null) && !ordered) { 13209 Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!"); 13210 } 13211 13212 userId = handleIncomingUser(callingPid, callingUid, userId, 13213 true, false, "broadcast", callerPackage); 13214 13215 // Make sure that the user who is receiving this broadcast is started. 13216 // If not, we will just skip it. 13217 if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) { 13218 if (callingUid != Process.SYSTEM_UID || (intent.getFlags() 13219 & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) { 13220 Slog.w(TAG, "Skipping broadcast of " + intent 13221 + ": user " + userId + " is stopped"); 13222 return ActivityManager.BROADCAST_SUCCESS; 13223 } 13224 } 13225 13226 /* 13227 * Prevent non-system code (defined here to be non-persistent 13228 * processes) from sending protected broadcasts. 13229 */ 13230 int callingAppId = UserHandle.getAppId(callingUid); 13231 if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID 13232 || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID || 13233 callingUid == 0) { 13234 // Always okay. 13235 } else if (callerApp == null || !callerApp.persistent) { 13236 try { 13237 if (AppGlobals.getPackageManager().isProtectedBroadcast( 13238 intent.getAction())) { 13239 String msg = "Permission Denial: not allowed to send broadcast " 13240 + intent.getAction() + " from pid=" 13241 + callingPid + ", uid=" + callingUid; 13242 Slog.w(TAG, msg); 13243 throw new SecurityException(msg); 13244 } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) { 13245 // Special case for compatibility: we don't want apps to send this, 13246 // but historically it has not been protected and apps may be using it 13247 // to poke their own app widget. So, instead of making it protected, 13248 // just limit it to the caller. 13249 if (callerApp == null) { 13250 String msg = "Permission Denial: not allowed to send broadcast " 13251 + intent.getAction() + " from unknown caller."; 13252 Slog.w(TAG, msg); 13253 throw new SecurityException(msg); 13254 } else if (intent.getComponent() != null) { 13255 // They are good enough to send to an explicit component... verify 13256 // it is being sent to the calling app. 13257 if (!intent.getComponent().getPackageName().equals( 13258 callerApp.info.packageName)) { 13259 String msg = "Permission Denial: not allowed to send broadcast " 13260 + intent.getAction() + " to " 13261 + intent.getComponent().getPackageName() + " from " 13262 + callerApp.info.packageName; 13263 Slog.w(TAG, msg); 13264 throw new SecurityException(msg); 13265 } 13266 } else { 13267 // Limit broadcast to their own package. 13268 intent.setPackage(callerApp.info.packageName); 13269 } 13270 } 13271 } catch (RemoteException e) { 13272 Slog.w(TAG, "Remote exception", e); 13273 return ActivityManager.BROADCAST_SUCCESS; 13274 } 13275 } 13276 13277 // Handle special intents: if this broadcast is from the package 13278 // manager about a package being removed, we need to remove all of 13279 // its activities from the history stack. 13280 final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals( 13281 intent.getAction()); 13282 if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction()) 13283 || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction()) 13284 || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction()) 13285 || uidRemoved) { 13286 if (checkComponentPermission( 13287 android.Manifest.permission.BROADCAST_PACKAGE_REMOVED, 13288 callingPid, callingUid, -1, true) 13289 == PackageManager.PERMISSION_GRANTED) { 13290 if (uidRemoved) { 13291 final Bundle intentExtras = intent.getExtras(); 13292 final int uid = intentExtras != null 13293 ? intentExtras.getInt(Intent.EXTRA_UID) : -1; 13294 if (uid >= 0) { 13295 BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics(); 13296 synchronized (bs) { 13297 bs.removeUidStatsLocked(uid); 13298 } 13299 mAppOpsService.uidRemoved(uid); 13300 } 13301 } else { 13302 // If resources are unavailable just force stop all 13303 // those packages and flush the attribute cache as well. 13304 if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) { 13305 String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 13306 if (list != null && (list.length > 0)) { 13307 for (String pkg : list) { 13308 forceStopPackageLocked(pkg, -1, false, true, true, false, userId, 13309 "storage unmount"); 13310 } 13311 sendPackageBroadcastLocked( 13312 IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId); 13313 } 13314 } else { 13315 Uri data = intent.getData(); 13316 String ssp; 13317 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 13318 boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals( 13319 intent.getAction()); 13320 if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) { 13321 forceStopPackageLocked(ssp, UserHandle.getAppId( 13322 intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true, 13323 false, userId, removed ? "pkg removed" : "pkg changed"); 13324 } 13325 if (removed) { 13326 sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED, 13327 new String[] {ssp}, userId); 13328 if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) { 13329 mAppOpsService.packageRemoved( 13330 intent.getIntExtra(Intent.EXTRA_UID, -1), ssp); 13331 13332 // Remove all permissions granted from/to this package 13333 removeUriPermissionsForPackageLocked(ssp, userId, true); 13334 } 13335 } 13336 } 13337 } 13338 } 13339 } else { 13340 String msg = "Permission Denial: " + intent.getAction() 13341 + " broadcast from " + callerPackage + " (pid=" + callingPid 13342 + ", uid=" + callingUid + ")" 13343 + " requires " 13344 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED; 13345 Slog.w(TAG, msg); 13346 throw new SecurityException(msg); 13347 } 13348 13349 // Special case for adding a package: by default turn on compatibility 13350 // mode. 13351 } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) { 13352 Uri data = intent.getData(); 13353 String ssp; 13354 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 13355 mCompatModePackages.handlePackageAddedLocked(ssp, 13356 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)); 13357 } 13358 } 13359 13360 /* 13361 * If this is the time zone changed action, queue up a message that will reset the timezone 13362 * of all currently running processes. This message will get queued up before the broadcast 13363 * happens. 13364 */ 13365 if (Intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) { 13366 mHandler.sendEmptyMessage(UPDATE_TIME_ZONE); 13367 } 13368 13369 /* 13370 * If the user set the time, let all running processes know. 13371 */ 13372 if (Intent.ACTION_TIME_CHANGED.equals(intent.getAction())) { 13373 final int is24Hour = intent.getBooleanExtra( 13374 Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1 : 0; 13375 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0)); 13376 } 13377 13378 if (Intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) { 13379 mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG); 13380 } 13381 13382 if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) { 13383 ProxyProperties proxy = intent.getParcelableExtra("proxy"); 13384 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy)); 13385 } 13386 13387 // Add to the sticky list if requested. 13388 if (sticky) { 13389 if (checkPermission(android.Manifest.permission.BROADCAST_STICKY, 13390 callingPid, callingUid) 13391 != PackageManager.PERMISSION_GRANTED) { 13392 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid=" 13393 + callingPid + ", uid=" + callingUid 13394 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 13395 Slog.w(TAG, msg); 13396 throw new SecurityException(msg); 13397 } 13398 if (requiredPermission != null) { 13399 Slog.w(TAG, "Can't broadcast sticky intent " + intent 13400 + " and enforce permission " + requiredPermission); 13401 return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION; 13402 } 13403 if (intent.getComponent() != null) { 13404 throw new SecurityException( 13405 "Sticky broadcasts can't target a specific component"); 13406 } 13407 // We use userId directly here, since the "all" target is maintained 13408 // as a separate set of sticky broadcasts. 13409 if (userId != UserHandle.USER_ALL) { 13410 // But first, if this is not a broadcast to all users, then 13411 // make sure it doesn't conflict with an existing broadcast to 13412 // all users. 13413 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get( 13414 UserHandle.USER_ALL); 13415 if (stickies != null) { 13416 ArrayList<Intent> list = stickies.get(intent.getAction()); 13417 if (list != null) { 13418 int N = list.size(); 13419 int i; 13420 for (i=0; i<N; i++) { 13421 if (intent.filterEquals(list.get(i))) { 13422 throw new IllegalArgumentException( 13423 "Sticky broadcast " + intent + " for user " 13424 + userId + " conflicts with existing global broadcast"); 13425 } 13426 } 13427 } 13428 } 13429 } 13430 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 13431 if (stickies == null) { 13432 stickies = new ArrayMap<String, ArrayList<Intent>>(); 13433 mStickyBroadcasts.put(userId, stickies); 13434 } 13435 ArrayList<Intent> list = stickies.get(intent.getAction()); 13436 if (list == null) { 13437 list = new ArrayList<Intent>(); 13438 stickies.put(intent.getAction(), list); 13439 } 13440 int N = list.size(); 13441 int i; 13442 for (i=0; i<N; i++) { 13443 if (intent.filterEquals(list.get(i))) { 13444 // This sticky already exists, replace it. 13445 list.set(i, new Intent(intent)); 13446 break; 13447 } 13448 } 13449 if (i >= N) { 13450 list.add(new Intent(intent)); 13451 } 13452 } 13453 13454 int[] users; 13455 if (userId == UserHandle.USER_ALL) { 13456 // Caller wants broadcast to go to all started users. 13457 users = mStartedUserArray; 13458 } else { 13459 // Caller wants broadcast to go to one specific user. 13460 users = new int[] {userId}; 13461 } 13462 13463 // Figure out who all will receive this broadcast. 13464 List receivers = null; 13465 List<BroadcastFilter> registeredReceivers = null; 13466 // Need to resolve the intent to interested receivers... 13467 if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) 13468 == 0) { 13469 receivers = collectReceiverComponents(intent, resolvedType, users); 13470 } 13471 if (intent.getComponent() == null) { 13472 registeredReceivers = mReceiverResolver.queryIntent(intent, 13473 resolvedType, false, userId); 13474 } 13475 13476 final boolean replacePending = 13477 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0; 13478 13479 if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction() 13480 + " replacePending=" + replacePending); 13481 13482 int NR = registeredReceivers != null ? registeredReceivers.size() : 0; 13483 if (!ordered && NR > 0) { 13484 // If we are not serializing this broadcast, then send the 13485 // registered receivers separately so they don't wait for the 13486 // components to be launched. 13487 final BroadcastQueue queue = broadcastQueueForIntent(intent); 13488 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 13489 callerPackage, callingPid, callingUid, resolvedType, requiredPermission, 13490 appOp, registeredReceivers, resultTo, resultCode, resultData, map, 13491 ordered, sticky, false, userId); 13492 if (DEBUG_BROADCAST) Slog.v( 13493 TAG, "Enqueueing parallel broadcast " + r); 13494 final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r); 13495 if (!replaced) { 13496 queue.enqueueParallelBroadcastLocked(r); 13497 queue.scheduleBroadcastsLocked(); 13498 } 13499 registeredReceivers = null; 13500 NR = 0; 13501 } 13502 13503 // Merge into one list. 13504 int ir = 0; 13505 if (receivers != null) { 13506 // A special case for PACKAGE_ADDED: do not allow the package 13507 // being added to see this broadcast. This prevents them from 13508 // using this as a back door to get run as soon as they are 13509 // installed. Maybe in the future we want to have a special install 13510 // broadcast or such for apps, but we'd like to deliberately make 13511 // this decision. 13512 String skipPackages[] = null; 13513 if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction()) 13514 || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction()) 13515 || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) { 13516 Uri data = intent.getData(); 13517 if (data != null) { 13518 String pkgName = data.getSchemeSpecificPart(); 13519 if (pkgName != null) { 13520 skipPackages = new String[] { pkgName }; 13521 } 13522 } 13523 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) { 13524 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 13525 } 13526 if (skipPackages != null && (skipPackages.length > 0)) { 13527 for (String skipPackage : skipPackages) { 13528 if (skipPackage != null) { 13529 int NT = receivers.size(); 13530 for (int it=0; it<NT; it++) { 13531 ResolveInfo curt = (ResolveInfo)receivers.get(it); 13532 if (curt.activityInfo.packageName.equals(skipPackage)) { 13533 receivers.remove(it); 13534 it--; 13535 NT--; 13536 } 13537 } 13538 } 13539 } 13540 } 13541 13542 int NT = receivers != null ? receivers.size() : 0; 13543 int it = 0; 13544 ResolveInfo curt = null; 13545 BroadcastFilter curr = null; 13546 while (it < NT && ir < NR) { 13547 if (curt == null) { 13548 curt = (ResolveInfo)receivers.get(it); 13549 } 13550 if (curr == null) { 13551 curr = registeredReceivers.get(ir); 13552 } 13553 if (curr.getPriority() >= curt.priority) { 13554 // Insert this broadcast record into the final list. 13555 receivers.add(it, curr); 13556 ir++; 13557 curr = null; 13558 it++; 13559 NT++; 13560 } else { 13561 // Skip to the next ResolveInfo in the final list. 13562 it++; 13563 curt = null; 13564 } 13565 } 13566 } 13567 while (ir < NR) { 13568 if (receivers == null) { 13569 receivers = new ArrayList(); 13570 } 13571 receivers.add(registeredReceivers.get(ir)); 13572 ir++; 13573 } 13574 13575 if ((receivers != null && receivers.size() > 0) 13576 || resultTo != null) { 13577 BroadcastQueue queue = broadcastQueueForIntent(intent); 13578 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 13579 callerPackage, callingPid, callingUid, resolvedType, 13580 requiredPermission, appOp, receivers, resultTo, resultCode, 13581 resultData, map, ordered, sticky, false, userId); 13582 if (DEBUG_BROADCAST) Slog.v( 13583 TAG, "Enqueueing ordered broadcast " + r 13584 + ": prev had " + queue.mOrderedBroadcasts.size()); 13585 if (DEBUG_BROADCAST) { 13586 int seq = r.intent.getIntExtra("seq", -1); 13587 Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq); 13588 } 13589 boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r); 13590 if (!replaced) { 13591 queue.enqueueOrderedBroadcastLocked(r); 13592 queue.scheduleBroadcastsLocked(); 13593 } 13594 } 13595 13596 return ActivityManager.BROADCAST_SUCCESS; 13597 } 13598 13599 final Intent verifyBroadcastLocked(Intent intent) { 13600 // Refuse possible leaked file descriptors 13601 if (intent != null && intent.hasFileDescriptors() == true) { 13602 throw new IllegalArgumentException("File descriptors passed in Intent"); 13603 } 13604 13605 int flags = intent.getFlags(); 13606 13607 if (!mProcessesReady) { 13608 // if the caller really truly claims to know what they're doing, go 13609 // ahead and allow the broadcast without launching any receivers 13610 if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) { 13611 intent = new Intent(intent); 13612 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 13613 } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) { 13614 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent 13615 + " before boot completion"); 13616 throw new IllegalStateException("Cannot broadcast before boot completed"); 13617 } 13618 } 13619 13620 if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 13621 throw new IllegalArgumentException( 13622 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 13623 } 13624 13625 return intent; 13626 } 13627 13628 public final int broadcastIntent(IApplicationThread caller, 13629 Intent intent, String resolvedType, IIntentReceiver resultTo, 13630 int resultCode, String resultData, Bundle map, 13631 String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) { 13632 enforceNotIsolatedCaller("broadcastIntent"); 13633 synchronized(this) { 13634 intent = verifyBroadcastLocked(intent); 13635 13636 final ProcessRecord callerApp = getRecordForAppLocked(caller); 13637 final int callingPid = Binder.getCallingPid(); 13638 final int callingUid = Binder.getCallingUid(); 13639 final long origId = Binder.clearCallingIdentity(); 13640 int res = broadcastIntentLocked(callerApp, 13641 callerApp != null ? callerApp.info.packageName : null, 13642 intent, resolvedType, resultTo, 13643 resultCode, resultData, map, requiredPermission, appOp, serialized, sticky, 13644 callingPid, callingUid, userId); 13645 Binder.restoreCallingIdentity(origId); 13646 return res; 13647 } 13648 } 13649 13650 int broadcastIntentInPackage(String packageName, int uid, 13651 Intent intent, String resolvedType, IIntentReceiver resultTo, 13652 int resultCode, String resultData, Bundle map, 13653 String requiredPermission, boolean serialized, boolean sticky, int userId) { 13654 synchronized(this) { 13655 intent = verifyBroadcastLocked(intent); 13656 13657 final long origId = Binder.clearCallingIdentity(); 13658 int res = broadcastIntentLocked(null, packageName, intent, resolvedType, 13659 resultTo, resultCode, resultData, map, requiredPermission, 13660 AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId); 13661 Binder.restoreCallingIdentity(origId); 13662 return res; 13663 } 13664 } 13665 13666 public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) { 13667 // Refuse possible leaked file descriptors 13668 if (intent != null && intent.hasFileDescriptors() == true) { 13669 throw new IllegalArgumentException("File descriptors passed in Intent"); 13670 } 13671 13672 userId = handleIncomingUser(Binder.getCallingPid(), 13673 Binder.getCallingUid(), userId, true, false, "removeStickyBroadcast", null); 13674 13675 synchronized(this) { 13676 if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY) 13677 != PackageManager.PERMISSION_GRANTED) { 13678 String msg = "Permission Denial: unbroadcastIntent() from pid=" 13679 + Binder.getCallingPid() 13680 + ", uid=" + Binder.getCallingUid() 13681 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 13682 Slog.w(TAG, msg); 13683 throw new SecurityException(msg); 13684 } 13685 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 13686 if (stickies != null) { 13687 ArrayList<Intent> list = stickies.get(intent.getAction()); 13688 if (list != null) { 13689 int N = list.size(); 13690 int i; 13691 for (i=0; i<N; i++) { 13692 if (intent.filterEquals(list.get(i))) { 13693 list.remove(i); 13694 break; 13695 } 13696 } 13697 if (list.size() <= 0) { 13698 stickies.remove(intent.getAction()); 13699 } 13700 } 13701 if (stickies.size() <= 0) { 13702 mStickyBroadcasts.remove(userId); 13703 } 13704 } 13705 } 13706 } 13707 13708 private final boolean finishReceiverLocked(IBinder receiver, int resultCode, 13709 String resultData, Bundle resultExtras, boolean resultAbort) { 13710 final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver); 13711 if (r == null) { 13712 Slog.w(TAG, "finishReceiver called but not found on queue"); 13713 return false; 13714 } 13715 13716 return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false); 13717 } 13718 13719 void backgroundServicesFinishedLocked(int userId) { 13720 for (BroadcastQueue queue : mBroadcastQueues) { 13721 queue.backgroundServicesFinishedLocked(userId); 13722 } 13723 } 13724 13725 public void finishReceiver(IBinder who, int resultCode, String resultData, 13726 Bundle resultExtras, boolean resultAbort) { 13727 if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who); 13728 13729 // Refuse possible leaked file descriptors 13730 if (resultExtras != null && resultExtras.hasFileDescriptors()) { 13731 throw new IllegalArgumentException("File descriptors passed in Bundle"); 13732 } 13733 13734 final long origId = Binder.clearCallingIdentity(); 13735 try { 13736 boolean doNext = false; 13737 BroadcastRecord r; 13738 13739 synchronized(this) { 13740 r = broadcastRecordForReceiverLocked(who); 13741 if (r != null) { 13742 doNext = r.queue.finishReceiverLocked(r, resultCode, 13743 resultData, resultExtras, resultAbort, true); 13744 } 13745 } 13746 13747 if (doNext) { 13748 r.queue.processNextBroadcast(false); 13749 } 13750 trimApplications(); 13751 } finally { 13752 Binder.restoreCallingIdentity(origId); 13753 } 13754 } 13755 13756 // ========================================================= 13757 // INSTRUMENTATION 13758 // ========================================================= 13759 13760 public boolean startInstrumentation(ComponentName className, 13761 String profileFile, int flags, Bundle arguments, 13762 IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection, 13763 int userId, String abiOverride) { 13764 enforceNotIsolatedCaller("startInstrumentation"); 13765 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 13766 userId, false, true, "startInstrumentation", null); 13767 // Refuse possible leaked file descriptors 13768 if (arguments != null && arguments.hasFileDescriptors()) { 13769 throw new IllegalArgumentException("File descriptors passed in Bundle"); 13770 } 13771 13772 synchronized(this) { 13773 InstrumentationInfo ii = null; 13774 ApplicationInfo ai = null; 13775 try { 13776 ii = mContext.getPackageManager().getInstrumentationInfo( 13777 className, STOCK_PM_FLAGS); 13778 ai = AppGlobals.getPackageManager().getApplicationInfo( 13779 ii.targetPackage, STOCK_PM_FLAGS, userId); 13780 } catch (PackageManager.NameNotFoundException e) { 13781 } catch (RemoteException e) { 13782 } 13783 if (ii == null) { 13784 reportStartInstrumentationFailure(watcher, className, 13785 "Unable to find instrumentation info for: " + className); 13786 return false; 13787 } 13788 if (ai == null) { 13789 reportStartInstrumentationFailure(watcher, className, 13790 "Unable to find instrumentation target package: " + ii.targetPackage); 13791 return false; 13792 } 13793 13794 int match = mContext.getPackageManager().checkSignatures( 13795 ii.targetPackage, ii.packageName); 13796 if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) { 13797 String msg = "Permission Denial: starting instrumentation " 13798 + className + " from pid=" 13799 + Binder.getCallingPid() 13800 + ", uid=" + Binder.getCallingPid() 13801 + " not allowed because package " + ii.packageName 13802 + " does not have a signature matching the target " 13803 + ii.targetPackage; 13804 reportStartInstrumentationFailure(watcher, className, msg); 13805 throw new SecurityException(msg); 13806 } 13807 13808 final long origId = Binder.clearCallingIdentity(); 13809 // Instrumentation can kill and relaunch even persistent processes 13810 forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, userId, 13811 "start instr"); 13812 ProcessRecord app = addAppLocked(ai, false, abiOverride); 13813 app.instrumentationClass = className; 13814 app.instrumentationInfo = ai; 13815 app.instrumentationProfileFile = profileFile; 13816 app.instrumentationArguments = arguments; 13817 app.instrumentationWatcher = watcher; 13818 app.instrumentationUiAutomationConnection = uiAutomationConnection; 13819 app.instrumentationResultClass = className; 13820 Binder.restoreCallingIdentity(origId); 13821 } 13822 13823 return true; 13824 } 13825 13826 /** 13827 * Report errors that occur while attempting to start Instrumentation. Always writes the 13828 * error to the logs, but if somebody is watching, send the report there too. This enables 13829 * the "am" command to report errors with more information. 13830 * 13831 * @param watcher The IInstrumentationWatcher. Null if there isn't one. 13832 * @param cn The component name of the instrumentation. 13833 * @param report The error report. 13834 */ 13835 private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher, 13836 ComponentName cn, String report) { 13837 Slog.w(TAG, report); 13838 try { 13839 if (watcher != null) { 13840 Bundle results = new Bundle(); 13841 results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService"); 13842 results.putString("Error", report); 13843 watcher.instrumentationStatus(cn, -1, results); 13844 } 13845 } catch (RemoteException e) { 13846 Slog.w(TAG, e); 13847 } 13848 } 13849 13850 void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) { 13851 if (app.instrumentationWatcher != null) { 13852 try { 13853 // NOTE: IInstrumentationWatcher *must* be oneway here 13854 app.instrumentationWatcher.instrumentationFinished( 13855 app.instrumentationClass, 13856 resultCode, 13857 results); 13858 } catch (RemoteException e) { 13859 } 13860 } 13861 if (app.instrumentationUiAutomationConnection != null) { 13862 try { 13863 app.instrumentationUiAutomationConnection.shutdown(); 13864 } catch (RemoteException re) { 13865 /* ignore */ 13866 } 13867 // Only a UiAutomation can set this flag and now that 13868 // it is finished we make sure it is reset to its default. 13869 mUserIsMonkey = false; 13870 } 13871 app.instrumentationWatcher = null; 13872 app.instrumentationUiAutomationConnection = null; 13873 app.instrumentationClass = null; 13874 app.instrumentationInfo = null; 13875 app.instrumentationProfileFile = null; 13876 app.instrumentationArguments = null; 13877 13878 forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, app.userId, 13879 "finished inst"); 13880 } 13881 13882 public void finishInstrumentation(IApplicationThread target, 13883 int resultCode, Bundle results) { 13884 int userId = UserHandle.getCallingUserId(); 13885 // Refuse possible leaked file descriptors 13886 if (results != null && results.hasFileDescriptors()) { 13887 throw new IllegalArgumentException("File descriptors passed in Intent"); 13888 } 13889 13890 synchronized(this) { 13891 ProcessRecord app = getRecordForAppLocked(target); 13892 if (app == null) { 13893 Slog.w(TAG, "finishInstrumentation: no app for " + target); 13894 return; 13895 } 13896 final long origId = Binder.clearCallingIdentity(); 13897 finishInstrumentationLocked(app, resultCode, results); 13898 Binder.restoreCallingIdentity(origId); 13899 } 13900 } 13901 13902 // ========================================================= 13903 // CONFIGURATION 13904 // ========================================================= 13905 13906 public ConfigurationInfo getDeviceConfigurationInfo() { 13907 ConfigurationInfo config = new ConfigurationInfo(); 13908 synchronized (this) { 13909 config.reqTouchScreen = mConfiguration.touchscreen; 13910 config.reqKeyboardType = mConfiguration.keyboard; 13911 config.reqNavigation = mConfiguration.navigation; 13912 if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD 13913 || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) { 13914 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV; 13915 } 13916 if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED 13917 && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) { 13918 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD; 13919 } 13920 config.reqGlEsVersion = GL_ES_VERSION; 13921 } 13922 return config; 13923 } 13924 13925 ActivityStack getFocusedStack() { 13926 return mStackSupervisor.getFocusedStack(); 13927 } 13928 13929 public Configuration getConfiguration() { 13930 Configuration ci; 13931 synchronized(this) { 13932 ci = new Configuration(mConfiguration); 13933 } 13934 return ci; 13935 } 13936 13937 public void updatePersistentConfiguration(Configuration values) { 13938 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 13939 "updateConfiguration()"); 13940 enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS, 13941 "updateConfiguration()"); 13942 if (values == null) { 13943 throw new NullPointerException("Configuration must not be null"); 13944 } 13945 13946 synchronized(this) { 13947 final long origId = Binder.clearCallingIdentity(); 13948 updateConfigurationLocked(values, null, true, false); 13949 Binder.restoreCallingIdentity(origId); 13950 } 13951 } 13952 13953 public void updateConfiguration(Configuration values) { 13954 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 13955 "updateConfiguration()"); 13956 13957 synchronized(this) { 13958 if (values == null && mWindowManager != null) { 13959 // sentinel: fetch the current configuration from the window manager 13960 values = mWindowManager.computeNewConfiguration(); 13961 } 13962 13963 if (mWindowManager != null) { 13964 mProcessList.applyDisplaySize(mWindowManager); 13965 } 13966 13967 final long origId = Binder.clearCallingIdentity(); 13968 if (values != null) { 13969 Settings.System.clearConfiguration(values); 13970 } 13971 updateConfigurationLocked(values, null, false, false); 13972 Binder.restoreCallingIdentity(origId); 13973 } 13974 } 13975 13976 /** 13977 * Do either or both things: (1) change the current configuration, and (2) 13978 * make sure the given activity is running with the (now) current 13979 * configuration. Returns true if the activity has been left running, or 13980 * false if <var>starting</var> is being destroyed to match the new 13981 * configuration. 13982 * @param persistent TODO 13983 */ 13984 boolean updateConfigurationLocked(Configuration values, 13985 ActivityRecord starting, boolean persistent, boolean initLocale) { 13986 int changes = 0; 13987 13988 if (values != null) { 13989 Configuration newConfig = new Configuration(mConfiguration); 13990 changes = newConfig.updateFrom(values); 13991 if (changes != 0) { 13992 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) { 13993 Slog.i(TAG, "Updating configuration to: " + values); 13994 } 13995 13996 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes); 13997 13998 if (values.locale != null && !initLocale) { 13999 saveLocaleLocked(values.locale, 14000 !values.locale.equals(mConfiguration.locale), 14001 values.userSetLocale); 14002 } 14003 14004 mConfigurationSeq++; 14005 if (mConfigurationSeq <= 0) { 14006 mConfigurationSeq = 1; 14007 } 14008 newConfig.seq = mConfigurationSeq; 14009 mConfiguration = newConfig; 14010 Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig); 14011 14012 final Configuration configCopy = new Configuration(mConfiguration); 14013 14014 // TODO: If our config changes, should we auto dismiss any currently 14015 // showing dialogs? 14016 mShowDialogs = shouldShowDialogs(newConfig); 14017 14018 AttributeCache ac = AttributeCache.instance(); 14019 if (ac != null) { 14020 ac.updateConfiguration(configCopy); 14021 } 14022 14023 // Make sure all resources in our process are updated 14024 // right now, so that anyone who is going to retrieve 14025 // resource values after we return will be sure to get 14026 // the new ones. This is especially important during 14027 // boot, where the first config change needs to guarantee 14028 // all resources have that config before following boot 14029 // code is executed. 14030 mSystemThread.applyConfigurationToResources(configCopy); 14031 14032 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) { 14033 Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG); 14034 msg.obj = new Configuration(configCopy); 14035 mHandler.sendMessage(msg); 14036 } 14037 14038 for (int i=mLruProcesses.size()-1; i>=0; i--) { 14039 ProcessRecord app = mLruProcesses.get(i); 14040 try { 14041 if (app.thread != null) { 14042 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc " 14043 + app.processName + " new config " + mConfiguration); 14044 app.thread.scheduleConfigurationChanged(configCopy); 14045 } 14046 } catch (Exception e) { 14047 } 14048 } 14049 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED); 14050 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 14051 | Intent.FLAG_RECEIVER_REPLACE_PENDING 14052 | Intent.FLAG_RECEIVER_FOREGROUND); 14053 broadcastIntentLocked(null, null, intent, null, null, 0, null, null, 14054 null, AppOpsManager.OP_NONE, false, false, MY_PID, 14055 Process.SYSTEM_UID, UserHandle.USER_ALL); 14056 if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) { 14057 intent = new Intent(Intent.ACTION_LOCALE_CHANGED); 14058 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 14059 broadcastIntentLocked(null, null, intent, 14060 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 14061 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 14062 } 14063 } 14064 } 14065 14066 boolean kept = true; 14067 final ActivityStack mainStack = mStackSupervisor.getFocusedStack(); 14068 // mainStack is null during startup. 14069 if (mainStack != null) { 14070 if (changes != 0 && starting == null) { 14071 // If the configuration changed, and the caller is not already 14072 // in the process of starting an activity, then find the top 14073 // activity to check if its configuration needs to change. 14074 starting = mainStack.topRunningActivityLocked(null); 14075 } 14076 14077 if (starting != null) { 14078 kept = mainStack.ensureActivityConfigurationLocked(starting, changes); 14079 // And we need to make sure at this point that all other activities 14080 // are made visible with the correct configuration. 14081 mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes); 14082 } 14083 } 14084 14085 if (values != null && mWindowManager != null) { 14086 mWindowManager.setNewConfiguration(mConfiguration); 14087 } 14088 14089 return kept; 14090 } 14091 14092 /** 14093 * Decide based on the configuration whether we should shouw the ANR, 14094 * crash, etc dialogs. The idea is that if there is no affordnace to 14095 * press the on-screen buttons, we shouldn't show the dialog. 14096 * 14097 * A thought: SystemUI might also want to get told about this, the Power 14098 * dialog / global actions also might want different behaviors. 14099 */ 14100 private static final boolean shouldShowDialogs(Configuration config) { 14101 return !(config.keyboard == Configuration.KEYBOARD_NOKEYS 14102 && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH); 14103 } 14104 14105 /** 14106 * Save the locale. You must be inside a synchronized (this) block. 14107 */ 14108 private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) { 14109 if(isDiff) { 14110 SystemProperties.set("user.language", l.getLanguage()); 14111 SystemProperties.set("user.region", l.getCountry()); 14112 } 14113 14114 if(isPersist) { 14115 SystemProperties.set("persist.sys.language", l.getLanguage()); 14116 SystemProperties.set("persist.sys.country", l.getCountry()); 14117 SystemProperties.set("persist.sys.localevar", l.getVariant()); 14118 } 14119 } 14120 14121 @Override 14122 public boolean targetTaskAffinityMatchesActivity(IBinder token, String destAffinity) { 14123 ActivityRecord srec = ActivityRecord.forToken(token); 14124 return srec != null && srec.task.affinity != null && 14125 srec.task.affinity.equals(destAffinity); 14126 } 14127 14128 public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode, 14129 Intent resultData) { 14130 14131 synchronized (this) { 14132 final ActivityStack stack = ActivityRecord.getStackLocked(token); 14133 if (stack != null) { 14134 return stack.navigateUpToLocked(token, destIntent, resultCode, resultData); 14135 } 14136 return false; 14137 } 14138 } 14139 14140 public int getLaunchedFromUid(IBinder activityToken) { 14141 ActivityRecord srec = ActivityRecord.forToken(activityToken); 14142 if (srec == null) { 14143 return -1; 14144 } 14145 return srec.launchedFromUid; 14146 } 14147 14148 public String getLaunchedFromPackage(IBinder activityToken) { 14149 ActivityRecord srec = ActivityRecord.forToken(activityToken); 14150 if (srec == null) { 14151 return null; 14152 } 14153 return srec.launchedFromPackage; 14154 } 14155 14156 // ========================================================= 14157 // LIFETIME MANAGEMENT 14158 // ========================================================= 14159 14160 // Returns which broadcast queue the app is the current [or imminent] receiver 14161 // on, or 'null' if the app is not an active broadcast recipient. 14162 private BroadcastQueue isReceivingBroadcast(ProcessRecord app) { 14163 BroadcastRecord r = app.curReceiver; 14164 if (r != null) { 14165 return r.queue; 14166 } 14167 14168 // It's not the current receiver, but it might be starting up to become one 14169 synchronized (this) { 14170 for (BroadcastQueue queue : mBroadcastQueues) { 14171 r = queue.mPendingBroadcast; 14172 if (r != null && r.curApp == app) { 14173 // found it; report which queue it's in 14174 return queue; 14175 } 14176 } 14177 } 14178 14179 return null; 14180 } 14181 14182 private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP, 14183 boolean doingAll, long now) { 14184 if (mAdjSeq == app.adjSeq) { 14185 // This adjustment has already been computed. 14186 return app.curRawAdj; 14187 } 14188 14189 if (app.thread == null) { 14190 app.adjSeq = mAdjSeq; 14191 app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 14192 app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 14193 return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ); 14194 } 14195 14196 app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN; 14197 app.adjSource = null; 14198 app.adjTarget = null; 14199 app.empty = false; 14200 app.cached = false; 14201 14202 final int activitiesSize = app.activities.size(); 14203 14204 if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) { 14205 // The max adjustment doesn't allow this app to be anything 14206 // below foreground, so it is not worth doing work for it. 14207 app.adjType = "fixed"; 14208 app.adjSeq = mAdjSeq; 14209 app.curRawAdj = app.maxAdj; 14210 app.foregroundActivities = false; 14211 app.keeping = true; 14212 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT; 14213 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT; 14214 // System process can do UI, and when they do we want to have 14215 // them trim their memory after the user leaves the UI. To 14216 // facilitate this, here we need to determine whether or not it 14217 // is currently showing UI. 14218 app.systemNoUi = true; 14219 if (app == TOP_APP) { 14220 app.systemNoUi = false; 14221 } else if (activitiesSize > 0) { 14222 for (int j = 0; j < activitiesSize; j++) { 14223 final ActivityRecord r = app.activities.get(j); 14224 if (r.visible) { 14225 app.systemNoUi = false; 14226 } 14227 } 14228 } 14229 if (!app.systemNoUi) { 14230 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI; 14231 } 14232 return (app.curAdj=app.maxAdj); 14233 } 14234 14235 app.keeping = false; 14236 app.systemNoUi = false; 14237 14238 // Determine the importance of the process, starting with most 14239 // important to least, and assign an appropriate OOM adjustment. 14240 int adj; 14241 int schedGroup; 14242 int procState; 14243 boolean foregroundActivities = false; 14244 boolean interesting = false; 14245 BroadcastQueue queue; 14246 if (app == TOP_APP) { 14247 // The last app on the list is the foreground app. 14248 adj = ProcessList.FOREGROUND_APP_ADJ; 14249 schedGroup = Process.THREAD_GROUP_DEFAULT; 14250 app.adjType = "top-activity"; 14251 foregroundActivities = true; 14252 interesting = true; 14253 procState = ActivityManager.PROCESS_STATE_TOP; 14254 } else if (app.instrumentationClass != null) { 14255 // Don't want to kill running instrumentation. 14256 adj = ProcessList.FOREGROUND_APP_ADJ; 14257 schedGroup = Process.THREAD_GROUP_DEFAULT; 14258 app.adjType = "instrumentation"; 14259 interesting = true; 14260 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14261 } else if ((queue = isReceivingBroadcast(app)) != null) { 14262 // An app that is currently receiving a broadcast also 14263 // counts as being in the foreground for OOM killer purposes. 14264 // It's placed in a sched group based on the nature of the 14265 // broadcast as reflected by which queue it's active in. 14266 adj = ProcessList.FOREGROUND_APP_ADJ; 14267 schedGroup = (queue == mFgBroadcastQueue) 14268 ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 14269 app.adjType = "broadcast"; 14270 procState = ActivityManager.PROCESS_STATE_RECEIVER; 14271 } else if (app.executingServices.size() > 0) { 14272 // An app that is currently executing a service callback also 14273 // counts as being in the foreground. 14274 adj = ProcessList.FOREGROUND_APP_ADJ; 14275 schedGroup = app.execServicesFg ? 14276 Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 14277 app.adjType = "exec-service"; 14278 procState = ActivityManager.PROCESS_STATE_SERVICE; 14279 //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app); 14280 } else { 14281 // As far as we know the process is empty. We may change our mind later. 14282 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 14283 // At this point we don't actually know the adjustment. Use the cached adj 14284 // value that the caller wants us to. 14285 adj = cachedAdj; 14286 procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 14287 app.cached = true; 14288 app.empty = true; 14289 app.adjType = "cch-empty"; 14290 } 14291 14292 // Examine all activities if not already foreground. 14293 if (!foregroundActivities && activitiesSize > 0) { 14294 for (int j = 0; j < activitiesSize; j++) { 14295 final ActivityRecord r = app.activities.get(j); 14296 if (r.app != app) { 14297 Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc " 14298 + app + "?!?"); 14299 continue; 14300 } 14301 if (r.visible) { 14302 // App has a visible activity; only upgrade adjustment. 14303 if (adj > ProcessList.VISIBLE_APP_ADJ) { 14304 adj = ProcessList.VISIBLE_APP_ADJ; 14305 app.adjType = "visible"; 14306 } 14307 if (procState > ActivityManager.PROCESS_STATE_TOP) { 14308 procState = ActivityManager.PROCESS_STATE_TOP; 14309 } 14310 schedGroup = Process.THREAD_GROUP_DEFAULT; 14311 app.cached = false; 14312 app.empty = false; 14313 foregroundActivities = true; 14314 break; 14315 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) { 14316 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14317 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 14318 app.adjType = "pausing"; 14319 } 14320 if (procState > ActivityManager.PROCESS_STATE_TOP) { 14321 procState = ActivityManager.PROCESS_STATE_TOP; 14322 } 14323 schedGroup = Process.THREAD_GROUP_DEFAULT; 14324 app.cached = false; 14325 app.empty = false; 14326 foregroundActivities = true; 14327 } else if (r.state == ActivityState.STOPPING) { 14328 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14329 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 14330 app.adjType = "stopping"; 14331 } 14332 // For the process state, we will at this point consider the 14333 // process to be cached. It will be cached either as an activity 14334 // or empty depending on whether the activity is finishing. We do 14335 // this so that we can treat the process as cached for purposes of 14336 // memory trimming (determing current memory level, trim command to 14337 // send to process) since there can be an arbitrary number of stopping 14338 // processes and they should soon all go into the cached state. 14339 if (!r.finishing) { 14340 if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 14341 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 14342 } 14343 } 14344 app.cached = false; 14345 app.empty = false; 14346 foregroundActivities = true; 14347 } else { 14348 if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 14349 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 14350 app.adjType = "cch-act"; 14351 } 14352 } 14353 } 14354 } 14355 14356 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14357 if (app.foregroundServices) { 14358 // The user is aware of this app, so make it visible. 14359 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 14360 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14361 app.cached = false; 14362 app.adjType = "fg-service"; 14363 schedGroup = Process.THREAD_GROUP_DEFAULT; 14364 } else if (app.forcingToForeground != null) { 14365 // The user is aware of this app, so make it visible. 14366 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 14367 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14368 app.cached = false; 14369 app.adjType = "force-fg"; 14370 app.adjSource = app.forcingToForeground; 14371 schedGroup = Process.THREAD_GROUP_DEFAULT; 14372 } 14373 } 14374 14375 if (app.foregroundServices) { 14376 interesting = true; 14377 } 14378 14379 if (app == mHeavyWeightProcess) { 14380 if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) { 14381 // We don't want to kill the current heavy-weight process. 14382 adj = ProcessList.HEAVY_WEIGHT_APP_ADJ; 14383 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 14384 app.cached = false; 14385 app.adjType = "heavy"; 14386 } 14387 if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) { 14388 procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT; 14389 } 14390 } 14391 14392 if (app == mHomeProcess) { 14393 if (adj > ProcessList.HOME_APP_ADJ) { 14394 // This process is hosting what we currently consider to be the 14395 // home app, so we don't want to let it go into the background. 14396 adj = ProcessList.HOME_APP_ADJ; 14397 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 14398 app.cached = false; 14399 app.adjType = "home"; 14400 } 14401 if (procState > ActivityManager.PROCESS_STATE_HOME) { 14402 procState = ActivityManager.PROCESS_STATE_HOME; 14403 } 14404 } 14405 14406 if (app == mPreviousProcess && app.activities.size() > 0) { 14407 if (adj > ProcessList.PREVIOUS_APP_ADJ) { 14408 // This was the previous process that showed UI to the user. 14409 // We want to try to keep it around more aggressively, to give 14410 // a good experience around switching between two apps. 14411 adj = ProcessList.PREVIOUS_APP_ADJ; 14412 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 14413 app.cached = false; 14414 app.adjType = "previous"; 14415 } 14416 if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) { 14417 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY; 14418 } 14419 } 14420 14421 if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj 14422 + " reason=" + app.adjType); 14423 14424 // By default, we use the computed adjustment. It may be changed if 14425 // there are applications dependent on our services or providers, but 14426 // this gives us a baseline and makes sure we don't get into an 14427 // infinite recursion. 14428 app.adjSeq = mAdjSeq; 14429 app.curRawAdj = adj; 14430 app.hasStartedServices = false; 14431 14432 if (mBackupTarget != null && app == mBackupTarget.app) { 14433 // If possible we want to avoid killing apps while they're being backed up 14434 if (adj > ProcessList.BACKUP_APP_ADJ) { 14435 if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app); 14436 adj = ProcessList.BACKUP_APP_ADJ; 14437 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) { 14438 procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND; 14439 } 14440 app.adjType = "backup"; 14441 app.cached = false; 14442 } 14443 if (procState > ActivityManager.PROCESS_STATE_BACKUP) { 14444 procState = ActivityManager.PROCESS_STATE_BACKUP; 14445 } 14446 } 14447 14448 boolean mayBeTop = false; 14449 14450 for (int is = app.services.size()-1; 14451 is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 14452 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 14453 || procState > ActivityManager.PROCESS_STATE_TOP); 14454 is--) { 14455 ServiceRecord s = app.services.valueAt(is); 14456 if (s.startRequested) { 14457 app.hasStartedServices = true; 14458 if (procState > ActivityManager.PROCESS_STATE_SERVICE) { 14459 procState = ActivityManager.PROCESS_STATE_SERVICE; 14460 } 14461 if (app.hasShownUi && app != mHomeProcess) { 14462 // If this process has shown some UI, let it immediately 14463 // go to the LRU list because it may be pretty heavy with 14464 // UI stuff. We'll tag it with a label just to help 14465 // debug and understand what is going on. 14466 if (adj > ProcessList.SERVICE_ADJ) { 14467 app.adjType = "cch-started-ui-services"; 14468 } 14469 } else { 14470 if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) { 14471 // This service has seen some activity within 14472 // recent memory, so we will keep its process ahead 14473 // of the background processes. 14474 if (adj > ProcessList.SERVICE_ADJ) { 14475 adj = ProcessList.SERVICE_ADJ; 14476 app.adjType = "started-services"; 14477 app.cached = false; 14478 } 14479 } 14480 // If we have let the service slide into the background 14481 // state, still have some text describing what it is doing 14482 // even though the service no longer has an impact. 14483 if (adj > ProcessList.SERVICE_ADJ) { 14484 app.adjType = "cch-started-services"; 14485 } 14486 } 14487 // Don't kill this process because it is doing work; it 14488 // has said it is doing work. 14489 app.keeping = true; 14490 } 14491 for (int conni = s.connections.size()-1; 14492 conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 14493 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 14494 || procState > ActivityManager.PROCESS_STATE_TOP); 14495 conni--) { 14496 ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni); 14497 for (int i = 0; 14498 i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ 14499 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 14500 || procState > ActivityManager.PROCESS_STATE_TOP); 14501 i++) { 14502 // XXX should compute this based on the max of 14503 // all connected clients. 14504 ConnectionRecord cr = clist.get(i); 14505 if (cr.binding.client == app) { 14506 // Binding to ourself is not interesting. 14507 continue; 14508 } 14509 if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) { 14510 ProcessRecord client = cr.binding.client; 14511 int clientAdj = computeOomAdjLocked(client, cachedAdj, 14512 TOP_APP, doingAll, now); 14513 int clientProcState = client.curProcState; 14514 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 14515 // If the other app is cached for any reason, for purposes here 14516 // we are going to consider it empty. The specific cached state 14517 // doesn't propagate except under certain conditions. 14518 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 14519 } 14520 String adjType = null; 14521 if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) { 14522 // Not doing bind OOM management, so treat 14523 // this guy more like a started service. 14524 if (app.hasShownUi && app != mHomeProcess) { 14525 // If this process has shown some UI, let it immediately 14526 // go to the LRU list because it may be pretty heavy with 14527 // UI stuff. We'll tag it with a label just to help 14528 // debug and understand what is going on. 14529 if (adj > clientAdj) { 14530 adjType = "cch-bound-ui-services"; 14531 } 14532 app.cached = false; 14533 clientAdj = adj; 14534 clientProcState = procState; 14535 } else { 14536 if (now >= (s.lastActivity 14537 + ActiveServices.MAX_SERVICE_INACTIVITY)) { 14538 // This service has not seen activity within 14539 // recent memory, so allow it to drop to the 14540 // LRU list if there is no other reason to keep 14541 // it around. We'll also tag it with a label just 14542 // to help debug and undertand what is going on. 14543 if (adj > clientAdj) { 14544 adjType = "cch-bound-services"; 14545 } 14546 clientAdj = adj; 14547 } 14548 } 14549 } 14550 if (adj > clientAdj) { 14551 // If this process has recently shown UI, and 14552 // the process that is binding to it is less 14553 // important than being visible, then we don't 14554 // care about the binding as much as we care 14555 // about letting this process get into the LRU 14556 // list to be killed and restarted if needed for 14557 // memory. 14558 if (app.hasShownUi && app != mHomeProcess 14559 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14560 adjType = "cch-bound-ui-services"; 14561 } else { 14562 if ((cr.flags&(Context.BIND_ABOVE_CLIENT 14563 |Context.BIND_IMPORTANT)) != 0) { 14564 adj = clientAdj; 14565 } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0 14566 && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ 14567 && adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14568 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 14569 } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) { 14570 adj = clientAdj; 14571 } else { 14572 if (adj > ProcessList.VISIBLE_APP_ADJ) { 14573 adj = ProcessList.VISIBLE_APP_ADJ; 14574 } 14575 } 14576 if (!client.cached) { 14577 app.cached = false; 14578 } 14579 if (client.keeping) { 14580 app.keeping = true; 14581 } 14582 adjType = "service"; 14583 } 14584 } 14585 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 14586 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 14587 schedGroup = Process.THREAD_GROUP_DEFAULT; 14588 } 14589 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) { 14590 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) { 14591 // Special handling of clients who are in the top state. 14592 // We *may* want to consider this process to be in the 14593 // top state as well, but only if there is not another 14594 // reason for it to be running. Being on the top is a 14595 // special state, meaning you are specifically running 14596 // for the current top app. If the process is already 14597 // running in the background for some other reason, it 14598 // is more important to continue considering it to be 14599 // in the background state. 14600 mayBeTop = true; 14601 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 14602 } else { 14603 // Special handling for above-top states (persistent 14604 // processes). These should not bring the current process 14605 // into the top state, since they are not on top. Instead 14606 // give them the best state after that. 14607 clientProcState = 14608 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14609 } 14610 } 14611 } else { 14612 if (clientProcState < 14613 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) { 14614 clientProcState = 14615 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND; 14616 } 14617 } 14618 if (procState > clientProcState) { 14619 procState = clientProcState; 14620 } 14621 if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 14622 && (cr.flags&Context.BIND_SHOWING_UI) != 0) { 14623 app.pendingUiClean = true; 14624 } 14625 if (adjType != null) { 14626 app.adjType = adjType; 14627 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 14628 .REASON_SERVICE_IN_USE; 14629 app.adjSource = cr.binding.client; 14630 app.adjSourceOom = clientAdj; 14631 app.adjTarget = s.name; 14632 } 14633 } 14634 final ActivityRecord a = cr.activity; 14635 if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) { 14636 if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ && 14637 (a.visible || a.state == ActivityState.RESUMED 14638 || a.state == ActivityState.PAUSING)) { 14639 adj = ProcessList.FOREGROUND_APP_ADJ; 14640 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 14641 schedGroup = Process.THREAD_GROUP_DEFAULT; 14642 } 14643 app.cached = false; 14644 app.adjType = "service"; 14645 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 14646 .REASON_SERVICE_IN_USE; 14647 app.adjSource = a; 14648 app.adjSourceOom = adj; 14649 app.adjTarget = s.name; 14650 } 14651 } 14652 } 14653 } 14654 } 14655 14656 for (int provi = app.pubProviders.size()-1; 14657 provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 14658 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 14659 || procState > ActivityManager.PROCESS_STATE_TOP); 14660 provi--) { 14661 ContentProviderRecord cpr = app.pubProviders.valueAt(provi); 14662 for (int i = cpr.connections.size()-1; 14663 i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 14664 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 14665 || procState > ActivityManager.PROCESS_STATE_TOP); 14666 i--) { 14667 ContentProviderConnection conn = cpr.connections.get(i); 14668 ProcessRecord client = conn.client; 14669 if (client == app) { 14670 // Being our own client is not interesting. 14671 continue; 14672 } 14673 int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now); 14674 int clientProcState = client.curProcState; 14675 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 14676 // If the other app is cached for any reason, for purposes here 14677 // we are going to consider it empty. 14678 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 14679 } 14680 if (adj > clientAdj) { 14681 if (app.hasShownUi && app != mHomeProcess 14682 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14683 app.adjType = "cch-ui-provider"; 14684 } else { 14685 adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ 14686 ? clientAdj : ProcessList.FOREGROUND_APP_ADJ; 14687 app.adjType = "provider"; 14688 } 14689 app.cached &= client.cached; 14690 app.keeping |= client.keeping; 14691 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 14692 .REASON_PROVIDER_IN_USE; 14693 app.adjSource = client; 14694 app.adjSourceOom = clientAdj; 14695 app.adjTarget = cpr.name; 14696 } 14697 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) { 14698 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) { 14699 // Special handling of clients who are in the top state. 14700 // We *may* want to consider this process to be in the 14701 // top state as well, but only if there is not another 14702 // reason for it to be running. Being on the top is a 14703 // special state, meaning you are specifically running 14704 // for the current top app. If the process is already 14705 // running in the background for some other reason, it 14706 // is more important to continue considering it to be 14707 // in the background state. 14708 mayBeTop = true; 14709 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 14710 } else { 14711 // Special handling for above-top states (persistent 14712 // processes). These should not bring the current process 14713 // into the top state, since they are not on top. Instead 14714 // give them the best state after that. 14715 clientProcState = 14716 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14717 } 14718 } 14719 if (procState > clientProcState) { 14720 procState = clientProcState; 14721 } 14722 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 14723 schedGroup = Process.THREAD_GROUP_DEFAULT; 14724 } 14725 } 14726 // If the provider has external (non-framework) process 14727 // dependencies, ensure that its adjustment is at least 14728 // FOREGROUND_APP_ADJ. 14729 if (cpr.hasExternalProcessHandles()) { 14730 if (adj > ProcessList.FOREGROUND_APP_ADJ) { 14731 adj = ProcessList.FOREGROUND_APP_ADJ; 14732 schedGroup = Process.THREAD_GROUP_DEFAULT; 14733 app.cached = false; 14734 app.keeping = true; 14735 app.adjType = "provider"; 14736 app.adjTarget = cpr.name; 14737 } 14738 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) { 14739 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14740 } 14741 } 14742 } 14743 14744 if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) { 14745 // A client of one of our services or providers is in the top state. We 14746 // *may* want to be in the top state, but not if we are already running in 14747 // the background for some other reason. For the decision here, we are going 14748 // to pick out a few specific states that we want to remain in when a client 14749 // is top (states that tend to be longer-term) and otherwise allow it to go 14750 // to the top state. 14751 switch (procState) { 14752 case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND: 14753 case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND: 14754 case ActivityManager.PROCESS_STATE_SERVICE: 14755 // These all are longer-term states, so pull them up to the top 14756 // of the background states, but not all the way to the top state. 14757 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14758 break; 14759 default: 14760 // Otherwise, top is a better choice, so take it. 14761 procState = ActivityManager.PROCESS_STATE_TOP; 14762 break; 14763 } 14764 } 14765 14766 if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY && app.hasClientActivities) { 14767 // This is a cached process, but with client activities. Mark it so. 14768 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT; 14769 app.adjType = "cch-client-act"; 14770 } 14771 14772 if (adj == ProcessList.SERVICE_ADJ) { 14773 if (doingAll) { 14774 app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3); 14775 mNewNumServiceProcs++; 14776 //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb); 14777 if (!app.serviceb) { 14778 // This service isn't far enough down on the LRU list to 14779 // normally be a B service, but if we are low on RAM and it 14780 // is large we want to force it down since we would prefer to 14781 // keep launcher over it. 14782 if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL 14783 && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) { 14784 app.serviceHighRam = true; 14785 app.serviceb = true; 14786 //Slog.i(TAG, "ADJ " + app + " high ram!"); 14787 } else { 14788 mNewNumAServiceProcs++; 14789 //Slog.i(TAG, "ADJ " + app + " not high ram!"); 14790 } 14791 } else { 14792 app.serviceHighRam = false; 14793 } 14794 } 14795 if (app.serviceb) { 14796 adj = ProcessList.SERVICE_B_ADJ; 14797 } 14798 } 14799 14800 app.curRawAdj = adj; 14801 14802 //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid + 14803 // " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj); 14804 if (adj > app.maxAdj) { 14805 adj = app.maxAdj; 14806 if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 14807 schedGroup = Process.THREAD_GROUP_DEFAULT; 14808 } 14809 } 14810 if (adj < ProcessList.CACHED_APP_MIN_ADJ) { 14811 app.keeping = true; 14812 } 14813 14814 // Do final modification to adj. Everything we do between here and applying 14815 // the final setAdj must be done in this function, because we will also use 14816 // it when computing the final cached adj later. Note that we don't need to 14817 // worry about this for max adj above, since max adj will always be used to 14818 // keep it out of the cached vaues. 14819 adj = app.modifyRawOomAdj(adj); 14820 14821 app.curProcState = procState; 14822 14823 int importance = app.memImportance; 14824 if (importance == 0 || adj != app.curAdj || schedGroup != app.curSchedGroup) { 14825 app.curAdj = adj; 14826 app.curSchedGroup = schedGroup; 14827 if (!interesting) { 14828 // For this reporting, if there is not something explicitly 14829 // interesting in this process then we will push it to the 14830 // background importance. 14831 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 14832 } else if (adj >= ProcessList.CACHED_APP_MIN_ADJ) { 14833 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 14834 } else if (adj >= ProcessList.SERVICE_B_ADJ) { 14835 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 14836 } else if (adj >= ProcessList.HOME_APP_ADJ) { 14837 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 14838 } else if (adj >= ProcessList.SERVICE_ADJ) { 14839 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 14840 } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 14841 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE; 14842 } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) { 14843 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE; 14844 } else if (adj >= ProcessList.VISIBLE_APP_ADJ) { 14845 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE; 14846 } else if (adj >= ProcessList.FOREGROUND_APP_ADJ) { 14847 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND; 14848 } else { 14849 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERSISTENT; 14850 } 14851 } 14852 14853 int changes = importance != app.memImportance ? ProcessChangeItem.CHANGE_IMPORTANCE : 0; 14854 if (foregroundActivities != app.foregroundActivities) { 14855 changes |= ProcessChangeItem.CHANGE_ACTIVITIES; 14856 } 14857 if (changes != 0) { 14858 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes); 14859 app.memImportance = importance; 14860 app.foregroundActivities = foregroundActivities; 14861 int i = mPendingProcessChanges.size()-1; 14862 ProcessChangeItem item = null; 14863 while (i >= 0) { 14864 item = mPendingProcessChanges.get(i); 14865 if (item.pid == app.pid) { 14866 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item); 14867 break; 14868 } 14869 i--; 14870 } 14871 if (i < 0) { 14872 // No existing item in pending changes; need a new one. 14873 final int NA = mAvailProcessChanges.size(); 14874 if (NA > 0) { 14875 item = mAvailProcessChanges.remove(NA-1); 14876 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item); 14877 } else { 14878 item = new ProcessChangeItem(); 14879 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item); 14880 } 14881 item.changes = 0; 14882 item.pid = app.pid; 14883 item.uid = app.info.uid; 14884 if (mPendingProcessChanges.size() == 0) { 14885 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, 14886 "*** Enqueueing dispatch processes changed!"); 14887 mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget(); 14888 } 14889 mPendingProcessChanges.add(item); 14890 } 14891 item.changes |= changes; 14892 item.importance = importance; 14893 item.foregroundActivities = foregroundActivities; 14894 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item " 14895 + Integer.toHexString(System.identityHashCode(item)) 14896 + " " + app.toShortString() + ": changes=" + item.changes 14897 + " importance=" + item.importance 14898 + " foreground=" + item.foregroundActivities 14899 + " type=" + app.adjType + " source=" + app.adjSource 14900 + " target=" + app.adjTarget); 14901 } 14902 14903 return app.curRawAdj; 14904 } 14905 14906 /** 14907 * Schedule PSS collection of a process. 14908 */ 14909 void requestPssLocked(ProcessRecord proc, int procState) { 14910 if (mPendingPssProcesses.contains(proc)) { 14911 return; 14912 } 14913 if (mPendingPssProcesses.size() == 0) { 14914 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG); 14915 } 14916 if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc); 14917 proc.pssProcState = procState; 14918 mPendingPssProcesses.add(proc); 14919 } 14920 14921 /** 14922 * Schedule PSS collection of all processes. 14923 */ 14924 void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) { 14925 if (!always) { 14926 if (now < (mLastFullPssTime + 14927 (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) { 14928 return; 14929 } 14930 } 14931 if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs! memLowered=" + memLowered); 14932 mLastFullPssTime = now; 14933 mPendingPssProcesses.ensureCapacity(mLruProcesses.size()); 14934 mPendingPssProcesses.clear(); 14935 for (int i=mLruProcesses.size()-1; i>=0; i--) { 14936 ProcessRecord app = mLruProcesses.get(i); 14937 if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) { 14938 app.pssProcState = app.setProcState; 14939 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true, 14940 mSleeping, now); 14941 mPendingPssProcesses.add(app); 14942 } 14943 } 14944 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG); 14945 } 14946 14947 /** 14948 * Ask a given process to GC right now. 14949 */ 14950 final void performAppGcLocked(ProcessRecord app) { 14951 try { 14952 app.lastRequestedGc = SystemClock.uptimeMillis(); 14953 if (app.thread != null) { 14954 if (app.reportLowMemory) { 14955 app.reportLowMemory = false; 14956 app.thread.scheduleLowMemory(); 14957 } else { 14958 app.thread.processInBackground(); 14959 } 14960 } 14961 } catch (Exception e) { 14962 // whatever. 14963 } 14964 } 14965 14966 /** 14967 * Returns true if things are idle enough to perform GCs. 14968 */ 14969 private final boolean canGcNowLocked() { 14970 boolean processingBroadcasts = false; 14971 for (BroadcastQueue q : mBroadcastQueues) { 14972 if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) { 14973 processingBroadcasts = true; 14974 } 14975 } 14976 return !processingBroadcasts 14977 && (mSleeping || mStackSupervisor.allResumedActivitiesIdle()); 14978 } 14979 14980 /** 14981 * Perform GCs on all processes that are waiting for it, but only 14982 * if things are idle. 14983 */ 14984 final void performAppGcsLocked() { 14985 final int N = mProcessesToGc.size(); 14986 if (N <= 0) { 14987 return; 14988 } 14989 if (canGcNowLocked()) { 14990 while (mProcessesToGc.size() > 0) { 14991 ProcessRecord proc = mProcessesToGc.remove(0); 14992 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) { 14993 if ((proc.lastRequestedGc+GC_MIN_INTERVAL) 14994 <= SystemClock.uptimeMillis()) { 14995 // To avoid spamming the system, we will GC processes one 14996 // at a time, waiting a few seconds between each. 14997 performAppGcLocked(proc); 14998 scheduleAppGcsLocked(); 14999 return; 15000 } else { 15001 // It hasn't been long enough since we last GCed this 15002 // process... put it in the list to wait for its time. 15003 addProcessToGcListLocked(proc); 15004 break; 15005 } 15006 } 15007 } 15008 15009 scheduleAppGcsLocked(); 15010 } 15011 } 15012 15013 /** 15014 * If all looks good, perform GCs on all processes waiting for them. 15015 */ 15016 final void performAppGcsIfAppropriateLocked() { 15017 if (canGcNowLocked()) { 15018 performAppGcsLocked(); 15019 return; 15020 } 15021 // Still not idle, wait some more. 15022 scheduleAppGcsLocked(); 15023 } 15024 15025 /** 15026 * Schedule the execution of all pending app GCs. 15027 */ 15028 final void scheduleAppGcsLocked() { 15029 mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG); 15030 15031 if (mProcessesToGc.size() > 0) { 15032 // Schedule a GC for the time to the next process. 15033 ProcessRecord proc = mProcessesToGc.get(0); 15034 Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG); 15035 15036 long when = proc.lastRequestedGc + GC_MIN_INTERVAL; 15037 long now = SystemClock.uptimeMillis(); 15038 if (when < (now+GC_TIMEOUT)) { 15039 when = now + GC_TIMEOUT; 15040 } 15041 mHandler.sendMessageAtTime(msg, when); 15042 } 15043 } 15044 15045 /** 15046 * Add a process to the array of processes waiting to be GCed. Keeps the 15047 * list in sorted order by the last GC time. The process can't already be 15048 * on the list. 15049 */ 15050 final void addProcessToGcListLocked(ProcessRecord proc) { 15051 boolean added = false; 15052 for (int i=mProcessesToGc.size()-1; i>=0; i--) { 15053 if (mProcessesToGc.get(i).lastRequestedGc < 15054 proc.lastRequestedGc) { 15055 added = true; 15056 mProcessesToGc.add(i+1, proc); 15057 break; 15058 } 15059 } 15060 if (!added) { 15061 mProcessesToGc.add(0, proc); 15062 } 15063 } 15064 15065 /** 15066 * Set up to ask a process to GC itself. This will either do it 15067 * immediately, or put it on the list of processes to gc the next 15068 * time things are idle. 15069 */ 15070 final void scheduleAppGcLocked(ProcessRecord app) { 15071 long now = SystemClock.uptimeMillis(); 15072 if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) { 15073 return; 15074 } 15075 if (!mProcessesToGc.contains(app)) { 15076 addProcessToGcListLocked(app); 15077 scheduleAppGcsLocked(); 15078 } 15079 } 15080 15081 final void checkExcessivePowerUsageLocked(boolean doKills) { 15082 updateCpuStatsNow(); 15083 15084 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 15085 boolean doWakeKills = doKills; 15086 boolean doCpuKills = doKills; 15087 if (mLastPowerCheckRealtime == 0) { 15088 doWakeKills = false; 15089 } 15090 if (mLastPowerCheckUptime == 0) { 15091 doCpuKills = false; 15092 } 15093 if (stats.isScreenOn()) { 15094 doWakeKills = false; 15095 } 15096 final long curRealtime = SystemClock.elapsedRealtime(); 15097 final long realtimeSince = curRealtime - mLastPowerCheckRealtime; 15098 final long curUptime = SystemClock.uptimeMillis(); 15099 final long uptimeSince = curUptime - mLastPowerCheckUptime; 15100 mLastPowerCheckRealtime = curRealtime; 15101 mLastPowerCheckUptime = curUptime; 15102 if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) { 15103 doWakeKills = false; 15104 } 15105 if (uptimeSince < CPU_MIN_CHECK_DURATION) { 15106 doCpuKills = false; 15107 } 15108 int i = mLruProcesses.size(); 15109 while (i > 0) { 15110 i--; 15111 ProcessRecord app = mLruProcesses.get(i); 15112 if (!app.keeping) { 15113 long wtime; 15114 synchronized (stats) { 15115 wtime = stats.getProcessWakeTime(app.info.uid, 15116 app.pid, curRealtime); 15117 } 15118 long wtimeUsed = wtime - app.lastWakeTime; 15119 long cputimeUsed = app.curCpuTime - app.lastCpuTime; 15120 if (DEBUG_POWER) { 15121 StringBuilder sb = new StringBuilder(128); 15122 sb.append("Wake for "); 15123 app.toShortString(sb); 15124 sb.append(": over "); 15125 TimeUtils.formatDuration(realtimeSince, sb); 15126 sb.append(" used "); 15127 TimeUtils.formatDuration(wtimeUsed, sb); 15128 sb.append(" ("); 15129 sb.append((wtimeUsed*100)/realtimeSince); 15130 sb.append("%)"); 15131 Slog.i(TAG, sb.toString()); 15132 sb.setLength(0); 15133 sb.append("CPU for "); 15134 app.toShortString(sb); 15135 sb.append(": over "); 15136 TimeUtils.formatDuration(uptimeSince, sb); 15137 sb.append(" used "); 15138 TimeUtils.formatDuration(cputimeUsed, sb); 15139 sb.append(" ("); 15140 sb.append((cputimeUsed*100)/uptimeSince); 15141 sb.append("%)"); 15142 Slog.i(TAG, sb.toString()); 15143 } 15144 // If a process has held a wake lock for more 15145 // than 50% of the time during this period, 15146 // that sounds bad. Kill! 15147 if (doWakeKills && realtimeSince > 0 15148 && ((wtimeUsed*100)/realtimeSince) >= 50) { 15149 synchronized (stats) { 15150 stats.reportExcessiveWakeLocked(app.info.uid, app.processName, 15151 realtimeSince, wtimeUsed); 15152 } 15153 killUnneededProcessLocked(app, "excessive wake held " + wtimeUsed 15154 + " during " + realtimeSince); 15155 app.baseProcessTracker.reportExcessiveWake(app.pkgList); 15156 } else if (doCpuKills && uptimeSince > 0 15157 && ((cputimeUsed*100)/uptimeSince) >= 50) { 15158 synchronized (stats) { 15159 stats.reportExcessiveCpuLocked(app.info.uid, app.processName, 15160 uptimeSince, cputimeUsed); 15161 } 15162 killUnneededProcessLocked(app, "excessive cpu " + cputimeUsed 15163 + " during " + uptimeSince); 15164 app.baseProcessTracker.reportExcessiveCpu(app.pkgList); 15165 } else { 15166 app.lastWakeTime = wtime; 15167 app.lastCpuTime = app.curCpuTime; 15168 } 15169 } 15170 } 15171 } 15172 15173 private final boolean applyOomAdjLocked(ProcessRecord app, boolean wasKeeping, 15174 ProcessRecord TOP_APP, boolean doingAll, boolean reportingProcessState, long now) { 15175 boolean success = true; 15176 15177 if (app.curRawAdj != app.setRawAdj) { 15178 if (wasKeeping && !app.keeping) { 15179 // This app is no longer something we want to keep. Note 15180 // its current wake lock time to later know to kill it if 15181 // it is not behaving well. 15182 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 15183 synchronized (stats) { 15184 app.lastWakeTime = stats.getProcessWakeTime(app.info.uid, 15185 app.pid, SystemClock.elapsedRealtime()); 15186 } 15187 app.lastCpuTime = app.curCpuTime; 15188 } 15189 15190 app.setRawAdj = app.curRawAdj; 15191 } 15192 15193 if (app.curAdj != app.setAdj) { 15194 ProcessList.setOomAdj(app.pid, app.curAdj); 15195 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v( 15196 TAG, "Set " + app.pid + " " + app.processName + 15197 " adj " + app.curAdj + ": " + app.adjType); 15198 app.setAdj = app.curAdj; 15199 } 15200 15201 if (app.setSchedGroup != app.curSchedGroup) { 15202 app.setSchedGroup = app.curSchedGroup; 15203 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 15204 "Setting process group of " + app.processName 15205 + " to " + app.curSchedGroup); 15206 if (app.waitingToKill != null && 15207 app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 15208 killUnneededProcessLocked(app, app.waitingToKill); 15209 success = false; 15210 } else { 15211 if (true) { 15212 long oldId = Binder.clearCallingIdentity(); 15213 try { 15214 Process.setProcessGroup(app.pid, app.curSchedGroup); 15215 } catch (Exception e) { 15216 Slog.w(TAG, "Failed setting process group of " + app.pid 15217 + " to " + app.curSchedGroup); 15218 e.printStackTrace(); 15219 } finally { 15220 Binder.restoreCallingIdentity(oldId); 15221 } 15222 } else { 15223 if (app.thread != null) { 15224 try { 15225 app.thread.setSchedulingGroup(app.curSchedGroup); 15226 } catch (RemoteException e) { 15227 } 15228 } 15229 } 15230 Process.setSwappiness(app.pid, 15231 app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE); 15232 } 15233 } 15234 if (app.repProcState != app.curProcState) { 15235 app.repProcState = app.curProcState; 15236 if (!reportingProcessState && app.thread != null) { 15237 try { 15238 if (false) { 15239 //RuntimeException h = new RuntimeException("here"); 15240 Slog.i(TAG, "Sending new process state " + app.repProcState 15241 + " to " + app /*, h*/); 15242 } 15243 app.thread.setProcessState(app.repProcState); 15244 } catch (RemoteException e) { 15245 } 15246 } 15247 } 15248 if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState, 15249 app.setProcState)) { 15250 app.lastStateTime = now; 15251 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true, 15252 mSleeping, now); 15253 if (DEBUG_PSS) Slog.d(TAG, "Process state change from " 15254 + ProcessList.makeProcStateString(app.setProcState) + " to " 15255 + ProcessList.makeProcStateString(app.curProcState) + " next pss in " 15256 + (app.nextPssTime-now) + ": " + app); 15257 } else { 15258 if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL) 15259 && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) { 15260 requestPssLocked(app, app.setProcState); 15261 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false, 15262 mSleeping, now); 15263 } else if (false && DEBUG_PSS) { 15264 Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now)); 15265 } 15266 } 15267 if (app.setProcState != app.curProcState) { 15268 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 15269 "Proc state change of " + app.processName 15270 + " to " + app.curProcState); 15271 app.setProcState = app.curProcState; 15272 if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) { 15273 app.notCachedSinceIdle = false; 15274 } 15275 if (!doingAll) { 15276 setProcessTrackerState(app, mProcessStats.getMemFactorLocked(), now); 15277 } else { 15278 app.procStateChanged = true; 15279 } 15280 } 15281 return success; 15282 } 15283 15284 private final void setProcessTrackerState(ProcessRecord proc, int memFactor, long now) { 15285 if (proc.thread != null && proc.baseProcessTracker != null) { 15286 proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList); 15287 } 15288 } 15289 15290 private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj, 15291 ProcessRecord TOP_APP, boolean doingAll, boolean reportingProcessState, long now) { 15292 if (app.thread == null) { 15293 return false; 15294 } 15295 15296 final boolean wasKeeping = app.keeping; 15297 15298 computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now); 15299 15300 return applyOomAdjLocked(app, wasKeeping, TOP_APP, doingAll, 15301 reportingProcessState, now); 15302 } 15303 15304 private final ActivityRecord resumedAppLocked() { 15305 return mStackSupervisor.resumedAppLocked(); 15306 } 15307 15308 final boolean updateOomAdjLocked(ProcessRecord app) { 15309 return updateOomAdjLocked(app, false); 15310 } 15311 15312 final boolean updateOomAdjLocked(ProcessRecord app, boolean doingProcessState) { 15313 final ActivityRecord TOP_ACT = resumedAppLocked(); 15314 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 15315 final boolean wasCached = app.cached; 15316 15317 mAdjSeq++; 15318 15319 // This is the desired cached adjusment we want to tell it to use. 15320 // If our app is currently cached, we know it, and that is it. Otherwise, 15321 // we don't know it yet, and it needs to now be cached we will then 15322 // need to do a complete oom adj. 15323 final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ 15324 ? app.curRawAdj : ProcessList.UNKNOWN_ADJ; 15325 boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false, doingProcessState, 15326 SystemClock.uptimeMillis()); 15327 if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) { 15328 // Changed to/from cached state, so apps after it in the LRU 15329 // list may also be changed. 15330 updateOomAdjLocked(); 15331 } 15332 return success; 15333 } 15334 15335 final void updateOomAdjLocked() { 15336 final ActivityRecord TOP_ACT = resumedAppLocked(); 15337 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 15338 final long now = SystemClock.uptimeMillis(); 15339 final long oldTime = now - ProcessList.MAX_EMPTY_TIME; 15340 final int N = mLruProcesses.size(); 15341 15342 if (false) { 15343 RuntimeException e = new RuntimeException(); 15344 e.fillInStackTrace(); 15345 Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e); 15346 } 15347 15348 mAdjSeq++; 15349 mNewNumServiceProcs = 0; 15350 mNewNumAServiceProcs = 0; 15351 15352 final int emptyProcessLimit; 15353 final int cachedProcessLimit; 15354 if (mProcessLimit <= 0) { 15355 emptyProcessLimit = cachedProcessLimit = 0; 15356 } else if (mProcessLimit == 1) { 15357 emptyProcessLimit = 1; 15358 cachedProcessLimit = 0; 15359 } else { 15360 emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit); 15361 cachedProcessLimit = mProcessLimit - emptyProcessLimit; 15362 } 15363 15364 // Let's determine how many processes we have running vs. 15365 // how many slots we have for background processes; we may want 15366 // to put multiple processes in a slot of there are enough of 15367 // them. 15368 int numSlots = (ProcessList.CACHED_APP_MAX_ADJ 15369 - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2; 15370 int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs; 15371 if (numEmptyProcs > cachedProcessLimit) { 15372 // If there are more empty processes than our limit on cached 15373 // processes, then use the cached process limit for the factor. 15374 // This ensures that the really old empty processes get pushed 15375 // down to the bottom, so if we are running low on memory we will 15376 // have a better chance at keeping around more cached processes 15377 // instead of a gazillion empty processes. 15378 numEmptyProcs = cachedProcessLimit; 15379 } 15380 int emptyFactor = numEmptyProcs/numSlots; 15381 if (emptyFactor < 1) emptyFactor = 1; 15382 int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots; 15383 if (cachedFactor < 1) cachedFactor = 1; 15384 int stepCached = 0; 15385 int stepEmpty = 0; 15386 int numCached = 0; 15387 int numEmpty = 0; 15388 int numTrimming = 0; 15389 15390 mNumNonCachedProcs = 0; 15391 mNumCachedHiddenProcs = 0; 15392 15393 // First update the OOM adjustment for each of the 15394 // application processes based on their current state. 15395 int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ; 15396 int nextCachedAdj = curCachedAdj+1; 15397 int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ; 15398 int nextEmptyAdj = curEmptyAdj+2; 15399 for (int i=N-1; i>=0; i--) { 15400 ProcessRecord app = mLruProcesses.get(i); 15401 if (!app.killedByAm && app.thread != null) { 15402 app.procStateChanged = false; 15403 final boolean wasKeeping = app.keeping; 15404 computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now); 15405 15406 // If we haven't yet assigned the final cached adj 15407 // to the process, do that now. 15408 if (app.curAdj >= ProcessList.UNKNOWN_ADJ) { 15409 switch (app.curProcState) { 15410 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY: 15411 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: 15412 // This process is a cached process holding activities... 15413 // assign it the next cached value for that type, and then 15414 // step that cached level. 15415 app.curRawAdj = curCachedAdj; 15416 app.curAdj = app.modifyRawOomAdj(curCachedAdj); 15417 if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i 15418 + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj 15419 + ")"); 15420 if (curCachedAdj != nextCachedAdj) { 15421 stepCached++; 15422 if (stepCached >= cachedFactor) { 15423 stepCached = 0; 15424 curCachedAdj = nextCachedAdj; 15425 nextCachedAdj += 2; 15426 if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) { 15427 nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ; 15428 } 15429 } 15430 } 15431 break; 15432 default: 15433 // For everything else, assign next empty cached process 15434 // level and bump that up. Note that this means that 15435 // long-running services that have dropped down to the 15436 // cached level will be treated as empty (since their process 15437 // state is still as a service), which is what we want. 15438 app.curRawAdj = curEmptyAdj; 15439 app.curAdj = app.modifyRawOomAdj(curEmptyAdj); 15440 if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i 15441 + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj 15442 + ")"); 15443 if (curEmptyAdj != nextEmptyAdj) { 15444 stepEmpty++; 15445 if (stepEmpty >= emptyFactor) { 15446 stepEmpty = 0; 15447 curEmptyAdj = nextEmptyAdj; 15448 nextEmptyAdj += 2; 15449 if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) { 15450 nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ; 15451 } 15452 } 15453 } 15454 break; 15455 } 15456 } 15457 15458 applyOomAdjLocked(app, wasKeeping, TOP_APP, true, false, now); 15459 15460 // Count the number of process types. 15461 switch (app.curProcState) { 15462 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY: 15463 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: 15464 mNumCachedHiddenProcs++; 15465 numCached++; 15466 if (numCached > cachedProcessLimit) { 15467 killUnneededProcessLocked(app, "cached #" + numCached); 15468 } 15469 break; 15470 case ActivityManager.PROCESS_STATE_CACHED_EMPTY: 15471 if (numEmpty > ProcessList.TRIM_EMPTY_APPS 15472 && app.lastActivityTime < oldTime) { 15473 killUnneededProcessLocked(app, "empty for " 15474 + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime) 15475 / 1000) + "s"); 15476 } else { 15477 numEmpty++; 15478 if (numEmpty > emptyProcessLimit) { 15479 killUnneededProcessLocked(app, "empty #" + numEmpty); 15480 } 15481 } 15482 break; 15483 default: 15484 mNumNonCachedProcs++; 15485 break; 15486 } 15487 15488 if (app.isolated && app.services.size() <= 0) { 15489 // If this is an isolated process, and there are no 15490 // services running in it, then the process is no longer 15491 // needed. We agressively kill these because we can by 15492 // definition not re-use the same process again, and it is 15493 // good to avoid having whatever code was running in them 15494 // left sitting around after no longer needed. 15495 killUnneededProcessLocked(app, "isolated not needed"); 15496 } 15497 15498 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME 15499 && !app.killedByAm) { 15500 numTrimming++; 15501 } 15502 } 15503 } 15504 15505 mNumServiceProcs = mNewNumServiceProcs; 15506 15507 // Now determine the memory trimming level of background processes. 15508 // Unfortunately we need to start at the back of the list to do this 15509 // properly. We only do this if the number of background apps we 15510 // are managing to keep around is less than half the maximum we desire; 15511 // if we are keeping a good number around, we'll let them use whatever 15512 // memory they want. 15513 final int numCachedAndEmpty = numCached + numEmpty; 15514 int memFactor; 15515 if (numCached <= ProcessList.TRIM_CACHED_APPS 15516 && numEmpty <= ProcessList.TRIM_EMPTY_APPS) { 15517 if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) { 15518 memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL; 15519 } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) { 15520 memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW; 15521 } else { 15522 memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE; 15523 } 15524 } else { 15525 memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL; 15526 } 15527 // We always allow the memory level to go up (better). We only allow it to go 15528 // down if we are in a state where that is allowed, *and* the total number of processes 15529 // has gone down since last time. 15530 if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel 15531 + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size() 15532 + " last=" + mLastNumProcesses); 15533 if (memFactor > mLastMemoryLevel) { 15534 if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) { 15535 memFactor = mLastMemoryLevel; 15536 if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!"); 15537 } 15538 } 15539 mLastMemoryLevel = memFactor; 15540 mLastNumProcesses = mLruProcesses.size(); 15541 boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !mSleeping, now); 15542 final int trackerMemFactor = mProcessStats.getMemFactorLocked(); 15543 if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) { 15544 if (mLowRamStartTime == 0) { 15545 mLowRamStartTime = now; 15546 } 15547 int step = 0; 15548 int fgTrimLevel; 15549 switch (memFactor) { 15550 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL: 15551 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL; 15552 break; 15553 case ProcessStats.ADJ_MEM_FACTOR_LOW: 15554 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW; 15555 break; 15556 default: 15557 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE; 15558 break; 15559 } 15560 int factor = numTrimming/3; 15561 int minFactor = 2; 15562 if (mHomeProcess != null) minFactor++; 15563 if (mPreviousProcess != null) minFactor++; 15564 if (factor < minFactor) factor = minFactor; 15565 int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE; 15566 for (int i=N-1; i>=0; i--) { 15567 ProcessRecord app = mLruProcesses.get(i); 15568 if (allChanged || app.procStateChanged) { 15569 setProcessTrackerState(app, trackerMemFactor, now); 15570 app.procStateChanged = false; 15571 } 15572 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME 15573 && !app.killedByAm) { 15574 if (app.trimMemoryLevel < curLevel && app.thread != null) { 15575 try { 15576 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 15577 "Trimming memory of " + app.processName 15578 + " to " + curLevel); 15579 app.thread.scheduleTrimMemory(curLevel); 15580 } catch (RemoteException e) { 15581 } 15582 if (false) { 15583 // For now we won't do this; our memory trimming seems 15584 // to be good enough at this point that destroying 15585 // activities causes more harm than good. 15586 if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE 15587 && app != mHomeProcess && app != mPreviousProcess) { 15588 // Need to do this on its own message because the stack may not 15589 // be in a consistent state at this point. 15590 // For these apps we will also finish their activities 15591 // to help them free memory. 15592 mStackSupervisor.scheduleDestroyAllActivities(app, "trim"); 15593 } 15594 } 15595 } 15596 app.trimMemoryLevel = curLevel; 15597 step++; 15598 if (step >= factor) { 15599 step = 0; 15600 switch (curLevel) { 15601 case ComponentCallbacks2.TRIM_MEMORY_COMPLETE: 15602 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE; 15603 break; 15604 case ComponentCallbacks2.TRIM_MEMORY_MODERATE: 15605 curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 15606 break; 15607 } 15608 } 15609 } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) { 15610 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND 15611 && app.thread != null) { 15612 try { 15613 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 15614 "Trimming memory of heavy-weight " + app.processName 15615 + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 15616 app.thread.scheduleTrimMemory( 15617 ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 15618 } catch (RemoteException e) { 15619 } 15620 } 15621 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 15622 } else { 15623 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 15624 || app.systemNoUi) && app.pendingUiClean) { 15625 // If this application is now in the background and it 15626 // had done UI, then give it the special trim level to 15627 // have it free UI resources. 15628 final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN; 15629 if (app.trimMemoryLevel < level && app.thread != null) { 15630 try { 15631 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 15632 "Trimming memory of bg-ui " + app.processName 15633 + " to " + level); 15634 app.thread.scheduleTrimMemory(level); 15635 } catch (RemoteException e) { 15636 } 15637 } 15638 app.pendingUiClean = false; 15639 } 15640 if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) { 15641 try { 15642 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 15643 "Trimming memory of fg " + app.processName 15644 + " to " + fgTrimLevel); 15645 app.thread.scheduleTrimMemory(fgTrimLevel); 15646 } catch (RemoteException e) { 15647 } 15648 } 15649 app.trimMemoryLevel = fgTrimLevel; 15650 } 15651 } 15652 } else { 15653 if (mLowRamStartTime != 0) { 15654 mLowRamTimeSinceLastIdle += now - mLowRamStartTime; 15655 mLowRamStartTime = 0; 15656 } 15657 for (int i=N-1; i>=0; i--) { 15658 ProcessRecord app = mLruProcesses.get(i); 15659 if (allChanged || app.procStateChanged) { 15660 setProcessTrackerState(app, trackerMemFactor, now); 15661 app.procStateChanged = false; 15662 } 15663 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 15664 || app.systemNoUi) && app.pendingUiClean) { 15665 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN 15666 && app.thread != null) { 15667 try { 15668 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 15669 "Trimming memory of ui hidden " + app.processName 15670 + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 15671 app.thread.scheduleTrimMemory( 15672 ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 15673 } catch (RemoteException e) { 15674 } 15675 } 15676 app.pendingUiClean = false; 15677 } 15678 app.trimMemoryLevel = 0; 15679 } 15680 } 15681 15682 if (mAlwaysFinishActivities) { 15683 // Need to do this on its own message because the stack may not 15684 // be in a consistent state at this point. 15685 mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish"); 15686 } 15687 15688 if (allChanged) { 15689 requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered()); 15690 } 15691 15692 if (mProcessStats.shouldWriteNowLocked(now)) { 15693 mHandler.post(new Runnable() { 15694 @Override public void run() { 15695 synchronized (ActivityManagerService.this) { 15696 mProcessStats.writeStateAsyncLocked(); 15697 } 15698 } 15699 }); 15700 } 15701 15702 if (DEBUG_OOM_ADJ) { 15703 Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms"); 15704 } 15705 } 15706 15707 final void trimApplications() { 15708 synchronized (this) { 15709 int i; 15710 15711 // First remove any unused application processes whose package 15712 // has been removed. 15713 for (i=mRemovedProcesses.size()-1; i>=0; i--) { 15714 final ProcessRecord app = mRemovedProcesses.get(i); 15715 if (app.activities.size() == 0 15716 && app.curReceiver == null && app.services.size() == 0) { 15717 Slog.i( 15718 TAG, "Exiting empty application process " 15719 + app.processName + " (" 15720 + (app.thread != null ? app.thread.asBinder() : null) 15721 + ")\n"); 15722 if (app.pid > 0 && app.pid != MY_PID) { 15723 EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid, 15724 app.processName, app.setAdj, "empty"); 15725 app.killedByAm = true; 15726 Process.killProcessQuiet(app.pid); 15727 } else { 15728 try { 15729 app.thread.scheduleExit(); 15730 } catch (Exception e) { 15731 // Ignore exceptions. 15732 } 15733 } 15734 cleanUpApplicationRecordLocked(app, false, true, -1); 15735 mRemovedProcesses.remove(i); 15736 15737 if (app.persistent) { 15738 if (app.persistent) { 15739 addAppLocked(app.info, false, null /* ABI override */); 15740 } 15741 } 15742 } 15743 } 15744 15745 // Now update the oom adj for all processes. 15746 updateOomAdjLocked(); 15747 } 15748 } 15749 15750 /** This method sends the specified signal to each of the persistent apps */ 15751 public void signalPersistentProcesses(int sig) throws RemoteException { 15752 if (sig != Process.SIGNAL_USR1) { 15753 throw new SecurityException("Only SIGNAL_USR1 is allowed"); 15754 } 15755 15756 synchronized (this) { 15757 if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES) 15758 != PackageManager.PERMISSION_GRANTED) { 15759 throw new SecurityException("Requires permission " 15760 + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES); 15761 } 15762 15763 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 15764 ProcessRecord r = mLruProcesses.get(i); 15765 if (r.thread != null && r.persistent) { 15766 Process.sendSignal(r.pid, sig); 15767 } 15768 } 15769 } 15770 } 15771 15772 private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) { 15773 if (proc == null || proc == mProfileProc) { 15774 proc = mProfileProc; 15775 path = mProfileFile; 15776 profileType = mProfileType; 15777 clearProfilerLocked(); 15778 } 15779 if (proc == null) { 15780 return; 15781 } 15782 try { 15783 proc.thread.profilerControl(false, path, null, profileType); 15784 } catch (RemoteException e) { 15785 throw new IllegalStateException("Process disappeared"); 15786 } 15787 } 15788 15789 private void clearProfilerLocked() { 15790 if (mProfileFd != null) { 15791 try { 15792 mProfileFd.close(); 15793 } catch (IOException e) { 15794 } 15795 } 15796 mProfileApp = null; 15797 mProfileProc = null; 15798 mProfileFile = null; 15799 mProfileType = 0; 15800 mAutoStopProfiler = false; 15801 } 15802 15803 public boolean profileControl(String process, int userId, boolean start, 15804 String path, ParcelFileDescriptor fd, int profileType) throws RemoteException { 15805 15806 try { 15807 synchronized (this) { 15808 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 15809 // its own permission. 15810 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 15811 != PackageManager.PERMISSION_GRANTED) { 15812 throw new SecurityException("Requires permission " 15813 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 15814 } 15815 15816 if (start && fd == null) { 15817 throw new IllegalArgumentException("null fd"); 15818 } 15819 15820 ProcessRecord proc = null; 15821 if (process != null) { 15822 proc = findProcessLocked(process, userId, "profileControl"); 15823 } 15824 15825 if (start && (proc == null || proc.thread == null)) { 15826 throw new IllegalArgumentException("Unknown process: " + process); 15827 } 15828 15829 if (start) { 15830 stopProfilerLocked(null, null, 0); 15831 setProfileApp(proc.info, proc.processName, path, fd, false); 15832 mProfileProc = proc; 15833 mProfileType = profileType; 15834 try { 15835 fd = fd.dup(); 15836 } catch (IOException e) { 15837 fd = null; 15838 } 15839 proc.thread.profilerControl(start, path, fd, profileType); 15840 fd = null; 15841 mProfileFd = null; 15842 } else { 15843 stopProfilerLocked(proc, path, profileType); 15844 if (fd != null) { 15845 try { 15846 fd.close(); 15847 } catch (IOException e) { 15848 } 15849 } 15850 } 15851 15852 return true; 15853 } 15854 } catch (RemoteException e) { 15855 throw new IllegalStateException("Process disappeared"); 15856 } finally { 15857 if (fd != null) { 15858 try { 15859 fd.close(); 15860 } catch (IOException e) { 15861 } 15862 } 15863 } 15864 } 15865 15866 private ProcessRecord findProcessLocked(String process, int userId, String callName) { 15867 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 15868 userId, true, true, callName, null); 15869 ProcessRecord proc = null; 15870 try { 15871 int pid = Integer.parseInt(process); 15872 synchronized (mPidsSelfLocked) { 15873 proc = mPidsSelfLocked.get(pid); 15874 } 15875 } catch (NumberFormatException e) { 15876 } 15877 15878 if (proc == null) { 15879 ArrayMap<String, SparseArray<ProcessRecord>> all 15880 = mProcessNames.getMap(); 15881 SparseArray<ProcessRecord> procs = all.get(process); 15882 if (procs != null && procs.size() > 0) { 15883 proc = procs.valueAt(0); 15884 if (userId != UserHandle.USER_ALL && proc.userId != userId) { 15885 for (int i=1; i<procs.size(); i++) { 15886 ProcessRecord thisProc = procs.valueAt(i); 15887 if (thisProc.userId == userId) { 15888 proc = thisProc; 15889 break; 15890 } 15891 } 15892 } 15893 } 15894 } 15895 15896 return proc; 15897 } 15898 15899 public boolean dumpHeap(String process, int userId, boolean managed, 15900 String path, ParcelFileDescriptor fd) throws RemoteException { 15901 15902 try { 15903 synchronized (this) { 15904 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 15905 // its own permission (same as profileControl). 15906 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 15907 != PackageManager.PERMISSION_GRANTED) { 15908 throw new SecurityException("Requires permission " 15909 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 15910 } 15911 15912 if (fd == null) { 15913 throw new IllegalArgumentException("null fd"); 15914 } 15915 15916 ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap"); 15917 if (proc == null || proc.thread == null) { 15918 throw new IllegalArgumentException("Unknown process: " + process); 15919 } 15920 15921 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 15922 if (!isDebuggable) { 15923 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 15924 throw new SecurityException("Process not debuggable: " + proc); 15925 } 15926 } 15927 15928 proc.thread.dumpHeap(managed, path, fd); 15929 fd = null; 15930 return true; 15931 } 15932 } catch (RemoteException e) { 15933 throw new IllegalStateException("Process disappeared"); 15934 } finally { 15935 if (fd != null) { 15936 try { 15937 fd.close(); 15938 } catch (IOException e) { 15939 } 15940 } 15941 } 15942 } 15943 15944 /** In this method we try to acquire our lock to make sure that we have not deadlocked */ 15945 public void monitor() { 15946 synchronized (this) { } 15947 } 15948 15949 void onCoreSettingsChange(Bundle settings) { 15950 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 15951 ProcessRecord processRecord = mLruProcesses.get(i); 15952 try { 15953 if (processRecord.thread != null) { 15954 processRecord.thread.setCoreSettings(settings); 15955 } 15956 } catch (RemoteException re) { 15957 /* ignore */ 15958 } 15959 } 15960 } 15961 15962 // Multi-user methods 15963 15964 @Override 15965 public boolean switchUser(final int userId) { 15966 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 15967 != PackageManager.PERMISSION_GRANTED) { 15968 String msg = "Permission Denial: switchUser() from pid=" 15969 + Binder.getCallingPid() 15970 + ", uid=" + Binder.getCallingUid() 15971 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 15972 Slog.w(TAG, msg); 15973 throw new SecurityException(msg); 15974 } 15975 15976 final long ident = Binder.clearCallingIdentity(); 15977 try { 15978 synchronized (this) { 15979 final int oldUserId = mCurrentUserId; 15980 if (oldUserId == userId) { 15981 return true; 15982 } 15983 15984 final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId); 15985 if (userInfo == null) { 15986 Slog.w(TAG, "No user info for user #" + userId); 15987 return false; 15988 } 15989 15990 mWindowManager.startFreezingScreen(R.anim.screen_user_exit, 15991 R.anim.screen_user_enter); 15992 15993 boolean needStart = false; 15994 15995 // If the user we are switching to is not currently started, then 15996 // we need to start it now. 15997 if (mStartedUsers.get(userId) == null) { 15998 mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false)); 15999 updateStartedUserArrayLocked(); 16000 needStart = true; 16001 } 16002 16003 mCurrentUserId = userId; 16004 final Integer userIdInt = Integer.valueOf(userId); 16005 mUserLru.remove(userIdInt); 16006 mUserLru.add(userIdInt); 16007 16008 mWindowManager.setCurrentUser(userId); 16009 16010 // Once the internal notion of the active user has switched, we lock the device 16011 // with the option to show the user switcher on the keyguard. 16012 mWindowManager.lockNow(null); 16013 16014 final UserStartedState uss = mStartedUsers.get(userId); 16015 16016 // Make sure user is in the started state. If it is currently 16017 // stopping, we need to knock that off. 16018 if (uss.mState == UserStartedState.STATE_STOPPING) { 16019 // If we are stopping, we haven't sent ACTION_SHUTDOWN, 16020 // so we can just fairly silently bring the user back from 16021 // the almost-dead. 16022 uss.mState = UserStartedState.STATE_RUNNING; 16023 updateStartedUserArrayLocked(); 16024 needStart = true; 16025 } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) { 16026 // This means ACTION_SHUTDOWN has been sent, so we will 16027 // need to treat this as a new boot of the user. 16028 uss.mState = UserStartedState.STATE_BOOTING; 16029 updateStartedUserArrayLocked(); 16030 needStart = true; 16031 } 16032 16033 mHandler.removeMessages(REPORT_USER_SWITCH_MSG); 16034 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 16035 mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG, 16036 oldUserId, userId, uss)); 16037 mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG, 16038 oldUserId, userId, uss), USER_SWITCH_TIMEOUT); 16039 if (needStart) { 16040 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 16041 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16042 | Intent.FLAG_RECEIVER_FOREGROUND); 16043 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 16044 broadcastIntentLocked(null, null, intent, 16045 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 16046 false, false, MY_PID, Process.SYSTEM_UID, userId); 16047 } 16048 16049 if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) { 16050 if (userId != 0) { 16051 Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE); 16052 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 16053 broadcastIntentLocked(null, null, intent, null, 16054 new IIntentReceiver.Stub() { 16055 public void performReceive(Intent intent, int resultCode, 16056 String data, Bundle extras, boolean ordered, 16057 boolean sticky, int sendingUser) { 16058 userInitialized(uss, userId); 16059 } 16060 }, 0, null, null, null, AppOpsManager.OP_NONE, 16061 true, false, MY_PID, Process.SYSTEM_UID, 16062 userId); 16063 uss.initializing = true; 16064 } else { 16065 getUserManagerLocked().makeInitialized(userInfo.id); 16066 } 16067 } 16068 16069 boolean homeInFront = mStackSupervisor.switchUserLocked(userId, uss); 16070 if (homeInFront) { 16071 startHomeActivityLocked(userId); 16072 } else { 16073 mStackSupervisor.resumeTopActivitiesLocked(); 16074 } 16075 16076 EventLogTags.writeAmSwitchUser(userId); 16077 getUserManagerLocked().userForeground(userId); 16078 sendUserSwitchBroadcastsLocked(oldUserId, userId); 16079 if (needStart) { 16080 Intent intent = new Intent(Intent.ACTION_USER_STARTING); 16081 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 16082 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 16083 broadcastIntentLocked(null, null, intent, 16084 null, new IIntentReceiver.Stub() { 16085 @Override 16086 public void performReceive(Intent intent, int resultCode, String data, 16087 Bundle extras, boolean ordered, boolean sticky, int sendingUser) 16088 throws RemoteException { 16089 } 16090 }, 0, null, null, 16091 android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 16092 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 16093 } 16094 } 16095 } finally { 16096 Binder.restoreCallingIdentity(ident); 16097 } 16098 16099 return true; 16100 } 16101 16102 void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) { 16103 long ident = Binder.clearCallingIdentity(); 16104 try { 16105 Intent intent; 16106 if (oldUserId >= 0) { 16107 intent = new Intent(Intent.ACTION_USER_BACKGROUND); 16108 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16109 | Intent.FLAG_RECEIVER_FOREGROUND); 16110 intent.putExtra(Intent.EXTRA_USER_HANDLE, oldUserId); 16111 broadcastIntentLocked(null, null, intent, 16112 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 16113 false, false, MY_PID, Process.SYSTEM_UID, oldUserId); 16114 } 16115 if (newUserId >= 0) { 16116 intent = new Intent(Intent.ACTION_USER_FOREGROUND); 16117 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16118 | Intent.FLAG_RECEIVER_FOREGROUND); 16119 intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId); 16120 broadcastIntentLocked(null, null, intent, 16121 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 16122 false, false, MY_PID, Process.SYSTEM_UID, newUserId); 16123 intent = new Intent(Intent.ACTION_USER_SWITCHED); 16124 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16125 | Intent.FLAG_RECEIVER_FOREGROUND); 16126 intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId); 16127 broadcastIntentLocked(null, null, intent, 16128 null, null, 0, null, null, 16129 android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE, 16130 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 16131 } 16132 } finally { 16133 Binder.restoreCallingIdentity(ident); 16134 } 16135 } 16136 16137 void dispatchUserSwitch(final UserStartedState uss, final int oldUserId, 16138 final int newUserId) { 16139 final int N = mUserSwitchObservers.beginBroadcast(); 16140 if (N > 0) { 16141 final IRemoteCallback callback = new IRemoteCallback.Stub() { 16142 int mCount = 0; 16143 @Override 16144 public void sendResult(Bundle data) throws RemoteException { 16145 synchronized (ActivityManagerService.this) { 16146 if (mCurUserSwitchCallback == this) { 16147 mCount++; 16148 if (mCount == N) { 16149 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 16150 } 16151 } 16152 } 16153 } 16154 }; 16155 synchronized (this) { 16156 uss.switching = true; 16157 mCurUserSwitchCallback = callback; 16158 } 16159 for (int i=0; i<N; i++) { 16160 try { 16161 mUserSwitchObservers.getBroadcastItem(i).onUserSwitching( 16162 newUserId, callback); 16163 } catch (RemoteException e) { 16164 } 16165 } 16166 } else { 16167 synchronized (this) { 16168 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 16169 } 16170 } 16171 mUserSwitchObservers.finishBroadcast(); 16172 } 16173 16174 void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 16175 synchronized (this) { 16176 Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId); 16177 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 16178 } 16179 } 16180 16181 void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) { 16182 mCurUserSwitchCallback = null; 16183 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 16184 mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG, 16185 oldUserId, newUserId, uss)); 16186 } 16187 16188 void userInitialized(UserStartedState uss, int newUserId) { 16189 completeSwitchAndInitalize(uss, newUserId, true, false); 16190 } 16191 16192 void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 16193 completeSwitchAndInitalize(uss, newUserId, false, true); 16194 } 16195 16196 void completeSwitchAndInitalize(UserStartedState uss, int newUserId, 16197 boolean clearInitializing, boolean clearSwitching) { 16198 boolean unfrozen = false; 16199 synchronized (this) { 16200 if (clearInitializing) { 16201 uss.initializing = false; 16202 getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier()); 16203 } 16204 if (clearSwitching) { 16205 uss.switching = false; 16206 } 16207 if (!uss.switching && !uss.initializing) { 16208 mWindowManager.stopFreezingScreen(); 16209 unfrozen = true; 16210 } 16211 } 16212 if (unfrozen) { 16213 final int N = mUserSwitchObservers.beginBroadcast(); 16214 for (int i=0; i<N; i++) { 16215 try { 16216 mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId); 16217 } catch (RemoteException e) { 16218 } 16219 } 16220 mUserSwitchObservers.finishBroadcast(); 16221 } 16222 } 16223 16224 void finishUserSwitch(UserStartedState uss) { 16225 synchronized (this) { 16226 if (uss.mState == UserStartedState.STATE_BOOTING 16227 && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) { 16228 uss.mState = UserStartedState.STATE_RUNNING; 16229 final int userId = uss.mHandle.getIdentifier(); 16230 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 16231 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 16232 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT); 16233 broadcastIntentLocked(null, null, intent, 16234 null, null, 0, null, null, 16235 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE, 16236 true, false, MY_PID, Process.SYSTEM_UID, userId); 16237 } 16238 int num = mUserLru.size(); 16239 int i = 0; 16240 while (num > MAX_RUNNING_USERS && i < mUserLru.size()) { 16241 Integer oldUserId = mUserLru.get(i); 16242 UserStartedState oldUss = mStartedUsers.get(oldUserId); 16243 if (oldUss == null) { 16244 // Shouldn't happen, but be sane if it does. 16245 mUserLru.remove(i); 16246 num--; 16247 continue; 16248 } 16249 if (oldUss.mState == UserStartedState.STATE_STOPPING 16250 || oldUss.mState == UserStartedState.STATE_SHUTDOWN) { 16251 // This user is already stopping, doesn't count. 16252 num--; 16253 i++; 16254 continue; 16255 } 16256 if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) { 16257 // Owner and current can't be stopped, but count as running. 16258 i++; 16259 continue; 16260 } 16261 // This is a user to be stopped. 16262 stopUserLocked(oldUserId, null); 16263 num--; 16264 i++; 16265 } 16266 } 16267 } 16268 16269 @Override 16270 public int stopUser(final int userId, final IStopUserCallback callback) { 16271 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 16272 != PackageManager.PERMISSION_GRANTED) { 16273 String msg = "Permission Denial: switchUser() from pid=" 16274 + Binder.getCallingPid() 16275 + ", uid=" + Binder.getCallingUid() 16276 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 16277 Slog.w(TAG, msg); 16278 throw new SecurityException(msg); 16279 } 16280 if (userId <= 0) { 16281 throw new IllegalArgumentException("Can't stop primary user " + userId); 16282 } 16283 synchronized (this) { 16284 return stopUserLocked(userId, callback); 16285 } 16286 } 16287 16288 private int stopUserLocked(final int userId, final IStopUserCallback callback) { 16289 if (mCurrentUserId == userId) { 16290 return ActivityManager.USER_OP_IS_CURRENT; 16291 } 16292 16293 final UserStartedState uss = mStartedUsers.get(userId); 16294 if (uss == null) { 16295 // User is not started, nothing to do... but we do need to 16296 // callback if requested. 16297 if (callback != null) { 16298 mHandler.post(new Runnable() { 16299 @Override 16300 public void run() { 16301 try { 16302 callback.userStopped(userId); 16303 } catch (RemoteException e) { 16304 } 16305 } 16306 }); 16307 } 16308 return ActivityManager.USER_OP_SUCCESS; 16309 } 16310 16311 if (callback != null) { 16312 uss.mStopCallbacks.add(callback); 16313 } 16314 16315 if (uss.mState != UserStartedState.STATE_STOPPING 16316 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 16317 uss.mState = UserStartedState.STATE_STOPPING; 16318 updateStartedUserArrayLocked(); 16319 16320 long ident = Binder.clearCallingIdentity(); 16321 try { 16322 // We are going to broadcast ACTION_USER_STOPPING and then 16323 // once that is done send a final ACTION_SHUTDOWN and then 16324 // stop the user. 16325 final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING); 16326 stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 16327 stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 16328 stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true); 16329 final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN); 16330 // This is the result receiver for the final shutdown broadcast. 16331 final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() { 16332 @Override 16333 public void performReceive(Intent intent, int resultCode, String data, 16334 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 16335 finishUserStop(uss); 16336 } 16337 }; 16338 // This is the result receiver for the initial stopping broadcast. 16339 final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() { 16340 @Override 16341 public void performReceive(Intent intent, int resultCode, String data, 16342 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 16343 // On to the next. 16344 synchronized (ActivityManagerService.this) { 16345 if (uss.mState != UserStartedState.STATE_STOPPING) { 16346 // Whoops, we are being started back up. Abort, abort! 16347 return; 16348 } 16349 uss.mState = UserStartedState.STATE_SHUTDOWN; 16350 } 16351 broadcastIntentLocked(null, null, shutdownIntent, 16352 null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE, 16353 true, false, MY_PID, Process.SYSTEM_UID, userId); 16354 } 16355 }; 16356 // Kick things off. 16357 broadcastIntentLocked(null, null, stoppingIntent, 16358 null, stoppingReceiver, 0, null, null, 16359 android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 16360 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 16361 } finally { 16362 Binder.restoreCallingIdentity(ident); 16363 } 16364 } 16365 16366 return ActivityManager.USER_OP_SUCCESS; 16367 } 16368 16369 void finishUserStop(UserStartedState uss) { 16370 final int userId = uss.mHandle.getIdentifier(); 16371 boolean stopped; 16372 ArrayList<IStopUserCallback> callbacks; 16373 synchronized (this) { 16374 callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks); 16375 if (mStartedUsers.get(userId) != uss) { 16376 stopped = false; 16377 } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) { 16378 stopped = false; 16379 } else { 16380 stopped = true; 16381 // User can no longer run. 16382 mStartedUsers.remove(userId); 16383 mUserLru.remove(Integer.valueOf(userId)); 16384 updateStartedUserArrayLocked(); 16385 16386 // Clean up all state and processes associated with the user. 16387 // Kill all the processes for the user. 16388 forceStopUserLocked(userId, "finish user"); 16389 } 16390 } 16391 16392 for (int i=0; i<callbacks.size(); i++) { 16393 try { 16394 if (stopped) callbacks.get(i).userStopped(userId); 16395 else callbacks.get(i).userStopAborted(userId); 16396 } catch (RemoteException e) { 16397 } 16398 } 16399 16400 mStackSupervisor.removeUserLocked(userId); 16401 } 16402 16403 @Override 16404 public UserInfo getCurrentUser() { 16405 if ((checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) 16406 != PackageManager.PERMISSION_GRANTED) && ( 16407 checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 16408 != PackageManager.PERMISSION_GRANTED)) { 16409 String msg = "Permission Denial: getCurrentUser() from pid=" 16410 + Binder.getCallingPid() 16411 + ", uid=" + Binder.getCallingUid() 16412 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS; 16413 Slog.w(TAG, msg); 16414 throw new SecurityException(msg); 16415 } 16416 synchronized (this) { 16417 return getUserManagerLocked().getUserInfo(mCurrentUserId); 16418 } 16419 } 16420 16421 int getCurrentUserIdLocked() { 16422 return mCurrentUserId; 16423 } 16424 16425 @Override 16426 public boolean isUserRunning(int userId, boolean orStopped) { 16427 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) 16428 != PackageManager.PERMISSION_GRANTED) { 16429 String msg = "Permission Denial: isUserRunning() from pid=" 16430 + Binder.getCallingPid() 16431 + ", uid=" + Binder.getCallingUid() 16432 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS; 16433 Slog.w(TAG, msg); 16434 throw new SecurityException(msg); 16435 } 16436 synchronized (this) { 16437 return isUserRunningLocked(userId, orStopped); 16438 } 16439 } 16440 16441 boolean isUserRunningLocked(int userId, boolean orStopped) { 16442 UserStartedState state = mStartedUsers.get(userId); 16443 if (state == null) { 16444 return false; 16445 } 16446 if (orStopped) { 16447 return true; 16448 } 16449 return state.mState != UserStartedState.STATE_STOPPING 16450 && state.mState != UserStartedState.STATE_SHUTDOWN; 16451 } 16452 16453 @Override 16454 public int[] getRunningUserIds() { 16455 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) 16456 != PackageManager.PERMISSION_GRANTED) { 16457 String msg = "Permission Denial: isUserRunning() from pid=" 16458 + Binder.getCallingPid() 16459 + ", uid=" + Binder.getCallingUid() 16460 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS; 16461 Slog.w(TAG, msg); 16462 throw new SecurityException(msg); 16463 } 16464 synchronized (this) { 16465 return mStartedUserArray; 16466 } 16467 } 16468 16469 private void updateStartedUserArrayLocked() { 16470 int num = 0; 16471 for (int i=0; i<mStartedUsers.size(); i++) { 16472 UserStartedState uss = mStartedUsers.valueAt(i); 16473 // This list does not include stopping users. 16474 if (uss.mState != UserStartedState.STATE_STOPPING 16475 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 16476 num++; 16477 } 16478 } 16479 mStartedUserArray = new int[num]; 16480 num = 0; 16481 for (int i=0; i<mStartedUsers.size(); i++) { 16482 UserStartedState uss = mStartedUsers.valueAt(i); 16483 if (uss.mState != UserStartedState.STATE_STOPPING 16484 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 16485 mStartedUserArray[num] = mStartedUsers.keyAt(i); 16486 num++; 16487 } 16488 } 16489 } 16490 16491 @Override 16492 public void registerUserSwitchObserver(IUserSwitchObserver observer) { 16493 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 16494 != PackageManager.PERMISSION_GRANTED) { 16495 String msg = "Permission Denial: registerUserSwitchObserver() from pid=" 16496 + Binder.getCallingPid() 16497 + ", uid=" + Binder.getCallingUid() 16498 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 16499 Slog.w(TAG, msg); 16500 throw new SecurityException(msg); 16501 } 16502 16503 mUserSwitchObservers.register(observer); 16504 } 16505 16506 @Override 16507 public void unregisterUserSwitchObserver(IUserSwitchObserver observer) { 16508 mUserSwitchObservers.unregister(observer); 16509 } 16510 16511 private boolean userExists(int userId) { 16512 if (userId == 0) { 16513 return true; 16514 } 16515 UserManagerService ums = getUserManagerLocked(); 16516 return ums != null ? (ums.getUserInfo(userId) != null) : false; 16517 } 16518 16519 int[] getUsersLocked() { 16520 UserManagerService ums = getUserManagerLocked(); 16521 return ums != null ? ums.getUserIds() : new int[] { 0 }; 16522 } 16523 16524 UserManagerService getUserManagerLocked() { 16525 if (mUserManager == null) { 16526 IBinder b = ServiceManager.getService(Context.USER_SERVICE); 16527 mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b); 16528 } 16529 return mUserManager; 16530 } 16531 16532 private int applyUserId(int uid, int userId) { 16533 return UserHandle.getUid(userId, uid); 16534 } 16535 16536 ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) { 16537 if (info == null) return null; 16538 ApplicationInfo newInfo = new ApplicationInfo(info); 16539 newInfo.uid = applyUserId(info.uid, userId); 16540 newInfo.dataDir = USER_DATA_DIR + userId + "/" 16541 + info.packageName; 16542 return newInfo; 16543 } 16544 16545 ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) { 16546 if (aInfo == null 16547 || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) { 16548 return aInfo; 16549 } 16550 16551 ActivityInfo info = new ActivityInfo(aInfo); 16552 info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId); 16553 return info; 16554 } 16555 16556 private final class LocalService extends ActivityManagerInternal { 16557 @Override 16558 public void goingToSleep() { 16559 ActivityManagerService.this.goingToSleep(); 16560 } 16561 16562 @Override 16563 public void wakingUp() { 16564 ActivityManagerService.this.wakingUp(); 16565 } 16566 } 16567} 16568