ActivityManagerService.java revision 5f6238e4a7b2b54c4852852bd9bf045f387a5e42
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.util.FastPrintWriter; 46import com.android.internal.util.FastXmlSerializer; 47import com.android.internal.util.MemInfoReader; 48import com.android.internal.util.Preconditions; 49import com.android.server.AppOpsService; 50import com.android.server.AttributeCache; 51import com.android.server.IntentResolver; 52import com.android.server.LocalServices; 53import com.android.server.ServiceThread; 54import com.android.server.SystemService; 55import com.android.server.Watchdog; 56import com.android.server.am.ActivityStack.ActivityState; 57import com.android.server.firewall.IntentFirewall; 58import com.android.server.pm.UserManagerService; 59import com.android.server.wm.AppTransition; 60import com.android.server.wm.WindowManagerService; 61import com.google.android.collect.Lists; 62import com.google.android.collect.Maps; 63 64import dalvik.system.Zygote; 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 = 300*1000; 277 278 // How long to wait after going idle before forcing apps to GC. 279 static final int GC_TIMEOUT = 5*1000; 280 281 // The minimum amount of time between successive GC requests for a process. 282 static final int GC_MIN_INTERVAL = 60*1000; 283 284 // The minimum amount of time between successive PSS requests for a process. 285 static final int FULL_PSS_MIN_INTERVAL = 10*60*1000; 286 287 // The minimum amount of time between successive PSS requests for a process 288 // when the request is due to the memory state being lowered. 289 static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000; 290 291 // The rate at which we check for apps using excessive power -- 15 mins. 292 static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000; 293 294 // The minimum sample duration we will allow before deciding we have 295 // enough data on wake locks to start killing things. 296 static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000; 297 298 // The minimum sample duration we will allow before deciding we have 299 // enough data on CPU usage to start killing things. 300 static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000; 301 302 // How long we allow a receiver to run before giving up on it. 303 static final int BROADCAST_FG_TIMEOUT = 10*1000; 304 static final int BROADCAST_BG_TIMEOUT = 60*1000; 305 306 // How long we wait until we timeout on key dispatching. 307 static final int KEY_DISPATCHING_TIMEOUT = 5*1000; 308 309 // How long we wait until we timeout on key dispatching during instrumentation. 310 static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000; 311 312 // Amount of time we wait for observers to handle a user switch before 313 // giving up on them and unfreezing the screen. 314 static final int USER_SWITCH_TIMEOUT = 2*1000; 315 316 // Maximum number of users we allow to be running at a time. 317 static final int MAX_RUNNING_USERS = 3; 318 319 // How long to wait in getAssistContextExtras for the activity and foreground services 320 // to respond with the result. 321 static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500; 322 323 // Maximum number of persisted Uri grants a package is allowed 324 static final int MAX_PERSISTED_URI_GRANTS = 128; 325 326 static final int MY_PID = Process.myPid(); 327 328 static final String[] EMPTY_STRING_ARRAY = new String[0]; 329 330 // How many bytes to write into the dropbox log before truncating 331 static final int DROPBOX_MAX_SIZE = 256 * 1024; 332 333 /** Run all ActivityStacks through this */ 334 ActivityStackSupervisor mStackSupervisor; 335 336 public IntentFirewall mIntentFirewall; 337 338 // Whether we should show our dialogs (ANR, crash, etc) or just perform their 339 // default actuion automatically. Important for devices without direct input 340 // devices. 341 private boolean mShowDialogs = true; 342 343 /** 344 * Description of a request to start a new activity, which has been held 345 * due to app switches being disabled. 346 */ 347 static class PendingActivityLaunch { 348 final ActivityRecord r; 349 final ActivityRecord sourceRecord; 350 final int startFlags; 351 final ActivityStack stack; 352 353 PendingActivityLaunch(ActivityRecord _r, ActivityRecord _sourceRecord, 354 int _startFlags, ActivityStack _stack) { 355 r = _r; 356 sourceRecord = _sourceRecord; 357 startFlags = _startFlags; 358 stack = _stack; 359 } 360 } 361 362 final ArrayList<PendingActivityLaunch> mPendingActivityLaunches 363 = new ArrayList<PendingActivityLaunch>(); 364 365 BroadcastQueue mFgBroadcastQueue; 366 BroadcastQueue mBgBroadcastQueue; 367 // Convenient for easy iteration over the queues. Foreground is first 368 // so that dispatch of foreground broadcasts gets precedence. 369 final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2]; 370 371 BroadcastQueue broadcastQueueForIntent(Intent intent) { 372 final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0; 373 if (DEBUG_BACKGROUND_BROADCAST) { 374 Slog.i(TAG, "Broadcast intent " + intent + " on " 375 + (isFg ? "foreground" : "background") 376 + " queue"); 377 } 378 return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue; 379 } 380 381 BroadcastRecord broadcastRecordForReceiverLocked(IBinder receiver) { 382 for (BroadcastQueue queue : mBroadcastQueues) { 383 BroadcastRecord r = queue.getMatchingOrderedReceiver(receiver); 384 if (r != null) { 385 return r; 386 } 387 } 388 return null; 389 } 390 391 /** 392 * Activity we have told the window manager to have key focus. 393 */ 394 ActivityRecord mFocusedActivity = null; 395 396 /** 397 * List of intents that were used to start the most recent tasks. 398 */ 399 private final ArrayList<TaskRecord> mRecentTasks = new ArrayList<TaskRecord>(); 400 401 public class PendingAssistExtras extends Binder implements Runnable { 402 public final ActivityRecord activity; 403 public boolean haveResult = false; 404 public Bundle result = null; 405 public PendingAssistExtras(ActivityRecord _activity) { 406 activity = _activity; 407 } 408 @Override 409 public void run() { 410 Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity); 411 synchronized (this) { 412 haveResult = true; 413 notifyAll(); 414 } 415 } 416 } 417 418 final ArrayList<PendingAssistExtras> mPendingAssistExtras 419 = new ArrayList<PendingAssistExtras>(); 420 421 /** 422 * Process management. 423 */ 424 final ProcessList mProcessList = new ProcessList(); 425 426 /** 427 * All of the applications we currently have running organized by name. 428 * The keys are strings of the application package name (as 429 * returned by the package manager), and the keys are ApplicationRecord 430 * objects. 431 */ 432 final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>(); 433 434 /** 435 * Tracking long-term execution of processes to look for abuse and other 436 * bad app behavior. 437 */ 438 final ProcessStatsService mProcessStats; 439 440 /** 441 * The currently running isolated processes. 442 */ 443 final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>(); 444 445 /** 446 * Counter for assigning isolated process uids, to avoid frequently reusing the 447 * same ones. 448 */ 449 int mNextIsolatedProcessUid = 0; 450 451 /** 452 * The currently running heavy-weight process, if any. 453 */ 454 ProcessRecord mHeavyWeightProcess = null; 455 456 /** 457 * The last time that various processes have crashed. 458 */ 459 final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>(); 460 461 /** 462 * Information about a process that is currently marked as bad. 463 */ 464 static final class BadProcessInfo { 465 BadProcessInfo(long time, String shortMsg, String longMsg, String stack) { 466 this.time = time; 467 this.shortMsg = shortMsg; 468 this.longMsg = longMsg; 469 this.stack = stack; 470 } 471 472 final long time; 473 final String shortMsg; 474 final String longMsg; 475 final String stack; 476 } 477 478 /** 479 * Set of applications that we consider to be bad, and will reject 480 * incoming broadcasts from (which the user has no control over). 481 * Processes are added to this set when they have crashed twice within 482 * a minimum amount of time; they are removed from it when they are 483 * later restarted (hopefully due to some user action). The value is the 484 * time it was added to the list. 485 */ 486 final ProcessMap<BadProcessInfo> mBadProcesses = new ProcessMap<BadProcessInfo>(); 487 488 /** 489 * All of the processes we currently have running organized by pid. 490 * The keys are the pid running the application. 491 * 492 * <p>NOTE: This object is protected by its own lock, NOT the global 493 * activity manager lock! 494 */ 495 final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>(); 496 497 /** 498 * All of the processes that have been forced to be foreground. The key 499 * is the pid of the caller who requested it (we hold a death 500 * link on it). 501 */ 502 abstract class ForegroundToken implements IBinder.DeathRecipient { 503 int pid; 504 IBinder token; 505 } 506 final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>(); 507 508 /** 509 * List of records for processes that someone had tried to start before the 510 * system was ready. We don't start them at that point, but ensure they 511 * are started by the time booting is complete. 512 */ 513 final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>(); 514 515 /** 516 * List of persistent applications that are in the process 517 * of being started. 518 */ 519 final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>(); 520 521 /** 522 * Processes that are being forcibly torn down. 523 */ 524 final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>(); 525 526 /** 527 * List of running applications, sorted by recent usage. 528 * The first entry in the list is the least recently used. 529 */ 530 final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>(); 531 532 /** 533 * Where in mLruProcesses that the processes hosting activities start. 534 */ 535 int mLruProcessActivityStart = 0; 536 537 /** 538 * Where in mLruProcesses that the processes hosting services start. 539 * This is after (lower index) than mLruProcessesActivityStart. 540 */ 541 int mLruProcessServiceStart = 0; 542 543 /** 544 * List of processes that should gc as soon as things are idle. 545 */ 546 final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>(); 547 548 /** 549 * Processes we want to collect PSS data from. 550 */ 551 final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>(); 552 553 /** 554 * Last time we requested PSS data of all processes. 555 */ 556 long mLastFullPssTime = SystemClock.uptimeMillis(); 557 558 /** 559 * This is the process holding what we currently consider to be 560 * the "home" activity. 561 */ 562 ProcessRecord mHomeProcess; 563 564 /** 565 * This is the process holding the activity the user last visited that 566 * is in a different process from the one they are currently in. 567 */ 568 ProcessRecord mPreviousProcess; 569 570 /** 571 * The time at which the previous process was last visible. 572 */ 573 long mPreviousProcessVisibleTime; 574 575 /** 576 * Which uses have been started, so are allowed to run code. 577 */ 578 final SparseArray<UserStartedState> mStartedUsers = new SparseArray<UserStartedState>(); 579 580 /** 581 * LRU list of history of current users. Most recently current is at the end. 582 */ 583 final ArrayList<Integer> mUserLru = new ArrayList<Integer>(); 584 585 /** 586 * Constant array of the users that are currently started. 587 */ 588 int[] mStartedUserArray = new int[] { 0 }; 589 590 /** 591 * Registered observers of the user switching mechanics. 592 */ 593 final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers 594 = new RemoteCallbackList<IUserSwitchObserver>(); 595 596 /** 597 * Currently active user switch. 598 */ 599 Object mCurUserSwitchCallback; 600 601 /** 602 * Packages that the user has asked to have run in screen size 603 * compatibility mode instead of filling the screen. 604 */ 605 final CompatModePackages mCompatModePackages; 606 607 /** 608 * Set of IntentSenderRecord objects that are currently active. 609 */ 610 final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords 611 = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>(); 612 613 /** 614 * Fingerprints (hashCode()) of stack traces that we've 615 * already logged DropBox entries for. Guarded by itself. If 616 * something (rogue user app) forces this over 617 * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared. 618 */ 619 private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>(); 620 private static final int MAX_DUP_SUPPRESSED_STACKS = 5000; 621 622 /** 623 * Strict Mode background batched logging state. 624 * 625 * The string buffer is guarded by itself, and its lock is also 626 * used to determine if another batched write is already 627 * in-flight. 628 */ 629 private final StringBuilder mStrictModeBuffer = new StringBuilder(); 630 631 /** 632 * Keeps track of all IIntentReceivers that have been registered for 633 * broadcasts. Hash keys are the receiver IBinder, hash value is 634 * a ReceiverList. 635 */ 636 final HashMap<IBinder, ReceiverList> mRegisteredReceivers = 637 new HashMap<IBinder, ReceiverList>(); 638 639 /** 640 * Resolver for broadcast intents to registered receivers. 641 * Holds BroadcastFilter (subclass of IntentFilter). 642 */ 643 final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver 644 = new IntentResolver<BroadcastFilter, BroadcastFilter>() { 645 @Override 646 protected boolean allowFilterResult( 647 BroadcastFilter filter, List<BroadcastFilter> dest) { 648 IBinder target = filter.receiverList.receiver.asBinder(); 649 for (int i=dest.size()-1; i>=0; i--) { 650 if (dest.get(i).receiverList.receiver.asBinder() == target) { 651 return false; 652 } 653 } 654 return true; 655 } 656 657 @Override 658 protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) { 659 if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL 660 || userId == filter.owningUserId) { 661 return super.newResult(filter, match, userId); 662 } 663 return null; 664 } 665 666 @Override 667 protected BroadcastFilter[] newArray(int size) { 668 return new BroadcastFilter[size]; 669 } 670 671 @Override 672 protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) { 673 return packageName.equals(filter.packageName); 674 } 675 }; 676 677 /** 678 * State of all active sticky broadcasts per user. Keys are the action of the 679 * sticky Intent, values are an ArrayList of all broadcasted intents with 680 * that action (which should usually be one). The SparseArray is keyed 681 * by the user ID the sticky is for, and can include UserHandle.USER_ALL 682 * for stickies that are sent to all users. 683 */ 684 final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts = 685 new SparseArray<ArrayMap<String, ArrayList<Intent>>>(); 686 687 final ActiveServices mServices; 688 689 /** 690 * Backup/restore process management 691 */ 692 String mBackupAppName = null; 693 BackupRecord mBackupTarget = null; 694 695 /** 696 * List of PendingThumbnailsRecord objects of clients who are still 697 * waiting to receive all of the thumbnails for a task. 698 */ 699 final ArrayList<PendingThumbnailsRecord> mPendingThumbnails = 700 new ArrayList<PendingThumbnailsRecord>(); 701 702 final ProviderMap mProviderMap; 703 704 /** 705 * List of content providers who have clients waiting for them. The 706 * application is currently being launched and the provider will be 707 * removed from this list once it is published. 708 */ 709 final ArrayList<ContentProviderRecord> mLaunchingProviders 710 = new ArrayList<ContentProviderRecord>(); 711 712 /** 713 * File storing persisted {@link #mGrantedUriPermissions}. 714 */ 715 private final AtomicFile mGrantFile; 716 717 /** XML constants used in {@link #mGrantFile} */ 718 private static final String TAG_URI_GRANTS = "uri-grants"; 719 private static final String TAG_URI_GRANT = "uri-grant"; 720 private static final String ATTR_USER_HANDLE = "userHandle"; 721 private static final String ATTR_SOURCE_PKG = "sourcePkg"; 722 private static final String ATTR_TARGET_PKG = "targetPkg"; 723 private static final String ATTR_URI = "uri"; 724 private static final String ATTR_MODE_FLAGS = "modeFlags"; 725 private static final String ATTR_CREATED_TIME = "createdTime"; 726 727 /** 728 * Global set of specific {@link Uri} permissions that have been granted. 729 * This optimized lookup structure maps from {@link UriPermission#targetUid} 730 * to {@link UriPermission#uri} to {@link UriPermission}. 731 */ 732 @GuardedBy("this") 733 private final SparseArray<ArrayMap<Uri, UriPermission>> 734 mGrantedUriPermissions = new SparseArray<ArrayMap<Uri, UriPermission>>(); 735 736 CoreSettingsObserver mCoreSettingsObserver; 737 738 /** 739 * Thread-local storage used to carry caller permissions over through 740 * indirect content-provider access. 741 */ 742 private class Identity { 743 public int pid; 744 public int uid; 745 746 Identity(int _pid, int _uid) { 747 pid = _pid; 748 uid = _uid; 749 } 750 } 751 752 private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>(); 753 754 /** 755 * All information we have collected about the runtime performance of 756 * any user id that can impact battery performance. 757 */ 758 final BatteryStatsService mBatteryStatsService; 759 760 /** 761 * Information about component usage 762 */ 763 final UsageStatsService mUsageStatsService; 764 765 /** 766 * Information about and control over application operations 767 */ 768 final AppOpsService mAppOpsService; 769 770 /** 771 * Current configuration information. HistoryRecord objects are given 772 * a reference to this object to indicate which configuration they are 773 * currently running in, so this object must be kept immutable. 774 */ 775 Configuration mConfiguration = new Configuration(); 776 777 /** 778 * Current sequencing integer of the configuration, for skipping old 779 * configurations. 780 */ 781 int mConfigurationSeq = 0; 782 783 /** 784 * Hardware-reported OpenGLES version. 785 */ 786 final int GL_ES_VERSION; 787 788 /** 789 * List of initialization arguments to pass to all processes when binding applications to them. 790 * For example, references to the commonly used services. 791 */ 792 HashMap<String, IBinder> mAppBindArgs; 793 794 /** 795 * Temporary to avoid allocations. Protected by main lock. 796 */ 797 final StringBuilder mStringBuilder = new StringBuilder(256); 798 799 /** 800 * Used to control how we initialize the service. 801 */ 802 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 increasing the ANR timeouts in that case. 930 */ 931 boolean mDidDexOpt; 932 933 String mDebugApp = null; 934 boolean mWaitForDebugger = false; 935 boolean mDebugTransient = false; 936 String mOrigDebugApp = null; 937 boolean mOrigWaitForDebugger = false; 938 boolean mAlwaysFinishActivities = false; 939 IActivityController mController = null; 940 String mProfileApp = null; 941 ProcessRecord mProfileProc = null; 942 String mProfileFile; 943 ParcelFileDescriptor mProfileFd; 944 int mProfileType = 0; 945 boolean mAutoStopProfiler = false; 946 String mOpenGlTraceApp = null; 947 948 static class ProcessChangeItem { 949 static final int CHANGE_ACTIVITIES = 1<<0; 950 static final int CHANGE_IMPORTANCE= 1<<1; 951 int changes; 952 int uid; 953 int pid; 954 int importance; 955 boolean foregroundActivities; 956 } 957 958 final RemoteCallbackList<IProcessObserver> mProcessObservers 959 = new RemoteCallbackList<IProcessObserver>(); 960 ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5]; 961 962 final ArrayList<ProcessChangeItem> mPendingProcessChanges 963 = new ArrayList<ProcessChangeItem>(); 964 final ArrayList<ProcessChangeItem> mAvailProcessChanges 965 = new ArrayList<ProcessChangeItem>(); 966 967 /** 968 * Runtime CPU use collection thread. This object's lock is used to 969 * protect all related state. 970 */ 971 final Thread mProcessCpuThread; 972 973 /** 974 * Used to collect process stats when showing not responding dialog. 975 * Protected by mProcessCpuThread. 976 */ 977 final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker( 978 MONITOR_THREAD_CPU_USAGE); 979 final AtomicLong mLastCpuTime = new AtomicLong(0); 980 final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true); 981 982 long mLastWriteTime = 0; 983 984 /** 985 * Used to retain an update lock when the foreground activity is in 986 * immersive mode. 987 */ 988 final UpdateLock mUpdateLock = new UpdateLock("immersive"); 989 990 /** 991 * Set to true after the system has finished booting. 992 */ 993 boolean mBooted = false; 994 995 int mProcessLimit = ProcessList.MAX_CACHED_APPS; 996 int mProcessLimitOverride = -1; 997 998 WindowManagerService mWindowManager; 999 1000 final ActivityThread mSystemThread; 1001 1002 int mCurrentUserId = 0; 1003 private UserManagerService mUserManager; 1004 1005 private final class AppDeathRecipient implements IBinder.DeathRecipient { 1006 final ProcessRecord mApp; 1007 final int mPid; 1008 final IApplicationThread mAppThread; 1009 1010 AppDeathRecipient(ProcessRecord app, int pid, 1011 IApplicationThread thread) { 1012 if (localLOGV) Slog.v( 1013 TAG, "New death recipient " + this 1014 + " for thread " + thread.asBinder()); 1015 mApp = app; 1016 mPid = pid; 1017 mAppThread = thread; 1018 } 1019 1020 @Override 1021 public void binderDied() { 1022 if (localLOGV) Slog.v( 1023 TAG, "Death received in " + this 1024 + " for thread " + mAppThread.asBinder()); 1025 synchronized(ActivityManagerService.this) { 1026 appDiedLocked(mApp, mPid, mAppThread); 1027 } 1028 } 1029 } 1030 1031 static final int SHOW_ERROR_MSG = 1; 1032 static final int SHOW_NOT_RESPONDING_MSG = 2; 1033 static final int SHOW_FACTORY_ERROR_MSG = 3; 1034 static final int UPDATE_CONFIGURATION_MSG = 4; 1035 static final int GC_BACKGROUND_PROCESSES_MSG = 5; 1036 static final int WAIT_FOR_DEBUGGER_MSG = 6; 1037 static final int SERVICE_TIMEOUT_MSG = 12; 1038 static final int UPDATE_TIME_ZONE = 13; 1039 static final int SHOW_UID_ERROR_MSG = 14; 1040 static final int IM_FEELING_LUCKY_MSG = 15; 1041 static final int PROC_START_TIMEOUT_MSG = 20; 1042 static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21; 1043 static final int KILL_APPLICATION_MSG = 22; 1044 static final int FINALIZE_PENDING_INTENT_MSG = 23; 1045 static final int POST_HEAVY_NOTIFICATION_MSG = 24; 1046 static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25; 1047 static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26; 1048 static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27; 1049 static final int CLEAR_DNS_CACHE_MSG = 28; 1050 static final int UPDATE_HTTP_PROXY_MSG = 29; 1051 static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30; 1052 static final int DISPATCH_PROCESSES_CHANGED = 31; 1053 static final int DISPATCH_PROCESS_DIED = 32; 1054 static final int REPORT_MEM_USAGE_MSG = 33; 1055 static final int REPORT_USER_SWITCH_MSG = 34; 1056 static final int CONTINUE_USER_SWITCH_MSG = 35; 1057 static final int USER_SWITCH_TIMEOUT_MSG = 36; 1058 static final int IMMERSIVE_MODE_LOCK_MSG = 37; 1059 static final int PERSIST_URI_GRANTS_MSG = 38; 1060 static final int REQUEST_ALL_PSS_MSG = 39; 1061 1062 static final int FIRST_ACTIVITY_STACK_MSG = 100; 1063 static final int FIRST_BROADCAST_QUEUE_MSG = 200; 1064 static final int FIRST_COMPAT_MODE_MSG = 300; 1065 static final int FIRST_SUPERVISOR_STACK_MSG = 100; 1066 1067 AlertDialog mUidAlert; 1068 CompatModeDialog mCompatModeDialog; 1069 long mLastMemUsageReportTime = 0; 1070 1071 /** 1072 * Flag whether the current user is a "monkey", i.e. whether 1073 * the UI is driven by a UI automation tool. 1074 */ 1075 private boolean mUserIsMonkey; 1076 1077 /** Flag whether the device has a recents UI */ 1078 final boolean mHasRecents; 1079 1080 final ServiceThread mHandlerThread; 1081 final MainHandler mHandler; 1082 1083 final class MainHandler extends Handler { 1084 public MainHandler(Looper looper) { 1085 super(looper, null, true); 1086 } 1087 1088 @Override 1089 public void handleMessage(Message msg) { 1090 switch (msg.what) { 1091 case SHOW_ERROR_MSG: { 1092 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1093 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), 1094 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; 1095 synchronized (ActivityManagerService.this) { 1096 ProcessRecord proc = (ProcessRecord)data.get("app"); 1097 AppErrorResult res = (AppErrorResult) data.get("result"); 1098 if (proc != null && proc.crashDialog != null) { 1099 Slog.e(TAG, "App already has crash dialog: " + proc); 1100 if (res != null) { 1101 res.set(0); 1102 } 1103 return; 1104 } 1105 if (!showBackground && UserHandle.getAppId(proc.uid) 1106 >= Process.FIRST_APPLICATION_UID && proc.userId != mCurrentUserId 1107 && proc.pid != MY_PID) { 1108 Slog.w(TAG, "Skipping crash dialog of " + proc + ": background"); 1109 if (res != null) { 1110 res.set(0); 1111 } 1112 return; 1113 } 1114 if (mShowDialogs && !mSleeping && !mShuttingDown) { 1115 Dialog d = new AppErrorDialog(mContext, 1116 ActivityManagerService.this, res, proc); 1117 d.show(); 1118 proc.crashDialog = d; 1119 } else { 1120 // The device is asleep, so just pretend that the user 1121 // saw a crash dialog and hit "force quit". 1122 if (res != null) { 1123 res.set(0); 1124 } 1125 } 1126 } 1127 1128 ensureBootCompleted(); 1129 } break; 1130 case SHOW_NOT_RESPONDING_MSG: { 1131 synchronized (ActivityManagerService.this) { 1132 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1133 ProcessRecord proc = (ProcessRecord)data.get("app"); 1134 if (proc != null && proc.anrDialog != null) { 1135 Slog.e(TAG, "App already has anr dialog: " + proc); 1136 return; 1137 } 1138 1139 Intent intent = new Intent("android.intent.action.ANR"); 1140 if (!mProcessesReady) { 1141 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 1142 | Intent.FLAG_RECEIVER_FOREGROUND); 1143 } 1144 broadcastIntentLocked(null, null, intent, 1145 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 1146 false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */); 1147 1148 if (mShowDialogs) { 1149 Dialog d = new AppNotRespondingDialog(ActivityManagerService.this, 1150 mContext, proc, (ActivityRecord)data.get("activity"), 1151 msg.arg1 != 0); 1152 d.show(); 1153 proc.anrDialog = d; 1154 } else { 1155 // Just kill the app if there is no dialog to be shown. 1156 killAppAtUsersRequest(proc, null); 1157 } 1158 } 1159 1160 ensureBootCompleted(); 1161 } break; 1162 case SHOW_STRICT_MODE_VIOLATION_MSG: { 1163 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1164 synchronized (ActivityManagerService.this) { 1165 ProcessRecord proc = (ProcessRecord) data.get("app"); 1166 if (proc == null) { 1167 Slog.e(TAG, "App not found when showing strict mode dialog."); 1168 break; 1169 } 1170 if (proc.crashDialog != null) { 1171 Slog.e(TAG, "App already has strict mode dialog: " + proc); 1172 return; 1173 } 1174 AppErrorResult res = (AppErrorResult) data.get("result"); 1175 if (mShowDialogs && !mSleeping && !mShuttingDown) { 1176 Dialog d = new StrictModeViolationDialog(mContext, 1177 ActivityManagerService.this, res, proc); 1178 d.show(); 1179 proc.crashDialog = d; 1180 } else { 1181 // The device is asleep, so just pretend that the user 1182 // saw a crash dialog and hit "force quit". 1183 res.set(0); 1184 } 1185 } 1186 ensureBootCompleted(); 1187 } break; 1188 case SHOW_FACTORY_ERROR_MSG: { 1189 Dialog d = new FactoryErrorDialog( 1190 mContext, msg.getData().getCharSequence("msg")); 1191 d.show(); 1192 ensureBootCompleted(); 1193 } break; 1194 case UPDATE_CONFIGURATION_MSG: { 1195 final ContentResolver resolver = mContext.getContentResolver(); 1196 Settings.System.putConfiguration(resolver, (Configuration)msg.obj); 1197 } break; 1198 case GC_BACKGROUND_PROCESSES_MSG: { 1199 synchronized (ActivityManagerService.this) { 1200 performAppGcsIfAppropriateLocked(); 1201 } 1202 } break; 1203 case WAIT_FOR_DEBUGGER_MSG: { 1204 synchronized (ActivityManagerService.this) { 1205 ProcessRecord app = (ProcessRecord)msg.obj; 1206 if (msg.arg1 != 0) { 1207 if (!app.waitedForDebugger) { 1208 Dialog d = new AppWaitingForDebuggerDialog( 1209 ActivityManagerService.this, 1210 mContext, app); 1211 app.waitDialog = d; 1212 app.waitedForDebugger = true; 1213 d.show(); 1214 } 1215 } else { 1216 if (app.waitDialog != null) { 1217 app.waitDialog.dismiss(); 1218 app.waitDialog = null; 1219 } 1220 } 1221 } 1222 } break; 1223 case SERVICE_TIMEOUT_MSG: { 1224 if (mDidDexOpt) { 1225 mDidDexOpt = false; 1226 Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG); 1227 nmsg.obj = msg.obj; 1228 mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT); 1229 return; 1230 } 1231 mServices.serviceTimeout((ProcessRecord)msg.obj); 1232 } break; 1233 case UPDATE_TIME_ZONE: { 1234 synchronized (ActivityManagerService.this) { 1235 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1236 ProcessRecord r = mLruProcesses.get(i); 1237 if (r.thread != null) { 1238 try { 1239 r.thread.updateTimeZone(); 1240 } catch (RemoteException ex) { 1241 Slog.w(TAG, "Failed to update time zone for: " + r.info.processName); 1242 } 1243 } 1244 } 1245 } 1246 } break; 1247 case CLEAR_DNS_CACHE_MSG: { 1248 synchronized (ActivityManagerService.this) { 1249 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1250 ProcessRecord r = mLruProcesses.get(i); 1251 if (r.thread != null) { 1252 try { 1253 r.thread.clearDnsCache(); 1254 } catch (RemoteException ex) { 1255 Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName); 1256 } 1257 } 1258 } 1259 } 1260 } break; 1261 case UPDATE_HTTP_PROXY_MSG: { 1262 ProxyProperties proxy = (ProxyProperties)msg.obj; 1263 String host = ""; 1264 String port = ""; 1265 String exclList = ""; 1266 String pacFileUrl = null; 1267 if (proxy != null) { 1268 host = proxy.getHost(); 1269 port = Integer.toString(proxy.getPort()); 1270 exclList = proxy.getExclusionList(); 1271 pacFileUrl = proxy.getPacFileUrl(); 1272 } 1273 synchronized (ActivityManagerService.this) { 1274 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1275 ProcessRecord r = mLruProcesses.get(i); 1276 if (r.thread != null) { 1277 try { 1278 r.thread.setHttpProxy(host, port, exclList, pacFileUrl); 1279 } catch (RemoteException ex) { 1280 Slog.w(TAG, "Failed to update http proxy for: " + 1281 r.info.processName); 1282 } 1283 } 1284 } 1285 } 1286 } break; 1287 case SHOW_UID_ERROR_MSG: { 1288 String title = "System UIDs Inconsistent"; 1289 String text = "UIDs on the system are inconsistent, you need to wipe your" 1290 + " data partition or your device will be unstable."; 1291 Log.e(TAG, title + ": " + text); 1292 if (mShowDialogs) { 1293 // XXX This is a temporary dialog, no need to localize. 1294 AlertDialog d = new BaseErrorDialog(mContext); 1295 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR); 1296 d.setCancelable(false); 1297 d.setTitle(title); 1298 d.setMessage(text); 1299 d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky", 1300 mHandler.obtainMessage(IM_FEELING_LUCKY_MSG)); 1301 mUidAlert = d; 1302 d.show(); 1303 } 1304 } break; 1305 case IM_FEELING_LUCKY_MSG: { 1306 if (mUidAlert != null) { 1307 mUidAlert.dismiss(); 1308 mUidAlert = null; 1309 } 1310 } break; 1311 case PROC_START_TIMEOUT_MSG: { 1312 if (mDidDexOpt) { 1313 mDidDexOpt = false; 1314 Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 1315 nmsg.obj = msg.obj; 1316 mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT); 1317 return; 1318 } 1319 ProcessRecord app = (ProcessRecord)msg.obj; 1320 synchronized (ActivityManagerService.this) { 1321 processStartTimedOutLocked(app); 1322 } 1323 } break; 1324 case DO_PENDING_ACTIVITY_LAUNCHES_MSG: { 1325 synchronized (ActivityManagerService.this) { 1326 doPendingActivityLaunchesLocked(true); 1327 } 1328 } break; 1329 case KILL_APPLICATION_MSG: { 1330 synchronized (ActivityManagerService.this) { 1331 int appid = msg.arg1; 1332 boolean restart = (msg.arg2 == 1); 1333 Bundle bundle = (Bundle)msg.obj; 1334 String pkg = bundle.getString("pkg"); 1335 String reason = bundle.getString("reason"); 1336 forceStopPackageLocked(pkg, appid, restart, false, true, false, 1337 UserHandle.USER_ALL, reason); 1338 } 1339 } break; 1340 case FINALIZE_PENDING_INTENT_MSG: { 1341 ((PendingIntentRecord)msg.obj).completeFinalize(); 1342 } break; 1343 case POST_HEAVY_NOTIFICATION_MSG: { 1344 INotificationManager inm = NotificationManager.getService(); 1345 if (inm == null) { 1346 return; 1347 } 1348 1349 ActivityRecord root = (ActivityRecord)msg.obj; 1350 ProcessRecord process = root.app; 1351 if (process == null) { 1352 return; 1353 } 1354 1355 try { 1356 Context context = mContext.createPackageContext(process.info.packageName, 0); 1357 String text = mContext.getString(R.string.heavy_weight_notification, 1358 context.getApplicationInfo().loadLabel(context.getPackageManager())); 1359 Notification notification = new Notification(); 1360 notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon; 1361 notification.when = 0; 1362 notification.flags = Notification.FLAG_ONGOING_EVENT; 1363 notification.tickerText = text; 1364 notification.defaults = 0; // please be quiet 1365 notification.sound = null; 1366 notification.vibrate = null; 1367 notification.setLatestEventInfo(context, text, 1368 mContext.getText(R.string.heavy_weight_notification_detail), 1369 PendingIntent.getActivityAsUser(mContext, 0, root.intent, 1370 PendingIntent.FLAG_CANCEL_CURRENT, null, 1371 new UserHandle(root.userId))); 1372 1373 try { 1374 int[] outId = new int[1]; 1375 inm.enqueueNotificationWithTag("android", "android", null, 1376 R.string.heavy_weight_notification, 1377 notification, outId, root.userId); 1378 } catch (RuntimeException e) { 1379 Slog.w(ActivityManagerService.TAG, 1380 "Error showing notification for heavy-weight app", e); 1381 } catch (RemoteException e) { 1382 } 1383 } catch (NameNotFoundException e) { 1384 Slog.w(TAG, "Unable to create context for heavy notification", e); 1385 } 1386 } break; 1387 case CANCEL_HEAVY_NOTIFICATION_MSG: { 1388 INotificationManager inm = NotificationManager.getService(); 1389 if (inm == null) { 1390 return; 1391 } 1392 try { 1393 inm.cancelNotificationWithTag("android", null, 1394 R.string.heavy_weight_notification, msg.arg1); 1395 } catch (RuntimeException e) { 1396 Slog.w(ActivityManagerService.TAG, 1397 "Error canceling notification for service", e); 1398 } catch (RemoteException e) { 1399 } 1400 } break; 1401 case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: { 1402 synchronized (ActivityManagerService.this) { 1403 checkExcessivePowerUsageLocked(true); 1404 removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1405 Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1406 sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 1407 } 1408 } break; 1409 case SHOW_COMPAT_MODE_DIALOG_MSG: { 1410 synchronized (ActivityManagerService.this) { 1411 ActivityRecord ar = (ActivityRecord)msg.obj; 1412 if (mCompatModeDialog != null) { 1413 if (mCompatModeDialog.mAppInfo.packageName.equals( 1414 ar.info.applicationInfo.packageName)) { 1415 return; 1416 } 1417 mCompatModeDialog.dismiss(); 1418 mCompatModeDialog = null; 1419 } 1420 if (ar != null && false) { 1421 if (mCompatModePackages.getPackageAskCompatModeLocked( 1422 ar.packageName)) { 1423 int mode = mCompatModePackages.computeCompatModeLocked( 1424 ar.info.applicationInfo); 1425 if (mode == ActivityManager.COMPAT_MODE_DISABLED 1426 || mode == ActivityManager.COMPAT_MODE_ENABLED) { 1427 mCompatModeDialog = new CompatModeDialog( 1428 ActivityManagerService.this, mContext, 1429 ar.info.applicationInfo); 1430 mCompatModeDialog.show(); 1431 } 1432 } 1433 } 1434 } 1435 break; 1436 } 1437 case DISPATCH_PROCESSES_CHANGED: { 1438 dispatchProcessesChanged(); 1439 break; 1440 } 1441 case DISPATCH_PROCESS_DIED: { 1442 final int pid = msg.arg1; 1443 final int uid = msg.arg2; 1444 dispatchProcessDied(pid, uid); 1445 break; 1446 } 1447 case REPORT_MEM_USAGE_MSG: { 1448 final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj; 1449 Thread thread = new Thread() { 1450 @Override public void run() { 1451 final SparseArray<ProcessMemInfo> infoMap 1452 = new SparseArray<ProcessMemInfo>(memInfos.size()); 1453 for (int i=0, N=memInfos.size(); i<N; i++) { 1454 ProcessMemInfo mi = memInfos.get(i); 1455 infoMap.put(mi.pid, mi); 1456 } 1457 updateCpuStatsNow(); 1458 synchronized (mProcessCpuThread) { 1459 final int N = mProcessCpuTracker.countStats(); 1460 for (int i=0; i<N; i++) { 1461 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 1462 if (st.vsize > 0) { 1463 long pss = Debug.getPss(st.pid, null); 1464 if (pss > 0) { 1465 if (infoMap.indexOfKey(st.pid) < 0) { 1466 ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid, 1467 ProcessList.NATIVE_ADJ, -1, "native", null); 1468 mi.pss = pss; 1469 memInfos.add(mi); 1470 } 1471 } 1472 } 1473 } 1474 } 1475 1476 long totalPss = 0; 1477 for (int i=0, N=memInfos.size(); i<N; i++) { 1478 ProcessMemInfo mi = memInfos.get(i); 1479 if (mi.pss == 0) { 1480 mi.pss = Debug.getPss(mi.pid, null); 1481 } 1482 totalPss += mi.pss; 1483 } 1484 Collections.sort(memInfos, new Comparator<ProcessMemInfo>() { 1485 @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) { 1486 if (lhs.oomAdj != rhs.oomAdj) { 1487 return lhs.oomAdj < rhs.oomAdj ? -1 : 1; 1488 } 1489 if (lhs.pss != rhs.pss) { 1490 return lhs.pss < rhs.pss ? 1 : -1; 1491 } 1492 return 0; 1493 } 1494 }); 1495 1496 StringBuilder tag = new StringBuilder(128); 1497 StringBuilder stack = new StringBuilder(128); 1498 tag.append("Low on memory -- "); 1499 appendMemBucket(tag, totalPss, "total", false); 1500 appendMemBucket(stack, totalPss, "total", true); 1501 1502 StringBuilder logBuilder = new StringBuilder(1024); 1503 logBuilder.append("Low on memory:\n"); 1504 1505 boolean firstLine = true; 1506 int lastOomAdj = Integer.MIN_VALUE; 1507 for (int i=0, N=memInfos.size(); i<N; i++) { 1508 ProcessMemInfo mi = memInfos.get(i); 1509 1510 if (mi.oomAdj != ProcessList.NATIVE_ADJ 1511 && (mi.oomAdj < ProcessList.SERVICE_ADJ 1512 || mi.oomAdj == ProcessList.HOME_APP_ADJ 1513 || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) { 1514 if (lastOomAdj != mi.oomAdj) { 1515 lastOomAdj = mi.oomAdj; 1516 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) { 1517 tag.append(" / "); 1518 } 1519 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) { 1520 if (firstLine) { 1521 stack.append(":"); 1522 firstLine = false; 1523 } 1524 stack.append("\n\t at "); 1525 } else { 1526 stack.append("$"); 1527 } 1528 } else { 1529 tag.append(" "); 1530 stack.append("$"); 1531 } 1532 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) { 1533 appendMemBucket(tag, mi.pss, mi.name, false); 1534 } 1535 appendMemBucket(stack, mi.pss, mi.name, true); 1536 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ 1537 && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) { 1538 stack.append("("); 1539 for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) { 1540 if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) { 1541 stack.append(DUMP_MEM_OOM_LABEL[k]); 1542 stack.append(":"); 1543 stack.append(DUMP_MEM_OOM_ADJ[k]); 1544 } 1545 } 1546 stack.append(")"); 1547 } 1548 } 1549 1550 logBuilder.append(" "); 1551 logBuilder.append(ProcessList.makeOomAdjString(mi.oomAdj)); 1552 logBuilder.append(' '); 1553 logBuilder.append(ProcessList.makeProcStateString(mi.procState)); 1554 logBuilder.append(' '); 1555 ProcessList.appendRamKb(logBuilder, mi.pss); 1556 logBuilder.append(" kB: "); 1557 logBuilder.append(mi.name); 1558 logBuilder.append(" ("); 1559 logBuilder.append(mi.pid); 1560 logBuilder.append(") "); 1561 logBuilder.append(mi.adjType); 1562 logBuilder.append('\n'); 1563 if (mi.adjReason != null) { 1564 logBuilder.append(" "); 1565 logBuilder.append(mi.adjReason); 1566 logBuilder.append('\n'); 1567 } 1568 } 1569 1570 logBuilder.append(" "); 1571 ProcessList.appendRamKb(logBuilder, totalPss); 1572 logBuilder.append(" kB: TOTAL\n"); 1573 1574 long[] infos = new long[Debug.MEMINFO_COUNT]; 1575 Debug.getMemInfo(infos); 1576 logBuilder.append(" MemInfo: "); 1577 logBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, "); 1578 logBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, "); 1579 logBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, "); 1580 logBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, "); 1581 logBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n"); 1582 if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) { 1583 logBuilder.append(" ZRAM: "); 1584 logBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]); 1585 logBuilder.append(" kB RAM, "); 1586 logBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]); 1587 logBuilder.append(" kB swap total, "); 1588 logBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]); 1589 logBuilder.append(" kB swap free\n"); 1590 } 1591 Slog.i(TAG, logBuilder.toString()); 1592 1593 StringBuilder dropBuilder = new StringBuilder(1024); 1594 /* 1595 StringWriter oomSw = new StringWriter(); 1596 PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256); 1597 StringWriter catSw = new StringWriter(); 1598 PrintWriter catPw = new FastPrintWriter(catSw, false, 256); 1599 String[] emptyArgs = new String[] { }; 1600 dumpApplicationMemoryUsage(null, oomPw, " ", emptyArgs, true, catPw); 1601 oomPw.flush(); 1602 String oomString = oomSw.toString(); 1603 */ 1604 dropBuilder.append(stack); 1605 dropBuilder.append('\n'); 1606 dropBuilder.append('\n'); 1607 dropBuilder.append(logBuilder); 1608 dropBuilder.append('\n'); 1609 /* 1610 dropBuilder.append(oomString); 1611 dropBuilder.append('\n'); 1612 */ 1613 StringWriter catSw = new StringWriter(); 1614 synchronized (ActivityManagerService.this) { 1615 PrintWriter catPw = new FastPrintWriter(catSw, false, 256); 1616 String[] emptyArgs = new String[] { }; 1617 catPw.println(); 1618 dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null); 1619 catPw.println(); 1620 mServices.dumpServicesLocked(null, catPw, emptyArgs, 0, 1621 false, false, null); 1622 catPw.println(); 1623 dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null); 1624 catPw.flush(); 1625 } 1626 dropBuilder.append(catSw.toString()); 1627 addErrorToDropBox("lowmem", null, "system_server", null, 1628 null, tag.toString(), dropBuilder.toString(), null, null); 1629 //Slog.i(TAG, "Sent to dropbox:"); 1630 //Slog.i(TAG, dropBuilder.toString()); 1631 synchronized (ActivityManagerService.this) { 1632 long now = SystemClock.uptimeMillis(); 1633 if (mLastMemUsageReportTime < now) { 1634 mLastMemUsageReportTime = now; 1635 } 1636 } 1637 } 1638 }; 1639 thread.start(); 1640 break; 1641 } 1642 case REPORT_USER_SWITCH_MSG: { 1643 dispatchUserSwitch((UserStartedState)msg.obj, msg.arg1, msg.arg2); 1644 break; 1645 } 1646 case CONTINUE_USER_SWITCH_MSG: { 1647 continueUserSwitch((UserStartedState)msg.obj, msg.arg1, msg.arg2); 1648 break; 1649 } 1650 case USER_SWITCH_TIMEOUT_MSG: { 1651 timeoutUserSwitch((UserStartedState)msg.obj, msg.arg1, msg.arg2); 1652 break; 1653 } 1654 case IMMERSIVE_MODE_LOCK_MSG: { 1655 final boolean nextState = (msg.arg1 != 0); 1656 if (mUpdateLock.isHeld() != nextState) { 1657 if (DEBUG_IMMERSIVE) { 1658 final ActivityRecord r = (ActivityRecord) msg.obj; 1659 Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r); 1660 } 1661 if (nextState) { 1662 mUpdateLock.acquire(); 1663 } else { 1664 mUpdateLock.release(); 1665 } 1666 } 1667 break; 1668 } 1669 case PERSIST_URI_GRANTS_MSG: { 1670 writeGrantedUriPermissions(); 1671 break; 1672 } 1673 case REQUEST_ALL_PSS_MSG: { 1674 requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false); 1675 break; 1676 } 1677 } 1678 } 1679 }; 1680 1681 static final int COLLECT_PSS_BG_MSG = 1; 1682 1683 final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) { 1684 @Override 1685 public void handleMessage(Message msg) { 1686 switch (msg.what) { 1687 case COLLECT_PSS_BG_MSG: { 1688 int i=0, num=0; 1689 long start = SystemClock.uptimeMillis(); 1690 long[] tmp = new long[1]; 1691 do { 1692 ProcessRecord proc; 1693 int procState; 1694 int pid; 1695 synchronized (ActivityManagerService.this) { 1696 if (i >= mPendingPssProcesses.size()) { 1697 if (DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num + " of " + i 1698 + " processes in " + (SystemClock.uptimeMillis()-start) + "ms"); 1699 mPendingPssProcesses.clear(); 1700 return; 1701 } 1702 proc = mPendingPssProcesses.get(i); 1703 procState = proc.pssProcState; 1704 if (proc.thread != null && procState == proc.setProcState) { 1705 pid = proc.pid; 1706 } else { 1707 proc = null; 1708 pid = 0; 1709 } 1710 i++; 1711 } 1712 if (proc != null) { 1713 long pss = Debug.getPss(pid, tmp); 1714 synchronized (ActivityManagerService.this) { 1715 if (proc.thread != null && proc.setProcState == procState 1716 && proc.pid == pid) { 1717 num++; 1718 proc.lastPssTime = SystemClock.uptimeMillis(); 1719 proc.baseProcessTracker.addPss(pss, tmp[0], true, proc.pkgList); 1720 if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString() 1721 + ": " + pss + " lastPss=" + proc.lastPss 1722 + " state=" + ProcessList.makeProcStateString(procState)); 1723 if (proc.initialIdlePss == 0) { 1724 proc.initialIdlePss = pss; 1725 } 1726 proc.lastPss = pss; 1727 if (procState >= ActivityManager.PROCESS_STATE_HOME) { 1728 proc.lastCachedPss = pss; 1729 } 1730 } 1731 } 1732 } 1733 } while (true); 1734 } 1735 } 1736 } 1737 }; 1738 1739 public void setSystemProcess() { 1740 try { 1741 ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true); 1742 ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats); 1743 ServiceManager.addService("meminfo", new MemBinder(this)); 1744 ServiceManager.addService("gfxinfo", new GraphicsBinder(this)); 1745 ServiceManager.addService("dbinfo", new DbBinder(this)); 1746 if (MONITOR_CPU_USAGE) { 1747 ServiceManager.addService("cpuinfo", new CpuBinder(this)); 1748 } 1749 ServiceManager.addService("permission", new PermissionController(this)); 1750 1751 ApplicationInfo info = mContext.getPackageManager().getApplicationInfo( 1752 "android", STOCK_PM_FLAGS); 1753 mSystemThread.installSystemApplicationInfo(info); 1754 1755 synchronized (this) { 1756 ProcessRecord app = newProcessRecordLocked(info, info.processName, false); 1757 app.persistent = true; 1758 app.pid = MY_PID; 1759 app.maxAdj = ProcessList.SYSTEM_ADJ; 1760 app.makeActive(mSystemThread.getApplicationThread(), mProcessStats); 1761 mProcessNames.put(app.processName, app.uid, app); 1762 synchronized (mPidsSelfLocked) { 1763 mPidsSelfLocked.put(app.pid, app); 1764 } 1765 updateLruProcessLocked(app, false, null); 1766 updateOomAdjLocked(); 1767 } 1768 } catch (PackageManager.NameNotFoundException e) { 1769 throw new RuntimeException( 1770 "Unable to find android system package", e); 1771 } 1772 } 1773 1774 public void setWindowManager(WindowManagerService wm) { 1775 mWindowManager = wm; 1776 mStackSupervisor.setWindowManager(wm); 1777 } 1778 1779 public void startObservingNativeCrashes() { 1780 final NativeCrashListener ncl = new NativeCrashListener(this); 1781 ncl.start(); 1782 } 1783 1784 public IAppOpsService getAppOpsService() { 1785 return mAppOpsService; 1786 } 1787 1788 static class MemBinder extends Binder { 1789 ActivityManagerService mActivityManagerService; 1790 MemBinder(ActivityManagerService activityManagerService) { 1791 mActivityManagerService = activityManagerService; 1792 } 1793 1794 @Override 1795 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1796 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1797 != PackageManager.PERMISSION_GRANTED) { 1798 pw.println("Permission Denial: can't dump meminfo from from pid=" 1799 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1800 + " without permission " + android.Manifest.permission.DUMP); 1801 return; 1802 } 1803 1804 mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, " ", args, false, null); 1805 } 1806 } 1807 1808 static class GraphicsBinder extends Binder { 1809 ActivityManagerService mActivityManagerService; 1810 GraphicsBinder(ActivityManagerService activityManagerService) { 1811 mActivityManagerService = activityManagerService; 1812 } 1813 1814 @Override 1815 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1816 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1817 != PackageManager.PERMISSION_GRANTED) { 1818 pw.println("Permission Denial: can't dump gfxinfo from from pid=" 1819 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1820 + " without permission " + android.Manifest.permission.DUMP); 1821 return; 1822 } 1823 1824 mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args); 1825 } 1826 } 1827 1828 static class DbBinder extends Binder { 1829 ActivityManagerService mActivityManagerService; 1830 DbBinder(ActivityManagerService activityManagerService) { 1831 mActivityManagerService = activityManagerService; 1832 } 1833 1834 @Override 1835 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1836 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1837 != PackageManager.PERMISSION_GRANTED) { 1838 pw.println("Permission Denial: can't dump dbinfo from from pid=" 1839 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1840 + " without permission " + android.Manifest.permission.DUMP); 1841 return; 1842 } 1843 1844 mActivityManagerService.dumpDbInfo(fd, pw, args); 1845 } 1846 } 1847 1848 static class CpuBinder extends Binder { 1849 ActivityManagerService mActivityManagerService; 1850 CpuBinder(ActivityManagerService activityManagerService) { 1851 mActivityManagerService = activityManagerService; 1852 } 1853 1854 @Override 1855 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1856 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1857 != PackageManager.PERMISSION_GRANTED) { 1858 pw.println("Permission Denial: can't dump cpuinfo from from pid=" 1859 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1860 + " without permission " + android.Manifest.permission.DUMP); 1861 return; 1862 } 1863 1864 synchronized (mActivityManagerService.mProcessCpuThread) { 1865 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad()); 1866 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState( 1867 SystemClock.uptimeMillis())); 1868 } 1869 } 1870 } 1871 1872 public static final class Lifecycle extends SystemService { 1873 private final ActivityManagerService mService; 1874 1875 public Lifecycle(Context context) { 1876 super(context); 1877 mService = new ActivityManagerService(context); 1878 } 1879 1880 @Override 1881 public void onStart() { 1882 mService.start(); 1883 } 1884 1885 public ActivityManagerService getService() { 1886 return mService; 1887 } 1888 } 1889 1890 // Note: This method is invoked on the main thread but may need to attach various 1891 // handlers to other threads. So take care to be explicit about the looper. 1892 public ActivityManagerService(Context systemContext) { 1893 mContext = systemContext; 1894 mFactoryTest = FactoryTest.getMode(); 1895 mSystemThread = ActivityThread.currentActivityThread(); 1896 1897 Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass()); 1898 1899 mHandlerThread = new ServiceThread(TAG, 1900 android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/); 1901 mHandlerThread.start(); 1902 mHandler = new MainHandler(mHandlerThread.getLooper()); 1903 1904 mFgBroadcastQueue = new BroadcastQueue(this, mHandler, 1905 "foreground", BROADCAST_FG_TIMEOUT, false); 1906 mBgBroadcastQueue = new BroadcastQueue(this, mHandler, 1907 "background", BROADCAST_BG_TIMEOUT, true); 1908 mBroadcastQueues[0] = mFgBroadcastQueue; 1909 mBroadcastQueues[1] = mBgBroadcastQueue; 1910 1911 mServices = new ActiveServices(this); 1912 mProviderMap = new ProviderMap(this); 1913 1914 // TODO: Move creation of battery stats service outside of activity manager service. 1915 File dataDir = Environment.getDataDirectory(); 1916 File systemDir = new File(dataDir, "system"); 1917 systemDir.mkdirs(); 1918 mBatteryStatsService = new BatteryStatsService(new File( 1919 systemDir, "batterystats.bin").toString(), mHandler); 1920 mBatteryStatsService.getActiveStatistics().readLocked(); 1921 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 1922 mOnBattery = DEBUG_POWER ? true 1923 : mBatteryStatsService.getActiveStatistics().getIsOnBattery(); 1924 mBatteryStatsService.getActiveStatistics().setCallback(this); 1925 1926 mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats")); 1927 1928 mUsageStatsService = new UsageStatsService(new File(systemDir, "usagestats").toString()); 1929 mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler); 1930 1931 mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml")); 1932 1933 // User 0 is the first and only user that runs at boot. 1934 mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true)); 1935 mUserLru.add(Integer.valueOf(0)); 1936 updateStartedUserArrayLocked(); 1937 1938 GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version", 1939 ConfigurationInfo.GL_ES_VERSION_UNDEFINED); 1940 1941 mConfiguration.setToDefaults(); 1942 mConfiguration.setLocale(Locale.getDefault()); 1943 1944 mConfigurationSeq = mConfiguration.seq = 1; 1945 mProcessCpuTracker.init(); 1946 1947 mHasRecents = mContext.getResources().getBoolean( 1948 com.android.internal.R.bool.config_hasRecents); 1949 1950 mCompatModePackages = new CompatModePackages(this, systemDir, mHandler); 1951 mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler); 1952 mStackSupervisor = new ActivityStackSupervisor(this); 1953 1954 mProcessCpuThread = new Thread("CpuTracker") { 1955 @Override 1956 public void run() { 1957 while (true) { 1958 try { 1959 try { 1960 synchronized(this) { 1961 final long now = SystemClock.uptimeMillis(); 1962 long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now; 1963 long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now; 1964 //Slog.i(TAG, "Cpu delay=" + nextCpuDelay 1965 // + ", write delay=" + nextWriteDelay); 1966 if (nextWriteDelay < nextCpuDelay) { 1967 nextCpuDelay = nextWriteDelay; 1968 } 1969 if (nextCpuDelay > 0) { 1970 mProcessCpuMutexFree.set(true); 1971 this.wait(nextCpuDelay); 1972 } 1973 } 1974 } catch (InterruptedException e) { 1975 } 1976 updateCpuStatsNow(); 1977 } catch (Exception e) { 1978 Slog.e(TAG, "Unexpected exception collecting process stats", e); 1979 } 1980 } 1981 } 1982 }; 1983 1984 Watchdog.getInstance().addMonitor(this); 1985 Watchdog.getInstance().addThread(mHandler); 1986 } 1987 1988 private void start() { 1989 mProcessCpuThread.start(); 1990 1991 mBatteryStatsService.publish(mContext); 1992 mUsageStatsService.publish(mContext); 1993 mAppOpsService.publish(mContext); 1994 1995 LocalServices.addService(ActivityManagerInternal.class, new LocalService()); 1996 } 1997 1998 @Override 1999 public boolean onTransact(int code, Parcel data, Parcel reply, int flags) 2000 throws RemoteException { 2001 if (code == SYSPROPS_TRANSACTION) { 2002 // We need to tell all apps about the system property change. 2003 ArrayList<IBinder> procs = new ArrayList<IBinder>(); 2004 synchronized(this) { 2005 final int NP = mProcessNames.getMap().size(); 2006 for (int ip=0; ip<NP; ip++) { 2007 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 2008 final int NA = apps.size(); 2009 for (int ia=0; ia<NA; ia++) { 2010 ProcessRecord app = apps.valueAt(ia); 2011 if (app.thread != null) { 2012 procs.add(app.thread.asBinder()); 2013 } 2014 } 2015 } 2016 } 2017 2018 int N = procs.size(); 2019 for (int i=0; i<N; i++) { 2020 Parcel data2 = Parcel.obtain(); 2021 try { 2022 procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0); 2023 } catch (RemoteException e) { 2024 } 2025 data2.recycle(); 2026 } 2027 } 2028 try { 2029 return super.onTransact(code, data, reply, flags); 2030 } catch (RuntimeException e) { 2031 // The activity manager only throws security exceptions, so let's 2032 // log all others. 2033 if (!(e instanceof SecurityException)) { 2034 Slog.wtf(TAG, "Activity Manager Crash", e); 2035 } 2036 throw e; 2037 } 2038 } 2039 2040 void updateCpuStats() { 2041 final long now = SystemClock.uptimeMillis(); 2042 if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) { 2043 return; 2044 } 2045 if (mProcessCpuMutexFree.compareAndSet(true, false)) { 2046 synchronized (mProcessCpuThread) { 2047 mProcessCpuThread.notify(); 2048 } 2049 } 2050 } 2051 2052 void updateCpuStatsNow() { 2053 synchronized (mProcessCpuThread) { 2054 mProcessCpuMutexFree.set(false); 2055 final long now = SystemClock.uptimeMillis(); 2056 boolean haveNewCpuStats = false; 2057 2058 if (MONITOR_CPU_USAGE && 2059 mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) { 2060 mLastCpuTime.set(now); 2061 haveNewCpuStats = true; 2062 mProcessCpuTracker.update(); 2063 //Slog.i(TAG, mProcessCpu.printCurrentState()); 2064 //Slog.i(TAG, "Total CPU usage: " 2065 // + mProcessCpu.getTotalCpuPercent() + "%"); 2066 2067 // Slog the cpu usage if the property is set. 2068 if ("true".equals(SystemProperties.get("events.cpu"))) { 2069 int user = mProcessCpuTracker.getLastUserTime(); 2070 int system = mProcessCpuTracker.getLastSystemTime(); 2071 int iowait = mProcessCpuTracker.getLastIoWaitTime(); 2072 int irq = mProcessCpuTracker.getLastIrqTime(); 2073 int softIrq = mProcessCpuTracker.getLastSoftIrqTime(); 2074 int idle = mProcessCpuTracker.getLastIdleTime(); 2075 2076 int total = user + system + iowait + irq + softIrq + idle; 2077 if (total == 0) total = 1; 2078 2079 EventLog.writeEvent(EventLogTags.CPU, 2080 ((user+system+iowait+irq+softIrq) * 100) / total, 2081 (user * 100) / total, 2082 (system * 100) / total, 2083 (iowait * 100) / total, 2084 (irq * 100) / total, 2085 (softIrq * 100) / total); 2086 } 2087 } 2088 2089 long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes(); 2090 final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics(); 2091 synchronized(bstats) { 2092 synchronized(mPidsSelfLocked) { 2093 if (haveNewCpuStats) { 2094 if (mOnBattery) { 2095 int perc = bstats.startAddingCpuLocked(); 2096 int totalUTime = 0; 2097 int totalSTime = 0; 2098 final int N = mProcessCpuTracker.countStats(); 2099 for (int i=0; i<N; i++) { 2100 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 2101 if (!st.working) { 2102 continue; 2103 } 2104 ProcessRecord pr = mPidsSelfLocked.get(st.pid); 2105 int otherUTime = (st.rel_utime*perc)/100; 2106 int otherSTime = (st.rel_stime*perc)/100; 2107 totalUTime += otherUTime; 2108 totalSTime += otherSTime; 2109 if (pr != null) { 2110 BatteryStatsImpl.Uid.Proc ps = bstats.getProcessStatsLocked( 2111 st.name, st.pid); 2112 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 2113 st.rel_stime-otherSTime); 2114 ps.addSpeedStepTimes(cpuSpeedTimes); 2115 pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10; 2116 } else if (st.uid >= Process.FIRST_APPLICATION_UID) { 2117 BatteryStatsImpl.Uid.Proc ps = st.batteryStats; 2118 if (ps == null) { 2119 st.batteryStats = ps = bstats.getProcessStatsLocked(st.uid, 2120 "(Unknown)"); 2121 } 2122 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 2123 st.rel_stime-otherSTime); 2124 ps.addSpeedStepTimes(cpuSpeedTimes); 2125 } else { 2126 BatteryStatsImpl.Uid.Proc ps = 2127 bstats.getProcessStatsLocked(st.name, st.pid); 2128 if (ps != null) { 2129 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 2130 st.rel_stime-otherSTime); 2131 ps.addSpeedStepTimes(cpuSpeedTimes); 2132 } 2133 } 2134 } 2135 bstats.finishAddingCpuLocked(perc, totalUTime, 2136 totalSTime, cpuSpeedTimes); 2137 } 2138 } 2139 } 2140 2141 if (mLastWriteTime < (now-BATTERY_STATS_TIME)) { 2142 mLastWriteTime = now; 2143 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 2144 } 2145 } 2146 } 2147 } 2148 2149 @Override 2150 public void batteryNeedsCpuUpdate() { 2151 updateCpuStatsNow(); 2152 } 2153 2154 @Override 2155 public void batteryPowerChanged(boolean onBattery) { 2156 // When plugging in, update the CPU stats first before changing 2157 // the plug state. 2158 updateCpuStatsNow(); 2159 synchronized (this) { 2160 synchronized(mPidsSelfLocked) { 2161 mOnBattery = DEBUG_POWER ? true : onBattery; 2162 } 2163 } 2164 } 2165 2166 /** 2167 * Initialize the application bind args. These are passed to each 2168 * process when the bindApplication() IPC is sent to the process. They're 2169 * lazily setup to make sure the services are running when they're asked for. 2170 */ 2171 private HashMap<String, IBinder> getCommonServicesLocked() { 2172 if (mAppBindArgs == null) { 2173 mAppBindArgs = new HashMap<String, IBinder>(); 2174 2175 // Setup the application init args 2176 mAppBindArgs.put("package", ServiceManager.getService("package")); 2177 mAppBindArgs.put("window", ServiceManager.getService("window")); 2178 mAppBindArgs.put(Context.ALARM_SERVICE, 2179 ServiceManager.getService(Context.ALARM_SERVICE)); 2180 } 2181 return mAppBindArgs; 2182 } 2183 2184 final void setFocusedActivityLocked(ActivityRecord r) { 2185 if (mFocusedActivity != r) { 2186 if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r); 2187 mFocusedActivity = r; 2188 mStackSupervisor.setFocusedStack(r); 2189 if (r != null) { 2190 mWindowManager.setFocusedApp(r.appToken, true); 2191 } 2192 applyUpdateLockStateLocked(r); 2193 } 2194 } 2195 2196 @Override 2197 public void setFocusedStack(int stackId) { 2198 if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId); 2199 synchronized (ActivityManagerService.this) { 2200 ActivityStack stack = mStackSupervisor.getStack(stackId); 2201 if (stack != null) { 2202 ActivityRecord r = stack.topRunningActivityLocked(null); 2203 if (r != null) { 2204 setFocusedActivityLocked(r); 2205 } 2206 } 2207 } 2208 } 2209 2210 @Override 2211 public void notifyActivityDrawn(IBinder token) { 2212 if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token); 2213 synchronized (this) { 2214 ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token); 2215 if (r != null) { 2216 r.task.stack.notifyActivityDrawnLocked(r); 2217 } 2218 } 2219 } 2220 2221 final void applyUpdateLockStateLocked(ActivityRecord r) { 2222 // Modifications to the UpdateLock state are done on our handler, outside 2223 // the activity manager's locks. The new state is determined based on the 2224 // state *now* of the relevant activity record. The object is passed to 2225 // the handler solely for logging detail, not to be consulted/modified. 2226 final boolean nextState = r != null && r.immersive; 2227 mHandler.sendMessage( 2228 mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r)); 2229 } 2230 2231 final void showAskCompatModeDialogLocked(ActivityRecord r) { 2232 Message msg = Message.obtain(); 2233 msg.what = SHOW_COMPAT_MODE_DIALOG_MSG; 2234 msg.obj = r.task.askedCompatMode ? null : r; 2235 mHandler.sendMessage(msg); 2236 } 2237 2238 private final int updateLruProcessInternalLocked(ProcessRecord app, long now, int index, 2239 String what, Object obj, ProcessRecord srcApp) { 2240 app.lastActivityTime = now; 2241 2242 if (app.activities.size() > 0) { 2243 // Don't want to touch dependent processes that are hosting activities. 2244 return index; 2245 } 2246 2247 int lrui = mLruProcesses.lastIndexOf(app); 2248 if (lrui < 0) { 2249 Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: " 2250 + what + " " + obj + " from " + srcApp); 2251 return index; 2252 } 2253 2254 if (lrui >= index) { 2255 // Don't want to cause this to move dependent processes *back* in the 2256 // list as if they were less frequently used. 2257 return index; 2258 } 2259 2260 if (lrui >= mLruProcessActivityStart) { 2261 // Don't want to touch dependent processes that are hosting activities. 2262 return index; 2263 } 2264 2265 mLruProcesses.remove(lrui); 2266 if (index > 0) { 2267 index--; 2268 } 2269 if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index 2270 + " in LRU list: " + app); 2271 mLruProcesses.add(index, app); 2272 return index; 2273 } 2274 2275 final void removeLruProcessLocked(ProcessRecord app) { 2276 int lrui = mLruProcesses.lastIndexOf(app); 2277 if (lrui >= 0) { 2278 if (lrui <= mLruProcessActivityStart) { 2279 mLruProcessActivityStart--; 2280 } 2281 if (lrui <= mLruProcessServiceStart) { 2282 mLruProcessServiceStart--; 2283 } 2284 mLruProcesses.remove(lrui); 2285 } 2286 } 2287 2288 final void updateLruProcessLocked(ProcessRecord app, boolean activityChange, 2289 ProcessRecord client) { 2290 final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities; 2291 final boolean hasService = false; // not impl yet. app.services.size() > 0; 2292 if (!activityChange && hasActivity) { 2293 // The process has activties, so we are only going to allow activity-based 2294 // adjustments move it. It should be kept in the front of the list with other 2295 // processes that have activities, and we don't want those to change their 2296 // order except due to activity operations. 2297 return; 2298 } 2299 2300 mLruSeq++; 2301 final long now = SystemClock.uptimeMillis(); 2302 app.lastActivityTime = now; 2303 2304 // First a quick reject: if the app is already at the position we will 2305 // put it, then there is nothing to do. 2306 if (hasActivity) { 2307 final int N = mLruProcesses.size(); 2308 if (N > 0 && mLruProcesses.get(N-1) == app) { 2309 if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app); 2310 return; 2311 } 2312 } else { 2313 if (mLruProcessServiceStart > 0 2314 && mLruProcesses.get(mLruProcessServiceStart-1) == app) { 2315 if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app); 2316 return; 2317 } 2318 } 2319 2320 int lrui = mLruProcesses.lastIndexOf(app); 2321 2322 if (app.persistent && lrui >= 0) { 2323 // We don't care about the position of persistent processes, as long as 2324 // they are in the list. 2325 if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app); 2326 return; 2327 } 2328 2329 /* In progress: compute new position first, so we can avoid doing work 2330 if the process is not actually going to move. Not yet working. 2331 int addIndex; 2332 int nextIndex; 2333 boolean inActivity = false, inService = false; 2334 if (hasActivity) { 2335 // Process has activities, put it at the very tipsy-top. 2336 addIndex = mLruProcesses.size(); 2337 nextIndex = mLruProcessServiceStart; 2338 inActivity = true; 2339 } else if (hasService) { 2340 // Process has services, put it at the top of the service list. 2341 addIndex = mLruProcessActivityStart; 2342 nextIndex = mLruProcessServiceStart; 2343 inActivity = true; 2344 inService = true; 2345 } else { 2346 // Process not otherwise of interest, it goes to the top of the non-service area. 2347 addIndex = mLruProcessServiceStart; 2348 if (client != null) { 2349 int clientIndex = mLruProcesses.lastIndexOf(client); 2350 if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating " 2351 + app); 2352 if (clientIndex >= 0 && addIndex > clientIndex) { 2353 addIndex = clientIndex; 2354 } 2355 } 2356 nextIndex = addIndex > 0 ? addIndex-1 : addIndex; 2357 } 2358 2359 Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act=" 2360 + mLruProcessActivityStart + "): " + app); 2361 */ 2362 2363 if (lrui >= 0) { 2364 if (lrui < mLruProcessActivityStart) { 2365 mLruProcessActivityStart--; 2366 } 2367 if (lrui < mLruProcessServiceStart) { 2368 mLruProcessServiceStart--; 2369 } 2370 /* 2371 if (addIndex > lrui) { 2372 addIndex--; 2373 } 2374 if (nextIndex > lrui) { 2375 nextIndex--; 2376 } 2377 */ 2378 mLruProcesses.remove(lrui); 2379 } 2380 2381 /* 2382 mLruProcesses.add(addIndex, app); 2383 if (inActivity) { 2384 mLruProcessActivityStart++; 2385 } 2386 if (inService) { 2387 mLruProcessActivityStart++; 2388 } 2389 */ 2390 2391 int nextIndex; 2392 if (hasActivity) { 2393 final int N = mLruProcesses.size(); 2394 if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) { 2395 // Process doesn't have activities, but has clients with 2396 // activities... move it up, but one below the top (the top 2397 // should always have a real activity). 2398 if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app); 2399 mLruProcesses.add(N-1, app); 2400 // To keep it from spamming the LRU list (by making a bunch of clients), 2401 // we will push down any other entries owned by the app. 2402 final int uid = app.info.uid; 2403 for (int i=N-2; i>mLruProcessActivityStart; i--) { 2404 ProcessRecord subProc = mLruProcesses.get(i); 2405 if (subProc.info.uid == uid) { 2406 // We want to push this one down the list. If the process after 2407 // it is for the same uid, however, don't do so, because we don't 2408 // want them internally to be re-ordered. 2409 if (mLruProcesses.get(i-1).info.uid != uid) { 2410 if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i 2411 + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1)); 2412 ProcessRecord tmp = mLruProcesses.get(i); 2413 mLruProcesses.set(i, mLruProcesses.get(i-1)); 2414 mLruProcesses.set(i-1, tmp); 2415 i--; 2416 } 2417 } else { 2418 // A gap, we can stop here. 2419 break; 2420 } 2421 } 2422 } else { 2423 // Process has activities, put it at the very tipsy-top. 2424 if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app); 2425 mLruProcesses.add(app); 2426 } 2427 nextIndex = mLruProcessServiceStart; 2428 } else if (hasService) { 2429 // Process has services, put it at the top of the service list. 2430 if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app); 2431 mLruProcesses.add(mLruProcessActivityStart, app); 2432 nextIndex = mLruProcessServiceStart; 2433 mLruProcessActivityStart++; 2434 } else { 2435 // Process not otherwise of interest, it goes to the top of the non-service area. 2436 int index = mLruProcessServiceStart; 2437 if (client != null) { 2438 // If there is a client, don't allow the process to be moved up higher 2439 // in the list than that client. 2440 int clientIndex = mLruProcesses.lastIndexOf(client); 2441 if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client 2442 + " when updating " + app); 2443 if (clientIndex <= lrui) { 2444 // Don't allow the client index restriction to push it down farther in the 2445 // list than it already is. 2446 clientIndex = lrui; 2447 } 2448 if (clientIndex >= 0 && index > clientIndex) { 2449 index = clientIndex; 2450 } 2451 } 2452 if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app); 2453 mLruProcesses.add(index, app); 2454 nextIndex = index-1; 2455 mLruProcessActivityStart++; 2456 mLruProcessServiceStart++; 2457 } 2458 2459 // If the app is currently using a content provider or service, 2460 // bump those processes as well. 2461 for (int j=app.connections.size()-1; j>=0; j--) { 2462 ConnectionRecord cr = app.connections.valueAt(j); 2463 if (cr.binding != null && !cr.serviceDead && cr.binding.service != null 2464 && cr.binding.service.app != null 2465 && cr.binding.service.app.lruSeq != mLruSeq 2466 && !cr.binding.service.app.persistent) { 2467 nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex, 2468 "service connection", cr, app); 2469 } 2470 } 2471 for (int j=app.conProviders.size()-1; j>=0; j--) { 2472 ContentProviderRecord cpr = app.conProviders.get(j).provider; 2473 if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) { 2474 nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex, 2475 "provider reference", cpr, app); 2476 } 2477 } 2478 } 2479 2480 final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) { 2481 if (uid == Process.SYSTEM_UID) { 2482 // The system gets to run in any process. If there are multiple 2483 // processes with the same uid, just pick the first (this 2484 // should never happen). 2485 SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName); 2486 if (procs == null) return null; 2487 final int N = procs.size(); 2488 for (int i = 0; i < N; i++) { 2489 if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i); 2490 } 2491 } 2492 ProcessRecord proc = mProcessNames.get(processName, uid); 2493 if (false && proc != null && !keepIfLarge 2494 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY 2495 && proc.lastCachedPss >= 4000) { 2496 // Turn this condition on to cause killing to happen regularly, for testing. 2497 if (proc.baseProcessTracker != null) { 2498 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss); 2499 } 2500 killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss) 2501 + "k from cached"); 2502 } else if (proc != null && !keepIfLarge 2503 && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL 2504 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) { 2505 if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss); 2506 if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) { 2507 if (proc.baseProcessTracker != null) { 2508 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss); 2509 } 2510 killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss) 2511 + "k from cached"); 2512 } 2513 } 2514 return proc; 2515 } 2516 2517 void ensurePackageDexOpt(String packageName) { 2518 IPackageManager pm = AppGlobals.getPackageManager(); 2519 try { 2520 if (pm.performDexOpt(packageName)) { 2521 mDidDexOpt = true; 2522 } 2523 } catch (RemoteException e) { 2524 } 2525 } 2526 2527 boolean isNextTransitionForward() { 2528 int transit = mWindowManager.getPendingAppTransition(); 2529 return transit == AppTransition.TRANSIT_ACTIVITY_OPEN 2530 || transit == AppTransition.TRANSIT_TASK_OPEN 2531 || transit == AppTransition.TRANSIT_TASK_TO_FRONT; 2532 } 2533 2534 final ProcessRecord startProcessLocked(String processName, 2535 ApplicationInfo info, boolean knownToBeDead, int intentFlags, 2536 String hostingType, ComponentName hostingName, boolean allowWhileBooting, 2537 boolean isolated, boolean keepIfLarge) { 2538 ProcessRecord app; 2539 if (!isolated) { 2540 app = getProcessRecordLocked(processName, info.uid, keepIfLarge); 2541 } else { 2542 // If this is an isolated process, it can't re-use an existing process. 2543 app = null; 2544 } 2545 // We don't have to do anything more if: 2546 // (1) There is an existing application record; and 2547 // (2) The caller doesn't think it is dead, OR there is no thread 2548 // object attached to it so we know it couldn't have crashed; and 2549 // (3) There is a pid assigned to it, so it is either starting or 2550 // already running. 2551 if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName 2552 + " app=" + app + " knownToBeDead=" + knownToBeDead 2553 + " thread=" + (app != null ? app.thread : null) 2554 + " pid=" + (app != null ? app.pid : -1)); 2555 if (app != null && app.pid > 0) { 2556 if (!knownToBeDead || app.thread == null) { 2557 // We already have the app running, or are waiting for it to 2558 // come up (we have a pid but not yet its thread), so keep it. 2559 if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app); 2560 // If this is a new package in the process, add the package to the list 2561 app.addPackage(info.packageName, mProcessStats); 2562 return app; 2563 } 2564 2565 // An application record is attached to a previous process, 2566 // clean it up now. 2567 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app); 2568 handleAppDiedLocked(app, true, true); 2569 } 2570 2571 String hostingNameStr = hostingName != null 2572 ? hostingName.flattenToShortString() : null; 2573 2574 if (!isolated) { 2575 if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) { 2576 // If we are in the background, then check to see if this process 2577 // is bad. If so, we will just silently fail. 2578 if (mBadProcesses.get(info.processName, info.uid) != null) { 2579 if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid 2580 + "/" + info.processName); 2581 return null; 2582 } 2583 } else { 2584 // When the user is explicitly starting a process, then clear its 2585 // crash count so that we won't make it bad until they see at 2586 // least one crash dialog again, and make the process good again 2587 // if it had been bad. 2588 if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid 2589 + "/" + info.processName); 2590 mProcessCrashTimes.remove(info.processName, info.uid); 2591 if (mBadProcesses.get(info.processName, info.uid) != null) { 2592 EventLog.writeEvent(EventLogTags.AM_PROC_GOOD, 2593 UserHandle.getUserId(info.uid), info.uid, 2594 info.processName); 2595 mBadProcesses.remove(info.processName, info.uid); 2596 if (app != null) { 2597 app.bad = false; 2598 } 2599 } 2600 } 2601 } 2602 2603 if (app == null) { 2604 app = newProcessRecordLocked(info, processName, isolated); 2605 if (app == null) { 2606 Slog.w(TAG, "Failed making new process record for " 2607 + processName + "/" + info.uid + " isolated=" + isolated); 2608 return null; 2609 } 2610 mProcessNames.put(processName, app.uid, app); 2611 if (isolated) { 2612 mIsolatedProcesses.put(app.uid, app); 2613 } 2614 } else { 2615 // If this is a new package in the process, add the package to the list 2616 app.addPackage(info.packageName, mProcessStats); 2617 } 2618 2619 // If the system is not ready yet, then hold off on starting this 2620 // process until it is. 2621 if (!mProcessesReady 2622 && !isAllowedWhileBooting(info) 2623 && !allowWhileBooting) { 2624 if (!mProcessesOnHold.contains(app)) { 2625 mProcessesOnHold.add(app); 2626 } 2627 if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app); 2628 return app; 2629 } 2630 2631 startProcessLocked(app, hostingType, hostingNameStr); 2632 return (app.pid != 0) ? app : null; 2633 } 2634 2635 boolean isAllowedWhileBooting(ApplicationInfo ai) { 2636 return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0; 2637 } 2638 2639 private final void startProcessLocked(ProcessRecord app, 2640 String hostingType, String hostingNameStr) { 2641 if (app.pid > 0 && app.pid != MY_PID) { 2642 synchronized (mPidsSelfLocked) { 2643 mPidsSelfLocked.remove(app.pid); 2644 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 2645 } 2646 app.setPid(0); 2647 } 2648 2649 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 2650 "startProcessLocked removing on hold: " + app); 2651 mProcessesOnHold.remove(app); 2652 2653 updateCpuStats(); 2654 2655 try { 2656 int uid = app.uid; 2657 2658 int[] gids = null; 2659 int mountExternal = Zygote.MOUNT_EXTERNAL_NONE; 2660 if (!app.isolated) { 2661 int[] permGids = null; 2662 try { 2663 final PackageManager pm = mContext.getPackageManager(); 2664 permGids = pm.getPackageGids(app.info.packageName); 2665 2666 if (Environment.isExternalStorageEmulated()) { 2667 if (pm.checkPermission( 2668 android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE, 2669 app.info.packageName) == PERMISSION_GRANTED) { 2670 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL; 2671 } else { 2672 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER; 2673 } 2674 } 2675 } catch (PackageManager.NameNotFoundException e) { 2676 Slog.w(TAG, "Unable to retrieve gids", e); 2677 } 2678 2679 /* 2680 * Add shared application GID so applications can share some 2681 * resources like shared libraries 2682 */ 2683 if (permGids == null) { 2684 gids = new int[1]; 2685 } else { 2686 gids = new int[permGids.length + 1]; 2687 System.arraycopy(permGids, 0, gids, 1, permGids.length); 2688 } 2689 gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid)); 2690 } 2691 if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) { 2692 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL 2693 && mTopComponent != null 2694 && app.processName.equals(mTopComponent.getPackageName())) { 2695 uid = 0; 2696 } 2697 if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL 2698 && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) { 2699 uid = 0; 2700 } 2701 } 2702 int debugFlags = 0; 2703 if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) { 2704 debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER; 2705 // Also turn on CheckJNI for debuggable apps. It's quite 2706 // awkward to turn on otherwise. 2707 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 2708 } 2709 // Run the app in safe mode if its manifest requests so or the 2710 // system is booted in safe mode. 2711 if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 || 2712 Zygote.systemInSafeMode == true) { 2713 debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE; 2714 } 2715 if ("1".equals(SystemProperties.get("debug.checkjni"))) { 2716 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 2717 } 2718 if ("1".equals(SystemProperties.get("debug.jni.logging"))) { 2719 debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING; 2720 } 2721 if ("1".equals(SystemProperties.get("debug.assert"))) { 2722 debugFlags |= Zygote.DEBUG_ENABLE_ASSERT; 2723 } 2724 2725 // Start the process. It will either succeed and return a result containing 2726 // the PID of the new process, or else throw a RuntimeException. 2727 Process.ProcessStartResult startResult = Process.start("android.app.ActivityThread", 2728 app.processName, uid, uid, gids, debugFlags, mountExternal, 2729 app.info.targetSdkVersion, app.info.seinfo, null); 2730 2731 BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics(); 2732 synchronized (bs) { 2733 if (bs.isOnBattery()) { 2734 bs.getProcessStatsLocked(app.uid, app.processName).incStartsLocked(); 2735 } 2736 } 2737 2738 EventLog.writeEvent(EventLogTags.AM_PROC_START, 2739 UserHandle.getUserId(uid), startResult.pid, uid, 2740 app.processName, hostingType, 2741 hostingNameStr != null ? hostingNameStr : ""); 2742 2743 if (app.persistent) { 2744 Watchdog.getInstance().processStarted(app.processName, startResult.pid); 2745 } 2746 2747 StringBuilder buf = mStringBuilder; 2748 buf.setLength(0); 2749 buf.append("Start proc "); 2750 buf.append(app.processName); 2751 buf.append(" for "); 2752 buf.append(hostingType); 2753 if (hostingNameStr != null) { 2754 buf.append(" "); 2755 buf.append(hostingNameStr); 2756 } 2757 buf.append(": pid="); 2758 buf.append(startResult.pid); 2759 buf.append(" uid="); 2760 buf.append(uid); 2761 buf.append(" gids={"); 2762 if (gids != null) { 2763 for (int gi=0; gi<gids.length; gi++) { 2764 if (gi != 0) buf.append(", "); 2765 buf.append(gids[gi]); 2766 2767 } 2768 } 2769 buf.append("}"); 2770 Slog.i(TAG, buf.toString()); 2771 app.setPid(startResult.pid); 2772 app.usingWrapper = startResult.usingWrapper; 2773 app.removed = false; 2774 synchronized (mPidsSelfLocked) { 2775 this.mPidsSelfLocked.put(startResult.pid, app); 2776 Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 2777 msg.obj = app; 2778 mHandler.sendMessageDelayed(msg, startResult.usingWrapper 2779 ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT); 2780 } 2781 } catch (RuntimeException e) { 2782 // XXX do better error recovery. 2783 app.setPid(0); 2784 Slog.e(TAG, "Failure starting process " + app.processName, e); 2785 } 2786 } 2787 2788 void updateUsageStats(ActivityRecord component, boolean resumed) { 2789 if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed); 2790 final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 2791 if (resumed) { 2792 mUsageStatsService.noteResumeComponent(component.realActivity); 2793 synchronized (stats) { 2794 stats.noteActivityResumedLocked(component.app.uid); 2795 } 2796 } else { 2797 mUsageStatsService.notePauseComponent(component.realActivity); 2798 synchronized (stats) { 2799 stats.noteActivityPausedLocked(component.app.uid); 2800 } 2801 } 2802 } 2803 2804 Intent getHomeIntent() { 2805 Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null); 2806 intent.setComponent(mTopComponent); 2807 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 2808 intent.addCategory(Intent.CATEGORY_HOME); 2809 } 2810 return intent; 2811 } 2812 2813 boolean startHomeActivityLocked(int userId) { 2814 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL 2815 && mTopAction == null) { 2816 // We are running in factory test mode, but unable to find 2817 // the factory test app, so just sit around displaying the 2818 // error message and don't try to start anything. 2819 return false; 2820 } 2821 Intent intent = getHomeIntent(); 2822 ActivityInfo aInfo = 2823 resolveActivityInfo(intent, STOCK_PM_FLAGS, userId); 2824 if (aInfo != null) { 2825 intent.setComponent(new ComponentName( 2826 aInfo.applicationInfo.packageName, aInfo.name)); 2827 // Don't do this if the home app is currently being 2828 // instrumented. 2829 aInfo = new ActivityInfo(aInfo); 2830 aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId); 2831 ProcessRecord app = getProcessRecordLocked(aInfo.processName, 2832 aInfo.applicationInfo.uid, true); 2833 if (app == null || app.instrumentationClass == null) { 2834 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK); 2835 mStackSupervisor.startHomeActivity(intent, aInfo); 2836 } 2837 } 2838 2839 return true; 2840 } 2841 2842 private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) { 2843 ActivityInfo ai = null; 2844 ComponentName comp = intent.getComponent(); 2845 try { 2846 if (comp != null) { 2847 ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId); 2848 } else { 2849 ResolveInfo info = AppGlobals.getPackageManager().resolveIntent( 2850 intent, 2851 intent.resolveTypeIfNeeded(mContext.getContentResolver()), 2852 flags, userId); 2853 2854 if (info != null) { 2855 ai = info.activityInfo; 2856 } 2857 } 2858 } catch (RemoteException e) { 2859 // ignore 2860 } 2861 2862 return ai; 2863 } 2864 2865 /** 2866 * Starts the "new version setup screen" if appropriate. 2867 */ 2868 void startSetupActivityLocked() { 2869 // Only do this once per boot. 2870 if (mCheckedForSetup) { 2871 return; 2872 } 2873 2874 // We will show this screen if the current one is a different 2875 // version than the last one shown, and we are not running in 2876 // low-level factory test mode. 2877 final ContentResolver resolver = mContext.getContentResolver(); 2878 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL && 2879 Settings.Global.getInt(resolver, 2880 Settings.Global.DEVICE_PROVISIONED, 0) != 0) { 2881 mCheckedForSetup = true; 2882 2883 // See if we should be showing the platform update setup UI. 2884 Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP); 2885 List<ResolveInfo> ris = mContext.getPackageManager() 2886 .queryIntentActivities(intent, PackageManager.GET_META_DATA); 2887 2888 // We don't allow third party apps to replace this. 2889 ResolveInfo ri = null; 2890 for (int i=0; ris != null && i<ris.size(); i++) { 2891 if ((ris.get(i).activityInfo.applicationInfo.flags 2892 & ApplicationInfo.FLAG_SYSTEM) != 0) { 2893 ri = ris.get(i); 2894 break; 2895 } 2896 } 2897 2898 if (ri != null) { 2899 String vers = ri.activityInfo.metaData != null 2900 ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION) 2901 : null; 2902 if (vers == null && ri.activityInfo.applicationInfo.metaData != null) { 2903 vers = ri.activityInfo.applicationInfo.metaData.getString( 2904 Intent.METADATA_SETUP_VERSION); 2905 } 2906 String lastVers = Settings.Secure.getString( 2907 resolver, Settings.Secure.LAST_SETUP_SHOWN); 2908 if (vers != null && !vers.equals(lastVers)) { 2909 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 2910 intent.setComponent(new ComponentName( 2911 ri.activityInfo.packageName, ri.activityInfo.name)); 2912 mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo, 2913 null, null, 0, 0, 0, null, 0, null, false, null, null); 2914 } 2915 } 2916 } 2917 } 2918 2919 CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) { 2920 return mCompatModePackages.compatibilityInfoForPackageLocked(ai); 2921 } 2922 2923 void enforceNotIsolatedCaller(String caller) { 2924 if (UserHandle.isIsolated(Binder.getCallingUid())) { 2925 throw new SecurityException("Isolated process not allowed to call " + caller); 2926 } 2927 } 2928 2929 @Override 2930 public int getFrontActivityScreenCompatMode() { 2931 enforceNotIsolatedCaller("getFrontActivityScreenCompatMode"); 2932 synchronized (this) { 2933 return mCompatModePackages.getFrontActivityScreenCompatModeLocked(); 2934 } 2935 } 2936 2937 @Override 2938 public void setFrontActivityScreenCompatMode(int mode) { 2939 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 2940 "setFrontActivityScreenCompatMode"); 2941 synchronized (this) { 2942 mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode); 2943 } 2944 } 2945 2946 @Override 2947 public int getPackageScreenCompatMode(String packageName) { 2948 enforceNotIsolatedCaller("getPackageScreenCompatMode"); 2949 synchronized (this) { 2950 return mCompatModePackages.getPackageScreenCompatModeLocked(packageName); 2951 } 2952 } 2953 2954 @Override 2955 public void setPackageScreenCompatMode(String packageName, int mode) { 2956 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 2957 "setPackageScreenCompatMode"); 2958 synchronized (this) { 2959 mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode); 2960 } 2961 } 2962 2963 @Override 2964 public boolean getPackageAskScreenCompat(String packageName) { 2965 enforceNotIsolatedCaller("getPackageAskScreenCompat"); 2966 synchronized (this) { 2967 return mCompatModePackages.getPackageAskCompatModeLocked(packageName); 2968 } 2969 } 2970 2971 @Override 2972 public void setPackageAskScreenCompat(String packageName, boolean ask) { 2973 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 2974 "setPackageAskScreenCompat"); 2975 synchronized (this) { 2976 mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask); 2977 } 2978 } 2979 2980 private void dispatchProcessesChanged() { 2981 int N; 2982 synchronized (this) { 2983 N = mPendingProcessChanges.size(); 2984 if (mActiveProcessChanges.length < N) { 2985 mActiveProcessChanges = new ProcessChangeItem[N]; 2986 } 2987 mPendingProcessChanges.toArray(mActiveProcessChanges); 2988 mAvailProcessChanges.addAll(mPendingProcessChanges); 2989 mPendingProcessChanges.clear(); 2990 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes"); 2991 } 2992 2993 int i = mProcessObservers.beginBroadcast(); 2994 while (i > 0) { 2995 i--; 2996 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 2997 if (observer != null) { 2998 try { 2999 for (int j=0; j<N; j++) { 3000 ProcessChangeItem item = mActiveProcessChanges[j]; 3001 if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) { 3002 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid=" 3003 + item.pid + " uid=" + item.uid + ": " 3004 + item.foregroundActivities); 3005 observer.onForegroundActivitiesChanged(item.pid, item.uid, 3006 item.foregroundActivities); 3007 } 3008 if ((item.changes&ProcessChangeItem.CHANGE_IMPORTANCE) != 0) { 3009 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "IMPORTANCE CHANGED pid=" 3010 + item.pid + " uid=" + item.uid + ": " + item.importance); 3011 observer.onImportanceChanged(item.pid, item.uid, 3012 item.importance); 3013 } 3014 } 3015 } catch (RemoteException e) { 3016 } 3017 } 3018 } 3019 mProcessObservers.finishBroadcast(); 3020 } 3021 3022 private void dispatchProcessDied(int pid, int uid) { 3023 int i = mProcessObservers.beginBroadcast(); 3024 while (i > 0) { 3025 i--; 3026 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 3027 if (observer != null) { 3028 try { 3029 observer.onProcessDied(pid, uid); 3030 } catch (RemoteException e) { 3031 } 3032 } 3033 } 3034 mProcessObservers.finishBroadcast(); 3035 } 3036 3037 final void doPendingActivityLaunchesLocked(boolean doResume) { 3038 final int N = mPendingActivityLaunches.size(); 3039 if (N <= 0) { 3040 return; 3041 } 3042 for (int i=0; i<N; i++) { 3043 PendingActivityLaunch pal = mPendingActivityLaunches.get(i); 3044 mStackSupervisor.startActivityUncheckedLocked(pal.r, pal.sourceRecord, pal.startFlags, 3045 doResume && i == (N-1), null); 3046 } 3047 mPendingActivityLaunches.clear(); 3048 } 3049 3050 @Override 3051 public final int startActivity(IApplicationThread caller, String callingPackage, 3052 Intent intent, String resolvedType, IBinder resultTo, 3053 String resultWho, int requestCode, int startFlags, 3054 String profileFile, ParcelFileDescriptor profileFd, Bundle options) { 3055 return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo, 3056 resultWho, requestCode, 3057 startFlags, profileFile, profileFd, options, UserHandle.getCallingUserId()); 3058 } 3059 3060 @Override 3061 public final int startActivityAsUser(IApplicationThread caller, String callingPackage, 3062 Intent intent, String resolvedType, IBinder resultTo, 3063 String resultWho, int requestCode, int startFlags, 3064 String profileFile, ParcelFileDescriptor profileFd, Bundle options, int userId) { 3065 enforceNotIsolatedCaller("startActivity"); 3066 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3067 false, true, "startActivity", null); 3068 // TODO: Switch to user app stacks here. 3069 return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType, 3070 resultTo, resultWho, requestCode, startFlags, profileFile, profileFd, 3071 null, null, options, userId, null); 3072 } 3073 3074 @Override 3075 public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage, 3076 Intent intent, String resolvedType, IBinder resultTo, 3077 String resultWho, int requestCode, int startFlags, String profileFile, 3078 ParcelFileDescriptor profileFd, Bundle options, int userId) { 3079 enforceNotIsolatedCaller("startActivityAndWait"); 3080 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3081 false, true, "startActivityAndWait", null); 3082 WaitResult res = new WaitResult(); 3083 // TODO: Switch to user app stacks here. 3084 mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType, 3085 resultTo, resultWho, requestCode, startFlags, profileFile, profileFd, 3086 res, null, options, UserHandle.getCallingUserId(), null); 3087 return res; 3088 } 3089 3090 @Override 3091 public final int startActivityWithConfig(IApplicationThread caller, String callingPackage, 3092 Intent intent, String resolvedType, IBinder resultTo, 3093 String resultWho, int requestCode, int startFlags, Configuration config, 3094 Bundle options, int userId) { 3095 enforceNotIsolatedCaller("startActivityWithConfig"); 3096 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3097 false, true, "startActivityWithConfig", null); 3098 // TODO: Switch to user app stacks here. 3099 int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, 3100 resolvedType, resultTo, resultWho, requestCode, startFlags, 3101 null, null, null, config, options, userId, null); 3102 return ret; 3103 } 3104 3105 @Override 3106 public int startActivityIntentSender(IApplicationThread caller, 3107 IntentSender intent, Intent fillInIntent, String resolvedType, 3108 IBinder resultTo, String resultWho, int requestCode, 3109 int flagsMask, int flagsValues, Bundle options) { 3110 enforceNotIsolatedCaller("startActivityIntentSender"); 3111 // Refuse possible leaked file descriptors 3112 if (fillInIntent != null && fillInIntent.hasFileDescriptors()) { 3113 throw new IllegalArgumentException("File descriptors passed in Intent"); 3114 } 3115 3116 IIntentSender sender = intent.getTarget(); 3117 if (!(sender instanceof PendingIntentRecord)) { 3118 throw new IllegalArgumentException("Bad PendingIntent object"); 3119 } 3120 3121 PendingIntentRecord pir = (PendingIntentRecord)sender; 3122 3123 synchronized (this) { 3124 // If this is coming from the currently resumed activity, it is 3125 // effectively saying that app switches are allowed at this point. 3126 final ActivityStack stack = getFocusedStack(); 3127 if (stack.mResumedActivity != null && 3128 stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) { 3129 mAppSwitchesAllowedTime = 0; 3130 } 3131 } 3132 int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null, 3133 resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null); 3134 return ret; 3135 } 3136 3137 @Override 3138 public boolean startNextMatchingActivity(IBinder callingActivity, 3139 Intent intent, Bundle options) { 3140 // Refuse possible leaked file descriptors 3141 if (intent != null && intent.hasFileDescriptors() == true) { 3142 throw new IllegalArgumentException("File descriptors passed in Intent"); 3143 } 3144 3145 synchronized (this) { 3146 final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity); 3147 if (r == null) { 3148 ActivityOptions.abort(options); 3149 return false; 3150 } 3151 if (r.app == null || r.app.thread == null) { 3152 // The caller is not running... d'oh! 3153 ActivityOptions.abort(options); 3154 return false; 3155 } 3156 intent = new Intent(intent); 3157 // The caller is not allowed to change the data. 3158 intent.setDataAndType(r.intent.getData(), r.intent.getType()); 3159 // And we are resetting to find the next component... 3160 intent.setComponent(null); 3161 3162 final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0); 3163 3164 ActivityInfo aInfo = null; 3165 try { 3166 List<ResolveInfo> resolves = 3167 AppGlobals.getPackageManager().queryIntentActivities( 3168 intent, r.resolvedType, 3169 PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS, 3170 UserHandle.getCallingUserId()); 3171 3172 // Look for the original activity in the list... 3173 final int N = resolves != null ? resolves.size() : 0; 3174 for (int i=0; i<N; i++) { 3175 ResolveInfo rInfo = resolves.get(i); 3176 if (rInfo.activityInfo.packageName.equals(r.packageName) 3177 && rInfo.activityInfo.name.equals(r.info.name)) { 3178 // We found the current one... the next matching is 3179 // after it. 3180 i++; 3181 if (i<N) { 3182 aInfo = resolves.get(i).activityInfo; 3183 } 3184 if (debug) { 3185 Slog.v(TAG, "Next matching activity: found current " + r.packageName 3186 + "/" + r.info.name); 3187 Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName 3188 + "/" + aInfo.name); 3189 } 3190 break; 3191 } 3192 } 3193 } catch (RemoteException e) { 3194 } 3195 3196 if (aInfo == null) { 3197 // Nobody who is next! 3198 ActivityOptions.abort(options); 3199 if (debug) Slog.d(TAG, "Next matching activity: nothing found"); 3200 return false; 3201 } 3202 3203 intent.setComponent(new ComponentName( 3204 aInfo.applicationInfo.packageName, aInfo.name)); 3205 intent.setFlags(intent.getFlags()&~( 3206 Intent.FLAG_ACTIVITY_FORWARD_RESULT| 3207 Intent.FLAG_ACTIVITY_CLEAR_TOP| 3208 Intent.FLAG_ACTIVITY_MULTIPLE_TASK| 3209 Intent.FLAG_ACTIVITY_NEW_TASK)); 3210 3211 // Okay now we need to start the new activity, replacing the 3212 // currently running activity. This is a little tricky because 3213 // we want to start the new one as if the current one is finished, 3214 // but not finish the current one first so that there is no flicker. 3215 // And thus... 3216 final boolean wasFinishing = r.finishing; 3217 r.finishing = true; 3218 3219 // Propagate reply information over to the new activity. 3220 final ActivityRecord resultTo = r.resultTo; 3221 final String resultWho = r.resultWho; 3222 final int requestCode = r.requestCode; 3223 r.resultTo = null; 3224 if (resultTo != null) { 3225 resultTo.removeResultsLocked(r, resultWho, requestCode); 3226 } 3227 3228 final long origId = Binder.clearCallingIdentity(); 3229 int res = mStackSupervisor.startActivityLocked(r.app.thread, intent, 3230 r.resolvedType, aInfo, resultTo != null ? resultTo.appToken : null, 3231 resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage, 0, 3232 options, false, null, null); 3233 Binder.restoreCallingIdentity(origId); 3234 3235 r.finishing = wasFinishing; 3236 if (res != ActivityManager.START_SUCCESS) { 3237 return false; 3238 } 3239 return true; 3240 } 3241 } 3242 3243 final int startActivityInPackage(int uid, String callingPackage, 3244 Intent intent, String resolvedType, IBinder resultTo, 3245 String resultWho, int requestCode, int startFlags, Bundle options, int userId, 3246 IActivityContainer container) { 3247 3248 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3249 false, true, "startActivityInPackage", null); 3250 3251 // TODO: Switch to user app stacks here. 3252 int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent, resolvedType, 3253 resultTo, resultWho, requestCode, startFlags, 3254 null, null, null, null, options, userId, container); 3255 return ret; 3256 } 3257 3258 @Override 3259 public final int startActivities(IApplicationThread caller, String callingPackage, 3260 Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options, 3261 int userId) { 3262 enforceNotIsolatedCaller("startActivities"); 3263 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3264 false, true, "startActivity", null); 3265 // TODO: Switch to user app stacks here. 3266 int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents, 3267 resolvedTypes, resultTo, options, userId); 3268 return ret; 3269 } 3270 3271 final int startActivitiesInPackage(int uid, String callingPackage, 3272 Intent[] intents, String[] resolvedTypes, IBinder resultTo, 3273 Bundle options, int userId) { 3274 3275 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3276 false, true, "startActivityInPackage", null); 3277 // TODO: Switch to user app stacks here. 3278 int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes, 3279 resultTo, options, userId); 3280 return ret; 3281 } 3282 3283 final void addRecentTaskLocked(TaskRecord task) { 3284 int N = mRecentTasks.size(); 3285 // Quick case: check if the top-most recent task is the same. 3286 if (N > 0 && mRecentTasks.get(0) == task) { 3287 return; 3288 } 3289 // Remove any existing entries that are the same kind of task. 3290 for (int i=0; i<N; i++) { 3291 TaskRecord tr = mRecentTasks.get(i); 3292 if (task.userId == tr.userId 3293 && ((task.affinity != null && task.affinity.equals(tr.affinity)) 3294 || (task.intent != null && task.intent.filterEquals(tr.intent)))) { 3295 tr.disposeThumbnail(); 3296 mRecentTasks.remove(i); 3297 i--; 3298 N--; 3299 if (task.intent == null) { 3300 // If the new recent task we are adding is not fully 3301 // specified, then replace it with the existing recent task. 3302 task = tr; 3303 } 3304 } 3305 } 3306 if (N >= MAX_RECENT_TASKS) { 3307 mRecentTasks.remove(N-1).disposeThumbnail(); 3308 } 3309 mRecentTasks.add(0, task); 3310 } 3311 3312 @Override 3313 public void reportActivityFullyDrawn(IBinder token) { 3314 synchronized (this) { 3315 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3316 if (r == null) { 3317 return; 3318 } 3319 r.reportFullyDrawnLocked(); 3320 } 3321 } 3322 3323 @Override 3324 public void setRequestedOrientation(IBinder token, int requestedOrientation) { 3325 synchronized (this) { 3326 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3327 if (r == null) { 3328 return; 3329 } 3330 final long origId = Binder.clearCallingIdentity(); 3331 mWindowManager.setAppOrientation(r.appToken, requestedOrientation); 3332 Configuration config = mWindowManager.updateOrientationFromAppTokens( 3333 mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null); 3334 if (config != null) { 3335 r.frozenBeforeDestroy = true; 3336 if (!updateConfigurationLocked(config, r, false, false)) { 3337 mStackSupervisor.resumeTopActivitiesLocked(); 3338 } 3339 } 3340 Binder.restoreCallingIdentity(origId); 3341 } 3342 } 3343 3344 @Override 3345 public int getRequestedOrientation(IBinder token) { 3346 synchronized (this) { 3347 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3348 if (r == null) { 3349 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; 3350 } 3351 return mWindowManager.getAppOrientation(r.appToken); 3352 } 3353 } 3354 3355 /** 3356 * This is the internal entry point for handling Activity.finish(). 3357 * 3358 * @param token The Binder token referencing the Activity we want to finish. 3359 * @param resultCode Result code, if any, from this Activity. 3360 * @param resultData Result data (Intent), if any, from this Activity. 3361 * 3362 * @return Returns true if the activity successfully finished, or false if it is still running. 3363 */ 3364 @Override 3365 public final boolean finishActivity(IBinder token, int resultCode, Intent resultData) { 3366 // Refuse possible leaked file descriptors 3367 if (resultData != null && resultData.hasFileDescriptors() == true) { 3368 throw new IllegalArgumentException("File descriptors passed in Intent"); 3369 } 3370 3371 synchronized(this) { 3372 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3373 if (r == null) { 3374 return true; 3375 } 3376 if (mController != null) { 3377 // Find the first activity that is not finishing. 3378 ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0); 3379 if (next != null) { 3380 // ask watcher if this is allowed 3381 boolean resumeOK = true; 3382 try { 3383 resumeOK = mController.activityResuming(next.packageName); 3384 } catch (RemoteException e) { 3385 mController = null; 3386 Watchdog.getInstance().setActivityController(null); 3387 } 3388 3389 if (!resumeOK) { 3390 return false; 3391 } 3392 } 3393 } 3394 final long origId = Binder.clearCallingIdentity(); 3395 boolean res = r.task.stack.requestFinishActivityLocked(token, resultCode, 3396 resultData, "app-request", true); 3397 Binder.restoreCallingIdentity(origId); 3398 return res; 3399 } 3400 } 3401 3402 @Override 3403 public final void finishHeavyWeightApp() { 3404 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 3405 != PackageManager.PERMISSION_GRANTED) { 3406 String msg = "Permission Denial: finishHeavyWeightApp() from pid=" 3407 + Binder.getCallingPid() 3408 + ", uid=" + Binder.getCallingUid() 3409 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 3410 Slog.w(TAG, msg); 3411 throw new SecurityException(msg); 3412 } 3413 3414 synchronized(this) { 3415 if (mHeavyWeightProcess == null) { 3416 return; 3417 } 3418 3419 ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>( 3420 mHeavyWeightProcess.activities); 3421 for (int i=0; i<activities.size(); i++) { 3422 ActivityRecord r = activities.get(i); 3423 if (!r.finishing) { 3424 r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED, 3425 null, "finish-heavy", true); 3426 } 3427 } 3428 3429 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 3430 mHeavyWeightProcess.userId, 0)); 3431 mHeavyWeightProcess = null; 3432 } 3433 } 3434 3435 @Override 3436 public void crashApplication(int uid, int initialPid, String packageName, 3437 String message) { 3438 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 3439 != PackageManager.PERMISSION_GRANTED) { 3440 String msg = "Permission Denial: crashApplication() from pid=" 3441 + Binder.getCallingPid() 3442 + ", uid=" + Binder.getCallingUid() 3443 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 3444 Slog.w(TAG, msg); 3445 throw new SecurityException(msg); 3446 } 3447 3448 synchronized(this) { 3449 ProcessRecord proc = null; 3450 3451 // Figure out which process to kill. We don't trust that initialPid 3452 // still has any relation to current pids, so must scan through the 3453 // list. 3454 synchronized (mPidsSelfLocked) { 3455 for (int i=0; i<mPidsSelfLocked.size(); i++) { 3456 ProcessRecord p = mPidsSelfLocked.valueAt(i); 3457 if (p.uid != uid) { 3458 continue; 3459 } 3460 if (p.pid == initialPid) { 3461 proc = p; 3462 break; 3463 } 3464 if (p.pkgList.containsKey(packageName)) { 3465 proc = p; 3466 } 3467 } 3468 } 3469 3470 if (proc == null) { 3471 Slog.w(TAG, "crashApplication: nothing for uid=" + uid 3472 + " initialPid=" + initialPid 3473 + " packageName=" + packageName); 3474 return; 3475 } 3476 3477 if (proc.thread != null) { 3478 if (proc.pid == Process.myPid()) { 3479 Log.w(TAG, "crashApplication: trying to crash self!"); 3480 return; 3481 } 3482 long ident = Binder.clearCallingIdentity(); 3483 try { 3484 proc.thread.scheduleCrash(message); 3485 } catch (RemoteException e) { 3486 } 3487 Binder.restoreCallingIdentity(ident); 3488 } 3489 } 3490 } 3491 3492 @Override 3493 public final void finishSubActivity(IBinder token, String resultWho, 3494 int requestCode) { 3495 synchronized(this) { 3496 final long origId = Binder.clearCallingIdentity(); 3497 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3498 if (r != null) { 3499 r.task.stack.finishSubActivityLocked(r, resultWho, requestCode); 3500 } 3501 Binder.restoreCallingIdentity(origId); 3502 } 3503 } 3504 3505 @Override 3506 public boolean finishActivityAffinity(IBinder token) { 3507 synchronized(this) { 3508 final long origId = Binder.clearCallingIdentity(); 3509 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3510 boolean res = false; 3511 if (r != null) { 3512 res = r.task.stack.finishActivityAffinityLocked(r); 3513 } 3514 Binder.restoreCallingIdentity(origId); 3515 return res; 3516 } 3517 } 3518 3519 @Override 3520 public boolean willActivityBeVisible(IBinder token) { 3521 synchronized(this) { 3522 ActivityStack stack = ActivityRecord.getStackLocked(token); 3523 if (stack != null) { 3524 return stack.willActivityBeVisibleLocked(token); 3525 } 3526 return false; 3527 } 3528 } 3529 3530 @Override 3531 public void overridePendingTransition(IBinder token, String packageName, 3532 int enterAnim, int exitAnim) { 3533 synchronized(this) { 3534 ActivityRecord self = ActivityRecord.isInStackLocked(token); 3535 if (self == null) { 3536 return; 3537 } 3538 3539 final long origId = Binder.clearCallingIdentity(); 3540 3541 if (self.state == ActivityState.RESUMED 3542 || self.state == ActivityState.PAUSING) { 3543 mWindowManager.overridePendingAppTransition(packageName, 3544 enterAnim, exitAnim, null); 3545 } 3546 3547 Binder.restoreCallingIdentity(origId); 3548 } 3549 } 3550 3551 /** 3552 * Main function for removing an existing process from the activity manager 3553 * as a result of that process going away. Clears out all connections 3554 * to the process. 3555 */ 3556 private final void handleAppDiedLocked(ProcessRecord app, 3557 boolean restarting, boolean allowRestart) { 3558 int pid = app.pid; 3559 cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1); 3560 if (!restarting) { 3561 removeLruProcessLocked(app); 3562 if (pid > 0) { 3563 ProcessList.remove(pid); 3564 } 3565 } 3566 3567 if (mProfileProc == app) { 3568 clearProfilerLocked(); 3569 } 3570 3571 // Remove this application's activities from active lists. 3572 boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app); 3573 3574 app.activities.clear(); 3575 3576 if (app.instrumentationClass != null) { 3577 Slog.w(TAG, "Crash of app " + app.processName 3578 + " running instrumentation " + app.instrumentationClass); 3579 Bundle info = new Bundle(); 3580 info.putString("shortMsg", "Process crashed."); 3581 finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info); 3582 } 3583 3584 if (!restarting) { 3585 if (!mStackSupervisor.resumeTopActivitiesLocked()) { 3586 // If there was nothing to resume, and we are not already 3587 // restarting this process, but there is a visible activity that 3588 // is hosted by the process... then make sure all visible 3589 // activities are running, taking care of restarting this 3590 // process. 3591 if (hasVisibleActivities) { 3592 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 3593 } 3594 } 3595 } 3596 } 3597 3598 private final int getLRURecordIndexForAppLocked(IApplicationThread thread) { 3599 IBinder threadBinder = thread.asBinder(); 3600 // Find the application record. 3601 for (int i=mLruProcesses.size()-1; i>=0; i--) { 3602 ProcessRecord rec = mLruProcesses.get(i); 3603 if (rec.thread != null && rec.thread.asBinder() == threadBinder) { 3604 return i; 3605 } 3606 } 3607 return -1; 3608 } 3609 3610 final ProcessRecord getRecordForAppLocked( 3611 IApplicationThread thread) { 3612 if (thread == null) { 3613 return null; 3614 } 3615 3616 int appIndex = getLRURecordIndexForAppLocked(thread); 3617 return appIndex >= 0 ? mLruProcesses.get(appIndex) : null; 3618 } 3619 3620 final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) { 3621 // If there are no longer any background processes running, 3622 // and the app that died was not running instrumentation, 3623 // then tell everyone we are now low on memory. 3624 boolean haveBg = false; 3625 for (int i=mLruProcesses.size()-1; i>=0; i--) { 3626 ProcessRecord rec = mLruProcesses.get(i); 3627 if (rec.thread != null 3628 && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 3629 haveBg = true; 3630 break; 3631 } 3632 } 3633 3634 if (!haveBg) { 3635 boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 3636 if (doReport) { 3637 long now = SystemClock.uptimeMillis(); 3638 if (now < (mLastMemUsageReportTime+5*60*1000)) { 3639 doReport = false; 3640 } else { 3641 mLastMemUsageReportTime = now; 3642 } 3643 } 3644 final ArrayList<ProcessMemInfo> memInfos 3645 = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null; 3646 EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size()); 3647 long now = SystemClock.uptimeMillis(); 3648 for (int i=mLruProcesses.size()-1; i>=0; i--) { 3649 ProcessRecord rec = mLruProcesses.get(i); 3650 if (rec == dyingProc || rec.thread == null) { 3651 continue; 3652 } 3653 if (doReport) { 3654 memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj, 3655 rec.setProcState, rec.adjType, rec.makeAdjReason())); 3656 } 3657 if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) { 3658 // The low memory report is overriding any current 3659 // state for a GC request. Make sure to do 3660 // heavy/important/visible/foreground processes first. 3661 if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 3662 rec.lastRequestedGc = 0; 3663 } else { 3664 rec.lastRequestedGc = rec.lastLowMemory; 3665 } 3666 rec.reportLowMemory = true; 3667 rec.lastLowMemory = now; 3668 mProcessesToGc.remove(rec); 3669 addProcessToGcListLocked(rec); 3670 } 3671 } 3672 if (doReport) { 3673 Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos); 3674 mHandler.sendMessage(msg); 3675 } 3676 scheduleAppGcsLocked(); 3677 } 3678 } 3679 3680 final void appDiedLocked(ProcessRecord app, int pid, 3681 IApplicationThread thread) { 3682 3683 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 3684 synchronized (stats) { 3685 stats.noteProcessDiedLocked(app.info.uid, pid); 3686 } 3687 3688 // Clean up already done if the process has been re-started. 3689 if (app.pid == pid && app.thread != null && 3690 app.thread.asBinder() == thread.asBinder()) { 3691 boolean doLowMem = app.instrumentationClass == null; 3692 boolean doOomAdj = doLowMem; 3693 if (!app.killedByAm) { 3694 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 3695 + ") has died."); 3696 mAllowLowerMemLevel = true; 3697 } else { 3698 // Note that we always want to do oom adj to update our state with the 3699 // new number of procs. 3700 mAllowLowerMemLevel = false; 3701 doLowMem = false; 3702 } 3703 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName); 3704 if (DEBUG_CLEANUP) Slog.v( 3705 TAG, "Dying app: " + app + ", pid: " + pid 3706 + ", thread: " + thread.asBinder()); 3707 handleAppDiedLocked(app, false, true); 3708 3709 if (doOomAdj) { 3710 updateOomAdjLocked(); 3711 } 3712 if (doLowMem) { 3713 doLowMemReportIfNeededLocked(app); 3714 } 3715 } else if (app.pid != pid) { 3716 // A new process has already been started. 3717 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 3718 + ") has died and restarted (pid " + app.pid + ")."); 3719 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName); 3720 } else if (DEBUG_PROCESSES) { 3721 Slog.d(TAG, "Received spurious death notification for thread " 3722 + thread.asBinder()); 3723 } 3724 } 3725 3726 /** 3727 * If a stack trace dump file is configured, dump process stack traces. 3728 * @param clearTraces causes the dump file to be erased prior to the new 3729 * traces being written, if true; when false, the new traces will be 3730 * appended to any existing file content. 3731 * @param firstPids of dalvik VM processes to dump stack traces for first 3732 * @param lastPids of dalvik VM processes to dump stack traces for last 3733 * @param nativeProcs optional list of native process names to dump stack crawls 3734 * @return file containing stack traces, or null if no dump file is configured 3735 */ 3736 public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids, 3737 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) { 3738 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 3739 if (tracesPath == null || tracesPath.length() == 0) { 3740 return null; 3741 } 3742 3743 File tracesFile = new File(tracesPath); 3744 try { 3745 File tracesDir = tracesFile.getParentFile(); 3746 if (!tracesDir.exists()) { 3747 tracesFile.mkdirs(); 3748 if (!SELinux.restorecon(tracesDir)) { 3749 return null; 3750 } 3751 } 3752 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 3753 3754 if (clearTraces && tracesFile.exists()) tracesFile.delete(); 3755 tracesFile.createNewFile(); 3756 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 3757 } catch (IOException e) { 3758 Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e); 3759 return null; 3760 } 3761 3762 dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs); 3763 return tracesFile; 3764 } 3765 3766 private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids, 3767 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) { 3768 // Use a FileObserver to detect when traces finish writing. 3769 // The order of traces is considered important to maintain for legibility. 3770 FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) { 3771 @Override 3772 public synchronized void onEvent(int event, String path) { notify(); } 3773 }; 3774 3775 try { 3776 observer.startWatching(); 3777 3778 // First collect all of the stacks of the most important pids. 3779 if (firstPids != null) { 3780 try { 3781 int num = firstPids.size(); 3782 for (int i = 0; i < num; i++) { 3783 synchronized (observer) { 3784 Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT); 3785 observer.wait(200); // Wait for write-close, give up after 200msec 3786 } 3787 } 3788 } catch (InterruptedException e) { 3789 Log.wtf(TAG, e); 3790 } 3791 } 3792 3793 // Next collect the stacks of the native pids 3794 if (nativeProcs != null) { 3795 int[] pids = Process.getPidsForCommands(nativeProcs); 3796 if (pids != null) { 3797 for (int pid : pids) { 3798 Debug.dumpNativeBacktraceToFile(pid, tracesPath); 3799 } 3800 } 3801 } 3802 3803 // Lastly, measure CPU usage. 3804 if (processCpuTracker != null) { 3805 processCpuTracker.init(); 3806 System.gc(); 3807 processCpuTracker.update(); 3808 try { 3809 synchronized (processCpuTracker) { 3810 processCpuTracker.wait(500); // measure over 1/2 second. 3811 } 3812 } catch (InterruptedException e) { 3813 } 3814 processCpuTracker.update(); 3815 3816 // We'll take the stack crawls of just the top apps using CPU. 3817 final int N = processCpuTracker.countWorkingStats(); 3818 int numProcs = 0; 3819 for (int i=0; i<N && numProcs<5; i++) { 3820 ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i); 3821 if (lastPids.indexOfKey(stats.pid) >= 0) { 3822 numProcs++; 3823 try { 3824 synchronized (observer) { 3825 Process.sendSignal(stats.pid, Process.SIGNAL_QUIT); 3826 observer.wait(200); // Wait for write-close, give up after 200msec 3827 } 3828 } catch (InterruptedException e) { 3829 Log.wtf(TAG, e); 3830 } 3831 3832 } 3833 } 3834 } 3835 } finally { 3836 observer.stopWatching(); 3837 } 3838 } 3839 3840 final void logAppTooSlow(ProcessRecord app, long startTime, String msg) { 3841 if (true || IS_USER_BUILD) { 3842 return; 3843 } 3844 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 3845 if (tracesPath == null || tracesPath.length() == 0) { 3846 return; 3847 } 3848 3849 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads(); 3850 StrictMode.allowThreadDiskWrites(); 3851 try { 3852 final File tracesFile = new File(tracesPath); 3853 final File tracesDir = tracesFile.getParentFile(); 3854 final File tracesTmp = new File(tracesDir, "__tmp__"); 3855 try { 3856 if (!tracesDir.exists()) { 3857 tracesFile.mkdirs(); 3858 if (!SELinux.restorecon(tracesDir.getPath())) { 3859 return; 3860 } 3861 } 3862 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 3863 3864 if (tracesFile.exists()) { 3865 tracesTmp.delete(); 3866 tracesFile.renameTo(tracesTmp); 3867 } 3868 StringBuilder sb = new StringBuilder(); 3869 Time tobj = new Time(); 3870 tobj.set(System.currentTimeMillis()); 3871 sb.append(tobj.format("%Y-%m-%d %H:%M:%S")); 3872 sb.append(": "); 3873 TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb); 3874 sb.append(" since "); 3875 sb.append(msg); 3876 FileOutputStream fos = new FileOutputStream(tracesFile); 3877 fos.write(sb.toString().getBytes()); 3878 if (app == null) { 3879 fos.write("\n*** No application process!".getBytes()); 3880 } 3881 fos.close(); 3882 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 3883 } catch (IOException e) { 3884 Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e); 3885 return; 3886 } 3887 3888 if (app != null) { 3889 ArrayList<Integer> firstPids = new ArrayList<Integer>(); 3890 firstPids.add(app.pid); 3891 dumpStackTraces(tracesPath, firstPids, null, null, null); 3892 } 3893 3894 File lastTracesFile = null; 3895 File curTracesFile = null; 3896 for (int i=9; i>=0; i--) { 3897 String name = String.format(Locale.US, "slow%02d.txt", i); 3898 curTracesFile = new File(tracesDir, name); 3899 if (curTracesFile.exists()) { 3900 if (lastTracesFile != null) { 3901 curTracesFile.renameTo(lastTracesFile); 3902 } else { 3903 curTracesFile.delete(); 3904 } 3905 } 3906 lastTracesFile = curTracesFile; 3907 } 3908 tracesFile.renameTo(curTracesFile); 3909 if (tracesTmp.exists()) { 3910 tracesTmp.renameTo(tracesFile); 3911 } 3912 } finally { 3913 StrictMode.setThreadPolicy(oldPolicy); 3914 } 3915 } 3916 3917 final void appNotResponding(ProcessRecord app, ActivityRecord activity, 3918 ActivityRecord parent, boolean aboveSystem, final String annotation) { 3919 ArrayList<Integer> firstPids = new ArrayList<Integer>(5); 3920 SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20); 3921 3922 if (mController != null) { 3923 try { 3924 // 0 == continue, -1 = kill process immediately 3925 int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation); 3926 if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid); 3927 } catch (RemoteException e) { 3928 mController = null; 3929 Watchdog.getInstance().setActivityController(null); 3930 } 3931 } 3932 3933 long anrTime = SystemClock.uptimeMillis(); 3934 if (MONITOR_CPU_USAGE) { 3935 updateCpuStatsNow(); 3936 } 3937 3938 synchronized (this) { 3939 // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down. 3940 if (mShuttingDown) { 3941 Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation); 3942 return; 3943 } else if (app.notResponding) { 3944 Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation); 3945 return; 3946 } else if (app.crashing) { 3947 Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation); 3948 return; 3949 } 3950 3951 // In case we come through here for the same app before completing 3952 // this one, mark as anring now so we will bail out. 3953 app.notResponding = true; 3954 3955 // Log the ANR to the event log. 3956 EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid, 3957 app.processName, app.info.flags, annotation); 3958 3959 // Dump thread traces as quickly as we can, starting with "interesting" processes. 3960 firstPids.add(app.pid); 3961 3962 int parentPid = app.pid; 3963 if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid; 3964 if (parentPid != app.pid) firstPids.add(parentPid); 3965 3966 if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID); 3967 3968 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 3969 ProcessRecord r = mLruProcesses.get(i); 3970 if (r != null && r.thread != null) { 3971 int pid = r.pid; 3972 if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) { 3973 if (r.persistent) { 3974 firstPids.add(pid); 3975 } else { 3976 lastPids.put(pid, Boolean.TRUE); 3977 } 3978 } 3979 } 3980 } 3981 } 3982 3983 // Log the ANR to the main log. 3984 StringBuilder info = new StringBuilder(); 3985 info.setLength(0); 3986 info.append("ANR in ").append(app.processName); 3987 if (activity != null && activity.shortComponentName != null) { 3988 info.append(" (").append(activity.shortComponentName).append(")"); 3989 } 3990 info.append("\n"); 3991 info.append("PID: ").append(app.pid).append("\n"); 3992 if (annotation != null) { 3993 info.append("Reason: ").append(annotation).append("\n"); 3994 } 3995 if (parent != null && parent != activity) { 3996 info.append("Parent: ").append(parent.shortComponentName).append("\n"); 3997 } 3998 3999 final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true); 4000 4001 File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids, 4002 NATIVE_STACKS_OF_INTEREST); 4003 4004 String cpuInfo = null; 4005 if (MONITOR_CPU_USAGE) { 4006 updateCpuStatsNow(); 4007 synchronized (mProcessCpuThread) { 4008 cpuInfo = mProcessCpuTracker.printCurrentState(anrTime); 4009 } 4010 info.append(processCpuTracker.printCurrentLoad()); 4011 info.append(cpuInfo); 4012 } 4013 4014 info.append(processCpuTracker.printCurrentState(anrTime)); 4015 4016 Slog.e(TAG, info.toString()); 4017 if (tracesFile == null) { 4018 // There is no trace file, so dump (only) the alleged culprit's threads to the log 4019 Process.sendSignal(app.pid, Process.SIGNAL_QUIT); 4020 } 4021 4022 addErrorToDropBox("anr", app, app.processName, activity, parent, annotation, 4023 cpuInfo, tracesFile, null); 4024 4025 if (mController != null) { 4026 try { 4027 // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately 4028 int res = mController.appNotResponding(app.processName, app.pid, info.toString()); 4029 if (res != 0) { 4030 if (res < 0 && app.pid != MY_PID) { 4031 Process.killProcess(app.pid); 4032 } else { 4033 synchronized (this) { 4034 mServices.scheduleServiceTimeoutLocked(app); 4035 } 4036 } 4037 return; 4038 } 4039 } catch (RemoteException e) { 4040 mController = null; 4041 Watchdog.getInstance().setActivityController(null); 4042 } 4043 } 4044 4045 // Unless configured otherwise, swallow ANRs in background processes & kill the process. 4046 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), 4047 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; 4048 4049 synchronized (this) { 4050 if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) { 4051 killUnneededProcessLocked(app, "background ANR"); 4052 return; 4053 } 4054 4055 // Set the app's notResponding state, and look up the errorReportReceiver 4056 makeAppNotRespondingLocked(app, 4057 activity != null ? activity.shortComponentName : null, 4058 annotation != null ? "ANR " + annotation : "ANR", 4059 info.toString()); 4060 4061 // Bring up the infamous App Not Responding dialog 4062 Message msg = Message.obtain(); 4063 HashMap<String, Object> map = new HashMap<String, Object>(); 4064 msg.what = SHOW_NOT_RESPONDING_MSG; 4065 msg.obj = map; 4066 msg.arg1 = aboveSystem ? 1 : 0; 4067 map.put("app", app); 4068 if (activity != null) { 4069 map.put("activity", activity); 4070 } 4071 4072 mHandler.sendMessage(msg); 4073 } 4074 } 4075 4076 final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) { 4077 if (!mLaunchWarningShown) { 4078 mLaunchWarningShown = true; 4079 mHandler.post(new Runnable() { 4080 @Override 4081 public void run() { 4082 synchronized (ActivityManagerService.this) { 4083 final Dialog d = new LaunchWarningWindow(mContext, cur, next); 4084 d.show(); 4085 mHandler.postDelayed(new Runnable() { 4086 @Override 4087 public void run() { 4088 synchronized (ActivityManagerService.this) { 4089 d.dismiss(); 4090 mLaunchWarningShown = false; 4091 } 4092 } 4093 }, 4000); 4094 } 4095 } 4096 }); 4097 } 4098 } 4099 4100 @Override 4101 public boolean clearApplicationUserData(final String packageName, 4102 final IPackageDataObserver observer, int userId) { 4103 enforceNotIsolatedCaller("clearApplicationUserData"); 4104 int uid = Binder.getCallingUid(); 4105 int pid = Binder.getCallingPid(); 4106 userId = handleIncomingUser(pid, uid, 4107 userId, false, true, "clearApplicationUserData", null); 4108 long callingId = Binder.clearCallingIdentity(); 4109 try { 4110 IPackageManager pm = AppGlobals.getPackageManager(); 4111 int pkgUid = -1; 4112 synchronized(this) { 4113 try { 4114 pkgUid = pm.getPackageUid(packageName, userId); 4115 } catch (RemoteException e) { 4116 } 4117 if (pkgUid == -1) { 4118 Slog.w(TAG, "Invalid packageName: " + packageName); 4119 if (observer != null) { 4120 try { 4121 observer.onRemoveCompleted(packageName, false); 4122 } catch (RemoteException e) { 4123 Slog.i(TAG, "Observer no longer exists."); 4124 } 4125 } 4126 return false; 4127 } 4128 if (uid == pkgUid || checkComponentPermission( 4129 android.Manifest.permission.CLEAR_APP_USER_DATA, 4130 pid, uid, -1, true) 4131 == PackageManager.PERMISSION_GRANTED) { 4132 forceStopPackageLocked(packageName, pkgUid, "clear data"); 4133 } else { 4134 throw new SecurityException("PID " + pid + " does not have permission " 4135 + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data" 4136 + " of package " + packageName); 4137 } 4138 } 4139 4140 try { 4141 // Clear application user data 4142 pm.clearApplicationUserData(packageName, observer, userId); 4143 4144 // Remove all permissions granted from/to this package 4145 removeUriPermissionsForPackageLocked(packageName, userId, true); 4146 4147 Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED, 4148 Uri.fromParts("package", packageName, null)); 4149 intent.putExtra(Intent.EXTRA_UID, pkgUid); 4150 broadcastIntentInPackage("android", Process.SYSTEM_UID, intent, 4151 null, null, 0, null, null, null, false, false, userId); 4152 } catch (RemoteException e) { 4153 } 4154 } finally { 4155 Binder.restoreCallingIdentity(callingId); 4156 } 4157 return true; 4158 } 4159 4160 @Override 4161 public void killBackgroundProcesses(final String packageName, int userId) { 4162 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 4163 != PackageManager.PERMISSION_GRANTED && 4164 checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES) 4165 != PackageManager.PERMISSION_GRANTED) { 4166 String msg = "Permission Denial: killBackgroundProcesses() from pid=" 4167 + Binder.getCallingPid() 4168 + ", uid=" + Binder.getCallingUid() 4169 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 4170 Slog.w(TAG, msg); 4171 throw new SecurityException(msg); 4172 } 4173 4174 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 4175 userId, true, true, "killBackgroundProcesses", null); 4176 long callingId = Binder.clearCallingIdentity(); 4177 try { 4178 IPackageManager pm = AppGlobals.getPackageManager(); 4179 synchronized(this) { 4180 int appId = -1; 4181 try { 4182 appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0)); 4183 } catch (RemoteException e) { 4184 } 4185 if (appId == -1) { 4186 Slog.w(TAG, "Invalid packageName: " + packageName); 4187 return; 4188 } 4189 killPackageProcessesLocked(packageName, appId, userId, 4190 ProcessList.SERVICE_ADJ, false, true, true, false, "kill background"); 4191 } 4192 } finally { 4193 Binder.restoreCallingIdentity(callingId); 4194 } 4195 } 4196 4197 @Override 4198 public void killAllBackgroundProcesses() { 4199 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 4200 != PackageManager.PERMISSION_GRANTED) { 4201 String msg = "Permission Denial: killAllBackgroundProcesses() from pid=" 4202 + Binder.getCallingPid() 4203 + ", uid=" + Binder.getCallingUid() 4204 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 4205 Slog.w(TAG, msg); 4206 throw new SecurityException(msg); 4207 } 4208 4209 long callingId = Binder.clearCallingIdentity(); 4210 try { 4211 synchronized(this) { 4212 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 4213 final int NP = mProcessNames.getMap().size(); 4214 for (int ip=0; ip<NP; ip++) { 4215 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 4216 final int NA = apps.size(); 4217 for (int ia=0; ia<NA; ia++) { 4218 ProcessRecord app = apps.valueAt(ia); 4219 if (app.persistent) { 4220 // we don't kill persistent processes 4221 continue; 4222 } 4223 if (app.removed) { 4224 procs.add(app); 4225 } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 4226 app.removed = true; 4227 procs.add(app); 4228 } 4229 } 4230 } 4231 4232 int N = procs.size(); 4233 for (int i=0; i<N; i++) { 4234 removeProcessLocked(procs.get(i), false, true, "kill all background"); 4235 } 4236 mAllowLowerMemLevel = true; 4237 updateOomAdjLocked(); 4238 doLowMemReportIfNeededLocked(null); 4239 } 4240 } finally { 4241 Binder.restoreCallingIdentity(callingId); 4242 } 4243 } 4244 4245 @Override 4246 public void forceStopPackage(final String packageName, int userId) { 4247 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 4248 != PackageManager.PERMISSION_GRANTED) { 4249 String msg = "Permission Denial: forceStopPackage() from pid=" 4250 + Binder.getCallingPid() 4251 + ", uid=" + Binder.getCallingUid() 4252 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 4253 Slog.w(TAG, msg); 4254 throw new SecurityException(msg); 4255 } 4256 final int callingPid = Binder.getCallingPid(); 4257 userId = handleIncomingUser(callingPid, Binder.getCallingUid(), 4258 userId, true, true, "forceStopPackage", null); 4259 long callingId = Binder.clearCallingIdentity(); 4260 try { 4261 IPackageManager pm = AppGlobals.getPackageManager(); 4262 synchronized(this) { 4263 int[] users = userId == UserHandle.USER_ALL 4264 ? getUsersLocked() : new int[] { userId }; 4265 for (int user : users) { 4266 int pkgUid = -1; 4267 try { 4268 pkgUid = pm.getPackageUid(packageName, user); 4269 } catch (RemoteException e) { 4270 } 4271 if (pkgUid == -1) { 4272 Slog.w(TAG, "Invalid packageName: " + packageName); 4273 continue; 4274 } 4275 try { 4276 pm.setPackageStoppedState(packageName, true, user); 4277 } catch (RemoteException e) { 4278 } catch (IllegalArgumentException e) { 4279 Slog.w(TAG, "Failed trying to unstop package " 4280 + packageName + ": " + e); 4281 } 4282 if (isUserRunningLocked(user, false)) { 4283 forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid); 4284 } 4285 } 4286 } 4287 } finally { 4288 Binder.restoreCallingIdentity(callingId); 4289 } 4290 } 4291 4292 /* 4293 * The pkg name and app id have to be specified. 4294 */ 4295 @Override 4296 public void killApplicationWithAppId(String pkg, int appid, String reason) { 4297 if (pkg == null) { 4298 return; 4299 } 4300 // Make sure the uid is valid. 4301 if (appid < 0) { 4302 Slog.w(TAG, "Invalid appid specified for pkg : " + pkg); 4303 return; 4304 } 4305 int callerUid = Binder.getCallingUid(); 4306 // Only the system server can kill an application 4307 if (callerUid == Process.SYSTEM_UID) { 4308 // Post an aysnc message to kill the application 4309 Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG); 4310 msg.arg1 = appid; 4311 msg.arg2 = 0; 4312 Bundle bundle = new Bundle(); 4313 bundle.putString("pkg", pkg); 4314 bundle.putString("reason", reason); 4315 msg.obj = bundle; 4316 mHandler.sendMessage(msg); 4317 } else { 4318 throw new SecurityException(callerUid + " cannot kill pkg: " + 4319 pkg); 4320 } 4321 } 4322 4323 @Override 4324 public void closeSystemDialogs(String reason) { 4325 enforceNotIsolatedCaller("closeSystemDialogs"); 4326 4327 final int pid = Binder.getCallingPid(); 4328 final int uid = Binder.getCallingUid(); 4329 final long origId = Binder.clearCallingIdentity(); 4330 try { 4331 synchronized (this) { 4332 // Only allow this from foreground processes, so that background 4333 // applications can't abuse it to prevent system UI from being shown. 4334 if (uid >= Process.FIRST_APPLICATION_UID) { 4335 ProcessRecord proc; 4336 synchronized (mPidsSelfLocked) { 4337 proc = mPidsSelfLocked.get(pid); 4338 } 4339 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 4340 Slog.w(TAG, "Ignoring closeSystemDialogs " + reason 4341 + " from background process " + proc); 4342 return; 4343 } 4344 } 4345 closeSystemDialogsLocked(reason); 4346 } 4347 } finally { 4348 Binder.restoreCallingIdentity(origId); 4349 } 4350 } 4351 4352 void closeSystemDialogsLocked(String reason) { 4353 Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS); 4354 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 4355 | Intent.FLAG_RECEIVER_FOREGROUND); 4356 if (reason != null) { 4357 intent.putExtra("reason", reason); 4358 } 4359 mWindowManager.closeSystemDialogs(reason); 4360 4361 mStackSupervisor.closeSystemDialogsLocked(); 4362 4363 broadcastIntentLocked(null, null, intent, null, 4364 null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1, 4365 Process.SYSTEM_UID, UserHandle.USER_ALL); 4366 } 4367 4368 @Override 4369 public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) { 4370 enforceNotIsolatedCaller("getProcessMemoryInfo"); 4371 Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length]; 4372 for (int i=pids.length-1; i>=0; i--) { 4373 ProcessRecord proc; 4374 int oomAdj; 4375 synchronized (this) { 4376 synchronized (mPidsSelfLocked) { 4377 proc = mPidsSelfLocked.get(pids[i]); 4378 oomAdj = proc != null ? proc.setAdj : 0; 4379 } 4380 } 4381 infos[i] = new Debug.MemoryInfo(); 4382 Debug.getMemoryInfo(pids[i], infos[i]); 4383 if (proc != null) { 4384 synchronized (this) { 4385 if (proc.thread != null && proc.setAdj == oomAdj) { 4386 // Record this for posterity if the process has been stable. 4387 proc.baseProcessTracker.addPss(infos[i].getTotalPss(), 4388 infos[i].getTotalUss(), false, proc.pkgList); 4389 } 4390 } 4391 } 4392 } 4393 return infos; 4394 } 4395 4396 @Override 4397 public long[] getProcessPss(int[] pids) { 4398 enforceNotIsolatedCaller("getProcessPss"); 4399 long[] pss = new long[pids.length]; 4400 for (int i=pids.length-1; i>=0; i--) { 4401 ProcessRecord proc; 4402 int oomAdj; 4403 synchronized (this) { 4404 synchronized (mPidsSelfLocked) { 4405 proc = mPidsSelfLocked.get(pids[i]); 4406 oomAdj = proc != null ? proc.setAdj : 0; 4407 } 4408 } 4409 long[] tmpUss = new long[1]; 4410 pss[i] = Debug.getPss(pids[i], tmpUss); 4411 if (proc != null) { 4412 synchronized (this) { 4413 if (proc.thread != null && proc.setAdj == oomAdj) { 4414 // Record this for posterity if the process has been stable. 4415 proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList); 4416 } 4417 } 4418 } 4419 } 4420 return pss; 4421 } 4422 4423 @Override 4424 public void killApplicationProcess(String processName, int uid) { 4425 if (processName == null) { 4426 return; 4427 } 4428 4429 int callerUid = Binder.getCallingUid(); 4430 // Only the system server can kill an application 4431 if (callerUid == Process.SYSTEM_UID) { 4432 synchronized (this) { 4433 ProcessRecord app = getProcessRecordLocked(processName, uid, true); 4434 if (app != null && app.thread != null) { 4435 try { 4436 app.thread.scheduleSuicide(); 4437 } catch (RemoteException e) { 4438 // If the other end already died, then our work here is done. 4439 } 4440 } else { 4441 Slog.w(TAG, "Process/uid not found attempting kill of " 4442 + processName + " / " + uid); 4443 } 4444 } 4445 } else { 4446 throw new SecurityException(callerUid + " cannot kill app process: " + 4447 processName); 4448 } 4449 } 4450 4451 private void forceStopPackageLocked(final String packageName, int uid, String reason) { 4452 forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false, 4453 false, true, false, UserHandle.getUserId(uid), reason); 4454 Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED, 4455 Uri.fromParts("package", packageName, null)); 4456 if (!mProcessesReady) { 4457 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 4458 | Intent.FLAG_RECEIVER_FOREGROUND); 4459 } 4460 intent.putExtra(Intent.EXTRA_UID, uid); 4461 intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid)); 4462 broadcastIntentLocked(null, null, intent, 4463 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 4464 false, false, 4465 MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid)); 4466 } 4467 4468 private void forceStopUserLocked(int userId, String reason) { 4469 forceStopPackageLocked(null, -1, false, false, true, false, userId, reason); 4470 Intent intent = new Intent(Intent.ACTION_USER_STOPPED); 4471 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 4472 | Intent.FLAG_RECEIVER_FOREGROUND); 4473 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 4474 broadcastIntentLocked(null, null, intent, 4475 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 4476 false, false, 4477 MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 4478 } 4479 4480 private final boolean killPackageProcessesLocked(String packageName, int appId, 4481 int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart, 4482 boolean doit, boolean evenPersistent, String reason) { 4483 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 4484 4485 // Remove all processes this package may have touched: all with the 4486 // same UID (except for the system or root user), and all whose name 4487 // matches the package name. 4488 final String procNamePrefix = packageName != null ? (packageName + ":") : null; 4489 final int NP = mProcessNames.getMap().size(); 4490 for (int ip=0; ip<NP; ip++) { 4491 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 4492 final int NA = apps.size(); 4493 for (int ia=0; ia<NA; ia++) { 4494 ProcessRecord app = apps.valueAt(ia); 4495 if (app.persistent && !evenPersistent) { 4496 // we don't kill persistent processes 4497 continue; 4498 } 4499 if (app.removed) { 4500 if (doit) { 4501 procs.add(app); 4502 } 4503 continue; 4504 } 4505 4506 // Skip process if it doesn't meet our oom adj requirement. 4507 if (app.setAdj < minOomAdj) { 4508 continue; 4509 } 4510 4511 // If no package is specified, we call all processes under the 4512 // give user id. 4513 if (packageName == null) { 4514 if (app.userId != userId) { 4515 continue; 4516 } 4517 if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) { 4518 continue; 4519 } 4520 // Package has been specified, we want to hit all processes 4521 // that match it. We need to qualify this by the processes 4522 // that are running under the specified app and user ID. 4523 } else { 4524 if (UserHandle.getAppId(app.uid) != appId) { 4525 continue; 4526 } 4527 if (userId != UserHandle.USER_ALL && app.userId != userId) { 4528 continue; 4529 } 4530 if (!app.pkgList.containsKey(packageName)) { 4531 continue; 4532 } 4533 } 4534 4535 // Process has passed all conditions, kill it! 4536 if (!doit) { 4537 return true; 4538 } 4539 app.removed = true; 4540 procs.add(app); 4541 } 4542 } 4543 4544 int N = procs.size(); 4545 for (int i=0; i<N; i++) { 4546 removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason); 4547 } 4548 updateOomAdjLocked(); 4549 return N > 0; 4550 } 4551 4552 private final boolean forceStopPackageLocked(String name, int appId, 4553 boolean callerWillRestart, boolean purgeCache, boolean doit, 4554 boolean evenPersistent, int userId, String reason) { 4555 int i; 4556 int N; 4557 4558 if (userId == UserHandle.USER_ALL && name == null) { 4559 Slog.w(TAG, "Can't force stop all processes of all users, that is insane!"); 4560 } 4561 4562 if (appId < 0 && name != null) { 4563 try { 4564 appId = UserHandle.getAppId( 4565 AppGlobals.getPackageManager().getPackageUid(name, 0)); 4566 } catch (RemoteException e) { 4567 } 4568 } 4569 4570 if (doit) { 4571 if (name != null) { 4572 Slog.i(TAG, "Force stopping " + name + " appid=" + appId 4573 + " user=" + userId + ": " + reason); 4574 } else { 4575 Slog.i(TAG, "Force stopping u" + userId + ": " + reason); 4576 } 4577 4578 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap(); 4579 for (int ip=pmap.size()-1; ip>=0; ip--) { 4580 SparseArray<Long> ba = pmap.valueAt(ip); 4581 for (i=ba.size()-1; i>=0; i--) { 4582 boolean remove = false; 4583 final int entUid = ba.keyAt(i); 4584 if (name != null) { 4585 if (userId == UserHandle.USER_ALL) { 4586 if (UserHandle.getAppId(entUid) == appId) { 4587 remove = true; 4588 } 4589 } else { 4590 if (entUid == UserHandle.getUid(userId, appId)) { 4591 remove = true; 4592 } 4593 } 4594 } else if (UserHandle.getUserId(entUid) == userId) { 4595 remove = true; 4596 } 4597 if (remove) { 4598 ba.removeAt(i); 4599 } 4600 } 4601 if (ba.size() == 0) { 4602 pmap.removeAt(ip); 4603 } 4604 } 4605 } 4606 4607 boolean didSomething = killPackageProcessesLocked(name, appId, userId, 4608 -100, callerWillRestart, true, doit, evenPersistent, 4609 name == null ? ("stop user " + userId) : ("stop " + name)); 4610 4611 if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) { 4612 if (!doit) { 4613 return true; 4614 } 4615 didSomething = true; 4616 } 4617 4618 if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) { 4619 if (!doit) { 4620 return true; 4621 } 4622 didSomething = true; 4623 } 4624 4625 if (name == null) { 4626 // Remove all sticky broadcasts from this user. 4627 mStickyBroadcasts.remove(userId); 4628 } 4629 4630 ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>(); 4631 if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent, 4632 userId, providers)) { 4633 if (!doit) { 4634 return true; 4635 } 4636 didSomething = true; 4637 } 4638 N = providers.size(); 4639 for (i=0; i<N; i++) { 4640 removeDyingProviderLocked(null, providers.get(i), true); 4641 } 4642 4643 // Remove transient permissions granted from/to this package/user 4644 removeUriPermissionsForPackageLocked(name, userId, false); 4645 4646 if (name == null) { 4647 // Remove pending intents. For now we only do this when force 4648 // stopping users, because we have some problems when doing this 4649 // for packages -- app widgets are not currently cleaned up for 4650 // such packages, so they can be left with bad pending intents. 4651 if (mIntentSenderRecords.size() > 0) { 4652 Iterator<WeakReference<PendingIntentRecord>> it 4653 = mIntentSenderRecords.values().iterator(); 4654 while (it.hasNext()) { 4655 WeakReference<PendingIntentRecord> wpir = it.next(); 4656 if (wpir == null) { 4657 it.remove(); 4658 continue; 4659 } 4660 PendingIntentRecord pir = wpir.get(); 4661 if (pir == null) { 4662 it.remove(); 4663 continue; 4664 } 4665 if (name == null) { 4666 // Stopping user, remove all objects for the user. 4667 if (pir.key.userId != userId) { 4668 // Not the same user, skip it. 4669 continue; 4670 } 4671 } else { 4672 if (UserHandle.getAppId(pir.uid) != appId) { 4673 // Different app id, skip it. 4674 continue; 4675 } 4676 if (userId != UserHandle.USER_ALL && pir.key.userId != userId) { 4677 // Different user, skip it. 4678 continue; 4679 } 4680 if (!pir.key.packageName.equals(name)) { 4681 // Different package, skip it. 4682 continue; 4683 } 4684 } 4685 if (!doit) { 4686 return true; 4687 } 4688 didSomething = true; 4689 it.remove(); 4690 pir.canceled = true; 4691 if (pir.key.activity != null) { 4692 pir.key.activity.pendingResults.remove(pir.ref); 4693 } 4694 } 4695 } 4696 } 4697 4698 if (doit) { 4699 if (purgeCache && name != null) { 4700 AttributeCache ac = AttributeCache.instance(); 4701 if (ac != null) { 4702 ac.removePackage(name); 4703 } 4704 } 4705 if (mBooted) { 4706 mStackSupervisor.resumeTopActivitiesLocked(); 4707 mStackSupervisor.scheduleIdleLocked(); 4708 } 4709 } 4710 4711 return didSomething; 4712 } 4713 4714 private final boolean removeProcessLocked(ProcessRecord app, 4715 boolean callerWillRestart, boolean allowRestart, String reason) { 4716 final String name = app.processName; 4717 final int uid = app.uid; 4718 if (DEBUG_PROCESSES) Slog.d( 4719 TAG, "Force removing proc " + app.toShortString() + " (" + name 4720 + "/" + uid + ")"); 4721 4722 mProcessNames.remove(name, uid); 4723 mIsolatedProcesses.remove(app.uid); 4724 if (mHeavyWeightProcess == app) { 4725 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 4726 mHeavyWeightProcess.userId, 0)); 4727 mHeavyWeightProcess = null; 4728 } 4729 boolean needRestart = false; 4730 if (app.pid > 0 && app.pid != MY_PID) { 4731 int pid = app.pid; 4732 synchronized (mPidsSelfLocked) { 4733 mPidsSelfLocked.remove(pid); 4734 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 4735 } 4736 killUnneededProcessLocked(app, reason); 4737 handleAppDiedLocked(app, true, allowRestart); 4738 removeLruProcessLocked(app); 4739 4740 if (app.persistent && !app.isolated) { 4741 if (!callerWillRestart) { 4742 addAppLocked(app.info, false); 4743 } else { 4744 needRestart = true; 4745 } 4746 } 4747 } else { 4748 mRemovedProcesses.add(app); 4749 } 4750 4751 return needRestart; 4752 } 4753 4754 private final void processStartTimedOutLocked(ProcessRecord app) { 4755 final int pid = app.pid; 4756 boolean gone = false; 4757 synchronized (mPidsSelfLocked) { 4758 ProcessRecord knownApp = mPidsSelfLocked.get(pid); 4759 if (knownApp != null && knownApp.thread == null) { 4760 mPidsSelfLocked.remove(pid); 4761 gone = true; 4762 } 4763 } 4764 4765 if (gone) { 4766 Slog.w(TAG, "Process " + app + " failed to attach"); 4767 EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId, 4768 pid, app.uid, app.processName); 4769 mProcessNames.remove(app.processName, app.uid); 4770 mIsolatedProcesses.remove(app.uid); 4771 if (mHeavyWeightProcess == app) { 4772 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 4773 mHeavyWeightProcess.userId, 0)); 4774 mHeavyWeightProcess = null; 4775 } 4776 // Take care of any launching providers waiting for this process. 4777 checkAppInLaunchingProvidersLocked(app, true); 4778 // Take care of any services that are waiting for the process. 4779 mServices.processStartTimedOutLocked(app); 4780 killUnneededProcessLocked(app, "start timeout"); 4781 if (mBackupTarget != null && mBackupTarget.app.pid == pid) { 4782 Slog.w(TAG, "Unattached app died before backup, skipping"); 4783 try { 4784 IBackupManager bm = IBackupManager.Stub.asInterface( 4785 ServiceManager.getService(Context.BACKUP_SERVICE)); 4786 bm.agentDisconnected(app.info.packageName); 4787 } catch (RemoteException e) { 4788 // Can't happen; the backup manager is local 4789 } 4790 } 4791 if (isPendingBroadcastProcessLocked(pid)) { 4792 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 4793 skipPendingBroadcastLocked(pid); 4794 } 4795 } else { 4796 Slog.w(TAG, "Spurious process start timeout - pid not known for " + app); 4797 } 4798 } 4799 4800 private final boolean attachApplicationLocked(IApplicationThread thread, 4801 int pid) { 4802 4803 // Find the application record that is being attached... either via 4804 // the pid if we are running in multiple processes, or just pull the 4805 // next app record if we are emulating process with anonymous threads. 4806 ProcessRecord app; 4807 if (pid != MY_PID && pid >= 0) { 4808 synchronized (mPidsSelfLocked) { 4809 app = mPidsSelfLocked.get(pid); 4810 } 4811 } else { 4812 app = null; 4813 } 4814 4815 if (app == null) { 4816 Slog.w(TAG, "No pending application record for pid " + pid 4817 + " (IApplicationThread " + thread + "); dropping process"); 4818 EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid); 4819 if (pid > 0 && pid != MY_PID) { 4820 Process.killProcessQuiet(pid); 4821 } else { 4822 try { 4823 thread.scheduleExit(); 4824 } catch (Exception e) { 4825 // Ignore exceptions. 4826 } 4827 } 4828 return false; 4829 } 4830 4831 // If this application record is still attached to a previous 4832 // process, clean it up now. 4833 if (app.thread != null) { 4834 handleAppDiedLocked(app, true, true); 4835 } 4836 4837 // Tell the process all about itself. 4838 4839 if (localLOGV) Slog.v( 4840 TAG, "Binding process pid " + pid + " to record " + app); 4841 4842 final String processName = app.processName; 4843 try { 4844 AppDeathRecipient adr = new AppDeathRecipient( 4845 app, pid, thread); 4846 thread.asBinder().linkToDeath(adr, 0); 4847 app.deathRecipient = adr; 4848 } catch (RemoteException e) { 4849 app.resetPackageList(mProcessStats); 4850 startProcessLocked(app, "link fail", processName); 4851 return false; 4852 } 4853 4854 EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName); 4855 4856 app.makeActive(thread, mProcessStats); 4857 app.curAdj = app.setAdj = -100; 4858 app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT; 4859 app.forcingToForeground = null; 4860 app.foregroundServices = false; 4861 app.hasShownUi = false; 4862 app.debugging = false; 4863 app.cached = false; 4864 4865 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 4866 4867 boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info); 4868 List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null; 4869 4870 if (!normalMode) { 4871 Slog.i(TAG, "Launching preboot mode app: " + app); 4872 } 4873 4874 if (localLOGV) Slog.v( 4875 TAG, "New app record " + app 4876 + " thread=" + thread.asBinder() + " pid=" + pid); 4877 try { 4878 int testMode = IApplicationThread.DEBUG_OFF; 4879 if (mDebugApp != null && mDebugApp.equals(processName)) { 4880 testMode = mWaitForDebugger 4881 ? IApplicationThread.DEBUG_WAIT 4882 : IApplicationThread.DEBUG_ON; 4883 app.debugging = true; 4884 if (mDebugTransient) { 4885 mDebugApp = mOrigDebugApp; 4886 mWaitForDebugger = mOrigWaitForDebugger; 4887 } 4888 } 4889 String profileFile = app.instrumentationProfileFile; 4890 ParcelFileDescriptor profileFd = null; 4891 boolean profileAutoStop = false; 4892 if (mProfileApp != null && mProfileApp.equals(processName)) { 4893 mProfileProc = app; 4894 profileFile = mProfileFile; 4895 profileFd = mProfileFd; 4896 profileAutoStop = mAutoStopProfiler; 4897 } 4898 boolean enableOpenGlTrace = false; 4899 if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) { 4900 enableOpenGlTrace = true; 4901 mOpenGlTraceApp = null; 4902 } 4903 4904 // If the app is being launched for restore or full backup, set it up specially 4905 boolean isRestrictedBackupMode = false; 4906 if (mBackupTarget != null && mBackupAppName.equals(processName)) { 4907 isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE) 4908 || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL) 4909 || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL); 4910 } 4911 4912 ensurePackageDexOpt(app.instrumentationInfo != null 4913 ? app.instrumentationInfo.packageName 4914 : app.info.packageName); 4915 if (app.instrumentationClass != null) { 4916 ensurePackageDexOpt(app.instrumentationClass.getPackageName()); 4917 } 4918 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc " 4919 + processName + " with config " + mConfiguration); 4920 ApplicationInfo appInfo = app.instrumentationInfo != null 4921 ? app.instrumentationInfo : app.info; 4922 app.compat = compatibilityInfoForPackageLocked(appInfo); 4923 if (profileFd != null) { 4924 profileFd = profileFd.dup(); 4925 } 4926 thread.bindApplication(processName, appInfo, providers, 4927 app.instrumentationClass, profileFile, profileFd, profileAutoStop, 4928 app.instrumentationArguments, app.instrumentationWatcher, 4929 app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace, 4930 isRestrictedBackupMode || !normalMode, app.persistent, 4931 new Configuration(mConfiguration), app.compat, getCommonServicesLocked(), 4932 mCoreSettingsObserver.getCoreSettingsLocked()); 4933 updateLruProcessLocked(app, false, null); 4934 app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis(); 4935 } catch (Exception e) { 4936 // todo: Yikes! What should we do? For now we will try to 4937 // start another process, but that could easily get us in 4938 // an infinite loop of restarting processes... 4939 Slog.w(TAG, "Exception thrown during bind!", e); 4940 4941 app.resetPackageList(mProcessStats); 4942 app.unlinkDeathRecipient(); 4943 startProcessLocked(app, "bind fail", processName); 4944 return false; 4945 } 4946 4947 // Remove this record from the list of starting applications. 4948 mPersistentStartingProcesses.remove(app); 4949 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 4950 "Attach application locked removing on hold: " + app); 4951 mProcessesOnHold.remove(app); 4952 4953 boolean badApp = false; 4954 boolean didSomething = false; 4955 4956 // See if the top visible activity is waiting to run in this process... 4957 if (normalMode) { 4958 try { 4959 if (mStackSupervisor.attachApplicationLocked(app)) { 4960 didSomething = true; 4961 } 4962 } catch (Exception e) { 4963 badApp = true; 4964 } 4965 } 4966 4967 // Find any services that should be running in this process... 4968 if (!badApp) { 4969 try { 4970 didSomething |= mServices.attachApplicationLocked(app, processName); 4971 } catch (Exception e) { 4972 badApp = true; 4973 } 4974 } 4975 4976 // Check if a next-broadcast receiver is in this process... 4977 if (!badApp && isPendingBroadcastProcessLocked(pid)) { 4978 try { 4979 didSomething |= sendPendingBroadcastsLocked(app); 4980 } catch (Exception e) { 4981 // If the app died trying to launch the receiver we declare it 'bad' 4982 badApp = true; 4983 } 4984 } 4985 4986 // Check whether the next backup agent is in this process... 4987 if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) { 4988 if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app); 4989 ensurePackageDexOpt(mBackupTarget.appInfo.packageName); 4990 try { 4991 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo, 4992 compatibilityInfoForPackageLocked(mBackupTarget.appInfo), 4993 mBackupTarget.backupMode); 4994 } catch (Exception e) { 4995 Slog.w(TAG, "Exception scheduling backup agent creation: "); 4996 e.printStackTrace(); 4997 } 4998 } 4999 5000 if (badApp) { 5001 // todo: Also need to kill application to deal with all 5002 // kinds of exceptions. 5003 handleAppDiedLocked(app, false, true); 5004 return false; 5005 } 5006 5007 if (!didSomething) { 5008 updateOomAdjLocked(); 5009 } 5010 5011 return true; 5012 } 5013 5014 @Override 5015 public final void attachApplication(IApplicationThread thread) { 5016 synchronized (this) { 5017 int callingPid = Binder.getCallingPid(); 5018 final long origId = Binder.clearCallingIdentity(); 5019 attachApplicationLocked(thread, callingPid); 5020 Binder.restoreCallingIdentity(origId); 5021 } 5022 } 5023 5024 @Override 5025 public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) { 5026 final long origId = Binder.clearCallingIdentity(); 5027 synchronized (this) { 5028 ActivityStack stack = ActivityRecord.getStackLocked(token); 5029 if (stack != null) { 5030 ActivityRecord r = 5031 mStackSupervisor.activityIdleInternalLocked(token, false, config); 5032 if (stopProfiling) { 5033 if ((mProfileProc == r.app) && (mProfileFd != null)) { 5034 try { 5035 mProfileFd.close(); 5036 } catch (IOException e) { 5037 } 5038 clearProfilerLocked(); 5039 } 5040 } 5041 } 5042 } 5043 Binder.restoreCallingIdentity(origId); 5044 } 5045 5046 void enableScreenAfterBoot() { 5047 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN, 5048 SystemClock.uptimeMillis()); 5049 mWindowManager.enableScreenAfterBoot(); 5050 5051 synchronized (this) { 5052 updateEventDispatchingLocked(); 5053 } 5054 } 5055 5056 @Override 5057 public void showBootMessage(final CharSequence msg, final boolean always) { 5058 enforceNotIsolatedCaller("showBootMessage"); 5059 mWindowManager.showBootMessage(msg, always); 5060 } 5061 5062 @Override 5063 public void dismissKeyguardOnNextActivity() { 5064 enforceNotIsolatedCaller("dismissKeyguardOnNextActivity"); 5065 final long token = Binder.clearCallingIdentity(); 5066 try { 5067 synchronized (this) { 5068 if (DEBUG_LOCKSCREEN) logLockScreen(""); 5069 if (mLockScreenShown) { 5070 mLockScreenShown = false; 5071 comeOutOfSleepIfNeededLocked(); 5072 } 5073 mStackSupervisor.setDismissKeyguard(true); 5074 } 5075 } finally { 5076 Binder.restoreCallingIdentity(token); 5077 } 5078 } 5079 5080 final void finishBooting() { 5081 IntentFilter pkgFilter = new IntentFilter(); 5082 pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART); 5083 pkgFilter.addDataScheme("package"); 5084 mContext.registerReceiver(new BroadcastReceiver() { 5085 @Override 5086 public void onReceive(Context context, Intent intent) { 5087 String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES); 5088 if (pkgs != null) { 5089 for (String pkg : pkgs) { 5090 synchronized (ActivityManagerService.this) { 5091 if (forceStopPackageLocked(pkg, -1, false, false, false, false, 0, 5092 "finished booting")) { 5093 setResultCode(Activity.RESULT_OK); 5094 return; 5095 } 5096 } 5097 } 5098 } 5099 } 5100 }, pkgFilter); 5101 5102 synchronized (this) { 5103 // Ensure that any processes we had put on hold are now started 5104 // up. 5105 final int NP = mProcessesOnHold.size(); 5106 if (NP > 0) { 5107 ArrayList<ProcessRecord> procs = 5108 new ArrayList<ProcessRecord>(mProcessesOnHold); 5109 for (int ip=0; ip<NP; ip++) { 5110 if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: " 5111 + procs.get(ip)); 5112 startProcessLocked(procs.get(ip), "on-hold", null); 5113 } 5114 } 5115 5116 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 5117 // Start looking for apps that are abusing wake locks. 5118 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 5119 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 5120 // Tell anyone interested that we are done booting! 5121 SystemProperties.set("sys.boot_completed", "1"); 5122 SystemProperties.set("dev.bootcomplete", "1"); 5123 for (int i=0; i<mStartedUsers.size(); i++) { 5124 UserStartedState uss = mStartedUsers.valueAt(i); 5125 if (uss.mState == UserStartedState.STATE_BOOTING) { 5126 uss.mState = UserStartedState.STATE_RUNNING; 5127 final int userId = mStartedUsers.keyAt(i); 5128 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 5129 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 5130 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT); 5131 broadcastIntentLocked(null, null, intent, null, 5132 new IIntentReceiver.Stub() { 5133 @Override 5134 public void performReceive(Intent intent, int resultCode, 5135 String data, Bundle extras, boolean ordered, 5136 boolean sticky, int sendingUser) { 5137 synchronized (ActivityManagerService.this) { 5138 requestPssAllProcsLocked(SystemClock.uptimeMillis(), 5139 true, false); 5140 } 5141 } 5142 }, 5143 0, null, null, 5144 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, 5145 AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID, 5146 userId); 5147 } 5148 } 5149 } 5150 } 5151 } 5152 5153 final void ensureBootCompleted() { 5154 boolean booting; 5155 boolean enableScreen; 5156 synchronized (this) { 5157 booting = mBooting; 5158 mBooting = false; 5159 enableScreen = !mBooted; 5160 mBooted = true; 5161 } 5162 5163 if (booting) { 5164 finishBooting(); 5165 } 5166 5167 if (enableScreen) { 5168 enableScreenAfterBoot(); 5169 } 5170 } 5171 5172 @Override 5173 public final void activityResumed(IBinder token) { 5174 final long origId = Binder.clearCallingIdentity(); 5175 synchronized(this) { 5176 ActivityStack stack = ActivityRecord.getStackLocked(token); 5177 if (stack != null) { 5178 ActivityRecord.activityResumedLocked(token); 5179 } 5180 } 5181 Binder.restoreCallingIdentity(origId); 5182 } 5183 5184 @Override 5185 public final void activityPaused(IBinder token) { 5186 final long origId = Binder.clearCallingIdentity(); 5187 synchronized(this) { 5188 ActivityStack stack = ActivityRecord.getStackLocked(token); 5189 if (stack != null) { 5190 stack.activityPausedLocked(token, false); 5191 } 5192 } 5193 Binder.restoreCallingIdentity(origId); 5194 } 5195 5196 @Override 5197 public final void activityStopped(IBinder token, Bundle icicle, Bitmap thumbnail, 5198 CharSequence description) { 5199 if (localLOGV) Slog.v( 5200 TAG, "Activity stopped: token=" + token); 5201 5202 // Refuse possible leaked file descriptors 5203 if (icicle != null && icicle.hasFileDescriptors()) { 5204 throw new IllegalArgumentException("File descriptors passed in Bundle"); 5205 } 5206 5207 ActivityRecord r = null; 5208 5209 final long origId = Binder.clearCallingIdentity(); 5210 5211 synchronized (this) { 5212 r = ActivityRecord.isInStackLocked(token); 5213 if (r != null) { 5214 r.task.stack.activityStoppedLocked(r, icicle, thumbnail, description); 5215 } 5216 } 5217 5218 if (r != null) { 5219 sendPendingThumbnail(r, null, null, null, false); 5220 } 5221 5222 trimApplications(); 5223 5224 Binder.restoreCallingIdentity(origId); 5225 } 5226 5227 @Override 5228 public final void activityDestroyed(IBinder token) { 5229 if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token); 5230 synchronized (this) { 5231 ActivityStack stack = ActivityRecord.getStackLocked(token); 5232 if (stack != null) { 5233 stack.activityDestroyedLocked(token); 5234 } 5235 } 5236 } 5237 5238 @Override 5239 public String getCallingPackage(IBinder token) { 5240 synchronized (this) { 5241 ActivityRecord r = getCallingRecordLocked(token); 5242 return r != null ? r.info.packageName : null; 5243 } 5244 } 5245 5246 @Override 5247 public ComponentName getCallingActivity(IBinder token) { 5248 synchronized (this) { 5249 ActivityRecord r = getCallingRecordLocked(token); 5250 return r != null ? r.intent.getComponent() : null; 5251 } 5252 } 5253 5254 private ActivityRecord getCallingRecordLocked(IBinder token) { 5255 ActivityRecord r = ActivityRecord.isInStackLocked(token); 5256 if (r == null) { 5257 return null; 5258 } 5259 return r.resultTo; 5260 } 5261 5262 @Override 5263 public ComponentName getActivityClassForToken(IBinder token) { 5264 synchronized(this) { 5265 ActivityRecord r = ActivityRecord.isInStackLocked(token); 5266 if (r == null) { 5267 return null; 5268 } 5269 return r.intent.getComponent(); 5270 } 5271 } 5272 5273 @Override 5274 public String getPackageForToken(IBinder token) { 5275 synchronized(this) { 5276 ActivityRecord r = ActivityRecord.isInStackLocked(token); 5277 if (r == null) { 5278 return null; 5279 } 5280 return r.packageName; 5281 } 5282 } 5283 5284 @Override 5285 public IIntentSender getIntentSender(int type, 5286 String packageName, IBinder token, String resultWho, 5287 int requestCode, Intent[] intents, String[] resolvedTypes, 5288 int flags, Bundle options, int userId) { 5289 enforceNotIsolatedCaller("getIntentSender"); 5290 // Refuse possible leaked file descriptors 5291 if (intents != null) { 5292 if (intents.length < 1) { 5293 throw new IllegalArgumentException("Intents array length must be >= 1"); 5294 } 5295 for (int i=0; i<intents.length; i++) { 5296 Intent intent = intents[i]; 5297 if (intent != null) { 5298 if (intent.hasFileDescriptors()) { 5299 throw new IllegalArgumentException("File descriptors passed in Intent"); 5300 } 5301 if (type == ActivityManager.INTENT_SENDER_BROADCAST && 5302 (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 5303 throw new IllegalArgumentException( 5304 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 5305 } 5306 intents[i] = new Intent(intent); 5307 } 5308 } 5309 if (resolvedTypes != null && resolvedTypes.length != intents.length) { 5310 throw new IllegalArgumentException( 5311 "Intent array length does not match resolvedTypes length"); 5312 } 5313 } 5314 if (options != null) { 5315 if (options.hasFileDescriptors()) { 5316 throw new IllegalArgumentException("File descriptors passed in options"); 5317 } 5318 } 5319 5320 synchronized(this) { 5321 int callingUid = Binder.getCallingUid(); 5322 int origUserId = userId; 5323 userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId, 5324 type == ActivityManager.INTENT_SENDER_BROADCAST, false, 5325 "getIntentSender", null); 5326 if (origUserId == UserHandle.USER_CURRENT) { 5327 // We don't want to evaluate this until the pending intent is 5328 // actually executed. However, we do want to always do the 5329 // security checking for it above. 5330 userId = UserHandle.USER_CURRENT; 5331 } 5332 try { 5333 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 5334 int uid = AppGlobals.getPackageManager() 5335 .getPackageUid(packageName, UserHandle.getUserId(callingUid)); 5336 if (!UserHandle.isSameApp(callingUid, uid)) { 5337 String msg = "Permission Denial: getIntentSender() from pid=" 5338 + Binder.getCallingPid() 5339 + ", uid=" + Binder.getCallingUid() 5340 + ", (need uid=" + uid + ")" 5341 + " is not allowed to send as package " + packageName; 5342 Slog.w(TAG, msg); 5343 throw new SecurityException(msg); 5344 } 5345 } 5346 5347 return getIntentSenderLocked(type, packageName, callingUid, userId, 5348 token, resultWho, requestCode, intents, resolvedTypes, flags, options); 5349 5350 } catch (RemoteException e) { 5351 throw new SecurityException(e); 5352 } 5353 } 5354 } 5355 5356 IIntentSender getIntentSenderLocked(int type, String packageName, 5357 int callingUid, int userId, IBinder token, String resultWho, 5358 int requestCode, Intent[] intents, String[] resolvedTypes, int flags, 5359 Bundle options) { 5360 if (DEBUG_MU) 5361 Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid); 5362 ActivityRecord activity = null; 5363 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 5364 activity = ActivityRecord.isInStackLocked(token); 5365 if (activity == null) { 5366 return null; 5367 } 5368 if (activity.finishing) { 5369 return null; 5370 } 5371 } 5372 5373 final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0; 5374 final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0; 5375 final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0; 5376 flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT 5377 |PendingIntent.FLAG_UPDATE_CURRENT); 5378 5379 PendingIntentRecord.Key key = new PendingIntentRecord.Key( 5380 type, packageName, activity, resultWho, 5381 requestCode, intents, resolvedTypes, flags, options, userId); 5382 WeakReference<PendingIntentRecord> ref; 5383 ref = mIntentSenderRecords.get(key); 5384 PendingIntentRecord rec = ref != null ? ref.get() : null; 5385 if (rec != null) { 5386 if (!cancelCurrent) { 5387 if (updateCurrent) { 5388 if (rec.key.requestIntent != null) { 5389 rec.key.requestIntent.replaceExtras(intents != null ? 5390 intents[intents.length - 1] : null); 5391 } 5392 if (intents != null) { 5393 intents[intents.length-1] = rec.key.requestIntent; 5394 rec.key.allIntents = intents; 5395 rec.key.allResolvedTypes = resolvedTypes; 5396 } else { 5397 rec.key.allIntents = null; 5398 rec.key.allResolvedTypes = null; 5399 } 5400 } 5401 return rec; 5402 } 5403 rec.canceled = true; 5404 mIntentSenderRecords.remove(key); 5405 } 5406 if (noCreate) { 5407 return rec; 5408 } 5409 rec = new PendingIntentRecord(this, key, callingUid); 5410 mIntentSenderRecords.put(key, rec.ref); 5411 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 5412 if (activity.pendingResults == null) { 5413 activity.pendingResults 5414 = new HashSet<WeakReference<PendingIntentRecord>>(); 5415 } 5416 activity.pendingResults.add(rec.ref); 5417 } 5418 return rec; 5419 } 5420 5421 @Override 5422 public void cancelIntentSender(IIntentSender sender) { 5423 if (!(sender instanceof PendingIntentRecord)) { 5424 return; 5425 } 5426 synchronized(this) { 5427 PendingIntentRecord rec = (PendingIntentRecord)sender; 5428 try { 5429 int uid = AppGlobals.getPackageManager() 5430 .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId()); 5431 if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) { 5432 String msg = "Permission Denial: cancelIntentSender() from pid=" 5433 + Binder.getCallingPid() 5434 + ", uid=" + Binder.getCallingUid() 5435 + " is not allowed to cancel packges " 5436 + rec.key.packageName; 5437 Slog.w(TAG, msg); 5438 throw new SecurityException(msg); 5439 } 5440 } catch (RemoteException e) { 5441 throw new SecurityException(e); 5442 } 5443 cancelIntentSenderLocked(rec, true); 5444 } 5445 } 5446 5447 void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) { 5448 rec.canceled = true; 5449 mIntentSenderRecords.remove(rec.key); 5450 if (cleanActivity && rec.key.activity != null) { 5451 rec.key.activity.pendingResults.remove(rec.ref); 5452 } 5453 } 5454 5455 @Override 5456 public String getPackageForIntentSender(IIntentSender pendingResult) { 5457 if (!(pendingResult instanceof PendingIntentRecord)) { 5458 return null; 5459 } 5460 try { 5461 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5462 return res.key.packageName; 5463 } catch (ClassCastException e) { 5464 } 5465 return null; 5466 } 5467 5468 @Override 5469 public int getUidForIntentSender(IIntentSender sender) { 5470 if (sender instanceof PendingIntentRecord) { 5471 try { 5472 PendingIntentRecord res = (PendingIntentRecord)sender; 5473 return res.uid; 5474 } catch (ClassCastException e) { 5475 } 5476 } 5477 return -1; 5478 } 5479 5480 @Override 5481 public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) { 5482 if (!(pendingResult instanceof PendingIntentRecord)) { 5483 return false; 5484 } 5485 try { 5486 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5487 if (res.key.allIntents == null) { 5488 return false; 5489 } 5490 for (int i=0; i<res.key.allIntents.length; i++) { 5491 Intent intent = res.key.allIntents[i]; 5492 if (intent.getPackage() != null && intent.getComponent() != null) { 5493 return false; 5494 } 5495 } 5496 return true; 5497 } catch (ClassCastException e) { 5498 } 5499 return false; 5500 } 5501 5502 @Override 5503 public boolean isIntentSenderAnActivity(IIntentSender pendingResult) { 5504 if (!(pendingResult instanceof PendingIntentRecord)) { 5505 return false; 5506 } 5507 try { 5508 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5509 if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) { 5510 return true; 5511 } 5512 return false; 5513 } catch (ClassCastException e) { 5514 } 5515 return false; 5516 } 5517 5518 @Override 5519 public Intent getIntentForIntentSender(IIntentSender pendingResult) { 5520 if (!(pendingResult instanceof PendingIntentRecord)) { 5521 return null; 5522 } 5523 try { 5524 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5525 return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null; 5526 } catch (ClassCastException e) { 5527 } 5528 return null; 5529 } 5530 5531 @Override 5532 public void setProcessLimit(int max) { 5533 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 5534 "setProcessLimit()"); 5535 synchronized (this) { 5536 mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max; 5537 mProcessLimitOverride = max; 5538 } 5539 trimApplications(); 5540 } 5541 5542 @Override 5543 public int getProcessLimit() { 5544 synchronized (this) { 5545 return mProcessLimitOverride; 5546 } 5547 } 5548 5549 void foregroundTokenDied(ForegroundToken token) { 5550 synchronized (ActivityManagerService.this) { 5551 synchronized (mPidsSelfLocked) { 5552 ForegroundToken cur 5553 = mForegroundProcesses.get(token.pid); 5554 if (cur != token) { 5555 return; 5556 } 5557 mForegroundProcesses.remove(token.pid); 5558 ProcessRecord pr = mPidsSelfLocked.get(token.pid); 5559 if (pr == null) { 5560 return; 5561 } 5562 pr.forcingToForeground = null; 5563 pr.foregroundServices = false; 5564 } 5565 updateOomAdjLocked(); 5566 } 5567 } 5568 5569 @Override 5570 public void setProcessForeground(IBinder token, int pid, boolean isForeground) { 5571 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 5572 "setProcessForeground()"); 5573 synchronized(this) { 5574 boolean changed = false; 5575 5576 synchronized (mPidsSelfLocked) { 5577 ProcessRecord pr = mPidsSelfLocked.get(pid); 5578 if (pr == null && isForeground) { 5579 Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid); 5580 return; 5581 } 5582 ForegroundToken oldToken = mForegroundProcesses.get(pid); 5583 if (oldToken != null) { 5584 oldToken.token.unlinkToDeath(oldToken, 0); 5585 mForegroundProcesses.remove(pid); 5586 if (pr != null) { 5587 pr.forcingToForeground = null; 5588 } 5589 changed = true; 5590 } 5591 if (isForeground && token != null) { 5592 ForegroundToken newToken = new ForegroundToken() { 5593 @Override 5594 public void binderDied() { 5595 foregroundTokenDied(this); 5596 } 5597 }; 5598 newToken.pid = pid; 5599 newToken.token = token; 5600 try { 5601 token.linkToDeath(newToken, 0); 5602 mForegroundProcesses.put(pid, newToken); 5603 pr.forcingToForeground = token; 5604 changed = true; 5605 } catch (RemoteException e) { 5606 // If the process died while doing this, we will later 5607 // do the cleanup with the process death link. 5608 } 5609 } 5610 } 5611 5612 if (changed) { 5613 updateOomAdjLocked(); 5614 } 5615 } 5616 } 5617 5618 // ========================================================= 5619 // PERMISSIONS 5620 // ========================================================= 5621 5622 static class PermissionController extends IPermissionController.Stub { 5623 ActivityManagerService mActivityManagerService; 5624 PermissionController(ActivityManagerService activityManagerService) { 5625 mActivityManagerService = activityManagerService; 5626 } 5627 5628 @Override 5629 public boolean checkPermission(String permission, int pid, int uid) { 5630 return mActivityManagerService.checkPermission(permission, pid, 5631 uid) == PackageManager.PERMISSION_GRANTED; 5632 } 5633 } 5634 5635 class IntentFirewallInterface implements IntentFirewall.AMSInterface { 5636 @Override 5637 public int checkComponentPermission(String permission, int pid, int uid, 5638 int owningUid, boolean exported) { 5639 return ActivityManagerService.this.checkComponentPermission(permission, pid, uid, 5640 owningUid, exported); 5641 } 5642 5643 @Override 5644 public Object getAMSLock() { 5645 return ActivityManagerService.this; 5646 } 5647 } 5648 5649 /** 5650 * This can be called with or without the global lock held. 5651 */ 5652 int checkComponentPermission(String permission, int pid, int uid, 5653 int owningUid, boolean exported) { 5654 // We might be performing an operation on behalf of an indirect binder 5655 // invocation, e.g. via {@link #openContentUri}. Check and adjust the 5656 // client identity accordingly before proceeding. 5657 Identity tlsIdentity = sCallerIdentity.get(); 5658 if (tlsIdentity != null) { 5659 Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {" 5660 + tlsIdentity.pid + "," + tlsIdentity.uid + "}"); 5661 uid = tlsIdentity.uid; 5662 pid = tlsIdentity.pid; 5663 } 5664 5665 if (pid == MY_PID) { 5666 return PackageManager.PERMISSION_GRANTED; 5667 } 5668 5669 return ActivityManager.checkComponentPermission(permission, uid, 5670 owningUid, exported); 5671 } 5672 5673 /** 5674 * As the only public entry point for permissions checking, this method 5675 * can enforce the semantic that requesting a check on a null global 5676 * permission is automatically denied. (Internally a null permission 5677 * string is used when calling {@link #checkComponentPermission} in cases 5678 * when only uid-based security is needed.) 5679 * 5680 * This can be called with or without the global lock held. 5681 */ 5682 @Override 5683 public int checkPermission(String permission, int pid, int uid) { 5684 if (permission == null) { 5685 return PackageManager.PERMISSION_DENIED; 5686 } 5687 return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true); 5688 } 5689 5690 /** 5691 * Binder IPC calls go through the public entry point. 5692 * This can be called with or without the global lock held. 5693 */ 5694 int checkCallingPermission(String permission) { 5695 return checkPermission(permission, 5696 Binder.getCallingPid(), 5697 UserHandle.getAppId(Binder.getCallingUid())); 5698 } 5699 5700 /** 5701 * This can be called with or without the global lock held. 5702 */ 5703 void enforceCallingPermission(String permission, String func) { 5704 if (checkCallingPermission(permission) 5705 == PackageManager.PERMISSION_GRANTED) { 5706 return; 5707 } 5708 5709 String msg = "Permission Denial: " + func + " from pid=" 5710 + Binder.getCallingPid() 5711 + ", uid=" + Binder.getCallingUid() 5712 + " requires " + permission; 5713 Slog.w(TAG, msg); 5714 throw new SecurityException(msg); 5715 } 5716 5717 /** 5718 * Determine if UID is holding permissions required to access {@link Uri} in 5719 * the given {@link ProviderInfo}. Final permission checking is always done 5720 * in {@link ContentProvider}. 5721 */ 5722 private final boolean checkHoldingPermissionsLocked( 5723 IPackageManager pm, ProviderInfo pi, Uri uri, int uid, int modeFlags) { 5724 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5725 "checkHoldingPermissionsLocked: uri=" + uri + " uid=" + uid); 5726 5727 if (pi.applicationInfo.uid == uid) { 5728 return true; 5729 } else if (!pi.exported) { 5730 return false; 5731 } 5732 5733 boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0; 5734 boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0; 5735 try { 5736 // check if target holds top-level <provider> permissions 5737 if (!readMet && pi.readPermission != null 5738 && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) { 5739 readMet = true; 5740 } 5741 if (!writeMet && pi.writePermission != null 5742 && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) { 5743 writeMet = true; 5744 } 5745 5746 // track if unprotected read/write is allowed; any denied 5747 // <path-permission> below removes this ability 5748 boolean allowDefaultRead = pi.readPermission == null; 5749 boolean allowDefaultWrite = pi.writePermission == null; 5750 5751 // check if target holds any <path-permission> that match uri 5752 final PathPermission[] pps = pi.pathPermissions; 5753 if (pps != null) { 5754 final String path = uri.getPath(); 5755 int i = pps.length; 5756 while (i > 0 && (!readMet || !writeMet)) { 5757 i--; 5758 PathPermission pp = pps[i]; 5759 if (pp.match(path)) { 5760 if (!readMet) { 5761 final String pprperm = pp.getReadPermission(); 5762 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for " 5763 + pprperm + " for " + pp.getPath() 5764 + ": match=" + pp.match(path) 5765 + " check=" + pm.checkUidPermission(pprperm, uid)); 5766 if (pprperm != null) { 5767 if (pm.checkUidPermission(pprperm, uid) == PERMISSION_GRANTED) { 5768 readMet = true; 5769 } else { 5770 allowDefaultRead = false; 5771 } 5772 } 5773 } 5774 if (!writeMet) { 5775 final String ppwperm = pp.getWritePermission(); 5776 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm " 5777 + ppwperm + " for " + pp.getPath() 5778 + ": match=" + pp.match(path) 5779 + " check=" + pm.checkUidPermission(ppwperm, uid)); 5780 if (ppwperm != null) { 5781 if (pm.checkUidPermission(ppwperm, uid) == PERMISSION_GRANTED) { 5782 writeMet = true; 5783 } else { 5784 allowDefaultWrite = false; 5785 } 5786 } 5787 } 5788 } 5789 } 5790 } 5791 5792 // grant unprotected <provider> read/write, if not blocked by 5793 // <path-permission> above 5794 if (allowDefaultRead) readMet = true; 5795 if (allowDefaultWrite) writeMet = true; 5796 5797 } catch (RemoteException e) { 5798 return false; 5799 } 5800 5801 return readMet && writeMet; 5802 } 5803 5804 private ProviderInfo getProviderInfoLocked(String authority, int userHandle) { 5805 ProviderInfo pi = null; 5806 ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle); 5807 if (cpr != null) { 5808 pi = cpr.info; 5809 } else { 5810 try { 5811 pi = AppGlobals.getPackageManager().resolveContentProvider( 5812 authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle); 5813 } catch (RemoteException ex) { 5814 } 5815 } 5816 return pi; 5817 } 5818 5819 private UriPermission findUriPermissionLocked(int targetUid, Uri uri) { 5820 ArrayMap<Uri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid); 5821 if (targetUris != null) { 5822 return targetUris.get(uri); 5823 } else { 5824 return null; 5825 } 5826 } 5827 5828 private UriPermission findOrCreateUriPermissionLocked( 5829 String sourcePkg, String targetPkg, int targetUid, Uri uri) { 5830 ArrayMap<Uri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid); 5831 if (targetUris == null) { 5832 targetUris = Maps.newArrayMap(); 5833 mGrantedUriPermissions.put(targetUid, targetUris); 5834 } 5835 5836 UriPermission perm = targetUris.get(uri); 5837 if (perm == null) { 5838 perm = new UriPermission(sourcePkg, targetPkg, targetUid, uri); 5839 targetUris.put(uri, perm); 5840 } 5841 5842 return perm; 5843 } 5844 5845 private final boolean checkUriPermissionLocked( 5846 Uri uri, int uid, int modeFlags, int minStrength) { 5847 // Root gets to do everything. 5848 if (uid == 0) { 5849 return true; 5850 } 5851 ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(uid); 5852 if (perms == null) return false; 5853 UriPermission perm = perms.get(uri); 5854 if (perm == null) return false; 5855 return perm.getStrength(modeFlags) >= minStrength; 5856 } 5857 5858 @Override 5859 public int checkUriPermission(Uri uri, int pid, int uid, int modeFlags) { 5860 enforceNotIsolatedCaller("checkUriPermission"); 5861 5862 // Another redirected-binder-call permissions check as in 5863 // {@link checkComponentPermission}. 5864 Identity tlsIdentity = sCallerIdentity.get(); 5865 if (tlsIdentity != null) { 5866 uid = tlsIdentity.uid; 5867 pid = tlsIdentity.pid; 5868 } 5869 5870 // Our own process gets to do everything. 5871 if (pid == MY_PID) { 5872 return PackageManager.PERMISSION_GRANTED; 5873 } 5874 synchronized(this) { 5875 return checkUriPermissionLocked(uri, uid, modeFlags, UriPermission.STRENGTH_OWNED) 5876 ? PackageManager.PERMISSION_GRANTED 5877 : PackageManager.PERMISSION_DENIED; 5878 } 5879 } 5880 5881 /** 5882 * Check if the targetPkg can be granted permission to access uri by 5883 * the callingUid using the given modeFlags. Throws a security exception 5884 * if callingUid is not allowed to do this. Returns the uid of the target 5885 * if the URI permission grant should be performed; returns -1 if it is not 5886 * needed (for example targetPkg already has permission to access the URI). 5887 * If you already know the uid of the target, you can supply it in 5888 * lastTargetUid else set that to -1. 5889 */ 5890 int checkGrantUriPermissionLocked(int callingUid, String targetPkg, 5891 Uri uri, int modeFlags, int lastTargetUid) { 5892 final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0; 5893 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION 5894 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 5895 if (modeFlags == 0) { 5896 return -1; 5897 } 5898 5899 if (targetPkg != null) { 5900 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5901 "Checking grant " + targetPkg + " permission to " + uri); 5902 } 5903 5904 final IPackageManager pm = AppGlobals.getPackageManager(); 5905 5906 // If this is not a content: uri, we can't do anything with it. 5907 if (!ContentResolver.SCHEME_CONTENT.equals(uri.getScheme())) { 5908 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5909 "Can't grant URI permission for non-content URI: " + uri); 5910 return -1; 5911 } 5912 5913 final String authority = uri.getAuthority(); 5914 final ProviderInfo pi = getProviderInfoLocked(authority, UserHandle.getUserId(callingUid)); 5915 if (pi == null) { 5916 Slog.w(TAG, "No content provider found for permission check: " + uri.toSafeString()); 5917 return -1; 5918 } 5919 5920 int targetUid = lastTargetUid; 5921 if (targetUid < 0 && targetPkg != null) { 5922 try { 5923 targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid)); 5924 if (targetUid < 0) { 5925 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5926 "Can't grant URI permission no uid for: " + targetPkg); 5927 return -1; 5928 } 5929 } catch (RemoteException ex) { 5930 return -1; 5931 } 5932 } 5933 5934 if (targetUid >= 0) { 5935 // First... does the target actually need this permission? 5936 if (checkHoldingPermissionsLocked(pm, pi, uri, targetUid, modeFlags)) { 5937 // No need to grant the target this permission. 5938 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5939 "Target " + targetPkg + " already has full permission to " + uri); 5940 return -1; 5941 } 5942 } else { 5943 // First... there is no target package, so can anyone access it? 5944 boolean allowed = pi.exported; 5945 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) { 5946 if (pi.readPermission != null) { 5947 allowed = false; 5948 } 5949 } 5950 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) { 5951 if (pi.writePermission != null) { 5952 allowed = false; 5953 } 5954 } 5955 if (allowed) { 5956 return -1; 5957 } 5958 } 5959 5960 // Second... is the provider allowing granting of URI permissions? 5961 if (!pi.grantUriPermissions) { 5962 throw new SecurityException("Provider " + pi.packageName 5963 + "/" + pi.name 5964 + " does not allow granting of Uri permissions (uri " 5965 + uri + ")"); 5966 } 5967 if (pi.uriPermissionPatterns != null) { 5968 final int N = pi.uriPermissionPatterns.length; 5969 boolean allowed = false; 5970 for (int i=0; i<N; i++) { 5971 if (pi.uriPermissionPatterns[i] != null 5972 && pi.uriPermissionPatterns[i].match(uri.getPath())) { 5973 allowed = true; 5974 break; 5975 } 5976 } 5977 if (!allowed) { 5978 throw new SecurityException("Provider " + pi.packageName 5979 + "/" + pi.name 5980 + " does not allow granting of permission to path of Uri " 5981 + uri); 5982 } 5983 } 5984 5985 // Third... does the caller itself have permission to access 5986 // this uri? 5987 if (callingUid != Process.myUid()) { 5988 if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) { 5989 // Require they hold a strong enough Uri permission 5990 final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE 5991 : UriPermission.STRENGTH_OWNED; 5992 if (!checkUriPermissionLocked(uri, callingUid, modeFlags, minStrength)) { 5993 throw new SecurityException("Uid " + callingUid 5994 + " does not have permission to uri " + uri); 5995 } 5996 } 5997 } 5998 5999 return targetUid; 6000 } 6001 6002 @Override 6003 public int checkGrantUriPermission(int callingUid, String targetPkg, 6004 Uri uri, int modeFlags) { 6005 enforceNotIsolatedCaller("checkGrantUriPermission"); 6006 synchronized(this) { 6007 return checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1); 6008 } 6009 } 6010 6011 void grantUriPermissionUncheckedLocked( 6012 int targetUid, String targetPkg, Uri uri, int modeFlags, UriPermissionOwner owner) { 6013 final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0; 6014 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION 6015 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 6016 if (modeFlags == 0) { 6017 return; 6018 } 6019 6020 // So here we are: the caller has the assumed permission 6021 // to the uri, and the target doesn't. Let's now give this to 6022 // the target. 6023 6024 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6025 "Granting " + targetPkg + "/" + targetUid + " permission to " + uri); 6026 6027 final String authority = uri.getAuthority(); 6028 final ProviderInfo pi = getProviderInfoLocked(authority, UserHandle.getUserId(targetUid)); 6029 if (pi == null) { 6030 Slog.w(TAG, "No content provider found for grant: " + uri.toSafeString()); 6031 return; 6032 } 6033 6034 final UriPermission perm = findOrCreateUriPermissionLocked( 6035 pi.packageName, targetPkg, targetUid, uri); 6036 perm.grantModes(modeFlags, persistable, owner); 6037 } 6038 6039 void grantUriPermissionLocked(int callingUid, String targetPkg, Uri uri, 6040 int modeFlags, UriPermissionOwner owner) { 6041 if (targetPkg == null) { 6042 throw new NullPointerException("targetPkg"); 6043 } 6044 6045 int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1); 6046 if (targetUid < 0) { 6047 return; 6048 } 6049 6050 grantUriPermissionUncheckedLocked(targetUid, targetPkg, uri, modeFlags, owner); 6051 } 6052 6053 static class NeededUriGrants extends ArrayList<Uri> { 6054 final String targetPkg; 6055 final int targetUid; 6056 final int flags; 6057 6058 NeededUriGrants(String targetPkg, int targetUid, int flags) { 6059 this.targetPkg = targetPkg; 6060 this.targetUid = targetUid; 6061 this.flags = flags; 6062 } 6063 } 6064 6065 /** 6066 * Like checkGrantUriPermissionLocked, but takes an Intent. 6067 */ 6068 NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid, 6069 String targetPkg, Intent intent, int mode, NeededUriGrants needed) { 6070 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6071 "Checking URI perm to data=" + (intent != null ? intent.getData() : null) 6072 + " clip=" + (intent != null ? intent.getClipData() : null) 6073 + " from " + intent + "; flags=0x" 6074 + Integer.toHexString(intent != null ? intent.getFlags() : 0)); 6075 6076 if (targetPkg == null) { 6077 throw new NullPointerException("targetPkg"); 6078 } 6079 6080 if (intent == null) { 6081 return null; 6082 } 6083 Uri data = intent.getData(); 6084 ClipData clip = intent.getClipData(); 6085 if (data == null && clip == null) { 6086 return null; 6087 } 6088 6089 if (data != null) { 6090 int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, data, 6091 mode, needed != null ? needed.targetUid : -1); 6092 if (targetUid > 0) { 6093 if (needed == null) { 6094 needed = new NeededUriGrants(targetPkg, targetUid, mode); 6095 } 6096 needed.add(data); 6097 } 6098 } 6099 if (clip != null) { 6100 for (int i=0; i<clip.getItemCount(); i++) { 6101 Uri uri = clip.getItemAt(i).getUri(); 6102 if (uri != null) { 6103 int targetUid = -1; 6104 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri, 6105 mode, needed != null ? needed.targetUid : -1); 6106 if (targetUid > 0) { 6107 if (needed == null) { 6108 needed = new NeededUriGrants(targetPkg, targetUid, mode); 6109 } 6110 needed.add(uri); 6111 } 6112 } else { 6113 Intent clipIntent = clip.getItemAt(i).getIntent(); 6114 if (clipIntent != null) { 6115 NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked( 6116 callingUid, targetPkg, clipIntent, mode, needed); 6117 if (newNeeded != null) { 6118 needed = newNeeded; 6119 } 6120 } 6121 } 6122 } 6123 } 6124 6125 return needed; 6126 } 6127 6128 /** 6129 * Like grantUriPermissionUncheckedLocked, but takes an Intent. 6130 */ 6131 void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed, 6132 UriPermissionOwner owner) { 6133 if (needed != null) { 6134 for (int i=0; i<needed.size(); i++) { 6135 grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg, 6136 needed.get(i), needed.flags, owner); 6137 } 6138 } 6139 } 6140 6141 void grantUriPermissionFromIntentLocked(int callingUid, 6142 String targetPkg, Intent intent, UriPermissionOwner owner) { 6143 NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg, 6144 intent, intent != null ? intent.getFlags() : 0, null); 6145 if (needed == null) { 6146 return; 6147 } 6148 6149 grantUriPermissionUncheckedFromIntentLocked(needed, owner); 6150 } 6151 6152 @Override 6153 public void grantUriPermission(IApplicationThread caller, String targetPkg, 6154 Uri uri, int modeFlags) { 6155 enforceNotIsolatedCaller("grantUriPermission"); 6156 synchronized(this) { 6157 final ProcessRecord r = getRecordForAppLocked(caller); 6158 if (r == null) { 6159 throw new SecurityException("Unable to find app for caller " 6160 + caller 6161 + " when granting permission to uri " + uri); 6162 } 6163 if (targetPkg == null) { 6164 throw new IllegalArgumentException("null target"); 6165 } 6166 if (uri == null) { 6167 throw new IllegalArgumentException("null uri"); 6168 } 6169 6170 // Persistable only supported through Intents 6171 Preconditions.checkFlagsArgument(modeFlags, 6172 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 6173 6174 grantUriPermissionLocked(r.uid, targetPkg, uri, modeFlags, 6175 null); 6176 } 6177 } 6178 6179 void removeUriPermissionIfNeededLocked(UriPermission perm) { 6180 if ((perm.modeFlags&(Intent.FLAG_GRANT_READ_URI_PERMISSION 6181 |Intent.FLAG_GRANT_WRITE_URI_PERMISSION)) == 0) { 6182 ArrayMap<Uri, UriPermission> perms 6183 = mGrantedUriPermissions.get(perm.targetUid); 6184 if (perms != null) { 6185 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6186 "Removing " + perm.targetUid + " permission to " + perm.uri); 6187 perms.remove(perm.uri); 6188 if (perms.size() == 0) { 6189 mGrantedUriPermissions.remove(perm.targetUid); 6190 } 6191 } 6192 } 6193 } 6194 6195 private void revokeUriPermissionLocked(int callingUid, Uri uri, int modeFlags) { 6196 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + uri); 6197 6198 final IPackageManager pm = AppGlobals.getPackageManager(); 6199 final String authority = uri.getAuthority(); 6200 final ProviderInfo pi = getProviderInfoLocked(authority, UserHandle.getUserId(callingUid)); 6201 if (pi == null) { 6202 Slog.w(TAG, "No content provider found for permission revoke: " + uri.toSafeString()); 6203 return; 6204 } 6205 6206 // Does the caller have this permission on the URI? 6207 if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) { 6208 // Right now, if you are not the original owner of the permission, 6209 // you are not allowed to revoke it. 6210 //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) { 6211 throw new SecurityException("Uid " + callingUid 6212 + " does not have permission to uri " + uri); 6213 //} 6214 } 6215 6216 boolean persistChanged = false; 6217 6218 // Go through all of the permissions and remove any that match. 6219 final List<String> SEGMENTS = uri.getPathSegments(); 6220 if (SEGMENTS != null) { 6221 final int NS = SEGMENTS.size(); 6222 int N = mGrantedUriPermissions.size(); 6223 for (int i=0; i<N; i++) { 6224 ArrayMap<Uri, UriPermission> perms 6225 = mGrantedUriPermissions.valueAt(i); 6226 Iterator<UriPermission> it = perms.values().iterator(); 6227 toploop: 6228 while (it.hasNext()) { 6229 UriPermission perm = it.next(); 6230 Uri targetUri = perm.uri; 6231 if (!authority.equals(targetUri.getAuthority())) { 6232 continue; 6233 } 6234 List<String> targetSegments = targetUri.getPathSegments(); 6235 if (targetSegments == null) { 6236 continue; 6237 } 6238 if (targetSegments.size() < NS) { 6239 continue; 6240 } 6241 for (int j=0; j<NS; j++) { 6242 if (!SEGMENTS.get(j).equals(targetSegments.get(j))) { 6243 continue toploop; 6244 } 6245 } 6246 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6247 "Revoking " + perm.targetUid + " permission to " + perm.uri); 6248 persistChanged |= perm.clearModes(modeFlags, true); 6249 if (perm.modeFlags == 0) { 6250 it.remove(); 6251 } 6252 } 6253 if (perms.size() == 0) { 6254 mGrantedUriPermissions.remove( 6255 mGrantedUriPermissions.keyAt(i)); 6256 N--; 6257 i--; 6258 } 6259 } 6260 } 6261 6262 if (persistChanged) { 6263 schedulePersistUriGrants(); 6264 } 6265 } 6266 6267 @Override 6268 public void revokeUriPermission(IApplicationThread caller, Uri uri, 6269 int modeFlags) { 6270 enforceNotIsolatedCaller("revokeUriPermission"); 6271 synchronized(this) { 6272 final ProcessRecord r = getRecordForAppLocked(caller); 6273 if (r == null) { 6274 throw new SecurityException("Unable to find app for caller " 6275 + caller 6276 + " when revoking permission to uri " + uri); 6277 } 6278 if (uri == null) { 6279 Slog.w(TAG, "revokeUriPermission: null uri"); 6280 return; 6281 } 6282 6283 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION 6284 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 6285 if (modeFlags == 0) { 6286 return; 6287 } 6288 6289 final IPackageManager pm = AppGlobals.getPackageManager(); 6290 final String authority = uri.getAuthority(); 6291 final ProviderInfo pi = getProviderInfoLocked(authority, r.userId); 6292 if (pi == null) { 6293 Slog.w(TAG, "No content provider found for permission revoke: " 6294 + uri.toSafeString()); 6295 return; 6296 } 6297 6298 revokeUriPermissionLocked(r.uid, uri, modeFlags); 6299 } 6300 } 6301 6302 /** 6303 * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the 6304 * given package. 6305 * 6306 * @param packageName Package name to match, or {@code null} to apply to all 6307 * packages. 6308 * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply 6309 * to all users. 6310 * @param persistable If persistable grants should be removed. 6311 */ 6312 private void removeUriPermissionsForPackageLocked( 6313 String packageName, int userHandle, boolean persistable) { 6314 if (userHandle == UserHandle.USER_ALL && packageName == null) { 6315 throw new IllegalArgumentException("Must narrow by either package or user"); 6316 } 6317 6318 boolean persistChanged = false; 6319 6320 final int size = mGrantedUriPermissions.size(); 6321 for (int i = 0; i < size; i++) { 6322 // Only inspect grants matching user 6323 if (userHandle == UserHandle.USER_ALL 6324 || userHandle == UserHandle.getUserId(mGrantedUriPermissions.keyAt(i))) { 6325 final Iterator<UriPermission> it = mGrantedUriPermissions.valueAt(i) 6326 .values().iterator(); 6327 while (it.hasNext()) { 6328 final UriPermission perm = it.next(); 6329 6330 // Only inspect grants matching package 6331 if (packageName == null || perm.sourcePkg.equals(packageName) 6332 || perm.targetPkg.equals(packageName)) { 6333 persistChanged |= perm.clearModes(~0, persistable); 6334 6335 // Only remove when no modes remain; any persisted grants 6336 // will keep this alive. 6337 if (perm.modeFlags == 0) { 6338 it.remove(); 6339 } 6340 } 6341 } 6342 } 6343 } 6344 6345 if (persistChanged) { 6346 schedulePersistUriGrants(); 6347 } 6348 } 6349 6350 @Override 6351 public IBinder newUriPermissionOwner(String name) { 6352 enforceNotIsolatedCaller("newUriPermissionOwner"); 6353 synchronized(this) { 6354 UriPermissionOwner owner = new UriPermissionOwner(this, name); 6355 return owner.getExternalTokenLocked(); 6356 } 6357 } 6358 6359 @Override 6360 public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, 6361 Uri uri, int modeFlags) { 6362 synchronized(this) { 6363 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 6364 if (owner == null) { 6365 throw new IllegalArgumentException("Unknown owner: " + token); 6366 } 6367 if (fromUid != Binder.getCallingUid()) { 6368 if (Binder.getCallingUid() != Process.myUid()) { 6369 // Only system code can grant URI permissions on behalf 6370 // of other users. 6371 throw new SecurityException("nice try"); 6372 } 6373 } 6374 if (targetPkg == null) { 6375 throw new IllegalArgumentException("null target"); 6376 } 6377 if (uri == null) { 6378 throw new IllegalArgumentException("null uri"); 6379 } 6380 6381 grantUriPermissionLocked(fromUid, targetPkg, uri, modeFlags, owner); 6382 } 6383 } 6384 6385 @Override 6386 public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode) { 6387 synchronized(this) { 6388 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 6389 if (owner == null) { 6390 throw new IllegalArgumentException("Unknown owner: " + token); 6391 } 6392 6393 if (uri == null) { 6394 owner.removeUriPermissionsLocked(mode); 6395 } else { 6396 owner.removeUriPermissionLocked(uri, mode); 6397 } 6398 } 6399 } 6400 6401 private void schedulePersistUriGrants() { 6402 if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) { 6403 mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG), 6404 10 * DateUtils.SECOND_IN_MILLIS); 6405 } 6406 } 6407 6408 private void writeGrantedUriPermissions() { 6409 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()"); 6410 6411 // Snapshot permissions so we can persist without lock 6412 ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList(); 6413 synchronized (this) { 6414 final int size = mGrantedUriPermissions.size(); 6415 for (int i = 0 ; i < size; i++) { 6416 for (UriPermission perm : mGrantedUriPermissions.valueAt(i).values()) { 6417 if (perm.persistedModeFlags != 0) { 6418 persist.add(perm.snapshot()); 6419 } 6420 } 6421 } 6422 } 6423 6424 FileOutputStream fos = null; 6425 try { 6426 fos = mGrantFile.startWrite(); 6427 6428 XmlSerializer out = new FastXmlSerializer(); 6429 out.setOutput(fos, "utf-8"); 6430 out.startDocument(null, true); 6431 out.startTag(null, TAG_URI_GRANTS); 6432 for (UriPermission.Snapshot perm : persist) { 6433 out.startTag(null, TAG_URI_GRANT); 6434 writeIntAttribute(out, ATTR_USER_HANDLE, perm.userHandle); 6435 out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg); 6436 out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg); 6437 out.attribute(null, ATTR_URI, String.valueOf(perm.uri)); 6438 writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags); 6439 writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime); 6440 out.endTag(null, TAG_URI_GRANT); 6441 } 6442 out.endTag(null, TAG_URI_GRANTS); 6443 out.endDocument(); 6444 6445 mGrantFile.finishWrite(fos); 6446 } catch (IOException e) { 6447 if (fos != null) { 6448 mGrantFile.failWrite(fos); 6449 } 6450 } 6451 } 6452 6453 private void readGrantedUriPermissionsLocked() { 6454 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()"); 6455 6456 final long now = System.currentTimeMillis(); 6457 6458 FileInputStream fis = null; 6459 try { 6460 fis = mGrantFile.openRead(); 6461 final XmlPullParser in = Xml.newPullParser(); 6462 in.setInput(fis, null); 6463 6464 int type; 6465 while ((type = in.next()) != END_DOCUMENT) { 6466 final String tag = in.getName(); 6467 if (type == START_TAG) { 6468 if (TAG_URI_GRANT.equals(tag)) { 6469 final int userHandle = readIntAttribute(in, ATTR_USER_HANDLE); 6470 final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG); 6471 final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG); 6472 final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI)); 6473 final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS); 6474 final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now); 6475 6476 // Sanity check that provider still belongs to source package 6477 final ProviderInfo pi = getProviderInfoLocked( 6478 uri.getAuthority(), userHandle); 6479 if (pi != null && sourcePkg.equals(pi.packageName)) { 6480 int targetUid = -1; 6481 try { 6482 targetUid = AppGlobals.getPackageManager() 6483 .getPackageUid(targetPkg, userHandle); 6484 } catch (RemoteException e) { 6485 } 6486 if (targetUid != -1) { 6487 final UriPermission perm = findOrCreateUriPermissionLocked( 6488 sourcePkg, targetPkg, targetUid, uri); 6489 perm.initPersistedModes(modeFlags, createdTime); 6490 } 6491 } else { 6492 Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg 6493 + " but instead found " + pi); 6494 } 6495 } 6496 } 6497 } 6498 } catch (FileNotFoundException e) { 6499 // Missing grants is okay 6500 } catch (IOException e) { 6501 Log.wtf(TAG, "Failed reading Uri grants", e); 6502 } catch (XmlPullParserException e) { 6503 Log.wtf(TAG, "Failed reading Uri grants", e); 6504 } finally { 6505 IoUtils.closeQuietly(fis); 6506 } 6507 } 6508 6509 @Override 6510 public void takePersistableUriPermission(Uri uri, int modeFlags) { 6511 enforceNotIsolatedCaller("takePersistableUriPermission"); 6512 6513 Preconditions.checkFlagsArgument(modeFlags, 6514 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 6515 6516 synchronized (this) { 6517 final int callingUid = Binder.getCallingUid(); 6518 final UriPermission perm = findUriPermissionLocked(callingUid, uri); 6519 if (perm == null) { 6520 throw new SecurityException("No permission grant found for UID " + callingUid 6521 + " and Uri " + uri.toSafeString()); 6522 } 6523 6524 boolean persistChanged = perm.takePersistableModes(modeFlags); 6525 persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid); 6526 6527 if (persistChanged) { 6528 schedulePersistUriGrants(); 6529 } 6530 } 6531 } 6532 6533 @Override 6534 public void releasePersistableUriPermission(Uri uri, int modeFlags) { 6535 enforceNotIsolatedCaller("releasePersistableUriPermission"); 6536 6537 Preconditions.checkFlagsArgument(modeFlags, 6538 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 6539 6540 synchronized (this) { 6541 final int callingUid = Binder.getCallingUid(); 6542 6543 final UriPermission perm = findUriPermissionLocked(callingUid, uri); 6544 if (perm == null) { 6545 Slog.w(TAG, "No permission grant found for UID " + callingUid + " and Uri " 6546 + uri.toSafeString()); 6547 return; 6548 } 6549 6550 final boolean persistChanged = perm.releasePersistableModes(modeFlags); 6551 removeUriPermissionIfNeededLocked(perm); 6552 if (persistChanged) { 6553 schedulePersistUriGrants(); 6554 } 6555 } 6556 } 6557 6558 /** 6559 * Prune any older {@link UriPermission} for the given UID until outstanding 6560 * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}. 6561 * 6562 * @return if any mutations occured that require persisting. 6563 */ 6564 private boolean maybePrunePersistedUriGrantsLocked(int uid) { 6565 final ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(uid); 6566 if (perms == null) return false; 6567 if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false; 6568 6569 final ArrayList<UriPermission> persisted = Lists.newArrayList(); 6570 for (UriPermission perm : perms.values()) { 6571 if (perm.persistedModeFlags != 0) { 6572 persisted.add(perm); 6573 } 6574 } 6575 6576 final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS; 6577 if (trimCount <= 0) return false; 6578 6579 Collections.sort(persisted, new UriPermission.PersistedTimeComparator()); 6580 for (int i = 0; i < trimCount; i++) { 6581 final UriPermission perm = persisted.get(i); 6582 6583 if (DEBUG_URI_PERMISSION) { 6584 Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime); 6585 } 6586 6587 perm.releasePersistableModes(~0); 6588 removeUriPermissionIfNeededLocked(perm); 6589 } 6590 6591 return true; 6592 } 6593 6594 @Override 6595 public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions( 6596 String packageName, boolean incoming) { 6597 enforceNotIsolatedCaller("getPersistedUriPermissions"); 6598 Preconditions.checkNotNull(packageName, "packageName"); 6599 6600 final int callingUid = Binder.getCallingUid(); 6601 final IPackageManager pm = AppGlobals.getPackageManager(); 6602 try { 6603 final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid)); 6604 if (packageUid != callingUid) { 6605 throw new SecurityException( 6606 "Package " + packageName + " does not belong to calling UID " + callingUid); 6607 } 6608 } catch (RemoteException e) { 6609 throw new SecurityException("Failed to verify package name ownership"); 6610 } 6611 6612 final ArrayList<android.content.UriPermission> result = Lists.newArrayList(); 6613 synchronized (this) { 6614 if (incoming) { 6615 final ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(callingUid); 6616 if (perms == null) { 6617 Slog.w(TAG, "No permission grants found for " + packageName); 6618 } else { 6619 final int size = perms.size(); 6620 for (int i = 0; i < size; i++) { 6621 final UriPermission perm = perms.valueAt(i); 6622 if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) { 6623 result.add(perm.buildPersistedPublicApiObject()); 6624 } 6625 } 6626 } 6627 } else { 6628 final int size = mGrantedUriPermissions.size(); 6629 for (int i = 0; i < size; i++) { 6630 final ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 6631 final int permsSize = perms.size(); 6632 for (int j = 0; j < permsSize; j++) { 6633 final UriPermission perm = perms.valueAt(j); 6634 if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) { 6635 result.add(perm.buildPersistedPublicApiObject()); 6636 } 6637 } 6638 } 6639 } 6640 } 6641 return new ParceledListSlice<android.content.UriPermission>(result); 6642 } 6643 6644 @Override 6645 public void showWaitingForDebugger(IApplicationThread who, boolean waiting) { 6646 synchronized (this) { 6647 ProcessRecord app = 6648 who != null ? getRecordForAppLocked(who) : null; 6649 if (app == null) return; 6650 6651 Message msg = Message.obtain(); 6652 msg.what = WAIT_FOR_DEBUGGER_MSG; 6653 msg.obj = app; 6654 msg.arg1 = waiting ? 1 : 0; 6655 mHandler.sendMessage(msg); 6656 } 6657 } 6658 6659 @Override 6660 public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) { 6661 final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ); 6662 final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ); 6663 outInfo.availMem = Process.getFreeMemory(); 6664 outInfo.totalMem = Process.getTotalMemory(); 6665 outInfo.threshold = homeAppMem; 6666 outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2)); 6667 outInfo.hiddenAppThreshold = cachedAppMem; 6668 outInfo.secondaryServerThreshold = mProcessList.getMemLevel( 6669 ProcessList.SERVICE_ADJ); 6670 outInfo.visibleAppThreshold = mProcessList.getMemLevel( 6671 ProcessList.VISIBLE_APP_ADJ); 6672 outInfo.foregroundAppThreshold = mProcessList.getMemLevel( 6673 ProcessList.FOREGROUND_APP_ADJ); 6674 } 6675 6676 // ========================================================= 6677 // TASK MANAGEMENT 6678 // ========================================================= 6679 6680 @Override 6681 public List<RunningTaskInfo> getTasks(int maxNum, int flags, 6682 IThumbnailReceiver receiver) { 6683 ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>(); 6684 6685 PendingThumbnailsRecord pending = new PendingThumbnailsRecord(receiver); 6686 ActivityRecord topRecord = null; 6687 6688 synchronized(this) { 6689 if (localLOGV) Slog.v( 6690 TAG, "getTasks: max=" + maxNum + ", flags=" + flags 6691 + ", receiver=" + receiver); 6692 6693 if (checkCallingPermission(android.Manifest.permission.GET_TASKS) 6694 != PackageManager.PERMISSION_GRANTED) { 6695 if (receiver != null) { 6696 // If the caller wants to wait for pending thumbnails, 6697 // it ain't gonna get them. 6698 try { 6699 receiver.finished(); 6700 } catch (RemoteException ex) { 6701 } 6702 } 6703 String msg = "Permission Denial: getTasks() from pid=" 6704 + Binder.getCallingPid() 6705 + ", uid=" + Binder.getCallingUid() 6706 + " requires " + android.Manifest.permission.GET_TASKS; 6707 Slog.w(TAG, msg); 6708 throw new SecurityException(msg); 6709 } 6710 6711 // TODO: Improve with MRU list from all ActivityStacks. 6712 topRecord = mStackSupervisor.getTasksLocked(maxNum, receiver, pending, list); 6713 6714 if (!pending.pendingRecords.isEmpty()) { 6715 mPendingThumbnails.add(pending); 6716 } 6717 } 6718 6719 if (localLOGV) Slog.v(TAG, "We have pending thumbnails: " + pending); 6720 6721 if (topRecord != null) { 6722 if (localLOGV) Slog.v(TAG, "Requesting top thumbnail"); 6723 try { 6724 IApplicationThread topThumbnail = topRecord.app.thread; 6725 topThumbnail.requestThumbnail(topRecord.appToken); 6726 } catch (Exception e) { 6727 Slog.w(TAG, "Exception thrown when requesting thumbnail", e); 6728 sendPendingThumbnail(null, topRecord.appToken, null, null, true); 6729 } 6730 } 6731 6732 if (pending == null && receiver != null) { 6733 // In this case all thumbnails were available and the client 6734 // is being asked to be told when the remaining ones come in... 6735 // which is unusually, since the top-most currently running 6736 // activity should never have a canned thumbnail! Oh well. 6737 try { 6738 receiver.finished(); 6739 } catch (RemoteException ex) { 6740 } 6741 } 6742 6743 return list; 6744 } 6745 6746 TaskRecord getMostRecentTask() { 6747 return mRecentTasks.get(0); 6748 } 6749 6750 @Override 6751 public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, 6752 int flags, int userId) { 6753 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 6754 false, true, "getRecentTasks", null); 6755 6756 synchronized (this) { 6757 enforceCallingPermission(android.Manifest.permission.GET_TASKS, 6758 "getRecentTasks()"); 6759 final boolean detailed = checkCallingPermission( 6760 android.Manifest.permission.GET_DETAILED_TASKS) 6761 == PackageManager.PERMISSION_GRANTED; 6762 6763 IPackageManager pm = AppGlobals.getPackageManager(); 6764 6765 final int N = mRecentTasks.size(); 6766 ArrayList<ActivityManager.RecentTaskInfo> res 6767 = new ArrayList<ActivityManager.RecentTaskInfo>( 6768 maxNum < N ? maxNum : N); 6769 for (int i=0; i<N && maxNum > 0; i++) { 6770 TaskRecord tr = mRecentTasks.get(i); 6771 // Only add calling user's recent tasks 6772 if (tr.userId != userId) continue; 6773 // Return the entry if desired by the caller. We always return 6774 // the first entry, because callers always expect this to be the 6775 // foreground app. We may filter others if the caller has 6776 // not supplied RECENT_WITH_EXCLUDED and there is some reason 6777 // we should exclude the entry. 6778 6779 if (i == 0 6780 || ((flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0) 6781 || (tr.intent == null) 6782 || ((tr.intent.getFlags() 6783 &Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0)) { 6784 ActivityManager.RecentTaskInfo rti 6785 = new ActivityManager.RecentTaskInfo(); 6786 rti.id = tr.numActivities > 0 ? tr.taskId : -1; 6787 rti.persistentId = tr.taskId; 6788 rti.baseIntent = new Intent( 6789 tr.intent != null ? tr.intent : tr.affinityIntent); 6790 if (!detailed) { 6791 rti.baseIntent.replaceExtras((Bundle)null); 6792 } 6793 rti.origActivity = tr.origActivity; 6794 rti.description = tr.lastDescription; 6795 rti.stackId = tr.stack.mStackId; 6796 6797 if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) { 6798 // Check whether this activity is currently available. 6799 try { 6800 if (rti.origActivity != null) { 6801 if (pm.getActivityInfo(rti.origActivity, 0, userId) 6802 == null) { 6803 continue; 6804 } 6805 } else if (rti.baseIntent != null) { 6806 if (pm.queryIntentActivities(rti.baseIntent, 6807 null, 0, userId) == null) { 6808 continue; 6809 } 6810 } 6811 } catch (RemoteException e) { 6812 // Will never happen. 6813 } 6814 } 6815 6816 res.add(rti); 6817 maxNum--; 6818 } 6819 } 6820 return res; 6821 } 6822 } 6823 6824 private TaskRecord recentTaskForIdLocked(int id) { 6825 final int N = mRecentTasks.size(); 6826 for (int i=0; i<N; i++) { 6827 TaskRecord tr = mRecentTasks.get(i); 6828 if (tr.taskId == id) { 6829 return tr; 6830 } 6831 } 6832 return null; 6833 } 6834 6835 @Override 6836 public ActivityManager.TaskThumbnails getTaskThumbnails(int id) { 6837 synchronized (this) { 6838 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER, 6839 "getTaskThumbnails()"); 6840 TaskRecord tr = recentTaskForIdLocked(id); 6841 if (tr != null) { 6842 return tr.getTaskThumbnailsLocked(); 6843 } 6844 } 6845 return null; 6846 } 6847 6848 @Override 6849 public Bitmap getTaskTopThumbnail(int id) { 6850 synchronized (this) { 6851 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER, 6852 "getTaskTopThumbnail()"); 6853 TaskRecord tr = recentTaskForIdLocked(id); 6854 if (tr != null) { 6855 return tr.getTaskTopThumbnailLocked(); 6856 } 6857 } 6858 return null; 6859 } 6860 6861 @Override 6862 public boolean removeSubTask(int taskId, int subTaskIndex) { 6863 synchronized (this) { 6864 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, 6865 "removeSubTask()"); 6866 long ident = Binder.clearCallingIdentity(); 6867 try { 6868 TaskRecord tr = recentTaskForIdLocked(taskId); 6869 if (tr != null) { 6870 return tr.removeTaskActivitiesLocked(subTaskIndex, true) != null; 6871 } 6872 return false; 6873 } finally { 6874 Binder.restoreCallingIdentity(ident); 6875 } 6876 } 6877 } 6878 6879 private void killUnneededProcessLocked(ProcessRecord pr, String reason) { 6880 if (!pr.killedByAm) { 6881 Slog.i(TAG, "Killing " + pr.toShortString() + " (adj " + pr.setAdj + "): " + reason); 6882 EventLog.writeEvent(EventLogTags.AM_KILL, pr.userId, pr.pid, 6883 pr.processName, pr.setAdj, reason); 6884 pr.killedByAm = true; 6885 Process.killProcessQuiet(pr.pid); 6886 } 6887 } 6888 6889 private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) { 6890 tr.disposeThumbnail(); 6891 mRecentTasks.remove(tr); 6892 final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0; 6893 Intent baseIntent = new Intent( 6894 tr.intent != null ? tr.intent : tr.affinityIntent); 6895 ComponentName component = baseIntent.getComponent(); 6896 if (component == null) { 6897 Slog.w(TAG, "Now component for base intent of task: " + tr); 6898 return; 6899 } 6900 6901 // Find any running services associated with this app. 6902 mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent); 6903 6904 if (killProcesses) { 6905 // Find any running processes associated with this app. 6906 final String pkg = component.getPackageName(); 6907 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 6908 ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap(); 6909 for (int i=0; i<pmap.size(); i++) { 6910 SparseArray<ProcessRecord> uids = pmap.valueAt(i); 6911 for (int j=0; j<uids.size(); j++) { 6912 ProcessRecord proc = uids.valueAt(j); 6913 if (proc.userId != tr.userId) { 6914 continue; 6915 } 6916 if (!proc.pkgList.containsKey(pkg)) { 6917 continue; 6918 } 6919 procs.add(proc); 6920 } 6921 } 6922 6923 // Kill the running processes. 6924 for (int i=0; i<procs.size(); i++) { 6925 ProcessRecord pr = procs.get(i); 6926 if (pr == mHomeProcess) { 6927 // Don't kill the home process along with tasks from the same package. 6928 continue; 6929 } 6930 if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 6931 killUnneededProcessLocked(pr, "remove task"); 6932 } else { 6933 pr.waitingToKill = "remove task"; 6934 } 6935 } 6936 } 6937 } 6938 6939 @Override 6940 public boolean removeTask(int taskId, int flags) { 6941 synchronized (this) { 6942 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, 6943 "removeTask()"); 6944 long ident = Binder.clearCallingIdentity(); 6945 try { 6946 TaskRecord tr = recentTaskForIdLocked(taskId); 6947 if (tr != null) { 6948 ActivityRecord r = tr.removeTaskActivitiesLocked(-1, false); 6949 if (r != null) { 6950 cleanUpRemovedTaskLocked(tr, flags); 6951 return true; 6952 } 6953 if (tr.mActivities.size() == 0) { 6954 // Caller is just removing a recent task that is 6955 // not actively running. That is easy! 6956 cleanUpRemovedTaskLocked(tr, flags); 6957 return true; 6958 } 6959 Slog.w(TAG, "removeTask: task " + taskId 6960 + " does not have activities to remove, " 6961 + " but numActivities=" + tr.numActivities 6962 + ": " + tr); 6963 } 6964 } finally { 6965 Binder.restoreCallingIdentity(ident); 6966 } 6967 } 6968 return false; 6969 } 6970 6971 /** 6972 * TODO: Add mController hook 6973 */ 6974 @Override 6975 public void moveTaskToFront(int task, int flags, Bundle options) { 6976 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 6977 "moveTaskToFront()"); 6978 6979 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving task=" + task); 6980 synchronized(this) { 6981 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 6982 Binder.getCallingUid(), "Task to front")) { 6983 ActivityOptions.abort(options); 6984 return; 6985 } 6986 final long origId = Binder.clearCallingIdentity(); 6987 try { 6988 mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options); 6989 } finally { 6990 Binder.restoreCallingIdentity(origId); 6991 } 6992 ActivityOptions.abort(options); 6993 } 6994 } 6995 6996 @Override 6997 public void moveTaskToBack(int taskId) { 6998 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 6999 "moveTaskToBack()"); 7000 7001 synchronized(this) { 7002 TaskRecord tr = recentTaskForIdLocked(taskId); 7003 if (tr != null) { 7004 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr); 7005 ActivityStack stack = tr.stack; 7006 if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) { 7007 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 7008 Binder.getCallingUid(), "Task to back")) { 7009 return; 7010 } 7011 } 7012 final long origId = Binder.clearCallingIdentity(); 7013 try { 7014 stack.moveTaskToBackLocked(taskId, null); 7015 } finally { 7016 Binder.restoreCallingIdentity(origId); 7017 } 7018 } 7019 } 7020 } 7021 7022 /** 7023 * Moves an activity, and all of the other activities within the same task, to the bottom 7024 * of the history stack. The activity's order within the task is unchanged. 7025 * 7026 * @param token A reference to the activity we wish to move 7027 * @param nonRoot If false then this only works if the activity is the root 7028 * of a task; if true it will work for any activity in a task. 7029 * @return Returns true if the move completed, false if not. 7030 */ 7031 @Override 7032 public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) { 7033 enforceNotIsolatedCaller("moveActivityTaskToBack"); 7034 synchronized(this) { 7035 final long origId = Binder.clearCallingIdentity(); 7036 int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot); 7037 if (taskId >= 0) { 7038 return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null); 7039 } 7040 Binder.restoreCallingIdentity(origId); 7041 } 7042 return false; 7043 } 7044 7045 @Override 7046 public void moveTaskBackwards(int task) { 7047 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 7048 "moveTaskBackwards()"); 7049 7050 synchronized(this) { 7051 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 7052 Binder.getCallingUid(), "Task backwards")) { 7053 return; 7054 } 7055 final long origId = Binder.clearCallingIdentity(); 7056 moveTaskBackwardsLocked(task); 7057 Binder.restoreCallingIdentity(origId); 7058 } 7059 } 7060 7061 private final void moveTaskBackwardsLocked(int task) { 7062 Slog.e(TAG, "moveTaskBackwards not yet implemented!"); 7063 } 7064 7065 @Override 7066 public IBinder getHomeActivityToken() throws RemoteException { 7067 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7068 "getHomeActivityToken()"); 7069 synchronized (this) { 7070 return mStackSupervisor.getHomeActivityToken(); 7071 } 7072 } 7073 7074 @Override 7075 public IActivityContainer createActivityContainer(IBinder parentActivityToken, 7076 IActivityContainerCallback callback) throws RemoteException { 7077 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7078 "createActivityContainer()"); 7079 synchronized (this) { 7080 if (parentActivityToken == null) { 7081 throw new IllegalArgumentException("parent token must not be null"); 7082 } 7083 ActivityRecord r = ActivityRecord.forToken(parentActivityToken); 7084 if (r == null) { 7085 return null; 7086 } 7087 if (callback == null) { 7088 throw new IllegalArgumentException("callback must not be null"); 7089 } 7090 return mStackSupervisor.createActivityContainer(r, callback); 7091 } 7092 } 7093 7094 @Override 7095 public void deleteActivityContainer(IActivityContainer container) throws RemoteException { 7096 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7097 "deleteActivityContainer()"); 7098 synchronized (this) { 7099 mStackSupervisor.deleteActivityContainer(container); 7100 } 7101 } 7102 7103 @Override 7104 public IActivityContainer getEnclosingActivityContainer(IBinder activityToken) 7105 throws RemoteException { 7106 synchronized (this) { 7107 ActivityStack stack = ActivityRecord.getStackLocked(activityToken); 7108 if (stack != null) { 7109 return stack.mActivityContainer; 7110 } 7111 return null; 7112 } 7113 } 7114 7115 @Override 7116 public void moveTaskToStack(int taskId, int stackId, boolean toTop) { 7117 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7118 "moveTaskToStack()"); 7119 if (stackId == HOME_STACK_ID) { 7120 Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack", 7121 new RuntimeException("here").fillInStackTrace()); 7122 } 7123 synchronized (this) { 7124 long ident = Binder.clearCallingIdentity(); 7125 try { 7126 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId=" 7127 + stackId + " toTop=" + toTop); 7128 mStackSupervisor.moveTaskToStack(taskId, stackId, toTop); 7129 } finally { 7130 Binder.restoreCallingIdentity(ident); 7131 } 7132 } 7133 } 7134 7135 @Override 7136 public void resizeStack(int stackBoxId, Rect bounds) { 7137 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7138 "resizeStackBox()"); 7139 long ident = Binder.clearCallingIdentity(); 7140 try { 7141 mWindowManager.resizeStack(stackBoxId, bounds); 7142 } finally { 7143 Binder.restoreCallingIdentity(ident); 7144 } 7145 } 7146 7147 @Override 7148 public List<StackInfo> getAllStackInfos() { 7149 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7150 "getAllStackInfos()"); 7151 long ident = Binder.clearCallingIdentity(); 7152 try { 7153 synchronized (this) { 7154 return mStackSupervisor.getAllStackInfosLocked(); 7155 } 7156 } finally { 7157 Binder.restoreCallingIdentity(ident); 7158 } 7159 } 7160 7161 @Override 7162 public StackInfo getStackInfo(int stackId) { 7163 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7164 "getStackInfo()"); 7165 long ident = Binder.clearCallingIdentity(); 7166 try { 7167 synchronized (this) { 7168 return mStackSupervisor.getStackInfoLocked(stackId); 7169 } 7170 } finally { 7171 Binder.restoreCallingIdentity(ident); 7172 } 7173 } 7174 7175 @Override 7176 public int getTaskForActivity(IBinder token, boolean onlyRoot) { 7177 synchronized(this) { 7178 return ActivityRecord.getTaskForActivityLocked(token, onlyRoot); 7179 } 7180 } 7181 7182 // ========================================================= 7183 // THUMBNAILS 7184 // ========================================================= 7185 7186 public void reportThumbnail(IBinder token, 7187 Bitmap thumbnail, CharSequence description) { 7188 //System.out.println("Report thumbnail for " + token + ": " + thumbnail); 7189 final long origId = Binder.clearCallingIdentity(); 7190 sendPendingThumbnail(null, token, thumbnail, description, true); 7191 Binder.restoreCallingIdentity(origId); 7192 } 7193 7194 final void sendPendingThumbnail(ActivityRecord r, IBinder token, 7195 Bitmap thumbnail, CharSequence description, boolean always) { 7196 TaskRecord task; 7197 ArrayList<PendingThumbnailsRecord> receivers = null; 7198 7199 //System.out.println("Send pending thumbnail: " + r); 7200 7201 synchronized(this) { 7202 if (r == null) { 7203 r = ActivityRecord.isInStackLocked(token); 7204 if (r == null) { 7205 return; 7206 } 7207 } 7208 if (thumbnail == null && r.thumbHolder != null) { 7209 thumbnail = r.thumbHolder.lastThumbnail; 7210 description = r.thumbHolder.lastDescription; 7211 } 7212 if (thumbnail == null && !always) { 7213 // If there is no thumbnail, and this entry is not actually 7214 // going away, then abort for now and pick up the next 7215 // thumbnail we get. 7216 return; 7217 } 7218 task = r.task; 7219 7220 int N = mPendingThumbnails.size(); 7221 int i=0; 7222 while (i<N) { 7223 PendingThumbnailsRecord pr = mPendingThumbnails.get(i); 7224 //System.out.println("Looking in " + pr.pendingRecords); 7225 if (pr.pendingRecords.remove(r)) { 7226 if (receivers == null) { 7227 receivers = new ArrayList<PendingThumbnailsRecord>(); 7228 } 7229 receivers.add(pr); 7230 if (pr.pendingRecords.size() == 0) { 7231 pr.finished = true; 7232 mPendingThumbnails.remove(i); 7233 N--; 7234 continue; 7235 } 7236 } 7237 i++; 7238 } 7239 } 7240 7241 if (receivers != null) { 7242 final int N = receivers.size(); 7243 for (int i=0; i<N; i++) { 7244 try { 7245 PendingThumbnailsRecord pr = receivers.get(i); 7246 pr.receiver.newThumbnail( 7247 task != null ? task.taskId : -1, thumbnail, description); 7248 if (pr.finished) { 7249 pr.receiver.finished(); 7250 } 7251 } catch (Exception e) { 7252 Slog.w(TAG, "Exception thrown when sending thumbnail", e); 7253 } 7254 } 7255 } 7256 } 7257 7258 // ========================================================= 7259 // CONTENT PROVIDERS 7260 // ========================================================= 7261 7262 private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) { 7263 List<ProviderInfo> providers = null; 7264 try { 7265 providers = AppGlobals.getPackageManager(). 7266 queryContentProviders(app.processName, app.uid, 7267 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS); 7268 } catch (RemoteException ex) { 7269 } 7270 if (DEBUG_MU) 7271 Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid); 7272 int userId = app.userId; 7273 if (providers != null) { 7274 int N = providers.size(); 7275 app.pubProviders.ensureCapacity(N + app.pubProviders.size()); 7276 for (int i=0; i<N; i++) { 7277 ProviderInfo cpi = 7278 (ProviderInfo)providers.get(i); 7279 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo, 7280 cpi.name, cpi.flags); 7281 if (singleton && UserHandle.getUserId(app.uid) != 0) { 7282 // This is a singleton provider, but a user besides the 7283 // default user is asking to initialize a process it runs 7284 // in... well, no, it doesn't actually run in this process, 7285 // it runs in the process of the default user. Get rid of it. 7286 providers.remove(i); 7287 N--; 7288 i--; 7289 continue; 7290 } 7291 7292 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 7293 ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId); 7294 if (cpr == null) { 7295 cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton); 7296 mProviderMap.putProviderByClass(comp, cpr); 7297 } 7298 if (DEBUG_MU) 7299 Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid); 7300 app.pubProviders.put(cpi.name, cpr); 7301 if (!cpi.multiprocess || !"android".equals(cpi.packageName)) { 7302 // Don't add this if it is a platform component that is marked 7303 // to run in multiple processes, because this is actually 7304 // part of the framework so doesn't make sense to track as a 7305 // separate apk in the process. 7306 app.addPackage(cpi.applicationInfo.packageName, mProcessStats); 7307 } 7308 ensurePackageDexOpt(cpi.applicationInfo.packageName); 7309 } 7310 } 7311 return providers; 7312 } 7313 7314 /** 7315 * Check if {@link ProcessRecord} has a possible chance at accessing the 7316 * given {@link ProviderInfo}. Final permission checking is always done 7317 * in {@link ContentProvider}. 7318 */ 7319 private final String checkContentProviderPermissionLocked( 7320 ProviderInfo cpi, ProcessRecord r) { 7321 final int callingPid = (r != null) ? r.pid : Binder.getCallingPid(); 7322 final int callingUid = (r != null) ? r.uid : Binder.getCallingUid(); 7323 if (checkComponentPermission(cpi.readPermission, callingPid, callingUid, 7324 cpi.applicationInfo.uid, cpi.exported) 7325 == PackageManager.PERMISSION_GRANTED) { 7326 return null; 7327 } 7328 if (checkComponentPermission(cpi.writePermission, callingPid, callingUid, 7329 cpi.applicationInfo.uid, cpi.exported) 7330 == PackageManager.PERMISSION_GRANTED) { 7331 return null; 7332 } 7333 7334 PathPermission[] pps = cpi.pathPermissions; 7335 if (pps != null) { 7336 int i = pps.length; 7337 while (i > 0) { 7338 i--; 7339 PathPermission pp = pps[i]; 7340 if (checkComponentPermission(pp.getReadPermission(), callingPid, callingUid, 7341 cpi.applicationInfo.uid, cpi.exported) 7342 == PackageManager.PERMISSION_GRANTED) { 7343 return null; 7344 } 7345 if (checkComponentPermission(pp.getWritePermission(), callingPid, callingUid, 7346 cpi.applicationInfo.uid, cpi.exported) 7347 == PackageManager.PERMISSION_GRANTED) { 7348 return null; 7349 } 7350 } 7351 } 7352 7353 ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(callingUid); 7354 if (perms != null) { 7355 for (Map.Entry<Uri, UriPermission> uri : perms.entrySet()) { 7356 if (uri.getKey().getAuthority().equals(cpi.authority)) { 7357 return null; 7358 } 7359 } 7360 } 7361 7362 String msg; 7363 if (!cpi.exported) { 7364 msg = "Permission Denial: opening provider " + cpi.name 7365 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 7366 + ", uid=" + callingUid + ") that is not exported from uid " 7367 + cpi.applicationInfo.uid; 7368 } else { 7369 msg = "Permission Denial: opening provider " + cpi.name 7370 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 7371 + ", uid=" + callingUid + ") requires " 7372 + cpi.readPermission + " or " + cpi.writePermission; 7373 } 7374 Slog.w(TAG, msg); 7375 return msg; 7376 } 7377 7378 ContentProviderConnection incProviderCountLocked(ProcessRecord r, 7379 final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 7380 if (r != null) { 7381 for (int i=0; i<r.conProviders.size(); i++) { 7382 ContentProviderConnection conn = r.conProviders.get(i); 7383 if (conn.provider == cpr) { 7384 if (DEBUG_PROVIDER) Slog.v(TAG, 7385 "Adding provider requested by " 7386 + r.processName + " from process " 7387 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 7388 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 7389 if (stable) { 7390 conn.stableCount++; 7391 conn.numStableIncs++; 7392 } else { 7393 conn.unstableCount++; 7394 conn.numUnstableIncs++; 7395 } 7396 return conn; 7397 } 7398 } 7399 ContentProviderConnection conn = new ContentProviderConnection(cpr, r); 7400 if (stable) { 7401 conn.stableCount = 1; 7402 conn.numStableIncs = 1; 7403 } else { 7404 conn.unstableCount = 1; 7405 conn.numUnstableIncs = 1; 7406 } 7407 cpr.connections.add(conn); 7408 r.conProviders.add(conn); 7409 return conn; 7410 } 7411 cpr.addExternalProcessHandleLocked(externalProcessToken); 7412 return null; 7413 } 7414 7415 boolean decProviderCountLocked(ContentProviderConnection conn, 7416 ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 7417 if (conn != null) { 7418 cpr = conn.provider; 7419 if (DEBUG_PROVIDER) Slog.v(TAG, 7420 "Removing provider requested by " 7421 + conn.client.processName + " from process " 7422 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 7423 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 7424 if (stable) { 7425 conn.stableCount--; 7426 } else { 7427 conn.unstableCount--; 7428 } 7429 if (conn.stableCount == 0 && conn.unstableCount == 0) { 7430 cpr.connections.remove(conn); 7431 conn.client.conProviders.remove(conn); 7432 return true; 7433 } 7434 return false; 7435 } 7436 cpr.removeExternalProcessHandleLocked(externalProcessToken); 7437 return false; 7438 } 7439 7440 private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller, 7441 String name, IBinder token, boolean stable, int userId) { 7442 ContentProviderRecord cpr; 7443 ContentProviderConnection conn = null; 7444 ProviderInfo cpi = null; 7445 7446 synchronized(this) { 7447 ProcessRecord r = null; 7448 if (caller != null) { 7449 r = getRecordForAppLocked(caller); 7450 if (r == null) { 7451 throw new SecurityException( 7452 "Unable to find app for caller " + caller 7453 + " (pid=" + Binder.getCallingPid() 7454 + ") when getting content provider " + name); 7455 } 7456 } 7457 7458 // First check if this content provider has been published... 7459 cpr = mProviderMap.getProviderByName(name, userId); 7460 boolean providerRunning = cpr != null; 7461 if (providerRunning) { 7462 cpi = cpr.info; 7463 String msg; 7464 if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) { 7465 throw new SecurityException(msg); 7466 } 7467 7468 if (r != null && cpr.canRunHere(r)) { 7469 // This provider has been published or is in the process 7470 // of being published... but it is also allowed to run 7471 // in the caller's process, so don't make a connection 7472 // and just let the caller instantiate its own instance. 7473 ContentProviderHolder holder = cpr.newHolder(null); 7474 // don't give caller the provider object, it needs 7475 // to make its own. 7476 holder.provider = null; 7477 return holder; 7478 } 7479 7480 final long origId = Binder.clearCallingIdentity(); 7481 7482 // In this case the provider instance already exists, so we can 7483 // return it right away. 7484 conn = incProviderCountLocked(r, cpr, token, stable); 7485 if (conn != null && (conn.stableCount+conn.unstableCount) == 1) { 7486 if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 7487 // If this is a perceptible app accessing the provider, 7488 // make sure to count it as being accessed and thus 7489 // back up on the LRU list. This is good because 7490 // content providers are often expensive to start. 7491 updateLruProcessLocked(cpr.proc, false, null); 7492 } 7493 } 7494 7495 if (cpr.proc != null) { 7496 if (false) { 7497 if (cpr.name.flattenToShortString().equals( 7498 "com.android.providers.calendar/.CalendarProvider2")) { 7499 Slog.v(TAG, "****************** KILLING " 7500 + cpr.name.flattenToShortString()); 7501 Process.killProcess(cpr.proc.pid); 7502 } 7503 } 7504 boolean success = updateOomAdjLocked(cpr.proc); 7505 if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success); 7506 // NOTE: there is still a race here where a signal could be 7507 // pending on the process even though we managed to update its 7508 // adj level. Not sure what to do about this, but at least 7509 // the race is now smaller. 7510 if (!success) { 7511 // Uh oh... it looks like the provider's process 7512 // has been killed on us. We need to wait for a new 7513 // process to be started, and make sure its death 7514 // doesn't kill our process. 7515 Slog.i(TAG, 7516 "Existing provider " + cpr.name.flattenToShortString() 7517 + " is crashing; detaching " + r); 7518 boolean lastRef = decProviderCountLocked(conn, cpr, token, stable); 7519 appDiedLocked(cpr.proc, cpr.proc.pid, cpr.proc.thread); 7520 if (!lastRef) { 7521 // This wasn't the last ref our process had on 7522 // the provider... we have now been killed, bail. 7523 return null; 7524 } 7525 providerRunning = false; 7526 conn = null; 7527 } 7528 } 7529 7530 Binder.restoreCallingIdentity(origId); 7531 } 7532 7533 boolean singleton; 7534 if (!providerRunning) { 7535 try { 7536 cpi = AppGlobals.getPackageManager(). 7537 resolveContentProvider(name, 7538 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId); 7539 } catch (RemoteException ex) { 7540 } 7541 if (cpi == null) { 7542 return null; 7543 } 7544 singleton = isSingleton(cpi.processName, cpi.applicationInfo, 7545 cpi.name, cpi.flags); 7546 if (singleton) { 7547 userId = 0; 7548 } 7549 cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId); 7550 7551 String msg; 7552 if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) { 7553 throw new SecurityException(msg); 7554 } 7555 7556 if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate 7557 && !cpi.processName.equals("system")) { 7558 // If this content provider does not run in the system 7559 // process, and the system is not yet ready to run other 7560 // processes, then fail fast instead of hanging. 7561 throw new IllegalArgumentException( 7562 "Attempt to launch content provider before system ready"); 7563 } 7564 7565 // Make sure that the user who owns this provider is started. If not, 7566 // we don't want to allow it to run. 7567 if (mStartedUsers.get(userId) == null) { 7568 Slog.w(TAG, "Unable to launch app " 7569 + cpi.applicationInfo.packageName + "/" 7570 + cpi.applicationInfo.uid + " for provider " 7571 + name + ": user " + userId + " is stopped"); 7572 return null; 7573 } 7574 7575 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 7576 cpr = mProviderMap.getProviderByClass(comp, userId); 7577 final boolean firstClass = cpr == null; 7578 if (firstClass) { 7579 try { 7580 ApplicationInfo ai = 7581 AppGlobals.getPackageManager(). 7582 getApplicationInfo( 7583 cpi.applicationInfo.packageName, 7584 STOCK_PM_FLAGS, userId); 7585 if (ai == null) { 7586 Slog.w(TAG, "No package info for content provider " 7587 + cpi.name); 7588 return null; 7589 } 7590 ai = getAppInfoForUser(ai, userId); 7591 cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton); 7592 } catch (RemoteException ex) { 7593 // pm is in same process, this will never happen. 7594 } 7595 } 7596 7597 if (r != null && cpr.canRunHere(r)) { 7598 // If this is a multiprocess provider, then just return its 7599 // info and allow the caller to instantiate it. Only do 7600 // this if the provider is the same user as the caller's 7601 // process, or can run as root (so can be in any process). 7602 return cpr.newHolder(null); 7603 } 7604 7605 if (DEBUG_PROVIDER) { 7606 RuntimeException e = new RuntimeException("here"); 7607 Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null) 7608 + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e); 7609 } 7610 7611 // This is single process, and our app is now connecting to it. 7612 // See if we are already in the process of launching this 7613 // provider. 7614 final int N = mLaunchingProviders.size(); 7615 int i; 7616 for (i=0; i<N; i++) { 7617 if (mLaunchingProviders.get(i) == cpr) { 7618 break; 7619 } 7620 } 7621 7622 // If the provider is not already being launched, then get it 7623 // started. 7624 if (i >= N) { 7625 final long origId = Binder.clearCallingIdentity(); 7626 7627 try { 7628 // Content provider is now in use, its package can't be stopped. 7629 try { 7630 AppGlobals.getPackageManager().setPackageStoppedState( 7631 cpr.appInfo.packageName, false, userId); 7632 } catch (RemoteException e) { 7633 } catch (IllegalArgumentException e) { 7634 Slog.w(TAG, "Failed trying to unstop package " 7635 + cpr.appInfo.packageName + ": " + e); 7636 } 7637 7638 // Use existing process if already started 7639 ProcessRecord proc = getProcessRecordLocked( 7640 cpi.processName, cpr.appInfo.uid, false); 7641 if (proc != null && proc.thread != null) { 7642 if (DEBUG_PROVIDER) { 7643 Slog.d(TAG, "Installing in existing process " + proc); 7644 } 7645 proc.pubProviders.put(cpi.name, cpr); 7646 try { 7647 proc.thread.scheduleInstallProvider(cpi); 7648 } catch (RemoteException e) { 7649 } 7650 } else { 7651 proc = startProcessLocked(cpi.processName, 7652 cpr.appInfo, false, 0, "content provider", 7653 new ComponentName(cpi.applicationInfo.packageName, 7654 cpi.name), false, false, false); 7655 if (proc == null) { 7656 Slog.w(TAG, "Unable to launch app " 7657 + cpi.applicationInfo.packageName + "/" 7658 + cpi.applicationInfo.uid + " for provider " 7659 + name + ": process is bad"); 7660 return null; 7661 } 7662 } 7663 cpr.launchingApp = proc; 7664 mLaunchingProviders.add(cpr); 7665 } finally { 7666 Binder.restoreCallingIdentity(origId); 7667 } 7668 } 7669 7670 // Make sure the provider is published (the same provider class 7671 // may be published under multiple names). 7672 if (firstClass) { 7673 mProviderMap.putProviderByClass(comp, cpr); 7674 } 7675 7676 mProviderMap.putProviderByName(name, cpr); 7677 conn = incProviderCountLocked(r, cpr, token, stable); 7678 if (conn != null) { 7679 conn.waiting = true; 7680 } 7681 } 7682 } 7683 7684 // Wait for the provider to be published... 7685 synchronized (cpr) { 7686 while (cpr.provider == null) { 7687 if (cpr.launchingApp == null) { 7688 Slog.w(TAG, "Unable to launch app " 7689 + cpi.applicationInfo.packageName + "/" 7690 + cpi.applicationInfo.uid + " for provider " 7691 + name + ": launching app became null"); 7692 EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS, 7693 UserHandle.getUserId(cpi.applicationInfo.uid), 7694 cpi.applicationInfo.packageName, 7695 cpi.applicationInfo.uid, name); 7696 return null; 7697 } 7698 try { 7699 if (DEBUG_MU) { 7700 Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp=" 7701 + cpr.launchingApp); 7702 } 7703 if (conn != null) { 7704 conn.waiting = true; 7705 } 7706 cpr.wait(); 7707 } catch (InterruptedException ex) { 7708 } finally { 7709 if (conn != null) { 7710 conn.waiting = false; 7711 } 7712 } 7713 } 7714 } 7715 return cpr != null ? cpr.newHolder(conn) : null; 7716 } 7717 7718 public final ContentProviderHolder getContentProvider( 7719 IApplicationThread caller, String name, int userId, boolean stable) { 7720 enforceNotIsolatedCaller("getContentProvider"); 7721 if (caller == null) { 7722 String msg = "null IApplicationThread when getting content provider " 7723 + name; 7724 Slog.w(TAG, msg); 7725 throw new SecurityException(msg); 7726 } 7727 7728 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 7729 false, true, "getContentProvider", null); 7730 return getContentProviderImpl(caller, name, null, stable, userId); 7731 } 7732 7733 public ContentProviderHolder getContentProviderExternal( 7734 String name, int userId, IBinder token) { 7735 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 7736 "Do not have permission in call getContentProviderExternal()"); 7737 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 7738 false, true, "getContentProvider", null); 7739 return getContentProviderExternalUnchecked(name, token, userId); 7740 } 7741 7742 private ContentProviderHolder getContentProviderExternalUnchecked(String name, 7743 IBinder token, int userId) { 7744 return getContentProviderImpl(null, name, token, true, userId); 7745 } 7746 7747 /** 7748 * Drop a content provider from a ProcessRecord's bookkeeping 7749 */ 7750 public void removeContentProvider(IBinder connection, boolean stable) { 7751 enforceNotIsolatedCaller("removeContentProvider"); 7752 synchronized (this) { 7753 ContentProviderConnection conn; 7754 try { 7755 conn = (ContentProviderConnection)connection; 7756 } catch (ClassCastException e) { 7757 String msg ="removeContentProvider: " + connection 7758 + " not a ContentProviderConnection"; 7759 Slog.w(TAG, msg); 7760 throw new IllegalArgumentException(msg); 7761 } 7762 if (conn == null) { 7763 throw new NullPointerException("connection is null"); 7764 } 7765 if (decProviderCountLocked(conn, null, null, stable)) { 7766 updateOomAdjLocked(); 7767 } 7768 } 7769 } 7770 7771 public void removeContentProviderExternal(String name, IBinder token) { 7772 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 7773 "Do not have permission in call removeContentProviderExternal()"); 7774 removeContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId()); 7775 } 7776 7777 private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) { 7778 synchronized (this) { 7779 ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId); 7780 if(cpr == null) { 7781 //remove from mProvidersByClass 7782 if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list"); 7783 return; 7784 } 7785 7786 //update content provider record entry info 7787 ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name); 7788 ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId); 7789 if (localCpr.hasExternalProcessHandles()) { 7790 if (localCpr.removeExternalProcessHandleLocked(token)) { 7791 updateOomAdjLocked(); 7792 } else { 7793 Slog.e(TAG, "Attmpt to remove content provider " + localCpr 7794 + " with no external reference for token: " 7795 + token + "."); 7796 } 7797 } else { 7798 Slog.e(TAG, "Attmpt to remove content provider: " + localCpr 7799 + " with no external references."); 7800 } 7801 } 7802 } 7803 7804 public final void publishContentProviders(IApplicationThread caller, 7805 List<ContentProviderHolder> providers) { 7806 if (providers == null) { 7807 return; 7808 } 7809 7810 enforceNotIsolatedCaller("publishContentProviders"); 7811 synchronized (this) { 7812 final ProcessRecord r = getRecordForAppLocked(caller); 7813 if (DEBUG_MU) 7814 Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid); 7815 if (r == null) { 7816 throw new SecurityException( 7817 "Unable to find app for caller " + caller 7818 + " (pid=" + Binder.getCallingPid() 7819 + ") when publishing content providers"); 7820 } 7821 7822 final long origId = Binder.clearCallingIdentity(); 7823 7824 final int N = providers.size(); 7825 for (int i=0; i<N; i++) { 7826 ContentProviderHolder src = providers.get(i); 7827 if (src == null || src.info == null || src.provider == null) { 7828 continue; 7829 } 7830 ContentProviderRecord dst = r.pubProviders.get(src.info.name); 7831 if (DEBUG_MU) 7832 Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid); 7833 if (dst != null) { 7834 ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name); 7835 mProviderMap.putProviderByClass(comp, dst); 7836 String names[] = dst.info.authority.split(";"); 7837 for (int j = 0; j < names.length; j++) { 7838 mProviderMap.putProviderByName(names[j], dst); 7839 } 7840 7841 int NL = mLaunchingProviders.size(); 7842 int j; 7843 for (j=0; j<NL; j++) { 7844 if (mLaunchingProviders.get(j) == dst) { 7845 mLaunchingProviders.remove(j); 7846 j--; 7847 NL--; 7848 } 7849 } 7850 synchronized (dst) { 7851 dst.provider = src.provider; 7852 dst.proc = r; 7853 dst.notifyAll(); 7854 } 7855 updateOomAdjLocked(r); 7856 } 7857 } 7858 7859 Binder.restoreCallingIdentity(origId); 7860 } 7861 } 7862 7863 public boolean refContentProvider(IBinder connection, int stable, int unstable) { 7864 ContentProviderConnection conn; 7865 try { 7866 conn = (ContentProviderConnection)connection; 7867 } catch (ClassCastException e) { 7868 String msg ="refContentProvider: " + connection 7869 + " not a ContentProviderConnection"; 7870 Slog.w(TAG, msg); 7871 throw new IllegalArgumentException(msg); 7872 } 7873 if (conn == null) { 7874 throw new NullPointerException("connection is null"); 7875 } 7876 7877 synchronized (this) { 7878 if (stable > 0) { 7879 conn.numStableIncs += stable; 7880 } 7881 stable = conn.stableCount + stable; 7882 if (stable < 0) { 7883 throw new IllegalStateException("stableCount < 0: " + stable); 7884 } 7885 7886 if (unstable > 0) { 7887 conn.numUnstableIncs += unstable; 7888 } 7889 unstable = conn.unstableCount + unstable; 7890 if (unstable < 0) { 7891 throw new IllegalStateException("unstableCount < 0: " + unstable); 7892 } 7893 7894 if ((stable+unstable) <= 0) { 7895 throw new IllegalStateException("ref counts can't go to zero here: stable=" 7896 + stable + " unstable=" + unstable); 7897 } 7898 conn.stableCount = stable; 7899 conn.unstableCount = unstable; 7900 return !conn.dead; 7901 } 7902 } 7903 7904 public void unstableProviderDied(IBinder connection) { 7905 ContentProviderConnection conn; 7906 try { 7907 conn = (ContentProviderConnection)connection; 7908 } catch (ClassCastException e) { 7909 String msg ="refContentProvider: " + connection 7910 + " not a ContentProviderConnection"; 7911 Slog.w(TAG, msg); 7912 throw new IllegalArgumentException(msg); 7913 } 7914 if (conn == null) { 7915 throw new NullPointerException("connection is null"); 7916 } 7917 7918 // Safely retrieve the content provider associated with the connection. 7919 IContentProvider provider; 7920 synchronized (this) { 7921 provider = conn.provider.provider; 7922 } 7923 7924 if (provider == null) { 7925 // Um, yeah, we're way ahead of you. 7926 return; 7927 } 7928 7929 // Make sure the caller is being honest with us. 7930 if (provider.asBinder().pingBinder()) { 7931 // Er, no, still looks good to us. 7932 synchronized (this) { 7933 Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid() 7934 + " says " + conn + " died, but we don't agree"); 7935 return; 7936 } 7937 } 7938 7939 // Well look at that! It's dead! 7940 synchronized (this) { 7941 if (conn.provider.provider != provider) { 7942 // But something changed... good enough. 7943 return; 7944 } 7945 7946 ProcessRecord proc = conn.provider.proc; 7947 if (proc == null || proc.thread == null) { 7948 // Seems like the process is already cleaned up. 7949 return; 7950 } 7951 7952 // As far as we're concerned, this is just like receiving a 7953 // death notification... just a bit prematurely. 7954 Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid 7955 + ") early provider death"); 7956 final long ident = Binder.clearCallingIdentity(); 7957 try { 7958 appDiedLocked(proc, proc.pid, proc.thread); 7959 } finally { 7960 Binder.restoreCallingIdentity(ident); 7961 } 7962 } 7963 } 7964 7965 @Override 7966 public void appNotRespondingViaProvider(IBinder connection) { 7967 enforceCallingPermission( 7968 android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()"); 7969 7970 final ContentProviderConnection conn = (ContentProviderConnection) connection; 7971 if (conn == null) { 7972 Slog.w(TAG, "ContentProviderConnection is null"); 7973 return; 7974 } 7975 7976 final ProcessRecord host = conn.provider.proc; 7977 if (host == null) { 7978 Slog.w(TAG, "Failed to find hosting ProcessRecord"); 7979 return; 7980 } 7981 7982 final long token = Binder.clearCallingIdentity(); 7983 try { 7984 appNotResponding(host, null, null, false, "ContentProvider not responding"); 7985 } finally { 7986 Binder.restoreCallingIdentity(token); 7987 } 7988 } 7989 7990 public final void installSystemProviders() { 7991 List<ProviderInfo> providers; 7992 synchronized (this) { 7993 ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID); 7994 providers = generateApplicationProvidersLocked(app); 7995 if (providers != null) { 7996 for (int i=providers.size()-1; i>=0; i--) { 7997 ProviderInfo pi = (ProviderInfo)providers.get(i); 7998 if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) { 7999 Slog.w(TAG, "Not installing system proc provider " + pi.name 8000 + ": not system .apk"); 8001 providers.remove(i); 8002 } 8003 } 8004 } 8005 } 8006 if (providers != null) { 8007 mSystemThread.installSystemProviders(providers); 8008 } 8009 8010 mCoreSettingsObserver = new CoreSettingsObserver(this); 8011 8012 mUsageStatsService.monitorPackages(); 8013 } 8014 8015 /** 8016 * Allows app to retrieve the MIME type of a URI without having permission 8017 * to access its content provider. 8018 * 8019 * CTS tests for this functionality can be run with "runtest cts-appsecurity". 8020 * 8021 * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/ 8022 * src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java 8023 */ 8024 public String getProviderMimeType(Uri uri, int userId) { 8025 enforceNotIsolatedCaller("getProviderMimeType"); 8026 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 8027 userId, false, true, "getProviderMimeType", null); 8028 final String name = uri.getAuthority(); 8029 final long ident = Binder.clearCallingIdentity(); 8030 ContentProviderHolder holder = null; 8031 8032 try { 8033 holder = getContentProviderExternalUnchecked(name, null, userId); 8034 if (holder != null) { 8035 return holder.provider.getType(uri); 8036 } 8037 } catch (RemoteException e) { 8038 Log.w(TAG, "Content provider dead retrieving " + uri, e); 8039 return null; 8040 } finally { 8041 if (holder != null) { 8042 removeContentProviderExternalUnchecked(name, null, userId); 8043 } 8044 Binder.restoreCallingIdentity(ident); 8045 } 8046 8047 return null; 8048 } 8049 8050 // ========================================================= 8051 // GLOBAL MANAGEMENT 8052 // ========================================================= 8053 8054 final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess, 8055 boolean isolated) { 8056 String proc = customProcess != null ? customProcess : info.processName; 8057 BatteryStatsImpl.Uid.Proc ps = null; 8058 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 8059 int uid = info.uid; 8060 if (isolated) { 8061 int userId = UserHandle.getUserId(uid); 8062 int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1; 8063 while (true) { 8064 if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID 8065 || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) { 8066 mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID; 8067 } 8068 uid = UserHandle.getUid(userId, mNextIsolatedProcessUid); 8069 mNextIsolatedProcessUid++; 8070 if (mIsolatedProcesses.indexOfKey(uid) < 0) { 8071 // No process for this uid, use it. 8072 break; 8073 } 8074 stepsLeft--; 8075 if (stepsLeft <= 0) { 8076 return null; 8077 } 8078 } 8079 } 8080 return new ProcessRecord(stats, info, proc, uid); 8081 } 8082 8083 final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated) { 8084 ProcessRecord app; 8085 if (!isolated) { 8086 app = getProcessRecordLocked(info.processName, info.uid, true); 8087 } else { 8088 app = null; 8089 } 8090 8091 if (app == null) { 8092 app = newProcessRecordLocked(info, null, isolated); 8093 mProcessNames.put(info.processName, app.uid, app); 8094 if (isolated) { 8095 mIsolatedProcesses.put(app.uid, app); 8096 } 8097 updateLruProcessLocked(app, false, null); 8098 updateOomAdjLocked(); 8099 } 8100 8101 // This package really, really can not be stopped. 8102 try { 8103 AppGlobals.getPackageManager().setPackageStoppedState( 8104 info.packageName, false, UserHandle.getUserId(app.uid)); 8105 } catch (RemoteException e) { 8106 } catch (IllegalArgumentException e) { 8107 Slog.w(TAG, "Failed trying to unstop package " 8108 + info.packageName + ": " + e); 8109 } 8110 8111 if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) 8112 == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) { 8113 app.persistent = true; 8114 app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ; 8115 } 8116 if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) { 8117 mPersistentStartingProcesses.add(app); 8118 startProcessLocked(app, "added application", app.processName); 8119 } 8120 8121 return app; 8122 } 8123 8124 public void unhandledBack() { 8125 enforceCallingPermission(android.Manifest.permission.FORCE_BACK, 8126 "unhandledBack()"); 8127 8128 synchronized(this) { 8129 final long origId = Binder.clearCallingIdentity(); 8130 try { 8131 getFocusedStack().unhandledBackLocked(); 8132 } finally { 8133 Binder.restoreCallingIdentity(origId); 8134 } 8135 } 8136 } 8137 8138 public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException { 8139 enforceNotIsolatedCaller("openContentUri"); 8140 final int userId = UserHandle.getCallingUserId(); 8141 String name = uri.getAuthority(); 8142 ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId); 8143 ParcelFileDescriptor pfd = null; 8144 if (cph != null) { 8145 // We record the binder invoker's uid in thread-local storage before 8146 // going to the content provider to open the file. Later, in the code 8147 // that handles all permissions checks, we look for this uid and use 8148 // that rather than the Activity Manager's own uid. The effect is that 8149 // we do the check against the caller's permissions even though it looks 8150 // to the content provider like the Activity Manager itself is making 8151 // the request. 8152 sCallerIdentity.set(new Identity( 8153 Binder.getCallingPid(), Binder.getCallingUid())); 8154 try { 8155 pfd = cph.provider.openFile(null, uri, "r", null); 8156 } catch (FileNotFoundException e) { 8157 // do nothing; pfd will be returned null 8158 } finally { 8159 // Ensure that whatever happens, we clean up the identity state 8160 sCallerIdentity.remove(); 8161 } 8162 8163 // We've got the fd now, so we're done with the provider. 8164 removeContentProviderExternalUnchecked(name, null, userId); 8165 } else { 8166 Slog.d(TAG, "Failed to get provider for authority '" + name + "'"); 8167 } 8168 return pfd; 8169 } 8170 8171 // Actually is sleeping or shutting down or whatever else in the future 8172 // is an inactive state. 8173 public boolean isSleepingOrShuttingDown() { 8174 return mSleeping || mShuttingDown; 8175 } 8176 8177 void goingToSleep() { 8178 synchronized(this) { 8179 mWentToSleep = true; 8180 updateEventDispatchingLocked(); 8181 8182 if (!mSleeping) { 8183 mSleeping = true; 8184 mStackSupervisor.goingToSleepLocked(); 8185 8186 // Initialize the wake times of all processes. 8187 checkExcessivePowerUsageLocked(false); 8188 mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 8189 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 8190 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 8191 } 8192 } 8193 } 8194 8195 @Override 8196 public boolean shutdown(int timeout) { 8197 if (checkCallingPermission(android.Manifest.permission.SHUTDOWN) 8198 != PackageManager.PERMISSION_GRANTED) { 8199 throw new SecurityException("Requires permission " 8200 + android.Manifest.permission.SHUTDOWN); 8201 } 8202 8203 boolean timedout = false; 8204 8205 synchronized(this) { 8206 mShuttingDown = true; 8207 updateEventDispatchingLocked(); 8208 timedout = mStackSupervisor.shutdownLocked(timeout); 8209 } 8210 8211 mAppOpsService.shutdown(); 8212 mUsageStatsService.shutdown(); 8213 mBatteryStatsService.shutdown(); 8214 synchronized (this) { 8215 mProcessStats.shutdownLocked(); 8216 } 8217 8218 return timedout; 8219 } 8220 8221 public final void activitySlept(IBinder token) { 8222 if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token); 8223 8224 final long origId = Binder.clearCallingIdentity(); 8225 8226 synchronized (this) { 8227 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 8228 if (r != null) { 8229 mStackSupervisor.activitySleptLocked(r); 8230 } 8231 } 8232 8233 Binder.restoreCallingIdentity(origId); 8234 } 8235 8236 void logLockScreen(String msg) { 8237 if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg + 8238 " mLockScreenShown=" + mLockScreenShown + " mWentToSleep=" + 8239 mWentToSleep + " mSleeping=" + mSleeping + " mDismissKeyguardOnNextActivity=" + 8240 mStackSupervisor.mDismissKeyguardOnNextActivity); 8241 } 8242 8243 private void comeOutOfSleepIfNeededLocked() { 8244 if (!mWentToSleep && !mLockScreenShown) { 8245 if (mSleeping) { 8246 mSleeping = false; 8247 mStackSupervisor.comeOutOfSleepIfNeededLocked(); 8248 } 8249 } 8250 } 8251 8252 void wakingUp() { 8253 synchronized(this) { 8254 mWentToSleep = false; 8255 updateEventDispatchingLocked(); 8256 comeOutOfSleepIfNeededLocked(); 8257 } 8258 } 8259 8260 private void updateEventDispatchingLocked() { 8261 mWindowManager.setEventDispatching(mBooted && !mWentToSleep && !mShuttingDown); 8262 } 8263 8264 public void setLockScreenShown(boolean shown) { 8265 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER) 8266 != PackageManager.PERMISSION_GRANTED) { 8267 throw new SecurityException("Requires permission " 8268 + android.Manifest.permission.DEVICE_POWER); 8269 } 8270 8271 synchronized(this) { 8272 long ident = Binder.clearCallingIdentity(); 8273 try { 8274 if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown); 8275 mLockScreenShown = shown; 8276 comeOutOfSleepIfNeededLocked(); 8277 } finally { 8278 Binder.restoreCallingIdentity(ident); 8279 } 8280 } 8281 } 8282 8283 public void stopAppSwitches() { 8284 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 8285 != PackageManager.PERMISSION_GRANTED) { 8286 throw new SecurityException("Requires permission " 8287 + android.Manifest.permission.STOP_APP_SWITCHES); 8288 } 8289 8290 synchronized(this) { 8291 mAppSwitchesAllowedTime = SystemClock.uptimeMillis() 8292 + APP_SWITCH_DELAY_TIME; 8293 mDidAppSwitch = false; 8294 mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 8295 Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 8296 mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME); 8297 } 8298 } 8299 8300 public void resumeAppSwitches() { 8301 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 8302 != PackageManager.PERMISSION_GRANTED) { 8303 throw new SecurityException("Requires permission " 8304 + android.Manifest.permission.STOP_APP_SWITCHES); 8305 } 8306 8307 synchronized(this) { 8308 // Note that we don't execute any pending app switches... we will 8309 // let those wait until either the timeout, or the next start 8310 // activity request. 8311 mAppSwitchesAllowedTime = 0; 8312 } 8313 } 8314 8315 boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid, 8316 String name) { 8317 if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) { 8318 return true; 8319 } 8320 8321 final int perm = checkComponentPermission( 8322 android.Manifest.permission.STOP_APP_SWITCHES, callingPid, 8323 callingUid, -1, true); 8324 if (perm == PackageManager.PERMISSION_GRANTED) { 8325 return true; 8326 } 8327 8328 Slog.w(TAG, name + " request from " + callingUid + " stopped"); 8329 return false; 8330 } 8331 8332 public void setDebugApp(String packageName, boolean waitForDebugger, 8333 boolean persistent) { 8334 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP, 8335 "setDebugApp()"); 8336 8337 long ident = Binder.clearCallingIdentity(); 8338 try { 8339 // Note that this is not really thread safe if there are multiple 8340 // callers into it at the same time, but that's not a situation we 8341 // care about. 8342 if (persistent) { 8343 final ContentResolver resolver = mContext.getContentResolver(); 8344 Settings.Global.putString( 8345 resolver, Settings.Global.DEBUG_APP, 8346 packageName); 8347 Settings.Global.putInt( 8348 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 8349 waitForDebugger ? 1 : 0); 8350 } 8351 8352 synchronized (this) { 8353 if (!persistent) { 8354 mOrigDebugApp = mDebugApp; 8355 mOrigWaitForDebugger = mWaitForDebugger; 8356 } 8357 mDebugApp = packageName; 8358 mWaitForDebugger = waitForDebugger; 8359 mDebugTransient = !persistent; 8360 if (packageName != null) { 8361 forceStopPackageLocked(packageName, -1, false, false, true, true, 8362 UserHandle.USER_ALL, "set debug app"); 8363 } 8364 } 8365 } finally { 8366 Binder.restoreCallingIdentity(ident); 8367 } 8368 } 8369 8370 void setOpenGlTraceApp(ApplicationInfo app, String processName) { 8371 synchronized (this) { 8372 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 8373 if (!isDebuggable) { 8374 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 8375 throw new SecurityException("Process not debuggable: " + app.packageName); 8376 } 8377 } 8378 8379 mOpenGlTraceApp = processName; 8380 } 8381 } 8382 8383 void setProfileApp(ApplicationInfo app, String processName, String profileFile, 8384 ParcelFileDescriptor profileFd, boolean autoStopProfiler) { 8385 synchronized (this) { 8386 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 8387 if (!isDebuggable) { 8388 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 8389 throw new SecurityException("Process not debuggable: " + app.packageName); 8390 } 8391 } 8392 mProfileApp = processName; 8393 mProfileFile = profileFile; 8394 if (mProfileFd != null) { 8395 try { 8396 mProfileFd.close(); 8397 } catch (IOException e) { 8398 } 8399 mProfileFd = null; 8400 } 8401 mProfileFd = profileFd; 8402 mProfileType = 0; 8403 mAutoStopProfiler = autoStopProfiler; 8404 } 8405 } 8406 8407 @Override 8408 public void setAlwaysFinish(boolean enabled) { 8409 enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH, 8410 "setAlwaysFinish()"); 8411 8412 Settings.Global.putInt( 8413 mContext.getContentResolver(), 8414 Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0); 8415 8416 synchronized (this) { 8417 mAlwaysFinishActivities = enabled; 8418 } 8419 } 8420 8421 @Override 8422 public void setActivityController(IActivityController controller) { 8423 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 8424 "setActivityController()"); 8425 synchronized (this) { 8426 mController = controller; 8427 Watchdog.getInstance().setActivityController(controller); 8428 } 8429 } 8430 8431 @Override 8432 public void setUserIsMonkey(boolean userIsMonkey) { 8433 synchronized (this) { 8434 synchronized (mPidsSelfLocked) { 8435 final int callingPid = Binder.getCallingPid(); 8436 ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid); 8437 if (precessRecord == null) { 8438 throw new SecurityException("Unknown process: " + callingPid); 8439 } 8440 if (precessRecord.instrumentationUiAutomationConnection == null) { 8441 throw new SecurityException("Only an instrumentation process " 8442 + "with a UiAutomation can call setUserIsMonkey"); 8443 } 8444 } 8445 mUserIsMonkey = userIsMonkey; 8446 } 8447 } 8448 8449 @Override 8450 public boolean isUserAMonkey() { 8451 synchronized (this) { 8452 // If there is a controller also implies the user is a monkey. 8453 return (mUserIsMonkey || mController != null); 8454 } 8455 } 8456 8457 public void requestBugReport() { 8458 enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport"); 8459 SystemProperties.set("ctl.start", "bugreport"); 8460 } 8461 8462 public static long getInputDispatchingTimeoutLocked(ActivityRecord r) { 8463 return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT; 8464 } 8465 8466 public static long getInputDispatchingTimeoutLocked(ProcessRecord r) { 8467 if (r != null && (r.instrumentationClass != null || r.usingWrapper)) { 8468 return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT; 8469 } 8470 return KEY_DISPATCHING_TIMEOUT; 8471 } 8472 8473 @Override 8474 public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) { 8475 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS) 8476 != PackageManager.PERMISSION_GRANTED) { 8477 throw new SecurityException("Requires permission " 8478 + android.Manifest.permission.FILTER_EVENTS); 8479 } 8480 ProcessRecord proc; 8481 long timeout; 8482 synchronized (this) { 8483 synchronized (mPidsSelfLocked) { 8484 proc = mPidsSelfLocked.get(pid); 8485 } 8486 timeout = getInputDispatchingTimeoutLocked(proc); 8487 } 8488 8489 if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) { 8490 return -1; 8491 } 8492 8493 return timeout; 8494 } 8495 8496 /** 8497 * Handle input dispatching timeouts. 8498 * Returns whether input dispatching should be aborted or not. 8499 */ 8500 public boolean inputDispatchingTimedOut(final ProcessRecord proc, 8501 final ActivityRecord activity, final ActivityRecord parent, 8502 final boolean aboveSystem, String reason) { 8503 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS) 8504 != PackageManager.PERMISSION_GRANTED) { 8505 throw new SecurityException("Requires permission " 8506 + android.Manifest.permission.FILTER_EVENTS); 8507 } 8508 8509 final String annotation; 8510 if (reason == null) { 8511 annotation = "Input dispatching timed out"; 8512 } else { 8513 annotation = "Input dispatching timed out (" + reason + ")"; 8514 } 8515 8516 if (proc != null) { 8517 synchronized (this) { 8518 if (proc.debugging) { 8519 return false; 8520 } 8521 8522 if (mDidDexOpt) { 8523 // Give more time since we were dexopting. 8524 mDidDexOpt = false; 8525 return false; 8526 } 8527 8528 if (proc.instrumentationClass != null) { 8529 Bundle info = new Bundle(); 8530 info.putString("shortMsg", "keyDispatchingTimedOut"); 8531 info.putString("longMsg", annotation); 8532 finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info); 8533 return true; 8534 } 8535 } 8536 mHandler.post(new Runnable() { 8537 @Override 8538 public void run() { 8539 appNotResponding(proc, activity, parent, aboveSystem, annotation); 8540 } 8541 }); 8542 } 8543 8544 return true; 8545 } 8546 8547 public Bundle getAssistContextExtras(int requestType) { 8548 enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO, 8549 "getAssistContextExtras()"); 8550 PendingAssistExtras pae; 8551 Bundle extras = new Bundle(); 8552 synchronized (this) { 8553 ActivityRecord activity = getFocusedStack().mResumedActivity; 8554 if (activity == null) { 8555 Slog.w(TAG, "getAssistContextExtras failed: no resumed activity"); 8556 return null; 8557 } 8558 extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName); 8559 if (activity.app == null || activity.app.thread == null) { 8560 Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity); 8561 return extras; 8562 } 8563 if (activity.app.pid == Binder.getCallingPid()) { 8564 Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity); 8565 return extras; 8566 } 8567 pae = new PendingAssistExtras(activity); 8568 try { 8569 activity.app.thread.requestAssistContextExtras(activity.appToken, pae, 8570 requestType); 8571 mPendingAssistExtras.add(pae); 8572 mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT); 8573 } catch (RemoteException e) { 8574 Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity); 8575 return extras; 8576 } 8577 } 8578 synchronized (pae) { 8579 while (!pae.haveResult) { 8580 try { 8581 pae.wait(); 8582 } catch (InterruptedException e) { 8583 } 8584 } 8585 if (pae.result != null) { 8586 extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result); 8587 } 8588 } 8589 synchronized (this) { 8590 mPendingAssistExtras.remove(pae); 8591 mHandler.removeCallbacks(pae); 8592 } 8593 return extras; 8594 } 8595 8596 public void reportAssistContextExtras(IBinder token, Bundle extras) { 8597 PendingAssistExtras pae = (PendingAssistExtras)token; 8598 synchronized (pae) { 8599 pae.result = extras; 8600 pae.haveResult = true; 8601 pae.notifyAll(); 8602 } 8603 } 8604 8605 public void registerProcessObserver(IProcessObserver observer) { 8606 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 8607 "registerProcessObserver()"); 8608 synchronized (this) { 8609 mProcessObservers.register(observer); 8610 } 8611 } 8612 8613 @Override 8614 public void unregisterProcessObserver(IProcessObserver observer) { 8615 synchronized (this) { 8616 mProcessObservers.unregister(observer); 8617 } 8618 } 8619 8620 @Override 8621 public boolean convertFromTranslucent(IBinder token) { 8622 final long origId = Binder.clearCallingIdentity(); 8623 try { 8624 synchronized (this) { 8625 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 8626 if (r == null) { 8627 return false; 8628 } 8629 if (r.changeWindowTranslucency(true)) { 8630 mWindowManager.setAppFullscreen(token, true); 8631 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 8632 return true; 8633 } 8634 return false; 8635 } 8636 } finally { 8637 Binder.restoreCallingIdentity(origId); 8638 } 8639 } 8640 8641 @Override 8642 public boolean convertToTranslucent(IBinder token) { 8643 final long origId = Binder.clearCallingIdentity(); 8644 try { 8645 synchronized (this) { 8646 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 8647 if (r == null) { 8648 return false; 8649 } 8650 if (r.changeWindowTranslucency(false)) { 8651 r.task.stack.convertToTranslucent(r); 8652 mWindowManager.setAppFullscreen(token, false); 8653 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 8654 return true; 8655 } 8656 return false; 8657 } 8658 } finally { 8659 Binder.restoreCallingIdentity(origId); 8660 } 8661 } 8662 8663 @Override 8664 public void setImmersive(IBinder token, boolean immersive) { 8665 synchronized(this) { 8666 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 8667 if (r == null) { 8668 throw new IllegalArgumentException(); 8669 } 8670 r.immersive = immersive; 8671 8672 // update associated state if we're frontmost 8673 if (r == mFocusedActivity) { 8674 if (DEBUG_IMMERSIVE) { 8675 Slog.d(TAG, "Frontmost changed immersion: "+ r); 8676 } 8677 applyUpdateLockStateLocked(r); 8678 } 8679 } 8680 } 8681 8682 @Override 8683 public boolean isImmersive(IBinder token) { 8684 synchronized (this) { 8685 ActivityRecord r = ActivityRecord.isInStackLocked(token); 8686 if (r == null) { 8687 throw new IllegalArgumentException(); 8688 } 8689 return r.immersive; 8690 } 8691 } 8692 8693 public boolean isTopActivityImmersive() { 8694 enforceNotIsolatedCaller("startActivity"); 8695 synchronized (this) { 8696 ActivityRecord r = getFocusedStack().topRunningActivityLocked(null); 8697 return (r != null) ? r.immersive : false; 8698 } 8699 } 8700 8701 public final void enterSafeMode() { 8702 synchronized(this) { 8703 // It only makes sense to do this before the system is ready 8704 // and started launching other packages. 8705 if (!mSystemReady) { 8706 try { 8707 AppGlobals.getPackageManager().enterSafeMode(); 8708 } catch (RemoteException e) { 8709 } 8710 } 8711 } 8712 } 8713 8714 public final void showSafeModeOverlay() { 8715 View v = LayoutInflater.from(mContext).inflate( 8716 com.android.internal.R.layout.safe_mode, null); 8717 WindowManager.LayoutParams lp = new WindowManager.LayoutParams(); 8718 lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY; 8719 lp.width = WindowManager.LayoutParams.WRAP_CONTENT; 8720 lp.height = WindowManager.LayoutParams.WRAP_CONTENT; 8721 lp.gravity = Gravity.BOTTOM | Gravity.START; 8722 lp.format = v.getBackground().getOpacity(); 8723 lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE 8724 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE; 8725 lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS; 8726 ((WindowManager)mContext.getSystemService( 8727 Context.WINDOW_SERVICE)).addView(v, lp); 8728 } 8729 8730 public void noteWakeupAlarm(IIntentSender sender) { 8731 if (!(sender instanceof PendingIntentRecord)) { 8732 return; 8733 } 8734 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 8735 synchronized (stats) { 8736 if (mBatteryStatsService.isOnBattery()) { 8737 mBatteryStatsService.enforceCallingPermission(); 8738 PendingIntentRecord rec = (PendingIntentRecord)sender; 8739 int MY_UID = Binder.getCallingUid(); 8740 int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid; 8741 BatteryStatsImpl.Uid.Pkg pkg = 8742 stats.getPackageStatsLocked(uid, rec.key.packageName); 8743 pkg.incWakeupsLocked(); 8744 } 8745 } 8746 } 8747 8748 public boolean killPids(int[] pids, String pReason, boolean secure) { 8749 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 8750 throw new SecurityException("killPids only available to the system"); 8751 } 8752 String reason = (pReason == null) ? "Unknown" : pReason; 8753 // XXX Note: don't acquire main activity lock here, because the window 8754 // manager calls in with its locks held. 8755 8756 boolean killed = false; 8757 synchronized (mPidsSelfLocked) { 8758 int[] types = new int[pids.length]; 8759 int worstType = 0; 8760 for (int i=0; i<pids.length; i++) { 8761 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 8762 if (proc != null) { 8763 int type = proc.setAdj; 8764 types[i] = type; 8765 if (type > worstType) { 8766 worstType = type; 8767 } 8768 } 8769 } 8770 8771 // If the worst oom_adj is somewhere in the cached proc LRU range, 8772 // then constrain it so we will kill all cached procs. 8773 if (worstType < ProcessList.CACHED_APP_MAX_ADJ 8774 && worstType > ProcessList.CACHED_APP_MIN_ADJ) { 8775 worstType = ProcessList.CACHED_APP_MIN_ADJ; 8776 } 8777 8778 // If this is not a secure call, don't let it kill processes that 8779 // are important. 8780 if (!secure && worstType < ProcessList.SERVICE_ADJ) { 8781 worstType = ProcessList.SERVICE_ADJ; 8782 } 8783 8784 Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType); 8785 for (int i=0; i<pids.length; i++) { 8786 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 8787 if (proc == null) { 8788 continue; 8789 } 8790 int adj = proc.setAdj; 8791 if (adj >= worstType && !proc.killedByAm) { 8792 killUnneededProcessLocked(proc, reason); 8793 killed = true; 8794 } 8795 } 8796 } 8797 return killed; 8798 } 8799 8800 @Override 8801 public void killUid(int uid, String reason) { 8802 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 8803 throw new SecurityException("killUid only available to the system"); 8804 } 8805 synchronized (this) { 8806 killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid), 8807 ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false, 8808 reason != null ? reason : "kill uid"); 8809 } 8810 } 8811 8812 @Override 8813 public boolean killProcessesBelowForeground(String reason) { 8814 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 8815 throw new SecurityException("killProcessesBelowForeground() only available to system"); 8816 } 8817 8818 return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason); 8819 } 8820 8821 private boolean killProcessesBelowAdj(int belowAdj, String reason) { 8822 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 8823 throw new SecurityException("killProcessesBelowAdj() only available to system"); 8824 } 8825 8826 boolean killed = false; 8827 synchronized (mPidsSelfLocked) { 8828 final int size = mPidsSelfLocked.size(); 8829 for (int i = 0; i < size; i++) { 8830 final int pid = mPidsSelfLocked.keyAt(i); 8831 final ProcessRecord proc = mPidsSelfLocked.valueAt(i); 8832 if (proc == null) continue; 8833 8834 final int adj = proc.setAdj; 8835 if (adj > belowAdj && !proc.killedByAm) { 8836 killUnneededProcessLocked(proc, reason); 8837 killed = true; 8838 } 8839 } 8840 } 8841 return killed; 8842 } 8843 8844 @Override 8845 public void hang(final IBinder who, boolean allowRestart) { 8846 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 8847 != PackageManager.PERMISSION_GRANTED) { 8848 throw new SecurityException("Requires permission " 8849 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 8850 } 8851 8852 final IBinder.DeathRecipient death = new DeathRecipient() { 8853 @Override 8854 public void binderDied() { 8855 synchronized (this) { 8856 notifyAll(); 8857 } 8858 } 8859 }; 8860 8861 try { 8862 who.linkToDeath(death, 0); 8863 } catch (RemoteException e) { 8864 Slog.w(TAG, "hang: given caller IBinder is already dead."); 8865 return; 8866 } 8867 8868 synchronized (this) { 8869 Watchdog.getInstance().setAllowRestart(allowRestart); 8870 Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid()); 8871 synchronized (death) { 8872 while (who.isBinderAlive()) { 8873 try { 8874 death.wait(); 8875 } catch (InterruptedException e) { 8876 } 8877 } 8878 } 8879 Watchdog.getInstance().setAllowRestart(true); 8880 } 8881 } 8882 8883 @Override 8884 public void restart() { 8885 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 8886 != PackageManager.PERMISSION_GRANTED) { 8887 throw new SecurityException("Requires permission " 8888 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 8889 } 8890 8891 Log.i(TAG, "Sending shutdown broadcast..."); 8892 8893 BroadcastReceiver br = new BroadcastReceiver() { 8894 @Override public void onReceive(Context context, Intent intent) { 8895 // Now the broadcast is done, finish up the low-level shutdown. 8896 Log.i(TAG, "Shutting down activity manager..."); 8897 shutdown(10000); 8898 Log.i(TAG, "Shutdown complete, restarting!"); 8899 Process.killProcess(Process.myPid()); 8900 System.exit(10); 8901 } 8902 }; 8903 8904 // First send the high-level shut down broadcast. 8905 Intent intent = new Intent(Intent.ACTION_SHUTDOWN); 8906 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 8907 intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true); 8908 /* For now we are not doing a clean shutdown, because things seem to get unhappy. 8909 mContext.sendOrderedBroadcastAsUser(intent, 8910 UserHandle.ALL, null, br, mHandler, 0, null, null); 8911 */ 8912 br.onReceive(mContext, intent); 8913 } 8914 8915 private long getLowRamTimeSinceIdle(long now) { 8916 return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0); 8917 } 8918 8919 @Override 8920 public void performIdleMaintenance() { 8921 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 8922 != PackageManager.PERMISSION_GRANTED) { 8923 throw new SecurityException("Requires permission " 8924 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 8925 } 8926 8927 synchronized (this) { 8928 final long now = SystemClock.uptimeMillis(); 8929 final long timeSinceLastIdle = now - mLastIdleTime; 8930 final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now); 8931 mLastIdleTime = now; 8932 mLowRamTimeSinceLastIdle = 0; 8933 if (mLowRamStartTime != 0) { 8934 mLowRamStartTime = now; 8935 } 8936 8937 StringBuilder sb = new StringBuilder(128); 8938 sb.append("Idle maintenance over "); 8939 TimeUtils.formatDuration(timeSinceLastIdle, sb); 8940 sb.append(" low RAM for "); 8941 TimeUtils.formatDuration(lowRamSinceLastIdle, sb); 8942 Slog.i(TAG, sb.toString()); 8943 8944 // If at least 1/3 of our time since the last idle period has been spent 8945 // with RAM low, then we want to kill processes. 8946 boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3); 8947 8948 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 8949 ProcessRecord proc = mLruProcesses.get(i); 8950 if (proc.notCachedSinceIdle) { 8951 if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP 8952 && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) { 8953 if (doKilling && proc.initialIdlePss != 0 8954 && proc.lastPss > ((proc.initialIdlePss*3)/2)) { 8955 killUnneededProcessLocked(proc, "idle maint (pss " + proc.lastPss 8956 + " from " + proc.initialIdlePss + ")"); 8957 } 8958 } 8959 } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) { 8960 proc.notCachedSinceIdle = true; 8961 proc.initialIdlePss = 0; 8962 proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true, 8963 mSleeping, now); 8964 } 8965 } 8966 8967 mHandler.removeMessages(REQUEST_ALL_PSS_MSG); 8968 mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000); 8969 } 8970 } 8971 8972 private void retrieveSettings() { 8973 final ContentResolver resolver = mContext.getContentResolver(); 8974 String debugApp = Settings.Global.getString( 8975 resolver, Settings.Global.DEBUG_APP); 8976 boolean waitForDebugger = Settings.Global.getInt( 8977 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0; 8978 boolean alwaysFinishActivities = Settings.Global.getInt( 8979 resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0; 8980 boolean forceRtl = Settings.Global.getInt( 8981 resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0; 8982 // Transfer any global setting for forcing RTL layout, into a System Property 8983 SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0"); 8984 8985 Configuration configuration = new Configuration(); 8986 Settings.System.getConfiguration(resolver, configuration); 8987 if (forceRtl) { 8988 // This will take care of setting the correct layout direction flags 8989 configuration.setLayoutDirection(configuration.locale); 8990 } 8991 8992 synchronized (this) { 8993 mDebugApp = mOrigDebugApp = debugApp; 8994 mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger; 8995 mAlwaysFinishActivities = alwaysFinishActivities; 8996 // This happens before any activities are started, so we can 8997 // change mConfiguration in-place. 8998 updateConfigurationLocked(configuration, null, false, true); 8999 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration); 9000 } 9001 } 9002 9003 public boolean testIsSystemReady() { 9004 // no need to synchronize(this) just to read & return the value 9005 return mSystemReady; 9006 } 9007 9008 private static File getCalledPreBootReceiversFile() { 9009 File dataDir = Environment.getDataDirectory(); 9010 File systemDir = new File(dataDir, "system"); 9011 File fname = new File(systemDir, "called_pre_boots.dat"); 9012 return fname; 9013 } 9014 9015 static final int LAST_DONE_VERSION = 10000; 9016 9017 private static ArrayList<ComponentName> readLastDonePreBootReceivers() { 9018 ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>(); 9019 File file = getCalledPreBootReceiversFile(); 9020 FileInputStream fis = null; 9021 try { 9022 fis = new FileInputStream(file); 9023 DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048)); 9024 int fvers = dis.readInt(); 9025 if (fvers == LAST_DONE_VERSION) { 9026 String vers = dis.readUTF(); 9027 String codename = dis.readUTF(); 9028 String build = dis.readUTF(); 9029 if (android.os.Build.VERSION.RELEASE.equals(vers) 9030 && android.os.Build.VERSION.CODENAME.equals(codename) 9031 && android.os.Build.VERSION.INCREMENTAL.equals(build)) { 9032 int num = dis.readInt(); 9033 while (num > 0) { 9034 num--; 9035 String pkg = dis.readUTF(); 9036 String cls = dis.readUTF(); 9037 lastDoneReceivers.add(new ComponentName(pkg, cls)); 9038 } 9039 } 9040 } 9041 } catch (FileNotFoundException e) { 9042 } catch (IOException e) { 9043 Slog.w(TAG, "Failure reading last done pre-boot receivers", e); 9044 } finally { 9045 if (fis != null) { 9046 try { 9047 fis.close(); 9048 } catch (IOException e) { 9049 } 9050 } 9051 } 9052 return lastDoneReceivers; 9053 } 9054 9055 private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) { 9056 File file = getCalledPreBootReceiversFile(); 9057 FileOutputStream fos = null; 9058 DataOutputStream dos = null; 9059 try { 9060 Slog.i(TAG, "Writing new set of last done pre-boot receivers..."); 9061 fos = new FileOutputStream(file); 9062 dos = new DataOutputStream(new BufferedOutputStream(fos, 2048)); 9063 dos.writeInt(LAST_DONE_VERSION); 9064 dos.writeUTF(android.os.Build.VERSION.RELEASE); 9065 dos.writeUTF(android.os.Build.VERSION.CODENAME); 9066 dos.writeUTF(android.os.Build.VERSION.INCREMENTAL); 9067 dos.writeInt(list.size()); 9068 for (int i=0; i<list.size(); i++) { 9069 dos.writeUTF(list.get(i).getPackageName()); 9070 dos.writeUTF(list.get(i).getClassName()); 9071 } 9072 } catch (IOException e) { 9073 Slog.w(TAG, "Failure writing last done pre-boot receivers", e); 9074 file.delete(); 9075 } finally { 9076 FileUtils.sync(fos); 9077 if (dos != null) { 9078 try { 9079 dos.close(); 9080 } catch (IOException e) { 9081 // TODO Auto-generated catch block 9082 e.printStackTrace(); 9083 } 9084 } 9085 } 9086 } 9087 9088 public void systemReady(final Runnable goingCallback) { 9089 synchronized(this) { 9090 if (mSystemReady) { 9091 if (goingCallback != null) goingCallback.run(); 9092 return; 9093 } 9094 9095 // Check to see if there are any update receivers to run. 9096 if (!mDidUpdate) { 9097 if (mWaitingUpdate) { 9098 return; 9099 } 9100 Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED); 9101 List<ResolveInfo> ris = null; 9102 try { 9103 ris = AppGlobals.getPackageManager().queryIntentReceivers( 9104 intent, null, 0, 0); 9105 } catch (RemoteException e) { 9106 } 9107 if (ris != null) { 9108 for (int i=ris.size()-1; i>=0; i--) { 9109 if ((ris.get(i).activityInfo.applicationInfo.flags 9110 &ApplicationInfo.FLAG_SYSTEM) == 0) { 9111 ris.remove(i); 9112 } 9113 } 9114 intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE); 9115 9116 ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers(); 9117 9118 final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>(); 9119 for (int i=0; i<ris.size(); i++) { 9120 ActivityInfo ai = ris.get(i).activityInfo; 9121 ComponentName comp = new ComponentName(ai.packageName, ai.name); 9122 if (lastDoneReceivers.contains(comp)) { 9123 // We already did the pre boot receiver for this app with the current 9124 // platform version, so don't do it again... 9125 ris.remove(i); 9126 i--; 9127 // ...however, do keep it as one that has been done, so we don't 9128 // forget about it when rewriting the file of last done receivers. 9129 doneReceivers.add(comp); 9130 } 9131 } 9132 9133 final int[] users = getUsersLocked(); 9134 for (int i=0; i<ris.size(); i++) { 9135 ActivityInfo ai = ris.get(i).activityInfo; 9136 ComponentName comp = new ComponentName(ai.packageName, ai.name); 9137 doneReceivers.add(comp); 9138 intent.setComponent(comp); 9139 for (int j=0; j<users.length; j++) { 9140 IIntentReceiver finisher = null; 9141 if (i == ris.size()-1 && j == users.length-1) { 9142 finisher = new IIntentReceiver.Stub() { 9143 public void performReceive(Intent intent, int resultCode, 9144 String data, Bundle extras, boolean ordered, 9145 boolean sticky, int sendingUser) { 9146 // The raw IIntentReceiver interface is called 9147 // with the AM lock held, so redispatch to 9148 // execute our code without the lock. 9149 mHandler.post(new Runnable() { 9150 public void run() { 9151 synchronized (ActivityManagerService.this) { 9152 mDidUpdate = true; 9153 } 9154 writeLastDonePreBootReceivers(doneReceivers); 9155 showBootMessage(mContext.getText( 9156 R.string.android_upgrading_complete), 9157 false); 9158 systemReady(goingCallback); 9159 } 9160 }); 9161 } 9162 }; 9163 } 9164 Slog.i(TAG, "Sending system update to " + intent.getComponent() 9165 + " for user " + users[j]); 9166 broadcastIntentLocked(null, null, intent, null, finisher, 9167 0, null, null, null, AppOpsManager.OP_NONE, 9168 true, false, MY_PID, Process.SYSTEM_UID, 9169 users[j]); 9170 if (finisher != null) { 9171 mWaitingUpdate = true; 9172 } 9173 } 9174 } 9175 } 9176 if (mWaitingUpdate) { 9177 return; 9178 } 9179 mDidUpdate = true; 9180 } 9181 9182 mAppOpsService.systemReady(); 9183 mSystemReady = true; 9184 } 9185 9186 ArrayList<ProcessRecord> procsToKill = null; 9187 synchronized(mPidsSelfLocked) { 9188 for (int i=mPidsSelfLocked.size()-1; i>=0; i--) { 9189 ProcessRecord proc = mPidsSelfLocked.valueAt(i); 9190 if (!isAllowedWhileBooting(proc.info)){ 9191 if (procsToKill == null) { 9192 procsToKill = new ArrayList<ProcessRecord>(); 9193 } 9194 procsToKill.add(proc); 9195 } 9196 } 9197 } 9198 9199 synchronized(this) { 9200 if (procsToKill != null) { 9201 for (int i=procsToKill.size()-1; i>=0; i--) { 9202 ProcessRecord proc = procsToKill.get(i); 9203 Slog.i(TAG, "Removing system update proc: " + proc); 9204 removeProcessLocked(proc, true, false, "system update done"); 9205 } 9206 } 9207 9208 // Now that we have cleaned up any update processes, we 9209 // are ready to start launching real processes and know that 9210 // we won't trample on them any more. 9211 mProcessesReady = true; 9212 } 9213 9214 Slog.i(TAG, "System now ready"); 9215 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY, 9216 SystemClock.uptimeMillis()); 9217 9218 synchronized(this) { 9219 // Make sure we have no pre-ready processes sitting around. 9220 9221 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) { 9222 ResolveInfo ri = mContext.getPackageManager() 9223 .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST), 9224 STOCK_PM_FLAGS); 9225 CharSequence errorMsg = null; 9226 if (ri != null) { 9227 ActivityInfo ai = ri.activityInfo; 9228 ApplicationInfo app = ai.applicationInfo; 9229 if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) { 9230 mTopAction = Intent.ACTION_FACTORY_TEST; 9231 mTopData = null; 9232 mTopComponent = new ComponentName(app.packageName, 9233 ai.name); 9234 } else { 9235 errorMsg = mContext.getResources().getText( 9236 com.android.internal.R.string.factorytest_not_system); 9237 } 9238 } else { 9239 errorMsg = mContext.getResources().getText( 9240 com.android.internal.R.string.factorytest_no_action); 9241 } 9242 if (errorMsg != null) { 9243 mTopAction = null; 9244 mTopData = null; 9245 mTopComponent = null; 9246 Message msg = Message.obtain(); 9247 msg.what = SHOW_FACTORY_ERROR_MSG; 9248 msg.getData().putCharSequence("msg", errorMsg); 9249 mHandler.sendMessage(msg); 9250 } 9251 } 9252 } 9253 9254 retrieveSettings(); 9255 9256 synchronized (this) { 9257 readGrantedUriPermissionsLocked(); 9258 } 9259 9260 if (goingCallback != null) goingCallback.run(); 9261 9262 synchronized (this) { 9263 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 9264 try { 9265 List apps = AppGlobals.getPackageManager(). 9266 getPersistentApplications(STOCK_PM_FLAGS); 9267 if (apps != null) { 9268 int N = apps.size(); 9269 int i; 9270 for (i=0; i<N; i++) { 9271 ApplicationInfo info 9272 = (ApplicationInfo)apps.get(i); 9273 if (info != null && 9274 !info.packageName.equals("android")) { 9275 addAppLocked(info, false); 9276 } 9277 } 9278 } 9279 } catch (RemoteException ex) { 9280 // pm is in same process, this will never happen. 9281 } 9282 } 9283 9284 // Start up initial activity. 9285 mBooting = true; 9286 9287 try { 9288 if (AppGlobals.getPackageManager().hasSystemUidErrors()) { 9289 Message msg = Message.obtain(); 9290 msg.what = SHOW_UID_ERROR_MSG; 9291 mHandler.sendMessage(msg); 9292 } 9293 } catch (RemoteException e) { 9294 } 9295 9296 long ident = Binder.clearCallingIdentity(); 9297 try { 9298 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 9299 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 9300 | Intent.FLAG_RECEIVER_FOREGROUND); 9301 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); 9302 broadcastIntentLocked(null, null, intent, 9303 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 9304 false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId); 9305 intent = new Intent(Intent.ACTION_USER_STARTING); 9306 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 9307 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); 9308 broadcastIntentLocked(null, null, intent, 9309 null, new IIntentReceiver.Stub() { 9310 @Override 9311 public void performReceive(Intent intent, int resultCode, String data, 9312 Bundle extras, boolean ordered, boolean sticky, int sendingUser) 9313 throws RemoteException { 9314 } 9315 }, 0, null, null, 9316 android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 9317 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 9318 } finally { 9319 Binder.restoreCallingIdentity(ident); 9320 } 9321 mStackSupervisor.resumeTopActivitiesLocked(); 9322 sendUserSwitchBroadcastsLocked(-1, mCurrentUserId); 9323 } 9324 } 9325 9326 private boolean makeAppCrashingLocked(ProcessRecord app, 9327 String shortMsg, String longMsg, String stackTrace) { 9328 app.crashing = true; 9329 app.crashingReport = generateProcessError(app, 9330 ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace); 9331 startAppProblemLocked(app); 9332 app.stopFreezingAllLocked(); 9333 return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace); 9334 } 9335 9336 private void makeAppNotRespondingLocked(ProcessRecord app, 9337 String activity, String shortMsg, String longMsg) { 9338 app.notResponding = true; 9339 app.notRespondingReport = generateProcessError(app, 9340 ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING, 9341 activity, shortMsg, longMsg, null); 9342 startAppProblemLocked(app); 9343 app.stopFreezingAllLocked(); 9344 } 9345 9346 /** 9347 * Generate a process error record, suitable for attachment to a ProcessRecord. 9348 * 9349 * @param app The ProcessRecord in which the error occurred. 9350 * @param condition Crashing, Application Not Responding, etc. Values are defined in 9351 * ActivityManager.AppErrorStateInfo 9352 * @param activity The activity associated with the crash, if known. 9353 * @param shortMsg Short message describing the crash. 9354 * @param longMsg Long message describing the crash. 9355 * @param stackTrace Full crash stack trace, may be null. 9356 * 9357 * @return Returns a fully-formed AppErrorStateInfo record. 9358 */ 9359 private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app, 9360 int condition, String activity, String shortMsg, String longMsg, String stackTrace) { 9361 ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo(); 9362 9363 report.condition = condition; 9364 report.processName = app.processName; 9365 report.pid = app.pid; 9366 report.uid = app.info.uid; 9367 report.tag = activity; 9368 report.shortMsg = shortMsg; 9369 report.longMsg = longMsg; 9370 report.stackTrace = stackTrace; 9371 9372 return report; 9373 } 9374 9375 void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) { 9376 synchronized (this) { 9377 app.crashing = false; 9378 app.crashingReport = null; 9379 app.notResponding = false; 9380 app.notRespondingReport = null; 9381 if (app.anrDialog == fromDialog) { 9382 app.anrDialog = null; 9383 } 9384 if (app.waitDialog == fromDialog) { 9385 app.waitDialog = null; 9386 } 9387 if (app.pid > 0 && app.pid != MY_PID) { 9388 handleAppCrashLocked(app, null, null, null); 9389 killUnneededProcessLocked(app, "user request after error"); 9390 } 9391 } 9392 } 9393 9394 private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg, 9395 String stackTrace) { 9396 long now = SystemClock.uptimeMillis(); 9397 9398 Long crashTime; 9399 if (!app.isolated) { 9400 crashTime = mProcessCrashTimes.get(app.info.processName, app.uid); 9401 } else { 9402 crashTime = null; 9403 } 9404 if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) { 9405 // This process loses! 9406 Slog.w(TAG, "Process " + app.info.processName 9407 + " has crashed too many times: killing!"); 9408 EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH, 9409 app.userId, app.info.processName, app.uid); 9410 mStackSupervisor.handleAppCrashLocked(app); 9411 if (!app.persistent) { 9412 // We don't want to start this process again until the user 9413 // explicitly does so... but for persistent process, we really 9414 // need to keep it running. If a persistent process is actually 9415 // repeatedly crashing, then badness for everyone. 9416 EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid, 9417 app.info.processName); 9418 if (!app.isolated) { 9419 // XXX We don't have a way to mark isolated processes 9420 // as bad, since they don't have a peristent identity. 9421 mBadProcesses.put(app.info.processName, app.uid, 9422 new BadProcessInfo(now, shortMsg, longMsg, stackTrace)); 9423 mProcessCrashTimes.remove(app.info.processName, app.uid); 9424 } 9425 app.bad = true; 9426 app.removed = true; 9427 // Don't let services in this process be restarted and potentially 9428 // annoy the user repeatedly. Unless it is persistent, since those 9429 // processes run critical code. 9430 removeProcessLocked(app, false, false, "crash"); 9431 mStackSupervisor.resumeTopActivitiesLocked(); 9432 return false; 9433 } 9434 mStackSupervisor.resumeTopActivitiesLocked(); 9435 } else { 9436 mStackSupervisor.finishTopRunningActivityLocked(app); 9437 } 9438 9439 // Bump up the crash count of any services currently running in the proc. 9440 for (int i=app.services.size()-1; i>=0; i--) { 9441 // Any services running in the application need to be placed 9442 // back in the pending list. 9443 ServiceRecord sr = app.services.valueAt(i); 9444 sr.crashCount++; 9445 } 9446 9447 // If the crashing process is what we consider to be the "home process" and it has been 9448 // replaced by a third-party app, clear the package preferred activities from packages 9449 // with a home activity running in the process to prevent a repeatedly crashing app 9450 // from blocking the user to manually clear the list. 9451 final ArrayList<ActivityRecord> activities = app.activities; 9452 if (app == mHomeProcess && activities.size() > 0 9453 && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) { 9454 for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) { 9455 final ActivityRecord r = activities.get(activityNdx); 9456 if (r.isHomeActivity()) { 9457 Log.i(TAG, "Clearing package preferred activities from " + r.packageName); 9458 try { 9459 ActivityThread.getPackageManager() 9460 .clearPackagePreferredActivities(r.packageName); 9461 } catch (RemoteException c) { 9462 // pm is in same process, this will never happen. 9463 } 9464 } 9465 } 9466 } 9467 9468 if (!app.isolated) { 9469 // XXX Can't keep track of crash times for isolated processes, 9470 // because they don't have a perisistent identity. 9471 mProcessCrashTimes.put(app.info.processName, app.uid, now); 9472 } 9473 9474 return true; 9475 } 9476 9477 void startAppProblemLocked(ProcessRecord app) { 9478 if (app.userId == mCurrentUserId) { 9479 app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver( 9480 mContext, app.info.packageName, app.info.flags); 9481 } else { 9482 // If this app is not running under the current user, then we 9483 // can't give it a report button because that would require 9484 // launching the report UI under a different user. 9485 app.errorReportReceiver = null; 9486 } 9487 skipCurrentReceiverLocked(app); 9488 } 9489 9490 void skipCurrentReceiverLocked(ProcessRecord app) { 9491 for (BroadcastQueue queue : mBroadcastQueues) { 9492 queue.skipCurrentReceiverLocked(app); 9493 } 9494 } 9495 9496 /** 9497 * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes. 9498 * The application process will exit immediately after this call returns. 9499 * @param app object of the crashing app, null for the system server 9500 * @param crashInfo describing the exception 9501 */ 9502 public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) { 9503 ProcessRecord r = findAppProcess(app, "Crash"); 9504 final String processName = app == null ? "system_server" 9505 : (r == null ? "unknown" : r.processName); 9506 9507 handleApplicationCrashInner("crash", r, processName, crashInfo); 9508 } 9509 9510 /* Native crash reporting uses this inner version because it needs to be somewhat 9511 * decoupled from the AM-managed cleanup lifecycle 9512 */ 9513 void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName, 9514 ApplicationErrorReport.CrashInfo crashInfo) { 9515 EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(), 9516 UserHandle.getUserId(Binder.getCallingUid()), processName, 9517 r == null ? -1 : r.info.flags, 9518 crashInfo.exceptionClassName, 9519 crashInfo.exceptionMessage, 9520 crashInfo.throwFileName, 9521 crashInfo.throwLineNumber); 9522 9523 addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo); 9524 9525 crashApplication(r, crashInfo); 9526 } 9527 9528 public void handleApplicationStrictModeViolation( 9529 IBinder app, 9530 int violationMask, 9531 StrictMode.ViolationInfo info) { 9532 ProcessRecord r = findAppProcess(app, "StrictMode"); 9533 if (r == null) { 9534 return; 9535 } 9536 9537 if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) { 9538 Integer stackFingerprint = info.hashCode(); 9539 boolean logIt = true; 9540 synchronized (mAlreadyLoggedViolatedStacks) { 9541 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) { 9542 logIt = false; 9543 // TODO: sub-sample into EventLog for these, with 9544 // the info.durationMillis? Then we'd get 9545 // the relative pain numbers, without logging all 9546 // the stack traces repeatedly. We'd want to do 9547 // likewise in the client code, which also does 9548 // dup suppression, before the Binder call. 9549 } else { 9550 if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) { 9551 mAlreadyLoggedViolatedStacks.clear(); 9552 } 9553 mAlreadyLoggedViolatedStacks.add(stackFingerprint); 9554 } 9555 } 9556 if (logIt) { 9557 logStrictModeViolationToDropBox(r, info); 9558 } 9559 } 9560 9561 if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) { 9562 AppErrorResult result = new AppErrorResult(); 9563 synchronized (this) { 9564 final long origId = Binder.clearCallingIdentity(); 9565 9566 Message msg = Message.obtain(); 9567 msg.what = SHOW_STRICT_MODE_VIOLATION_MSG; 9568 HashMap<String, Object> data = new HashMap<String, Object>(); 9569 data.put("result", result); 9570 data.put("app", r); 9571 data.put("violationMask", violationMask); 9572 data.put("info", info); 9573 msg.obj = data; 9574 mHandler.sendMessage(msg); 9575 9576 Binder.restoreCallingIdentity(origId); 9577 } 9578 int res = result.get(); 9579 Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res); 9580 } 9581 } 9582 9583 // Depending on the policy in effect, there could be a bunch of 9584 // these in quick succession so we try to batch these together to 9585 // minimize disk writes, number of dropbox entries, and maximize 9586 // compression, by having more fewer, larger records. 9587 private void logStrictModeViolationToDropBox( 9588 ProcessRecord process, 9589 StrictMode.ViolationInfo info) { 9590 if (info == null) { 9591 return; 9592 } 9593 final boolean isSystemApp = process == null || 9594 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM | 9595 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0; 9596 final String processName = process == null ? "unknown" : process.processName; 9597 final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode"; 9598 final DropBoxManager dbox = (DropBoxManager) 9599 mContext.getSystemService(Context.DROPBOX_SERVICE); 9600 9601 // Exit early if the dropbox isn't configured to accept this report type. 9602 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 9603 9604 boolean bufferWasEmpty; 9605 boolean needsFlush; 9606 final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024); 9607 synchronized (sb) { 9608 bufferWasEmpty = sb.length() == 0; 9609 appendDropBoxProcessHeaders(process, processName, sb); 9610 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 9611 sb.append("System-App: ").append(isSystemApp).append("\n"); 9612 sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n"); 9613 if (info.violationNumThisLoop != 0) { 9614 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n"); 9615 } 9616 if (info.numAnimationsRunning != 0) { 9617 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n"); 9618 } 9619 if (info.broadcastIntentAction != null) { 9620 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n"); 9621 } 9622 if (info.durationMillis != -1) { 9623 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n"); 9624 } 9625 if (info.numInstances != -1) { 9626 sb.append("Instance-Count: ").append(info.numInstances).append("\n"); 9627 } 9628 if (info.tags != null) { 9629 for (String tag : info.tags) { 9630 sb.append("Span-Tag: ").append(tag).append("\n"); 9631 } 9632 } 9633 sb.append("\n"); 9634 if (info.crashInfo != null && info.crashInfo.stackTrace != null) { 9635 sb.append(info.crashInfo.stackTrace); 9636 } 9637 sb.append("\n"); 9638 9639 // Only buffer up to ~64k. Various logging bits truncate 9640 // things at 128k. 9641 needsFlush = (sb.length() > 64 * 1024); 9642 } 9643 9644 // Flush immediately if the buffer's grown too large, or this 9645 // is a non-system app. Non-system apps are isolated with a 9646 // different tag & policy and not batched. 9647 // 9648 // Batching is useful during internal testing with 9649 // StrictMode settings turned up high. Without batching, 9650 // thousands of separate files could be created on boot. 9651 if (!isSystemApp || needsFlush) { 9652 new Thread("Error dump: " + dropboxTag) { 9653 @Override 9654 public void run() { 9655 String report; 9656 synchronized (sb) { 9657 report = sb.toString(); 9658 sb.delete(0, sb.length()); 9659 sb.trimToSize(); 9660 } 9661 if (report.length() != 0) { 9662 dbox.addText(dropboxTag, report); 9663 } 9664 } 9665 }.start(); 9666 return; 9667 } 9668 9669 // System app batching: 9670 if (!bufferWasEmpty) { 9671 // An existing dropbox-writing thread is outstanding, so 9672 // we don't need to start it up. The existing thread will 9673 // catch the buffer appends we just did. 9674 return; 9675 } 9676 9677 // Worker thread to both batch writes and to avoid blocking the caller on I/O. 9678 // (After this point, we shouldn't access AMS internal data structures.) 9679 new Thread("Error dump: " + dropboxTag) { 9680 @Override 9681 public void run() { 9682 // 5 second sleep to let stacks arrive and be batched together 9683 try { 9684 Thread.sleep(5000); // 5 seconds 9685 } catch (InterruptedException e) {} 9686 9687 String errorReport; 9688 synchronized (mStrictModeBuffer) { 9689 errorReport = mStrictModeBuffer.toString(); 9690 if (errorReport.length() == 0) { 9691 return; 9692 } 9693 mStrictModeBuffer.delete(0, mStrictModeBuffer.length()); 9694 mStrictModeBuffer.trimToSize(); 9695 } 9696 dbox.addText(dropboxTag, errorReport); 9697 } 9698 }.start(); 9699 } 9700 9701 /** 9702 * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors. 9703 * @param app object of the crashing app, null for the system server 9704 * @param tag reported by the caller 9705 * @param crashInfo describing the context of the error 9706 * @return true if the process should exit immediately (WTF is fatal) 9707 */ 9708 public boolean handleApplicationWtf(IBinder app, String tag, 9709 ApplicationErrorReport.CrashInfo crashInfo) { 9710 ProcessRecord r = findAppProcess(app, "WTF"); 9711 final String processName = app == null ? "system_server" 9712 : (r == null ? "unknown" : r.processName); 9713 9714 EventLog.writeEvent(EventLogTags.AM_WTF, 9715 UserHandle.getUserId(Binder.getCallingUid()), Binder.getCallingPid(), 9716 processName, 9717 r == null ? -1 : r.info.flags, 9718 tag, crashInfo.exceptionMessage); 9719 9720 addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo); 9721 9722 if (r != null && r.pid != Process.myPid() && 9723 Settings.Global.getInt(mContext.getContentResolver(), 9724 Settings.Global.WTF_IS_FATAL, 0) != 0) { 9725 crashApplication(r, crashInfo); 9726 return true; 9727 } else { 9728 return false; 9729 } 9730 } 9731 9732 /** 9733 * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit}) 9734 * @return the corresponding {@link ProcessRecord} object, or null if none could be found 9735 */ 9736 private ProcessRecord findAppProcess(IBinder app, String reason) { 9737 if (app == null) { 9738 return null; 9739 } 9740 9741 synchronized (this) { 9742 final int NP = mProcessNames.getMap().size(); 9743 for (int ip=0; ip<NP; ip++) { 9744 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 9745 final int NA = apps.size(); 9746 for (int ia=0; ia<NA; ia++) { 9747 ProcessRecord p = apps.valueAt(ia); 9748 if (p.thread != null && p.thread.asBinder() == app) { 9749 return p; 9750 } 9751 } 9752 } 9753 9754 Slog.w(TAG, "Can't find mystery application for " + reason 9755 + " from pid=" + Binder.getCallingPid() 9756 + " uid=" + Binder.getCallingUid() + ": " + app); 9757 return null; 9758 } 9759 } 9760 9761 /** 9762 * Utility function for addErrorToDropBox and handleStrictModeViolation's logging 9763 * to append various headers to the dropbox log text. 9764 */ 9765 private void appendDropBoxProcessHeaders(ProcessRecord process, String processName, 9766 StringBuilder sb) { 9767 // Watchdog thread ends up invoking this function (with 9768 // a null ProcessRecord) to add the stack file to dropbox. 9769 // Do not acquire a lock on this (am) in such cases, as it 9770 // could cause a potential deadlock, if and when watchdog 9771 // is invoked due to unavailability of lock on am and it 9772 // would prevent watchdog from killing system_server. 9773 if (process == null) { 9774 sb.append("Process: ").append(processName).append("\n"); 9775 return; 9776 } 9777 // Note: ProcessRecord 'process' is guarded by the service 9778 // instance. (notably process.pkgList, which could otherwise change 9779 // concurrently during execution of this method) 9780 synchronized (this) { 9781 sb.append("Process: ").append(processName).append("\n"); 9782 int flags = process.info.flags; 9783 IPackageManager pm = AppGlobals.getPackageManager(); 9784 sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n"); 9785 for (int ip=0; ip<process.pkgList.size(); ip++) { 9786 String pkg = process.pkgList.keyAt(ip); 9787 sb.append("Package: ").append(pkg); 9788 try { 9789 PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId()); 9790 if (pi != null) { 9791 sb.append(" v").append(pi.versionCode); 9792 if (pi.versionName != null) { 9793 sb.append(" (").append(pi.versionName).append(")"); 9794 } 9795 } 9796 } catch (RemoteException e) { 9797 Slog.e(TAG, "Error getting package info: " + pkg, e); 9798 } 9799 sb.append("\n"); 9800 } 9801 } 9802 } 9803 9804 private static String processClass(ProcessRecord process) { 9805 if (process == null || process.pid == MY_PID) { 9806 return "system_server"; 9807 } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) { 9808 return "system_app"; 9809 } else { 9810 return "data_app"; 9811 } 9812 } 9813 9814 /** 9815 * Write a description of an error (crash, WTF, ANR) to the drop box. 9816 * @param eventType to include in the drop box tag ("crash", "wtf", etc.) 9817 * @param process which caused the error, null means the system server 9818 * @param activity which triggered the error, null if unknown 9819 * @param parent activity related to the error, null if unknown 9820 * @param subject line related to the error, null if absent 9821 * @param report in long form describing the error, null if absent 9822 * @param logFile to include in the report, null if none 9823 * @param crashInfo giving an application stack trace, null if absent 9824 */ 9825 public void addErrorToDropBox(String eventType, 9826 ProcessRecord process, String processName, ActivityRecord activity, 9827 ActivityRecord parent, String subject, 9828 final String report, final File logFile, 9829 final ApplicationErrorReport.CrashInfo crashInfo) { 9830 // NOTE -- this must never acquire the ActivityManagerService lock, 9831 // otherwise the watchdog may be prevented from resetting the system. 9832 9833 final String dropboxTag = processClass(process) + "_" + eventType; 9834 final DropBoxManager dbox = (DropBoxManager) 9835 mContext.getSystemService(Context.DROPBOX_SERVICE); 9836 9837 // Exit early if the dropbox isn't configured to accept this report type. 9838 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 9839 9840 final StringBuilder sb = new StringBuilder(1024); 9841 appendDropBoxProcessHeaders(process, processName, sb); 9842 if (activity != null) { 9843 sb.append("Activity: ").append(activity.shortComponentName).append("\n"); 9844 } 9845 if (parent != null && parent.app != null && parent.app.pid != process.pid) { 9846 sb.append("Parent-Process: ").append(parent.app.processName).append("\n"); 9847 } 9848 if (parent != null && parent != activity) { 9849 sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n"); 9850 } 9851 if (subject != null) { 9852 sb.append("Subject: ").append(subject).append("\n"); 9853 } 9854 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 9855 if (Debug.isDebuggerConnected()) { 9856 sb.append("Debugger: Connected\n"); 9857 } 9858 sb.append("\n"); 9859 9860 // Do the rest in a worker thread to avoid blocking the caller on I/O 9861 // (After this point, we shouldn't access AMS internal data structures.) 9862 Thread worker = new Thread("Error dump: " + dropboxTag) { 9863 @Override 9864 public void run() { 9865 if (report != null) { 9866 sb.append(report); 9867 } 9868 if (logFile != null) { 9869 try { 9870 sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE, 9871 "\n\n[[TRUNCATED]]")); 9872 } catch (IOException e) { 9873 Slog.e(TAG, "Error reading " + logFile, e); 9874 } 9875 } 9876 if (crashInfo != null && crashInfo.stackTrace != null) { 9877 sb.append(crashInfo.stackTrace); 9878 } 9879 9880 String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag; 9881 int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0); 9882 if (lines > 0) { 9883 sb.append("\n"); 9884 9885 // Merge several logcat streams, and take the last N lines 9886 InputStreamReader input = null; 9887 try { 9888 java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat", 9889 "-v", "time", "-b", "events", "-b", "system", "-b", "main", 9890 "-t", String.valueOf(lines)).redirectErrorStream(true).start(); 9891 9892 try { logcat.getOutputStream().close(); } catch (IOException e) {} 9893 try { logcat.getErrorStream().close(); } catch (IOException e) {} 9894 input = new InputStreamReader(logcat.getInputStream()); 9895 9896 int num; 9897 char[] buf = new char[8192]; 9898 while ((num = input.read(buf)) > 0) sb.append(buf, 0, num); 9899 } catch (IOException e) { 9900 Slog.e(TAG, "Error running logcat", e); 9901 } finally { 9902 if (input != null) try { input.close(); } catch (IOException e) {} 9903 } 9904 } 9905 9906 dbox.addText(dropboxTag, sb.toString()); 9907 } 9908 }; 9909 9910 if (process == null) { 9911 // If process is null, we are being called from some internal code 9912 // and may be about to die -- run this synchronously. 9913 worker.run(); 9914 } else { 9915 worker.start(); 9916 } 9917 } 9918 9919 /** 9920 * Bring up the "unexpected error" dialog box for a crashing app. 9921 * Deal with edge cases (intercepts from instrumented applications, 9922 * ActivityController, error intent receivers, that sort of thing). 9923 * @param r the application crashing 9924 * @param crashInfo describing the failure 9925 */ 9926 private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) { 9927 long timeMillis = System.currentTimeMillis(); 9928 String shortMsg = crashInfo.exceptionClassName; 9929 String longMsg = crashInfo.exceptionMessage; 9930 String stackTrace = crashInfo.stackTrace; 9931 if (shortMsg != null && longMsg != null) { 9932 longMsg = shortMsg + ": " + longMsg; 9933 } else if (shortMsg != null) { 9934 longMsg = shortMsg; 9935 } 9936 9937 AppErrorResult result = new AppErrorResult(); 9938 synchronized (this) { 9939 if (mController != null) { 9940 try { 9941 String name = r != null ? r.processName : null; 9942 int pid = r != null ? r.pid : Binder.getCallingPid(); 9943 if (!mController.appCrashed(name, pid, 9944 shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) { 9945 Slog.w(TAG, "Force-killing crashed app " + name 9946 + " at watcher's request"); 9947 Process.killProcess(pid); 9948 return; 9949 } 9950 } catch (RemoteException e) { 9951 mController = null; 9952 Watchdog.getInstance().setActivityController(null); 9953 } 9954 } 9955 9956 final long origId = Binder.clearCallingIdentity(); 9957 9958 // If this process is running instrumentation, finish it. 9959 if (r != null && r.instrumentationClass != null) { 9960 Slog.w(TAG, "Error in app " + r.processName 9961 + " running instrumentation " + r.instrumentationClass + ":"); 9962 if (shortMsg != null) Slog.w(TAG, " " + shortMsg); 9963 if (longMsg != null) Slog.w(TAG, " " + longMsg); 9964 Bundle info = new Bundle(); 9965 info.putString("shortMsg", shortMsg); 9966 info.putString("longMsg", longMsg); 9967 finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info); 9968 Binder.restoreCallingIdentity(origId); 9969 return; 9970 } 9971 9972 // If we can't identify the process or it's already exceeded its crash quota, 9973 // quit right away without showing a crash dialog. 9974 if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) { 9975 Binder.restoreCallingIdentity(origId); 9976 return; 9977 } 9978 9979 Message msg = Message.obtain(); 9980 msg.what = SHOW_ERROR_MSG; 9981 HashMap data = new HashMap(); 9982 data.put("result", result); 9983 data.put("app", r); 9984 msg.obj = data; 9985 mHandler.sendMessage(msg); 9986 9987 Binder.restoreCallingIdentity(origId); 9988 } 9989 9990 int res = result.get(); 9991 9992 Intent appErrorIntent = null; 9993 synchronized (this) { 9994 if (r != null && !r.isolated) { 9995 // XXX Can't keep track of crash time for isolated processes, 9996 // since they don't have a persistent identity. 9997 mProcessCrashTimes.put(r.info.processName, r.uid, 9998 SystemClock.uptimeMillis()); 9999 } 10000 if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) { 10001 appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo); 10002 } 10003 } 10004 10005 if (appErrorIntent != null) { 10006 try { 10007 mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId)); 10008 } catch (ActivityNotFoundException e) { 10009 Slog.w(TAG, "bug report receiver dissappeared", e); 10010 } 10011 } 10012 } 10013 10014 Intent createAppErrorIntentLocked(ProcessRecord r, 10015 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 10016 ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo); 10017 if (report == null) { 10018 return null; 10019 } 10020 Intent result = new Intent(Intent.ACTION_APP_ERROR); 10021 result.setComponent(r.errorReportReceiver); 10022 result.putExtra(Intent.EXTRA_BUG_REPORT, report); 10023 result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 10024 return result; 10025 } 10026 10027 private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r, 10028 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 10029 if (r.errorReportReceiver == null) { 10030 return null; 10031 } 10032 10033 if (!r.crashing && !r.notResponding && !r.forceCrashReport) { 10034 return null; 10035 } 10036 10037 ApplicationErrorReport report = new ApplicationErrorReport(); 10038 report.packageName = r.info.packageName; 10039 report.installerPackageName = r.errorReportReceiver.getPackageName(); 10040 report.processName = r.processName; 10041 report.time = timeMillis; 10042 report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0; 10043 10044 if (r.crashing || r.forceCrashReport) { 10045 report.type = ApplicationErrorReport.TYPE_CRASH; 10046 report.crashInfo = crashInfo; 10047 } else if (r.notResponding) { 10048 report.type = ApplicationErrorReport.TYPE_ANR; 10049 report.anrInfo = new ApplicationErrorReport.AnrInfo(); 10050 10051 report.anrInfo.activity = r.notRespondingReport.tag; 10052 report.anrInfo.cause = r.notRespondingReport.shortMsg; 10053 report.anrInfo.info = r.notRespondingReport.longMsg; 10054 } 10055 10056 return report; 10057 } 10058 10059 public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() { 10060 enforceNotIsolatedCaller("getProcessesInErrorState"); 10061 // assume our apps are happy - lazy create the list 10062 List<ActivityManager.ProcessErrorStateInfo> errList = null; 10063 10064 final boolean allUsers = ActivityManager.checkUidPermission( 10065 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 10066 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 10067 int userId = UserHandle.getUserId(Binder.getCallingUid()); 10068 10069 synchronized (this) { 10070 10071 // iterate across all processes 10072 for (int i=mLruProcesses.size()-1; i>=0; i--) { 10073 ProcessRecord app = mLruProcesses.get(i); 10074 if (!allUsers && app.userId != userId) { 10075 continue; 10076 } 10077 if ((app.thread != null) && (app.crashing || app.notResponding)) { 10078 // This one's in trouble, so we'll generate a report for it 10079 // crashes are higher priority (in case there's a crash *and* an anr) 10080 ActivityManager.ProcessErrorStateInfo report = null; 10081 if (app.crashing) { 10082 report = app.crashingReport; 10083 } else if (app.notResponding) { 10084 report = app.notRespondingReport; 10085 } 10086 10087 if (report != null) { 10088 if (errList == null) { 10089 errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1); 10090 } 10091 errList.add(report); 10092 } else { 10093 Slog.w(TAG, "Missing app error report, app = " + app.processName + 10094 " crashing = " + app.crashing + 10095 " notResponding = " + app.notResponding); 10096 } 10097 } 10098 } 10099 } 10100 10101 return errList; 10102 } 10103 10104 static int oomAdjToImportance(int adj, ActivityManager.RunningAppProcessInfo currApp) { 10105 if (adj >= ProcessList.CACHED_APP_MIN_ADJ) { 10106 if (currApp != null) { 10107 currApp.lru = adj - ProcessList.CACHED_APP_MIN_ADJ + 1; 10108 } 10109 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 10110 } else if (adj >= ProcessList.SERVICE_B_ADJ) { 10111 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 10112 } else if (adj >= ProcessList.HOME_APP_ADJ) { 10113 if (currApp != null) { 10114 currApp.lru = 0; 10115 } 10116 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 10117 } else if (adj >= ProcessList.SERVICE_ADJ) { 10118 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 10119 } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 10120 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE; 10121 } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) { 10122 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE; 10123 } else if (adj >= ProcessList.VISIBLE_APP_ADJ) { 10124 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE; 10125 } else { 10126 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND; 10127 } 10128 } 10129 10130 private void fillInProcMemInfo(ProcessRecord app, 10131 ActivityManager.RunningAppProcessInfo outInfo) { 10132 outInfo.pid = app.pid; 10133 outInfo.uid = app.info.uid; 10134 if (mHeavyWeightProcess == app) { 10135 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE; 10136 } 10137 if (app.persistent) { 10138 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT; 10139 } 10140 if (app.activities.size() > 0) { 10141 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES; 10142 } 10143 outInfo.lastTrimLevel = app.trimMemoryLevel; 10144 int adj = app.curAdj; 10145 outInfo.importance = oomAdjToImportance(adj, outInfo); 10146 outInfo.importanceReasonCode = app.adjTypeCode; 10147 } 10148 10149 public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() { 10150 enforceNotIsolatedCaller("getRunningAppProcesses"); 10151 // Lazy instantiation of list 10152 List<ActivityManager.RunningAppProcessInfo> runList = null; 10153 final boolean allUsers = ActivityManager.checkUidPermission( 10154 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 10155 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 10156 int userId = UserHandle.getUserId(Binder.getCallingUid()); 10157 synchronized (this) { 10158 // Iterate across all processes 10159 for (int i=mLruProcesses.size()-1; i>=0; i--) { 10160 ProcessRecord app = mLruProcesses.get(i); 10161 if (!allUsers && app.userId != userId) { 10162 continue; 10163 } 10164 if ((app.thread != null) && (!app.crashing && !app.notResponding)) { 10165 // Generate process state info for running application 10166 ActivityManager.RunningAppProcessInfo currApp = 10167 new ActivityManager.RunningAppProcessInfo(app.processName, 10168 app.pid, app.getPackageList()); 10169 fillInProcMemInfo(app, currApp); 10170 if (app.adjSource instanceof ProcessRecord) { 10171 currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid; 10172 currApp.importanceReasonImportance = oomAdjToImportance( 10173 app.adjSourceOom, null); 10174 } else if (app.adjSource instanceof ActivityRecord) { 10175 ActivityRecord r = (ActivityRecord)app.adjSource; 10176 if (r.app != null) currApp.importanceReasonPid = r.app.pid; 10177 } 10178 if (app.adjTarget instanceof ComponentName) { 10179 currApp.importanceReasonComponent = (ComponentName)app.adjTarget; 10180 } 10181 //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance 10182 // + " lru=" + currApp.lru); 10183 if (runList == null) { 10184 runList = new ArrayList<ActivityManager.RunningAppProcessInfo>(); 10185 } 10186 runList.add(currApp); 10187 } 10188 } 10189 } 10190 return runList; 10191 } 10192 10193 public List<ApplicationInfo> getRunningExternalApplications() { 10194 enforceNotIsolatedCaller("getRunningExternalApplications"); 10195 List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses(); 10196 List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>(); 10197 if (runningApps != null && runningApps.size() > 0) { 10198 Set<String> extList = new HashSet<String>(); 10199 for (ActivityManager.RunningAppProcessInfo app : runningApps) { 10200 if (app.pkgList != null) { 10201 for (String pkg : app.pkgList) { 10202 extList.add(pkg); 10203 } 10204 } 10205 } 10206 IPackageManager pm = AppGlobals.getPackageManager(); 10207 for (String pkg : extList) { 10208 try { 10209 ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId()); 10210 if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) { 10211 retList.add(info); 10212 } 10213 } catch (RemoteException e) { 10214 } 10215 } 10216 } 10217 return retList; 10218 } 10219 10220 @Override 10221 public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) { 10222 enforceNotIsolatedCaller("getMyMemoryState"); 10223 synchronized (this) { 10224 ProcessRecord proc; 10225 synchronized (mPidsSelfLocked) { 10226 proc = mPidsSelfLocked.get(Binder.getCallingPid()); 10227 } 10228 fillInProcMemInfo(proc, outInfo); 10229 } 10230 } 10231 10232 @Override 10233 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 10234 if (checkCallingPermission(android.Manifest.permission.DUMP) 10235 != PackageManager.PERMISSION_GRANTED) { 10236 pw.println("Permission Denial: can't dump ActivityManager from from pid=" 10237 + Binder.getCallingPid() 10238 + ", uid=" + Binder.getCallingUid() 10239 + " without permission " 10240 + android.Manifest.permission.DUMP); 10241 return; 10242 } 10243 10244 boolean dumpAll = false; 10245 boolean dumpClient = false; 10246 String dumpPackage = null; 10247 10248 int opti = 0; 10249 while (opti < args.length) { 10250 String opt = args[opti]; 10251 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 10252 break; 10253 } 10254 opti++; 10255 if ("-a".equals(opt)) { 10256 dumpAll = true; 10257 } else if ("-c".equals(opt)) { 10258 dumpClient = true; 10259 } else if ("-h".equals(opt)) { 10260 pw.println("Activity manager dump options:"); 10261 pw.println(" [-a] [-c] [-h] [cmd] ..."); 10262 pw.println(" cmd may be one of:"); 10263 pw.println(" a[ctivities]: activity stack state"); 10264 pw.println(" b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state"); 10265 pw.println(" i[ntents] [PACKAGE_NAME]: pending intent state"); 10266 pw.println(" p[rocesses] [PACKAGE_NAME]: process state"); 10267 pw.println(" o[om]: out of memory management"); 10268 pw.println(" prov[iders] [COMP_SPEC ...]: content provider state"); 10269 pw.println(" provider [COMP_SPEC]: provider client-side state"); 10270 pw.println(" s[ervices] [COMP_SPEC ...]: service state"); 10271 pw.println(" service [COMP_SPEC]: service client-side state"); 10272 pw.println(" package [PACKAGE_NAME]: all state related to given package"); 10273 pw.println(" all: dump all activities"); 10274 pw.println(" top: dump the top activity"); 10275 pw.println(" cmd may also be a COMP_SPEC to dump activities."); 10276 pw.println(" COMP_SPEC may be a component name (com.foo/.myApp),"); 10277 pw.println(" a partial substring in a component name, a"); 10278 pw.println(" hex object identifier."); 10279 pw.println(" -a: include all available server state."); 10280 pw.println(" -c: include client state."); 10281 return; 10282 } else { 10283 pw.println("Unknown argument: " + opt + "; use -h for help"); 10284 } 10285 } 10286 10287 long origId = Binder.clearCallingIdentity(); 10288 boolean more = false; 10289 // Is the caller requesting to dump a particular piece of data? 10290 if (opti < args.length) { 10291 String cmd = args[opti]; 10292 opti++; 10293 if ("activities".equals(cmd) || "a".equals(cmd)) { 10294 synchronized (this) { 10295 dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null); 10296 } 10297 } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) { 10298 String[] newArgs; 10299 String name; 10300 if (opti >= args.length) { 10301 name = null; 10302 newArgs = EMPTY_STRING_ARRAY; 10303 } else { 10304 name = args[opti]; 10305 opti++; 10306 newArgs = new String[args.length - opti]; 10307 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 10308 args.length - opti); 10309 } 10310 synchronized (this) { 10311 dumpBroadcastsLocked(fd, pw, args, opti, true, name); 10312 } 10313 } else if ("intents".equals(cmd) || "i".equals(cmd)) { 10314 String[] newArgs; 10315 String name; 10316 if (opti >= args.length) { 10317 name = null; 10318 newArgs = EMPTY_STRING_ARRAY; 10319 } else { 10320 name = args[opti]; 10321 opti++; 10322 newArgs = new String[args.length - opti]; 10323 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 10324 args.length - opti); 10325 } 10326 synchronized (this) { 10327 dumpPendingIntentsLocked(fd, pw, args, opti, true, name); 10328 } 10329 } else if ("processes".equals(cmd) || "p".equals(cmd)) { 10330 String[] newArgs; 10331 String name; 10332 if (opti >= args.length) { 10333 name = null; 10334 newArgs = EMPTY_STRING_ARRAY; 10335 } else { 10336 name = args[opti]; 10337 opti++; 10338 newArgs = new String[args.length - opti]; 10339 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 10340 args.length - opti); 10341 } 10342 synchronized (this) { 10343 dumpProcessesLocked(fd, pw, args, opti, true, name); 10344 } 10345 } else if ("oom".equals(cmd) || "o".equals(cmd)) { 10346 synchronized (this) { 10347 dumpOomLocked(fd, pw, args, opti, true); 10348 } 10349 } else if ("provider".equals(cmd)) { 10350 String[] newArgs; 10351 String name; 10352 if (opti >= args.length) { 10353 name = null; 10354 newArgs = EMPTY_STRING_ARRAY; 10355 } else { 10356 name = args[opti]; 10357 opti++; 10358 newArgs = new String[args.length - opti]; 10359 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti); 10360 } 10361 if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) { 10362 pw.println("No providers match: " + name); 10363 pw.println("Use -h for help."); 10364 } 10365 } else if ("providers".equals(cmd) || "prov".equals(cmd)) { 10366 synchronized (this) { 10367 dumpProvidersLocked(fd, pw, args, opti, true, null); 10368 } 10369 } else if ("service".equals(cmd)) { 10370 String[] newArgs; 10371 String name; 10372 if (opti >= args.length) { 10373 name = null; 10374 newArgs = EMPTY_STRING_ARRAY; 10375 } else { 10376 name = args[opti]; 10377 opti++; 10378 newArgs = new String[args.length - opti]; 10379 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 10380 args.length - opti); 10381 } 10382 if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) { 10383 pw.println("No services match: " + name); 10384 pw.println("Use -h for help."); 10385 } 10386 } else if ("package".equals(cmd)) { 10387 String[] newArgs; 10388 if (opti >= args.length) { 10389 pw.println("package: no package name specified"); 10390 pw.println("Use -h for help."); 10391 } else { 10392 dumpPackage = args[opti]; 10393 opti++; 10394 newArgs = new String[args.length - opti]; 10395 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 10396 args.length - opti); 10397 args = newArgs; 10398 opti = 0; 10399 more = true; 10400 } 10401 } else if ("services".equals(cmd) || "s".equals(cmd)) { 10402 synchronized (this) { 10403 mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null); 10404 } 10405 } else { 10406 // Dumping a single activity? 10407 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) { 10408 pw.println("Bad activity command, or no activities match: " + cmd); 10409 pw.println("Use -h for help."); 10410 } 10411 } 10412 if (!more) { 10413 Binder.restoreCallingIdentity(origId); 10414 return; 10415 } 10416 } 10417 10418 // No piece of data specified, dump everything. 10419 synchronized (this) { 10420 dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 10421 pw.println(); 10422 if (dumpAll) { 10423 pw.println("-------------------------------------------------------------------------------"); 10424 } 10425 dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 10426 pw.println(); 10427 if (dumpAll) { 10428 pw.println("-------------------------------------------------------------------------------"); 10429 } 10430 dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage); 10431 pw.println(); 10432 if (dumpAll) { 10433 pw.println("-------------------------------------------------------------------------------"); 10434 } 10435 mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 10436 pw.println(); 10437 if (dumpAll) { 10438 pw.println("-------------------------------------------------------------------------------"); 10439 } 10440 dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 10441 pw.println(); 10442 if (dumpAll) { 10443 pw.println("-------------------------------------------------------------------------------"); 10444 } 10445 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage); 10446 } 10447 Binder.restoreCallingIdentity(origId); 10448 } 10449 10450 void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 10451 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) { 10452 pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)"); 10453 10454 boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient, 10455 dumpPackage); 10456 boolean needSep = printedAnything; 10457 10458 boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity, 10459 dumpPackage, needSep, " mFocusedActivity: "); 10460 if (printed) { 10461 printedAnything = true; 10462 needSep = false; 10463 } 10464 10465 if (dumpPackage == null) { 10466 if (needSep) { 10467 pw.println(); 10468 } 10469 needSep = true; 10470 printedAnything = true; 10471 mStackSupervisor.dump(pw, " "); 10472 } 10473 10474 if (mRecentTasks.size() > 0) { 10475 boolean printedHeader = false; 10476 10477 final int N = mRecentTasks.size(); 10478 for (int i=0; i<N; i++) { 10479 TaskRecord tr = mRecentTasks.get(i); 10480 if (dumpPackage != null) { 10481 if (tr.realActivity == null || 10482 !dumpPackage.equals(tr.realActivity)) { 10483 continue; 10484 } 10485 } 10486 if (!printedHeader) { 10487 if (needSep) { 10488 pw.println(); 10489 } 10490 pw.println(" Recent tasks:"); 10491 printedHeader = true; 10492 printedAnything = true; 10493 } 10494 pw.print(" * Recent #"); pw.print(i); pw.print(": "); 10495 pw.println(tr); 10496 if (dumpAll) { 10497 mRecentTasks.get(i).dump(pw, " "); 10498 } 10499 } 10500 } 10501 10502 if (!printedAnything) { 10503 pw.println(" (nothing)"); 10504 } 10505 } 10506 10507 void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 10508 int opti, boolean dumpAll, String dumpPackage) { 10509 boolean needSep = false; 10510 boolean printedAnything = false; 10511 int numPers = 0; 10512 10513 pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)"); 10514 10515 if (dumpAll) { 10516 final int NP = mProcessNames.getMap().size(); 10517 for (int ip=0; ip<NP; ip++) { 10518 SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip); 10519 final int NA = procs.size(); 10520 for (int ia=0; ia<NA; ia++) { 10521 ProcessRecord r = procs.valueAt(ia); 10522 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 10523 continue; 10524 } 10525 if (!needSep) { 10526 pw.println(" All known processes:"); 10527 needSep = true; 10528 printedAnything = true; 10529 } 10530 pw.print(r.persistent ? " *PERS*" : " *APP*"); 10531 pw.print(" UID "); pw.print(procs.keyAt(ia)); 10532 pw.print(" "); pw.println(r); 10533 r.dump(pw, " "); 10534 if (r.persistent) { 10535 numPers++; 10536 } 10537 } 10538 } 10539 } 10540 10541 if (mIsolatedProcesses.size() > 0) { 10542 boolean printed = false; 10543 for (int i=0; i<mIsolatedProcesses.size(); i++) { 10544 ProcessRecord r = mIsolatedProcesses.valueAt(i); 10545 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 10546 continue; 10547 } 10548 if (!printed) { 10549 if (needSep) { 10550 pw.println(); 10551 } 10552 pw.println(" Isolated process list (sorted by uid):"); 10553 printedAnything = true; 10554 printed = true; 10555 needSep = true; 10556 } 10557 pw.println(String.format("%sIsolated #%2d: %s", 10558 " ", i, r.toString())); 10559 } 10560 } 10561 10562 if (mLruProcesses.size() > 0) { 10563 if (needSep) { 10564 pw.println(); 10565 } 10566 pw.print(" Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size()); 10567 pw.print(" total, non-act at "); 10568 pw.print(mLruProcesses.size()-mLruProcessActivityStart); 10569 pw.print(", non-svc at "); 10570 pw.print(mLruProcesses.size()-mLruProcessServiceStart); 10571 pw.println("):"); 10572 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", false, dumpPackage); 10573 needSep = true; 10574 printedAnything = true; 10575 } 10576 10577 if (dumpAll || dumpPackage != null) { 10578 synchronized (mPidsSelfLocked) { 10579 boolean printed = false; 10580 for (int i=0; i<mPidsSelfLocked.size(); i++) { 10581 ProcessRecord r = mPidsSelfLocked.valueAt(i); 10582 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 10583 continue; 10584 } 10585 if (!printed) { 10586 if (needSep) pw.println(); 10587 needSep = true; 10588 pw.println(" PID mappings:"); 10589 printed = true; 10590 printedAnything = true; 10591 } 10592 pw.print(" PID #"); pw.print(mPidsSelfLocked.keyAt(i)); 10593 pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i)); 10594 } 10595 } 10596 } 10597 10598 if (mForegroundProcesses.size() > 0) { 10599 synchronized (mPidsSelfLocked) { 10600 boolean printed = false; 10601 for (int i=0; i<mForegroundProcesses.size(); i++) { 10602 ProcessRecord r = mPidsSelfLocked.get( 10603 mForegroundProcesses.valueAt(i).pid); 10604 if (dumpPackage != null && (r == null 10605 || !r.pkgList.containsKey(dumpPackage))) { 10606 continue; 10607 } 10608 if (!printed) { 10609 if (needSep) pw.println(); 10610 needSep = true; 10611 pw.println(" Foreground Processes:"); 10612 printed = true; 10613 printedAnything = true; 10614 } 10615 pw.print(" PID #"); pw.print(mForegroundProcesses.keyAt(i)); 10616 pw.print(": "); pw.println(mForegroundProcesses.valueAt(i)); 10617 } 10618 } 10619 } 10620 10621 if (mPersistentStartingProcesses.size() > 0) { 10622 if (needSep) pw.println(); 10623 needSep = true; 10624 printedAnything = true; 10625 pw.println(" Persisent processes that are starting:"); 10626 dumpProcessList(pw, this, mPersistentStartingProcesses, " ", 10627 "Starting Norm", "Restarting PERS", dumpPackage); 10628 } 10629 10630 if (mRemovedProcesses.size() > 0) { 10631 if (needSep) pw.println(); 10632 needSep = true; 10633 printedAnything = true; 10634 pw.println(" Processes that are being removed:"); 10635 dumpProcessList(pw, this, mRemovedProcesses, " ", 10636 "Removed Norm", "Removed PERS", dumpPackage); 10637 } 10638 10639 if (mProcessesOnHold.size() > 0) { 10640 if (needSep) pw.println(); 10641 needSep = true; 10642 printedAnything = true; 10643 pw.println(" Processes that are on old until the system is ready:"); 10644 dumpProcessList(pw, this, mProcessesOnHold, " ", 10645 "OnHold Norm", "OnHold PERS", dumpPackage); 10646 } 10647 10648 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage); 10649 10650 if (mProcessCrashTimes.getMap().size() > 0) { 10651 boolean printed = false; 10652 long now = SystemClock.uptimeMillis(); 10653 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap(); 10654 final int NP = pmap.size(); 10655 for (int ip=0; ip<NP; ip++) { 10656 String pname = pmap.keyAt(ip); 10657 SparseArray<Long> uids = pmap.valueAt(ip); 10658 final int N = uids.size(); 10659 for (int i=0; i<N; i++) { 10660 int puid = uids.keyAt(i); 10661 ProcessRecord r = mProcessNames.get(pname, puid); 10662 if (dumpPackage != null && (r == null 10663 || !r.pkgList.containsKey(dumpPackage))) { 10664 continue; 10665 } 10666 if (!printed) { 10667 if (needSep) pw.println(); 10668 needSep = true; 10669 pw.println(" Time since processes crashed:"); 10670 printed = true; 10671 printedAnything = true; 10672 } 10673 pw.print(" Process "); pw.print(pname); 10674 pw.print(" uid "); pw.print(puid); 10675 pw.print(": last crashed "); 10676 TimeUtils.formatDuration(now-uids.valueAt(i), pw); 10677 pw.println(" ago"); 10678 } 10679 } 10680 } 10681 10682 if (mBadProcesses.getMap().size() > 0) { 10683 boolean printed = false; 10684 final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap(); 10685 final int NP = pmap.size(); 10686 for (int ip=0; ip<NP; ip++) { 10687 String pname = pmap.keyAt(ip); 10688 SparseArray<BadProcessInfo> uids = pmap.valueAt(ip); 10689 final int N = uids.size(); 10690 for (int i=0; i<N; i++) { 10691 int puid = uids.keyAt(i); 10692 ProcessRecord r = mProcessNames.get(pname, puid); 10693 if (dumpPackage != null && (r == null 10694 || !r.pkgList.containsKey(dumpPackage))) { 10695 continue; 10696 } 10697 if (!printed) { 10698 if (needSep) pw.println(); 10699 needSep = true; 10700 pw.println(" Bad processes:"); 10701 printedAnything = true; 10702 } 10703 BadProcessInfo info = uids.valueAt(i); 10704 pw.print(" Bad process "); pw.print(pname); 10705 pw.print(" uid "); pw.print(puid); 10706 pw.print(": crashed at time "); pw.println(info.time); 10707 if (info.shortMsg != null) { 10708 pw.print(" Short msg: "); pw.println(info.shortMsg); 10709 } 10710 if (info.longMsg != null) { 10711 pw.print(" Long msg: "); pw.println(info.longMsg); 10712 } 10713 if (info.stack != null) { 10714 pw.println(" Stack:"); 10715 int lastPos = 0; 10716 for (int pos=0; pos<info.stack.length(); pos++) { 10717 if (info.stack.charAt(pos) == '\n') { 10718 pw.print(" "); 10719 pw.write(info.stack, lastPos, pos-lastPos); 10720 pw.println(); 10721 lastPos = pos+1; 10722 } 10723 } 10724 if (lastPos < info.stack.length()) { 10725 pw.print(" "); 10726 pw.write(info.stack, lastPos, info.stack.length()-lastPos); 10727 pw.println(); 10728 } 10729 } 10730 } 10731 } 10732 } 10733 10734 if (dumpPackage == null) { 10735 pw.println(); 10736 needSep = false; 10737 pw.println(" mStartedUsers:"); 10738 for (int i=0; i<mStartedUsers.size(); i++) { 10739 UserStartedState uss = mStartedUsers.valueAt(i); 10740 pw.print(" User #"); pw.print(uss.mHandle.getIdentifier()); 10741 pw.print(": "); uss.dump("", pw); 10742 } 10743 pw.print(" mStartedUserArray: ["); 10744 for (int i=0; i<mStartedUserArray.length; i++) { 10745 if (i > 0) pw.print(", "); 10746 pw.print(mStartedUserArray[i]); 10747 } 10748 pw.println("]"); 10749 pw.print(" mUserLru: ["); 10750 for (int i=0; i<mUserLru.size(); i++) { 10751 if (i > 0) pw.print(", "); 10752 pw.print(mUserLru.get(i)); 10753 } 10754 pw.println("]"); 10755 if (dumpAll) { 10756 pw.print(" mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray)); 10757 } 10758 } 10759 if (mHomeProcess != null && (dumpPackage == null 10760 || mHomeProcess.pkgList.containsKey(dumpPackage))) { 10761 if (needSep) { 10762 pw.println(); 10763 needSep = false; 10764 } 10765 pw.println(" mHomeProcess: " + mHomeProcess); 10766 } 10767 if (mPreviousProcess != null && (dumpPackage == null 10768 || mPreviousProcess.pkgList.containsKey(dumpPackage))) { 10769 if (needSep) { 10770 pw.println(); 10771 needSep = false; 10772 } 10773 pw.println(" mPreviousProcess: " + mPreviousProcess); 10774 } 10775 if (dumpAll) { 10776 StringBuilder sb = new StringBuilder(128); 10777 sb.append(" mPreviousProcessVisibleTime: "); 10778 TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb); 10779 pw.println(sb); 10780 } 10781 if (mHeavyWeightProcess != null && (dumpPackage == null 10782 || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) { 10783 if (needSep) { 10784 pw.println(); 10785 needSep = false; 10786 } 10787 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 10788 } 10789 if (dumpPackage == null) { 10790 pw.println(" mConfiguration: " + mConfiguration); 10791 } 10792 if (dumpAll) { 10793 pw.println(" mConfigWillChange: " + getFocusedStack().mConfigWillChange); 10794 if (mCompatModePackages.getPackages().size() > 0) { 10795 boolean printed = false; 10796 for (Map.Entry<String, Integer> entry 10797 : mCompatModePackages.getPackages().entrySet()) { 10798 String pkg = entry.getKey(); 10799 int mode = entry.getValue(); 10800 if (dumpPackage != null && !dumpPackage.equals(pkg)) { 10801 continue; 10802 } 10803 if (!printed) { 10804 pw.println(" mScreenCompatPackages:"); 10805 printed = true; 10806 } 10807 pw.print(" "); pw.print(pkg); pw.print(": "); 10808 pw.print(mode); pw.println(); 10809 } 10810 } 10811 } 10812 if (dumpPackage == null) { 10813 if (mSleeping || mWentToSleep || mLockScreenShown) { 10814 pw.println(" mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep 10815 + " mLockScreenShown " + mLockScreenShown); 10816 } 10817 if (mShuttingDown) { 10818 pw.println(" mShuttingDown=" + mShuttingDown); 10819 } 10820 } 10821 if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient 10822 || mOrigWaitForDebugger) { 10823 if (dumpPackage == null || dumpPackage.equals(mDebugApp) 10824 || dumpPackage.equals(mOrigDebugApp)) { 10825 if (needSep) { 10826 pw.println(); 10827 needSep = false; 10828 } 10829 pw.println(" mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp 10830 + " mDebugTransient=" + mDebugTransient 10831 + " mOrigWaitForDebugger=" + mOrigWaitForDebugger); 10832 } 10833 } 10834 if (mOpenGlTraceApp != null) { 10835 if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) { 10836 if (needSep) { 10837 pw.println(); 10838 needSep = false; 10839 } 10840 pw.println(" mOpenGlTraceApp=" + mOpenGlTraceApp); 10841 } 10842 } 10843 if (mProfileApp != null || mProfileProc != null || mProfileFile != null 10844 || mProfileFd != null) { 10845 if (dumpPackage == null || dumpPackage.equals(mProfileApp)) { 10846 if (needSep) { 10847 pw.println(); 10848 needSep = false; 10849 } 10850 pw.println(" mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc); 10851 pw.println(" mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd); 10852 pw.println(" mProfileType=" + mProfileType + " mAutoStopProfiler=" 10853 + mAutoStopProfiler); 10854 } 10855 } 10856 if (dumpPackage == null) { 10857 if (mAlwaysFinishActivities || mController != null) { 10858 pw.println(" mAlwaysFinishActivities=" + mAlwaysFinishActivities 10859 + " mController=" + mController); 10860 } 10861 if (dumpAll) { 10862 pw.println(" Total persistent processes: " + numPers); 10863 pw.println(" mProcessesReady=" + mProcessesReady 10864 + " mSystemReady=" + mSystemReady); 10865 pw.println(" mBooting=" + mBooting 10866 + " mBooted=" + mBooted 10867 + " mFactoryTest=" + mFactoryTest); 10868 pw.print(" mLastPowerCheckRealtime="); 10869 TimeUtils.formatDuration(mLastPowerCheckRealtime, pw); 10870 pw.println(""); 10871 pw.print(" mLastPowerCheckUptime="); 10872 TimeUtils.formatDuration(mLastPowerCheckUptime, pw); 10873 pw.println(""); 10874 pw.println(" mGoingToSleep=" + mStackSupervisor.mGoingToSleep); 10875 pw.println(" mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity); 10876 pw.println(" mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq); 10877 pw.println(" mNumNonCachedProcs=" + mNumNonCachedProcs 10878 + " (" + mLruProcesses.size() + " total)" 10879 + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs 10880 + " mNumServiceProcs=" + mNumServiceProcs 10881 + " mNewNumServiceProcs=" + mNewNumServiceProcs); 10882 pw.println(" mAllowLowerMemLevel=" + mAllowLowerMemLevel 10883 + " mLastMemoryLevel" + mLastMemoryLevel 10884 + " mLastNumProcesses" + mLastNumProcesses); 10885 long now = SystemClock.uptimeMillis(); 10886 pw.print(" mLastIdleTime="); 10887 TimeUtils.formatDuration(now, mLastIdleTime, pw); 10888 pw.print(" mLowRamSinceLastIdle="); 10889 TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw); 10890 pw.println(); 10891 } 10892 } 10893 10894 if (!printedAnything) { 10895 pw.println(" (nothing)"); 10896 } 10897 } 10898 10899 boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args, 10900 int opti, boolean needSep, boolean dumpAll, String dumpPackage) { 10901 if (mProcessesToGc.size() > 0) { 10902 boolean printed = false; 10903 long now = SystemClock.uptimeMillis(); 10904 for (int i=0; i<mProcessesToGc.size(); i++) { 10905 ProcessRecord proc = mProcessesToGc.get(i); 10906 if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) { 10907 continue; 10908 } 10909 if (!printed) { 10910 if (needSep) pw.println(); 10911 needSep = true; 10912 pw.println(" Processes that are waiting to GC:"); 10913 printed = true; 10914 } 10915 pw.print(" Process "); pw.println(proc); 10916 pw.print(" lowMem="); pw.print(proc.reportLowMemory); 10917 pw.print(", last gced="); 10918 pw.print(now-proc.lastRequestedGc); 10919 pw.print(" ms ago, last lowMem="); 10920 pw.print(now-proc.lastLowMemory); 10921 pw.println(" ms ago"); 10922 10923 } 10924 } 10925 return needSep; 10926 } 10927 10928 void printOomLevel(PrintWriter pw, String name, int adj) { 10929 pw.print(" "); 10930 if (adj >= 0) { 10931 pw.print(' '); 10932 if (adj < 10) pw.print(' '); 10933 } else { 10934 if (adj > -10) pw.print(' '); 10935 } 10936 pw.print(adj); 10937 pw.print(": "); 10938 pw.print(name); 10939 pw.print(" ("); 10940 pw.print(mProcessList.getMemLevel(adj)/1024); 10941 pw.println(" kB)"); 10942 } 10943 10944 boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args, 10945 int opti, boolean dumpAll) { 10946 boolean needSep = false; 10947 10948 if (mLruProcesses.size() > 0) { 10949 if (needSep) pw.println(); 10950 needSep = true; 10951 pw.println(" OOM levels:"); 10952 printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ); 10953 printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ); 10954 printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ); 10955 printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ); 10956 printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ); 10957 printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ); 10958 printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ); 10959 printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ); 10960 printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ); 10961 printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ); 10962 printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ); 10963 printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ); 10964 printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ); 10965 10966 if (needSep) pw.println(); 10967 pw.print(" Process OOM control ("); pw.print(mLruProcesses.size()); 10968 pw.print(" total, non-act at "); 10969 pw.print(mLruProcesses.size()-mLruProcessActivityStart); 10970 pw.print(", non-svc at "); 10971 pw.print(mLruProcesses.size()-mLruProcessServiceStart); 10972 pw.println("):"); 10973 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", true, null); 10974 needSep = true; 10975 } 10976 10977 dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null); 10978 10979 pw.println(); 10980 pw.println(" mHomeProcess: " + mHomeProcess); 10981 pw.println(" mPreviousProcess: " + mPreviousProcess); 10982 if (mHeavyWeightProcess != null) { 10983 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 10984 } 10985 10986 return true; 10987 } 10988 10989 /** 10990 * There are three ways to call this: 10991 * - no provider specified: dump all the providers 10992 * - a flattened component name that matched an existing provider was specified as the 10993 * first arg: dump that one provider 10994 * - the first arg isn't the flattened component name of an existing provider: 10995 * dump all providers whose component contains the first arg as a substring 10996 */ 10997 protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args, 10998 int opti, boolean dumpAll) { 10999 return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll); 11000 } 11001 11002 static class ItemMatcher { 11003 ArrayList<ComponentName> components; 11004 ArrayList<String> strings; 11005 ArrayList<Integer> objects; 11006 boolean all; 11007 11008 ItemMatcher() { 11009 all = true; 11010 } 11011 11012 void build(String name) { 11013 ComponentName componentName = ComponentName.unflattenFromString(name); 11014 if (componentName != null) { 11015 if (components == null) { 11016 components = new ArrayList<ComponentName>(); 11017 } 11018 components.add(componentName); 11019 all = false; 11020 } else { 11021 int objectId = 0; 11022 // Not a '/' separated full component name; maybe an object ID? 11023 try { 11024 objectId = Integer.parseInt(name, 16); 11025 if (objects == null) { 11026 objects = new ArrayList<Integer>(); 11027 } 11028 objects.add(objectId); 11029 all = false; 11030 } catch (RuntimeException e) { 11031 // Not an integer; just do string match. 11032 if (strings == null) { 11033 strings = new ArrayList<String>(); 11034 } 11035 strings.add(name); 11036 all = false; 11037 } 11038 } 11039 } 11040 11041 int build(String[] args, int opti) { 11042 for (; opti<args.length; opti++) { 11043 String name = args[opti]; 11044 if ("--".equals(name)) { 11045 return opti+1; 11046 } 11047 build(name); 11048 } 11049 return opti; 11050 } 11051 11052 boolean match(Object object, ComponentName comp) { 11053 if (all) { 11054 return true; 11055 } 11056 if (components != null) { 11057 for (int i=0; i<components.size(); i++) { 11058 if (components.get(i).equals(comp)) { 11059 return true; 11060 } 11061 } 11062 } 11063 if (objects != null) { 11064 for (int i=0; i<objects.size(); i++) { 11065 if (System.identityHashCode(object) == objects.get(i)) { 11066 return true; 11067 } 11068 } 11069 } 11070 if (strings != null) { 11071 String flat = comp.flattenToString(); 11072 for (int i=0; i<strings.size(); i++) { 11073 if (flat.contains(strings.get(i))) { 11074 return true; 11075 } 11076 } 11077 } 11078 return false; 11079 } 11080 } 11081 11082 /** 11083 * There are three things that cmd can be: 11084 * - a flattened component name that matches an existing activity 11085 * - the cmd arg isn't the flattened component name of an existing activity: 11086 * dump all activity whose component contains the cmd as a substring 11087 * - A hex number of the ActivityRecord object instance. 11088 */ 11089 protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args, 11090 int opti, boolean dumpAll) { 11091 ArrayList<ActivityRecord> activities; 11092 11093 synchronized (this) { 11094 activities = mStackSupervisor.getDumpActivitiesLocked(name); 11095 } 11096 11097 if (activities.size() <= 0) { 11098 return false; 11099 } 11100 11101 String[] newArgs = new String[args.length - opti]; 11102 System.arraycopy(args, opti, newArgs, 0, args.length - opti); 11103 11104 TaskRecord lastTask = null; 11105 boolean needSep = false; 11106 for (int i=activities.size()-1; i>=0; i--) { 11107 ActivityRecord r = activities.get(i); 11108 if (needSep) { 11109 pw.println(); 11110 } 11111 needSep = true; 11112 synchronized (this) { 11113 if (lastTask != r.task) { 11114 lastTask = r.task; 11115 pw.print("TASK "); pw.print(lastTask.affinity); 11116 pw.print(" id="); pw.println(lastTask.taskId); 11117 if (dumpAll) { 11118 lastTask.dump(pw, " "); 11119 } 11120 } 11121 } 11122 dumpActivity(" ", fd, pw, activities.get(i), newArgs, dumpAll); 11123 } 11124 return true; 11125 } 11126 11127 /** 11128 * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if 11129 * there is a thread associated with the activity. 11130 */ 11131 private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw, 11132 final ActivityRecord r, String[] args, boolean dumpAll) { 11133 String innerPrefix = prefix + " "; 11134 synchronized (this) { 11135 pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName); 11136 pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r))); 11137 pw.print(" pid="); 11138 if (r.app != null) pw.println(r.app.pid); 11139 else pw.println("(not running)"); 11140 if (dumpAll) { 11141 r.dump(pw, innerPrefix); 11142 } 11143 } 11144 if (r.app != null && r.app.thread != null) { 11145 // flush anything that is already in the PrintWriter since the thread is going 11146 // to write to the file descriptor directly 11147 pw.flush(); 11148 try { 11149 TransferPipe tp = new TransferPipe(); 11150 try { 11151 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(), 11152 r.appToken, innerPrefix, args); 11153 tp.go(fd); 11154 } finally { 11155 tp.kill(); 11156 } 11157 } catch (IOException e) { 11158 pw.println(innerPrefix + "Failure while dumping the activity: " + e); 11159 } catch (RemoteException e) { 11160 pw.println(innerPrefix + "Got a RemoteException while dumping the activity"); 11161 } 11162 } 11163 } 11164 11165 void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 11166 int opti, boolean dumpAll, String dumpPackage) { 11167 boolean needSep = false; 11168 boolean onlyHistory = false; 11169 boolean printedAnything = false; 11170 11171 if ("history".equals(dumpPackage)) { 11172 if (opti < args.length && "-s".equals(args[opti])) { 11173 dumpAll = false; 11174 } 11175 onlyHistory = true; 11176 dumpPackage = null; 11177 } 11178 11179 pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)"); 11180 if (!onlyHistory && dumpAll) { 11181 if (mRegisteredReceivers.size() > 0) { 11182 boolean printed = false; 11183 Iterator it = mRegisteredReceivers.values().iterator(); 11184 while (it.hasNext()) { 11185 ReceiverList r = (ReceiverList)it.next(); 11186 if (dumpPackage != null && (r.app == null || 11187 !dumpPackage.equals(r.app.info.packageName))) { 11188 continue; 11189 } 11190 if (!printed) { 11191 pw.println(" Registered Receivers:"); 11192 needSep = true; 11193 printed = true; 11194 printedAnything = true; 11195 } 11196 pw.print(" * "); pw.println(r); 11197 r.dump(pw, " "); 11198 } 11199 } 11200 11201 if (mReceiverResolver.dump(pw, needSep ? 11202 "\n Receiver Resolver Table:" : " Receiver Resolver Table:", 11203 " ", dumpPackage, false)) { 11204 needSep = true; 11205 printedAnything = true; 11206 } 11207 } 11208 11209 for (BroadcastQueue q : mBroadcastQueues) { 11210 needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep); 11211 printedAnything |= needSep; 11212 } 11213 11214 needSep = true; 11215 11216 if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) { 11217 for (int user=0; user<mStickyBroadcasts.size(); user++) { 11218 if (needSep) { 11219 pw.println(); 11220 } 11221 needSep = true; 11222 printedAnything = true; 11223 pw.print(" Sticky broadcasts for user "); 11224 pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":"); 11225 StringBuilder sb = new StringBuilder(128); 11226 for (Map.Entry<String, ArrayList<Intent>> ent 11227 : mStickyBroadcasts.valueAt(user).entrySet()) { 11228 pw.print(" * Sticky action "); pw.print(ent.getKey()); 11229 if (dumpAll) { 11230 pw.println(":"); 11231 ArrayList<Intent> intents = ent.getValue(); 11232 final int N = intents.size(); 11233 for (int i=0; i<N; i++) { 11234 sb.setLength(0); 11235 sb.append(" Intent: "); 11236 intents.get(i).toShortString(sb, false, true, false, false); 11237 pw.println(sb.toString()); 11238 Bundle bundle = intents.get(i).getExtras(); 11239 if (bundle != null) { 11240 pw.print(" "); 11241 pw.println(bundle.toString()); 11242 } 11243 } 11244 } else { 11245 pw.println(""); 11246 } 11247 } 11248 } 11249 } 11250 11251 if (!onlyHistory && dumpAll) { 11252 pw.println(); 11253 for (BroadcastQueue queue : mBroadcastQueues) { 11254 pw.println(" mBroadcastsScheduled [" + queue.mQueueName + "]=" 11255 + queue.mBroadcastsScheduled); 11256 } 11257 pw.println(" mHandler:"); 11258 mHandler.dump(new PrintWriterPrinter(pw), " "); 11259 needSep = true; 11260 printedAnything = true; 11261 } 11262 11263 if (!printedAnything) { 11264 pw.println(" (nothing)"); 11265 } 11266 } 11267 11268 void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args, 11269 int opti, boolean dumpAll, String dumpPackage) { 11270 boolean needSep; 11271 boolean printedAnything = false; 11272 11273 ItemMatcher matcher = new ItemMatcher(); 11274 matcher.build(args, opti); 11275 11276 pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)"); 11277 11278 needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage); 11279 printedAnything |= needSep; 11280 11281 if (mLaunchingProviders.size() > 0) { 11282 boolean printed = false; 11283 for (int i=mLaunchingProviders.size()-1; i>=0; i--) { 11284 ContentProviderRecord r = mLaunchingProviders.get(i); 11285 if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) { 11286 continue; 11287 } 11288 if (!printed) { 11289 if (needSep) pw.println(); 11290 needSep = true; 11291 pw.println(" Launching content providers:"); 11292 printed = true; 11293 printedAnything = true; 11294 } 11295 pw.print(" Launching #"); pw.print(i); pw.print(": "); 11296 pw.println(r); 11297 } 11298 } 11299 11300 if (mGrantedUriPermissions.size() > 0) { 11301 boolean printed = false; 11302 int dumpUid = -2; 11303 if (dumpPackage != null) { 11304 try { 11305 dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0); 11306 } catch (NameNotFoundException e) { 11307 dumpUid = -1; 11308 } 11309 } 11310 for (int i=0; i<mGrantedUriPermissions.size(); i++) { 11311 int uid = mGrantedUriPermissions.keyAt(i); 11312 if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) { 11313 continue; 11314 } 11315 ArrayMap<Uri, UriPermission> perms 11316 = mGrantedUriPermissions.valueAt(i); 11317 if (!printed) { 11318 if (needSep) pw.println(); 11319 needSep = true; 11320 pw.println(" Granted Uri Permissions:"); 11321 printed = true; 11322 printedAnything = true; 11323 } 11324 pw.print(" * UID "); pw.print(uid); 11325 pw.println(" holds:"); 11326 for (UriPermission perm : perms.values()) { 11327 pw.print(" "); pw.println(perm); 11328 if (dumpAll) { 11329 perm.dump(pw, " "); 11330 } 11331 } 11332 } 11333 } 11334 11335 if (!printedAnything) { 11336 pw.println(" (nothing)"); 11337 } 11338 } 11339 11340 void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 11341 int opti, boolean dumpAll, String dumpPackage) { 11342 boolean printed = false; 11343 11344 pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)"); 11345 11346 if (mIntentSenderRecords.size() > 0) { 11347 Iterator<WeakReference<PendingIntentRecord>> it 11348 = mIntentSenderRecords.values().iterator(); 11349 while (it.hasNext()) { 11350 WeakReference<PendingIntentRecord> ref = it.next(); 11351 PendingIntentRecord rec = ref != null ? ref.get(): null; 11352 if (dumpPackage != null && (rec == null 11353 || !dumpPackage.equals(rec.key.packageName))) { 11354 continue; 11355 } 11356 printed = true; 11357 if (rec != null) { 11358 pw.print(" * "); pw.println(rec); 11359 if (dumpAll) { 11360 rec.dump(pw, " "); 11361 } 11362 } else { 11363 pw.print(" * "); pw.println(ref); 11364 } 11365 } 11366 } 11367 11368 if (!printed) { 11369 pw.println(" (nothing)"); 11370 } 11371 } 11372 11373 private static final int dumpProcessList(PrintWriter pw, 11374 ActivityManagerService service, List list, 11375 String prefix, String normalLabel, String persistentLabel, 11376 String dumpPackage) { 11377 int numPers = 0; 11378 final int N = list.size()-1; 11379 for (int i=N; i>=0; i--) { 11380 ProcessRecord r = (ProcessRecord)list.get(i); 11381 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 11382 continue; 11383 } 11384 pw.println(String.format("%s%s #%2d: %s", 11385 prefix, (r.persistent ? persistentLabel : normalLabel), 11386 i, r.toString())); 11387 if (r.persistent) { 11388 numPers++; 11389 } 11390 } 11391 return numPers; 11392 } 11393 11394 private static final boolean dumpProcessOomList(PrintWriter pw, 11395 ActivityManagerService service, List<ProcessRecord> origList, 11396 String prefix, String normalLabel, String persistentLabel, 11397 boolean inclDetails, String dumpPackage) { 11398 11399 ArrayList<Pair<ProcessRecord, Integer>> list 11400 = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size()); 11401 for (int i=0; i<origList.size(); i++) { 11402 ProcessRecord r = origList.get(i); 11403 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 11404 continue; 11405 } 11406 list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i)); 11407 } 11408 11409 if (list.size() <= 0) { 11410 return false; 11411 } 11412 11413 Comparator<Pair<ProcessRecord, Integer>> comparator 11414 = new Comparator<Pair<ProcessRecord, Integer>>() { 11415 @Override 11416 public int compare(Pair<ProcessRecord, Integer> object1, 11417 Pair<ProcessRecord, Integer> object2) { 11418 if (object1.first.setAdj != object2.first.setAdj) { 11419 return object1.first.setAdj > object2.first.setAdj ? -1 : 1; 11420 } 11421 if (object1.second.intValue() != object2.second.intValue()) { 11422 return object1.second.intValue() > object2.second.intValue() ? -1 : 1; 11423 } 11424 return 0; 11425 } 11426 }; 11427 11428 Collections.sort(list, comparator); 11429 11430 final long curRealtime = SystemClock.elapsedRealtime(); 11431 final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime; 11432 final long curUptime = SystemClock.uptimeMillis(); 11433 final long uptimeSince = curUptime - service.mLastPowerCheckUptime; 11434 11435 for (int i=list.size()-1; i>=0; i--) { 11436 ProcessRecord r = list.get(i).first; 11437 String oomAdj = ProcessList.makeOomAdjString(r.setAdj); 11438 char schedGroup; 11439 switch (r.setSchedGroup) { 11440 case Process.THREAD_GROUP_BG_NONINTERACTIVE: 11441 schedGroup = 'B'; 11442 break; 11443 case Process.THREAD_GROUP_DEFAULT: 11444 schedGroup = 'F'; 11445 break; 11446 default: 11447 schedGroup = '?'; 11448 break; 11449 } 11450 char foreground; 11451 if (r.foregroundActivities) { 11452 foreground = 'A'; 11453 } else if (r.foregroundServices) { 11454 foreground = 'S'; 11455 } else { 11456 foreground = ' '; 11457 } 11458 String procState = ProcessList.makeProcStateString(r.curProcState); 11459 pw.print(prefix); 11460 pw.print(r.persistent ? persistentLabel : normalLabel); 11461 pw.print(" #"); 11462 int num = (origList.size()-1)-list.get(i).second; 11463 if (num < 10) pw.print(' '); 11464 pw.print(num); 11465 pw.print(": "); 11466 pw.print(oomAdj); 11467 pw.print(' '); 11468 pw.print(schedGroup); 11469 pw.print('/'); 11470 pw.print(foreground); 11471 pw.print('/'); 11472 pw.print(procState); 11473 pw.print(" trm:"); 11474 if (r.trimMemoryLevel < 10) pw.print(' '); 11475 pw.print(r.trimMemoryLevel); 11476 pw.print(' '); 11477 pw.print(r.toShortString()); 11478 pw.print(" ("); 11479 pw.print(r.adjType); 11480 pw.println(')'); 11481 if (r.adjSource != null || r.adjTarget != null) { 11482 pw.print(prefix); 11483 pw.print(" "); 11484 if (r.adjTarget instanceof ComponentName) { 11485 pw.print(((ComponentName)r.adjTarget).flattenToShortString()); 11486 } else if (r.adjTarget != null) { 11487 pw.print(r.adjTarget.toString()); 11488 } else { 11489 pw.print("{null}"); 11490 } 11491 pw.print("<="); 11492 if (r.adjSource instanceof ProcessRecord) { 11493 pw.print("Proc{"); 11494 pw.print(((ProcessRecord)r.adjSource).toShortString()); 11495 pw.println("}"); 11496 } else if (r.adjSource != null) { 11497 pw.println(r.adjSource.toString()); 11498 } else { 11499 pw.println("{null}"); 11500 } 11501 } 11502 if (inclDetails) { 11503 pw.print(prefix); 11504 pw.print(" "); 11505 pw.print("oom: max="); pw.print(r.maxAdj); 11506 pw.print(" curRaw="); pw.print(r.curRawAdj); 11507 pw.print(" setRaw="); pw.print(r.setRawAdj); 11508 pw.print(" cur="); pw.print(r.curAdj); 11509 pw.print(" set="); pw.println(r.setAdj); 11510 pw.print(prefix); 11511 pw.print(" "); 11512 pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState)); 11513 pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState)); 11514 pw.print(" lastPss="); pw.print(r.lastPss); 11515 pw.print(" lastCachedPss="); pw.println(r.lastCachedPss); 11516 pw.print(prefix); 11517 pw.print(" "); 11518 pw.print("keeping="); pw.print(r.keeping); 11519 pw.print(" cached="); pw.print(r.cached); 11520 pw.print(" empty="); pw.print(r.empty); 11521 pw.print(" hasAboveClient="); pw.println(r.hasAboveClient); 11522 11523 if (!r.keeping) { 11524 if (r.lastWakeTime != 0) { 11525 long wtime; 11526 BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics(); 11527 synchronized (stats) { 11528 wtime = stats.getProcessWakeTime(r.info.uid, 11529 r.pid, curRealtime); 11530 } 11531 long timeUsed = wtime - r.lastWakeTime; 11532 pw.print(prefix); 11533 pw.print(" "); 11534 pw.print("keep awake over "); 11535 TimeUtils.formatDuration(realtimeSince, pw); 11536 pw.print(" used "); 11537 TimeUtils.formatDuration(timeUsed, pw); 11538 pw.print(" ("); 11539 pw.print((timeUsed*100)/realtimeSince); 11540 pw.println("%)"); 11541 } 11542 if (r.lastCpuTime != 0) { 11543 long timeUsed = r.curCpuTime - r.lastCpuTime; 11544 pw.print(prefix); 11545 pw.print(" "); 11546 pw.print("run cpu over "); 11547 TimeUtils.formatDuration(uptimeSince, pw); 11548 pw.print(" used "); 11549 TimeUtils.formatDuration(timeUsed, pw); 11550 pw.print(" ("); 11551 pw.print((timeUsed*100)/uptimeSince); 11552 pw.println("%)"); 11553 } 11554 } 11555 } 11556 } 11557 return true; 11558 } 11559 11560 ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) { 11561 ArrayList<ProcessRecord> procs; 11562 synchronized (this) { 11563 if (args != null && args.length > start 11564 && args[start].charAt(0) != '-') { 11565 procs = new ArrayList<ProcessRecord>(); 11566 int pid = -1; 11567 try { 11568 pid = Integer.parseInt(args[start]); 11569 } catch (NumberFormatException e) { 11570 } 11571 for (int i=mLruProcesses.size()-1; i>=0; i--) { 11572 ProcessRecord proc = mLruProcesses.get(i); 11573 if (proc.pid == pid) { 11574 procs.add(proc); 11575 } else if (proc.processName.equals(args[start])) { 11576 procs.add(proc); 11577 } 11578 } 11579 if (procs.size() <= 0) { 11580 return null; 11581 } 11582 } else { 11583 procs = new ArrayList<ProcessRecord>(mLruProcesses); 11584 } 11585 } 11586 return procs; 11587 } 11588 11589 final void dumpGraphicsHardwareUsage(FileDescriptor fd, 11590 PrintWriter pw, String[] args) { 11591 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args); 11592 if (procs == null) { 11593 pw.println("No process found for: " + args[0]); 11594 return; 11595 } 11596 11597 long uptime = SystemClock.uptimeMillis(); 11598 long realtime = SystemClock.elapsedRealtime(); 11599 pw.println("Applications Graphics Acceleration Info:"); 11600 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 11601 11602 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 11603 ProcessRecord r = procs.get(i); 11604 if (r.thread != null) { 11605 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **"); 11606 pw.flush(); 11607 try { 11608 TransferPipe tp = new TransferPipe(); 11609 try { 11610 r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args); 11611 tp.go(fd); 11612 } finally { 11613 tp.kill(); 11614 } 11615 } catch (IOException e) { 11616 pw.println("Failure while dumping the app: " + r); 11617 pw.flush(); 11618 } catch (RemoteException e) { 11619 pw.println("Got a RemoteException while dumping the app " + r); 11620 pw.flush(); 11621 } 11622 } 11623 } 11624 } 11625 11626 final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) { 11627 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args); 11628 if (procs == null) { 11629 pw.println("No process found for: " + args[0]); 11630 return; 11631 } 11632 11633 pw.println("Applications Database Info:"); 11634 11635 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 11636 ProcessRecord r = procs.get(i); 11637 if (r.thread != null) { 11638 pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **"); 11639 pw.flush(); 11640 try { 11641 TransferPipe tp = new TransferPipe(); 11642 try { 11643 r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args); 11644 tp.go(fd); 11645 } finally { 11646 tp.kill(); 11647 } 11648 } catch (IOException e) { 11649 pw.println("Failure while dumping the app: " + r); 11650 pw.flush(); 11651 } catch (RemoteException e) { 11652 pw.println("Got a RemoteException while dumping the app " + r); 11653 pw.flush(); 11654 } 11655 } 11656 } 11657 } 11658 11659 final static class MemItem { 11660 final boolean isProc; 11661 final String label; 11662 final String shortLabel; 11663 final long pss; 11664 final int id; 11665 final boolean hasActivities; 11666 ArrayList<MemItem> subitems; 11667 11668 public MemItem(String _label, String _shortLabel, long _pss, int _id, 11669 boolean _hasActivities) { 11670 isProc = true; 11671 label = _label; 11672 shortLabel = _shortLabel; 11673 pss = _pss; 11674 id = _id; 11675 hasActivities = _hasActivities; 11676 } 11677 11678 public MemItem(String _label, String _shortLabel, long _pss, int _id) { 11679 isProc = false; 11680 label = _label; 11681 shortLabel = _shortLabel; 11682 pss = _pss; 11683 id = _id; 11684 hasActivities = false; 11685 } 11686 } 11687 11688 static final void dumpMemItems(PrintWriter pw, String prefix, String tag, 11689 ArrayList<MemItem> items, boolean sort, boolean isCompact) { 11690 if (sort && !isCompact) { 11691 Collections.sort(items, new Comparator<MemItem>() { 11692 @Override 11693 public int compare(MemItem lhs, MemItem rhs) { 11694 if (lhs.pss < rhs.pss) { 11695 return 1; 11696 } else if (lhs.pss > rhs.pss) { 11697 return -1; 11698 } 11699 return 0; 11700 } 11701 }); 11702 } 11703 11704 for (int i=0; i<items.size(); i++) { 11705 MemItem mi = items.get(i); 11706 if (!isCompact) { 11707 pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label); 11708 } else if (mi.isProc) { 11709 pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel); 11710 pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss); 11711 pw.println(mi.hasActivities ? ",a" : ",e"); 11712 } else { 11713 pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(","); 11714 pw.println(mi.pss); 11715 } 11716 if (mi.subitems != null) { 11717 dumpMemItems(pw, prefix + " ", mi.shortLabel, mi.subitems, 11718 true, isCompact); 11719 } 11720 } 11721 } 11722 11723 // These are in KB. 11724 static final long[] DUMP_MEM_BUCKETS = new long[] { 11725 5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024, 11726 120*1024, 160*1024, 200*1024, 11727 250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024, 11728 1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024 11729 }; 11730 11731 static final void appendMemBucket(StringBuilder out, long memKB, String label, 11732 boolean stackLike) { 11733 int start = label.lastIndexOf('.'); 11734 if (start >= 0) start++; 11735 else start = 0; 11736 int end = label.length(); 11737 for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) { 11738 if (DUMP_MEM_BUCKETS[i] >= memKB) { 11739 long bucket = DUMP_MEM_BUCKETS[i]/1024; 11740 out.append(bucket); 11741 out.append(stackLike ? "MB." : "MB "); 11742 out.append(label, start, end); 11743 return; 11744 } 11745 } 11746 out.append(memKB/1024); 11747 out.append(stackLike ? "MB." : "MB "); 11748 out.append(label, start, end); 11749 } 11750 11751 static final int[] DUMP_MEM_OOM_ADJ = new int[] { 11752 ProcessList.NATIVE_ADJ, 11753 ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ, 11754 ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ, 11755 ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ, 11756 ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ, 11757 ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ 11758 }; 11759 static final String[] DUMP_MEM_OOM_LABEL = new String[] { 11760 "Native", 11761 "System", "Persistent", "Foreground", 11762 "Visible", "Perceptible", 11763 "Heavy Weight", "Backup", 11764 "A Services", "Home", 11765 "Previous", "B Services", "Cached" 11766 }; 11767 static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] { 11768 "native", 11769 "sys", "pers", "fore", 11770 "vis", "percept", 11771 "heavy", "backup", 11772 "servicea", "home", 11773 "prev", "serviceb", "cached" 11774 }; 11775 11776 private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime, 11777 long realtime, boolean isCheckinRequest, boolean isCompact) { 11778 if (isCheckinRequest || isCompact) { 11779 // short checkin version 11780 pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime); 11781 } else { 11782 pw.println("Applications Memory Usage (kB):"); 11783 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 11784 } 11785 } 11786 11787 final void dumpApplicationMemoryUsage(FileDescriptor fd, 11788 PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) { 11789 boolean dumpDetails = false; 11790 boolean dumpFullDetails = false; 11791 boolean dumpDalvik = false; 11792 boolean oomOnly = false; 11793 boolean isCompact = false; 11794 boolean localOnly = false; 11795 11796 int opti = 0; 11797 while (opti < args.length) { 11798 String opt = args[opti]; 11799 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 11800 break; 11801 } 11802 opti++; 11803 if ("-a".equals(opt)) { 11804 dumpDetails = true; 11805 dumpFullDetails = true; 11806 dumpDalvik = true; 11807 } else if ("-d".equals(opt)) { 11808 dumpDalvik = true; 11809 } else if ("-c".equals(opt)) { 11810 isCompact = true; 11811 } else if ("--oom".equals(opt)) { 11812 oomOnly = true; 11813 } else if ("--local".equals(opt)) { 11814 localOnly = true; 11815 } else if ("-h".equals(opt)) { 11816 pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]"); 11817 pw.println(" -a: include all available information for each process."); 11818 pw.println(" -d: include dalvik details when dumping process details."); 11819 pw.println(" -c: dump in a compact machine-parseable representation."); 11820 pw.println(" --oom: only show processes organized by oom adj."); 11821 pw.println(" --local: only collect details locally, don't call process."); 11822 pw.println("If [process] is specified it can be the name or "); 11823 pw.println("pid of a specific process to dump."); 11824 return; 11825 } else { 11826 pw.println("Unknown argument: " + opt + "; use -h for help"); 11827 } 11828 } 11829 11830 final boolean isCheckinRequest = scanArgs(args, "--checkin"); 11831 long uptime = SystemClock.uptimeMillis(); 11832 long realtime = SystemClock.elapsedRealtime(); 11833 final long[] tmpLong = new long[1]; 11834 11835 ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args); 11836 if (procs == null) { 11837 // No Java processes. Maybe they want to print a native process. 11838 if (args != null && args.length > opti 11839 && args[opti].charAt(0) != '-') { 11840 ArrayList<ProcessCpuTracker.Stats> nativeProcs 11841 = new ArrayList<ProcessCpuTracker.Stats>(); 11842 updateCpuStatsNow(); 11843 int findPid = -1; 11844 try { 11845 findPid = Integer.parseInt(args[opti]); 11846 } catch (NumberFormatException e) { 11847 } 11848 synchronized (mProcessCpuThread) { 11849 final int N = mProcessCpuTracker.countStats(); 11850 for (int i=0; i<N; i++) { 11851 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 11852 if (st.pid == findPid || (st.baseName != null 11853 && st.baseName.equals(args[opti]))) { 11854 nativeProcs.add(st); 11855 } 11856 } 11857 } 11858 if (nativeProcs.size() > 0) { 11859 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, 11860 isCompact); 11861 Debug.MemoryInfo mi = null; 11862 for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) { 11863 final ProcessCpuTracker.Stats r = nativeProcs.get(i); 11864 final int pid = r.pid; 11865 if (!isCheckinRequest && dumpDetails) { 11866 pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **"); 11867 } 11868 if (mi == null) { 11869 mi = new Debug.MemoryInfo(); 11870 } 11871 if (dumpDetails || (!brief && !oomOnly)) { 11872 Debug.getMemoryInfo(pid, mi); 11873 } else { 11874 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong); 11875 mi.dalvikPrivateDirty = (int)tmpLong[0]; 11876 } 11877 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails, 11878 dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0); 11879 if (isCheckinRequest) { 11880 pw.println(); 11881 } 11882 } 11883 return; 11884 } 11885 } 11886 pw.println("No process found for: " + args[opti]); 11887 return; 11888 } 11889 11890 if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest)) { 11891 dumpDetails = true; 11892 } 11893 11894 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact); 11895 11896 String[] innerArgs = new String[args.length-opti]; 11897 System.arraycopy(args, opti, innerArgs, 0, args.length-opti); 11898 11899 ArrayList<MemItem> procMems = new ArrayList<MemItem>(); 11900 final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>(); 11901 long nativePss=0, dalvikPss=0, otherPss=0; 11902 long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS]; 11903 11904 long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length]; 11905 ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[]) 11906 new ArrayList[DUMP_MEM_OOM_LABEL.length]; 11907 11908 long totalPss = 0; 11909 long cachedPss = 0; 11910 11911 Debug.MemoryInfo mi = null; 11912 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 11913 final ProcessRecord r = procs.get(i); 11914 final IApplicationThread thread; 11915 final int pid; 11916 final int oomAdj; 11917 final boolean hasActivities; 11918 synchronized (this) { 11919 thread = r.thread; 11920 pid = r.pid; 11921 oomAdj = r.getSetAdjWithServices(); 11922 hasActivities = r.activities.size() > 0; 11923 } 11924 if (thread != null) { 11925 if (!isCheckinRequest && dumpDetails) { 11926 pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **"); 11927 } 11928 if (mi == null) { 11929 mi = new Debug.MemoryInfo(); 11930 } 11931 if (dumpDetails || (!brief && !oomOnly)) { 11932 Debug.getMemoryInfo(pid, mi); 11933 } else { 11934 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong); 11935 mi.dalvikPrivateDirty = (int)tmpLong[0]; 11936 } 11937 if (dumpDetails) { 11938 if (localOnly) { 11939 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails, 11940 dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0); 11941 if (isCheckinRequest) { 11942 pw.println(); 11943 } 11944 } else { 11945 try { 11946 pw.flush(); 11947 thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails, 11948 dumpDalvik, innerArgs); 11949 } catch (RemoteException e) { 11950 if (!isCheckinRequest) { 11951 pw.println("Got RemoteException!"); 11952 pw.flush(); 11953 } 11954 } 11955 } 11956 } 11957 11958 final long myTotalPss = mi.getTotalPss(); 11959 final long myTotalUss = mi.getTotalUss(); 11960 11961 synchronized (this) { 11962 if (r.thread != null && oomAdj == r.getSetAdjWithServices()) { 11963 // Record this for posterity if the process has been stable. 11964 r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList); 11965 } 11966 } 11967 11968 if (!isCheckinRequest && mi != null) { 11969 totalPss += myTotalPss; 11970 MemItem pssItem = new MemItem(r.processName + " (pid " + pid + 11971 (hasActivities ? " / activities)" : ")"), 11972 r.processName, myTotalPss, pid, hasActivities); 11973 procMems.add(pssItem); 11974 procMemsMap.put(pid, pssItem); 11975 11976 nativePss += mi.nativePss; 11977 dalvikPss += mi.dalvikPss; 11978 otherPss += mi.otherPss; 11979 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 11980 long mem = mi.getOtherPss(j); 11981 miscPss[j] += mem; 11982 otherPss -= mem; 11983 } 11984 11985 if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 11986 cachedPss += myTotalPss; 11987 } 11988 11989 for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) { 11990 if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex] 11991 || oomIndex == (oomPss.length-1)) { 11992 oomPss[oomIndex] += myTotalPss; 11993 if (oomProcs[oomIndex] == null) { 11994 oomProcs[oomIndex] = new ArrayList<MemItem>(); 11995 } 11996 oomProcs[oomIndex].add(pssItem); 11997 break; 11998 } 11999 } 12000 } 12001 } 12002 } 12003 12004 if (!isCheckinRequest && procs.size() > 1) { 12005 // If we are showing aggregations, also look for native processes to 12006 // include so that our aggregations are more accurate. 12007 updateCpuStatsNow(); 12008 synchronized (mProcessCpuThread) { 12009 final int N = mProcessCpuTracker.countStats(); 12010 for (int i=0; i<N; i++) { 12011 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 12012 if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) { 12013 if (mi == null) { 12014 mi = new Debug.MemoryInfo(); 12015 } 12016 if (!brief && !oomOnly) { 12017 Debug.getMemoryInfo(st.pid, mi); 12018 } else { 12019 mi.nativePss = (int)Debug.getPss(st.pid, tmpLong); 12020 mi.nativePrivateDirty = (int)tmpLong[0]; 12021 } 12022 12023 final long myTotalPss = mi.getTotalPss(); 12024 totalPss += myTotalPss; 12025 12026 MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")", 12027 st.name, myTotalPss, st.pid, false); 12028 procMems.add(pssItem); 12029 12030 nativePss += mi.nativePss; 12031 dalvikPss += mi.dalvikPss; 12032 otherPss += mi.otherPss; 12033 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 12034 long mem = mi.getOtherPss(j); 12035 miscPss[j] += mem; 12036 otherPss -= mem; 12037 } 12038 oomPss[0] += myTotalPss; 12039 if (oomProcs[0] == null) { 12040 oomProcs[0] = new ArrayList<MemItem>(); 12041 } 12042 oomProcs[0].add(pssItem); 12043 } 12044 } 12045 } 12046 12047 ArrayList<MemItem> catMems = new ArrayList<MemItem>(); 12048 12049 catMems.add(new MemItem("Native", "Native", nativePss, -1)); 12050 catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2)); 12051 catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3)); 12052 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 12053 String label = Debug.MemoryInfo.getOtherLabel(j); 12054 catMems.add(new MemItem(label, label, miscPss[j], j)); 12055 } 12056 12057 ArrayList<MemItem> oomMems = new ArrayList<MemItem>(); 12058 for (int j=0; j<oomPss.length; j++) { 12059 if (oomPss[j] != 0) { 12060 String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j] 12061 : DUMP_MEM_OOM_LABEL[j]; 12062 MemItem item = new MemItem(label, label, oomPss[j], 12063 DUMP_MEM_OOM_ADJ[j]); 12064 item.subitems = oomProcs[j]; 12065 oomMems.add(item); 12066 } 12067 } 12068 12069 if (!brief && !oomOnly && !isCompact) { 12070 pw.println(); 12071 pw.println("Total PSS by process:"); 12072 dumpMemItems(pw, " ", "proc", procMems, true, isCompact); 12073 pw.println(); 12074 } 12075 if (!isCompact) { 12076 pw.println("Total PSS by OOM adjustment:"); 12077 } 12078 dumpMemItems(pw, " ", "oom", oomMems, false, isCompact); 12079 if (!brief && !oomOnly) { 12080 PrintWriter out = categoryPw != null ? categoryPw : pw; 12081 if (!isCompact) { 12082 out.println(); 12083 out.println("Total PSS by category:"); 12084 } 12085 dumpMemItems(out, " ", "cat", catMems, true, isCompact); 12086 } 12087 if (!isCompact) { 12088 pw.println(); 12089 } 12090 MemInfoReader memInfo = new MemInfoReader(); 12091 memInfo.readMemInfo(); 12092 if (!brief) { 12093 if (!isCompact) { 12094 pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb()); 12095 pw.println(" kB"); 12096 pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb() 12097 + memInfo.getFreeSizeKb()); pw.print(" kB ("); 12098 pw.print(cachedPss); pw.print(" cached pss + "); 12099 pw.print(memInfo.getCachedSizeKb()); pw.print(" cached + "); 12100 pw.print(memInfo.getFreeSizeKb()); pw.println(" free)"); 12101 } else { 12102 pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(","); 12103 pw.print(cachedPss + memInfo.getCachedSizeKb() 12104 + memInfo.getFreeSizeKb()); pw.print(","); 12105 pw.println(totalPss - cachedPss); 12106 } 12107 } 12108 if (!isCompact) { 12109 pw.print(" Used RAM: "); pw.print(totalPss - cachedPss 12110 + memInfo.getBuffersSizeKb() + memInfo.getShmemSizeKb() 12111 + memInfo.getSlabSizeKb()); pw.print(" kB ("); 12112 pw.print(totalPss - cachedPss); pw.print(" used pss + "); 12113 pw.print(memInfo.getBuffersSizeKb()); pw.print(" buffers + "); 12114 pw.print(memInfo.getShmemSizeKb()); pw.print(" shmem + "); 12115 pw.print(memInfo.getSlabSizeKb()); pw.println(" slab)"); 12116 pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb() 12117 - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb() 12118 - memInfo.getBuffersSizeKb() - memInfo.getShmemSizeKb() 12119 - memInfo.getSlabSizeKb()); pw.println(" kB"); 12120 } 12121 if (!brief) { 12122 if (memInfo.getZramTotalSizeKb() != 0) { 12123 if (!isCompact) { 12124 pw.print(" ZRAM: "); pw.print(memInfo.getZramTotalSizeKb()); 12125 pw.print(" kB physical used for "); 12126 pw.print(memInfo.getSwapTotalSizeKb() 12127 - memInfo.getSwapFreeSizeKb()); 12128 pw.print(" kB in swap ("); 12129 pw.print(memInfo.getSwapTotalSizeKb()); 12130 pw.println(" kB total swap)"); 12131 } else { 12132 pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(","); 12133 pw.print(memInfo.getSwapTotalSizeKb()); pw.print(","); 12134 pw.println(memInfo.getSwapFreeSizeKb()); 12135 } 12136 } 12137 final int[] SINGLE_LONG_FORMAT = new int[] { 12138 Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG 12139 }; 12140 long[] longOut = new long[1]; 12141 Process.readProcFile("/sys/kernel/mm/ksm/pages_shared", 12142 SINGLE_LONG_FORMAT, null, longOut, null); 12143 long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024; 12144 longOut[0] = 0; 12145 Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing", 12146 SINGLE_LONG_FORMAT, null, longOut, null); 12147 long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024; 12148 longOut[0] = 0; 12149 Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared", 12150 SINGLE_LONG_FORMAT, null, longOut, null); 12151 long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024; 12152 longOut[0] = 0; 12153 Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile", 12154 SINGLE_LONG_FORMAT, null, longOut, null); 12155 long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024; 12156 if (!isCompact) { 12157 if (sharing != 0 || shared != 0 || unshared != 0 || voltile != 0) { 12158 pw.print(" KSM: "); pw.print(sharing); 12159 pw.print(" kB saved from shared "); 12160 pw.print(shared); pw.println(" kB"); 12161 pw.print(" "); pw.print(unshared); pw.print(" kB unshared; "); 12162 pw.print(voltile); pw.println(" kB volatile"); 12163 } 12164 pw.print(" Tuning: "); 12165 pw.print(ActivityManager.staticGetMemoryClass()); 12166 pw.print(" (large "); 12167 pw.print(ActivityManager.staticGetLargeMemoryClass()); 12168 pw.print("), oom "); 12169 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024); 12170 pw.print(" kB"); 12171 pw.print(", restore limit "); 12172 pw.print(mProcessList.getCachedRestoreThresholdKb()); 12173 pw.print(" kB"); 12174 if (ActivityManager.isLowRamDeviceStatic()) { 12175 pw.print(" (low-ram)"); 12176 } 12177 if (ActivityManager.isHighEndGfx()) { 12178 pw.print(" (high-end-gfx)"); 12179 } 12180 pw.println(); 12181 } else { 12182 pw.print("ksm,"); pw.print(sharing); pw.print(","); 12183 pw.print(shared); pw.print(","); pw.print(unshared); pw.print(","); 12184 pw.println(voltile); 12185 pw.print("tuning,"); 12186 pw.print(ActivityManager.staticGetMemoryClass()); 12187 pw.print(','); 12188 pw.print(ActivityManager.staticGetLargeMemoryClass()); 12189 pw.print(','); 12190 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024); 12191 if (ActivityManager.isLowRamDeviceStatic()) { 12192 pw.print(",low-ram"); 12193 } 12194 if (ActivityManager.isHighEndGfx()) { 12195 pw.print(",high-end-gfx"); 12196 } 12197 pw.println(); 12198 } 12199 } 12200 } 12201 } 12202 12203 /** 12204 * Searches array of arguments for the specified string 12205 * @param args array of argument strings 12206 * @param value value to search for 12207 * @return true if the value is contained in the array 12208 */ 12209 private static boolean scanArgs(String[] args, String value) { 12210 if (args != null) { 12211 for (String arg : args) { 12212 if (value.equals(arg)) { 12213 return true; 12214 } 12215 } 12216 } 12217 return false; 12218 } 12219 12220 private final boolean removeDyingProviderLocked(ProcessRecord proc, 12221 ContentProviderRecord cpr, boolean always) { 12222 final boolean inLaunching = mLaunchingProviders.contains(cpr); 12223 12224 if (!inLaunching || always) { 12225 synchronized (cpr) { 12226 cpr.launchingApp = null; 12227 cpr.notifyAll(); 12228 } 12229 mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid)); 12230 String names[] = cpr.info.authority.split(";"); 12231 for (int j = 0; j < names.length; j++) { 12232 mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid)); 12233 } 12234 } 12235 12236 for (int i=0; i<cpr.connections.size(); i++) { 12237 ContentProviderConnection conn = cpr.connections.get(i); 12238 if (conn.waiting) { 12239 // If this connection is waiting for the provider, then we don't 12240 // need to mess with its process unless we are always removing 12241 // or for some reason the provider is not currently launching. 12242 if (inLaunching && !always) { 12243 continue; 12244 } 12245 } 12246 ProcessRecord capp = conn.client; 12247 conn.dead = true; 12248 if (conn.stableCount > 0) { 12249 if (!capp.persistent && capp.thread != null 12250 && capp.pid != 0 12251 && capp.pid != MY_PID) { 12252 killUnneededProcessLocked(capp, "depends on provider " 12253 + cpr.name.flattenToShortString() 12254 + " in dying proc " + (proc != null ? proc.processName : "??")); 12255 } 12256 } else if (capp.thread != null && conn.provider.provider != null) { 12257 try { 12258 capp.thread.unstableProviderDied(conn.provider.provider.asBinder()); 12259 } catch (RemoteException e) { 12260 } 12261 // In the protocol here, we don't expect the client to correctly 12262 // clean up this connection, we'll just remove it. 12263 cpr.connections.remove(i); 12264 conn.client.conProviders.remove(conn); 12265 } 12266 } 12267 12268 if (inLaunching && always) { 12269 mLaunchingProviders.remove(cpr); 12270 } 12271 return inLaunching; 12272 } 12273 12274 /** 12275 * Main code for cleaning up a process when it has gone away. This is 12276 * called both as a result of the process dying, or directly when stopping 12277 * a process when running in single process mode. 12278 */ 12279 private final void cleanUpApplicationRecordLocked(ProcessRecord app, 12280 boolean restarting, boolean allowRestart, int index) { 12281 if (index >= 0) { 12282 removeLruProcessLocked(app); 12283 ProcessList.remove(app.pid); 12284 } 12285 12286 mProcessesToGc.remove(app); 12287 mPendingPssProcesses.remove(app); 12288 12289 // Dismiss any open dialogs. 12290 if (app.crashDialog != null && !app.forceCrashReport) { 12291 app.crashDialog.dismiss(); 12292 app.crashDialog = null; 12293 } 12294 if (app.anrDialog != null) { 12295 app.anrDialog.dismiss(); 12296 app.anrDialog = null; 12297 } 12298 if (app.waitDialog != null) { 12299 app.waitDialog.dismiss(); 12300 app.waitDialog = null; 12301 } 12302 12303 app.crashing = false; 12304 app.notResponding = false; 12305 12306 app.resetPackageList(mProcessStats); 12307 app.unlinkDeathRecipient(); 12308 app.makeInactive(mProcessStats); 12309 app.forcingToForeground = null; 12310 app.foregroundServices = false; 12311 app.foregroundActivities = false; 12312 app.hasShownUi = false; 12313 app.hasAboveClient = false; 12314 12315 mServices.killServicesLocked(app, allowRestart); 12316 12317 boolean restart = false; 12318 12319 // Remove published content providers. 12320 for (int i=app.pubProviders.size()-1; i>=0; i--) { 12321 ContentProviderRecord cpr = app.pubProviders.valueAt(i); 12322 final boolean always = app.bad || !allowRestart; 12323 if (removeDyingProviderLocked(app, cpr, always) || always) { 12324 // We left the provider in the launching list, need to 12325 // restart it. 12326 restart = true; 12327 } 12328 12329 cpr.provider = null; 12330 cpr.proc = null; 12331 } 12332 app.pubProviders.clear(); 12333 12334 // Take care of any launching providers waiting for this process. 12335 if (checkAppInLaunchingProvidersLocked(app, false)) { 12336 restart = true; 12337 } 12338 12339 // Unregister from connected content providers. 12340 if (!app.conProviders.isEmpty()) { 12341 for (int i=0; i<app.conProviders.size(); i++) { 12342 ContentProviderConnection conn = app.conProviders.get(i); 12343 conn.provider.connections.remove(conn); 12344 } 12345 app.conProviders.clear(); 12346 } 12347 12348 // At this point there may be remaining entries in mLaunchingProviders 12349 // where we were the only one waiting, so they are no longer of use. 12350 // Look for these and clean up if found. 12351 // XXX Commented out for now. Trying to figure out a way to reproduce 12352 // the actual situation to identify what is actually going on. 12353 if (false) { 12354 for (int i=0; i<mLaunchingProviders.size(); i++) { 12355 ContentProviderRecord cpr = (ContentProviderRecord) 12356 mLaunchingProviders.get(i); 12357 if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) { 12358 synchronized (cpr) { 12359 cpr.launchingApp = null; 12360 cpr.notifyAll(); 12361 } 12362 } 12363 } 12364 } 12365 12366 skipCurrentReceiverLocked(app); 12367 12368 // Unregister any receivers. 12369 for (int i=app.receivers.size()-1; i>=0; i--) { 12370 removeReceiverLocked(app.receivers.valueAt(i)); 12371 } 12372 app.receivers.clear(); 12373 12374 // If the app is undergoing backup, tell the backup manager about it 12375 if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) { 12376 if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App " 12377 + mBackupTarget.appInfo + " died during backup"); 12378 try { 12379 IBackupManager bm = IBackupManager.Stub.asInterface( 12380 ServiceManager.getService(Context.BACKUP_SERVICE)); 12381 bm.agentDisconnected(app.info.packageName); 12382 } catch (RemoteException e) { 12383 // can't happen; backup manager is local 12384 } 12385 } 12386 12387 for (int i = mPendingProcessChanges.size()-1; i>=0; i--) { 12388 ProcessChangeItem item = mPendingProcessChanges.get(i); 12389 if (item.pid == app.pid) { 12390 mPendingProcessChanges.remove(i); 12391 mAvailProcessChanges.add(item); 12392 } 12393 } 12394 mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget(); 12395 12396 // If the caller is restarting this app, then leave it in its 12397 // current lists and let the caller take care of it. 12398 if (restarting) { 12399 return; 12400 } 12401 12402 if (!app.persistent || app.isolated) { 12403 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, 12404 "Removing non-persistent process during cleanup: " + app); 12405 mProcessNames.remove(app.processName, app.uid); 12406 mIsolatedProcesses.remove(app.uid); 12407 if (mHeavyWeightProcess == app) { 12408 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 12409 mHeavyWeightProcess.userId, 0)); 12410 mHeavyWeightProcess = null; 12411 } 12412 } else if (!app.removed) { 12413 // This app is persistent, so we need to keep its record around. 12414 // If it is not already on the pending app list, add it there 12415 // and start a new process for it. 12416 if (mPersistentStartingProcesses.indexOf(app) < 0) { 12417 mPersistentStartingProcesses.add(app); 12418 restart = true; 12419 } 12420 } 12421 if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG, 12422 "Clean-up removing on hold: " + app); 12423 mProcessesOnHold.remove(app); 12424 12425 if (app == mHomeProcess) { 12426 mHomeProcess = null; 12427 } 12428 if (app == mPreviousProcess) { 12429 mPreviousProcess = null; 12430 } 12431 12432 if (restart && !app.isolated) { 12433 // We have components that still need to be running in the 12434 // process, so re-launch it. 12435 mProcessNames.put(app.processName, app.uid, app); 12436 startProcessLocked(app, "restart", app.processName); 12437 } else if (app.pid > 0 && app.pid != MY_PID) { 12438 // Goodbye! 12439 synchronized (mPidsSelfLocked) { 12440 mPidsSelfLocked.remove(app.pid); 12441 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 12442 } 12443 app.setPid(0); 12444 } 12445 } 12446 12447 boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) { 12448 // Look through the content providers we are waiting to have launched, 12449 // and if any run in this process then either schedule a restart of 12450 // the process or kill the client waiting for it if this process has 12451 // gone bad. 12452 int NL = mLaunchingProviders.size(); 12453 boolean restart = false; 12454 for (int i=0; i<NL; i++) { 12455 ContentProviderRecord cpr = mLaunchingProviders.get(i); 12456 if (cpr.launchingApp == app) { 12457 if (!alwaysBad && !app.bad) { 12458 restart = true; 12459 } else { 12460 removeDyingProviderLocked(app, cpr, true); 12461 // cpr should have been removed from mLaunchingProviders 12462 NL = mLaunchingProviders.size(); 12463 i--; 12464 } 12465 } 12466 } 12467 return restart; 12468 } 12469 12470 // ========================================================= 12471 // SERVICES 12472 // ========================================================= 12473 12474 public List<ActivityManager.RunningServiceInfo> getServices(int maxNum, 12475 int flags) { 12476 enforceNotIsolatedCaller("getServices"); 12477 synchronized (this) { 12478 return mServices.getRunningServiceInfoLocked(maxNum, flags); 12479 } 12480 } 12481 12482 public PendingIntent getRunningServiceControlPanel(ComponentName name) { 12483 enforceNotIsolatedCaller("getRunningServiceControlPanel"); 12484 synchronized (this) { 12485 return mServices.getRunningServiceControlPanelLocked(name); 12486 } 12487 } 12488 12489 public ComponentName startService(IApplicationThread caller, Intent service, 12490 String resolvedType, int userId) { 12491 enforceNotIsolatedCaller("startService"); 12492 // Refuse possible leaked file descriptors 12493 if (service != null && service.hasFileDescriptors() == true) { 12494 throw new IllegalArgumentException("File descriptors passed in Intent"); 12495 } 12496 12497 if (DEBUG_SERVICE) 12498 Slog.v(TAG, "startService: " + service + " type=" + resolvedType); 12499 synchronized(this) { 12500 final int callingPid = Binder.getCallingPid(); 12501 final int callingUid = Binder.getCallingUid(); 12502 final long origId = Binder.clearCallingIdentity(); 12503 ComponentName res = mServices.startServiceLocked(caller, service, 12504 resolvedType, callingPid, callingUid, userId); 12505 Binder.restoreCallingIdentity(origId); 12506 return res; 12507 } 12508 } 12509 12510 ComponentName startServiceInPackage(int uid, 12511 Intent service, String resolvedType, int userId) { 12512 synchronized(this) { 12513 if (DEBUG_SERVICE) 12514 Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType); 12515 final long origId = Binder.clearCallingIdentity(); 12516 ComponentName res = mServices.startServiceLocked(null, service, 12517 resolvedType, -1, uid, userId); 12518 Binder.restoreCallingIdentity(origId); 12519 return res; 12520 } 12521 } 12522 12523 public int stopService(IApplicationThread caller, Intent service, 12524 String resolvedType, int userId) { 12525 enforceNotIsolatedCaller("stopService"); 12526 // Refuse possible leaked file descriptors 12527 if (service != null && service.hasFileDescriptors() == true) { 12528 throw new IllegalArgumentException("File descriptors passed in Intent"); 12529 } 12530 12531 synchronized(this) { 12532 return mServices.stopServiceLocked(caller, service, resolvedType, userId); 12533 } 12534 } 12535 12536 public IBinder peekService(Intent service, String resolvedType) { 12537 enforceNotIsolatedCaller("peekService"); 12538 // Refuse possible leaked file descriptors 12539 if (service != null && service.hasFileDescriptors() == true) { 12540 throw new IllegalArgumentException("File descriptors passed in Intent"); 12541 } 12542 synchronized(this) { 12543 return mServices.peekServiceLocked(service, resolvedType); 12544 } 12545 } 12546 12547 public boolean stopServiceToken(ComponentName className, IBinder token, 12548 int startId) { 12549 synchronized(this) { 12550 return mServices.stopServiceTokenLocked(className, token, startId); 12551 } 12552 } 12553 12554 public void setServiceForeground(ComponentName className, IBinder token, 12555 int id, Notification notification, boolean removeNotification) { 12556 synchronized(this) { 12557 mServices.setServiceForegroundLocked(className, token, id, notification, 12558 removeNotification); 12559 } 12560 } 12561 12562 public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll, 12563 boolean requireFull, String name, String callerPackage) { 12564 final int callingUserId = UserHandle.getUserId(callingUid); 12565 if (callingUserId != userId) { 12566 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 12567 if ((requireFull || checkComponentPermission( 12568 android.Manifest.permission.INTERACT_ACROSS_USERS, 12569 callingPid, callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) 12570 && checkComponentPermission( 12571 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 12572 callingPid, callingUid, -1, true) 12573 != PackageManager.PERMISSION_GRANTED) { 12574 if (userId == UserHandle.USER_CURRENT_OR_SELF) { 12575 // In this case, they would like to just execute as their 12576 // owner user instead of failing. 12577 userId = callingUserId; 12578 } else { 12579 StringBuilder builder = new StringBuilder(128); 12580 builder.append("Permission Denial: "); 12581 builder.append(name); 12582 if (callerPackage != null) { 12583 builder.append(" from "); 12584 builder.append(callerPackage); 12585 } 12586 builder.append(" asks to run as user "); 12587 builder.append(userId); 12588 builder.append(" but is calling from user "); 12589 builder.append(UserHandle.getUserId(callingUid)); 12590 builder.append("; this requires "); 12591 builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL); 12592 if (!requireFull) { 12593 builder.append(" or "); 12594 builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS); 12595 } 12596 String msg = builder.toString(); 12597 Slog.w(TAG, msg); 12598 throw new SecurityException(msg); 12599 } 12600 } 12601 } 12602 if (userId == UserHandle.USER_CURRENT 12603 || userId == UserHandle.USER_CURRENT_OR_SELF) { 12604 // Note that we may be accessing this outside of a lock... 12605 // shouldn't be a big deal, if this is being called outside 12606 // of a locked context there is intrinsically a race with 12607 // the value the caller will receive and someone else changing it. 12608 userId = mCurrentUserId; 12609 } 12610 if (!allowAll && userId < 0) { 12611 throw new IllegalArgumentException( 12612 "Call does not support special user #" + userId); 12613 } 12614 } 12615 return userId; 12616 } 12617 12618 boolean isSingleton(String componentProcessName, ApplicationInfo aInfo, 12619 String className, int flags) { 12620 boolean result = false; 12621 if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) { 12622 if ((flags&ServiceInfo.FLAG_SINGLE_USER) != 0) { 12623 if (ActivityManager.checkUidPermission( 12624 android.Manifest.permission.INTERACT_ACROSS_USERS, 12625 aInfo.uid) != PackageManager.PERMISSION_GRANTED) { 12626 ComponentName comp = new ComponentName(aInfo.packageName, className); 12627 String msg = "Permission Denial: Component " + comp.flattenToShortString() 12628 + " requests FLAG_SINGLE_USER, but app does not hold " 12629 + android.Manifest.permission.INTERACT_ACROSS_USERS; 12630 Slog.w(TAG, msg); 12631 throw new SecurityException(msg); 12632 } 12633 result = true; 12634 } 12635 } else if (componentProcessName == aInfo.packageName) { 12636 result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0; 12637 } else if ("system".equals(componentProcessName)) { 12638 result = true; 12639 } 12640 if (DEBUG_MU) { 12641 Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo 12642 + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result); 12643 } 12644 return result; 12645 } 12646 12647 public int bindService(IApplicationThread caller, IBinder token, 12648 Intent service, String resolvedType, 12649 IServiceConnection connection, int flags, int userId) { 12650 enforceNotIsolatedCaller("bindService"); 12651 // Refuse possible leaked file descriptors 12652 if (service != null && service.hasFileDescriptors() == true) { 12653 throw new IllegalArgumentException("File descriptors passed in Intent"); 12654 } 12655 12656 synchronized(this) { 12657 return mServices.bindServiceLocked(caller, token, service, resolvedType, 12658 connection, flags, userId); 12659 } 12660 } 12661 12662 public boolean unbindService(IServiceConnection connection) { 12663 synchronized (this) { 12664 return mServices.unbindServiceLocked(connection); 12665 } 12666 } 12667 12668 public void publishService(IBinder token, Intent intent, IBinder service) { 12669 // Refuse possible leaked file descriptors 12670 if (intent != null && intent.hasFileDescriptors() == true) { 12671 throw new IllegalArgumentException("File descriptors passed in Intent"); 12672 } 12673 12674 synchronized(this) { 12675 if (!(token instanceof ServiceRecord)) { 12676 throw new IllegalArgumentException("Invalid service token"); 12677 } 12678 mServices.publishServiceLocked((ServiceRecord)token, intent, service); 12679 } 12680 } 12681 12682 public void unbindFinished(IBinder token, Intent intent, boolean doRebind) { 12683 // Refuse possible leaked file descriptors 12684 if (intent != null && intent.hasFileDescriptors() == true) { 12685 throw new IllegalArgumentException("File descriptors passed in Intent"); 12686 } 12687 12688 synchronized(this) { 12689 mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind); 12690 } 12691 } 12692 12693 public void serviceDoneExecuting(IBinder token, int type, int startId, int res) { 12694 synchronized(this) { 12695 if (!(token instanceof ServiceRecord)) { 12696 throw new IllegalArgumentException("Invalid service token"); 12697 } 12698 mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res); 12699 } 12700 } 12701 12702 // ========================================================= 12703 // BACKUP AND RESTORE 12704 // ========================================================= 12705 12706 // Cause the target app to be launched if necessary and its backup agent 12707 // instantiated. The backup agent will invoke backupAgentCreated() on the 12708 // activity manager to announce its creation. 12709 public boolean bindBackupAgent(ApplicationInfo app, int backupMode) { 12710 if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode); 12711 enforceCallingPermission("android.permission.BACKUP", "bindBackupAgent"); 12712 12713 synchronized(this) { 12714 // !!! TODO: currently no check here that we're already bound 12715 BatteryStatsImpl.Uid.Pkg.Serv ss = null; 12716 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 12717 synchronized (stats) { 12718 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name); 12719 } 12720 12721 // Backup agent is now in use, its package can't be stopped. 12722 try { 12723 AppGlobals.getPackageManager().setPackageStoppedState( 12724 app.packageName, false, UserHandle.getUserId(app.uid)); 12725 } catch (RemoteException e) { 12726 } catch (IllegalArgumentException e) { 12727 Slog.w(TAG, "Failed trying to unstop package " 12728 + app.packageName + ": " + e); 12729 } 12730 12731 BackupRecord r = new BackupRecord(ss, app, backupMode); 12732 ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL) 12733 ? new ComponentName(app.packageName, app.backupAgentName) 12734 : new ComponentName("android", "FullBackupAgent"); 12735 // startProcessLocked() returns existing proc's record if it's already running 12736 ProcessRecord proc = startProcessLocked(app.processName, app, 12737 false, 0, "backup", hostingName, false, false, false); 12738 if (proc == null) { 12739 Slog.e(TAG, "Unable to start backup agent process " + r); 12740 return false; 12741 } 12742 12743 r.app = proc; 12744 mBackupTarget = r; 12745 mBackupAppName = app.packageName; 12746 12747 // Try not to kill the process during backup 12748 updateOomAdjLocked(proc); 12749 12750 // If the process is already attached, schedule the creation of the backup agent now. 12751 // If it is not yet live, this will be done when it attaches to the framework. 12752 if (proc.thread != null) { 12753 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc); 12754 try { 12755 proc.thread.scheduleCreateBackupAgent(app, 12756 compatibilityInfoForPackageLocked(app), backupMode); 12757 } catch (RemoteException e) { 12758 // Will time out on the backup manager side 12759 } 12760 } else { 12761 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach"); 12762 } 12763 // Invariants: at this point, the target app process exists and the application 12764 // is either already running or in the process of coming up. mBackupTarget and 12765 // mBackupAppName describe the app, so that when it binds back to the AM we 12766 // know that it's scheduled for a backup-agent operation. 12767 } 12768 12769 return true; 12770 } 12771 12772 @Override 12773 public void clearPendingBackup() { 12774 if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup"); 12775 enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup"); 12776 12777 synchronized (this) { 12778 mBackupTarget = null; 12779 mBackupAppName = null; 12780 } 12781 } 12782 12783 // A backup agent has just come up 12784 public void backupAgentCreated(String agentPackageName, IBinder agent) { 12785 if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName 12786 + " = " + agent); 12787 12788 synchronized(this) { 12789 if (!agentPackageName.equals(mBackupAppName)) { 12790 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!"); 12791 return; 12792 } 12793 } 12794 12795 long oldIdent = Binder.clearCallingIdentity(); 12796 try { 12797 IBackupManager bm = IBackupManager.Stub.asInterface( 12798 ServiceManager.getService(Context.BACKUP_SERVICE)); 12799 bm.agentConnected(agentPackageName, agent); 12800 } catch (RemoteException e) { 12801 // can't happen; the backup manager service is local 12802 } catch (Exception e) { 12803 Slog.w(TAG, "Exception trying to deliver BackupAgent binding: "); 12804 e.printStackTrace(); 12805 } finally { 12806 Binder.restoreCallingIdentity(oldIdent); 12807 } 12808 } 12809 12810 // done with this agent 12811 public void unbindBackupAgent(ApplicationInfo appInfo) { 12812 if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo); 12813 if (appInfo == null) { 12814 Slog.w(TAG, "unbind backup agent for null app"); 12815 return; 12816 } 12817 12818 synchronized(this) { 12819 try { 12820 if (mBackupAppName == null) { 12821 Slog.w(TAG, "Unbinding backup agent with no active backup"); 12822 return; 12823 } 12824 12825 if (!mBackupAppName.equals(appInfo.packageName)) { 12826 Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target"); 12827 return; 12828 } 12829 12830 // Not backing this app up any more; reset its OOM adjustment 12831 final ProcessRecord proc = mBackupTarget.app; 12832 updateOomAdjLocked(proc); 12833 12834 // If the app crashed during backup, 'thread' will be null here 12835 if (proc.thread != null) { 12836 try { 12837 proc.thread.scheduleDestroyBackupAgent(appInfo, 12838 compatibilityInfoForPackageLocked(appInfo)); 12839 } catch (Exception e) { 12840 Slog.e(TAG, "Exception when unbinding backup agent:"); 12841 e.printStackTrace(); 12842 } 12843 } 12844 } finally { 12845 mBackupTarget = null; 12846 mBackupAppName = null; 12847 } 12848 } 12849 } 12850 // ========================================================= 12851 // BROADCASTS 12852 // ========================================================= 12853 12854 private final List getStickiesLocked(String action, IntentFilter filter, 12855 List cur, int userId) { 12856 final ContentResolver resolver = mContext.getContentResolver(); 12857 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 12858 if (stickies == null) { 12859 return cur; 12860 } 12861 final ArrayList<Intent> list = stickies.get(action); 12862 if (list == null) { 12863 return cur; 12864 } 12865 int N = list.size(); 12866 for (int i=0; i<N; i++) { 12867 Intent intent = list.get(i); 12868 if (filter.match(resolver, intent, true, TAG) >= 0) { 12869 if (cur == null) { 12870 cur = new ArrayList<Intent>(); 12871 } 12872 cur.add(intent); 12873 } 12874 } 12875 return cur; 12876 } 12877 12878 boolean isPendingBroadcastProcessLocked(int pid) { 12879 return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid) 12880 || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid); 12881 } 12882 12883 void skipPendingBroadcastLocked(int pid) { 12884 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 12885 for (BroadcastQueue queue : mBroadcastQueues) { 12886 queue.skipPendingBroadcastLocked(pid); 12887 } 12888 } 12889 12890 // The app just attached; send any pending broadcasts that it should receive 12891 boolean sendPendingBroadcastsLocked(ProcessRecord app) { 12892 boolean didSomething = false; 12893 for (BroadcastQueue queue : mBroadcastQueues) { 12894 didSomething |= queue.sendPendingBroadcastsLocked(app); 12895 } 12896 return didSomething; 12897 } 12898 12899 public Intent registerReceiver(IApplicationThread caller, String callerPackage, 12900 IIntentReceiver receiver, IntentFilter filter, String permission, int userId) { 12901 enforceNotIsolatedCaller("registerReceiver"); 12902 int callingUid; 12903 int callingPid; 12904 synchronized(this) { 12905 ProcessRecord callerApp = null; 12906 if (caller != null) { 12907 callerApp = getRecordForAppLocked(caller); 12908 if (callerApp == null) { 12909 throw new SecurityException( 12910 "Unable to find app for caller " + caller 12911 + " (pid=" + Binder.getCallingPid() 12912 + ") when registering receiver " + receiver); 12913 } 12914 if (callerApp.info.uid != Process.SYSTEM_UID && 12915 !callerApp.pkgList.containsKey(callerPackage) && 12916 !"android".equals(callerPackage)) { 12917 throw new SecurityException("Given caller package " + callerPackage 12918 + " is not running in process " + callerApp); 12919 } 12920 callingUid = callerApp.info.uid; 12921 callingPid = callerApp.pid; 12922 } else { 12923 callerPackage = null; 12924 callingUid = Binder.getCallingUid(); 12925 callingPid = Binder.getCallingPid(); 12926 } 12927 12928 userId = this.handleIncomingUser(callingPid, callingUid, userId, 12929 true, true, "registerReceiver", callerPackage); 12930 12931 List allSticky = null; 12932 12933 // Look for any matching sticky broadcasts... 12934 Iterator actions = filter.actionsIterator(); 12935 if (actions != null) { 12936 while (actions.hasNext()) { 12937 String action = (String)actions.next(); 12938 allSticky = getStickiesLocked(action, filter, allSticky, 12939 UserHandle.USER_ALL); 12940 allSticky = getStickiesLocked(action, filter, allSticky, 12941 UserHandle.getUserId(callingUid)); 12942 } 12943 } else { 12944 allSticky = getStickiesLocked(null, filter, allSticky, 12945 UserHandle.USER_ALL); 12946 allSticky = getStickiesLocked(null, filter, allSticky, 12947 UserHandle.getUserId(callingUid)); 12948 } 12949 12950 // The first sticky in the list is returned directly back to 12951 // the client. 12952 Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null; 12953 12954 if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter 12955 + ": " + sticky); 12956 12957 if (receiver == null) { 12958 return sticky; 12959 } 12960 12961 ReceiverList rl 12962 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder()); 12963 if (rl == null) { 12964 rl = new ReceiverList(this, callerApp, callingPid, callingUid, 12965 userId, receiver); 12966 if (rl.app != null) { 12967 rl.app.receivers.add(rl); 12968 } else { 12969 try { 12970 receiver.asBinder().linkToDeath(rl, 0); 12971 } catch (RemoteException e) { 12972 return sticky; 12973 } 12974 rl.linkedToDeath = true; 12975 } 12976 mRegisteredReceivers.put(receiver.asBinder(), rl); 12977 } else if (rl.uid != callingUid) { 12978 throw new IllegalArgumentException( 12979 "Receiver requested to register for uid " + callingUid 12980 + " was previously registered for uid " + rl.uid); 12981 } else if (rl.pid != callingPid) { 12982 throw new IllegalArgumentException( 12983 "Receiver requested to register for pid " + callingPid 12984 + " was previously registered for pid " + rl.pid); 12985 } else if (rl.userId != userId) { 12986 throw new IllegalArgumentException( 12987 "Receiver requested to register for user " + userId 12988 + " was previously registered for user " + rl.userId); 12989 } 12990 BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage, 12991 permission, callingUid, userId); 12992 rl.add(bf); 12993 if (!bf.debugCheck()) { 12994 Slog.w(TAG, "==> For Dynamic broadast"); 12995 } 12996 mReceiverResolver.addFilter(bf); 12997 12998 // Enqueue broadcasts for all existing stickies that match 12999 // this filter. 13000 if (allSticky != null) { 13001 ArrayList receivers = new ArrayList(); 13002 receivers.add(bf); 13003 13004 int N = allSticky.size(); 13005 for (int i=0; i<N; i++) { 13006 Intent intent = (Intent)allSticky.get(i); 13007 BroadcastQueue queue = broadcastQueueForIntent(intent); 13008 BroadcastRecord r = new BroadcastRecord(queue, intent, null, 13009 null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0, 13010 null, null, false, true, true, -1); 13011 queue.enqueueParallelBroadcastLocked(r); 13012 queue.scheduleBroadcastsLocked(); 13013 } 13014 } 13015 13016 return sticky; 13017 } 13018 } 13019 13020 public void unregisterReceiver(IIntentReceiver receiver) { 13021 if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver); 13022 13023 final long origId = Binder.clearCallingIdentity(); 13024 try { 13025 boolean doTrim = false; 13026 13027 synchronized(this) { 13028 ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder()); 13029 if (rl != null) { 13030 if (rl.curBroadcast != null) { 13031 BroadcastRecord r = rl.curBroadcast; 13032 final boolean doNext = finishReceiverLocked( 13033 receiver.asBinder(), r.resultCode, r.resultData, 13034 r.resultExtras, r.resultAbort); 13035 if (doNext) { 13036 doTrim = true; 13037 r.queue.processNextBroadcast(false); 13038 } 13039 } 13040 13041 if (rl.app != null) { 13042 rl.app.receivers.remove(rl); 13043 } 13044 removeReceiverLocked(rl); 13045 if (rl.linkedToDeath) { 13046 rl.linkedToDeath = false; 13047 rl.receiver.asBinder().unlinkToDeath(rl, 0); 13048 } 13049 } 13050 } 13051 13052 // If we actually concluded any broadcasts, we might now be able 13053 // to trim the recipients' apps from our working set 13054 if (doTrim) { 13055 trimApplications(); 13056 return; 13057 } 13058 13059 } finally { 13060 Binder.restoreCallingIdentity(origId); 13061 } 13062 } 13063 13064 void removeReceiverLocked(ReceiverList rl) { 13065 mRegisteredReceivers.remove(rl.receiver.asBinder()); 13066 int N = rl.size(); 13067 for (int i=0; i<N; i++) { 13068 mReceiverResolver.removeFilter(rl.get(i)); 13069 } 13070 } 13071 13072 private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) { 13073 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 13074 ProcessRecord r = mLruProcesses.get(i); 13075 if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) { 13076 try { 13077 r.thread.dispatchPackageBroadcast(cmd, packages); 13078 } catch (RemoteException ex) { 13079 } 13080 } 13081 } 13082 } 13083 13084 private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType, 13085 int[] users) { 13086 List<ResolveInfo> receivers = null; 13087 try { 13088 HashSet<ComponentName> singleUserReceivers = null; 13089 boolean scannedFirstReceivers = false; 13090 for (int user : users) { 13091 List<ResolveInfo> newReceivers = AppGlobals.getPackageManager() 13092 .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user); 13093 if (user != 0 && newReceivers != null) { 13094 // If this is not the primary user, we need to check for 13095 // any receivers that should be filtered out. 13096 for (int i=0; i<newReceivers.size(); i++) { 13097 ResolveInfo ri = newReceivers.get(i); 13098 if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) { 13099 newReceivers.remove(i); 13100 i--; 13101 } 13102 } 13103 } 13104 if (newReceivers != null && newReceivers.size() == 0) { 13105 newReceivers = null; 13106 } 13107 if (receivers == null) { 13108 receivers = newReceivers; 13109 } else if (newReceivers != null) { 13110 // We need to concatenate the additional receivers 13111 // found with what we have do far. This would be easy, 13112 // but we also need to de-dup any receivers that are 13113 // singleUser. 13114 if (!scannedFirstReceivers) { 13115 // Collect any single user receivers we had already retrieved. 13116 scannedFirstReceivers = true; 13117 for (int i=0; i<receivers.size(); i++) { 13118 ResolveInfo ri = receivers.get(i); 13119 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 13120 ComponentName cn = new ComponentName( 13121 ri.activityInfo.packageName, ri.activityInfo.name); 13122 if (singleUserReceivers == null) { 13123 singleUserReceivers = new HashSet<ComponentName>(); 13124 } 13125 singleUserReceivers.add(cn); 13126 } 13127 } 13128 } 13129 // Add the new results to the existing results, tracking 13130 // and de-dupping single user receivers. 13131 for (int i=0; i<newReceivers.size(); i++) { 13132 ResolveInfo ri = newReceivers.get(i); 13133 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 13134 ComponentName cn = new ComponentName( 13135 ri.activityInfo.packageName, ri.activityInfo.name); 13136 if (singleUserReceivers == null) { 13137 singleUserReceivers = new HashSet<ComponentName>(); 13138 } 13139 if (!singleUserReceivers.contains(cn)) { 13140 singleUserReceivers.add(cn); 13141 receivers.add(ri); 13142 } 13143 } else { 13144 receivers.add(ri); 13145 } 13146 } 13147 } 13148 } 13149 } catch (RemoteException ex) { 13150 // pm is in same process, this will never happen. 13151 } 13152 return receivers; 13153 } 13154 13155 private final int broadcastIntentLocked(ProcessRecord callerApp, 13156 String callerPackage, Intent intent, String resolvedType, 13157 IIntentReceiver resultTo, int resultCode, String resultData, 13158 Bundle map, String requiredPermission, int appOp, 13159 boolean ordered, boolean sticky, int callingPid, int callingUid, 13160 int userId) { 13161 intent = new Intent(intent); 13162 13163 // By default broadcasts do not go to stopped apps. 13164 intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES); 13165 13166 if (DEBUG_BROADCAST_LIGHT) Slog.v( 13167 TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent 13168 + " ordered=" + ordered + " userid=" + userId); 13169 if ((resultTo != null) && !ordered) { 13170 Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!"); 13171 } 13172 13173 userId = handleIncomingUser(callingPid, callingUid, userId, 13174 true, false, "broadcast", callerPackage); 13175 13176 // Make sure that the user who is receiving this broadcast is started. 13177 // If not, we will just skip it. 13178 if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) { 13179 if (callingUid != Process.SYSTEM_UID || (intent.getFlags() 13180 & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) { 13181 Slog.w(TAG, "Skipping broadcast of " + intent 13182 + ": user " + userId + " is stopped"); 13183 return ActivityManager.BROADCAST_SUCCESS; 13184 } 13185 } 13186 13187 /* 13188 * Prevent non-system code (defined here to be non-persistent 13189 * processes) from sending protected broadcasts. 13190 */ 13191 int callingAppId = UserHandle.getAppId(callingUid); 13192 if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID 13193 || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID || 13194 callingUid == 0) { 13195 // Always okay. 13196 } else if (callerApp == null || !callerApp.persistent) { 13197 try { 13198 if (AppGlobals.getPackageManager().isProtectedBroadcast( 13199 intent.getAction())) { 13200 String msg = "Permission Denial: not allowed to send broadcast " 13201 + intent.getAction() + " from pid=" 13202 + callingPid + ", uid=" + callingUid; 13203 Slog.w(TAG, msg); 13204 throw new SecurityException(msg); 13205 } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) { 13206 // Special case for compatibility: we don't want apps to send this, 13207 // but historically it has not been protected and apps may be using it 13208 // to poke their own app widget. So, instead of making it protected, 13209 // just limit it to the caller. 13210 if (callerApp == null) { 13211 String msg = "Permission Denial: not allowed to send broadcast " 13212 + intent.getAction() + " from unknown caller."; 13213 Slog.w(TAG, msg); 13214 throw new SecurityException(msg); 13215 } else if (intent.getComponent() != null) { 13216 // They are good enough to send to an explicit component... verify 13217 // it is being sent to the calling app. 13218 if (!intent.getComponent().getPackageName().equals( 13219 callerApp.info.packageName)) { 13220 String msg = "Permission Denial: not allowed to send broadcast " 13221 + intent.getAction() + " to " 13222 + intent.getComponent().getPackageName() + " from " 13223 + callerApp.info.packageName; 13224 Slog.w(TAG, msg); 13225 throw new SecurityException(msg); 13226 } 13227 } else { 13228 // Limit broadcast to their own package. 13229 intent.setPackage(callerApp.info.packageName); 13230 } 13231 } 13232 } catch (RemoteException e) { 13233 Slog.w(TAG, "Remote exception", e); 13234 return ActivityManager.BROADCAST_SUCCESS; 13235 } 13236 } 13237 13238 // Handle special intents: if this broadcast is from the package 13239 // manager about a package being removed, we need to remove all of 13240 // its activities from the history stack. 13241 final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals( 13242 intent.getAction()); 13243 if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction()) 13244 || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction()) 13245 || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction()) 13246 || uidRemoved) { 13247 if (checkComponentPermission( 13248 android.Manifest.permission.BROADCAST_PACKAGE_REMOVED, 13249 callingPid, callingUid, -1, true) 13250 == PackageManager.PERMISSION_GRANTED) { 13251 if (uidRemoved) { 13252 final Bundle intentExtras = intent.getExtras(); 13253 final int uid = intentExtras != null 13254 ? intentExtras.getInt(Intent.EXTRA_UID) : -1; 13255 if (uid >= 0) { 13256 BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics(); 13257 synchronized (bs) { 13258 bs.removeUidStatsLocked(uid); 13259 } 13260 mAppOpsService.uidRemoved(uid); 13261 } 13262 } else { 13263 // If resources are unavailable just force stop all 13264 // those packages and flush the attribute cache as well. 13265 if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) { 13266 String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 13267 if (list != null && (list.length > 0)) { 13268 for (String pkg : list) { 13269 forceStopPackageLocked(pkg, -1, false, true, true, false, userId, 13270 "storage unmount"); 13271 } 13272 sendPackageBroadcastLocked( 13273 IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId); 13274 } 13275 } else { 13276 Uri data = intent.getData(); 13277 String ssp; 13278 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 13279 boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals( 13280 intent.getAction()); 13281 if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) { 13282 forceStopPackageLocked(ssp, UserHandle.getAppId( 13283 intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true, 13284 false, userId, removed ? "pkg removed" : "pkg changed"); 13285 } 13286 if (removed) { 13287 sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED, 13288 new String[] {ssp}, userId); 13289 if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) { 13290 mAppOpsService.packageRemoved( 13291 intent.getIntExtra(Intent.EXTRA_UID, -1), ssp); 13292 13293 // Remove all permissions granted from/to this package 13294 removeUriPermissionsForPackageLocked(ssp, userId, true); 13295 } 13296 } 13297 } 13298 } 13299 } 13300 } else { 13301 String msg = "Permission Denial: " + intent.getAction() 13302 + " broadcast from " + callerPackage + " (pid=" + callingPid 13303 + ", uid=" + callingUid + ")" 13304 + " requires " 13305 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED; 13306 Slog.w(TAG, msg); 13307 throw new SecurityException(msg); 13308 } 13309 13310 // Special case for adding a package: by default turn on compatibility 13311 // mode. 13312 } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) { 13313 Uri data = intent.getData(); 13314 String ssp; 13315 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 13316 mCompatModePackages.handlePackageAddedLocked(ssp, 13317 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)); 13318 } 13319 } 13320 13321 /* 13322 * If this is the time zone changed action, queue up a message that will reset the timezone 13323 * of all currently running processes. This message will get queued up before the broadcast 13324 * happens. 13325 */ 13326 if (intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) { 13327 mHandler.sendEmptyMessage(UPDATE_TIME_ZONE); 13328 } 13329 13330 if (intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) { 13331 mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG); 13332 } 13333 13334 if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) { 13335 ProxyProperties proxy = intent.getParcelableExtra("proxy"); 13336 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy)); 13337 } 13338 13339 // Add to the sticky list if requested. 13340 if (sticky) { 13341 if (checkPermission(android.Manifest.permission.BROADCAST_STICKY, 13342 callingPid, callingUid) 13343 != PackageManager.PERMISSION_GRANTED) { 13344 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid=" 13345 + callingPid + ", uid=" + callingUid 13346 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 13347 Slog.w(TAG, msg); 13348 throw new SecurityException(msg); 13349 } 13350 if (requiredPermission != null) { 13351 Slog.w(TAG, "Can't broadcast sticky intent " + intent 13352 + " and enforce permission " + requiredPermission); 13353 return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION; 13354 } 13355 if (intent.getComponent() != null) { 13356 throw new SecurityException( 13357 "Sticky broadcasts can't target a specific component"); 13358 } 13359 // We use userId directly here, since the "all" target is maintained 13360 // as a separate set of sticky broadcasts. 13361 if (userId != UserHandle.USER_ALL) { 13362 // But first, if this is not a broadcast to all users, then 13363 // make sure it doesn't conflict with an existing broadcast to 13364 // all users. 13365 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get( 13366 UserHandle.USER_ALL); 13367 if (stickies != null) { 13368 ArrayList<Intent> list = stickies.get(intent.getAction()); 13369 if (list != null) { 13370 int N = list.size(); 13371 int i; 13372 for (i=0; i<N; i++) { 13373 if (intent.filterEquals(list.get(i))) { 13374 throw new IllegalArgumentException( 13375 "Sticky broadcast " + intent + " for user " 13376 + userId + " conflicts with existing global broadcast"); 13377 } 13378 } 13379 } 13380 } 13381 } 13382 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 13383 if (stickies == null) { 13384 stickies = new ArrayMap<String, ArrayList<Intent>>(); 13385 mStickyBroadcasts.put(userId, stickies); 13386 } 13387 ArrayList<Intent> list = stickies.get(intent.getAction()); 13388 if (list == null) { 13389 list = new ArrayList<Intent>(); 13390 stickies.put(intent.getAction(), list); 13391 } 13392 int N = list.size(); 13393 int i; 13394 for (i=0; i<N; i++) { 13395 if (intent.filterEquals(list.get(i))) { 13396 // This sticky already exists, replace it. 13397 list.set(i, new Intent(intent)); 13398 break; 13399 } 13400 } 13401 if (i >= N) { 13402 list.add(new Intent(intent)); 13403 } 13404 } 13405 13406 int[] users; 13407 if (userId == UserHandle.USER_ALL) { 13408 // Caller wants broadcast to go to all started users. 13409 users = mStartedUserArray; 13410 } else { 13411 // Caller wants broadcast to go to one specific user. 13412 users = new int[] {userId}; 13413 } 13414 13415 // Figure out who all will receive this broadcast. 13416 List receivers = null; 13417 List<BroadcastFilter> registeredReceivers = null; 13418 // Need to resolve the intent to interested receivers... 13419 if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) 13420 == 0) { 13421 receivers = collectReceiverComponents(intent, resolvedType, users); 13422 } 13423 if (intent.getComponent() == null) { 13424 registeredReceivers = mReceiverResolver.queryIntent(intent, 13425 resolvedType, false, userId); 13426 } 13427 13428 final boolean replacePending = 13429 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0; 13430 13431 if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction() 13432 + " replacePending=" + replacePending); 13433 13434 int NR = registeredReceivers != null ? registeredReceivers.size() : 0; 13435 if (!ordered && NR > 0) { 13436 // If we are not serializing this broadcast, then send the 13437 // registered receivers separately so they don't wait for the 13438 // components to be launched. 13439 final BroadcastQueue queue = broadcastQueueForIntent(intent); 13440 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 13441 callerPackage, callingPid, callingUid, resolvedType, requiredPermission, 13442 appOp, registeredReceivers, resultTo, resultCode, resultData, map, 13443 ordered, sticky, false, userId); 13444 if (DEBUG_BROADCAST) Slog.v( 13445 TAG, "Enqueueing parallel broadcast " + r); 13446 final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r); 13447 if (!replaced) { 13448 queue.enqueueParallelBroadcastLocked(r); 13449 queue.scheduleBroadcastsLocked(); 13450 } 13451 registeredReceivers = null; 13452 NR = 0; 13453 } 13454 13455 // Merge into one list. 13456 int ir = 0; 13457 if (receivers != null) { 13458 // A special case for PACKAGE_ADDED: do not allow the package 13459 // being added to see this broadcast. This prevents them from 13460 // using this as a back door to get run as soon as they are 13461 // installed. Maybe in the future we want to have a special install 13462 // broadcast or such for apps, but we'd like to deliberately make 13463 // this decision. 13464 String skipPackages[] = null; 13465 if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction()) 13466 || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction()) 13467 || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) { 13468 Uri data = intent.getData(); 13469 if (data != null) { 13470 String pkgName = data.getSchemeSpecificPart(); 13471 if (pkgName != null) { 13472 skipPackages = new String[] { pkgName }; 13473 } 13474 } 13475 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) { 13476 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 13477 } 13478 if (skipPackages != null && (skipPackages.length > 0)) { 13479 for (String skipPackage : skipPackages) { 13480 if (skipPackage != null) { 13481 int NT = receivers.size(); 13482 for (int it=0; it<NT; it++) { 13483 ResolveInfo curt = (ResolveInfo)receivers.get(it); 13484 if (curt.activityInfo.packageName.equals(skipPackage)) { 13485 receivers.remove(it); 13486 it--; 13487 NT--; 13488 } 13489 } 13490 } 13491 } 13492 } 13493 13494 int NT = receivers != null ? receivers.size() : 0; 13495 int it = 0; 13496 ResolveInfo curt = null; 13497 BroadcastFilter curr = null; 13498 while (it < NT && ir < NR) { 13499 if (curt == null) { 13500 curt = (ResolveInfo)receivers.get(it); 13501 } 13502 if (curr == null) { 13503 curr = registeredReceivers.get(ir); 13504 } 13505 if (curr.getPriority() >= curt.priority) { 13506 // Insert this broadcast record into the final list. 13507 receivers.add(it, curr); 13508 ir++; 13509 curr = null; 13510 it++; 13511 NT++; 13512 } else { 13513 // Skip to the next ResolveInfo in the final list. 13514 it++; 13515 curt = null; 13516 } 13517 } 13518 } 13519 while (ir < NR) { 13520 if (receivers == null) { 13521 receivers = new ArrayList(); 13522 } 13523 receivers.add(registeredReceivers.get(ir)); 13524 ir++; 13525 } 13526 13527 if ((receivers != null && receivers.size() > 0) 13528 || resultTo != null) { 13529 BroadcastQueue queue = broadcastQueueForIntent(intent); 13530 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 13531 callerPackage, callingPid, callingUid, resolvedType, 13532 requiredPermission, appOp, receivers, resultTo, resultCode, 13533 resultData, map, ordered, sticky, false, userId); 13534 if (DEBUG_BROADCAST) Slog.v( 13535 TAG, "Enqueueing ordered broadcast " + r 13536 + ": prev had " + queue.mOrderedBroadcasts.size()); 13537 if (DEBUG_BROADCAST) { 13538 int seq = r.intent.getIntExtra("seq", -1); 13539 Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq); 13540 } 13541 boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r); 13542 if (!replaced) { 13543 queue.enqueueOrderedBroadcastLocked(r); 13544 queue.scheduleBroadcastsLocked(); 13545 } 13546 } 13547 13548 return ActivityManager.BROADCAST_SUCCESS; 13549 } 13550 13551 final Intent verifyBroadcastLocked(Intent intent) { 13552 // Refuse possible leaked file descriptors 13553 if (intent != null && intent.hasFileDescriptors() == true) { 13554 throw new IllegalArgumentException("File descriptors passed in Intent"); 13555 } 13556 13557 int flags = intent.getFlags(); 13558 13559 if (!mProcessesReady) { 13560 // if the caller really truly claims to know what they're doing, go 13561 // ahead and allow the broadcast without launching any receivers 13562 if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) { 13563 intent = new Intent(intent); 13564 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 13565 } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) { 13566 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent 13567 + " before boot completion"); 13568 throw new IllegalStateException("Cannot broadcast before boot completed"); 13569 } 13570 } 13571 13572 if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 13573 throw new IllegalArgumentException( 13574 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 13575 } 13576 13577 return intent; 13578 } 13579 13580 public final int broadcastIntent(IApplicationThread caller, 13581 Intent intent, String resolvedType, IIntentReceiver resultTo, 13582 int resultCode, String resultData, Bundle map, 13583 String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) { 13584 enforceNotIsolatedCaller("broadcastIntent"); 13585 synchronized(this) { 13586 intent = verifyBroadcastLocked(intent); 13587 13588 final ProcessRecord callerApp = getRecordForAppLocked(caller); 13589 final int callingPid = Binder.getCallingPid(); 13590 final int callingUid = Binder.getCallingUid(); 13591 final long origId = Binder.clearCallingIdentity(); 13592 int res = broadcastIntentLocked(callerApp, 13593 callerApp != null ? callerApp.info.packageName : null, 13594 intent, resolvedType, resultTo, 13595 resultCode, resultData, map, requiredPermission, appOp, serialized, sticky, 13596 callingPid, callingUid, userId); 13597 Binder.restoreCallingIdentity(origId); 13598 return res; 13599 } 13600 } 13601 13602 int broadcastIntentInPackage(String packageName, int uid, 13603 Intent intent, String resolvedType, IIntentReceiver resultTo, 13604 int resultCode, String resultData, Bundle map, 13605 String requiredPermission, boolean serialized, boolean sticky, int userId) { 13606 synchronized(this) { 13607 intent = verifyBroadcastLocked(intent); 13608 13609 final long origId = Binder.clearCallingIdentity(); 13610 int res = broadcastIntentLocked(null, packageName, intent, resolvedType, 13611 resultTo, resultCode, resultData, map, requiredPermission, 13612 AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId); 13613 Binder.restoreCallingIdentity(origId); 13614 return res; 13615 } 13616 } 13617 13618 public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) { 13619 // Refuse possible leaked file descriptors 13620 if (intent != null && intent.hasFileDescriptors() == true) { 13621 throw new IllegalArgumentException("File descriptors passed in Intent"); 13622 } 13623 13624 userId = handleIncomingUser(Binder.getCallingPid(), 13625 Binder.getCallingUid(), userId, true, false, "removeStickyBroadcast", null); 13626 13627 synchronized(this) { 13628 if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY) 13629 != PackageManager.PERMISSION_GRANTED) { 13630 String msg = "Permission Denial: unbroadcastIntent() from pid=" 13631 + Binder.getCallingPid() 13632 + ", uid=" + Binder.getCallingUid() 13633 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 13634 Slog.w(TAG, msg); 13635 throw new SecurityException(msg); 13636 } 13637 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 13638 if (stickies != null) { 13639 ArrayList<Intent> list = stickies.get(intent.getAction()); 13640 if (list != null) { 13641 int N = list.size(); 13642 int i; 13643 for (i=0; i<N; i++) { 13644 if (intent.filterEquals(list.get(i))) { 13645 list.remove(i); 13646 break; 13647 } 13648 } 13649 if (list.size() <= 0) { 13650 stickies.remove(intent.getAction()); 13651 } 13652 } 13653 if (stickies.size() <= 0) { 13654 mStickyBroadcasts.remove(userId); 13655 } 13656 } 13657 } 13658 } 13659 13660 private final boolean finishReceiverLocked(IBinder receiver, int resultCode, 13661 String resultData, Bundle resultExtras, boolean resultAbort) { 13662 final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver); 13663 if (r == null) { 13664 Slog.w(TAG, "finishReceiver called but not found on queue"); 13665 return false; 13666 } 13667 13668 return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false); 13669 } 13670 13671 void backgroundServicesFinishedLocked(int userId) { 13672 for (BroadcastQueue queue : mBroadcastQueues) { 13673 queue.backgroundServicesFinishedLocked(userId); 13674 } 13675 } 13676 13677 public void finishReceiver(IBinder who, int resultCode, String resultData, 13678 Bundle resultExtras, boolean resultAbort) { 13679 if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who); 13680 13681 // Refuse possible leaked file descriptors 13682 if (resultExtras != null && resultExtras.hasFileDescriptors()) { 13683 throw new IllegalArgumentException("File descriptors passed in Bundle"); 13684 } 13685 13686 final long origId = Binder.clearCallingIdentity(); 13687 try { 13688 boolean doNext = false; 13689 BroadcastRecord r; 13690 13691 synchronized(this) { 13692 r = broadcastRecordForReceiverLocked(who); 13693 if (r != null) { 13694 doNext = r.queue.finishReceiverLocked(r, resultCode, 13695 resultData, resultExtras, resultAbort, true); 13696 } 13697 } 13698 13699 if (doNext) { 13700 r.queue.processNextBroadcast(false); 13701 } 13702 trimApplications(); 13703 } finally { 13704 Binder.restoreCallingIdentity(origId); 13705 } 13706 } 13707 13708 // ========================================================= 13709 // INSTRUMENTATION 13710 // ========================================================= 13711 13712 public boolean startInstrumentation(ComponentName className, 13713 String profileFile, int flags, Bundle arguments, 13714 IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection, 13715 int userId) { 13716 enforceNotIsolatedCaller("startInstrumentation"); 13717 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 13718 userId, false, true, "startInstrumentation", null); 13719 // Refuse possible leaked file descriptors 13720 if (arguments != null && arguments.hasFileDescriptors()) { 13721 throw new IllegalArgumentException("File descriptors passed in Bundle"); 13722 } 13723 13724 synchronized(this) { 13725 InstrumentationInfo ii = null; 13726 ApplicationInfo ai = null; 13727 try { 13728 ii = mContext.getPackageManager().getInstrumentationInfo( 13729 className, STOCK_PM_FLAGS); 13730 ai = AppGlobals.getPackageManager().getApplicationInfo( 13731 ii.targetPackage, STOCK_PM_FLAGS, userId); 13732 } catch (PackageManager.NameNotFoundException e) { 13733 } catch (RemoteException e) { 13734 } 13735 if (ii == null) { 13736 reportStartInstrumentationFailure(watcher, className, 13737 "Unable to find instrumentation info for: " + className); 13738 return false; 13739 } 13740 if (ai == null) { 13741 reportStartInstrumentationFailure(watcher, className, 13742 "Unable to find instrumentation target package: " + ii.targetPackage); 13743 return false; 13744 } 13745 13746 int match = mContext.getPackageManager().checkSignatures( 13747 ii.targetPackage, ii.packageName); 13748 if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) { 13749 String msg = "Permission Denial: starting instrumentation " 13750 + className + " from pid=" 13751 + Binder.getCallingPid() 13752 + ", uid=" + Binder.getCallingPid() 13753 + " not allowed because package " + ii.packageName 13754 + " does not have a signature matching the target " 13755 + ii.targetPackage; 13756 reportStartInstrumentationFailure(watcher, className, msg); 13757 throw new SecurityException(msg); 13758 } 13759 13760 final long origId = Binder.clearCallingIdentity(); 13761 // Instrumentation can kill and relaunch even persistent processes 13762 forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, userId, 13763 "start instr"); 13764 ProcessRecord app = addAppLocked(ai, false); 13765 app.instrumentationClass = className; 13766 app.instrumentationInfo = ai; 13767 app.instrumentationProfileFile = profileFile; 13768 app.instrumentationArguments = arguments; 13769 app.instrumentationWatcher = watcher; 13770 app.instrumentationUiAutomationConnection = uiAutomationConnection; 13771 app.instrumentationResultClass = className; 13772 Binder.restoreCallingIdentity(origId); 13773 } 13774 13775 return true; 13776 } 13777 13778 /** 13779 * Report errors that occur while attempting to start Instrumentation. Always writes the 13780 * error to the logs, but if somebody is watching, send the report there too. This enables 13781 * the "am" command to report errors with more information. 13782 * 13783 * @param watcher The IInstrumentationWatcher. Null if there isn't one. 13784 * @param cn The component name of the instrumentation. 13785 * @param report The error report. 13786 */ 13787 private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher, 13788 ComponentName cn, String report) { 13789 Slog.w(TAG, report); 13790 try { 13791 if (watcher != null) { 13792 Bundle results = new Bundle(); 13793 results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService"); 13794 results.putString("Error", report); 13795 watcher.instrumentationStatus(cn, -1, results); 13796 } 13797 } catch (RemoteException e) { 13798 Slog.w(TAG, e); 13799 } 13800 } 13801 13802 void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) { 13803 if (app.instrumentationWatcher != null) { 13804 try { 13805 // NOTE: IInstrumentationWatcher *must* be oneway here 13806 app.instrumentationWatcher.instrumentationFinished( 13807 app.instrumentationClass, 13808 resultCode, 13809 results); 13810 } catch (RemoteException e) { 13811 } 13812 } 13813 if (app.instrumentationUiAutomationConnection != null) { 13814 try { 13815 app.instrumentationUiAutomationConnection.shutdown(); 13816 } catch (RemoteException re) { 13817 /* ignore */ 13818 } 13819 // Only a UiAutomation can set this flag and now that 13820 // it is finished we make sure it is reset to its default. 13821 mUserIsMonkey = false; 13822 } 13823 app.instrumentationWatcher = null; 13824 app.instrumentationUiAutomationConnection = null; 13825 app.instrumentationClass = null; 13826 app.instrumentationInfo = null; 13827 app.instrumentationProfileFile = null; 13828 app.instrumentationArguments = null; 13829 13830 forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, app.userId, 13831 "finished inst"); 13832 } 13833 13834 public void finishInstrumentation(IApplicationThread target, 13835 int resultCode, Bundle results) { 13836 int userId = UserHandle.getCallingUserId(); 13837 // Refuse possible leaked file descriptors 13838 if (results != null && results.hasFileDescriptors()) { 13839 throw new IllegalArgumentException("File descriptors passed in Intent"); 13840 } 13841 13842 synchronized(this) { 13843 ProcessRecord app = getRecordForAppLocked(target); 13844 if (app == null) { 13845 Slog.w(TAG, "finishInstrumentation: no app for " + target); 13846 return; 13847 } 13848 final long origId = Binder.clearCallingIdentity(); 13849 finishInstrumentationLocked(app, resultCode, results); 13850 Binder.restoreCallingIdentity(origId); 13851 } 13852 } 13853 13854 // ========================================================= 13855 // CONFIGURATION 13856 // ========================================================= 13857 13858 public ConfigurationInfo getDeviceConfigurationInfo() { 13859 ConfigurationInfo config = new ConfigurationInfo(); 13860 synchronized (this) { 13861 config.reqTouchScreen = mConfiguration.touchscreen; 13862 config.reqKeyboardType = mConfiguration.keyboard; 13863 config.reqNavigation = mConfiguration.navigation; 13864 if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD 13865 || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) { 13866 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV; 13867 } 13868 if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED 13869 && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) { 13870 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD; 13871 } 13872 config.reqGlEsVersion = GL_ES_VERSION; 13873 } 13874 return config; 13875 } 13876 13877 ActivityStack getFocusedStack() { 13878 return mStackSupervisor.getFocusedStack(); 13879 } 13880 13881 public Configuration getConfiguration() { 13882 Configuration ci; 13883 synchronized(this) { 13884 ci = new Configuration(mConfiguration); 13885 } 13886 return ci; 13887 } 13888 13889 public void updatePersistentConfiguration(Configuration values) { 13890 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 13891 "updateConfiguration()"); 13892 enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS, 13893 "updateConfiguration()"); 13894 if (values == null) { 13895 throw new NullPointerException("Configuration must not be null"); 13896 } 13897 13898 synchronized(this) { 13899 final long origId = Binder.clearCallingIdentity(); 13900 updateConfigurationLocked(values, null, true, false); 13901 Binder.restoreCallingIdentity(origId); 13902 } 13903 } 13904 13905 public void updateConfiguration(Configuration values) { 13906 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 13907 "updateConfiguration()"); 13908 13909 synchronized(this) { 13910 if (values == null && mWindowManager != null) { 13911 // sentinel: fetch the current configuration from the window manager 13912 values = mWindowManager.computeNewConfiguration(); 13913 } 13914 13915 if (mWindowManager != null) { 13916 mProcessList.applyDisplaySize(mWindowManager); 13917 } 13918 13919 final long origId = Binder.clearCallingIdentity(); 13920 if (values != null) { 13921 Settings.System.clearConfiguration(values); 13922 } 13923 updateConfigurationLocked(values, null, false, false); 13924 Binder.restoreCallingIdentity(origId); 13925 } 13926 } 13927 13928 /** 13929 * Do either or both things: (1) change the current configuration, and (2) 13930 * make sure the given activity is running with the (now) current 13931 * configuration. Returns true if the activity has been left running, or 13932 * false if <var>starting</var> is being destroyed to match the new 13933 * configuration. 13934 * @param persistent TODO 13935 */ 13936 boolean updateConfigurationLocked(Configuration values, 13937 ActivityRecord starting, boolean persistent, boolean initLocale) { 13938 int changes = 0; 13939 13940 if (values != null) { 13941 Configuration newConfig = new Configuration(mConfiguration); 13942 changes = newConfig.updateFrom(values); 13943 if (changes != 0) { 13944 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) { 13945 Slog.i(TAG, "Updating configuration to: " + values); 13946 } 13947 13948 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes); 13949 13950 if (values.locale != null && !initLocale) { 13951 saveLocaleLocked(values.locale, 13952 !values.locale.equals(mConfiguration.locale), 13953 values.userSetLocale); 13954 } 13955 13956 mConfigurationSeq++; 13957 if (mConfigurationSeq <= 0) { 13958 mConfigurationSeq = 1; 13959 } 13960 newConfig.seq = mConfigurationSeq; 13961 mConfiguration = newConfig; 13962 Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig); 13963 13964 final Configuration configCopy = new Configuration(mConfiguration); 13965 13966 // TODO: If our config changes, should we auto dismiss any currently 13967 // showing dialogs? 13968 mShowDialogs = shouldShowDialogs(newConfig); 13969 13970 AttributeCache ac = AttributeCache.instance(); 13971 if (ac != null) { 13972 ac.updateConfiguration(configCopy); 13973 } 13974 13975 // Make sure all resources in our process are updated 13976 // right now, so that anyone who is going to retrieve 13977 // resource values after we return will be sure to get 13978 // the new ones. This is especially important during 13979 // boot, where the first config change needs to guarantee 13980 // all resources have that config before following boot 13981 // code is executed. 13982 mSystemThread.applyConfigurationToResources(configCopy); 13983 13984 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) { 13985 Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG); 13986 msg.obj = new Configuration(configCopy); 13987 mHandler.sendMessage(msg); 13988 } 13989 13990 for (int i=mLruProcesses.size()-1; i>=0; i--) { 13991 ProcessRecord app = mLruProcesses.get(i); 13992 try { 13993 if (app.thread != null) { 13994 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc " 13995 + app.processName + " new config " + mConfiguration); 13996 app.thread.scheduleConfigurationChanged(configCopy); 13997 } 13998 } catch (Exception e) { 13999 } 14000 } 14001 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED); 14002 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 14003 | Intent.FLAG_RECEIVER_REPLACE_PENDING 14004 | Intent.FLAG_RECEIVER_FOREGROUND); 14005 broadcastIntentLocked(null, null, intent, null, null, 0, null, null, 14006 null, AppOpsManager.OP_NONE, false, false, MY_PID, 14007 Process.SYSTEM_UID, UserHandle.USER_ALL); 14008 if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) { 14009 intent = new Intent(Intent.ACTION_LOCALE_CHANGED); 14010 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 14011 broadcastIntentLocked(null, null, intent, 14012 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 14013 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 14014 } 14015 } 14016 } 14017 14018 boolean kept = true; 14019 final ActivityStack mainStack = mStackSupervisor.getFocusedStack(); 14020 // mainStack is null during startup. 14021 if (mainStack != null) { 14022 if (changes != 0 && starting == null) { 14023 // If the configuration changed, and the caller is not already 14024 // in the process of starting an activity, then find the top 14025 // activity to check if its configuration needs to change. 14026 starting = mainStack.topRunningActivityLocked(null); 14027 } 14028 14029 if (starting != null) { 14030 kept = mainStack.ensureActivityConfigurationLocked(starting, changes); 14031 // And we need to make sure at this point that all other activities 14032 // are made visible with the correct configuration. 14033 mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes); 14034 } 14035 } 14036 14037 if (values != null && mWindowManager != null) { 14038 mWindowManager.setNewConfiguration(mConfiguration); 14039 } 14040 14041 return kept; 14042 } 14043 14044 /** 14045 * Decide based on the configuration whether we should shouw the ANR, 14046 * crash, etc dialogs. The idea is that if there is no affordnace to 14047 * press the on-screen buttons, we shouldn't show the dialog. 14048 * 14049 * A thought: SystemUI might also want to get told about this, the Power 14050 * dialog / global actions also might want different behaviors. 14051 */ 14052 private static final boolean shouldShowDialogs(Configuration config) { 14053 return !(config.keyboard == Configuration.KEYBOARD_NOKEYS 14054 && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH); 14055 } 14056 14057 /** 14058 * Save the locale. You must be inside a synchronized (this) block. 14059 */ 14060 private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) { 14061 if(isDiff) { 14062 SystemProperties.set("user.language", l.getLanguage()); 14063 SystemProperties.set("user.region", l.getCountry()); 14064 } 14065 14066 if(isPersist) { 14067 SystemProperties.set("persist.sys.language", l.getLanguage()); 14068 SystemProperties.set("persist.sys.country", l.getCountry()); 14069 SystemProperties.set("persist.sys.localevar", l.getVariant()); 14070 } 14071 } 14072 14073 @Override 14074 public boolean targetTaskAffinityMatchesActivity(IBinder token, String destAffinity) { 14075 ActivityRecord srec = ActivityRecord.forToken(token); 14076 return srec != null && srec.task.affinity != null && 14077 srec.task.affinity.equals(destAffinity); 14078 } 14079 14080 public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode, 14081 Intent resultData) { 14082 14083 synchronized (this) { 14084 final ActivityStack stack = ActivityRecord.getStackLocked(token); 14085 if (stack != null) { 14086 return stack.navigateUpToLocked(token, destIntent, resultCode, resultData); 14087 } 14088 return false; 14089 } 14090 } 14091 14092 public int getLaunchedFromUid(IBinder activityToken) { 14093 ActivityRecord srec = ActivityRecord.forToken(activityToken); 14094 if (srec == null) { 14095 return -1; 14096 } 14097 return srec.launchedFromUid; 14098 } 14099 14100 public String getLaunchedFromPackage(IBinder activityToken) { 14101 ActivityRecord srec = ActivityRecord.forToken(activityToken); 14102 if (srec == null) { 14103 return null; 14104 } 14105 return srec.launchedFromPackage; 14106 } 14107 14108 // ========================================================= 14109 // LIFETIME MANAGEMENT 14110 // ========================================================= 14111 14112 // Returns which broadcast queue the app is the current [or imminent] receiver 14113 // on, or 'null' if the app is not an active broadcast recipient. 14114 private BroadcastQueue isReceivingBroadcast(ProcessRecord app) { 14115 BroadcastRecord r = app.curReceiver; 14116 if (r != null) { 14117 return r.queue; 14118 } 14119 14120 // It's not the current receiver, but it might be starting up to become one 14121 synchronized (this) { 14122 for (BroadcastQueue queue : mBroadcastQueues) { 14123 r = queue.mPendingBroadcast; 14124 if (r != null && r.curApp == app) { 14125 // found it; report which queue it's in 14126 return queue; 14127 } 14128 } 14129 } 14130 14131 return null; 14132 } 14133 14134 private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP, 14135 boolean doingAll, long now) { 14136 if (mAdjSeq == app.adjSeq) { 14137 // This adjustment has already been computed. 14138 return app.curRawAdj; 14139 } 14140 14141 if (app.thread == null) { 14142 app.adjSeq = mAdjSeq; 14143 app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 14144 app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 14145 return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ); 14146 } 14147 14148 app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN; 14149 app.adjSource = null; 14150 app.adjTarget = null; 14151 app.empty = false; 14152 app.cached = false; 14153 14154 final int activitiesSize = app.activities.size(); 14155 14156 if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) { 14157 // The max adjustment doesn't allow this app to be anything 14158 // below foreground, so it is not worth doing work for it. 14159 app.adjType = "fixed"; 14160 app.adjSeq = mAdjSeq; 14161 app.curRawAdj = app.maxAdj; 14162 app.foregroundActivities = false; 14163 app.keeping = true; 14164 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT; 14165 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT; 14166 // System process can do UI, and when they do we want to have 14167 // them trim their memory after the user leaves the UI. To 14168 // facilitate this, here we need to determine whether or not it 14169 // is currently showing UI. 14170 app.systemNoUi = true; 14171 if (app == TOP_APP) { 14172 app.systemNoUi = false; 14173 } else if (activitiesSize > 0) { 14174 for (int j = 0; j < activitiesSize; j++) { 14175 final ActivityRecord r = app.activities.get(j); 14176 if (r.visible) { 14177 app.systemNoUi = false; 14178 } 14179 } 14180 } 14181 if (!app.systemNoUi) { 14182 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI; 14183 } 14184 return (app.curAdj=app.maxAdj); 14185 } 14186 14187 app.keeping = false; 14188 app.systemNoUi = false; 14189 14190 // Determine the importance of the process, starting with most 14191 // important to least, and assign an appropriate OOM adjustment. 14192 int adj; 14193 int schedGroup; 14194 int procState; 14195 boolean foregroundActivities = false; 14196 boolean interesting = false; 14197 BroadcastQueue queue; 14198 if (app == TOP_APP) { 14199 // The last app on the list is the foreground app. 14200 adj = ProcessList.FOREGROUND_APP_ADJ; 14201 schedGroup = Process.THREAD_GROUP_DEFAULT; 14202 app.adjType = "top-activity"; 14203 foregroundActivities = true; 14204 interesting = true; 14205 procState = ActivityManager.PROCESS_STATE_TOP; 14206 } else if (app.instrumentationClass != null) { 14207 // Don't want to kill running instrumentation. 14208 adj = ProcessList.FOREGROUND_APP_ADJ; 14209 schedGroup = Process.THREAD_GROUP_DEFAULT; 14210 app.adjType = "instrumentation"; 14211 interesting = true; 14212 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14213 } else if ((queue = isReceivingBroadcast(app)) != null) { 14214 // An app that is currently receiving a broadcast also 14215 // counts as being in the foreground for OOM killer purposes. 14216 // It's placed in a sched group based on the nature of the 14217 // broadcast as reflected by which queue it's active in. 14218 adj = ProcessList.FOREGROUND_APP_ADJ; 14219 schedGroup = (queue == mFgBroadcastQueue) 14220 ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 14221 app.adjType = "broadcast"; 14222 procState = ActivityManager.PROCESS_STATE_RECEIVER; 14223 } else if (app.executingServices.size() > 0) { 14224 // An app that is currently executing a service callback also 14225 // counts as being in the foreground. 14226 adj = ProcessList.FOREGROUND_APP_ADJ; 14227 schedGroup = app.execServicesFg ? 14228 Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 14229 app.adjType = "exec-service"; 14230 procState = ActivityManager.PROCESS_STATE_SERVICE; 14231 //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app); 14232 } else { 14233 // As far as we know the process is empty. We may change our mind later. 14234 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 14235 // At this point we don't actually know the adjustment. Use the cached adj 14236 // value that the caller wants us to. 14237 adj = cachedAdj; 14238 procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 14239 app.cached = true; 14240 app.empty = true; 14241 app.adjType = "cch-empty"; 14242 } 14243 14244 // Examine all activities if not already foreground. 14245 if (!foregroundActivities && activitiesSize > 0) { 14246 for (int j = 0; j < activitiesSize; j++) { 14247 final ActivityRecord r = app.activities.get(j); 14248 if (r.app != app) { 14249 Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc " 14250 + app + "?!?"); 14251 continue; 14252 } 14253 if (r.visible) { 14254 // App has a visible activity; only upgrade adjustment. 14255 if (adj > ProcessList.VISIBLE_APP_ADJ) { 14256 adj = ProcessList.VISIBLE_APP_ADJ; 14257 app.adjType = "visible"; 14258 } 14259 if (procState > ActivityManager.PROCESS_STATE_TOP) { 14260 procState = ActivityManager.PROCESS_STATE_TOP; 14261 } 14262 schedGroup = Process.THREAD_GROUP_DEFAULT; 14263 app.cached = false; 14264 app.empty = false; 14265 foregroundActivities = true; 14266 break; 14267 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) { 14268 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14269 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 14270 app.adjType = "pausing"; 14271 } 14272 if (procState > ActivityManager.PROCESS_STATE_TOP) { 14273 procState = ActivityManager.PROCESS_STATE_TOP; 14274 } 14275 schedGroup = Process.THREAD_GROUP_DEFAULT; 14276 app.cached = false; 14277 app.empty = false; 14278 foregroundActivities = true; 14279 } else if (r.state == ActivityState.STOPPING) { 14280 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14281 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 14282 app.adjType = "stopping"; 14283 } 14284 // For the process state, we will at this point consider the 14285 // process to be cached. It will be cached either as an activity 14286 // or empty depending on whether the activity is finishing. We do 14287 // this so that we can treat the process as cached for purposes of 14288 // memory trimming (determing current memory level, trim command to 14289 // send to process) since there can be an arbitrary number of stopping 14290 // processes and they should soon all go into the cached state. 14291 if (!r.finishing) { 14292 if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 14293 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 14294 } 14295 } 14296 app.cached = false; 14297 app.empty = false; 14298 foregroundActivities = true; 14299 } else { 14300 if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 14301 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 14302 app.adjType = "cch-act"; 14303 } 14304 } 14305 } 14306 } 14307 14308 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14309 if (app.foregroundServices) { 14310 // The user is aware of this app, so make it visible. 14311 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 14312 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14313 app.cached = false; 14314 app.adjType = "fg-service"; 14315 schedGroup = Process.THREAD_GROUP_DEFAULT; 14316 } else if (app.forcingToForeground != null) { 14317 // The user is aware of this app, so make it visible. 14318 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 14319 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14320 app.cached = false; 14321 app.adjType = "force-fg"; 14322 app.adjSource = app.forcingToForeground; 14323 schedGroup = Process.THREAD_GROUP_DEFAULT; 14324 } 14325 } 14326 14327 if (app.foregroundServices) { 14328 interesting = true; 14329 } 14330 14331 if (app == mHeavyWeightProcess) { 14332 if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) { 14333 // We don't want to kill the current heavy-weight process. 14334 adj = ProcessList.HEAVY_WEIGHT_APP_ADJ; 14335 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 14336 app.cached = false; 14337 app.adjType = "heavy"; 14338 } 14339 if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) { 14340 procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT; 14341 } 14342 } 14343 14344 if (app == mHomeProcess) { 14345 if (adj > ProcessList.HOME_APP_ADJ) { 14346 // This process is hosting what we currently consider to be the 14347 // home app, so we don't want to let it go into the background. 14348 adj = ProcessList.HOME_APP_ADJ; 14349 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 14350 app.cached = false; 14351 app.adjType = "home"; 14352 } 14353 if (procState > ActivityManager.PROCESS_STATE_HOME) { 14354 procState = ActivityManager.PROCESS_STATE_HOME; 14355 } 14356 } 14357 14358 if (app == mPreviousProcess && app.activities.size() > 0) { 14359 if (adj > ProcessList.PREVIOUS_APP_ADJ) { 14360 // This was the previous process that showed UI to the user. 14361 // We want to try to keep it around more aggressively, to give 14362 // a good experience around switching between two apps. 14363 adj = ProcessList.PREVIOUS_APP_ADJ; 14364 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 14365 app.cached = false; 14366 app.adjType = "previous"; 14367 } 14368 if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) { 14369 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY; 14370 } 14371 } 14372 14373 if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj 14374 + " reason=" + app.adjType); 14375 14376 // By default, we use the computed adjustment. It may be changed if 14377 // there are applications dependent on our services or providers, but 14378 // this gives us a baseline and makes sure we don't get into an 14379 // infinite recursion. 14380 app.adjSeq = mAdjSeq; 14381 app.curRawAdj = adj; 14382 app.hasStartedServices = false; 14383 14384 if (mBackupTarget != null && app == mBackupTarget.app) { 14385 // If possible we want to avoid killing apps while they're being backed up 14386 if (adj > ProcessList.BACKUP_APP_ADJ) { 14387 if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app); 14388 adj = ProcessList.BACKUP_APP_ADJ; 14389 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) { 14390 procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND; 14391 } 14392 app.adjType = "backup"; 14393 app.cached = false; 14394 } 14395 if (procState > ActivityManager.PROCESS_STATE_BACKUP) { 14396 procState = ActivityManager.PROCESS_STATE_BACKUP; 14397 } 14398 } 14399 14400 boolean mayBeTop = false; 14401 14402 for (int is = app.services.size()-1; 14403 is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 14404 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 14405 || procState > ActivityManager.PROCESS_STATE_TOP); 14406 is--) { 14407 ServiceRecord s = app.services.valueAt(is); 14408 if (s.startRequested) { 14409 app.hasStartedServices = true; 14410 if (procState > ActivityManager.PROCESS_STATE_SERVICE) { 14411 procState = ActivityManager.PROCESS_STATE_SERVICE; 14412 } 14413 if (app.hasShownUi && app != mHomeProcess) { 14414 // If this process has shown some UI, let it immediately 14415 // go to the LRU list because it may be pretty heavy with 14416 // UI stuff. We'll tag it with a label just to help 14417 // debug and understand what is going on. 14418 if (adj > ProcessList.SERVICE_ADJ) { 14419 app.adjType = "cch-started-ui-services"; 14420 } 14421 } else { 14422 if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) { 14423 // This service has seen some activity within 14424 // recent memory, so we will keep its process ahead 14425 // of the background processes. 14426 if (adj > ProcessList.SERVICE_ADJ) { 14427 adj = ProcessList.SERVICE_ADJ; 14428 app.adjType = "started-services"; 14429 app.cached = false; 14430 } 14431 } 14432 // If we have let the service slide into the background 14433 // state, still have some text describing what it is doing 14434 // even though the service no longer has an impact. 14435 if (adj > ProcessList.SERVICE_ADJ) { 14436 app.adjType = "cch-started-services"; 14437 } 14438 } 14439 // Don't kill this process because it is doing work; it 14440 // has said it is doing work. 14441 app.keeping = true; 14442 } 14443 for (int conni = s.connections.size()-1; 14444 conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 14445 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 14446 || procState > ActivityManager.PROCESS_STATE_TOP); 14447 conni--) { 14448 ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni); 14449 for (int i = 0; 14450 i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ 14451 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 14452 || procState > ActivityManager.PROCESS_STATE_TOP); 14453 i++) { 14454 // XXX should compute this based on the max of 14455 // all connected clients. 14456 ConnectionRecord cr = clist.get(i); 14457 if (cr.binding.client == app) { 14458 // Binding to ourself is not interesting. 14459 continue; 14460 } 14461 if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) { 14462 ProcessRecord client = cr.binding.client; 14463 int clientAdj = computeOomAdjLocked(client, cachedAdj, 14464 TOP_APP, doingAll, now); 14465 int clientProcState = client.curProcState; 14466 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 14467 // If the other app is cached for any reason, for purposes here 14468 // we are going to consider it empty. The specific cached state 14469 // doesn't propagate except under certain conditions. 14470 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 14471 } 14472 String adjType = null; 14473 if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) { 14474 // Not doing bind OOM management, so treat 14475 // this guy more like a started service. 14476 if (app.hasShownUi && app != mHomeProcess) { 14477 // If this process has shown some UI, let it immediately 14478 // go to the LRU list because it may be pretty heavy with 14479 // UI stuff. We'll tag it with a label just to help 14480 // debug and understand what is going on. 14481 if (adj > clientAdj) { 14482 adjType = "cch-bound-ui-services"; 14483 } 14484 app.cached = false; 14485 clientAdj = adj; 14486 clientProcState = procState; 14487 } else { 14488 if (now >= (s.lastActivity 14489 + ActiveServices.MAX_SERVICE_INACTIVITY)) { 14490 // This service has not seen activity within 14491 // recent memory, so allow it to drop to the 14492 // LRU list if there is no other reason to keep 14493 // it around. We'll also tag it with a label just 14494 // to help debug and undertand what is going on. 14495 if (adj > clientAdj) { 14496 adjType = "cch-bound-services"; 14497 } 14498 clientAdj = adj; 14499 } 14500 } 14501 } 14502 if (adj > clientAdj) { 14503 // If this process has recently shown UI, and 14504 // the process that is binding to it is less 14505 // important than being visible, then we don't 14506 // care about the binding as much as we care 14507 // about letting this process get into the LRU 14508 // list to be killed and restarted if needed for 14509 // memory. 14510 if (app.hasShownUi && app != mHomeProcess 14511 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14512 adjType = "cch-bound-ui-services"; 14513 } else { 14514 if ((cr.flags&(Context.BIND_ABOVE_CLIENT 14515 |Context.BIND_IMPORTANT)) != 0) { 14516 adj = clientAdj; 14517 } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0 14518 && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ 14519 && adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14520 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 14521 } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) { 14522 adj = clientAdj; 14523 } else { 14524 if (adj > ProcessList.VISIBLE_APP_ADJ) { 14525 adj = ProcessList.VISIBLE_APP_ADJ; 14526 } 14527 } 14528 if (!client.cached) { 14529 app.cached = false; 14530 } 14531 if (client.keeping) { 14532 app.keeping = true; 14533 } 14534 adjType = "service"; 14535 } 14536 } 14537 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 14538 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 14539 schedGroup = Process.THREAD_GROUP_DEFAULT; 14540 } 14541 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) { 14542 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) { 14543 // Special handling of clients who are in the top state. 14544 // We *may* want to consider this process to be in the 14545 // top state as well, but only if there is not another 14546 // reason for it to be running. Being on the top is a 14547 // special state, meaning you are specifically running 14548 // for the current top app. If the process is already 14549 // running in the background for some other reason, it 14550 // is more important to continue considering it to be 14551 // in the background state. 14552 mayBeTop = true; 14553 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 14554 } else { 14555 // Special handling for above-top states (persistent 14556 // processes). These should not bring the current process 14557 // into the top state, since they are not on top. Instead 14558 // give them the best state after that. 14559 clientProcState = 14560 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14561 } 14562 } 14563 } else { 14564 if (clientProcState < 14565 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) { 14566 clientProcState = 14567 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND; 14568 } 14569 } 14570 if (procState > clientProcState) { 14571 procState = clientProcState; 14572 } 14573 if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 14574 && (cr.flags&Context.BIND_SHOWING_UI) != 0) { 14575 app.pendingUiClean = true; 14576 } 14577 if (adjType != null) { 14578 app.adjType = adjType; 14579 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 14580 .REASON_SERVICE_IN_USE; 14581 app.adjSource = cr.binding.client; 14582 app.adjSourceOom = clientAdj; 14583 app.adjTarget = s.name; 14584 } 14585 } 14586 final ActivityRecord a = cr.activity; 14587 if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) { 14588 if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ && 14589 (a.visible || a.state == ActivityState.RESUMED 14590 || a.state == ActivityState.PAUSING)) { 14591 adj = ProcessList.FOREGROUND_APP_ADJ; 14592 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 14593 schedGroup = Process.THREAD_GROUP_DEFAULT; 14594 } 14595 app.cached = false; 14596 app.adjType = "service"; 14597 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 14598 .REASON_SERVICE_IN_USE; 14599 app.adjSource = a; 14600 app.adjSourceOom = adj; 14601 app.adjTarget = s.name; 14602 } 14603 } 14604 } 14605 } 14606 } 14607 14608 for (int provi = app.pubProviders.size()-1; 14609 provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 14610 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 14611 || procState > ActivityManager.PROCESS_STATE_TOP); 14612 provi--) { 14613 ContentProviderRecord cpr = app.pubProviders.valueAt(provi); 14614 for (int i = cpr.connections.size()-1; 14615 i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 14616 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 14617 || procState > ActivityManager.PROCESS_STATE_TOP); 14618 i--) { 14619 ContentProviderConnection conn = cpr.connections.get(i); 14620 ProcessRecord client = conn.client; 14621 if (client == app) { 14622 // Being our own client is not interesting. 14623 continue; 14624 } 14625 int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now); 14626 int clientProcState = client.curProcState; 14627 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 14628 // If the other app is cached for any reason, for purposes here 14629 // we are going to consider it empty. 14630 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 14631 } 14632 if (adj > clientAdj) { 14633 if (app.hasShownUi && app != mHomeProcess 14634 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14635 app.adjType = "cch-ui-provider"; 14636 } else { 14637 adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ 14638 ? clientAdj : ProcessList.FOREGROUND_APP_ADJ; 14639 app.adjType = "provider"; 14640 } 14641 app.cached &= client.cached; 14642 app.keeping |= client.keeping; 14643 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 14644 .REASON_PROVIDER_IN_USE; 14645 app.adjSource = client; 14646 app.adjSourceOom = clientAdj; 14647 app.adjTarget = cpr.name; 14648 } 14649 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) { 14650 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) { 14651 // Special handling of clients who are in the top state. 14652 // We *may* want to consider this process to be in the 14653 // top state as well, but only if there is not another 14654 // reason for it to be running. Being on the top is a 14655 // special state, meaning you are specifically running 14656 // for the current top app. If the process is already 14657 // running in the background for some other reason, it 14658 // is more important to continue considering it to be 14659 // in the background state. 14660 mayBeTop = true; 14661 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 14662 } else { 14663 // Special handling for above-top states (persistent 14664 // processes). These should not bring the current process 14665 // into the top state, since they are not on top. Instead 14666 // give them the best state after that. 14667 clientProcState = 14668 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14669 } 14670 } 14671 if (procState > clientProcState) { 14672 procState = clientProcState; 14673 } 14674 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 14675 schedGroup = Process.THREAD_GROUP_DEFAULT; 14676 } 14677 } 14678 // If the provider has external (non-framework) process 14679 // dependencies, ensure that its adjustment is at least 14680 // FOREGROUND_APP_ADJ. 14681 if (cpr.hasExternalProcessHandles()) { 14682 if (adj > ProcessList.FOREGROUND_APP_ADJ) { 14683 adj = ProcessList.FOREGROUND_APP_ADJ; 14684 schedGroup = Process.THREAD_GROUP_DEFAULT; 14685 app.cached = false; 14686 app.keeping = true; 14687 app.adjType = "provider"; 14688 app.adjTarget = cpr.name; 14689 } 14690 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) { 14691 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14692 } 14693 } 14694 } 14695 14696 if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) { 14697 // A client of one of our services or providers is in the top state. We 14698 // *may* want to be in the top state, but not if we are already running in 14699 // the background for some other reason. For the decision here, we are going 14700 // to pick out a few specific states that we want to remain in when a client 14701 // is top (states that tend to be longer-term) and otherwise allow it to go 14702 // to the top state. 14703 switch (procState) { 14704 case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND: 14705 case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND: 14706 case ActivityManager.PROCESS_STATE_SERVICE: 14707 // These all are longer-term states, so pull them up to the top 14708 // of the background states, but not all the way to the top state. 14709 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14710 break; 14711 default: 14712 // Otherwise, top is a better choice, so take it. 14713 procState = ActivityManager.PROCESS_STATE_TOP; 14714 break; 14715 } 14716 } 14717 14718 if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY && app.hasClientActivities) { 14719 // This is a cached process, but with client activities. Mark it so. 14720 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT; 14721 app.adjType = "cch-client-act"; 14722 } 14723 14724 if (adj == ProcessList.SERVICE_ADJ) { 14725 if (doingAll) { 14726 app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3); 14727 mNewNumServiceProcs++; 14728 //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb); 14729 if (!app.serviceb) { 14730 // This service isn't far enough down on the LRU list to 14731 // normally be a B service, but if we are low on RAM and it 14732 // is large we want to force it down since we would prefer to 14733 // keep launcher over it. 14734 if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL 14735 && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) { 14736 app.serviceHighRam = true; 14737 app.serviceb = true; 14738 //Slog.i(TAG, "ADJ " + app + " high ram!"); 14739 } else { 14740 mNewNumAServiceProcs++; 14741 //Slog.i(TAG, "ADJ " + app + " not high ram!"); 14742 } 14743 } else { 14744 app.serviceHighRam = false; 14745 } 14746 } 14747 if (app.serviceb) { 14748 adj = ProcessList.SERVICE_B_ADJ; 14749 } 14750 } 14751 14752 app.curRawAdj = adj; 14753 14754 //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid + 14755 // " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj); 14756 if (adj > app.maxAdj) { 14757 adj = app.maxAdj; 14758 if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 14759 schedGroup = Process.THREAD_GROUP_DEFAULT; 14760 } 14761 } 14762 if (adj < ProcessList.CACHED_APP_MIN_ADJ) { 14763 app.keeping = true; 14764 } 14765 14766 // Do final modification to adj. Everything we do between here and applying 14767 // the final setAdj must be done in this function, because we will also use 14768 // it when computing the final cached adj later. Note that we don't need to 14769 // worry about this for max adj above, since max adj will always be used to 14770 // keep it out of the cached vaues. 14771 adj = app.modifyRawOomAdj(adj); 14772 14773 app.curProcState = procState; 14774 14775 int importance = app.memImportance; 14776 if (importance == 0 || adj != app.curAdj || schedGroup != app.curSchedGroup) { 14777 app.curAdj = adj; 14778 app.curSchedGroup = schedGroup; 14779 if (!interesting) { 14780 // For this reporting, if there is not something explicitly 14781 // interesting in this process then we will push it to the 14782 // background importance. 14783 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 14784 } else if (adj >= ProcessList.CACHED_APP_MIN_ADJ) { 14785 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 14786 } else if (adj >= ProcessList.SERVICE_B_ADJ) { 14787 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 14788 } else if (adj >= ProcessList.HOME_APP_ADJ) { 14789 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 14790 } else if (adj >= ProcessList.SERVICE_ADJ) { 14791 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 14792 } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 14793 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE; 14794 } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) { 14795 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE; 14796 } else if (adj >= ProcessList.VISIBLE_APP_ADJ) { 14797 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE; 14798 } else if (adj >= ProcessList.FOREGROUND_APP_ADJ) { 14799 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND; 14800 } else { 14801 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERSISTENT; 14802 } 14803 } 14804 14805 int changes = importance != app.memImportance ? ProcessChangeItem.CHANGE_IMPORTANCE : 0; 14806 if (foregroundActivities != app.foregroundActivities) { 14807 changes |= ProcessChangeItem.CHANGE_ACTIVITIES; 14808 } 14809 if (changes != 0) { 14810 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes); 14811 app.memImportance = importance; 14812 app.foregroundActivities = foregroundActivities; 14813 int i = mPendingProcessChanges.size()-1; 14814 ProcessChangeItem item = null; 14815 while (i >= 0) { 14816 item = mPendingProcessChanges.get(i); 14817 if (item.pid == app.pid) { 14818 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item); 14819 break; 14820 } 14821 i--; 14822 } 14823 if (i < 0) { 14824 // No existing item in pending changes; need a new one. 14825 final int NA = mAvailProcessChanges.size(); 14826 if (NA > 0) { 14827 item = mAvailProcessChanges.remove(NA-1); 14828 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item); 14829 } else { 14830 item = new ProcessChangeItem(); 14831 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item); 14832 } 14833 item.changes = 0; 14834 item.pid = app.pid; 14835 item.uid = app.info.uid; 14836 if (mPendingProcessChanges.size() == 0) { 14837 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, 14838 "*** Enqueueing dispatch processes changed!"); 14839 mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget(); 14840 } 14841 mPendingProcessChanges.add(item); 14842 } 14843 item.changes |= changes; 14844 item.importance = importance; 14845 item.foregroundActivities = foregroundActivities; 14846 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item " 14847 + Integer.toHexString(System.identityHashCode(item)) 14848 + " " + app.toShortString() + ": changes=" + item.changes 14849 + " importance=" + item.importance 14850 + " foreground=" + item.foregroundActivities 14851 + " type=" + app.adjType + " source=" + app.adjSource 14852 + " target=" + app.adjTarget); 14853 } 14854 14855 return app.curRawAdj; 14856 } 14857 14858 /** 14859 * Schedule PSS collection of a process. 14860 */ 14861 void requestPssLocked(ProcessRecord proc, int procState) { 14862 if (mPendingPssProcesses.contains(proc)) { 14863 return; 14864 } 14865 if (mPendingPssProcesses.size() == 0) { 14866 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG); 14867 } 14868 if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc); 14869 proc.pssProcState = procState; 14870 mPendingPssProcesses.add(proc); 14871 } 14872 14873 /** 14874 * Schedule PSS collection of all processes. 14875 */ 14876 void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) { 14877 if (!always) { 14878 if (now < (mLastFullPssTime + 14879 (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) { 14880 return; 14881 } 14882 } 14883 if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs! memLowered=" + memLowered); 14884 mLastFullPssTime = now; 14885 mPendingPssProcesses.ensureCapacity(mLruProcesses.size()); 14886 mPendingPssProcesses.clear(); 14887 for (int i=mLruProcesses.size()-1; i>=0; i--) { 14888 ProcessRecord app = mLruProcesses.get(i); 14889 if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) { 14890 app.pssProcState = app.setProcState; 14891 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true, 14892 mSleeping, now); 14893 mPendingPssProcesses.add(app); 14894 } 14895 } 14896 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG); 14897 } 14898 14899 /** 14900 * Ask a given process to GC right now. 14901 */ 14902 final void performAppGcLocked(ProcessRecord app) { 14903 try { 14904 app.lastRequestedGc = SystemClock.uptimeMillis(); 14905 if (app.thread != null) { 14906 if (app.reportLowMemory) { 14907 app.reportLowMemory = false; 14908 app.thread.scheduleLowMemory(); 14909 } else { 14910 app.thread.processInBackground(); 14911 } 14912 } 14913 } catch (Exception e) { 14914 // whatever. 14915 } 14916 } 14917 14918 /** 14919 * Returns true if things are idle enough to perform GCs. 14920 */ 14921 private final boolean canGcNowLocked() { 14922 boolean processingBroadcasts = false; 14923 for (BroadcastQueue q : mBroadcastQueues) { 14924 if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) { 14925 processingBroadcasts = true; 14926 } 14927 } 14928 return !processingBroadcasts 14929 && (mSleeping || mStackSupervisor.allResumedActivitiesIdle()); 14930 } 14931 14932 /** 14933 * Perform GCs on all processes that are waiting for it, but only 14934 * if things are idle. 14935 */ 14936 final void performAppGcsLocked() { 14937 final int N = mProcessesToGc.size(); 14938 if (N <= 0) { 14939 return; 14940 } 14941 if (canGcNowLocked()) { 14942 while (mProcessesToGc.size() > 0) { 14943 ProcessRecord proc = mProcessesToGc.remove(0); 14944 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) { 14945 if ((proc.lastRequestedGc+GC_MIN_INTERVAL) 14946 <= SystemClock.uptimeMillis()) { 14947 // To avoid spamming the system, we will GC processes one 14948 // at a time, waiting a few seconds between each. 14949 performAppGcLocked(proc); 14950 scheduleAppGcsLocked(); 14951 return; 14952 } else { 14953 // It hasn't been long enough since we last GCed this 14954 // process... put it in the list to wait for its time. 14955 addProcessToGcListLocked(proc); 14956 break; 14957 } 14958 } 14959 } 14960 14961 scheduleAppGcsLocked(); 14962 } 14963 } 14964 14965 /** 14966 * If all looks good, perform GCs on all processes waiting for them. 14967 */ 14968 final void performAppGcsIfAppropriateLocked() { 14969 if (canGcNowLocked()) { 14970 performAppGcsLocked(); 14971 return; 14972 } 14973 // Still not idle, wait some more. 14974 scheduleAppGcsLocked(); 14975 } 14976 14977 /** 14978 * Schedule the execution of all pending app GCs. 14979 */ 14980 final void scheduleAppGcsLocked() { 14981 mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG); 14982 14983 if (mProcessesToGc.size() > 0) { 14984 // Schedule a GC for the time to the next process. 14985 ProcessRecord proc = mProcessesToGc.get(0); 14986 Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG); 14987 14988 long when = proc.lastRequestedGc + GC_MIN_INTERVAL; 14989 long now = SystemClock.uptimeMillis(); 14990 if (when < (now+GC_TIMEOUT)) { 14991 when = now + GC_TIMEOUT; 14992 } 14993 mHandler.sendMessageAtTime(msg, when); 14994 } 14995 } 14996 14997 /** 14998 * Add a process to the array of processes waiting to be GCed. Keeps the 14999 * list in sorted order by the last GC time. The process can't already be 15000 * on the list. 15001 */ 15002 final void addProcessToGcListLocked(ProcessRecord proc) { 15003 boolean added = false; 15004 for (int i=mProcessesToGc.size()-1; i>=0; i--) { 15005 if (mProcessesToGc.get(i).lastRequestedGc < 15006 proc.lastRequestedGc) { 15007 added = true; 15008 mProcessesToGc.add(i+1, proc); 15009 break; 15010 } 15011 } 15012 if (!added) { 15013 mProcessesToGc.add(0, proc); 15014 } 15015 } 15016 15017 /** 15018 * Set up to ask a process to GC itself. This will either do it 15019 * immediately, or put it on the list of processes to gc the next 15020 * time things are idle. 15021 */ 15022 final void scheduleAppGcLocked(ProcessRecord app) { 15023 long now = SystemClock.uptimeMillis(); 15024 if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) { 15025 return; 15026 } 15027 if (!mProcessesToGc.contains(app)) { 15028 addProcessToGcListLocked(app); 15029 scheduleAppGcsLocked(); 15030 } 15031 } 15032 15033 final void checkExcessivePowerUsageLocked(boolean doKills) { 15034 updateCpuStatsNow(); 15035 15036 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 15037 boolean doWakeKills = doKills; 15038 boolean doCpuKills = doKills; 15039 if (mLastPowerCheckRealtime == 0) { 15040 doWakeKills = false; 15041 } 15042 if (mLastPowerCheckUptime == 0) { 15043 doCpuKills = false; 15044 } 15045 if (stats.isScreenOn()) { 15046 doWakeKills = false; 15047 } 15048 final long curRealtime = SystemClock.elapsedRealtime(); 15049 final long realtimeSince = curRealtime - mLastPowerCheckRealtime; 15050 final long curUptime = SystemClock.uptimeMillis(); 15051 final long uptimeSince = curUptime - mLastPowerCheckUptime; 15052 mLastPowerCheckRealtime = curRealtime; 15053 mLastPowerCheckUptime = curUptime; 15054 if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) { 15055 doWakeKills = false; 15056 } 15057 if (uptimeSince < CPU_MIN_CHECK_DURATION) { 15058 doCpuKills = false; 15059 } 15060 int i = mLruProcesses.size(); 15061 while (i > 0) { 15062 i--; 15063 ProcessRecord app = mLruProcesses.get(i); 15064 if (!app.keeping) { 15065 long wtime; 15066 synchronized (stats) { 15067 wtime = stats.getProcessWakeTime(app.info.uid, 15068 app.pid, curRealtime); 15069 } 15070 long wtimeUsed = wtime - app.lastWakeTime; 15071 long cputimeUsed = app.curCpuTime - app.lastCpuTime; 15072 if (DEBUG_POWER) { 15073 StringBuilder sb = new StringBuilder(128); 15074 sb.append("Wake for "); 15075 app.toShortString(sb); 15076 sb.append(": over "); 15077 TimeUtils.formatDuration(realtimeSince, sb); 15078 sb.append(" used "); 15079 TimeUtils.formatDuration(wtimeUsed, sb); 15080 sb.append(" ("); 15081 sb.append((wtimeUsed*100)/realtimeSince); 15082 sb.append("%)"); 15083 Slog.i(TAG, sb.toString()); 15084 sb.setLength(0); 15085 sb.append("CPU for "); 15086 app.toShortString(sb); 15087 sb.append(": over "); 15088 TimeUtils.formatDuration(uptimeSince, sb); 15089 sb.append(" used "); 15090 TimeUtils.formatDuration(cputimeUsed, sb); 15091 sb.append(" ("); 15092 sb.append((cputimeUsed*100)/uptimeSince); 15093 sb.append("%)"); 15094 Slog.i(TAG, sb.toString()); 15095 } 15096 // If a process has held a wake lock for more 15097 // than 50% of the time during this period, 15098 // that sounds bad. Kill! 15099 if (doWakeKills && realtimeSince > 0 15100 && ((wtimeUsed*100)/realtimeSince) >= 50) { 15101 synchronized (stats) { 15102 stats.reportExcessiveWakeLocked(app.info.uid, app.processName, 15103 realtimeSince, wtimeUsed); 15104 } 15105 killUnneededProcessLocked(app, "excessive wake held " + wtimeUsed 15106 + " during " + realtimeSince); 15107 app.baseProcessTracker.reportExcessiveWake(app.pkgList); 15108 } else if (doCpuKills && uptimeSince > 0 15109 && ((cputimeUsed*100)/uptimeSince) >= 50) { 15110 synchronized (stats) { 15111 stats.reportExcessiveCpuLocked(app.info.uid, app.processName, 15112 uptimeSince, cputimeUsed); 15113 } 15114 killUnneededProcessLocked(app, "excessive cpu " + cputimeUsed 15115 + " during " + uptimeSince); 15116 app.baseProcessTracker.reportExcessiveCpu(app.pkgList); 15117 } else { 15118 app.lastWakeTime = wtime; 15119 app.lastCpuTime = app.curCpuTime; 15120 } 15121 } 15122 } 15123 } 15124 15125 private final boolean applyOomAdjLocked(ProcessRecord app, boolean wasKeeping, 15126 ProcessRecord TOP_APP, boolean doingAll, boolean reportingProcessState, long now) { 15127 boolean success = true; 15128 15129 if (app.curRawAdj != app.setRawAdj) { 15130 if (wasKeeping && !app.keeping) { 15131 // This app is no longer something we want to keep. Note 15132 // its current wake lock time to later know to kill it if 15133 // it is not behaving well. 15134 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 15135 synchronized (stats) { 15136 app.lastWakeTime = stats.getProcessWakeTime(app.info.uid, 15137 app.pid, SystemClock.elapsedRealtime()); 15138 } 15139 app.lastCpuTime = app.curCpuTime; 15140 } 15141 15142 app.setRawAdj = app.curRawAdj; 15143 } 15144 15145 if (app.curAdj != app.setAdj) { 15146 ProcessList.setOomAdj(app.pid, app.curAdj); 15147 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v( 15148 TAG, "Set " + app.pid + " " + app.processName + 15149 " adj " + app.curAdj + ": " + app.adjType); 15150 app.setAdj = app.curAdj; 15151 } 15152 15153 if (app.setSchedGroup != app.curSchedGroup) { 15154 app.setSchedGroup = app.curSchedGroup; 15155 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 15156 "Setting process group of " + app.processName 15157 + " to " + app.curSchedGroup); 15158 if (app.waitingToKill != null && 15159 app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 15160 killUnneededProcessLocked(app, app.waitingToKill); 15161 success = false; 15162 } else { 15163 if (true) { 15164 long oldId = Binder.clearCallingIdentity(); 15165 try { 15166 Process.setProcessGroup(app.pid, app.curSchedGroup); 15167 } catch (Exception e) { 15168 Slog.w(TAG, "Failed setting process group of " + app.pid 15169 + " to " + app.curSchedGroup); 15170 e.printStackTrace(); 15171 } finally { 15172 Binder.restoreCallingIdentity(oldId); 15173 } 15174 } else { 15175 if (app.thread != null) { 15176 try { 15177 app.thread.setSchedulingGroup(app.curSchedGroup); 15178 } catch (RemoteException e) { 15179 } 15180 } 15181 } 15182 Process.setSwappiness(app.pid, 15183 app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE); 15184 } 15185 } 15186 if (app.repProcState != app.curProcState) { 15187 app.repProcState = app.curProcState; 15188 if (!reportingProcessState && app.thread != null) { 15189 try { 15190 if (false) { 15191 //RuntimeException h = new RuntimeException("here"); 15192 Slog.i(TAG, "Sending new process state " + app.repProcState 15193 + " to " + app /*, h*/); 15194 } 15195 app.thread.setProcessState(app.repProcState); 15196 } catch (RemoteException e) { 15197 } 15198 } 15199 } 15200 if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState, 15201 app.setProcState)) { 15202 app.lastStateTime = now; 15203 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true, 15204 mSleeping, now); 15205 if (DEBUG_PSS) Slog.d(TAG, "Process state change from " 15206 + ProcessList.makeProcStateString(app.setProcState) + " to " 15207 + ProcessList.makeProcStateString(app.curProcState) + " next pss in " 15208 + (app.nextPssTime-now) + ": " + app); 15209 } else { 15210 if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL) 15211 && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) { 15212 requestPssLocked(app, app.setProcState); 15213 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false, 15214 mSleeping, now); 15215 } else if (false && DEBUG_PSS) { 15216 Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now)); 15217 } 15218 } 15219 if (app.setProcState != app.curProcState) { 15220 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 15221 "Proc state change of " + app.processName 15222 + " to " + app.curProcState); 15223 app.setProcState = app.curProcState; 15224 if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) { 15225 app.notCachedSinceIdle = false; 15226 } 15227 if (!doingAll) { 15228 setProcessTrackerState(app, mProcessStats.getMemFactorLocked(), now); 15229 } else { 15230 app.procStateChanged = true; 15231 } 15232 } 15233 return success; 15234 } 15235 15236 private final void setProcessTrackerState(ProcessRecord proc, int memFactor, long now) { 15237 if (proc.thread != null && proc.baseProcessTracker != null) { 15238 proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList); 15239 } 15240 } 15241 15242 private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj, 15243 ProcessRecord TOP_APP, boolean doingAll, boolean reportingProcessState, long now) { 15244 if (app.thread == null) { 15245 return false; 15246 } 15247 15248 final boolean wasKeeping = app.keeping; 15249 15250 computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now); 15251 15252 return applyOomAdjLocked(app, wasKeeping, TOP_APP, doingAll, 15253 reportingProcessState, now); 15254 } 15255 15256 private final ActivityRecord resumedAppLocked() { 15257 return mStackSupervisor.resumedAppLocked(); 15258 } 15259 15260 final boolean updateOomAdjLocked(ProcessRecord app) { 15261 return updateOomAdjLocked(app, false); 15262 } 15263 15264 final boolean updateOomAdjLocked(ProcessRecord app, boolean doingProcessState) { 15265 final ActivityRecord TOP_ACT = resumedAppLocked(); 15266 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 15267 final boolean wasCached = app.cached; 15268 15269 mAdjSeq++; 15270 15271 // This is the desired cached adjusment we want to tell it to use. 15272 // If our app is currently cached, we know it, and that is it. Otherwise, 15273 // we don't know it yet, and it needs to now be cached we will then 15274 // need to do a complete oom adj. 15275 final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ 15276 ? app.curRawAdj : ProcessList.UNKNOWN_ADJ; 15277 boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false, doingProcessState, 15278 SystemClock.uptimeMillis()); 15279 if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) { 15280 // Changed to/from cached state, so apps after it in the LRU 15281 // list may also be changed. 15282 updateOomAdjLocked(); 15283 } 15284 return success; 15285 } 15286 15287 final void updateOomAdjLocked() { 15288 final ActivityRecord TOP_ACT = resumedAppLocked(); 15289 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 15290 final long now = SystemClock.uptimeMillis(); 15291 final long oldTime = now - ProcessList.MAX_EMPTY_TIME; 15292 final int N = mLruProcesses.size(); 15293 15294 if (false) { 15295 RuntimeException e = new RuntimeException(); 15296 e.fillInStackTrace(); 15297 Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e); 15298 } 15299 15300 mAdjSeq++; 15301 mNewNumServiceProcs = 0; 15302 mNewNumAServiceProcs = 0; 15303 15304 final int emptyProcessLimit; 15305 final int cachedProcessLimit; 15306 if (mProcessLimit <= 0) { 15307 emptyProcessLimit = cachedProcessLimit = 0; 15308 } else if (mProcessLimit == 1) { 15309 emptyProcessLimit = 1; 15310 cachedProcessLimit = 0; 15311 } else { 15312 emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit); 15313 cachedProcessLimit = mProcessLimit - emptyProcessLimit; 15314 } 15315 15316 // Let's determine how many processes we have running vs. 15317 // how many slots we have for background processes; we may want 15318 // to put multiple processes in a slot of there are enough of 15319 // them. 15320 int numSlots = (ProcessList.CACHED_APP_MAX_ADJ 15321 - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2; 15322 int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs; 15323 if (numEmptyProcs > cachedProcessLimit) { 15324 // If there are more empty processes than our limit on cached 15325 // processes, then use the cached process limit for the factor. 15326 // This ensures that the really old empty processes get pushed 15327 // down to the bottom, so if we are running low on memory we will 15328 // have a better chance at keeping around more cached processes 15329 // instead of a gazillion empty processes. 15330 numEmptyProcs = cachedProcessLimit; 15331 } 15332 int emptyFactor = numEmptyProcs/numSlots; 15333 if (emptyFactor < 1) emptyFactor = 1; 15334 int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots; 15335 if (cachedFactor < 1) cachedFactor = 1; 15336 int stepCached = 0; 15337 int stepEmpty = 0; 15338 int numCached = 0; 15339 int numEmpty = 0; 15340 int numTrimming = 0; 15341 15342 mNumNonCachedProcs = 0; 15343 mNumCachedHiddenProcs = 0; 15344 15345 // First update the OOM adjustment for each of the 15346 // application processes based on their current state. 15347 int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ; 15348 int nextCachedAdj = curCachedAdj+1; 15349 int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ; 15350 int nextEmptyAdj = curEmptyAdj+2; 15351 for (int i=N-1; i>=0; i--) { 15352 ProcessRecord app = mLruProcesses.get(i); 15353 if (!app.killedByAm && app.thread != null) { 15354 app.procStateChanged = false; 15355 final boolean wasKeeping = app.keeping; 15356 computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now); 15357 15358 // If we haven't yet assigned the final cached adj 15359 // to the process, do that now. 15360 if (app.curAdj >= ProcessList.UNKNOWN_ADJ) { 15361 switch (app.curProcState) { 15362 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY: 15363 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: 15364 // This process is a cached process holding activities... 15365 // assign it the next cached value for that type, and then 15366 // step that cached level. 15367 app.curRawAdj = curCachedAdj; 15368 app.curAdj = app.modifyRawOomAdj(curCachedAdj); 15369 if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i 15370 + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj 15371 + ")"); 15372 if (curCachedAdj != nextCachedAdj) { 15373 stepCached++; 15374 if (stepCached >= cachedFactor) { 15375 stepCached = 0; 15376 curCachedAdj = nextCachedAdj; 15377 nextCachedAdj += 2; 15378 if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) { 15379 nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ; 15380 } 15381 } 15382 } 15383 break; 15384 default: 15385 // For everything else, assign next empty cached process 15386 // level and bump that up. Note that this means that 15387 // long-running services that have dropped down to the 15388 // cached level will be treated as empty (since their process 15389 // state is still as a service), which is what we want. 15390 app.curRawAdj = curEmptyAdj; 15391 app.curAdj = app.modifyRawOomAdj(curEmptyAdj); 15392 if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i 15393 + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj 15394 + ")"); 15395 if (curEmptyAdj != nextEmptyAdj) { 15396 stepEmpty++; 15397 if (stepEmpty >= emptyFactor) { 15398 stepEmpty = 0; 15399 curEmptyAdj = nextEmptyAdj; 15400 nextEmptyAdj += 2; 15401 if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) { 15402 nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ; 15403 } 15404 } 15405 } 15406 break; 15407 } 15408 } 15409 15410 applyOomAdjLocked(app, wasKeeping, TOP_APP, true, false, now); 15411 15412 // Count the number of process types. 15413 switch (app.curProcState) { 15414 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY: 15415 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: 15416 mNumCachedHiddenProcs++; 15417 numCached++; 15418 if (numCached > cachedProcessLimit) { 15419 killUnneededProcessLocked(app, "cached #" + numCached); 15420 } 15421 break; 15422 case ActivityManager.PROCESS_STATE_CACHED_EMPTY: 15423 if (numEmpty > ProcessList.TRIM_EMPTY_APPS 15424 && app.lastActivityTime < oldTime) { 15425 killUnneededProcessLocked(app, "empty for " 15426 + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime) 15427 / 1000) + "s"); 15428 } else { 15429 numEmpty++; 15430 if (numEmpty > emptyProcessLimit) { 15431 killUnneededProcessLocked(app, "empty #" + numEmpty); 15432 } 15433 } 15434 break; 15435 default: 15436 mNumNonCachedProcs++; 15437 break; 15438 } 15439 15440 if (app.isolated && app.services.size() <= 0) { 15441 // If this is an isolated process, and there are no 15442 // services running in it, then the process is no longer 15443 // needed. We agressively kill these because we can by 15444 // definition not re-use the same process again, and it is 15445 // good to avoid having whatever code was running in them 15446 // left sitting around after no longer needed. 15447 killUnneededProcessLocked(app, "isolated not needed"); 15448 } 15449 15450 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME 15451 && !app.killedByAm) { 15452 numTrimming++; 15453 } 15454 } 15455 } 15456 15457 mNumServiceProcs = mNewNumServiceProcs; 15458 15459 // Now determine the memory trimming level of background processes. 15460 // Unfortunately we need to start at the back of the list to do this 15461 // properly. We only do this if the number of background apps we 15462 // are managing to keep around is less than half the maximum we desire; 15463 // if we are keeping a good number around, we'll let them use whatever 15464 // memory they want. 15465 final int numCachedAndEmpty = numCached + numEmpty; 15466 int memFactor; 15467 if (numCached <= ProcessList.TRIM_CACHED_APPS 15468 && numEmpty <= ProcessList.TRIM_EMPTY_APPS) { 15469 if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) { 15470 memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL; 15471 } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) { 15472 memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW; 15473 } else { 15474 memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE; 15475 } 15476 } else { 15477 memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL; 15478 } 15479 // We always allow the memory level to go up (better). We only allow it to go 15480 // down if we are in a state where that is allowed, *and* the total number of processes 15481 // has gone down since last time. 15482 if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel 15483 + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size() 15484 + " last=" + mLastNumProcesses); 15485 if (memFactor > mLastMemoryLevel) { 15486 if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) { 15487 memFactor = mLastMemoryLevel; 15488 if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!"); 15489 } 15490 } 15491 mLastMemoryLevel = memFactor; 15492 mLastNumProcesses = mLruProcesses.size(); 15493 boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !mSleeping, now); 15494 final int trackerMemFactor = mProcessStats.getMemFactorLocked(); 15495 if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) { 15496 if (mLowRamStartTime == 0) { 15497 mLowRamStartTime = now; 15498 } 15499 int step = 0; 15500 int fgTrimLevel; 15501 switch (memFactor) { 15502 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL: 15503 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL; 15504 break; 15505 case ProcessStats.ADJ_MEM_FACTOR_LOW: 15506 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW; 15507 break; 15508 default: 15509 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE; 15510 break; 15511 } 15512 int factor = numTrimming/3; 15513 int minFactor = 2; 15514 if (mHomeProcess != null) minFactor++; 15515 if (mPreviousProcess != null) minFactor++; 15516 if (factor < minFactor) factor = minFactor; 15517 int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE; 15518 for (int i=N-1; i>=0; i--) { 15519 ProcessRecord app = mLruProcesses.get(i); 15520 if (allChanged || app.procStateChanged) { 15521 setProcessTrackerState(app, trackerMemFactor, now); 15522 app.procStateChanged = false; 15523 } 15524 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME 15525 && !app.killedByAm) { 15526 if (app.trimMemoryLevel < curLevel && app.thread != null) { 15527 try { 15528 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 15529 "Trimming memory of " + app.processName 15530 + " to " + curLevel); 15531 app.thread.scheduleTrimMemory(curLevel); 15532 } catch (RemoteException e) { 15533 } 15534 if (false) { 15535 // For now we won't do this; our memory trimming seems 15536 // to be good enough at this point that destroying 15537 // activities causes more harm than good. 15538 if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE 15539 && app != mHomeProcess && app != mPreviousProcess) { 15540 // Need to do this on its own message because the stack may not 15541 // be in a consistent state at this point. 15542 // For these apps we will also finish their activities 15543 // to help them free memory. 15544 mStackSupervisor.scheduleDestroyAllActivities(app, "trim"); 15545 } 15546 } 15547 } 15548 app.trimMemoryLevel = curLevel; 15549 step++; 15550 if (step >= factor) { 15551 step = 0; 15552 switch (curLevel) { 15553 case ComponentCallbacks2.TRIM_MEMORY_COMPLETE: 15554 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE; 15555 break; 15556 case ComponentCallbacks2.TRIM_MEMORY_MODERATE: 15557 curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 15558 break; 15559 } 15560 } 15561 } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) { 15562 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND 15563 && app.thread != null) { 15564 try { 15565 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 15566 "Trimming memory of heavy-weight " + app.processName 15567 + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 15568 app.thread.scheduleTrimMemory( 15569 ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 15570 } catch (RemoteException e) { 15571 } 15572 } 15573 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 15574 } else { 15575 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 15576 || app.systemNoUi) && app.pendingUiClean) { 15577 // If this application is now in the background and it 15578 // had done UI, then give it the special trim level to 15579 // have it free UI resources. 15580 final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN; 15581 if (app.trimMemoryLevel < level && app.thread != null) { 15582 try { 15583 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 15584 "Trimming memory of bg-ui " + app.processName 15585 + " to " + level); 15586 app.thread.scheduleTrimMemory(level); 15587 } catch (RemoteException e) { 15588 } 15589 } 15590 app.pendingUiClean = false; 15591 } 15592 if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) { 15593 try { 15594 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 15595 "Trimming memory of fg " + app.processName 15596 + " to " + fgTrimLevel); 15597 app.thread.scheduleTrimMemory(fgTrimLevel); 15598 } catch (RemoteException e) { 15599 } 15600 } 15601 app.trimMemoryLevel = fgTrimLevel; 15602 } 15603 } 15604 } else { 15605 if (mLowRamStartTime != 0) { 15606 mLowRamTimeSinceLastIdle += now - mLowRamStartTime; 15607 mLowRamStartTime = 0; 15608 } 15609 for (int i=N-1; i>=0; i--) { 15610 ProcessRecord app = mLruProcesses.get(i); 15611 if (allChanged || app.procStateChanged) { 15612 setProcessTrackerState(app, trackerMemFactor, now); 15613 app.procStateChanged = false; 15614 } 15615 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 15616 || app.systemNoUi) && app.pendingUiClean) { 15617 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN 15618 && app.thread != null) { 15619 try { 15620 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 15621 "Trimming memory of ui hidden " + app.processName 15622 + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 15623 app.thread.scheduleTrimMemory( 15624 ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 15625 } catch (RemoteException e) { 15626 } 15627 } 15628 app.pendingUiClean = false; 15629 } 15630 app.trimMemoryLevel = 0; 15631 } 15632 } 15633 15634 if (mAlwaysFinishActivities) { 15635 // Need to do this on its own message because the stack may not 15636 // be in a consistent state at this point. 15637 mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish"); 15638 } 15639 15640 if (allChanged) { 15641 requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered()); 15642 } 15643 15644 if (mProcessStats.shouldWriteNowLocked(now)) { 15645 mHandler.post(new Runnable() { 15646 @Override public void run() { 15647 synchronized (ActivityManagerService.this) { 15648 mProcessStats.writeStateAsyncLocked(); 15649 } 15650 } 15651 }); 15652 } 15653 15654 if (DEBUG_OOM_ADJ) { 15655 Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms"); 15656 } 15657 } 15658 15659 final void trimApplications() { 15660 synchronized (this) { 15661 int i; 15662 15663 // First remove any unused application processes whose package 15664 // has been removed. 15665 for (i=mRemovedProcesses.size()-1; i>=0; i--) { 15666 final ProcessRecord app = mRemovedProcesses.get(i); 15667 if (app.activities.size() == 0 15668 && app.curReceiver == null && app.services.size() == 0) { 15669 Slog.i( 15670 TAG, "Exiting empty application process " 15671 + app.processName + " (" 15672 + (app.thread != null ? app.thread.asBinder() : null) 15673 + ")\n"); 15674 if (app.pid > 0 && app.pid != MY_PID) { 15675 EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid, 15676 app.processName, app.setAdj, "empty"); 15677 app.killedByAm = true; 15678 Process.killProcessQuiet(app.pid); 15679 } else { 15680 try { 15681 app.thread.scheduleExit(); 15682 } catch (Exception e) { 15683 // Ignore exceptions. 15684 } 15685 } 15686 cleanUpApplicationRecordLocked(app, false, true, -1); 15687 mRemovedProcesses.remove(i); 15688 15689 if (app.persistent) { 15690 if (app.persistent) { 15691 addAppLocked(app.info, false); 15692 } 15693 } 15694 } 15695 } 15696 15697 // Now update the oom adj for all processes. 15698 updateOomAdjLocked(); 15699 } 15700 } 15701 15702 /** This method sends the specified signal to each of the persistent apps */ 15703 public void signalPersistentProcesses(int sig) throws RemoteException { 15704 if (sig != Process.SIGNAL_USR1) { 15705 throw new SecurityException("Only SIGNAL_USR1 is allowed"); 15706 } 15707 15708 synchronized (this) { 15709 if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES) 15710 != PackageManager.PERMISSION_GRANTED) { 15711 throw new SecurityException("Requires permission " 15712 + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES); 15713 } 15714 15715 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 15716 ProcessRecord r = mLruProcesses.get(i); 15717 if (r.thread != null && r.persistent) { 15718 Process.sendSignal(r.pid, sig); 15719 } 15720 } 15721 } 15722 } 15723 15724 private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) { 15725 if (proc == null || proc == mProfileProc) { 15726 proc = mProfileProc; 15727 path = mProfileFile; 15728 profileType = mProfileType; 15729 clearProfilerLocked(); 15730 } 15731 if (proc == null) { 15732 return; 15733 } 15734 try { 15735 proc.thread.profilerControl(false, path, null, profileType); 15736 } catch (RemoteException e) { 15737 throw new IllegalStateException("Process disappeared"); 15738 } 15739 } 15740 15741 private void clearProfilerLocked() { 15742 if (mProfileFd != null) { 15743 try { 15744 mProfileFd.close(); 15745 } catch (IOException e) { 15746 } 15747 } 15748 mProfileApp = null; 15749 mProfileProc = null; 15750 mProfileFile = null; 15751 mProfileType = 0; 15752 mAutoStopProfiler = false; 15753 } 15754 15755 public boolean profileControl(String process, int userId, boolean start, 15756 String path, ParcelFileDescriptor fd, int profileType) throws RemoteException { 15757 15758 try { 15759 synchronized (this) { 15760 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 15761 // its own permission. 15762 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 15763 != PackageManager.PERMISSION_GRANTED) { 15764 throw new SecurityException("Requires permission " 15765 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 15766 } 15767 15768 if (start && fd == null) { 15769 throw new IllegalArgumentException("null fd"); 15770 } 15771 15772 ProcessRecord proc = null; 15773 if (process != null) { 15774 proc = findProcessLocked(process, userId, "profileControl"); 15775 } 15776 15777 if (start && (proc == null || proc.thread == null)) { 15778 throw new IllegalArgumentException("Unknown process: " + process); 15779 } 15780 15781 if (start) { 15782 stopProfilerLocked(null, null, 0); 15783 setProfileApp(proc.info, proc.processName, path, fd, false); 15784 mProfileProc = proc; 15785 mProfileType = profileType; 15786 try { 15787 fd = fd.dup(); 15788 } catch (IOException e) { 15789 fd = null; 15790 } 15791 proc.thread.profilerControl(start, path, fd, profileType); 15792 fd = null; 15793 mProfileFd = null; 15794 } else { 15795 stopProfilerLocked(proc, path, profileType); 15796 if (fd != null) { 15797 try { 15798 fd.close(); 15799 } catch (IOException e) { 15800 } 15801 } 15802 } 15803 15804 return true; 15805 } 15806 } catch (RemoteException e) { 15807 throw new IllegalStateException("Process disappeared"); 15808 } finally { 15809 if (fd != null) { 15810 try { 15811 fd.close(); 15812 } catch (IOException e) { 15813 } 15814 } 15815 } 15816 } 15817 15818 private ProcessRecord findProcessLocked(String process, int userId, String callName) { 15819 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 15820 userId, true, true, callName, null); 15821 ProcessRecord proc = null; 15822 try { 15823 int pid = Integer.parseInt(process); 15824 synchronized (mPidsSelfLocked) { 15825 proc = mPidsSelfLocked.get(pid); 15826 } 15827 } catch (NumberFormatException e) { 15828 } 15829 15830 if (proc == null) { 15831 ArrayMap<String, SparseArray<ProcessRecord>> all 15832 = mProcessNames.getMap(); 15833 SparseArray<ProcessRecord> procs = all.get(process); 15834 if (procs != null && procs.size() > 0) { 15835 proc = procs.valueAt(0); 15836 if (userId != UserHandle.USER_ALL && proc.userId != userId) { 15837 for (int i=1; i<procs.size(); i++) { 15838 ProcessRecord thisProc = procs.valueAt(i); 15839 if (thisProc.userId == userId) { 15840 proc = thisProc; 15841 break; 15842 } 15843 } 15844 } 15845 } 15846 } 15847 15848 return proc; 15849 } 15850 15851 public boolean dumpHeap(String process, int userId, boolean managed, 15852 String path, ParcelFileDescriptor fd) throws RemoteException { 15853 15854 try { 15855 synchronized (this) { 15856 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 15857 // its own permission (same as profileControl). 15858 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 15859 != PackageManager.PERMISSION_GRANTED) { 15860 throw new SecurityException("Requires permission " 15861 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 15862 } 15863 15864 if (fd == null) { 15865 throw new IllegalArgumentException("null fd"); 15866 } 15867 15868 ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap"); 15869 if (proc == null || proc.thread == null) { 15870 throw new IllegalArgumentException("Unknown process: " + process); 15871 } 15872 15873 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 15874 if (!isDebuggable) { 15875 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 15876 throw new SecurityException("Process not debuggable: " + proc); 15877 } 15878 } 15879 15880 proc.thread.dumpHeap(managed, path, fd); 15881 fd = null; 15882 return true; 15883 } 15884 } catch (RemoteException e) { 15885 throw new IllegalStateException("Process disappeared"); 15886 } finally { 15887 if (fd != null) { 15888 try { 15889 fd.close(); 15890 } catch (IOException e) { 15891 } 15892 } 15893 } 15894 } 15895 15896 /** In this method we try to acquire our lock to make sure that we have not deadlocked */ 15897 public void monitor() { 15898 synchronized (this) { } 15899 } 15900 15901 void onCoreSettingsChange(Bundle settings) { 15902 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 15903 ProcessRecord processRecord = mLruProcesses.get(i); 15904 try { 15905 if (processRecord.thread != null) { 15906 processRecord.thread.setCoreSettings(settings); 15907 } 15908 } catch (RemoteException re) { 15909 /* ignore */ 15910 } 15911 } 15912 } 15913 15914 // Multi-user methods 15915 15916 @Override 15917 public boolean switchUser(final int userId) { 15918 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 15919 != PackageManager.PERMISSION_GRANTED) { 15920 String msg = "Permission Denial: switchUser() from pid=" 15921 + Binder.getCallingPid() 15922 + ", uid=" + Binder.getCallingUid() 15923 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 15924 Slog.w(TAG, msg); 15925 throw new SecurityException(msg); 15926 } 15927 15928 final long ident = Binder.clearCallingIdentity(); 15929 try { 15930 synchronized (this) { 15931 final int oldUserId = mCurrentUserId; 15932 if (oldUserId == userId) { 15933 return true; 15934 } 15935 15936 final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId); 15937 if (userInfo == null) { 15938 Slog.w(TAG, "No user info for user #" + userId); 15939 return false; 15940 } 15941 15942 mWindowManager.startFreezingScreen(R.anim.screen_user_exit, 15943 R.anim.screen_user_enter); 15944 15945 boolean needStart = false; 15946 15947 // If the user we are switching to is not currently started, then 15948 // we need to start it now. 15949 if (mStartedUsers.get(userId) == null) { 15950 mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false)); 15951 updateStartedUserArrayLocked(); 15952 needStart = true; 15953 } 15954 15955 mCurrentUserId = userId; 15956 final Integer userIdInt = Integer.valueOf(userId); 15957 mUserLru.remove(userIdInt); 15958 mUserLru.add(userIdInt); 15959 15960 mWindowManager.setCurrentUser(userId); 15961 15962 // Once the internal notion of the active user has switched, we lock the device 15963 // with the option to show the user switcher on the keyguard. 15964 mWindowManager.lockNow(null); 15965 15966 final UserStartedState uss = mStartedUsers.get(userId); 15967 15968 // Make sure user is in the started state. If it is currently 15969 // stopping, we need to knock that off. 15970 if (uss.mState == UserStartedState.STATE_STOPPING) { 15971 // If we are stopping, we haven't sent ACTION_SHUTDOWN, 15972 // so we can just fairly silently bring the user back from 15973 // the almost-dead. 15974 uss.mState = UserStartedState.STATE_RUNNING; 15975 updateStartedUserArrayLocked(); 15976 needStart = true; 15977 } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) { 15978 // This means ACTION_SHUTDOWN has been sent, so we will 15979 // need to treat this as a new boot of the user. 15980 uss.mState = UserStartedState.STATE_BOOTING; 15981 updateStartedUserArrayLocked(); 15982 needStart = true; 15983 } 15984 15985 mHandler.removeMessages(REPORT_USER_SWITCH_MSG); 15986 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 15987 mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG, 15988 oldUserId, userId, uss)); 15989 mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG, 15990 oldUserId, userId, uss), USER_SWITCH_TIMEOUT); 15991 if (needStart) { 15992 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 15993 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 15994 | Intent.FLAG_RECEIVER_FOREGROUND); 15995 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 15996 broadcastIntentLocked(null, null, intent, 15997 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 15998 false, false, MY_PID, Process.SYSTEM_UID, userId); 15999 } 16000 16001 if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) { 16002 if (userId != 0) { 16003 Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE); 16004 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 16005 broadcastIntentLocked(null, null, intent, null, 16006 new IIntentReceiver.Stub() { 16007 public void performReceive(Intent intent, int resultCode, 16008 String data, Bundle extras, boolean ordered, 16009 boolean sticky, int sendingUser) { 16010 userInitialized(uss, userId); 16011 } 16012 }, 0, null, null, null, AppOpsManager.OP_NONE, 16013 true, false, MY_PID, Process.SYSTEM_UID, 16014 userId); 16015 uss.initializing = true; 16016 } else { 16017 getUserManagerLocked().makeInitialized(userInfo.id); 16018 } 16019 } 16020 16021 boolean homeInFront = mStackSupervisor.switchUserLocked(userId, uss); 16022 if (homeInFront) { 16023 startHomeActivityLocked(userId); 16024 } else { 16025 mStackSupervisor.resumeTopActivitiesLocked(); 16026 } 16027 16028 EventLogTags.writeAmSwitchUser(userId); 16029 getUserManagerLocked().userForeground(userId); 16030 sendUserSwitchBroadcastsLocked(oldUserId, userId); 16031 if (needStart) { 16032 Intent intent = new Intent(Intent.ACTION_USER_STARTING); 16033 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 16034 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 16035 broadcastIntentLocked(null, null, intent, 16036 null, new IIntentReceiver.Stub() { 16037 @Override 16038 public void performReceive(Intent intent, int resultCode, String data, 16039 Bundle extras, boolean ordered, boolean sticky, int sendingUser) 16040 throws RemoteException { 16041 } 16042 }, 0, null, null, 16043 android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 16044 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 16045 } 16046 } 16047 } finally { 16048 Binder.restoreCallingIdentity(ident); 16049 } 16050 16051 return true; 16052 } 16053 16054 void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) { 16055 long ident = Binder.clearCallingIdentity(); 16056 try { 16057 Intent intent; 16058 if (oldUserId >= 0) { 16059 intent = new Intent(Intent.ACTION_USER_BACKGROUND); 16060 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16061 | Intent.FLAG_RECEIVER_FOREGROUND); 16062 intent.putExtra(Intent.EXTRA_USER_HANDLE, oldUserId); 16063 broadcastIntentLocked(null, null, intent, 16064 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 16065 false, false, MY_PID, Process.SYSTEM_UID, oldUserId); 16066 } 16067 if (newUserId >= 0) { 16068 intent = new Intent(Intent.ACTION_USER_FOREGROUND); 16069 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16070 | Intent.FLAG_RECEIVER_FOREGROUND); 16071 intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId); 16072 broadcastIntentLocked(null, null, intent, 16073 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 16074 false, false, MY_PID, Process.SYSTEM_UID, newUserId); 16075 intent = new Intent(Intent.ACTION_USER_SWITCHED); 16076 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16077 | Intent.FLAG_RECEIVER_FOREGROUND); 16078 intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId); 16079 broadcastIntentLocked(null, null, intent, 16080 null, null, 0, null, null, 16081 android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE, 16082 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 16083 } 16084 } finally { 16085 Binder.restoreCallingIdentity(ident); 16086 } 16087 } 16088 16089 void dispatchUserSwitch(final UserStartedState uss, final int oldUserId, 16090 final int newUserId) { 16091 final int N = mUserSwitchObservers.beginBroadcast(); 16092 if (N > 0) { 16093 final IRemoteCallback callback = new IRemoteCallback.Stub() { 16094 int mCount = 0; 16095 @Override 16096 public void sendResult(Bundle data) throws RemoteException { 16097 synchronized (ActivityManagerService.this) { 16098 if (mCurUserSwitchCallback == this) { 16099 mCount++; 16100 if (mCount == N) { 16101 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 16102 } 16103 } 16104 } 16105 } 16106 }; 16107 synchronized (this) { 16108 uss.switching = true; 16109 mCurUserSwitchCallback = callback; 16110 } 16111 for (int i=0; i<N; i++) { 16112 try { 16113 mUserSwitchObservers.getBroadcastItem(i).onUserSwitching( 16114 newUserId, callback); 16115 } catch (RemoteException e) { 16116 } 16117 } 16118 } else { 16119 synchronized (this) { 16120 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 16121 } 16122 } 16123 mUserSwitchObservers.finishBroadcast(); 16124 } 16125 16126 void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 16127 synchronized (this) { 16128 Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId); 16129 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 16130 } 16131 } 16132 16133 void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) { 16134 mCurUserSwitchCallback = null; 16135 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 16136 mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG, 16137 oldUserId, newUserId, uss)); 16138 } 16139 16140 void userInitialized(UserStartedState uss, int newUserId) { 16141 completeSwitchAndInitalize(uss, newUserId, true, false); 16142 } 16143 16144 void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 16145 completeSwitchAndInitalize(uss, newUserId, false, true); 16146 } 16147 16148 void completeSwitchAndInitalize(UserStartedState uss, int newUserId, 16149 boolean clearInitializing, boolean clearSwitching) { 16150 boolean unfrozen = false; 16151 synchronized (this) { 16152 if (clearInitializing) { 16153 uss.initializing = false; 16154 getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier()); 16155 } 16156 if (clearSwitching) { 16157 uss.switching = false; 16158 } 16159 if (!uss.switching && !uss.initializing) { 16160 mWindowManager.stopFreezingScreen(); 16161 unfrozen = true; 16162 } 16163 } 16164 if (unfrozen) { 16165 final int N = mUserSwitchObservers.beginBroadcast(); 16166 for (int i=0; i<N; i++) { 16167 try { 16168 mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId); 16169 } catch (RemoteException e) { 16170 } 16171 } 16172 mUserSwitchObservers.finishBroadcast(); 16173 } 16174 } 16175 16176 void finishUserSwitch(UserStartedState uss) { 16177 synchronized (this) { 16178 if (uss.mState == UserStartedState.STATE_BOOTING 16179 && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) { 16180 uss.mState = UserStartedState.STATE_RUNNING; 16181 final int userId = uss.mHandle.getIdentifier(); 16182 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 16183 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 16184 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT); 16185 broadcastIntentLocked(null, null, intent, 16186 null, null, 0, null, null, 16187 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE, 16188 true, false, MY_PID, Process.SYSTEM_UID, userId); 16189 } 16190 int num = mUserLru.size(); 16191 int i = 0; 16192 while (num > MAX_RUNNING_USERS && i < mUserLru.size()) { 16193 Integer oldUserId = mUserLru.get(i); 16194 UserStartedState oldUss = mStartedUsers.get(oldUserId); 16195 if (oldUss == null) { 16196 // Shouldn't happen, but be sane if it does. 16197 mUserLru.remove(i); 16198 num--; 16199 continue; 16200 } 16201 if (oldUss.mState == UserStartedState.STATE_STOPPING 16202 || oldUss.mState == UserStartedState.STATE_SHUTDOWN) { 16203 // This user is already stopping, doesn't count. 16204 num--; 16205 i++; 16206 continue; 16207 } 16208 if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) { 16209 // Owner and current can't be stopped, but count as running. 16210 i++; 16211 continue; 16212 } 16213 // This is a user to be stopped. 16214 stopUserLocked(oldUserId, null); 16215 num--; 16216 i++; 16217 } 16218 } 16219 } 16220 16221 @Override 16222 public int stopUser(final int userId, final IStopUserCallback callback) { 16223 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 16224 != PackageManager.PERMISSION_GRANTED) { 16225 String msg = "Permission Denial: switchUser() from pid=" 16226 + Binder.getCallingPid() 16227 + ", uid=" + Binder.getCallingUid() 16228 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 16229 Slog.w(TAG, msg); 16230 throw new SecurityException(msg); 16231 } 16232 if (userId <= 0) { 16233 throw new IllegalArgumentException("Can't stop primary user " + userId); 16234 } 16235 synchronized (this) { 16236 return stopUserLocked(userId, callback); 16237 } 16238 } 16239 16240 private int stopUserLocked(final int userId, final IStopUserCallback callback) { 16241 if (mCurrentUserId == userId) { 16242 return ActivityManager.USER_OP_IS_CURRENT; 16243 } 16244 16245 final UserStartedState uss = mStartedUsers.get(userId); 16246 if (uss == null) { 16247 // User is not started, nothing to do... but we do need to 16248 // callback if requested. 16249 if (callback != null) { 16250 mHandler.post(new Runnable() { 16251 @Override 16252 public void run() { 16253 try { 16254 callback.userStopped(userId); 16255 } catch (RemoteException e) { 16256 } 16257 } 16258 }); 16259 } 16260 return ActivityManager.USER_OP_SUCCESS; 16261 } 16262 16263 if (callback != null) { 16264 uss.mStopCallbacks.add(callback); 16265 } 16266 16267 if (uss.mState != UserStartedState.STATE_STOPPING 16268 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 16269 uss.mState = UserStartedState.STATE_STOPPING; 16270 updateStartedUserArrayLocked(); 16271 16272 long ident = Binder.clearCallingIdentity(); 16273 try { 16274 // We are going to broadcast ACTION_USER_STOPPING and then 16275 // once that is done send a final ACTION_SHUTDOWN and then 16276 // stop the user. 16277 final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING); 16278 stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 16279 stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 16280 stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true); 16281 final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN); 16282 // This is the result receiver for the final shutdown broadcast. 16283 final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() { 16284 @Override 16285 public void performReceive(Intent intent, int resultCode, String data, 16286 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 16287 finishUserStop(uss); 16288 } 16289 }; 16290 // This is the result receiver for the initial stopping broadcast. 16291 final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() { 16292 @Override 16293 public void performReceive(Intent intent, int resultCode, String data, 16294 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 16295 // On to the next. 16296 synchronized (ActivityManagerService.this) { 16297 if (uss.mState != UserStartedState.STATE_STOPPING) { 16298 // Whoops, we are being started back up. Abort, abort! 16299 return; 16300 } 16301 uss.mState = UserStartedState.STATE_SHUTDOWN; 16302 } 16303 broadcastIntentLocked(null, null, shutdownIntent, 16304 null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE, 16305 true, false, MY_PID, Process.SYSTEM_UID, userId); 16306 } 16307 }; 16308 // Kick things off. 16309 broadcastIntentLocked(null, null, stoppingIntent, 16310 null, stoppingReceiver, 0, null, null, 16311 android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 16312 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 16313 } finally { 16314 Binder.restoreCallingIdentity(ident); 16315 } 16316 } 16317 16318 return ActivityManager.USER_OP_SUCCESS; 16319 } 16320 16321 void finishUserStop(UserStartedState uss) { 16322 final int userId = uss.mHandle.getIdentifier(); 16323 boolean stopped; 16324 ArrayList<IStopUserCallback> callbacks; 16325 synchronized (this) { 16326 callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks); 16327 if (mStartedUsers.get(userId) != uss) { 16328 stopped = false; 16329 } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) { 16330 stopped = false; 16331 } else { 16332 stopped = true; 16333 // User can no longer run. 16334 mStartedUsers.remove(userId); 16335 mUserLru.remove(Integer.valueOf(userId)); 16336 updateStartedUserArrayLocked(); 16337 16338 // Clean up all state and processes associated with the user. 16339 // Kill all the processes for the user. 16340 forceStopUserLocked(userId, "finish user"); 16341 } 16342 } 16343 16344 for (int i=0; i<callbacks.size(); i++) { 16345 try { 16346 if (stopped) callbacks.get(i).userStopped(userId); 16347 else callbacks.get(i).userStopAborted(userId); 16348 } catch (RemoteException e) { 16349 } 16350 } 16351 16352 mStackSupervisor.removeUserLocked(userId); 16353 } 16354 16355 @Override 16356 public UserInfo getCurrentUser() { 16357 if ((checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) 16358 != PackageManager.PERMISSION_GRANTED) && ( 16359 checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 16360 != PackageManager.PERMISSION_GRANTED)) { 16361 String msg = "Permission Denial: getCurrentUser() from pid=" 16362 + Binder.getCallingPid() 16363 + ", uid=" + Binder.getCallingUid() 16364 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS; 16365 Slog.w(TAG, msg); 16366 throw new SecurityException(msg); 16367 } 16368 synchronized (this) { 16369 return getUserManagerLocked().getUserInfo(mCurrentUserId); 16370 } 16371 } 16372 16373 int getCurrentUserIdLocked() { 16374 return mCurrentUserId; 16375 } 16376 16377 @Override 16378 public boolean isUserRunning(int userId, boolean orStopped) { 16379 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) 16380 != PackageManager.PERMISSION_GRANTED) { 16381 String msg = "Permission Denial: isUserRunning() from pid=" 16382 + Binder.getCallingPid() 16383 + ", uid=" + Binder.getCallingUid() 16384 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS; 16385 Slog.w(TAG, msg); 16386 throw new SecurityException(msg); 16387 } 16388 synchronized (this) { 16389 return isUserRunningLocked(userId, orStopped); 16390 } 16391 } 16392 16393 boolean isUserRunningLocked(int userId, boolean orStopped) { 16394 UserStartedState state = mStartedUsers.get(userId); 16395 if (state == null) { 16396 return false; 16397 } 16398 if (orStopped) { 16399 return true; 16400 } 16401 return state.mState != UserStartedState.STATE_STOPPING 16402 && state.mState != UserStartedState.STATE_SHUTDOWN; 16403 } 16404 16405 @Override 16406 public int[] getRunningUserIds() { 16407 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) 16408 != PackageManager.PERMISSION_GRANTED) { 16409 String msg = "Permission Denial: isUserRunning() 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 mStartedUserArray; 16418 } 16419 } 16420 16421 private void updateStartedUserArrayLocked() { 16422 int num = 0; 16423 for (int i=0; i<mStartedUsers.size(); i++) { 16424 UserStartedState uss = mStartedUsers.valueAt(i); 16425 // This list does not include stopping users. 16426 if (uss.mState != UserStartedState.STATE_STOPPING 16427 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 16428 num++; 16429 } 16430 } 16431 mStartedUserArray = new int[num]; 16432 num = 0; 16433 for (int i=0; i<mStartedUsers.size(); i++) { 16434 UserStartedState uss = mStartedUsers.valueAt(i); 16435 if (uss.mState != UserStartedState.STATE_STOPPING 16436 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 16437 mStartedUserArray[num] = mStartedUsers.keyAt(i); 16438 num++; 16439 } 16440 } 16441 } 16442 16443 @Override 16444 public void registerUserSwitchObserver(IUserSwitchObserver observer) { 16445 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 16446 != PackageManager.PERMISSION_GRANTED) { 16447 String msg = "Permission Denial: registerUserSwitchObserver() from pid=" 16448 + Binder.getCallingPid() 16449 + ", uid=" + Binder.getCallingUid() 16450 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 16451 Slog.w(TAG, msg); 16452 throw new SecurityException(msg); 16453 } 16454 16455 mUserSwitchObservers.register(observer); 16456 } 16457 16458 @Override 16459 public void unregisterUserSwitchObserver(IUserSwitchObserver observer) { 16460 mUserSwitchObservers.unregister(observer); 16461 } 16462 16463 private boolean userExists(int userId) { 16464 if (userId == 0) { 16465 return true; 16466 } 16467 UserManagerService ums = getUserManagerLocked(); 16468 return ums != null ? (ums.getUserInfo(userId) != null) : false; 16469 } 16470 16471 int[] getUsersLocked() { 16472 UserManagerService ums = getUserManagerLocked(); 16473 return ums != null ? ums.getUserIds() : new int[] { 0 }; 16474 } 16475 16476 UserManagerService getUserManagerLocked() { 16477 if (mUserManager == null) { 16478 IBinder b = ServiceManager.getService(Context.USER_SERVICE); 16479 mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b); 16480 } 16481 return mUserManager; 16482 } 16483 16484 private int applyUserId(int uid, int userId) { 16485 return UserHandle.getUid(userId, uid); 16486 } 16487 16488 ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) { 16489 if (info == null) return null; 16490 ApplicationInfo newInfo = new ApplicationInfo(info); 16491 newInfo.uid = applyUserId(info.uid, userId); 16492 newInfo.dataDir = USER_DATA_DIR + userId + "/" 16493 + info.packageName; 16494 return newInfo; 16495 } 16496 16497 ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) { 16498 if (aInfo == null 16499 || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) { 16500 return aInfo; 16501 } 16502 16503 ActivityInfo info = new ActivityInfo(aInfo); 16504 info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId); 16505 return info; 16506 } 16507 16508 private final class LocalService extends ActivityManagerInternal { 16509 @Override 16510 public void goingToSleep() { 16511 ActivityManagerService.this.goingToSleep(); 16512 } 16513 16514 @Override 16515 public void wakingUp() { 16516 ActivityManagerService.this.wakingUp(); 16517 } 16518 } 16519} 16520