ActivityManagerService.java revision 34f6084bc21b07ae9112be6e7a8f50c49828ac9c
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.readBooleanAttribute; 21import static com.android.internal.util.XmlUtils.readIntAttribute; 22import static com.android.internal.util.XmlUtils.readLongAttribute; 23import static com.android.internal.util.XmlUtils.writeBooleanAttribute; 24import static com.android.internal.util.XmlUtils.writeIntAttribute; 25import static com.android.internal.util.XmlUtils.writeLongAttribute; 26import static com.android.server.Watchdog.NATIVE_STACKS_OF_INTEREST; 27import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT; 28import static org.xmlpull.v1.XmlPullParser.START_TAG; 29import static com.android.server.am.ActivityStackSupervisor.HOME_STACK_ID; 30 31import android.Manifest; 32import android.app.AppOpsManager; 33import android.app.IActivityContainer; 34import android.app.IActivityContainerCallback; 35import android.appwidget.AppWidgetManager; 36import android.graphics.Rect; 37import android.os.BatteryStats; 38import android.os.PersistableBundle; 39import android.service.voice.IVoiceInteractionSession; 40import android.util.ArrayMap; 41 42import com.android.internal.R; 43import com.android.internal.annotations.GuardedBy; 44import com.android.internal.app.IAppOpsService; 45import com.android.internal.app.IVoiceInteractor; 46import com.android.internal.app.ProcessMap; 47import com.android.internal.app.ProcessStats; 48import com.android.internal.content.PackageMonitor; 49import com.android.internal.os.BackgroundThread; 50import com.android.internal.os.BatteryStatsImpl; 51import com.android.internal.os.ProcessCpuTracker; 52import com.android.internal.os.TransferPipe; 53import com.android.internal.os.Zygote; 54import com.android.internal.util.FastPrintWriter; 55import com.android.internal.util.FastXmlSerializer; 56import com.android.internal.util.MemInfoReader; 57import com.android.internal.util.Preconditions; 58import com.android.server.AppOpsService; 59import com.android.server.AttributeCache; 60import com.android.server.IntentResolver; 61import com.android.server.LocalServices; 62import com.android.server.ServiceThread; 63import com.android.server.SystemService; 64import com.android.server.SystemServiceManager; 65import com.android.server.Watchdog; 66import com.android.server.am.ActivityStack.ActivityState; 67import com.android.server.firewall.IntentFirewall; 68import com.android.server.pm.UserManagerService; 69import com.android.server.wm.AppTransition; 70import com.android.server.wm.WindowManagerService; 71import com.google.android.collect.Lists; 72import com.google.android.collect.Maps; 73 74import libcore.io.IoUtils; 75 76import org.xmlpull.v1.XmlPullParser; 77import org.xmlpull.v1.XmlPullParserException; 78import org.xmlpull.v1.XmlSerializer; 79 80import android.app.Activity; 81import android.app.ActivityManager; 82import android.app.ActivityManager.RunningTaskInfo; 83import android.app.ActivityManager.StackInfo; 84import android.app.ActivityManagerInternal; 85import android.app.ActivityManagerNative; 86import android.app.ActivityOptions; 87import android.app.ActivityThread; 88import android.app.AlertDialog; 89import android.app.AppGlobals; 90import android.app.ApplicationErrorReport; 91import android.app.Dialog; 92import android.app.IActivityController; 93import android.app.IApplicationThread; 94import android.app.IInstrumentationWatcher; 95import android.app.INotificationManager; 96import android.app.IProcessObserver; 97import android.app.IServiceConnection; 98import android.app.IStopUserCallback; 99import android.app.IUiAutomationConnection; 100import android.app.IUserSwitchObserver; 101import android.app.Instrumentation; 102import android.app.Notification; 103import android.app.NotificationManager; 104import android.app.PendingIntent; 105import android.app.backup.IBackupManager; 106import android.content.ActivityNotFoundException; 107import android.content.BroadcastReceiver; 108import android.content.ClipData; 109import android.content.ComponentCallbacks2; 110import android.content.ComponentName; 111import android.content.ContentProvider; 112import android.content.ContentResolver; 113import android.content.Context; 114import android.content.DialogInterface; 115import android.content.IContentProvider; 116import android.content.IIntentReceiver; 117import android.content.IIntentSender; 118import android.content.Intent; 119import android.content.IntentFilter; 120import android.content.IntentSender; 121import android.content.pm.ActivityInfo; 122import android.content.pm.ApplicationInfo; 123import android.content.pm.ConfigurationInfo; 124import android.content.pm.IPackageDataObserver; 125import android.content.pm.IPackageManager; 126import android.content.pm.InstrumentationInfo; 127import android.content.pm.PackageInfo; 128import android.content.pm.PackageManager; 129import android.content.pm.ParceledListSlice; 130import android.content.pm.UserInfo; 131import android.content.pm.PackageManager.NameNotFoundException; 132import android.content.pm.PathPermission; 133import android.content.pm.ProviderInfo; 134import android.content.pm.ResolveInfo; 135import android.content.pm.ServiceInfo; 136import android.content.res.CompatibilityInfo; 137import android.content.res.Configuration; 138import android.graphics.Bitmap; 139import android.net.Proxy; 140import android.net.ProxyInfo; 141import android.net.Uri; 142import android.os.Binder; 143import android.os.Build; 144import android.os.Bundle; 145import android.os.Debug; 146import android.os.DropBoxManager; 147import android.os.Environment; 148import android.os.FactoryTest; 149import android.os.FileObserver; 150import android.os.FileUtils; 151import android.os.Handler; 152import android.os.IBinder; 153import android.os.IPermissionController; 154import android.os.IRemoteCallback; 155import android.os.IUserManager; 156import android.os.Looper; 157import android.os.Message; 158import android.os.Parcel; 159import android.os.ParcelFileDescriptor; 160import android.os.Process; 161import android.os.RemoteCallbackList; 162import android.os.RemoteException; 163import android.os.SELinux; 164import android.os.ServiceManager; 165import android.os.StrictMode; 166import android.os.SystemClock; 167import android.os.SystemProperties; 168import android.os.UpdateLock; 169import android.os.UserHandle; 170import android.provider.Settings; 171import android.text.format.DateUtils; 172import android.text.format.Time; 173import android.util.AtomicFile; 174import android.util.EventLog; 175import android.util.Log; 176import android.util.Pair; 177import android.util.PrintWriterPrinter; 178import android.util.Slog; 179import android.util.SparseArray; 180import android.util.TimeUtils; 181import android.util.Xml; 182import android.view.Gravity; 183import android.view.LayoutInflater; 184import android.view.View; 185import android.view.WindowManager; 186 187import java.io.BufferedInputStream; 188import java.io.BufferedOutputStream; 189import java.io.DataInputStream; 190import java.io.DataOutputStream; 191import java.io.File; 192import java.io.FileDescriptor; 193import java.io.FileInputStream; 194import java.io.FileNotFoundException; 195import java.io.FileOutputStream; 196import java.io.IOException; 197import java.io.InputStreamReader; 198import java.io.PrintWriter; 199import java.io.StringWriter; 200import java.lang.ref.WeakReference; 201import java.util.ArrayList; 202import java.util.Arrays; 203import java.util.Collections; 204import java.util.Comparator; 205import java.util.HashMap; 206import java.util.HashSet; 207import java.util.Iterator; 208import java.util.List; 209import java.util.Locale; 210import java.util.Map; 211import java.util.Set; 212import java.util.concurrent.atomic.AtomicBoolean; 213import java.util.concurrent.atomic.AtomicLong; 214 215public final class ActivityManagerService extends ActivityManagerNative 216 implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback { 217 private static final String USER_DATA_DIR = "/data/user/"; 218 static final String TAG = "ActivityManager"; 219 static final String TAG_MU = "ActivityManagerServiceMU"; 220 static final boolean DEBUG = false; 221 static final boolean localLOGV = DEBUG; 222 static final boolean DEBUG_BACKUP = localLOGV || false; 223 static final boolean DEBUG_BROADCAST = localLOGV || false; 224 static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false; 225 static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false; 226 static final boolean DEBUG_CLEANUP = localLOGV || false; 227 static final boolean DEBUG_CONFIGURATION = localLOGV || false; 228 static final boolean DEBUG_FOCUS = false; 229 static final boolean DEBUG_IMMERSIVE = localLOGV || false; 230 static final boolean DEBUG_MU = localLOGV || false; 231 static final boolean DEBUG_OOM_ADJ = localLOGV || false; 232 static final boolean DEBUG_LRU = localLOGV || false; 233 static final boolean DEBUG_PAUSE = localLOGV || false; 234 static final boolean DEBUG_POWER = localLOGV || false; 235 static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false; 236 static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false; 237 static final boolean DEBUG_PROCESSES = localLOGV || false; 238 static final boolean DEBUG_PROVIDER = localLOGV || false; 239 static final boolean DEBUG_RESULTS = localLOGV || false; 240 static final boolean DEBUG_SERVICE = localLOGV || false; 241 static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false; 242 static final boolean DEBUG_STACK = localLOGV || false; 243 static final boolean DEBUG_SWITCH = localLOGV || false; 244 static final boolean DEBUG_TASKS = localLOGV || false; 245 static final boolean DEBUG_THUMBNAILS = localLOGV || false; 246 static final boolean DEBUG_TRANSITION = localLOGV || false; 247 static final boolean DEBUG_URI_PERMISSION = localLOGV || false; 248 static final boolean DEBUG_USER_LEAVING = localLOGV || false; 249 static final boolean DEBUG_VISBILITY = localLOGV || false; 250 static final boolean DEBUG_PSS = localLOGV || false; 251 static final boolean DEBUG_LOCKSCREEN = localLOGV || false; 252 static final boolean VALIDATE_TOKENS = false; 253 static final boolean SHOW_ACTIVITY_START_TIME = true; 254 255 // Control over CPU and battery monitoring. 256 static final long BATTERY_STATS_TIME = 30*60*1000; // write battery stats every 30 minutes. 257 static final boolean MONITOR_CPU_USAGE = true; 258 static final long MONITOR_CPU_MIN_TIME = 5*1000; // don't sample cpu less than every 5 seconds. 259 static final long MONITOR_CPU_MAX_TIME = 0x0fffffff; // wait possibly forever for next cpu sample. 260 static final boolean MONITOR_THREAD_CPU_USAGE = false; 261 262 // The flags that are set for all calls we make to the package manager. 263 static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES; 264 265 private static final String SYSTEM_DEBUGGABLE = "ro.debuggable"; 266 267 static final boolean IS_USER_BUILD = "user".equals(Build.TYPE); 268 269 // Maximum number of recent tasks that we can remember. 270 static final int MAX_RECENT_TASKS = ActivityManager.isLowRamDeviceStatic() ? 10 : 20; 271 272 // Amount of time after a call to stopAppSwitches() during which we will 273 // prevent further untrusted switches from happening. 274 static final long APP_SWITCH_DELAY_TIME = 5*1000; 275 276 // How long we wait for a launched process to attach to the activity manager 277 // before we decide it's never going to come up for real. 278 static final int PROC_START_TIMEOUT = 10*1000; 279 280 // How long we wait for a launched process to attach to the activity manager 281 // before we decide it's never going to come up for real, when the process was 282 // started with a wrapper for instrumentation (such as Valgrind) because it 283 // could take much longer than usual. 284 static final int PROC_START_TIMEOUT_WITH_WRAPPER = 300*1000; 285 286 // How long to wait after going idle before forcing apps to GC. 287 static final int GC_TIMEOUT = 5*1000; 288 289 // The minimum amount of time between successive GC requests for a process. 290 static final int GC_MIN_INTERVAL = 60*1000; 291 292 // The minimum amount of time between successive PSS requests for a process. 293 static final int FULL_PSS_MIN_INTERVAL = 10*60*1000; 294 295 // The minimum amount of time between successive PSS requests for a process 296 // when the request is due to the memory state being lowered. 297 static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000; 298 299 // The rate at which we check for apps using excessive power -- 15 mins. 300 static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000; 301 302 // The minimum sample duration we will allow before deciding we have 303 // enough data on wake locks to start killing things. 304 static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000; 305 306 // The minimum sample duration we will allow before deciding we have 307 // enough data on CPU usage to start killing things. 308 static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000; 309 310 // How long we allow a receiver to run before giving up on it. 311 static final int BROADCAST_FG_TIMEOUT = 10*1000; 312 static final int BROADCAST_BG_TIMEOUT = 60*1000; 313 314 // How long we wait until we timeout on key dispatching. 315 static final int KEY_DISPATCHING_TIMEOUT = 5*1000; 316 317 // How long we wait until we timeout on key dispatching during instrumentation. 318 static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000; 319 320 // Amount of time we wait for observers to handle a user switch before 321 // giving up on them and unfreezing the screen. 322 static final int USER_SWITCH_TIMEOUT = 2*1000; 323 324 // Maximum number of users we allow to be running at a time. 325 static final int MAX_RUNNING_USERS = 3; 326 327 // How long to wait in getAssistContextExtras for the activity and foreground services 328 // to respond with the result. 329 static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500; 330 331 // Maximum number of persisted Uri grants a package is allowed 332 static final int MAX_PERSISTED_URI_GRANTS = 128; 333 334 static final int MY_PID = Process.myPid(); 335 336 static final String[] EMPTY_STRING_ARRAY = new String[0]; 337 338 // How many bytes to write into the dropbox log before truncating 339 static final int DROPBOX_MAX_SIZE = 256 * 1024; 340 341 /** All system services */ 342 SystemServiceManager mSystemServiceManager; 343 344 /** Run all ActivityStacks through this */ 345 ActivityStackSupervisor mStackSupervisor; 346 347 public IntentFirewall mIntentFirewall; 348 349 // Whether we should show our dialogs (ANR, crash, etc) or just perform their 350 // default actuion automatically. Important for devices without direct input 351 // devices. 352 private boolean mShowDialogs = true; 353 354 /** 355 * Description of a request to start a new activity, which has been held 356 * due to app switches being disabled. 357 */ 358 static class PendingActivityLaunch { 359 final ActivityRecord r; 360 final ActivityRecord sourceRecord; 361 final int startFlags; 362 final ActivityStack stack; 363 364 PendingActivityLaunch(ActivityRecord _r, ActivityRecord _sourceRecord, 365 int _startFlags, ActivityStack _stack) { 366 r = _r; 367 sourceRecord = _sourceRecord; 368 startFlags = _startFlags; 369 stack = _stack; 370 } 371 } 372 373 final ArrayList<PendingActivityLaunch> mPendingActivityLaunches 374 = new ArrayList<PendingActivityLaunch>(); 375 376 BroadcastQueue mFgBroadcastQueue; 377 BroadcastQueue mBgBroadcastQueue; 378 // Convenient for easy iteration over the queues. Foreground is first 379 // so that dispatch of foreground broadcasts gets precedence. 380 final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2]; 381 382 BroadcastQueue broadcastQueueForIntent(Intent intent) { 383 final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0; 384 if (DEBUG_BACKGROUND_BROADCAST) { 385 Slog.i(TAG, "Broadcast intent " + intent + " on " 386 + (isFg ? "foreground" : "background") 387 + " queue"); 388 } 389 return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue; 390 } 391 392 BroadcastRecord broadcastRecordForReceiverLocked(IBinder receiver) { 393 for (BroadcastQueue queue : mBroadcastQueues) { 394 BroadcastRecord r = queue.getMatchingOrderedReceiver(receiver); 395 if (r != null) { 396 return r; 397 } 398 } 399 return null; 400 } 401 402 /** 403 * Activity we have told the window manager to have key focus. 404 */ 405 ActivityRecord mFocusedActivity = null; 406 407 /** 408 * List of intents that were used to start the most recent tasks. 409 */ 410 final ArrayList<TaskRecord> mRecentTasks = new ArrayList<TaskRecord>(); 411 412 public class PendingAssistExtras extends Binder implements Runnable { 413 public final ActivityRecord activity; 414 public boolean haveResult = false; 415 public Bundle result = null; 416 public PendingAssistExtras(ActivityRecord _activity) { 417 activity = _activity; 418 } 419 @Override 420 public void run() { 421 Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity); 422 synchronized (this) { 423 haveResult = true; 424 notifyAll(); 425 } 426 } 427 } 428 429 final ArrayList<PendingAssistExtras> mPendingAssistExtras 430 = new ArrayList<PendingAssistExtras>(); 431 432 /** 433 * Process management. 434 */ 435 final ProcessList mProcessList = new ProcessList(); 436 437 /** 438 * All of the applications we currently have running organized by name. 439 * The keys are strings of the application package name (as 440 * returned by the package manager), and the keys are ApplicationRecord 441 * objects. 442 */ 443 final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>(); 444 445 /** 446 * Tracking long-term execution of processes to look for abuse and other 447 * bad app behavior. 448 */ 449 final ProcessStatsService mProcessStats; 450 451 /** 452 * The currently running isolated processes. 453 */ 454 final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>(); 455 456 /** 457 * Counter for assigning isolated process uids, to avoid frequently reusing the 458 * same ones. 459 */ 460 int mNextIsolatedProcessUid = 0; 461 462 /** 463 * The currently running heavy-weight process, if any. 464 */ 465 ProcessRecord mHeavyWeightProcess = null; 466 467 /** 468 * The last time that various processes have crashed. 469 */ 470 final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>(); 471 472 /** 473 * Information about a process that is currently marked as bad. 474 */ 475 static final class BadProcessInfo { 476 BadProcessInfo(long time, String shortMsg, String longMsg, String stack) { 477 this.time = time; 478 this.shortMsg = shortMsg; 479 this.longMsg = longMsg; 480 this.stack = stack; 481 } 482 483 final long time; 484 final String shortMsg; 485 final String longMsg; 486 final String stack; 487 } 488 489 /** 490 * Set of applications that we consider to be bad, and will reject 491 * incoming broadcasts from (which the user has no control over). 492 * Processes are added to this set when they have crashed twice within 493 * a minimum amount of time; they are removed from it when they are 494 * later restarted (hopefully due to some user action). The value is the 495 * time it was added to the list. 496 */ 497 final ProcessMap<BadProcessInfo> mBadProcesses = new ProcessMap<BadProcessInfo>(); 498 499 /** 500 * All of the processes we currently have running organized by pid. 501 * The keys are the pid running the application. 502 * 503 * <p>NOTE: This object is protected by its own lock, NOT the global 504 * activity manager lock! 505 */ 506 final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>(); 507 508 /** 509 * All of the processes that have been forced to be foreground. The key 510 * is the pid of the caller who requested it (we hold a death 511 * link on it). 512 */ 513 abstract class ForegroundToken implements IBinder.DeathRecipient { 514 int pid; 515 IBinder token; 516 } 517 final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>(); 518 519 /** 520 * List of records for processes that someone had tried to start before the 521 * system was ready. We don't start them at that point, but ensure they 522 * are started by the time booting is complete. 523 */ 524 final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>(); 525 526 /** 527 * List of persistent applications that are in the process 528 * of being started. 529 */ 530 final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>(); 531 532 /** 533 * Processes that are being forcibly torn down. 534 */ 535 final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>(); 536 537 /** 538 * List of running applications, sorted by recent usage. 539 * The first entry in the list is the least recently used. 540 */ 541 final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>(); 542 543 /** 544 * Where in mLruProcesses that the processes hosting activities start. 545 */ 546 int mLruProcessActivityStart = 0; 547 548 /** 549 * Where in mLruProcesses that the processes hosting services start. 550 * This is after (lower index) than mLruProcessesActivityStart. 551 */ 552 int mLruProcessServiceStart = 0; 553 554 /** 555 * List of processes that should gc as soon as things are idle. 556 */ 557 final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>(); 558 559 /** 560 * Processes we want to collect PSS data from. 561 */ 562 final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>(); 563 564 /** 565 * Last time we requested PSS data of all processes. 566 */ 567 long mLastFullPssTime = SystemClock.uptimeMillis(); 568 569 /** 570 * This is the process holding what we currently consider to be 571 * the "home" activity. 572 */ 573 ProcessRecord mHomeProcess; 574 575 /** 576 * This is the process holding the activity the user last visited that 577 * is in a different process from the one they are currently in. 578 */ 579 ProcessRecord mPreviousProcess; 580 581 /** 582 * The time at which the previous process was last visible. 583 */ 584 long mPreviousProcessVisibleTime; 585 586 /** 587 * Which uses have been started, so are allowed to run code. 588 */ 589 final SparseArray<UserStartedState> mStartedUsers = new SparseArray<UserStartedState>(); 590 591 /** 592 * LRU list of history of current users. Most recently current is at the end. 593 */ 594 final ArrayList<Integer> mUserLru = new ArrayList<Integer>(); 595 596 /** 597 * Constant array of the users that are currently started. 598 */ 599 int[] mStartedUserArray = new int[] { 0 }; 600 601 /** 602 * Registered observers of the user switching mechanics. 603 */ 604 final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers 605 = new RemoteCallbackList<IUserSwitchObserver>(); 606 607 /** 608 * Currently active user switch. 609 */ 610 Object mCurUserSwitchCallback; 611 612 /** 613 * Packages that the user has asked to have run in screen size 614 * compatibility mode instead of filling the screen. 615 */ 616 final CompatModePackages mCompatModePackages; 617 618 /** 619 * Set of IntentSenderRecord objects that are currently active. 620 */ 621 final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords 622 = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>(); 623 624 /** 625 * Fingerprints (hashCode()) of stack traces that we've 626 * already logged DropBox entries for. Guarded by itself. If 627 * something (rogue user app) forces this over 628 * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared. 629 */ 630 private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>(); 631 private static final int MAX_DUP_SUPPRESSED_STACKS = 5000; 632 633 /** 634 * Strict Mode background batched logging state. 635 * 636 * The string buffer is guarded by itself, and its lock is also 637 * used to determine if another batched write is already 638 * in-flight. 639 */ 640 private final StringBuilder mStrictModeBuffer = new StringBuilder(); 641 642 /** 643 * Keeps track of all IIntentReceivers that have been registered for 644 * broadcasts. Hash keys are the receiver IBinder, hash value is 645 * a ReceiverList. 646 */ 647 final HashMap<IBinder, ReceiverList> mRegisteredReceivers = 648 new HashMap<IBinder, ReceiverList>(); 649 650 /** 651 * Resolver for broadcast intents to registered receivers. 652 * Holds BroadcastFilter (subclass of IntentFilter). 653 */ 654 final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver 655 = new IntentResolver<BroadcastFilter, BroadcastFilter>() { 656 @Override 657 protected boolean allowFilterResult( 658 BroadcastFilter filter, List<BroadcastFilter> dest) { 659 IBinder target = filter.receiverList.receiver.asBinder(); 660 for (int i=dest.size()-1; i>=0; i--) { 661 if (dest.get(i).receiverList.receiver.asBinder() == target) { 662 return false; 663 } 664 } 665 return true; 666 } 667 668 @Override 669 protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) { 670 if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL 671 || userId == filter.owningUserId) { 672 return super.newResult(filter, match, userId); 673 } 674 return null; 675 } 676 677 @Override 678 protected BroadcastFilter[] newArray(int size) { 679 return new BroadcastFilter[size]; 680 } 681 682 @Override 683 protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) { 684 return packageName.equals(filter.packageName); 685 } 686 }; 687 688 /** 689 * State of all active sticky broadcasts per user. Keys are the action of the 690 * sticky Intent, values are an ArrayList of all broadcasted intents with 691 * that action (which should usually be one). The SparseArray is keyed 692 * by the user ID the sticky is for, and can include UserHandle.USER_ALL 693 * for stickies that are sent to all users. 694 */ 695 final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts = 696 new SparseArray<ArrayMap<String, ArrayList<Intent>>>(); 697 698 final ActiveServices mServices; 699 700 /** 701 * Backup/restore process management 702 */ 703 String mBackupAppName = null; 704 BackupRecord mBackupTarget = null; 705 706 final ProviderMap mProviderMap; 707 708 /** 709 * List of content providers who have clients waiting for them. The 710 * application is currently being launched and the provider will be 711 * removed from this list once it is published. 712 */ 713 final ArrayList<ContentProviderRecord> mLaunchingProviders 714 = new ArrayList<ContentProviderRecord>(); 715 716 /** 717 * File storing persisted {@link #mGrantedUriPermissions}. 718 */ 719 private final AtomicFile mGrantFile; 720 721 /** XML constants used in {@link #mGrantFile} */ 722 private static final String TAG_URI_GRANTS = "uri-grants"; 723 private static final String TAG_URI_GRANT = "uri-grant"; 724 private static final String ATTR_USER_HANDLE = "userHandle"; 725 private static final String ATTR_SOURCE_PKG = "sourcePkg"; 726 private static final String ATTR_TARGET_PKG = "targetPkg"; 727 private static final String ATTR_URI = "uri"; 728 private static final String ATTR_MODE_FLAGS = "modeFlags"; 729 private static final String ATTR_CREATED_TIME = "createdTime"; 730 private static final String ATTR_PREFIX = "prefix"; 731 732 /** 733 * Global set of specific {@link Uri} permissions that have been granted. 734 * This optimized lookup structure maps from {@link UriPermission#targetUid} 735 * to {@link UriPermission#uri} to {@link UriPermission}. 736 */ 737 @GuardedBy("this") 738 private final SparseArray<ArrayMap<GrantUri, UriPermission>> 739 mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>(); 740 741 public static class GrantUri { 742 public final Uri uri; 743 public final boolean prefix; 744 745 public GrantUri(Uri uri, boolean prefix) { 746 this.uri = uri; 747 this.prefix = prefix; 748 } 749 750 @Override 751 public int hashCode() { 752 return toString().hashCode(); 753 } 754 755 @Override 756 public boolean equals(Object o) { 757 if (o instanceof GrantUri) { 758 GrantUri other = (GrantUri) o; 759 return uri.equals(other.uri) && prefix == other.prefix; 760 } 761 return false; 762 } 763 764 @Override 765 public String toString() { 766 if (prefix) { 767 return uri.toString() + " [prefix]"; 768 } else { 769 return uri.toString(); 770 } 771 } 772 } 773 774 CoreSettingsObserver mCoreSettingsObserver; 775 776 /** 777 * Thread-local storage used to carry caller permissions over through 778 * indirect content-provider access. 779 */ 780 private class Identity { 781 public int pid; 782 public int uid; 783 784 Identity(int _pid, int _uid) { 785 pid = _pid; 786 uid = _uid; 787 } 788 } 789 790 private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>(); 791 792 /** 793 * All information we have collected about the runtime performance of 794 * any user id that can impact battery performance. 795 */ 796 final BatteryStatsService mBatteryStatsService; 797 798 /** 799 * Information about component usage 800 */ 801 final UsageStatsService mUsageStatsService; 802 803 /** 804 * Information about and control over application operations 805 */ 806 final AppOpsService mAppOpsService; 807 808 /** 809 * Current configuration information. HistoryRecord objects are given 810 * a reference to this object to indicate which configuration they are 811 * currently running in, so this object must be kept immutable. 812 */ 813 Configuration mConfiguration = new Configuration(); 814 815 /** 816 * Current sequencing integer of the configuration, for skipping old 817 * configurations. 818 */ 819 int mConfigurationSeq = 0; 820 821 /** 822 * Hardware-reported OpenGLES version. 823 */ 824 final int GL_ES_VERSION; 825 826 /** 827 * List of initialization arguments to pass to all processes when binding applications to them. 828 * For example, references to the commonly used services. 829 */ 830 HashMap<String, IBinder> mAppBindArgs; 831 832 /** 833 * Temporary to avoid allocations. Protected by main lock. 834 */ 835 final StringBuilder mStringBuilder = new StringBuilder(256); 836 837 /** 838 * Used to control how we initialize the service. 839 */ 840 ComponentName mTopComponent; 841 String mTopAction = Intent.ACTION_MAIN; 842 String mTopData; 843 boolean mProcessesReady = false; 844 boolean mSystemReady = false; 845 boolean mBooting = false; 846 boolean mWaitingUpdate = false; 847 boolean mDidUpdate = false; 848 boolean mOnBattery = false; 849 boolean mLaunchWarningShown = false; 850 851 Context mContext; 852 853 int mFactoryTest; 854 855 boolean mCheckedForSetup; 856 857 /** 858 * The time at which we will allow normal application switches again, 859 * after a call to {@link #stopAppSwitches()}. 860 */ 861 long mAppSwitchesAllowedTime; 862 863 /** 864 * This is set to true after the first switch after mAppSwitchesAllowedTime 865 * is set; any switches after that will clear the time. 866 */ 867 boolean mDidAppSwitch; 868 869 /** 870 * Last time (in realtime) at which we checked for power usage. 871 */ 872 long mLastPowerCheckRealtime; 873 874 /** 875 * Last time (in uptime) at which we checked for power usage. 876 */ 877 long mLastPowerCheckUptime; 878 879 /** 880 * Set while we are wanting to sleep, to prevent any 881 * activities from being started/resumed. 882 */ 883 private boolean mSleeping = false; 884 885 /** 886 * Set while we are running a voice interaction. This overrides 887 * sleeping while it is active. 888 */ 889 private boolean mRunningVoice = false; 890 891 /** 892 * State of external calls telling us if the device is asleep. 893 */ 894 private boolean mWentToSleep = false; 895 896 /** 897 * State of external call telling us if the lock screen is shown. 898 */ 899 private boolean mLockScreenShown = false; 900 901 /** 902 * Set if we are shutting down the system, similar to sleeping. 903 */ 904 boolean mShuttingDown = false; 905 906 /** 907 * Current sequence id for oom_adj computation traversal. 908 */ 909 int mAdjSeq = 0; 910 911 /** 912 * Current sequence id for process LRU updating. 913 */ 914 int mLruSeq = 0; 915 916 /** 917 * Keep track of the non-cached/empty process we last found, to help 918 * determine how to distribute cached/empty processes next time. 919 */ 920 int mNumNonCachedProcs = 0; 921 922 /** 923 * Keep track of the number of cached hidden procs, to balance oom adj 924 * distribution between those and empty procs. 925 */ 926 int mNumCachedHiddenProcs = 0; 927 928 /** 929 * Keep track of the number of service processes we last found, to 930 * determine on the next iteration which should be B services. 931 */ 932 int mNumServiceProcs = 0; 933 int mNewNumAServiceProcs = 0; 934 int mNewNumServiceProcs = 0; 935 936 /** 937 * Allow the current computed overall memory level of the system to go down? 938 * This is set to false when we are killing processes for reasons other than 939 * memory management, so that the now smaller process list will not be taken as 940 * an indication that memory is tighter. 941 */ 942 boolean mAllowLowerMemLevel = false; 943 944 /** 945 * The last computed memory level, for holding when we are in a state that 946 * processes are going away for other reasons. 947 */ 948 int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL; 949 950 /** 951 * The last total number of process we have, to determine if changes actually look 952 * like a shrinking number of process due to lower RAM. 953 */ 954 int mLastNumProcesses; 955 956 /** 957 * The uptime of the last time we performed idle maintenance. 958 */ 959 long mLastIdleTime = SystemClock.uptimeMillis(); 960 961 /** 962 * Total time spent with RAM that has been added in the past since the last idle time. 963 */ 964 long mLowRamTimeSinceLastIdle = 0; 965 966 /** 967 * If RAM is currently low, when that horrible situation started. 968 */ 969 long mLowRamStartTime = 0; 970 971 /** 972 * For reporting to battery stats the current top application. 973 */ 974 private String mCurResumedPackage = null; 975 private int mCurResumedUid = -1; 976 977 /** 978 * For reporting to battery stats the apps currently running foreground 979 * service. The ProcessMap is package/uid tuples; each of these contain 980 * an array of the currently foreground processes. 981 */ 982 final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages 983 = new ProcessMap<ArrayList<ProcessRecord>>(); 984 985 /** 986 * This is set if we had to do a delayed dexopt of an app before launching 987 * it, to increase the ANR timeouts in that case. 988 */ 989 boolean mDidDexOpt; 990 991 /** 992 * Set if the systemServer made a call to enterSafeMode. 993 */ 994 boolean mSafeMode; 995 996 String mDebugApp = null; 997 boolean mWaitForDebugger = false; 998 boolean mDebugTransient = false; 999 String mOrigDebugApp = null; 1000 boolean mOrigWaitForDebugger = false; 1001 boolean mAlwaysFinishActivities = false; 1002 IActivityController mController = null; 1003 String mProfileApp = null; 1004 ProcessRecord mProfileProc = null; 1005 String mProfileFile; 1006 ParcelFileDescriptor mProfileFd; 1007 int mProfileType = 0; 1008 boolean mAutoStopProfiler = false; 1009 String mOpenGlTraceApp = null; 1010 1011 static class ProcessChangeItem { 1012 static final int CHANGE_ACTIVITIES = 1<<0; 1013 static final int CHANGE_PROCESS_STATE = 1<<1; 1014 int changes; 1015 int uid; 1016 int pid; 1017 int processState; 1018 boolean foregroundActivities; 1019 } 1020 1021 final RemoteCallbackList<IProcessObserver> mProcessObservers 1022 = new RemoteCallbackList<IProcessObserver>(); 1023 ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5]; 1024 1025 final ArrayList<ProcessChangeItem> mPendingProcessChanges 1026 = new ArrayList<ProcessChangeItem>(); 1027 final ArrayList<ProcessChangeItem> mAvailProcessChanges 1028 = new ArrayList<ProcessChangeItem>(); 1029 1030 /** 1031 * Runtime CPU use collection thread. This object's lock is used to 1032 * protect all related state. 1033 */ 1034 final Thread mProcessCpuThread; 1035 1036 /** 1037 * Used to collect process stats when showing not responding dialog. 1038 * Protected by mProcessCpuThread. 1039 */ 1040 final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker( 1041 MONITOR_THREAD_CPU_USAGE); 1042 final AtomicLong mLastCpuTime = new AtomicLong(0); 1043 final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true); 1044 1045 long mLastWriteTime = 0; 1046 1047 /** 1048 * Used to retain an update lock when the foreground activity is in 1049 * immersive mode. 1050 */ 1051 final UpdateLock mUpdateLock = new UpdateLock("immersive"); 1052 1053 /** 1054 * Set to true after the system has finished booting. 1055 */ 1056 boolean mBooted = false; 1057 1058 int mProcessLimit = ProcessList.MAX_CACHED_APPS; 1059 int mProcessLimitOverride = -1; 1060 1061 WindowManagerService mWindowManager; 1062 1063 final ActivityThread mSystemThread; 1064 1065 int mCurrentUserId = 0; 1066 int[] mCurrentProfileIds = new int[] {UserHandle.USER_OWNER}; // Accessed by ActivityStack 1067 private UserManagerService mUserManager; 1068 1069 private final class AppDeathRecipient implements IBinder.DeathRecipient { 1070 final ProcessRecord mApp; 1071 final int mPid; 1072 final IApplicationThread mAppThread; 1073 1074 AppDeathRecipient(ProcessRecord app, int pid, 1075 IApplicationThread thread) { 1076 if (localLOGV) Slog.v( 1077 TAG, "New death recipient " + this 1078 + " for thread " + thread.asBinder()); 1079 mApp = app; 1080 mPid = pid; 1081 mAppThread = thread; 1082 } 1083 1084 @Override 1085 public void binderDied() { 1086 if (localLOGV) Slog.v( 1087 TAG, "Death received in " + this 1088 + " for thread " + mAppThread.asBinder()); 1089 synchronized(ActivityManagerService.this) { 1090 appDiedLocked(mApp, mPid, mAppThread); 1091 } 1092 } 1093 } 1094 1095 static final int SHOW_ERROR_MSG = 1; 1096 static final int SHOW_NOT_RESPONDING_MSG = 2; 1097 static final int SHOW_FACTORY_ERROR_MSG = 3; 1098 static final int UPDATE_CONFIGURATION_MSG = 4; 1099 static final int GC_BACKGROUND_PROCESSES_MSG = 5; 1100 static final int WAIT_FOR_DEBUGGER_MSG = 6; 1101 static final int SERVICE_TIMEOUT_MSG = 12; 1102 static final int UPDATE_TIME_ZONE = 13; 1103 static final int SHOW_UID_ERROR_MSG = 14; 1104 static final int IM_FEELING_LUCKY_MSG = 15; 1105 static final int PROC_START_TIMEOUT_MSG = 20; 1106 static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21; 1107 static final int KILL_APPLICATION_MSG = 22; 1108 static final int FINALIZE_PENDING_INTENT_MSG = 23; 1109 static final int POST_HEAVY_NOTIFICATION_MSG = 24; 1110 static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25; 1111 static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26; 1112 static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27; 1113 static final int CLEAR_DNS_CACHE_MSG = 28; 1114 static final int UPDATE_HTTP_PROXY_MSG = 29; 1115 static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30; 1116 static final int DISPATCH_PROCESSES_CHANGED = 31; 1117 static final int DISPATCH_PROCESS_DIED = 32; 1118 static final int REPORT_MEM_USAGE_MSG = 33; 1119 static final int REPORT_USER_SWITCH_MSG = 34; 1120 static final int CONTINUE_USER_SWITCH_MSG = 35; 1121 static final int USER_SWITCH_TIMEOUT_MSG = 36; 1122 static final int IMMERSIVE_MODE_LOCK_MSG = 37; 1123 static final int PERSIST_URI_GRANTS_MSG = 38; 1124 static final int REQUEST_ALL_PSS_MSG = 39; 1125 static final int START_PROFILES_MSG = 40; 1126 static final int UPDATE_TIME = 41; 1127 static final int SYSTEM_USER_START_MSG = 42; 1128 static final int SYSTEM_USER_CURRENT_MSG = 43; 1129 1130 static final int FIRST_ACTIVITY_STACK_MSG = 100; 1131 static final int FIRST_BROADCAST_QUEUE_MSG = 200; 1132 static final int FIRST_COMPAT_MODE_MSG = 300; 1133 static final int FIRST_SUPERVISOR_STACK_MSG = 100; 1134 1135 AlertDialog mUidAlert; 1136 CompatModeDialog mCompatModeDialog; 1137 long mLastMemUsageReportTime = 0; 1138 1139 /** 1140 * Flag whether the current user is a "monkey", i.e. whether 1141 * the UI is driven by a UI automation tool. 1142 */ 1143 private boolean mUserIsMonkey; 1144 1145 final ServiceThread mHandlerThread; 1146 final MainHandler mHandler; 1147 1148 final class MainHandler extends Handler { 1149 public MainHandler(Looper looper) { 1150 super(looper, null, true); 1151 } 1152 1153 @Override 1154 public void handleMessage(Message msg) { 1155 switch (msg.what) { 1156 case SHOW_ERROR_MSG: { 1157 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1158 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), 1159 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; 1160 synchronized (ActivityManagerService.this) { 1161 ProcessRecord proc = (ProcessRecord)data.get("app"); 1162 AppErrorResult res = (AppErrorResult) data.get("result"); 1163 if (proc != null && proc.crashDialog != null) { 1164 Slog.e(TAG, "App already has crash dialog: " + proc); 1165 if (res != null) { 1166 res.set(0); 1167 } 1168 return; 1169 } 1170 if (!showBackground && UserHandle.getAppId(proc.uid) 1171 >= Process.FIRST_APPLICATION_UID && proc.userId != mCurrentUserId 1172 && proc.pid != MY_PID) { 1173 Slog.w(TAG, "Skipping crash dialog of " + proc + ": background"); 1174 if (res != null) { 1175 res.set(0); 1176 } 1177 return; 1178 } 1179 if (mShowDialogs && !mSleeping && !mShuttingDown) { 1180 Dialog d = new AppErrorDialog(mContext, 1181 ActivityManagerService.this, res, proc); 1182 d.show(); 1183 proc.crashDialog = d; 1184 } else { 1185 // The device is asleep, so just pretend that the user 1186 // saw a crash dialog and hit "force quit". 1187 if (res != null) { 1188 res.set(0); 1189 } 1190 } 1191 } 1192 1193 ensureBootCompleted(); 1194 } break; 1195 case SHOW_NOT_RESPONDING_MSG: { 1196 synchronized (ActivityManagerService.this) { 1197 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1198 ProcessRecord proc = (ProcessRecord)data.get("app"); 1199 if (proc != null && proc.anrDialog != null) { 1200 Slog.e(TAG, "App already has anr dialog: " + proc); 1201 return; 1202 } 1203 1204 Intent intent = new Intent("android.intent.action.ANR"); 1205 if (!mProcessesReady) { 1206 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 1207 | Intent.FLAG_RECEIVER_FOREGROUND); 1208 } 1209 broadcastIntentLocked(null, null, intent, 1210 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 1211 false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */); 1212 1213 if (mShowDialogs) { 1214 Dialog d = new AppNotRespondingDialog(ActivityManagerService.this, 1215 mContext, proc, (ActivityRecord)data.get("activity"), 1216 msg.arg1 != 0); 1217 d.show(); 1218 proc.anrDialog = d; 1219 } else { 1220 // Just kill the app if there is no dialog to be shown. 1221 killAppAtUsersRequest(proc, null); 1222 } 1223 } 1224 1225 ensureBootCompleted(); 1226 } break; 1227 case SHOW_STRICT_MODE_VIOLATION_MSG: { 1228 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1229 synchronized (ActivityManagerService.this) { 1230 ProcessRecord proc = (ProcessRecord) data.get("app"); 1231 if (proc == null) { 1232 Slog.e(TAG, "App not found when showing strict mode dialog."); 1233 break; 1234 } 1235 if (proc.crashDialog != null) { 1236 Slog.e(TAG, "App already has strict mode dialog: " + proc); 1237 return; 1238 } 1239 AppErrorResult res = (AppErrorResult) data.get("result"); 1240 if (mShowDialogs && !mSleeping && !mShuttingDown) { 1241 Dialog d = new StrictModeViolationDialog(mContext, 1242 ActivityManagerService.this, res, proc); 1243 d.show(); 1244 proc.crashDialog = d; 1245 } else { 1246 // The device is asleep, so just pretend that the user 1247 // saw a crash dialog and hit "force quit". 1248 res.set(0); 1249 } 1250 } 1251 ensureBootCompleted(); 1252 } break; 1253 case SHOW_FACTORY_ERROR_MSG: { 1254 Dialog d = new FactoryErrorDialog( 1255 mContext, msg.getData().getCharSequence("msg")); 1256 d.show(); 1257 ensureBootCompleted(); 1258 } break; 1259 case UPDATE_CONFIGURATION_MSG: { 1260 final ContentResolver resolver = mContext.getContentResolver(); 1261 Settings.System.putConfiguration(resolver, (Configuration)msg.obj); 1262 } break; 1263 case GC_BACKGROUND_PROCESSES_MSG: { 1264 synchronized (ActivityManagerService.this) { 1265 performAppGcsIfAppropriateLocked(); 1266 } 1267 } break; 1268 case WAIT_FOR_DEBUGGER_MSG: { 1269 synchronized (ActivityManagerService.this) { 1270 ProcessRecord app = (ProcessRecord)msg.obj; 1271 if (msg.arg1 != 0) { 1272 if (!app.waitedForDebugger) { 1273 Dialog d = new AppWaitingForDebuggerDialog( 1274 ActivityManagerService.this, 1275 mContext, app); 1276 app.waitDialog = d; 1277 app.waitedForDebugger = true; 1278 d.show(); 1279 } 1280 } else { 1281 if (app.waitDialog != null) { 1282 app.waitDialog.dismiss(); 1283 app.waitDialog = null; 1284 } 1285 } 1286 } 1287 } break; 1288 case SERVICE_TIMEOUT_MSG: { 1289 if (mDidDexOpt) { 1290 mDidDexOpt = false; 1291 Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG); 1292 nmsg.obj = msg.obj; 1293 mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT); 1294 return; 1295 } 1296 mServices.serviceTimeout((ProcessRecord)msg.obj); 1297 } break; 1298 case UPDATE_TIME_ZONE: { 1299 synchronized (ActivityManagerService.this) { 1300 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1301 ProcessRecord r = mLruProcesses.get(i); 1302 if (r.thread != null) { 1303 try { 1304 r.thread.updateTimeZone(); 1305 } catch (RemoteException ex) { 1306 Slog.w(TAG, "Failed to update time zone for: " + r.info.processName); 1307 } 1308 } 1309 } 1310 } 1311 } break; 1312 case CLEAR_DNS_CACHE_MSG: { 1313 synchronized (ActivityManagerService.this) { 1314 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1315 ProcessRecord r = mLruProcesses.get(i); 1316 if (r.thread != null) { 1317 try { 1318 r.thread.clearDnsCache(); 1319 } catch (RemoteException ex) { 1320 Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName); 1321 } 1322 } 1323 } 1324 } 1325 } break; 1326 case UPDATE_HTTP_PROXY_MSG: { 1327 ProxyInfo proxy = (ProxyInfo)msg.obj; 1328 String host = ""; 1329 String port = ""; 1330 String exclList = ""; 1331 String pacFileUrl = ""; 1332 if (proxy != null) { 1333 host = proxy.getHost(); 1334 port = Integer.toString(proxy.getPort()); 1335 exclList = proxy.getExclusionListAsString(); 1336 if (proxy.getPacFileUrl() != null) { 1337 pacFileUrl = proxy.getPacFileUrl().toString(); 1338 } 1339 } 1340 synchronized (ActivityManagerService.this) { 1341 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1342 ProcessRecord r = mLruProcesses.get(i); 1343 if (r.thread != null) { 1344 try { 1345 r.thread.setHttpProxy(host, port, exclList, pacFileUrl); 1346 } catch (RemoteException ex) { 1347 Slog.w(TAG, "Failed to update http proxy for: " + 1348 r.info.processName); 1349 } 1350 } 1351 } 1352 } 1353 } break; 1354 case SHOW_UID_ERROR_MSG: { 1355 String title = "System UIDs Inconsistent"; 1356 String text = "UIDs on the system are inconsistent, you need to wipe your" 1357 + " data partition or your device will be unstable."; 1358 Log.e(TAG, title + ": " + text); 1359 if (mShowDialogs) { 1360 // XXX This is a temporary dialog, no need to localize. 1361 AlertDialog d = new BaseErrorDialog(mContext); 1362 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR); 1363 d.setCancelable(false); 1364 d.setTitle(title); 1365 d.setMessage(text); 1366 d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky", 1367 mHandler.obtainMessage(IM_FEELING_LUCKY_MSG)); 1368 mUidAlert = d; 1369 d.show(); 1370 } 1371 } break; 1372 case IM_FEELING_LUCKY_MSG: { 1373 if (mUidAlert != null) { 1374 mUidAlert.dismiss(); 1375 mUidAlert = null; 1376 } 1377 } break; 1378 case PROC_START_TIMEOUT_MSG: { 1379 if (mDidDexOpt) { 1380 mDidDexOpt = false; 1381 Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 1382 nmsg.obj = msg.obj; 1383 mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT); 1384 return; 1385 } 1386 ProcessRecord app = (ProcessRecord)msg.obj; 1387 synchronized (ActivityManagerService.this) { 1388 processStartTimedOutLocked(app); 1389 } 1390 } break; 1391 case DO_PENDING_ACTIVITY_LAUNCHES_MSG: { 1392 synchronized (ActivityManagerService.this) { 1393 doPendingActivityLaunchesLocked(true); 1394 } 1395 } break; 1396 case KILL_APPLICATION_MSG: { 1397 synchronized (ActivityManagerService.this) { 1398 int appid = msg.arg1; 1399 boolean restart = (msg.arg2 == 1); 1400 Bundle bundle = (Bundle)msg.obj; 1401 String pkg = bundle.getString("pkg"); 1402 String reason = bundle.getString("reason"); 1403 forceStopPackageLocked(pkg, appid, restart, false, true, false, 1404 false, UserHandle.USER_ALL, reason); 1405 } 1406 } break; 1407 case FINALIZE_PENDING_INTENT_MSG: { 1408 ((PendingIntentRecord)msg.obj).completeFinalize(); 1409 } break; 1410 case POST_HEAVY_NOTIFICATION_MSG: { 1411 INotificationManager inm = NotificationManager.getService(); 1412 if (inm == null) { 1413 return; 1414 } 1415 1416 ActivityRecord root = (ActivityRecord)msg.obj; 1417 ProcessRecord process = root.app; 1418 if (process == null) { 1419 return; 1420 } 1421 1422 try { 1423 Context context = mContext.createPackageContext(process.info.packageName, 0); 1424 String text = mContext.getString(R.string.heavy_weight_notification, 1425 context.getApplicationInfo().loadLabel(context.getPackageManager())); 1426 Notification notification = new Notification(); 1427 notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon; 1428 notification.when = 0; 1429 notification.flags = Notification.FLAG_ONGOING_EVENT; 1430 notification.tickerText = text; 1431 notification.defaults = 0; // please be quiet 1432 notification.sound = null; 1433 notification.vibrate = null; 1434 notification.setLatestEventInfo(context, text, 1435 mContext.getText(R.string.heavy_weight_notification_detail), 1436 PendingIntent.getActivityAsUser(mContext, 0, root.intent, 1437 PendingIntent.FLAG_CANCEL_CURRENT, null, 1438 new UserHandle(root.userId))); 1439 1440 try { 1441 int[] outId = new int[1]; 1442 inm.enqueueNotificationWithTag("android", "android", null, 1443 R.string.heavy_weight_notification, 1444 notification, outId, root.userId); 1445 } catch (RuntimeException e) { 1446 Slog.w(ActivityManagerService.TAG, 1447 "Error showing notification for heavy-weight app", e); 1448 } catch (RemoteException e) { 1449 } 1450 } catch (NameNotFoundException e) { 1451 Slog.w(TAG, "Unable to create context for heavy notification", e); 1452 } 1453 } break; 1454 case CANCEL_HEAVY_NOTIFICATION_MSG: { 1455 INotificationManager inm = NotificationManager.getService(); 1456 if (inm == null) { 1457 return; 1458 } 1459 try { 1460 inm.cancelNotificationWithTag("android", null, 1461 R.string.heavy_weight_notification, msg.arg1); 1462 } catch (RuntimeException e) { 1463 Slog.w(ActivityManagerService.TAG, 1464 "Error canceling notification for service", e); 1465 } catch (RemoteException e) { 1466 } 1467 } break; 1468 case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: { 1469 synchronized (ActivityManagerService.this) { 1470 checkExcessivePowerUsageLocked(true); 1471 removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1472 Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1473 sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 1474 } 1475 } break; 1476 case SHOW_COMPAT_MODE_DIALOG_MSG: { 1477 synchronized (ActivityManagerService.this) { 1478 ActivityRecord ar = (ActivityRecord)msg.obj; 1479 if (mCompatModeDialog != null) { 1480 if (mCompatModeDialog.mAppInfo.packageName.equals( 1481 ar.info.applicationInfo.packageName)) { 1482 return; 1483 } 1484 mCompatModeDialog.dismiss(); 1485 mCompatModeDialog = null; 1486 } 1487 if (ar != null && false) { 1488 if (mCompatModePackages.getPackageAskCompatModeLocked( 1489 ar.packageName)) { 1490 int mode = mCompatModePackages.computeCompatModeLocked( 1491 ar.info.applicationInfo); 1492 if (mode == ActivityManager.COMPAT_MODE_DISABLED 1493 || mode == ActivityManager.COMPAT_MODE_ENABLED) { 1494 mCompatModeDialog = new CompatModeDialog( 1495 ActivityManagerService.this, mContext, 1496 ar.info.applicationInfo); 1497 mCompatModeDialog.show(); 1498 } 1499 } 1500 } 1501 } 1502 break; 1503 } 1504 case DISPATCH_PROCESSES_CHANGED: { 1505 dispatchProcessesChanged(); 1506 break; 1507 } 1508 case DISPATCH_PROCESS_DIED: { 1509 final int pid = msg.arg1; 1510 final int uid = msg.arg2; 1511 dispatchProcessDied(pid, uid); 1512 break; 1513 } 1514 case REPORT_MEM_USAGE_MSG: { 1515 final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj; 1516 Thread thread = new Thread() { 1517 @Override public void run() { 1518 final SparseArray<ProcessMemInfo> infoMap 1519 = new SparseArray<ProcessMemInfo>(memInfos.size()); 1520 for (int i=0, N=memInfos.size(); i<N; i++) { 1521 ProcessMemInfo mi = memInfos.get(i); 1522 infoMap.put(mi.pid, mi); 1523 } 1524 updateCpuStatsNow(); 1525 synchronized (mProcessCpuThread) { 1526 final int N = mProcessCpuTracker.countStats(); 1527 for (int i=0; i<N; i++) { 1528 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 1529 if (st.vsize > 0) { 1530 long pss = Debug.getPss(st.pid, null); 1531 if (pss > 0) { 1532 if (infoMap.indexOfKey(st.pid) < 0) { 1533 ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid, 1534 ProcessList.NATIVE_ADJ, -1, "native", null); 1535 mi.pss = pss; 1536 memInfos.add(mi); 1537 } 1538 } 1539 } 1540 } 1541 } 1542 1543 long totalPss = 0; 1544 for (int i=0, N=memInfos.size(); i<N; i++) { 1545 ProcessMemInfo mi = memInfos.get(i); 1546 if (mi.pss == 0) { 1547 mi.pss = Debug.getPss(mi.pid, null); 1548 } 1549 totalPss += mi.pss; 1550 } 1551 Collections.sort(memInfos, new Comparator<ProcessMemInfo>() { 1552 @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) { 1553 if (lhs.oomAdj != rhs.oomAdj) { 1554 return lhs.oomAdj < rhs.oomAdj ? -1 : 1; 1555 } 1556 if (lhs.pss != rhs.pss) { 1557 return lhs.pss < rhs.pss ? 1 : -1; 1558 } 1559 return 0; 1560 } 1561 }); 1562 1563 StringBuilder tag = new StringBuilder(128); 1564 StringBuilder stack = new StringBuilder(128); 1565 tag.append("Low on memory -- "); 1566 appendMemBucket(tag, totalPss, "total", false); 1567 appendMemBucket(stack, totalPss, "total", true); 1568 1569 StringBuilder logBuilder = new StringBuilder(1024); 1570 logBuilder.append("Low on memory:\n"); 1571 1572 boolean firstLine = true; 1573 int lastOomAdj = Integer.MIN_VALUE; 1574 for (int i=0, N=memInfos.size(); i<N; i++) { 1575 ProcessMemInfo mi = memInfos.get(i); 1576 1577 if (mi.oomAdj != ProcessList.NATIVE_ADJ 1578 && (mi.oomAdj < ProcessList.SERVICE_ADJ 1579 || mi.oomAdj == ProcessList.HOME_APP_ADJ 1580 || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) { 1581 if (lastOomAdj != mi.oomAdj) { 1582 lastOomAdj = mi.oomAdj; 1583 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) { 1584 tag.append(" / "); 1585 } 1586 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) { 1587 if (firstLine) { 1588 stack.append(":"); 1589 firstLine = false; 1590 } 1591 stack.append("\n\t at "); 1592 } else { 1593 stack.append("$"); 1594 } 1595 } else { 1596 tag.append(" "); 1597 stack.append("$"); 1598 } 1599 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) { 1600 appendMemBucket(tag, mi.pss, mi.name, false); 1601 } 1602 appendMemBucket(stack, mi.pss, mi.name, true); 1603 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ 1604 && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) { 1605 stack.append("("); 1606 for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) { 1607 if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) { 1608 stack.append(DUMP_MEM_OOM_LABEL[k]); 1609 stack.append(":"); 1610 stack.append(DUMP_MEM_OOM_ADJ[k]); 1611 } 1612 } 1613 stack.append(")"); 1614 } 1615 } 1616 1617 logBuilder.append(" "); 1618 logBuilder.append(ProcessList.makeOomAdjString(mi.oomAdj)); 1619 logBuilder.append(' '); 1620 logBuilder.append(ProcessList.makeProcStateString(mi.procState)); 1621 logBuilder.append(' '); 1622 ProcessList.appendRamKb(logBuilder, mi.pss); 1623 logBuilder.append(" kB: "); 1624 logBuilder.append(mi.name); 1625 logBuilder.append(" ("); 1626 logBuilder.append(mi.pid); 1627 logBuilder.append(") "); 1628 logBuilder.append(mi.adjType); 1629 logBuilder.append('\n'); 1630 if (mi.adjReason != null) { 1631 logBuilder.append(" "); 1632 logBuilder.append(mi.adjReason); 1633 logBuilder.append('\n'); 1634 } 1635 } 1636 1637 logBuilder.append(" "); 1638 ProcessList.appendRamKb(logBuilder, totalPss); 1639 logBuilder.append(" kB: TOTAL\n"); 1640 1641 long[] infos = new long[Debug.MEMINFO_COUNT]; 1642 Debug.getMemInfo(infos); 1643 logBuilder.append(" MemInfo: "); 1644 logBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, "); 1645 logBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, "); 1646 logBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, "); 1647 logBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, "); 1648 logBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n"); 1649 if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) { 1650 logBuilder.append(" ZRAM: "); 1651 logBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]); 1652 logBuilder.append(" kB RAM, "); 1653 logBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]); 1654 logBuilder.append(" kB swap total, "); 1655 logBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]); 1656 logBuilder.append(" kB swap free\n"); 1657 } 1658 Slog.i(TAG, logBuilder.toString()); 1659 1660 StringBuilder dropBuilder = new StringBuilder(1024); 1661 /* 1662 StringWriter oomSw = new StringWriter(); 1663 PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256); 1664 StringWriter catSw = new StringWriter(); 1665 PrintWriter catPw = new FastPrintWriter(catSw, false, 256); 1666 String[] emptyArgs = new String[] { }; 1667 dumpApplicationMemoryUsage(null, oomPw, " ", emptyArgs, true, catPw); 1668 oomPw.flush(); 1669 String oomString = oomSw.toString(); 1670 */ 1671 dropBuilder.append(stack); 1672 dropBuilder.append('\n'); 1673 dropBuilder.append('\n'); 1674 dropBuilder.append(logBuilder); 1675 dropBuilder.append('\n'); 1676 /* 1677 dropBuilder.append(oomString); 1678 dropBuilder.append('\n'); 1679 */ 1680 StringWriter catSw = new StringWriter(); 1681 synchronized (ActivityManagerService.this) { 1682 PrintWriter catPw = new FastPrintWriter(catSw, false, 256); 1683 String[] emptyArgs = new String[] { }; 1684 catPw.println(); 1685 dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null); 1686 catPw.println(); 1687 mServices.dumpServicesLocked(null, catPw, emptyArgs, 0, 1688 false, false, null); 1689 catPw.println(); 1690 dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null); 1691 catPw.flush(); 1692 } 1693 dropBuilder.append(catSw.toString()); 1694 addErrorToDropBox("lowmem", null, "system_server", null, 1695 null, tag.toString(), dropBuilder.toString(), null, null); 1696 //Slog.i(TAG, "Sent to dropbox:"); 1697 //Slog.i(TAG, dropBuilder.toString()); 1698 synchronized (ActivityManagerService.this) { 1699 long now = SystemClock.uptimeMillis(); 1700 if (mLastMemUsageReportTime < now) { 1701 mLastMemUsageReportTime = now; 1702 } 1703 } 1704 } 1705 }; 1706 thread.start(); 1707 break; 1708 } 1709 case REPORT_USER_SWITCH_MSG: { 1710 dispatchUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2); 1711 break; 1712 } 1713 case CONTINUE_USER_SWITCH_MSG: { 1714 continueUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2); 1715 break; 1716 } 1717 case USER_SWITCH_TIMEOUT_MSG: { 1718 timeoutUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2); 1719 break; 1720 } 1721 case IMMERSIVE_MODE_LOCK_MSG: { 1722 final boolean nextState = (msg.arg1 != 0); 1723 if (mUpdateLock.isHeld() != nextState) { 1724 if (DEBUG_IMMERSIVE) { 1725 final ActivityRecord r = (ActivityRecord) msg.obj; 1726 Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r); 1727 } 1728 if (nextState) { 1729 mUpdateLock.acquire(); 1730 } else { 1731 mUpdateLock.release(); 1732 } 1733 } 1734 break; 1735 } 1736 case PERSIST_URI_GRANTS_MSG: { 1737 writeGrantedUriPermissions(); 1738 break; 1739 } 1740 case REQUEST_ALL_PSS_MSG: { 1741 requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false); 1742 break; 1743 } 1744 case START_PROFILES_MSG: { 1745 synchronized (ActivityManagerService.this) { 1746 startProfilesLocked(); 1747 } 1748 break; 1749 } 1750 case UPDATE_TIME: { 1751 synchronized (ActivityManagerService.this) { 1752 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1753 ProcessRecord r = mLruProcesses.get(i); 1754 if (r.thread != null) { 1755 try { 1756 r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true); 1757 } catch (RemoteException ex) { 1758 Slog.w(TAG, "Failed to update preferences for: " + r.info.processName); 1759 } 1760 } 1761 } 1762 } 1763 break; 1764 } 1765 case SYSTEM_USER_START_MSG: { 1766 mSystemServiceManager.startUser(msg.arg1); 1767 break; 1768 } 1769 case SYSTEM_USER_CURRENT_MSG: { 1770 mSystemServiceManager.switchUser(msg.arg1); 1771 break; 1772 } 1773 } 1774 } 1775 }; 1776 1777 static final int COLLECT_PSS_BG_MSG = 1; 1778 1779 final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) { 1780 @Override 1781 public void handleMessage(Message msg) { 1782 switch (msg.what) { 1783 case COLLECT_PSS_BG_MSG: { 1784 int i=0, num=0; 1785 long start = SystemClock.uptimeMillis(); 1786 long[] tmp = new long[1]; 1787 do { 1788 ProcessRecord proc; 1789 int procState; 1790 int pid; 1791 synchronized (ActivityManagerService.this) { 1792 if (i >= mPendingPssProcesses.size()) { 1793 if (DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num + " of " + i 1794 + " processes in " + (SystemClock.uptimeMillis()-start) + "ms"); 1795 mPendingPssProcesses.clear(); 1796 return; 1797 } 1798 proc = mPendingPssProcesses.get(i); 1799 procState = proc.pssProcState; 1800 if (proc.thread != null && procState == proc.setProcState) { 1801 pid = proc.pid; 1802 } else { 1803 proc = null; 1804 pid = 0; 1805 } 1806 i++; 1807 } 1808 if (proc != null) { 1809 long pss = Debug.getPss(pid, tmp); 1810 synchronized (ActivityManagerService.this) { 1811 if (proc.thread != null && proc.setProcState == procState 1812 && proc.pid == pid) { 1813 num++; 1814 proc.lastPssTime = SystemClock.uptimeMillis(); 1815 proc.baseProcessTracker.addPss(pss, tmp[0], true, proc.pkgList); 1816 if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString() 1817 + ": " + pss + " lastPss=" + proc.lastPss 1818 + " state=" + ProcessList.makeProcStateString(procState)); 1819 if (proc.initialIdlePss == 0) { 1820 proc.initialIdlePss = pss; 1821 } 1822 proc.lastPss = pss; 1823 if (procState >= ActivityManager.PROCESS_STATE_HOME) { 1824 proc.lastCachedPss = pss; 1825 } 1826 } 1827 } 1828 } 1829 } while (true); 1830 } 1831 } 1832 } 1833 }; 1834 1835 /** 1836 * Monitor for package changes and update our internal state. 1837 */ 1838 private final PackageMonitor mPackageMonitor = new PackageMonitor() { 1839 @Override 1840 public void onPackageRemoved(String packageName, int uid) { 1841 // Remove all tasks with activities in the specified package from the list of recent tasks 1842 synchronized (ActivityManagerService.this) { 1843 for (int i = mRecentTasks.size() - 1; i >= 0; i--) { 1844 TaskRecord tr = mRecentTasks.get(i); 1845 ComponentName cn = tr.intent.getComponent(); 1846 if (cn != null && cn.getPackageName().equals(packageName)) { 1847 // If the package name matches, remove the task and kill the process 1848 removeTaskByIdLocked(tr.taskId, ActivityManager.REMOVE_TASK_KILL_PROCESS); 1849 } 1850 } 1851 } 1852 } 1853 1854 @Override 1855 public boolean onPackageChanged(String packageName, int uid, String[] components) { 1856 onPackageModified(packageName); 1857 return true; 1858 } 1859 1860 @Override 1861 public void onPackageModified(String packageName) { 1862 final PackageManager pm = mContext.getPackageManager(); 1863 final ArrayList<Pair<Intent, Integer>> recentTaskIntents = 1864 new ArrayList<Pair<Intent, Integer>>(); 1865 final ArrayList<Integer> tasksToRemove = new ArrayList<Integer>(); 1866 // Copy the list of recent tasks so that we don't hold onto the lock on 1867 // ActivityManagerService for long periods while checking if components exist. 1868 synchronized (ActivityManagerService.this) { 1869 for (int i = mRecentTasks.size() - 1; i >= 0; i--) { 1870 TaskRecord tr = mRecentTasks.get(i); 1871 recentTaskIntents.add(new Pair<Intent, Integer>(tr.intent, tr.taskId)); 1872 } 1873 } 1874 // Check the recent tasks and filter out all tasks with components that no longer exist. 1875 Intent tmpI = new Intent(); 1876 for (int i = recentTaskIntents.size() - 1; i >= 0; i--) { 1877 Pair<Intent, Integer> p = recentTaskIntents.get(i); 1878 ComponentName cn = p.first.getComponent(); 1879 if (cn != null && cn.getPackageName().equals(packageName)) { 1880 try { 1881 // Add the task to the list to remove if the component no longer exists 1882 tmpI.setComponent(cn); 1883 if (pm.queryIntentActivities(tmpI, PackageManager.MATCH_DEFAULT_ONLY).isEmpty()) { 1884 tasksToRemove.add(p.second); 1885 } 1886 } catch (Exception e) {} 1887 } 1888 } 1889 // Prune all the tasks with removed components from the list of recent tasks 1890 synchronized (ActivityManagerService.this) { 1891 for (int i = tasksToRemove.size() - 1; i >= 0; i--) { 1892 // Remove the task but don't kill the process (since other components in that 1893 // package may still be running and in the background) 1894 removeTaskByIdLocked(tasksToRemove.get(i), 0); 1895 } 1896 } 1897 } 1898 1899 @Override 1900 public boolean onHandleForceStop(Intent intent, String[] packages, int uid, boolean doit) { 1901 // Force stop the specified packages 1902 if (packages != null) { 1903 for (String pkg : packages) { 1904 synchronized (ActivityManagerService.this) { 1905 if (forceStopPackageLocked(pkg, -1, false, false, false, false, false, 0, 1906 "finished booting")) { 1907 return true; 1908 } 1909 } 1910 } 1911 } 1912 return false; 1913 } 1914 }; 1915 1916 public void setSystemProcess() { 1917 try { 1918 ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true); 1919 ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats); 1920 ServiceManager.addService("meminfo", new MemBinder(this)); 1921 ServiceManager.addService("gfxinfo", new GraphicsBinder(this)); 1922 ServiceManager.addService("dbinfo", new DbBinder(this)); 1923 if (MONITOR_CPU_USAGE) { 1924 ServiceManager.addService("cpuinfo", new CpuBinder(this)); 1925 } 1926 ServiceManager.addService("permission", new PermissionController(this)); 1927 1928 ApplicationInfo info = mContext.getPackageManager().getApplicationInfo( 1929 "android", STOCK_PM_FLAGS); 1930 mSystemThread.installSystemApplicationInfo(info); 1931 1932 synchronized (this) { 1933 ProcessRecord app = newProcessRecordLocked(info, info.processName, false); 1934 app.persistent = true; 1935 app.pid = MY_PID; 1936 app.maxAdj = ProcessList.SYSTEM_ADJ; 1937 app.makeActive(mSystemThread.getApplicationThread(), mProcessStats); 1938 mProcessNames.put(app.processName, app.uid, app); 1939 synchronized (mPidsSelfLocked) { 1940 mPidsSelfLocked.put(app.pid, app); 1941 } 1942 updateLruProcessLocked(app, false, null); 1943 updateOomAdjLocked(); 1944 } 1945 } catch (PackageManager.NameNotFoundException e) { 1946 throw new RuntimeException( 1947 "Unable to find android system package", e); 1948 } 1949 } 1950 1951 public void setWindowManager(WindowManagerService wm) { 1952 mWindowManager = wm; 1953 mStackSupervisor.setWindowManager(wm); 1954 } 1955 1956 public void startObservingNativeCrashes() { 1957 final NativeCrashListener ncl = new NativeCrashListener(this); 1958 ncl.start(); 1959 } 1960 1961 public IAppOpsService getAppOpsService() { 1962 return mAppOpsService; 1963 } 1964 1965 static class MemBinder extends Binder { 1966 ActivityManagerService mActivityManagerService; 1967 MemBinder(ActivityManagerService activityManagerService) { 1968 mActivityManagerService = activityManagerService; 1969 } 1970 1971 @Override 1972 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1973 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1974 != PackageManager.PERMISSION_GRANTED) { 1975 pw.println("Permission Denial: can't dump meminfo from from pid=" 1976 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1977 + " without permission " + android.Manifest.permission.DUMP); 1978 return; 1979 } 1980 1981 mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, " ", args, false, null); 1982 } 1983 } 1984 1985 static class GraphicsBinder extends Binder { 1986 ActivityManagerService mActivityManagerService; 1987 GraphicsBinder(ActivityManagerService activityManagerService) { 1988 mActivityManagerService = activityManagerService; 1989 } 1990 1991 @Override 1992 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1993 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1994 != PackageManager.PERMISSION_GRANTED) { 1995 pw.println("Permission Denial: can't dump gfxinfo from from pid=" 1996 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1997 + " without permission " + android.Manifest.permission.DUMP); 1998 return; 1999 } 2000 2001 mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args); 2002 } 2003 } 2004 2005 static class DbBinder extends Binder { 2006 ActivityManagerService mActivityManagerService; 2007 DbBinder(ActivityManagerService activityManagerService) { 2008 mActivityManagerService = activityManagerService; 2009 } 2010 2011 @Override 2012 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 2013 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 2014 != PackageManager.PERMISSION_GRANTED) { 2015 pw.println("Permission Denial: can't dump dbinfo from from pid=" 2016 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 2017 + " without permission " + android.Manifest.permission.DUMP); 2018 return; 2019 } 2020 2021 mActivityManagerService.dumpDbInfo(fd, pw, args); 2022 } 2023 } 2024 2025 static class CpuBinder extends Binder { 2026 ActivityManagerService mActivityManagerService; 2027 CpuBinder(ActivityManagerService activityManagerService) { 2028 mActivityManagerService = activityManagerService; 2029 } 2030 2031 @Override 2032 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 2033 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 2034 != PackageManager.PERMISSION_GRANTED) { 2035 pw.println("Permission Denial: can't dump cpuinfo from from pid=" 2036 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 2037 + " without permission " + android.Manifest.permission.DUMP); 2038 return; 2039 } 2040 2041 synchronized (mActivityManagerService.mProcessCpuThread) { 2042 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad()); 2043 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState( 2044 SystemClock.uptimeMillis())); 2045 } 2046 } 2047 } 2048 2049 public static final class Lifecycle extends SystemService { 2050 private final ActivityManagerService mService; 2051 2052 public Lifecycle(Context context) { 2053 super(context); 2054 mService = new ActivityManagerService(context); 2055 } 2056 2057 @Override 2058 public void onStart() { 2059 mService.start(); 2060 } 2061 2062 public ActivityManagerService getService() { 2063 return mService; 2064 } 2065 } 2066 2067 // Note: This method is invoked on the main thread but may need to attach various 2068 // handlers to other threads. So take care to be explicit about the looper. 2069 public ActivityManagerService(Context systemContext) { 2070 mContext = systemContext; 2071 mFactoryTest = FactoryTest.getMode(); 2072 mSystemThread = ActivityThread.currentActivityThread(); 2073 2074 Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass()); 2075 2076 mHandlerThread = new ServiceThread(TAG, 2077 android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/); 2078 mHandlerThread.start(); 2079 mHandler = new MainHandler(mHandlerThread.getLooper()); 2080 2081 mFgBroadcastQueue = new BroadcastQueue(this, mHandler, 2082 "foreground", BROADCAST_FG_TIMEOUT, false); 2083 mBgBroadcastQueue = new BroadcastQueue(this, mHandler, 2084 "background", BROADCAST_BG_TIMEOUT, true); 2085 mBroadcastQueues[0] = mFgBroadcastQueue; 2086 mBroadcastQueues[1] = mBgBroadcastQueue; 2087 2088 mServices = new ActiveServices(this); 2089 mProviderMap = new ProviderMap(this); 2090 2091 // TODO: Move creation of battery stats service outside of activity manager service. 2092 File dataDir = Environment.getDataDirectory(); 2093 File systemDir = new File(dataDir, "system"); 2094 systemDir.mkdirs(); 2095 mBatteryStatsService = new BatteryStatsService(new File( 2096 systemDir, "batterystats.bin").toString(), mHandler); 2097 mBatteryStatsService.getActiveStatistics().readLocked(); 2098 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 2099 mOnBattery = DEBUG_POWER ? true 2100 : mBatteryStatsService.getActiveStatistics().getIsOnBattery(); 2101 mBatteryStatsService.getActiveStatistics().setCallback(this); 2102 2103 mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats")); 2104 2105 mUsageStatsService = new UsageStatsService(new File(systemDir, "usagestats").toString()); 2106 mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler); 2107 2108 mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml")); 2109 2110 // User 0 is the first and only user that runs at boot. 2111 mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true)); 2112 mUserLru.add(Integer.valueOf(0)); 2113 updateStartedUserArrayLocked(); 2114 2115 GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version", 2116 ConfigurationInfo.GL_ES_VERSION_UNDEFINED); 2117 2118 mConfiguration.setToDefaults(); 2119 mConfiguration.setLocale(Locale.getDefault()); 2120 2121 mConfigurationSeq = mConfiguration.seq = 1; 2122 mProcessCpuTracker.init(); 2123 2124 mCompatModePackages = new CompatModePackages(this, systemDir, mHandler); 2125 mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler); 2126 mStackSupervisor = new ActivityStackSupervisor(this); 2127 2128 mProcessCpuThread = new Thread("CpuTracker") { 2129 @Override 2130 public void run() { 2131 while (true) { 2132 try { 2133 try { 2134 synchronized(this) { 2135 final long now = SystemClock.uptimeMillis(); 2136 long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now; 2137 long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now; 2138 //Slog.i(TAG, "Cpu delay=" + nextCpuDelay 2139 // + ", write delay=" + nextWriteDelay); 2140 if (nextWriteDelay < nextCpuDelay) { 2141 nextCpuDelay = nextWriteDelay; 2142 } 2143 if (nextCpuDelay > 0) { 2144 mProcessCpuMutexFree.set(true); 2145 this.wait(nextCpuDelay); 2146 } 2147 } 2148 } catch (InterruptedException e) { 2149 } 2150 updateCpuStatsNow(); 2151 } catch (Exception e) { 2152 Slog.e(TAG, "Unexpected exception collecting process stats", e); 2153 } 2154 } 2155 } 2156 }; 2157 2158 Watchdog.getInstance().addMonitor(this); 2159 Watchdog.getInstance().addThread(mHandler); 2160 } 2161 2162 public void setSystemServiceManager(SystemServiceManager mgr) { 2163 mSystemServiceManager = mgr; 2164 } 2165 2166 private void start() { 2167 mProcessCpuThread.start(); 2168 2169 mBatteryStatsService.publish(mContext); 2170 mUsageStatsService.publish(mContext); 2171 mAppOpsService.publish(mContext); 2172 2173 LocalServices.addService(ActivityManagerInternal.class, new LocalService()); 2174 } 2175 2176 @Override 2177 public boolean onTransact(int code, Parcel data, Parcel reply, int flags) 2178 throws RemoteException { 2179 if (code == SYSPROPS_TRANSACTION) { 2180 // We need to tell all apps about the system property change. 2181 ArrayList<IBinder> procs = new ArrayList<IBinder>(); 2182 synchronized(this) { 2183 final int NP = mProcessNames.getMap().size(); 2184 for (int ip=0; ip<NP; ip++) { 2185 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 2186 final int NA = apps.size(); 2187 for (int ia=0; ia<NA; ia++) { 2188 ProcessRecord app = apps.valueAt(ia); 2189 if (app.thread != null) { 2190 procs.add(app.thread.asBinder()); 2191 } 2192 } 2193 } 2194 } 2195 2196 int N = procs.size(); 2197 for (int i=0; i<N; i++) { 2198 Parcel data2 = Parcel.obtain(); 2199 try { 2200 procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0); 2201 } catch (RemoteException e) { 2202 } 2203 data2.recycle(); 2204 } 2205 } 2206 try { 2207 return super.onTransact(code, data, reply, flags); 2208 } catch (RuntimeException e) { 2209 // The activity manager only throws security exceptions, so let's 2210 // log all others. 2211 if (!(e instanceof SecurityException)) { 2212 Slog.wtf(TAG, "Activity Manager Crash", e); 2213 } 2214 throw e; 2215 } 2216 } 2217 2218 void updateCpuStats() { 2219 final long now = SystemClock.uptimeMillis(); 2220 if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) { 2221 return; 2222 } 2223 if (mProcessCpuMutexFree.compareAndSet(true, false)) { 2224 synchronized (mProcessCpuThread) { 2225 mProcessCpuThread.notify(); 2226 } 2227 } 2228 } 2229 2230 void updateCpuStatsNow() { 2231 synchronized (mProcessCpuThread) { 2232 mProcessCpuMutexFree.set(false); 2233 final long now = SystemClock.uptimeMillis(); 2234 boolean haveNewCpuStats = false; 2235 2236 if (MONITOR_CPU_USAGE && 2237 mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) { 2238 mLastCpuTime.set(now); 2239 haveNewCpuStats = true; 2240 mProcessCpuTracker.update(); 2241 //Slog.i(TAG, mProcessCpu.printCurrentState()); 2242 //Slog.i(TAG, "Total CPU usage: " 2243 // + mProcessCpu.getTotalCpuPercent() + "%"); 2244 2245 // Slog the cpu usage if the property is set. 2246 if ("true".equals(SystemProperties.get("events.cpu"))) { 2247 int user = mProcessCpuTracker.getLastUserTime(); 2248 int system = mProcessCpuTracker.getLastSystemTime(); 2249 int iowait = mProcessCpuTracker.getLastIoWaitTime(); 2250 int irq = mProcessCpuTracker.getLastIrqTime(); 2251 int softIrq = mProcessCpuTracker.getLastSoftIrqTime(); 2252 int idle = mProcessCpuTracker.getLastIdleTime(); 2253 2254 int total = user + system + iowait + irq + softIrq + idle; 2255 if (total == 0) total = 1; 2256 2257 EventLog.writeEvent(EventLogTags.CPU, 2258 ((user+system+iowait+irq+softIrq) * 100) / total, 2259 (user * 100) / total, 2260 (system * 100) / total, 2261 (iowait * 100) / total, 2262 (irq * 100) / total, 2263 (softIrq * 100) / total); 2264 } 2265 } 2266 2267 long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes(); 2268 final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics(); 2269 synchronized(bstats) { 2270 synchronized(mPidsSelfLocked) { 2271 if (haveNewCpuStats) { 2272 if (mOnBattery) { 2273 int perc = bstats.startAddingCpuLocked(); 2274 int totalUTime = 0; 2275 int totalSTime = 0; 2276 final int N = mProcessCpuTracker.countStats(); 2277 for (int i=0; i<N; i++) { 2278 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 2279 if (!st.working) { 2280 continue; 2281 } 2282 ProcessRecord pr = mPidsSelfLocked.get(st.pid); 2283 int otherUTime = (st.rel_utime*perc)/100; 2284 int otherSTime = (st.rel_stime*perc)/100; 2285 totalUTime += otherUTime; 2286 totalSTime += otherSTime; 2287 if (pr != null) { 2288 BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats; 2289 if (ps == null || !ps.isActive()) { 2290 pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked( 2291 pr.info.uid, pr.processName); 2292 } 2293 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 2294 st.rel_stime-otherSTime); 2295 ps.addSpeedStepTimes(cpuSpeedTimes); 2296 pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10; 2297 } else { 2298 BatteryStatsImpl.Uid.Proc ps = st.batteryStats; 2299 if (ps == null || !ps.isActive()) { 2300 st.batteryStats = ps = bstats.getProcessStatsLocked( 2301 bstats.mapUid(st.uid), st.name); 2302 } 2303 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 2304 st.rel_stime-otherSTime); 2305 ps.addSpeedStepTimes(cpuSpeedTimes); 2306 } 2307 } 2308 bstats.finishAddingCpuLocked(perc, totalUTime, 2309 totalSTime, cpuSpeedTimes); 2310 } 2311 } 2312 } 2313 2314 if (mLastWriteTime < (now-BATTERY_STATS_TIME)) { 2315 mLastWriteTime = now; 2316 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 2317 } 2318 } 2319 } 2320 } 2321 2322 @Override 2323 public void batteryNeedsCpuUpdate() { 2324 updateCpuStatsNow(); 2325 } 2326 2327 @Override 2328 public void batteryPowerChanged(boolean onBattery) { 2329 // When plugging in, update the CPU stats first before changing 2330 // the plug state. 2331 updateCpuStatsNow(); 2332 synchronized (this) { 2333 synchronized(mPidsSelfLocked) { 2334 mOnBattery = DEBUG_POWER ? true : onBattery; 2335 } 2336 } 2337 } 2338 2339 /** 2340 * Initialize the application bind args. These are passed to each 2341 * process when the bindApplication() IPC is sent to the process. They're 2342 * lazily setup to make sure the services are running when they're asked for. 2343 */ 2344 private HashMap<String, IBinder> getCommonServicesLocked() { 2345 if (mAppBindArgs == null) { 2346 mAppBindArgs = new HashMap<String, IBinder>(); 2347 2348 // Setup the application init args 2349 mAppBindArgs.put("package", ServiceManager.getService("package")); 2350 mAppBindArgs.put("window", ServiceManager.getService("window")); 2351 mAppBindArgs.put(Context.ALARM_SERVICE, 2352 ServiceManager.getService(Context.ALARM_SERVICE)); 2353 } 2354 return mAppBindArgs; 2355 } 2356 2357 final void setFocusedActivityLocked(ActivityRecord r) { 2358 if (mFocusedActivity != r) { 2359 if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r); 2360 mFocusedActivity = r; 2361 if (r.task != null && r.task.voiceInteractor != null) { 2362 startRunningVoiceLocked(); 2363 } else { 2364 finishRunningVoiceLocked(); 2365 } 2366 mStackSupervisor.setFocusedStack(r); 2367 if (r != null) { 2368 mWindowManager.setFocusedApp(r.appToken, true); 2369 } 2370 applyUpdateLockStateLocked(r); 2371 } 2372 } 2373 2374 final void clearFocusedActivity(ActivityRecord r) { 2375 if (mFocusedActivity == r) { 2376 mFocusedActivity = null; 2377 } 2378 } 2379 2380 @Override 2381 public void setFocusedStack(int stackId) { 2382 if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId); 2383 synchronized (ActivityManagerService.this) { 2384 ActivityStack stack = mStackSupervisor.getStack(stackId); 2385 if (stack != null) { 2386 ActivityRecord r = stack.topRunningActivityLocked(null); 2387 if (r != null) { 2388 setFocusedActivityLocked(r); 2389 } 2390 } 2391 } 2392 } 2393 2394 @Override 2395 public void notifyActivityDrawn(IBinder token) { 2396 if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token); 2397 synchronized (this) { 2398 ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token); 2399 if (r != null) { 2400 r.task.stack.notifyActivityDrawnLocked(r); 2401 } 2402 } 2403 } 2404 2405 final void applyUpdateLockStateLocked(ActivityRecord r) { 2406 // Modifications to the UpdateLock state are done on our handler, outside 2407 // the activity manager's locks. The new state is determined based on the 2408 // state *now* of the relevant activity record. The object is passed to 2409 // the handler solely for logging detail, not to be consulted/modified. 2410 final boolean nextState = r != null && r.immersive; 2411 mHandler.sendMessage( 2412 mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r)); 2413 } 2414 2415 final void showAskCompatModeDialogLocked(ActivityRecord r) { 2416 Message msg = Message.obtain(); 2417 msg.what = SHOW_COMPAT_MODE_DIALOG_MSG; 2418 msg.obj = r.task.askedCompatMode ? null : r; 2419 mHandler.sendMessage(msg); 2420 } 2421 2422 private final int updateLruProcessInternalLocked(ProcessRecord app, long now, int index, 2423 String what, Object obj, ProcessRecord srcApp) { 2424 app.lastActivityTime = now; 2425 2426 if (app.activities.size() > 0) { 2427 // Don't want to touch dependent processes that are hosting activities. 2428 return index; 2429 } 2430 2431 int lrui = mLruProcesses.lastIndexOf(app); 2432 if (lrui < 0) { 2433 Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: " 2434 + what + " " + obj + " from " + srcApp); 2435 return index; 2436 } 2437 2438 if (lrui >= index) { 2439 // Don't want to cause this to move dependent processes *back* in the 2440 // list as if they were less frequently used. 2441 return index; 2442 } 2443 2444 if (lrui >= mLruProcessActivityStart) { 2445 // Don't want to touch dependent processes that are hosting activities. 2446 return index; 2447 } 2448 2449 mLruProcesses.remove(lrui); 2450 if (index > 0) { 2451 index--; 2452 } 2453 if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index 2454 + " in LRU list: " + app); 2455 mLruProcesses.add(index, app); 2456 return index; 2457 } 2458 2459 final void removeLruProcessLocked(ProcessRecord app) { 2460 int lrui = mLruProcesses.lastIndexOf(app); 2461 if (lrui >= 0) { 2462 if (lrui <= mLruProcessActivityStart) { 2463 mLruProcessActivityStart--; 2464 } 2465 if (lrui <= mLruProcessServiceStart) { 2466 mLruProcessServiceStart--; 2467 } 2468 mLruProcesses.remove(lrui); 2469 } 2470 } 2471 2472 final void updateLruProcessLocked(ProcessRecord app, boolean activityChange, 2473 ProcessRecord client) { 2474 final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities 2475 || app.treatLikeActivity; 2476 final boolean hasService = false; // not impl yet. app.services.size() > 0; 2477 if (!activityChange && hasActivity) { 2478 // The process has activities, so we are only allowing activity-based adjustments 2479 // to move it. It should be kept in the front of the list with other 2480 // processes that have activities, and we don't want those to change their 2481 // order except due to activity operations. 2482 return; 2483 } 2484 2485 mLruSeq++; 2486 final long now = SystemClock.uptimeMillis(); 2487 app.lastActivityTime = now; 2488 2489 // First a quick reject: if the app is already at the position we will 2490 // put it, then there is nothing to do. 2491 if (hasActivity) { 2492 final int N = mLruProcesses.size(); 2493 if (N > 0 && mLruProcesses.get(N-1) == app) { 2494 if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app); 2495 return; 2496 } 2497 } else { 2498 if (mLruProcessServiceStart > 0 2499 && mLruProcesses.get(mLruProcessServiceStart-1) == app) { 2500 if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app); 2501 return; 2502 } 2503 } 2504 2505 int lrui = mLruProcesses.lastIndexOf(app); 2506 2507 if (app.persistent && lrui >= 0) { 2508 // We don't care about the position of persistent processes, as long as 2509 // they are in the list. 2510 if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app); 2511 return; 2512 } 2513 2514 /* In progress: compute new position first, so we can avoid doing work 2515 if the process is not actually going to move. Not yet working. 2516 int addIndex; 2517 int nextIndex; 2518 boolean inActivity = false, inService = false; 2519 if (hasActivity) { 2520 // Process has activities, put it at the very tipsy-top. 2521 addIndex = mLruProcesses.size(); 2522 nextIndex = mLruProcessServiceStart; 2523 inActivity = true; 2524 } else if (hasService) { 2525 // Process has services, put it at the top of the service list. 2526 addIndex = mLruProcessActivityStart; 2527 nextIndex = mLruProcessServiceStart; 2528 inActivity = true; 2529 inService = true; 2530 } else { 2531 // Process not otherwise of interest, it goes to the top of the non-service area. 2532 addIndex = mLruProcessServiceStart; 2533 if (client != null) { 2534 int clientIndex = mLruProcesses.lastIndexOf(client); 2535 if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating " 2536 + app); 2537 if (clientIndex >= 0 && addIndex > clientIndex) { 2538 addIndex = clientIndex; 2539 } 2540 } 2541 nextIndex = addIndex > 0 ? addIndex-1 : addIndex; 2542 } 2543 2544 Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act=" 2545 + mLruProcessActivityStart + "): " + app); 2546 */ 2547 2548 if (lrui >= 0) { 2549 if (lrui < mLruProcessActivityStart) { 2550 mLruProcessActivityStart--; 2551 } 2552 if (lrui < mLruProcessServiceStart) { 2553 mLruProcessServiceStart--; 2554 } 2555 /* 2556 if (addIndex > lrui) { 2557 addIndex--; 2558 } 2559 if (nextIndex > lrui) { 2560 nextIndex--; 2561 } 2562 */ 2563 mLruProcesses.remove(lrui); 2564 } 2565 2566 /* 2567 mLruProcesses.add(addIndex, app); 2568 if (inActivity) { 2569 mLruProcessActivityStart++; 2570 } 2571 if (inService) { 2572 mLruProcessActivityStart++; 2573 } 2574 */ 2575 2576 int nextIndex; 2577 if (hasActivity) { 2578 final int N = mLruProcesses.size(); 2579 if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) { 2580 // Process doesn't have activities, but has clients with 2581 // activities... move it up, but one below the top (the top 2582 // should always have a real activity). 2583 if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app); 2584 mLruProcesses.add(N-1, app); 2585 // To keep it from spamming the LRU list (by making a bunch of clients), 2586 // we will push down any other entries owned by the app. 2587 final int uid = app.info.uid; 2588 for (int i=N-2; i>mLruProcessActivityStart; i--) { 2589 ProcessRecord subProc = mLruProcesses.get(i); 2590 if (subProc.info.uid == uid) { 2591 // We want to push this one down the list. If the process after 2592 // it is for the same uid, however, don't do so, because we don't 2593 // want them internally to be re-ordered. 2594 if (mLruProcesses.get(i-1).info.uid != uid) { 2595 if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i 2596 + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1)); 2597 ProcessRecord tmp = mLruProcesses.get(i); 2598 mLruProcesses.set(i, mLruProcesses.get(i-1)); 2599 mLruProcesses.set(i-1, tmp); 2600 i--; 2601 } 2602 } else { 2603 // A gap, we can stop here. 2604 break; 2605 } 2606 } 2607 } else { 2608 // Process has activities, put it at the very tipsy-top. 2609 if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app); 2610 mLruProcesses.add(app); 2611 } 2612 nextIndex = mLruProcessServiceStart; 2613 } else if (hasService) { 2614 // Process has services, put it at the top of the service list. 2615 if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app); 2616 mLruProcesses.add(mLruProcessActivityStart, app); 2617 nextIndex = mLruProcessServiceStart; 2618 mLruProcessActivityStart++; 2619 } else { 2620 // Process not otherwise of interest, it goes to the top of the non-service area. 2621 int index = mLruProcessServiceStart; 2622 if (client != null) { 2623 // If there is a client, don't allow the process to be moved up higher 2624 // in the list than that client. 2625 int clientIndex = mLruProcesses.lastIndexOf(client); 2626 if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client 2627 + " when updating " + app); 2628 if (clientIndex <= lrui) { 2629 // Don't allow the client index restriction to push it down farther in the 2630 // list than it already is. 2631 clientIndex = lrui; 2632 } 2633 if (clientIndex >= 0 && index > clientIndex) { 2634 index = clientIndex; 2635 } 2636 } 2637 if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app); 2638 mLruProcesses.add(index, app); 2639 nextIndex = index-1; 2640 mLruProcessActivityStart++; 2641 mLruProcessServiceStart++; 2642 } 2643 2644 // If the app is currently using a content provider or service, 2645 // bump those processes as well. 2646 for (int j=app.connections.size()-1; j>=0; j--) { 2647 ConnectionRecord cr = app.connections.valueAt(j); 2648 if (cr.binding != null && !cr.serviceDead && cr.binding.service != null 2649 && cr.binding.service.app != null 2650 && cr.binding.service.app.lruSeq != mLruSeq 2651 && !cr.binding.service.app.persistent) { 2652 nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex, 2653 "service connection", cr, app); 2654 } 2655 } 2656 for (int j=app.conProviders.size()-1; j>=0; j--) { 2657 ContentProviderRecord cpr = app.conProviders.get(j).provider; 2658 if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) { 2659 nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex, 2660 "provider reference", cpr, app); 2661 } 2662 } 2663 } 2664 2665 final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) { 2666 if (uid == Process.SYSTEM_UID) { 2667 // The system gets to run in any process. If there are multiple 2668 // processes with the same uid, just pick the first (this 2669 // should never happen). 2670 SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName); 2671 if (procs == null) return null; 2672 final int N = procs.size(); 2673 for (int i = 0; i < N; i++) { 2674 if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i); 2675 } 2676 } 2677 ProcessRecord proc = mProcessNames.get(processName, uid); 2678 if (false && proc != null && !keepIfLarge 2679 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY 2680 && proc.lastCachedPss >= 4000) { 2681 // Turn this condition on to cause killing to happen regularly, for testing. 2682 if (proc.baseProcessTracker != null) { 2683 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss); 2684 } 2685 killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss) 2686 + "k from cached"); 2687 } else if (proc != null && !keepIfLarge 2688 && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL 2689 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) { 2690 if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss); 2691 if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) { 2692 if (proc.baseProcessTracker != null) { 2693 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss); 2694 } 2695 killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss) 2696 + "k from cached"); 2697 } 2698 } 2699 return proc; 2700 } 2701 2702 void ensurePackageDexOpt(String packageName) { 2703 IPackageManager pm = AppGlobals.getPackageManager(); 2704 try { 2705 if (pm.performDexOpt(packageName)) { 2706 mDidDexOpt = true; 2707 } 2708 } catch (RemoteException e) { 2709 } 2710 } 2711 2712 boolean isNextTransitionForward() { 2713 int transit = mWindowManager.getPendingAppTransition(); 2714 return transit == AppTransition.TRANSIT_ACTIVITY_OPEN 2715 || transit == AppTransition.TRANSIT_TASK_OPEN 2716 || transit == AppTransition.TRANSIT_TASK_TO_FRONT; 2717 } 2718 2719 final ProcessRecord startProcessLocked(String processName, 2720 ApplicationInfo info, boolean knownToBeDead, int intentFlags, 2721 String hostingType, ComponentName hostingName, boolean allowWhileBooting, 2722 boolean isolated, boolean keepIfLarge) { 2723 ProcessRecord app; 2724 if (!isolated) { 2725 app = getProcessRecordLocked(processName, info.uid, keepIfLarge); 2726 } else { 2727 // If this is an isolated process, it can't re-use an existing process. 2728 app = null; 2729 } 2730 // We don't have to do anything more if: 2731 // (1) There is an existing application record; and 2732 // (2) The caller doesn't think it is dead, OR there is no thread 2733 // object attached to it so we know it couldn't have crashed; and 2734 // (3) There is a pid assigned to it, so it is either starting or 2735 // already running. 2736 if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName 2737 + " app=" + app + " knownToBeDead=" + knownToBeDead 2738 + " thread=" + (app != null ? app.thread : null) 2739 + " pid=" + (app != null ? app.pid : -1)); 2740 if (app != null && app.pid > 0) { 2741 if (!knownToBeDead || app.thread == null) { 2742 // We already have the app running, or are waiting for it to 2743 // come up (we have a pid but not yet its thread), so keep it. 2744 if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app); 2745 // If this is a new package in the process, add the package to the list 2746 app.addPackage(info.packageName, mProcessStats); 2747 return app; 2748 } 2749 2750 // An application record is attached to a previous process, 2751 // clean it up now. 2752 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app); 2753 handleAppDiedLocked(app, true, true); 2754 } 2755 2756 String hostingNameStr = hostingName != null 2757 ? hostingName.flattenToShortString() : null; 2758 2759 if (!isolated) { 2760 if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) { 2761 // If we are in the background, then check to see if this process 2762 // is bad. If so, we will just silently fail. 2763 if (mBadProcesses.get(info.processName, info.uid) != null) { 2764 if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid 2765 + "/" + info.processName); 2766 return null; 2767 } 2768 } else { 2769 // When the user is explicitly starting a process, then clear its 2770 // crash count so that we won't make it bad until they see at 2771 // least one crash dialog again, and make the process good again 2772 // if it had been bad. 2773 if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid 2774 + "/" + info.processName); 2775 mProcessCrashTimes.remove(info.processName, info.uid); 2776 if (mBadProcesses.get(info.processName, info.uid) != null) { 2777 EventLog.writeEvent(EventLogTags.AM_PROC_GOOD, 2778 UserHandle.getUserId(info.uid), info.uid, 2779 info.processName); 2780 mBadProcesses.remove(info.processName, info.uid); 2781 if (app != null) { 2782 app.bad = false; 2783 } 2784 } 2785 } 2786 } 2787 2788 if (app == null) { 2789 app = newProcessRecordLocked(info, processName, isolated); 2790 if (app == null) { 2791 Slog.w(TAG, "Failed making new process record for " 2792 + processName + "/" + info.uid + " isolated=" + isolated); 2793 return null; 2794 } 2795 mProcessNames.put(processName, app.uid, app); 2796 if (isolated) { 2797 mIsolatedProcesses.put(app.uid, app); 2798 } 2799 } else { 2800 // If this is a new package in the process, add the package to the list 2801 app.addPackage(info.packageName, mProcessStats); 2802 } 2803 2804 // If the system is not ready yet, then hold off on starting this 2805 // process until it is. 2806 if (!mProcessesReady 2807 && !isAllowedWhileBooting(info) 2808 && !allowWhileBooting) { 2809 if (!mProcessesOnHold.contains(app)) { 2810 mProcessesOnHold.add(app); 2811 } 2812 if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app); 2813 return app; 2814 } 2815 2816 startProcessLocked(app, hostingType, hostingNameStr); 2817 return (app.pid != 0) ? app : null; 2818 } 2819 2820 boolean isAllowedWhileBooting(ApplicationInfo ai) { 2821 return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0; 2822 } 2823 2824 private final void startProcessLocked(ProcessRecord app, 2825 String hostingType, String hostingNameStr) { 2826 if (app.pid > 0 && app.pid != MY_PID) { 2827 synchronized (mPidsSelfLocked) { 2828 mPidsSelfLocked.remove(app.pid); 2829 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 2830 } 2831 app.setPid(0); 2832 } 2833 2834 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 2835 "startProcessLocked removing on hold: " + app); 2836 mProcessesOnHold.remove(app); 2837 2838 updateCpuStats(); 2839 2840 try { 2841 int uid = app.uid; 2842 2843 int[] gids = null; 2844 int mountExternal = Zygote.MOUNT_EXTERNAL_NONE; 2845 if (!app.isolated) { 2846 int[] permGids = null; 2847 try { 2848 final PackageManager pm = mContext.getPackageManager(); 2849 permGids = pm.getPackageGids(app.info.packageName); 2850 2851 if (Environment.isExternalStorageEmulated()) { 2852 if (pm.checkPermission( 2853 android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE, 2854 app.info.packageName) == PERMISSION_GRANTED) { 2855 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL; 2856 } else { 2857 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER; 2858 } 2859 } 2860 } catch (PackageManager.NameNotFoundException e) { 2861 Slog.w(TAG, "Unable to retrieve gids", e); 2862 } 2863 2864 /* 2865 * Add shared application GID so applications can share some 2866 * resources like shared libraries 2867 */ 2868 if (permGids == null) { 2869 gids = new int[1]; 2870 } else { 2871 gids = new int[permGids.length + 1]; 2872 System.arraycopy(permGids, 0, gids, 1, permGids.length); 2873 } 2874 gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid)); 2875 } 2876 if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) { 2877 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL 2878 && mTopComponent != null 2879 && app.processName.equals(mTopComponent.getPackageName())) { 2880 uid = 0; 2881 } 2882 if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL 2883 && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) { 2884 uid = 0; 2885 } 2886 } 2887 int debugFlags = 0; 2888 if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) { 2889 debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER; 2890 // Also turn on CheckJNI for debuggable apps. It's quite 2891 // awkward to turn on otherwise. 2892 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 2893 } 2894 // Run the app in safe mode if its manifest requests so or the 2895 // system is booted in safe mode. 2896 if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 || 2897 mSafeMode == true) { 2898 debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE; 2899 } 2900 if ("1".equals(SystemProperties.get("debug.checkjni"))) { 2901 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 2902 } 2903 if ("1".equals(SystemProperties.get("debug.jni.logging"))) { 2904 debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING; 2905 } 2906 if ("1".equals(SystemProperties.get("debug.assert"))) { 2907 debugFlags |= Zygote.DEBUG_ENABLE_ASSERT; 2908 } 2909 2910 String requiredAbi = app.info.cpuAbi; 2911 if (requiredAbi == null) { 2912 requiredAbi = Build.SUPPORTED_ABIS[0]; 2913 } 2914 2915 // Start the process. It will either succeed and return a result containing 2916 // the PID of the new process, or else throw a RuntimeException. 2917 Process.ProcessStartResult startResult = Process.start("android.app.ActivityThread", 2918 app.processName, uid, uid, gids, debugFlags, mountExternal, 2919 app.info.targetSdkVersion, app.info.seinfo, requiredAbi, null); 2920 2921 BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics(); 2922 synchronized (bs) { 2923 if (bs.isOnBattery()) { 2924 bs.getProcessStatsLocked(app.uid, app.processName).incStartsLocked(); 2925 } 2926 } 2927 2928 EventLog.writeEvent(EventLogTags.AM_PROC_START, 2929 UserHandle.getUserId(uid), startResult.pid, uid, 2930 app.processName, hostingType, 2931 hostingNameStr != null ? hostingNameStr : ""); 2932 2933 if (app.persistent) { 2934 Watchdog.getInstance().processStarted(app.processName, startResult.pid); 2935 } 2936 2937 StringBuilder buf = mStringBuilder; 2938 buf.setLength(0); 2939 buf.append("Start proc "); 2940 buf.append(app.processName); 2941 buf.append(" for "); 2942 buf.append(hostingType); 2943 if (hostingNameStr != null) { 2944 buf.append(" "); 2945 buf.append(hostingNameStr); 2946 } 2947 buf.append(": pid="); 2948 buf.append(startResult.pid); 2949 buf.append(" uid="); 2950 buf.append(uid); 2951 buf.append(" gids={"); 2952 if (gids != null) { 2953 for (int gi=0; gi<gids.length; gi++) { 2954 if (gi != 0) buf.append(", "); 2955 buf.append(gids[gi]); 2956 2957 } 2958 } 2959 buf.append("}"); 2960 Slog.i(TAG, buf.toString()); 2961 app.setPid(startResult.pid); 2962 app.usingWrapper = startResult.usingWrapper; 2963 app.removed = false; 2964 synchronized (mPidsSelfLocked) { 2965 this.mPidsSelfLocked.put(startResult.pid, app); 2966 Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 2967 msg.obj = app; 2968 mHandler.sendMessageDelayed(msg, startResult.usingWrapper 2969 ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT); 2970 } 2971 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_START, 2972 app.processName, app.info.uid); 2973 if (app.isolated) { 2974 mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid); 2975 } 2976 } catch (RuntimeException e) { 2977 // XXX do better error recovery. 2978 app.setPid(0); 2979 Slog.e(TAG, "Failure starting process " + app.processName, e); 2980 } 2981 } 2982 2983 void updateUsageStats(ActivityRecord component, boolean resumed) { 2984 if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed); 2985 final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 2986 if (resumed) { 2987 mUsageStatsService.noteResumeComponent(component.realActivity); 2988 synchronized (stats) { 2989 stats.noteActivityResumedLocked(component.app.uid); 2990 } 2991 } else { 2992 mUsageStatsService.notePauseComponent(component.realActivity); 2993 synchronized (stats) { 2994 stats.noteActivityPausedLocked(component.app.uid); 2995 } 2996 } 2997 } 2998 2999 Intent getHomeIntent() { 3000 Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null); 3001 intent.setComponent(mTopComponent); 3002 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 3003 intent.addCategory(Intent.CATEGORY_HOME); 3004 } 3005 return intent; 3006 } 3007 3008 boolean startHomeActivityLocked(int userId) { 3009 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL 3010 && mTopAction == null) { 3011 // We are running in factory test mode, but unable to find 3012 // the factory test app, so just sit around displaying the 3013 // error message and don't try to start anything. 3014 return false; 3015 } 3016 Intent intent = getHomeIntent(); 3017 ActivityInfo aInfo = 3018 resolveActivityInfo(intent, STOCK_PM_FLAGS, userId); 3019 if (aInfo != null) { 3020 intent.setComponent(new ComponentName( 3021 aInfo.applicationInfo.packageName, aInfo.name)); 3022 // Don't do this if the home app is currently being 3023 // instrumented. 3024 aInfo = new ActivityInfo(aInfo); 3025 aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId); 3026 ProcessRecord app = getProcessRecordLocked(aInfo.processName, 3027 aInfo.applicationInfo.uid, true); 3028 if (app == null || app.instrumentationClass == null) { 3029 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK); 3030 mStackSupervisor.startHomeActivity(intent, aInfo); 3031 } 3032 } 3033 3034 return true; 3035 } 3036 3037 private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) { 3038 ActivityInfo ai = null; 3039 ComponentName comp = intent.getComponent(); 3040 try { 3041 if (comp != null) { 3042 ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId); 3043 } else { 3044 ResolveInfo info = AppGlobals.getPackageManager().resolveIntent( 3045 intent, 3046 intent.resolveTypeIfNeeded(mContext.getContentResolver()), 3047 flags, userId); 3048 3049 if (info != null) { 3050 ai = info.activityInfo; 3051 } 3052 } 3053 } catch (RemoteException e) { 3054 // ignore 3055 } 3056 3057 return ai; 3058 } 3059 3060 /** 3061 * Starts the "new version setup screen" if appropriate. 3062 */ 3063 void startSetupActivityLocked() { 3064 // Only do this once per boot. 3065 if (mCheckedForSetup) { 3066 return; 3067 } 3068 3069 // We will show this screen if the current one is a different 3070 // version than the last one shown, and we are not running in 3071 // low-level factory test mode. 3072 final ContentResolver resolver = mContext.getContentResolver(); 3073 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL && 3074 Settings.Global.getInt(resolver, 3075 Settings.Global.DEVICE_PROVISIONED, 0) != 0) { 3076 mCheckedForSetup = true; 3077 3078 // See if we should be showing the platform update setup UI. 3079 Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP); 3080 List<ResolveInfo> ris = mContext.getPackageManager() 3081 .queryIntentActivities(intent, PackageManager.GET_META_DATA); 3082 3083 // We don't allow third party apps to replace this. 3084 ResolveInfo ri = null; 3085 for (int i=0; ris != null && i<ris.size(); i++) { 3086 if ((ris.get(i).activityInfo.applicationInfo.flags 3087 & ApplicationInfo.FLAG_SYSTEM) != 0) { 3088 ri = ris.get(i); 3089 break; 3090 } 3091 } 3092 3093 if (ri != null) { 3094 String vers = ri.activityInfo.metaData != null 3095 ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION) 3096 : null; 3097 if (vers == null && ri.activityInfo.applicationInfo.metaData != null) { 3098 vers = ri.activityInfo.applicationInfo.metaData.getString( 3099 Intent.METADATA_SETUP_VERSION); 3100 } 3101 String lastVers = Settings.Secure.getString( 3102 resolver, Settings.Secure.LAST_SETUP_SHOWN); 3103 if (vers != null && !vers.equals(lastVers)) { 3104 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 3105 intent.setComponent(new ComponentName( 3106 ri.activityInfo.packageName, ri.activityInfo.name)); 3107 mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo, 3108 null, null, null, null, 0, 0, 0, null, 0, null, false, null, null); 3109 } 3110 } 3111 } 3112 } 3113 3114 CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) { 3115 return mCompatModePackages.compatibilityInfoForPackageLocked(ai); 3116 } 3117 3118 void enforceNotIsolatedCaller(String caller) { 3119 if (UserHandle.isIsolated(Binder.getCallingUid())) { 3120 throw new SecurityException("Isolated process not allowed to call " + caller); 3121 } 3122 } 3123 3124 @Override 3125 public int getFrontActivityScreenCompatMode() { 3126 enforceNotIsolatedCaller("getFrontActivityScreenCompatMode"); 3127 synchronized (this) { 3128 return mCompatModePackages.getFrontActivityScreenCompatModeLocked(); 3129 } 3130 } 3131 3132 @Override 3133 public void setFrontActivityScreenCompatMode(int mode) { 3134 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3135 "setFrontActivityScreenCompatMode"); 3136 synchronized (this) { 3137 mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode); 3138 } 3139 } 3140 3141 @Override 3142 public int getPackageScreenCompatMode(String packageName) { 3143 enforceNotIsolatedCaller("getPackageScreenCompatMode"); 3144 synchronized (this) { 3145 return mCompatModePackages.getPackageScreenCompatModeLocked(packageName); 3146 } 3147 } 3148 3149 @Override 3150 public void setPackageScreenCompatMode(String packageName, int mode) { 3151 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3152 "setPackageScreenCompatMode"); 3153 synchronized (this) { 3154 mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode); 3155 } 3156 } 3157 3158 @Override 3159 public boolean getPackageAskScreenCompat(String packageName) { 3160 enforceNotIsolatedCaller("getPackageAskScreenCompat"); 3161 synchronized (this) { 3162 return mCompatModePackages.getPackageAskCompatModeLocked(packageName); 3163 } 3164 } 3165 3166 @Override 3167 public void setPackageAskScreenCompat(String packageName, boolean ask) { 3168 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3169 "setPackageAskScreenCompat"); 3170 synchronized (this) { 3171 mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask); 3172 } 3173 } 3174 3175 private void dispatchProcessesChanged() { 3176 int N; 3177 synchronized (this) { 3178 N = mPendingProcessChanges.size(); 3179 if (mActiveProcessChanges.length < N) { 3180 mActiveProcessChanges = new ProcessChangeItem[N]; 3181 } 3182 mPendingProcessChanges.toArray(mActiveProcessChanges); 3183 mAvailProcessChanges.addAll(mPendingProcessChanges); 3184 mPendingProcessChanges.clear(); 3185 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes"); 3186 } 3187 3188 int i = mProcessObservers.beginBroadcast(); 3189 while (i > 0) { 3190 i--; 3191 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 3192 if (observer != null) { 3193 try { 3194 for (int j=0; j<N; j++) { 3195 ProcessChangeItem item = mActiveProcessChanges[j]; 3196 if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) { 3197 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid=" 3198 + item.pid + " uid=" + item.uid + ": " 3199 + item.foregroundActivities); 3200 observer.onForegroundActivitiesChanged(item.pid, item.uid, 3201 item.foregroundActivities); 3202 } 3203 if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) { 3204 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "PROCSTATE CHANGED pid=" 3205 + item.pid + " uid=" + item.uid + ": " + item.processState); 3206 observer.onProcessStateChanged(item.pid, item.uid, item.processState); 3207 } 3208 } 3209 } catch (RemoteException e) { 3210 } 3211 } 3212 } 3213 mProcessObservers.finishBroadcast(); 3214 } 3215 3216 private void dispatchProcessDied(int pid, int uid) { 3217 int i = mProcessObservers.beginBroadcast(); 3218 while (i > 0) { 3219 i--; 3220 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 3221 if (observer != null) { 3222 try { 3223 observer.onProcessDied(pid, uid); 3224 } catch (RemoteException e) { 3225 } 3226 } 3227 } 3228 mProcessObservers.finishBroadcast(); 3229 } 3230 3231 final void doPendingActivityLaunchesLocked(boolean doResume) { 3232 final int N = mPendingActivityLaunches.size(); 3233 if (N <= 0) { 3234 return; 3235 } 3236 for (int i=0; i<N; i++) { 3237 PendingActivityLaunch pal = mPendingActivityLaunches.get(i); 3238 mStackSupervisor.startActivityUncheckedLocked(pal.r, pal.sourceRecord, null, null, pal.startFlags, 3239 doResume && i == (N-1), null); 3240 } 3241 mPendingActivityLaunches.clear(); 3242 } 3243 3244 @Override 3245 public final int startActivity(IApplicationThread caller, String callingPackage, 3246 Intent intent, String resolvedType, IBinder resultTo, 3247 String resultWho, int requestCode, int startFlags, 3248 String profileFile, ParcelFileDescriptor profileFd, Bundle options) { 3249 return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo, 3250 resultWho, requestCode, 3251 startFlags, profileFile, profileFd, options, UserHandle.getCallingUserId()); 3252 } 3253 3254 @Override 3255 public final int startActivityAsUser(IApplicationThread caller, String callingPackage, 3256 Intent intent, String resolvedType, IBinder resultTo, 3257 String resultWho, int requestCode, int startFlags, 3258 String profileFile, ParcelFileDescriptor profileFd, Bundle options, int userId) { 3259 enforceNotIsolatedCaller("startActivity"); 3260 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3261 false, true, "startActivity", null); 3262 // TODO: Switch to user app stacks here. 3263 return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType, 3264 null, null, resultTo, resultWho, requestCode, startFlags, profileFile, profileFd, 3265 null, null, options, userId, null); 3266 } 3267 3268 @Override 3269 public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage, 3270 Intent intent, String resolvedType, IBinder resultTo, 3271 String resultWho, int requestCode, int startFlags, String profileFile, 3272 ParcelFileDescriptor profileFd, Bundle options, int userId) { 3273 enforceNotIsolatedCaller("startActivityAndWait"); 3274 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3275 false, true, "startActivityAndWait", null); 3276 WaitResult res = new WaitResult(); 3277 // TODO: Switch to user app stacks here. 3278 mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType, 3279 null, null, resultTo, resultWho, requestCode, startFlags, profileFile, profileFd, 3280 res, null, options, UserHandle.getCallingUserId(), null); 3281 return res; 3282 } 3283 3284 @Override 3285 public final int startActivityWithConfig(IApplicationThread caller, String callingPackage, 3286 Intent intent, String resolvedType, IBinder resultTo, 3287 String resultWho, int requestCode, int startFlags, Configuration config, 3288 Bundle options, int userId) { 3289 enforceNotIsolatedCaller("startActivityWithConfig"); 3290 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3291 false, true, "startActivityWithConfig", null); 3292 // TODO: Switch to user app stacks here. 3293 int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, 3294 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, 3295 null, null, null, config, options, userId, null); 3296 return ret; 3297 } 3298 3299 @Override 3300 public int startActivityIntentSender(IApplicationThread caller, 3301 IntentSender intent, Intent fillInIntent, String resolvedType, 3302 IBinder resultTo, String resultWho, int requestCode, 3303 int flagsMask, int flagsValues, Bundle options) { 3304 enforceNotIsolatedCaller("startActivityIntentSender"); 3305 // Refuse possible leaked file descriptors 3306 if (fillInIntent != null && fillInIntent.hasFileDescriptors()) { 3307 throw new IllegalArgumentException("File descriptors passed in Intent"); 3308 } 3309 3310 IIntentSender sender = intent.getTarget(); 3311 if (!(sender instanceof PendingIntentRecord)) { 3312 throw new IllegalArgumentException("Bad PendingIntent object"); 3313 } 3314 3315 PendingIntentRecord pir = (PendingIntentRecord)sender; 3316 3317 synchronized (this) { 3318 // If this is coming from the currently resumed activity, it is 3319 // effectively saying that app switches are allowed at this point. 3320 final ActivityStack stack = getFocusedStack(); 3321 if (stack.mResumedActivity != null && 3322 stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) { 3323 mAppSwitchesAllowedTime = 0; 3324 } 3325 } 3326 int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null, 3327 resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null); 3328 return ret; 3329 } 3330 3331 @Override 3332 public int startVoiceActivity(String callingPackage, int callingPid, int callingUid, 3333 Intent intent, String resolvedType, IVoiceInteractionSession session, 3334 IVoiceInteractor interactor, int startFlags, String profileFile, 3335 ParcelFileDescriptor profileFd, Bundle options, int userId) { 3336 if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION) 3337 != PackageManager.PERMISSION_GRANTED) { 3338 String msg = "Permission Denial: startVoiceActivity() from pid=" 3339 + Binder.getCallingPid() 3340 + ", uid=" + Binder.getCallingUid() 3341 + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION; 3342 Slog.w(TAG, msg); 3343 throw new SecurityException(msg); 3344 } 3345 if (session == null || interactor == null) { 3346 throw new NullPointerException("null session or interactor"); 3347 } 3348 userId = handleIncomingUser(callingPid, callingUid, userId, 3349 false, true, "startVoiceActivity", null); 3350 // TODO: Switch to user app stacks here. 3351 return mStackSupervisor.startActivityMayWait(null, callingUid, callingPackage, intent, 3352 resolvedType, session, interactor, null, null, 0, startFlags, 3353 profileFile, profileFd, null, null, options, userId, null); 3354 } 3355 3356 @Override 3357 public boolean startNextMatchingActivity(IBinder callingActivity, 3358 Intent intent, Bundle options) { 3359 // Refuse possible leaked file descriptors 3360 if (intent != null && intent.hasFileDescriptors() == true) { 3361 throw new IllegalArgumentException("File descriptors passed in Intent"); 3362 } 3363 3364 synchronized (this) { 3365 final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity); 3366 if (r == null) { 3367 ActivityOptions.abort(options); 3368 return false; 3369 } 3370 if (r.app == null || r.app.thread == null) { 3371 // The caller is not running... d'oh! 3372 ActivityOptions.abort(options); 3373 return false; 3374 } 3375 intent = new Intent(intent); 3376 // The caller is not allowed to change the data. 3377 intent.setDataAndType(r.intent.getData(), r.intent.getType()); 3378 // And we are resetting to find the next component... 3379 intent.setComponent(null); 3380 3381 final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0); 3382 3383 ActivityInfo aInfo = null; 3384 try { 3385 List<ResolveInfo> resolves = 3386 AppGlobals.getPackageManager().queryIntentActivities( 3387 intent, r.resolvedType, 3388 PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS, 3389 UserHandle.getCallingUserId()); 3390 3391 // Look for the original activity in the list... 3392 final int N = resolves != null ? resolves.size() : 0; 3393 for (int i=0; i<N; i++) { 3394 ResolveInfo rInfo = resolves.get(i); 3395 if (rInfo.activityInfo.packageName.equals(r.packageName) 3396 && rInfo.activityInfo.name.equals(r.info.name)) { 3397 // We found the current one... the next matching is 3398 // after it. 3399 i++; 3400 if (i<N) { 3401 aInfo = resolves.get(i).activityInfo; 3402 } 3403 if (debug) { 3404 Slog.v(TAG, "Next matching activity: found current " + r.packageName 3405 + "/" + r.info.name); 3406 Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName 3407 + "/" + aInfo.name); 3408 } 3409 break; 3410 } 3411 } 3412 } catch (RemoteException e) { 3413 } 3414 3415 if (aInfo == null) { 3416 // Nobody who is next! 3417 ActivityOptions.abort(options); 3418 if (debug) Slog.d(TAG, "Next matching activity: nothing found"); 3419 return false; 3420 } 3421 3422 intent.setComponent(new ComponentName( 3423 aInfo.applicationInfo.packageName, aInfo.name)); 3424 intent.setFlags(intent.getFlags()&~( 3425 Intent.FLAG_ACTIVITY_FORWARD_RESULT| 3426 Intent.FLAG_ACTIVITY_CLEAR_TOP| 3427 Intent.FLAG_ACTIVITY_MULTIPLE_TASK| 3428 Intent.FLAG_ACTIVITY_NEW_TASK)); 3429 3430 // Okay now we need to start the new activity, replacing the 3431 // currently running activity. This is a little tricky because 3432 // we want to start the new one as if the current one is finished, 3433 // but not finish the current one first so that there is no flicker. 3434 // And thus... 3435 final boolean wasFinishing = r.finishing; 3436 r.finishing = true; 3437 3438 // Propagate reply information over to the new activity. 3439 final ActivityRecord resultTo = r.resultTo; 3440 final String resultWho = r.resultWho; 3441 final int requestCode = r.requestCode; 3442 r.resultTo = null; 3443 if (resultTo != null) { 3444 resultTo.removeResultsLocked(r, resultWho, requestCode); 3445 } 3446 3447 final long origId = Binder.clearCallingIdentity(); 3448 int res = mStackSupervisor.startActivityLocked(r.app.thread, intent, 3449 r.resolvedType, aInfo, null, null, resultTo != null ? resultTo.appToken : null, 3450 resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage, 0, 3451 options, false, null, null); 3452 Binder.restoreCallingIdentity(origId); 3453 3454 r.finishing = wasFinishing; 3455 if (res != ActivityManager.START_SUCCESS) { 3456 return false; 3457 } 3458 return true; 3459 } 3460 } 3461 3462 final int startActivityInPackage(int uid, String callingPackage, 3463 Intent intent, String resolvedType, IBinder resultTo, 3464 String resultWho, int requestCode, int startFlags, Bundle options, int userId, 3465 IActivityContainer container) { 3466 3467 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3468 false, true, "startActivityInPackage", null); 3469 3470 // TODO: Switch to user app stacks here. 3471 int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent, resolvedType, 3472 null, null, resultTo, resultWho, requestCode, startFlags, 3473 null, null, null, null, options, userId, container); 3474 return ret; 3475 } 3476 3477 @Override 3478 public final int startActivities(IApplicationThread caller, String callingPackage, 3479 Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options, 3480 int userId) { 3481 enforceNotIsolatedCaller("startActivities"); 3482 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3483 false, true, "startActivity", null); 3484 // TODO: Switch to user app stacks here. 3485 int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents, 3486 resolvedTypes, resultTo, options, userId); 3487 return ret; 3488 } 3489 3490 final int startActivitiesInPackage(int uid, String callingPackage, 3491 Intent[] intents, String[] resolvedTypes, IBinder resultTo, 3492 Bundle options, int userId) { 3493 3494 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3495 false, true, "startActivityInPackage", null); 3496 // TODO: Switch to user app stacks here. 3497 int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes, 3498 resultTo, options, userId); 3499 return ret; 3500 } 3501 3502 final void addRecentTaskLocked(TaskRecord task) { 3503 int N = mRecentTasks.size(); 3504 // Quick case: check if the top-most recent task is the same. 3505 if (N > 0 && mRecentTasks.get(0) == task) { 3506 return; 3507 } 3508 // Another quick case: never add voice sessions. 3509 if (task.voiceSession != null) { 3510 return; 3511 } 3512 // Remove any existing entries that are the same kind of task. 3513 final Intent intent = task.intent; 3514 final boolean document = intent != null && intent.isDocument(); 3515 for (int i=0; i<N; i++) { 3516 TaskRecord tr = mRecentTasks.get(i); 3517 if (task != tr) { 3518 if (task.userId != tr.userId) { 3519 continue; 3520 } 3521 final Intent trIntent = tr.intent; 3522 if ((task.affinity == null || !task.affinity.equals(tr.affinity)) && 3523 (intent == null || !intent.filterEquals(trIntent))) { 3524 continue; 3525 } 3526 if (document || trIntent != null && trIntent.isDocument()) { 3527 // Document tasks do not match other tasks. 3528 continue; 3529 } 3530 } 3531 3532 // Either task and tr are the same or, their affinities match or their intents match 3533 // and neither of them is a document. 3534 tr.disposeThumbnail(); 3535 mRecentTasks.remove(i); 3536 i--; 3537 N--; 3538 if (task.intent == null) { 3539 // If the new recent task we are adding is not fully 3540 // specified, then replace it with the existing recent task. 3541 task = tr; 3542 } 3543 } 3544 if (N >= MAX_RECENT_TASKS) { 3545 mRecentTasks.remove(N-1).disposeThumbnail(); 3546 } 3547 mRecentTasks.add(0, task); 3548 } 3549 3550 @Override 3551 public void reportActivityFullyDrawn(IBinder token) { 3552 synchronized (this) { 3553 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3554 if (r == null) { 3555 return; 3556 } 3557 r.reportFullyDrawnLocked(); 3558 } 3559 } 3560 3561 @Override 3562 public void setRequestedOrientation(IBinder token, int requestedOrientation) { 3563 synchronized (this) { 3564 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3565 if (r == null) { 3566 return; 3567 } 3568 final long origId = Binder.clearCallingIdentity(); 3569 mWindowManager.setAppOrientation(r.appToken, requestedOrientation); 3570 Configuration config = mWindowManager.updateOrientationFromAppTokens( 3571 mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null); 3572 if (config != null) { 3573 r.frozenBeforeDestroy = true; 3574 if (!updateConfigurationLocked(config, r, false, false)) { 3575 mStackSupervisor.resumeTopActivitiesLocked(); 3576 } 3577 } 3578 Binder.restoreCallingIdentity(origId); 3579 } 3580 } 3581 3582 @Override 3583 public int getRequestedOrientation(IBinder token) { 3584 synchronized (this) { 3585 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3586 if (r == null) { 3587 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; 3588 } 3589 return mWindowManager.getAppOrientation(r.appToken); 3590 } 3591 } 3592 3593 /** 3594 * This is the internal entry point for handling Activity.finish(). 3595 * 3596 * @param token The Binder token referencing the Activity we want to finish. 3597 * @param resultCode Result code, if any, from this Activity. 3598 * @param resultData Result data (Intent), if any, from this Activity. 3599 * @param finishTask Whether to finish the task associated with this Activity. Only applies to 3600 * the root Activity in the task. 3601 * 3602 * @return Returns true if the activity successfully finished, or false if it is still running. 3603 */ 3604 @Override 3605 public final boolean finishActivity(IBinder token, int resultCode, Intent resultData, 3606 boolean finishTask) { 3607 // Refuse possible leaked file descriptors 3608 if (resultData != null && resultData.hasFileDescriptors() == true) { 3609 throw new IllegalArgumentException("File descriptors passed in Intent"); 3610 } 3611 3612 synchronized(this) { 3613 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3614 if (r == null) { 3615 return true; 3616 } 3617 // Keep track of the root activity of the task before we finish it 3618 TaskRecord tr = r.task; 3619 ActivityRecord rootR = tr.getRootActivity(); 3620 if (mController != null) { 3621 // Find the first activity that is not finishing. 3622 ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0); 3623 if (next != null) { 3624 // ask watcher if this is allowed 3625 boolean resumeOK = true; 3626 try { 3627 resumeOK = mController.activityResuming(next.packageName); 3628 } catch (RemoteException e) { 3629 mController = null; 3630 Watchdog.getInstance().setActivityController(null); 3631 } 3632 3633 if (!resumeOK) { 3634 return false; 3635 } 3636 } 3637 } 3638 final long origId = Binder.clearCallingIdentity(); 3639 try { 3640 boolean res; 3641 if (finishTask && r == rootR) { 3642 // If requested, remove the task that is associated to this activity only if it 3643 // was the root activity in the task. The result code and data is ignored because 3644 // we don't support returning them across task boundaries. 3645 res = removeTaskByIdLocked(tr.taskId, 0); 3646 } else { 3647 res = tr.stack.requestFinishActivityLocked(token, resultCode, 3648 resultData, "app-request", true); 3649 } 3650 return res; 3651 } finally { 3652 Binder.restoreCallingIdentity(origId); 3653 } 3654 } 3655 } 3656 3657 @Override 3658 public final void finishHeavyWeightApp() { 3659 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 3660 != PackageManager.PERMISSION_GRANTED) { 3661 String msg = "Permission Denial: finishHeavyWeightApp() from pid=" 3662 + Binder.getCallingPid() 3663 + ", uid=" + Binder.getCallingUid() 3664 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 3665 Slog.w(TAG, msg); 3666 throw new SecurityException(msg); 3667 } 3668 3669 synchronized(this) { 3670 if (mHeavyWeightProcess == null) { 3671 return; 3672 } 3673 3674 ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>( 3675 mHeavyWeightProcess.activities); 3676 for (int i=0; i<activities.size(); i++) { 3677 ActivityRecord r = activities.get(i); 3678 if (!r.finishing) { 3679 r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED, 3680 null, "finish-heavy", true); 3681 } 3682 } 3683 3684 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 3685 mHeavyWeightProcess.userId, 0)); 3686 mHeavyWeightProcess = null; 3687 } 3688 } 3689 3690 @Override 3691 public void crashApplication(int uid, int initialPid, String packageName, 3692 String message) { 3693 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 3694 != PackageManager.PERMISSION_GRANTED) { 3695 String msg = "Permission Denial: crashApplication() from pid=" 3696 + Binder.getCallingPid() 3697 + ", uid=" + Binder.getCallingUid() 3698 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 3699 Slog.w(TAG, msg); 3700 throw new SecurityException(msg); 3701 } 3702 3703 synchronized(this) { 3704 ProcessRecord proc = null; 3705 3706 // Figure out which process to kill. We don't trust that initialPid 3707 // still has any relation to current pids, so must scan through the 3708 // list. 3709 synchronized (mPidsSelfLocked) { 3710 for (int i=0; i<mPidsSelfLocked.size(); i++) { 3711 ProcessRecord p = mPidsSelfLocked.valueAt(i); 3712 if (p.uid != uid) { 3713 continue; 3714 } 3715 if (p.pid == initialPid) { 3716 proc = p; 3717 break; 3718 } 3719 if (p.pkgList.containsKey(packageName)) { 3720 proc = p; 3721 } 3722 } 3723 } 3724 3725 if (proc == null) { 3726 Slog.w(TAG, "crashApplication: nothing for uid=" + uid 3727 + " initialPid=" + initialPid 3728 + " packageName=" + packageName); 3729 return; 3730 } 3731 3732 if (proc.thread != null) { 3733 if (proc.pid == Process.myPid()) { 3734 Log.w(TAG, "crashApplication: trying to crash self!"); 3735 return; 3736 } 3737 long ident = Binder.clearCallingIdentity(); 3738 try { 3739 proc.thread.scheduleCrash(message); 3740 } catch (RemoteException e) { 3741 } 3742 Binder.restoreCallingIdentity(ident); 3743 } 3744 } 3745 } 3746 3747 @Override 3748 public final void finishSubActivity(IBinder token, String resultWho, 3749 int requestCode) { 3750 synchronized(this) { 3751 final long origId = Binder.clearCallingIdentity(); 3752 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3753 if (r != null) { 3754 r.task.stack.finishSubActivityLocked(r, resultWho, requestCode); 3755 } 3756 Binder.restoreCallingIdentity(origId); 3757 } 3758 } 3759 3760 @Override 3761 public boolean finishActivityAffinity(IBinder token) { 3762 synchronized(this) { 3763 final long origId = Binder.clearCallingIdentity(); 3764 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3765 boolean res = false; 3766 if (r != null) { 3767 res = r.task.stack.finishActivityAffinityLocked(r); 3768 } 3769 Binder.restoreCallingIdentity(origId); 3770 return res; 3771 } 3772 } 3773 3774 @Override 3775 public boolean willActivityBeVisible(IBinder token) { 3776 synchronized(this) { 3777 ActivityStack stack = ActivityRecord.getStackLocked(token); 3778 if (stack != null) { 3779 return stack.willActivityBeVisibleLocked(token); 3780 } 3781 return false; 3782 } 3783 } 3784 3785 @Override 3786 public void overridePendingTransition(IBinder token, String packageName, 3787 int enterAnim, int exitAnim) { 3788 synchronized(this) { 3789 ActivityRecord self = ActivityRecord.isInStackLocked(token); 3790 if (self == null) { 3791 return; 3792 } 3793 3794 final long origId = Binder.clearCallingIdentity(); 3795 3796 if (self.state == ActivityState.RESUMED 3797 || self.state == ActivityState.PAUSING) { 3798 mWindowManager.overridePendingAppTransition(packageName, 3799 enterAnim, exitAnim, null); 3800 } 3801 3802 Binder.restoreCallingIdentity(origId); 3803 } 3804 } 3805 3806 /** 3807 * Main function for removing an existing process from the activity manager 3808 * as a result of that process going away. Clears out all connections 3809 * to the process. 3810 */ 3811 private final void handleAppDiedLocked(ProcessRecord app, 3812 boolean restarting, boolean allowRestart) { 3813 int pid = app.pid; 3814 cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1); 3815 if (!restarting) { 3816 removeLruProcessLocked(app); 3817 if (pid > 0) { 3818 ProcessList.remove(pid); 3819 } 3820 } 3821 3822 if (mProfileProc == app) { 3823 clearProfilerLocked(); 3824 } 3825 3826 // Remove this application's activities from active lists. 3827 boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app); 3828 3829 app.activities.clear(); 3830 3831 if (app.instrumentationClass != null) { 3832 Slog.w(TAG, "Crash of app " + app.processName 3833 + " running instrumentation " + app.instrumentationClass); 3834 Bundle info = new Bundle(); 3835 info.putString("shortMsg", "Process crashed."); 3836 finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info); 3837 } 3838 3839 if (!restarting) { 3840 if (!mStackSupervisor.resumeTopActivitiesLocked()) { 3841 // If there was nothing to resume, and we are not already 3842 // restarting this process, but there is a visible activity that 3843 // is hosted by the process... then make sure all visible 3844 // activities are running, taking care of restarting this 3845 // process. 3846 if (hasVisibleActivities) { 3847 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 3848 } 3849 } 3850 } 3851 } 3852 3853 private final int getLRURecordIndexForAppLocked(IApplicationThread thread) { 3854 IBinder threadBinder = thread.asBinder(); 3855 // Find the application record. 3856 for (int i=mLruProcesses.size()-1; i>=0; i--) { 3857 ProcessRecord rec = mLruProcesses.get(i); 3858 if (rec.thread != null && rec.thread.asBinder() == threadBinder) { 3859 return i; 3860 } 3861 } 3862 return -1; 3863 } 3864 3865 final ProcessRecord getRecordForAppLocked( 3866 IApplicationThread thread) { 3867 if (thread == null) { 3868 return null; 3869 } 3870 3871 int appIndex = getLRURecordIndexForAppLocked(thread); 3872 return appIndex >= 0 ? mLruProcesses.get(appIndex) : null; 3873 } 3874 3875 final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) { 3876 // If there are no longer any background processes running, 3877 // and the app that died was not running instrumentation, 3878 // then tell everyone we are now low on memory. 3879 boolean haveBg = false; 3880 for (int i=mLruProcesses.size()-1; i>=0; i--) { 3881 ProcessRecord rec = mLruProcesses.get(i); 3882 if (rec.thread != null 3883 && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 3884 haveBg = true; 3885 break; 3886 } 3887 } 3888 3889 if (!haveBg) { 3890 boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 3891 if (doReport) { 3892 long now = SystemClock.uptimeMillis(); 3893 if (now < (mLastMemUsageReportTime+5*60*1000)) { 3894 doReport = false; 3895 } else { 3896 mLastMemUsageReportTime = now; 3897 } 3898 } 3899 final ArrayList<ProcessMemInfo> memInfos 3900 = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null; 3901 EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size()); 3902 long now = SystemClock.uptimeMillis(); 3903 for (int i=mLruProcesses.size()-1; i>=0; i--) { 3904 ProcessRecord rec = mLruProcesses.get(i); 3905 if (rec == dyingProc || rec.thread == null) { 3906 continue; 3907 } 3908 if (doReport) { 3909 memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj, 3910 rec.setProcState, rec.adjType, rec.makeAdjReason())); 3911 } 3912 if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) { 3913 // The low memory report is overriding any current 3914 // state for a GC request. Make sure to do 3915 // heavy/important/visible/foreground processes first. 3916 if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 3917 rec.lastRequestedGc = 0; 3918 } else { 3919 rec.lastRequestedGc = rec.lastLowMemory; 3920 } 3921 rec.reportLowMemory = true; 3922 rec.lastLowMemory = now; 3923 mProcessesToGc.remove(rec); 3924 addProcessToGcListLocked(rec); 3925 } 3926 } 3927 if (doReport) { 3928 Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos); 3929 mHandler.sendMessage(msg); 3930 } 3931 scheduleAppGcsLocked(); 3932 } 3933 } 3934 3935 final void appDiedLocked(ProcessRecord app, int pid, 3936 IApplicationThread thread) { 3937 3938 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 3939 synchronized (stats) { 3940 stats.noteProcessDiedLocked(app.info.uid, pid); 3941 } 3942 3943 // Clean up already done if the process has been re-started. 3944 if (app.pid == pid && app.thread != null && 3945 app.thread.asBinder() == thread.asBinder()) { 3946 boolean doLowMem = app.instrumentationClass == null; 3947 boolean doOomAdj = doLowMem; 3948 if (!app.killedByAm) { 3949 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 3950 + ") has died."); 3951 mAllowLowerMemLevel = true; 3952 } else { 3953 // Note that we always want to do oom adj to update our state with the 3954 // new number of procs. 3955 mAllowLowerMemLevel = false; 3956 doLowMem = false; 3957 } 3958 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName); 3959 if (DEBUG_CLEANUP) Slog.v( 3960 TAG, "Dying app: " + app + ", pid: " + pid 3961 + ", thread: " + thread.asBinder()); 3962 handleAppDiedLocked(app, false, true); 3963 3964 if (doOomAdj) { 3965 updateOomAdjLocked(); 3966 } 3967 if (doLowMem) { 3968 doLowMemReportIfNeededLocked(app); 3969 } 3970 } else if (app.pid != pid) { 3971 // A new process has already been started. 3972 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 3973 + ") has died and restarted (pid " + app.pid + ")."); 3974 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName); 3975 } else if (DEBUG_PROCESSES) { 3976 Slog.d(TAG, "Received spurious death notification for thread " 3977 + thread.asBinder()); 3978 } 3979 } 3980 3981 /** 3982 * If a stack trace dump file is configured, dump process stack traces. 3983 * @param clearTraces causes the dump file to be erased prior to the new 3984 * traces being written, if true; when false, the new traces will be 3985 * appended to any existing file content. 3986 * @param firstPids of dalvik VM processes to dump stack traces for first 3987 * @param lastPids of dalvik VM processes to dump stack traces for last 3988 * @param nativeProcs optional list of native process names to dump stack crawls 3989 * @return file containing stack traces, or null if no dump file is configured 3990 */ 3991 public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids, 3992 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) { 3993 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 3994 if (tracesPath == null || tracesPath.length() == 0) { 3995 return null; 3996 } 3997 3998 File tracesFile = new File(tracesPath); 3999 try { 4000 File tracesDir = tracesFile.getParentFile(); 4001 if (!tracesDir.exists()) { 4002 tracesFile.mkdirs(); 4003 if (!SELinux.restorecon(tracesDir)) { 4004 return null; 4005 } 4006 } 4007 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 4008 4009 if (clearTraces && tracesFile.exists()) tracesFile.delete(); 4010 tracesFile.createNewFile(); 4011 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 4012 } catch (IOException e) { 4013 Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e); 4014 return null; 4015 } 4016 4017 dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs); 4018 return tracesFile; 4019 } 4020 4021 private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids, 4022 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) { 4023 // Use a FileObserver to detect when traces finish writing. 4024 // The order of traces is considered important to maintain for legibility. 4025 FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) { 4026 @Override 4027 public synchronized void onEvent(int event, String path) { notify(); } 4028 }; 4029 4030 try { 4031 observer.startWatching(); 4032 4033 // First collect all of the stacks of the most important pids. 4034 if (firstPids != null) { 4035 try { 4036 int num = firstPids.size(); 4037 for (int i = 0; i < num; i++) { 4038 synchronized (observer) { 4039 Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT); 4040 observer.wait(200); // Wait for write-close, give up after 200msec 4041 } 4042 } 4043 } catch (InterruptedException e) { 4044 Log.wtf(TAG, e); 4045 } 4046 } 4047 4048 // Next collect the stacks of the native pids 4049 if (nativeProcs != null) { 4050 int[] pids = Process.getPidsForCommands(nativeProcs); 4051 if (pids != null) { 4052 for (int pid : pids) { 4053 Debug.dumpNativeBacktraceToFile(pid, tracesPath); 4054 } 4055 } 4056 } 4057 4058 // Lastly, measure CPU usage. 4059 if (processCpuTracker != null) { 4060 processCpuTracker.init(); 4061 System.gc(); 4062 processCpuTracker.update(); 4063 try { 4064 synchronized (processCpuTracker) { 4065 processCpuTracker.wait(500); // measure over 1/2 second. 4066 } 4067 } catch (InterruptedException e) { 4068 } 4069 processCpuTracker.update(); 4070 4071 // We'll take the stack crawls of just the top apps using CPU. 4072 final int N = processCpuTracker.countWorkingStats(); 4073 int numProcs = 0; 4074 for (int i=0; i<N && numProcs<5; i++) { 4075 ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i); 4076 if (lastPids.indexOfKey(stats.pid) >= 0) { 4077 numProcs++; 4078 try { 4079 synchronized (observer) { 4080 Process.sendSignal(stats.pid, Process.SIGNAL_QUIT); 4081 observer.wait(200); // Wait for write-close, give up after 200msec 4082 } 4083 } catch (InterruptedException e) { 4084 Log.wtf(TAG, e); 4085 } 4086 4087 } 4088 } 4089 } 4090 } finally { 4091 observer.stopWatching(); 4092 } 4093 } 4094 4095 final void logAppTooSlow(ProcessRecord app, long startTime, String msg) { 4096 if (true || IS_USER_BUILD) { 4097 return; 4098 } 4099 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 4100 if (tracesPath == null || tracesPath.length() == 0) { 4101 return; 4102 } 4103 4104 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads(); 4105 StrictMode.allowThreadDiskWrites(); 4106 try { 4107 final File tracesFile = new File(tracesPath); 4108 final File tracesDir = tracesFile.getParentFile(); 4109 final File tracesTmp = new File(tracesDir, "__tmp__"); 4110 try { 4111 if (!tracesDir.exists()) { 4112 tracesFile.mkdirs(); 4113 if (!SELinux.restorecon(tracesDir.getPath())) { 4114 return; 4115 } 4116 } 4117 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 4118 4119 if (tracesFile.exists()) { 4120 tracesTmp.delete(); 4121 tracesFile.renameTo(tracesTmp); 4122 } 4123 StringBuilder sb = new StringBuilder(); 4124 Time tobj = new Time(); 4125 tobj.set(System.currentTimeMillis()); 4126 sb.append(tobj.format("%Y-%m-%d %H:%M:%S")); 4127 sb.append(": "); 4128 TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb); 4129 sb.append(" since "); 4130 sb.append(msg); 4131 FileOutputStream fos = new FileOutputStream(tracesFile); 4132 fos.write(sb.toString().getBytes()); 4133 if (app == null) { 4134 fos.write("\n*** No application process!".getBytes()); 4135 } 4136 fos.close(); 4137 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 4138 } catch (IOException e) { 4139 Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e); 4140 return; 4141 } 4142 4143 if (app != null) { 4144 ArrayList<Integer> firstPids = new ArrayList<Integer>(); 4145 firstPids.add(app.pid); 4146 dumpStackTraces(tracesPath, firstPids, null, null, null); 4147 } 4148 4149 File lastTracesFile = null; 4150 File curTracesFile = null; 4151 for (int i=9; i>=0; i--) { 4152 String name = String.format(Locale.US, "slow%02d.txt", i); 4153 curTracesFile = new File(tracesDir, name); 4154 if (curTracesFile.exists()) { 4155 if (lastTracesFile != null) { 4156 curTracesFile.renameTo(lastTracesFile); 4157 } else { 4158 curTracesFile.delete(); 4159 } 4160 } 4161 lastTracesFile = curTracesFile; 4162 } 4163 tracesFile.renameTo(curTracesFile); 4164 if (tracesTmp.exists()) { 4165 tracesTmp.renameTo(tracesFile); 4166 } 4167 } finally { 4168 StrictMode.setThreadPolicy(oldPolicy); 4169 } 4170 } 4171 4172 final void appNotResponding(ProcessRecord app, ActivityRecord activity, 4173 ActivityRecord parent, boolean aboveSystem, final String annotation) { 4174 ArrayList<Integer> firstPids = new ArrayList<Integer>(5); 4175 SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20); 4176 4177 if (mController != null) { 4178 try { 4179 // 0 == continue, -1 = kill process immediately 4180 int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation); 4181 if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid); 4182 } catch (RemoteException e) { 4183 mController = null; 4184 Watchdog.getInstance().setActivityController(null); 4185 } 4186 } 4187 4188 long anrTime = SystemClock.uptimeMillis(); 4189 if (MONITOR_CPU_USAGE) { 4190 updateCpuStatsNow(); 4191 } 4192 4193 synchronized (this) { 4194 // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down. 4195 if (mShuttingDown) { 4196 Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation); 4197 return; 4198 } else if (app.notResponding) { 4199 Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation); 4200 return; 4201 } else if (app.crashing) { 4202 Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation); 4203 return; 4204 } 4205 4206 // In case we come through here for the same app before completing 4207 // this one, mark as anring now so we will bail out. 4208 app.notResponding = true; 4209 4210 // Log the ANR to the event log. 4211 EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid, 4212 app.processName, app.info.flags, annotation); 4213 4214 // Dump thread traces as quickly as we can, starting with "interesting" processes. 4215 firstPids.add(app.pid); 4216 4217 int parentPid = app.pid; 4218 if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid; 4219 if (parentPid != app.pid) firstPids.add(parentPid); 4220 4221 if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID); 4222 4223 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 4224 ProcessRecord r = mLruProcesses.get(i); 4225 if (r != null && r.thread != null) { 4226 int pid = r.pid; 4227 if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) { 4228 if (r.persistent) { 4229 firstPids.add(pid); 4230 } else { 4231 lastPids.put(pid, Boolean.TRUE); 4232 } 4233 } 4234 } 4235 } 4236 } 4237 4238 // Log the ANR to the main log. 4239 StringBuilder info = new StringBuilder(); 4240 info.setLength(0); 4241 info.append("ANR in ").append(app.processName); 4242 if (activity != null && activity.shortComponentName != null) { 4243 info.append(" (").append(activity.shortComponentName).append(")"); 4244 } 4245 info.append("\n"); 4246 info.append("PID: ").append(app.pid).append("\n"); 4247 if (annotation != null) { 4248 info.append("Reason: ").append(annotation).append("\n"); 4249 } 4250 if (parent != null && parent != activity) { 4251 info.append("Parent: ").append(parent.shortComponentName).append("\n"); 4252 } 4253 4254 final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true); 4255 4256 File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids, 4257 NATIVE_STACKS_OF_INTEREST); 4258 4259 String cpuInfo = null; 4260 if (MONITOR_CPU_USAGE) { 4261 updateCpuStatsNow(); 4262 synchronized (mProcessCpuThread) { 4263 cpuInfo = mProcessCpuTracker.printCurrentState(anrTime); 4264 } 4265 info.append(processCpuTracker.printCurrentLoad()); 4266 info.append(cpuInfo); 4267 } 4268 4269 info.append(processCpuTracker.printCurrentState(anrTime)); 4270 4271 Slog.e(TAG, info.toString()); 4272 if (tracesFile == null) { 4273 // There is no trace file, so dump (only) the alleged culprit's threads to the log 4274 Process.sendSignal(app.pid, Process.SIGNAL_QUIT); 4275 } 4276 4277 addErrorToDropBox("anr", app, app.processName, activity, parent, annotation, 4278 cpuInfo, tracesFile, null); 4279 4280 if (mController != null) { 4281 try { 4282 // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately 4283 int res = mController.appNotResponding(app.processName, app.pid, info.toString()); 4284 if (res != 0) { 4285 if (res < 0 && app.pid != MY_PID) { 4286 Process.killProcess(app.pid); 4287 } else { 4288 synchronized (this) { 4289 mServices.scheduleServiceTimeoutLocked(app); 4290 } 4291 } 4292 return; 4293 } 4294 } catch (RemoteException e) { 4295 mController = null; 4296 Watchdog.getInstance().setActivityController(null); 4297 } 4298 } 4299 4300 // Unless configured otherwise, swallow ANRs in background processes & kill the process. 4301 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), 4302 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; 4303 4304 synchronized (this) { 4305 if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) { 4306 killUnneededProcessLocked(app, "background ANR"); 4307 return; 4308 } 4309 4310 // Set the app's notResponding state, and look up the errorReportReceiver 4311 makeAppNotRespondingLocked(app, 4312 activity != null ? activity.shortComponentName : null, 4313 annotation != null ? "ANR " + annotation : "ANR", 4314 info.toString()); 4315 4316 // Bring up the infamous App Not Responding dialog 4317 Message msg = Message.obtain(); 4318 HashMap<String, Object> map = new HashMap<String, Object>(); 4319 msg.what = SHOW_NOT_RESPONDING_MSG; 4320 msg.obj = map; 4321 msg.arg1 = aboveSystem ? 1 : 0; 4322 map.put("app", app); 4323 if (activity != null) { 4324 map.put("activity", activity); 4325 } 4326 4327 mHandler.sendMessage(msg); 4328 } 4329 } 4330 4331 final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) { 4332 if (!mLaunchWarningShown) { 4333 mLaunchWarningShown = true; 4334 mHandler.post(new Runnable() { 4335 @Override 4336 public void run() { 4337 synchronized (ActivityManagerService.this) { 4338 final Dialog d = new LaunchWarningWindow(mContext, cur, next); 4339 d.show(); 4340 mHandler.postDelayed(new Runnable() { 4341 @Override 4342 public void run() { 4343 synchronized (ActivityManagerService.this) { 4344 d.dismiss(); 4345 mLaunchWarningShown = false; 4346 } 4347 } 4348 }, 4000); 4349 } 4350 } 4351 }); 4352 } 4353 } 4354 4355 @Override 4356 public boolean clearApplicationUserData(final String packageName, 4357 final IPackageDataObserver observer, int userId) { 4358 enforceNotIsolatedCaller("clearApplicationUserData"); 4359 int uid = Binder.getCallingUid(); 4360 int pid = Binder.getCallingPid(); 4361 userId = handleIncomingUser(pid, uid, 4362 userId, false, true, "clearApplicationUserData", null); 4363 long callingId = Binder.clearCallingIdentity(); 4364 try { 4365 IPackageManager pm = AppGlobals.getPackageManager(); 4366 int pkgUid = -1; 4367 synchronized(this) { 4368 try { 4369 pkgUid = pm.getPackageUid(packageName, userId); 4370 } catch (RemoteException e) { 4371 } 4372 if (pkgUid == -1) { 4373 Slog.w(TAG, "Invalid packageName: " + packageName); 4374 if (observer != null) { 4375 try { 4376 observer.onRemoveCompleted(packageName, false); 4377 } catch (RemoteException e) { 4378 Slog.i(TAG, "Observer no longer exists."); 4379 } 4380 } 4381 return false; 4382 } 4383 if (uid == pkgUid || checkComponentPermission( 4384 android.Manifest.permission.CLEAR_APP_USER_DATA, 4385 pid, uid, -1, true) 4386 == PackageManager.PERMISSION_GRANTED) { 4387 forceStopPackageLocked(packageName, pkgUid, "clear data"); 4388 } else { 4389 throw new SecurityException("PID " + pid + " does not have permission " 4390 + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data" 4391 + " of package " + packageName); 4392 } 4393 } 4394 4395 try { 4396 // Clear application user data 4397 pm.clearApplicationUserData(packageName, observer, userId); 4398 4399 // Remove all permissions granted from/to this package 4400 removeUriPermissionsForPackageLocked(packageName, userId, true); 4401 4402 Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED, 4403 Uri.fromParts("package", packageName, null)); 4404 intent.putExtra(Intent.EXTRA_UID, pkgUid); 4405 broadcastIntentInPackage("android", Process.SYSTEM_UID, intent, 4406 null, null, 0, null, null, null, false, false, userId); 4407 } catch (RemoteException e) { 4408 } 4409 } finally { 4410 Binder.restoreCallingIdentity(callingId); 4411 } 4412 return true; 4413 } 4414 4415 @Override 4416 public void killBackgroundProcesses(final String packageName, int userId) { 4417 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 4418 != PackageManager.PERMISSION_GRANTED && 4419 checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES) 4420 != PackageManager.PERMISSION_GRANTED) { 4421 String msg = "Permission Denial: killBackgroundProcesses() from pid=" 4422 + Binder.getCallingPid() 4423 + ", uid=" + Binder.getCallingUid() 4424 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 4425 Slog.w(TAG, msg); 4426 throw new SecurityException(msg); 4427 } 4428 4429 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 4430 userId, true, true, "killBackgroundProcesses", null); 4431 long callingId = Binder.clearCallingIdentity(); 4432 try { 4433 IPackageManager pm = AppGlobals.getPackageManager(); 4434 synchronized(this) { 4435 int appId = -1; 4436 try { 4437 appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0)); 4438 } catch (RemoteException e) { 4439 } 4440 if (appId == -1) { 4441 Slog.w(TAG, "Invalid packageName: " + packageName); 4442 return; 4443 } 4444 killPackageProcessesLocked(packageName, appId, userId, 4445 ProcessList.SERVICE_ADJ, false, true, true, false, "kill background"); 4446 } 4447 } finally { 4448 Binder.restoreCallingIdentity(callingId); 4449 } 4450 } 4451 4452 @Override 4453 public void killAllBackgroundProcesses() { 4454 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 4455 != PackageManager.PERMISSION_GRANTED) { 4456 String msg = "Permission Denial: killAllBackgroundProcesses() from pid=" 4457 + Binder.getCallingPid() 4458 + ", uid=" + Binder.getCallingUid() 4459 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 4460 Slog.w(TAG, msg); 4461 throw new SecurityException(msg); 4462 } 4463 4464 long callingId = Binder.clearCallingIdentity(); 4465 try { 4466 synchronized(this) { 4467 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 4468 final int NP = mProcessNames.getMap().size(); 4469 for (int ip=0; ip<NP; ip++) { 4470 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 4471 final int NA = apps.size(); 4472 for (int ia=0; ia<NA; ia++) { 4473 ProcessRecord app = apps.valueAt(ia); 4474 if (app.persistent) { 4475 // we don't kill persistent processes 4476 continue; 4477 } 4478 if (app.removed) { 4479 procs.add(app); 4480 } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 4481 app.removed = true; 4482 procs.add(app); 4483 } 4484 } 4485 } 4486 4487 int N = procs.size(); 4488 for (int i=0; i<N; i++) { 4489 removeProcessLocked(procs.get(i), false, true, "kill all background"); 4490 } 4491 mAllowLowerMemLevel = true; 4492 updateOomAdjLocked(); 4493 doLowMemReportIfNeededLocked(null); 4494 } 4495 } finally { 4496 Binder.restoreCallingIdentity(callingId); 4497 } 4498 } 4499 4500 @Override 4501 public void forceStopPackage(final String packageName, int userId) { 4502 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 4503 != PackageManager.PERMISSION_GRANTED) { 4504 String msg = "Permission Denial: forceStopPackage() from pid=" 4505 + Binder.getCallingPid() 4506 + ", uid=" + Binder.getCallingUid() 4507 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 4508 Slog.w(TAG, msg); 4509 throw new SecurityException(msg); 4510 } 4511 final int callingPid = Binder.getCallingPid(); 4512 userId = handleIncomingUser(callingPid, Binder.getCallingUid(), 4513 userId, true, true, "forceStopPackage", null); 4514 long callingId = Binder.clearCallingIdentity(); 4515 try { 4516 IPackageManager pm = AppGlobals.getPackageManager(); 4517 synchronized(this) { 4518 int[] users = userId == UserHandle.USER_ALL 4519 ? getUsersLocked() : new int[] { userId }; 4520 for (int user : users) { 4521 int pkgUid = -1; 4522 try { 4523 pkgUid = pm.getPackageUid(packageName, user); 4524 } catch (RemoteException e) { 4525 } 4526 if (pkgUid == -1) { 4527 Slog.w(TAG, "Invalid packageName: " + packageName); 4528 continue; 4529 } 4530 try { 4531 pm.setPackageStoppedState(packageName, true, user); 4532 } catch (RemoteException e) { 4533 } catch (IllegalArgumentException e) { 4534 Slog.w(TAG, "Failed trying to unstop package " 4535 + packageName + ": " + e); 4536 } 4537 if (isUserRunningLocked(user, false)) { 4538 forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid); 4539 } 4540 } 4541 } 4542 } finally { 4543 Binder.restoreCallingIdentity(callingId); 4544 } 4545 } 4546 4547 /* 4548 * The pkg name and app id have to be specified. 4549 */ 4550 @Override 4551 public void killApplicationWithAppId(String pkg, int appid, String reason) { 4552 if (pkg == null) { 4553 return; 4554 } 4555 // Make sure the uid is valid. 4556 if (appid < 0) { 4557 Slog.w(TAG, "Invalid appid specified for pkg : " + pkg); 4558 return; 4559 } 4560 int callerUid = Binder.getCallingUid(); 4561 // Only the system server can kill an application 4562 if (callerUid == Process.SYSTEM_UID) { 4563 // Post an aysnc message to kill the application 4564 Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG); 4565 msg.arg1 = appid; 4566 msg.arg2 = 0; 4567 Bundle bundle = new Bundle(); 4568 bundle.putString("pkg", pkg); 4569 bundle.putString("reason", reason); 4570 msg.obj = bundle; 4571 mHandler.sendMessage(msg); 4572 } else { 4573 throw new SecurityException(callerUid + " cannot kill pkg: " + 4574 pkg); 4575 } 4576 } 4577 4578 @Override 4579 public void closeSystemDialogs(String reason) { 4580 enforceNotIsolatedCaller("closeSystemDialogs"); 4581 4582 final int pid = Binder.getCallingPid(); 4583 final int uid = Binder.getCallingUid(); 4584 final long origId = Binder.clearCallingIdentity(); 4585 try { 4586 synchronized (this) { 4587 // Only allow this from foreground processes, so that background 4588 // applications can't abuse it to prevent system UI from being shown. 4589 if (uid >= Process.FIRST_APPLICATION_UID) { 4590 ProcessRecord proc; 4591 synchronized (mPidsSelfLocked) { 4592 proc = mPidsSelfLocked.get(pid); 4593 } 4594 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 4595 Slog.w(TAG, "Ignoring closeSystemDialogs " + reason 4596 + " from background process " + proc); 4597 return; 4598 } 4599 } 4600 closeSystemDialogsLocked(reason); 4601 } 4602 } finally { 4603 Binder.restoreCallingIdentity(origId); 4604 } 4605 } 4606 4607 void closeSystemDialogsLocked(String reason) { 4608 Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS); 4609 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 4610 | Intent.FLAG_RECEIVER_FOREGROUND); 4611 if (reason != null) { 4612 intent.putExtra("reason", reason); 4613 } 4614 mWindowManager.closeSystemDialogs(reason); 4615 4616 mStackSupervisor.closeSystemDialogsLocked(); 4617 4618 broadcastIntentLocked(null, null, intent, null, 4619 null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1, 4620 Process.SYSTEM_UID, UserHandle.USER_ALL); 4621 } 4622 4623 @Override 4624 public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) { 4625 enforceNotIsolatedCaller("getProcessMemoryInfo"); 4626 Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length]; 4627 for (int i=pids.length-1; i>=0; i--) { 4628 ProcessRecord proc; 4629 int oomAdj; 4630 synchronized (this) { 4631 synchronized (mPidsSelfLocked) { 4632 proc = mPidsSelfLocked.get(pids[i]); 4633 oomAdj = proc != null ? proc.setAdj : 0; 4634 } 4635 } 4636 infos[i] = new Debug.MemoryInfo(); 4637 Debug.getMemoryInfo(pids[i], infos[i]); 4638 if (proc != null) { 4639 synchronized (this) { 4640 if (proc.thread != null && proc.setAdj == oomAdj) { 4641 // Record this for posterity if the process has been stable. 4642 proc.baseProcessTracker.addPss(infos[i].getTotalPss(), 4643 infos[i].getTotalUss(), false, proc.pkgList); 4644 } 4645 } 4646 } 4647 } 4648 return infos; 4649 } 4650 4651 @Override 4652 public long[] getProcessPss(int[] pids) { 4653 enforceNotIsolatedCaller("getProcessPss"); 4654 long[] pss = new long[pids.length]; 4655 for (int i=pids.length-1; i>=0; i--) { 4656 ProcessRecord proc; 4657 int oomAdj; 4658 synchronized (this) { 4659 synchronized (mPidsSelfLocked) { 4660 proc = mPidsSelfLocked.get(pids[i]); 4661 oomAdj = proc != null ? proc.setAdj : 0; 4662 } 4663 } 4664 long[] tmpUss = new long[1]; 4665 pss[i] = Debug.getPss(pids[i], tmpUss); 4666 if (proc != null) { 4667 synchronized (this) { 4668 if (proc.thread != null && proc.setAdj == oomAdj) { 4669 // Record this for posterity if the process has been stable. 4670 proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList); 4671 } 4672 } 4673 } 4674 } 4675 return pss; 4676 } 4677 4678 @Override 4679 public void killApplicationProcess(String processName, int uid) { 4680 if (processName == null) { 4681 return; 4682 } 4683 4684 int callerUid = Binder.getCallingUid(); 4685 // Only the system server can kill an application 4686 if (callerUid == Process.SYSTEM_UID) { 4687 synchronized (this) { 4688 ProcessRecord app = getProcessRecordLocked(processName, uid, true); 4689 if (app != null && app.thread != null) { 4690 try { 4691 app.thread.scheduleSuicide(); 4692 } catch (RemoteException e) { 4693 // If the other end already died, then our work here is done. 4694 } 4695 } else { 4696 Slog.w(TAG, "Process/uid not found attempting kill of " 4697 + processName + " / " + uid); 4698 } 4699 } 4700 } else { 4701 throw new SecurityException(callerUid + " cannot kill app process: " + 4702 processName); 4703 } 4704 } 4705 4706 private void forceStopPackageLocked(final String packageName, int uid, String reason) { 4707 forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false, 4708 false, true, false, false, UserHandle.getUserId(uid), reason); 4709 Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED, 4710 Uri.fromParts("package", packageName, null)); 4711 if (!mProcessesReady) { 4712 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 4713 | Intent.FLAG_RECEIVER_FOREGROUND); 4714 } 4715 intent.putExtra(Intent.EXTRA_UID, uid); 4716 intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid)); 4717 broadcastIntentLocked(null, null, intent, 4718 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 4719 false, false, 4720 MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid)); 4721 } 4722 4723 private void forceStopUserLocked(int userId, String reason) { 4724 forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason); 4725 Intent intent = new Intent(Intent.ACTION_USER_STOPPED); 4726 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 4727 | Intent.FLAG_RECEIVER_FOREGROUND); 4728 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 4729 broadcastIntentLocked(null, null, intent, 4730 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 4731 false, false, 4732 MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 4733 } 4734 4735 private final boolean killPackageProcessesLocked(String packageName, int appId, 4736 int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart, 4737 boolean doit, boolean evenPersistent, String reason) { 4738 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 4739 4740 // Remove all processes this package may have touched: all with the 4741 // same UID (except for the system or root user), and all whose name 4742 // matches the package name. 4743 final String procNamePrefix = packageName != null ? (packageName + ":") : null; 4744 final int NP = mProcessNames.getMap().size(); 4745 for (int ip=0; ip<NP; ip++) { 4746 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 4747 final int NA = apps.size(); 4748 for (int ia=0; ia<NA; ia++) { 4749 ProcessRecord app = apps.valueAt(ia); 4750 if (app.persistent && !evenPersistent) { 4751 // we don't kill persistent processes 4752 continue; 4753 } 4754 if (app.removed) { 4755 if (doit) { 4756 procs.add(app); 4757 } 4758 continue; 4759 } 4760 4761 // Skip process if it doesn't meet our oom adj requirement. 4762 if (app.setAdj < minOomAdj) { 4763 continue; 4764 } 4765 4766 // If no package is specified, we call all processes under the 4767 // give user id. 4768 if (packageName == null) { 4769 if (app.userId != userId) { 4770 continue; 4771 } 4772 if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) { 4773 continue; 4774 } 4775 // Package has been specified, we want to hit all processes 4776 // that match it. We need to qualify this by the processes 4777 // that are running under the specified app and user ID. 4778 } else { 4779 if (UserHandle.getAppId(app.uid) != appId) { 4780 continue; 4781 } 4782 if (userId != UserHandle.USER_ALL && app.userId != userId) { 4783 continue; 4784 } 4785 if (!app.pkgList.containsKey(packageName)) { 4786 continue; 4787 } 4788 } 4789 4790 // Process has passed all conditions, kill it! 4791 if (!doit) { 4792 return true; 4793 } 4794 app.removed = true; 4795 procs.add(app); 4796 } 4797 } 4798 4799 int N = procs.size(); 4800 for (int i=0; i<N; i++) { 4801 removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason); 4802 } 4803 updateOomAdjLocked(); 4804 return N > 0; 4805 } 4806 4807 private final boolean forceStopPackageLocked(String name, int appId, 4808 boolean callerWillRestart, boolean purgeCache, boolean doit, 4809 boolean evenPersistent, boolean uninstalling, int userId, String reason) { 4810 int i; 4811 int N; 4812 4813 if (userId == UserHandle.USER_ALL && name == null) { 4814 Slog.w(TAG, "Can't force stop all processes of all users, that is insane!"); 4815 } 4816 4817 if (appId < 0 && name != null) { 4818 try { 4819 appId = UserHandle.getAppId( 4820 AppGlobals.getPackageManager().getPackageUid(name, 0)); 4821 } catch (RemoteException e) { 4822 } 4823 } 4824 4825 if (doit) { 4826 if (name != null) { 4827 Slog.i(TAG, "Force stopping " + name + " appid=" + appId 4828 + " user=" + userId + ": " + reason); 4829 } else { 4830 Slog.i(TAG, "Force stopping u" + userId + ": " + reason); 4831 } 4832 4833 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap(); 4834 for (int ip=pmap.size()-1; ip>=0; ip--) { 4835 SparseArray<Long> ba = pmap.valueAt(ip); 4836 for (i=ba.size()-1; i>=0; i--) { 4837 boolean remove = false; 4838 final int entUid = ba.keyAt(i); 4839 if (name != null) { 4840 if (userId == UserHandle.USER_ALL) { 4841 if (UserHandle.getAppId(entUid) == appId) { 4842 remove = true; 4843 } 4844 } else { 4845 if (entUid == UserHandle.getUid(userId, appId)) { 4846 remove = true; 4847 } 4848 } 4849 } else if (UserHandle.getUserId(entUid) == userId) { 4850 remove = true; 4851 } 4852 if (remove) { 4853 ba.removeAt(i); 4854 } 4855 } 4856 if (ba.size() == 0) { 4857 pmap.removeAt(ip); 4858 } 4859 } 4860 } 4861 4862 boolean didSomething = killPackageProcessesLocked(name, appId, userId, 4863 -100, callerWillRestart, true, doit, evenPersistent, 4864 name == null ? ("stop user " + userId) : ("stop " + name)); 4865 4866 if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) { 4867 if (!doit) { 4868 return true; 4869 } 4870 didSomething = true; 4871 } 4872 4873 if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) { 4874 if (!doit) { 4875 return true; 4876 } 4877 didSomething = true; 4878 } 4879 4880 if (name == null) { 4881 // Remove all sticky broadcasts from this user. 4882 mStickyBroadcasts.remove(userId); 4883 } 4884 4885 ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>(); 4886 if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent, 4887 userId, providers)) { 4888 if (!doit) { 4889 return true; 4890 } 4891 didSomething = true; 4892 } 4893 N = providers.size(); 4894 for (i=0; i<N; i++) { 4895 removeDyingProviderLocked(null, providers.get(i), true); 4896 } 4897 4898 // Remove transient permissions granted from/to this package/user 4899 removeUriPermissionsForPackageLocked(name, userId, false); 4900 4901 if (name == null || uninstalling) { 4902 // Remove pending intents. For now we only do this when force 4903 // stopping users, because we have some problems when doing this 4904 // for packages -- app widgets are not currently cleaned up for 4905 // such packages, so they can be left with bad pending intents. 4906 if (mIntentSenderRecords.size() > 0) { 4907 Iterator<WeakReference<PendingIntentRecord>> it 4908 = mIntentSenderRecords.values().iterator(); 4909 while (it.hasNext()) { 4910 WeakReference<PendingIntentRecord> wpir = it.next(); 4911 if (wpir == null) { 4912 it.remove(); 4913 continue; 4914 } 4915 PendingIntentRecord pir = wpir.get(); 4916 if (pir == null) { 4917 it.remove(); 4918 continue; 4919 } 4920 if (name == null) { 4921 // Stopping user, remove all objects for the user. 4922 if (pir.key.userId != userId) { 4923 // Not the same user, skip it. 4924 continue; 4925 } 4926 } else { 4927 if (UserHandle.getAppId(pir.uid) != appId) { 4928 // Different app id, skip it. 4929 continue; 4930 } 4931 if (userId != UserHandle.USER_ALL && pir.key.userId != userId) { 4932 // Different user, skip it. 4933 continue; 4934 } 4935 if (!pir.key.packageName.equals(name)) { 4936 // Different package, skip it. 4937 continue; 4938 } 4939 } 4940 if (!doit) { 4941 return true; 4942 } 4943 didSomething = true; 4944 it.remove(); 4945 pir.canceled = true; 4946 if (pir.key.activity != null) { 4947 pir.key.activity.pendingResults.remove(pir.ref); 4948 } 4949 } 4950 } 4951 } 4952 4953 if (doit) { 4954 if (purgeCache && name != null) { 4955 AttributeCache ac = AttributeCache.instance(); 4956 if (ac != null) { 4957 ac.removePackage(name); 4958 } 4959 } 4960 if (mBooted) { 4961 mStackSupervisor.resumeTopActivitiesLocked(); 4962 mStackSupervisor.scheduleIdleLocked(); 4963 } 4964 } 4965 4966 return didSomething; 4967 } 4968 4969 private final boolean removeProcessLocked(ProcessRecord app, 4970 boolean callerWillRestart, boolean allowRestart, String reason) { 4971 final String name = app.processName; 4972 final int uid = app.uid; 4973 if (DEBUG_PROCESSES) Slog.d( 4974 TAG, "Force removing proc " + app.toShortString() + " (" + name 4975 + "/" + uid + ")"); 4976 4977 mProcessNames.remove(name, uid); 4978 mIsolatedProcesses.remove(app.uid); 4979 if (mHeavyWeightProcess == app) { 4980 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 4981 mHeavyWeightProcess.userId, 0)); 4982 mHeavyWeightProcess = null; 4983 } 4984 boolean needRestart = false; 4985 if (app.pid > 0 && app.pid != MY_PID) { 4986 int pid = app.pid; 4987 synchronized (mPidsSelfLocked) { 4988 mPidsSelfLocked.remove(pid); 4989 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 4990 } 4991 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH, 4992 app.processName, app.info.uid); 4993 if (app.isolated) { 4994 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 4995 } 4996 killUnneededProcessLocked(app, reason); 4997 handleAppDiedLocked(app, true, allowRestart); 4998 removeLruProcessLocked(app); 4999 5000 if (app.persistent && !app.isolated) { 5001 if (!callerWillRestart) { 5002 addAppLocked(app.info, false); 5003 } else { 5004 needRestart = true; 5005 } 5006 } 5007 } else { 5008 mRemovedProcesses.add(app); 5009 } 5010 5011 return needRestart; 5012 } 5013 5014 private final void processStartTimedOutLocked(ProcessRecord app) { 5015 final int pid = app.pid; 5016 boolean gone = false; 5017 synchronized (mPidsSelfLocked) { 5018 ProcessRecord knownApp = mPidsSelfLocked.get(pid); 5019 if (knownApp != null && knownApp.thread == null) { 5020 mPidsSelfLocked.remove(pid); 5021 gone = true; 5022 } 5023 } 5024 5025 if (gone) { 5026 Slog.w(TAG, "Process " + app + " failed to attach"); 5027 EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId, 5028 pid, app.uid, app.processName); 5029 mProcessNames.remove(app.processName, app.uid); 5030 mIsolatedProcesses.remove(app.uid); 5031 if (mHeavyWeightProcess == app) { 5032 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 5033 mHeavyWeightProcess.userId, 0)); 5034 mHeavyWeightProcess = null; 5035 } 5036 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH, 5037 app.processName, app.info.uid); 5038 if (app.isolated) { 5039 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 5040 } 5041 // Take care of any launching providers waiting for this process. 5042 checkAppInLaunchingProvidersLocked(app, true); 5043 // Take care of any services that are waiting for the process. 5044 mServices.processStartTimedOutLocked(app); 5045 killUnneededProcessLocked(app, "start timeout"); 5046 if (mBackupTarget != null && mBackupTarget.app.pid == pid) { 5047 Slog.w(TAG, "Unattached app died before backup, skipping"); 5048 try { 5049 IBackupManager bm = IBackupManager.Stub.asInterface( 5050 ServiceManager.getService(Context.BACKUP_SERVICE)); 5051 bm.agentDisconnected(app.info.packageName); 5052 } catch (RemoteException e) { 5053 // Can't happen; the backup manager is local 5054 } 5055 } 5056 if (isPendingBroadcastProcessLocked(pid)) { 5057 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 5058 skipPendingBroadcastLocked(pid); 5059 } 5060 } else { 5061 Slog.w(TAG, "Spurious process start timeout - pid not known for " + app); 5062 } 5063 } 5064 5065 private final boolean attachApplicationLocked(IApplicationThread thread, 5066 int pid) { 5067 5068 // Find the application record that is being attached... either via 5069 // the pid if we are running in multiple processes, or just pull the 5070 // next app record if we are emulating process with anonymous threads. 5071 ProcessRecord app; 5072 if (pid != MY_PID && pid >= 0) { 5073 synchronized (mPidsSelfLocked) { 5074 app = mPidsSelfLocked.get(pid); 5075 } 5076 } else { 5077 app = null; 5078 } 5079 5080 if (app == null) { 5081 Slog.w(TAG, "No pending application record for pid " + pid 5082 + " (IApplicationThread " + thread + "); dropping process"); 5083 EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid); 5084 if (pid > 0 && pid != MY_PID) { 5085 Process.killProcessQuiet(pid); 5086 } else { 5087 try { 5088 thread.scheduleExit(); 5089 } catch (Exception e) { 5090 // Ignore exceptions. 5091 } 5092 } 5093 return false; 5094 } 5095 5096 // If this application record is still attached to a previous 5097 // process, clean it up now. 5098 if (app.thread != null) { 5099 handleAppDiedLocked(app, true, true); 5100 } 5101 5102 // Tell the process all about itself. 5103 5104 if (localLOGV) Slog.v( 5105 TAG, "Binding process pid " + pid + " to record " + app); 5106 5107 final String processName = app.processName; 5108 try { 5109 AppDeathRecipient adr = new AppDeathRecipient( 5110 app, pid, thread); 5111 thread.asBinder().linkToDeath(adr, 0); 5112 app.deathRecipient = adr; 5113 } catch (RemoteException e) { 5114 app.resetPackageList(mProcessStats); 5115 startProcessLocked(app, "link fail", processName); 5116 return false; 5117 } 5118 5119 EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName); 5120 5121 app.makeActive(thread, mProcessStats); 5122 app.curAdj = app.setAdj = -100; 5123 app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT; 5124 app.forcingToForeground = null; 5125 updateProcessForegroundLocked(app, false, false); 5126 app.hasShownUi = false; 5127 app.debugging = false; 5128 app.cached = false; 5129 5130 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 5131 5132 boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info); 5133 List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null; 5134 5135 if (!normalMode) { 5136 Slog.i(TAG, "Launching preboot mode app: " + app); 5137 } 5138 5139 if (localLOGV) Slog.v( 5140 TAG, "New app record " + app 5141 + " thread=" + thread.asBinder() + " pid=" + pid); 5142 try { 5143 int testMode = IApplicationThread.DEBUG_OFF; 5144 if (mDebugApp != null && mDebugApp.equals(processName)) { 5145 testMode = mWaitForDebugger 5146 ? IApplicationThread.DEBUG_WAIT 5147 : IApplicationThread.DEBUG_ON; 5148 app.debugging = true; 5149 if (mDebugTransient) { 5150 mDebugApp = mOrigDebugApp; 5151 mWaitForDebugger = mOrigWaitForDebugger; 5152 } 5153 } 5154 String profileFile = app.instrumentationProfileFile; 5155 ParcelFileDescriptor profileFd = null; 5156 boolean profileAutoStop = false; 5157 if (mProfileApp != null && mProfileApp.equals(processName)) { 5158 mProfileProc = app; 5159 profileFile = mProfileFile; 5160 profileFd = mProfileFd; 5161 profileAutoStop = mAutoStopProfiler; 5162 } 5163 boolean enableOpenGlTrace = false; 5164 if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) { 5165 enableOpenGlTrace = true; 5166 mOpenGlTraceApp = null; 5167 } 5168 5169 // If the app is being launched for restore or full backup, set it up specially 5170 boolean isRestrictedBackupMode = false; 5171 if (mBackupTarget != null && mBackupAppName.equals(processName)) { 5172 isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE) 5173 || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL) 5174 || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL); 5175 } 5176 5177 ensurePackageDexOpt(app.instrumentationInfo != null 5178 ? app.instrumentationInfo.packageName 5179 : app.info.packageName); 5180 if (app.instrumentationClass != null) { 5181 ensurePackageDexOpt(app.instrumentationClass.getPackageName()); 5182 } 5183 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc " 5184 + processName + " with config " + mConfiguration); 5185 ApplicationInfo appInfo = app.instrumentationInfo != null 5186 ? app.instrumentationInfo : app.info; 5187 app.compat = compatibilityInfoForPackageLocked(appInfo); 5188 if (profileFd != null) { 5189 profileFd = profileFd.dup(); 5190 } 5191 thread.bindApplication(processName, appInfo, providers, 5192 app.instrumentationClass, profileFile, profileFd, profileAutoStop, 5193 app.instrumentationArguments, app.instrumentationWatcher, 5194 app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace, 5195 isRestrictedBackupMode || !normalMode, app.persistent, 5196 new Configuration(mConfiguration), app.compat, getCommonServicesLocked(), 5197 mCoreSettingsObserver.getCoreSettingsLocked()); 5198 updateLruProcessLocked(app, false, null); 5199 app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis(); 5200 } catch (Exception e) { 5201 // todo: Yikes! What should we do? For now we will try to 5202 // start another process, but that could easily get us in 5203 // an infinite loop of restarting processes... 5204 Slog.w(TAG, "Exception thrown during bind!", e); 5205 5206 app.resetPackageList(mProcessStats); 5207 app.unlinkDeathRecipient(); 5208 startProcessLocked(app, "bind fail", processName); 5209 return false; 5210 } 5211 5212 // Remove this record from the list of starting applications. 5213 mPersistentStartingProcesses.remove(app); 5214 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 5215 "Attach application locked removing on hold: " + app); 5216 mProcessesOnHold.remove(app); 5217 5218 boolean badApp = false; 5219 boolean didSomething = false; 5220 5221 // See if the top visible activity is waiting to run in this process... 5222 if (normalMode) { 5223 try { 5224 if (mStackSupervisor.attachApplicationLocked(app)) { 5225 didSomething = true; 5226 } 5227 } catch (Exception e) { 5228 badApp = true; 5229 } 5230 } 5231 5232 // Find any services that should be running in this process... 5233 if (!badApp) { 5234 try { 5235 didSomething |= mServices.attachApplicationLocked(app, processName); 5236 } catch (Exception e) { 5237 badApp = true; 5238 } 5239 } 5240 5241 // Check if a next-broadcast receiver is in this process... 5242 if (!badApp && isPendingBroadcastProcessLocked(pid)) { 5243 try { 5244 didSomething |= sendPendingBroadcastsLocked(app); 5245 } catch (Exception e) { 5246 // If the app died trying to launch the receiver we declare it 'bad' 5247 badApp = true; 5248 } 5249 } 5250 5251 // Check whether the next backup agent is in this process... 5252 if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) { 5253 if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app); 5254 ensurePackageDexOpt(mBackupTarget.appInfo.packageName); 5255 try { 5256 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo, 5257 compatibilityInfoForPackageLocked(mBackupTarget.appInfo), 5258 mBackupTarget.backupMode); 5259 } catch (Exception e) { 5260 Slog.w(TAG, "Exception scheduling backup agent creation: "); 5261 e.printStackTrace(); 5262 } 5263 } 5264 5265 if (badApp) { 5266 // todo: Also need to kill application to deal with all 5267 // kinds of exceptions. 5268 handleAppDiedLocked(app, false, true); 5269 return false; 5270 } 5271 5272 if (!didSomething) { 5273 updateOomAdjLocked(); 5274 } 5275 5276 return true; 5277 } 5278 5279 @Override 5280 public final void attachApplication(IApplicationThread thread) { 5281 synchronized (this) { 5282 int callingPid = Binder.getCallingPid(); 5283 final long origId = Binder.clearCallingIdentity(); 5284 attachApplicationLocked(thread, callingPid); 5285 Binder.restoreCallingIdentity(origId); 5286 } 5287 } 5288 5289 @Override 5290 public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) { 5291 final long origId = Binder.clearCallingIdentity(); 5292 synchronized (this) { 5293 ActivityStack stack = ActivityRecord.getStackLocked(token); 5294 if (stack != null) { 5295 ActivityRecord r = 5296 mStackSupervisor.activityIdleInternalLocked(token, false, config); 5297 if (stopProfiling) { 5298 if ((mProfileProc == r.app) && (mProfileFd != null)) { 5299 try { 5300 mProfileFd.close(); 5301 } catch (IOException e) { 5302 } 5303 clearProfilerLocked(); 5304 } 5305 } 5306 } 5307 } 5308 Binder.restoreCallingIdentity(origId); 5309 } 5310 5311 void enableScreenAfterBoot() { 5312 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN, 5313 SystemClock.uptimeMillis()); 5314 mWindowManager.enableScreenAfterBoot(); 5315 5316 synchronized (this) { 5317 updateEventDispatchingLocked(); 5318 } 5319 } 5320 5321 @Override 5322 public void showBootMessage(final CharSequence msg, final boolean always) { 5323 enforceNotIsolatedCaller("showBootMessage"); 5324 mWindowManager.showBootMessage(msg, always); 5325 } 5326 5327 @Override 5328 public void dismissKeyguardOnNextActivity() { 5329 enforceNotIsolatedCaller("dismissKeyguardOnNextActivity"); 5330 final long token = Binder.clearCallingIdentity(); 5331 try { 5332 synchronized (this) { 5333 if (DEBUG_LOCKSCREEN) logLockScreen(""); 5334 if (mLockScreenShown) { 5335 mLockScreenShown = false; 5336 comeOutOfSleepIfNeededLocked(); 5337 } 5338 mStackSupervisor.setDismissKeyguard(true); 5339 } 5340 } finally { 5341 Binder.restoreCallingIdentity(token); 5342 } 5343 } 5344 5345 final void finishBooting() { 5346 // Register receivers to handle package update events 5347 mPackageMonitor.register(mContext, Looper.getMainLooper(), false); 5348 5349 synchronized (this) { 5350 // Ensure that any processes we had put on hold are now started 5351 // up. 5352 final int NP = mProcessesOnHold.size(); 5353 if (NP > 0) { 5354 ArrayList<ProcessRecord> procs = 5355 new ArrayList<ProcessRecord>(mProcessesOnHold); 5356 for (int ip=0; ip<NP; ip++) { 5357 if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: " 5358 + procs.get(ip)); 5359 startProcessLocked(procs.get(ip), "on-hold", null); 5360 } 5361 } 5362 5363 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 5364 // Start looking for apps that are abusing wake locks. 5365 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 5366 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 5367 // Tell anyone interested that we are done booting! 5368 SystemProperties.set("sys.boot_completed", "1"); 5369 SystemProperties.set("dev.bootcomplete", "1"); 5370 for (int i=0; i<mStartedUsers.size(); i++) { 5371 UserStartedState uss = mStartedUsers.valueAt(i); 5372 if (uss.mState == UserStartedState.STATE_BOOTING) { 5373 uss.mState = UserStartedState.STATE_RUNNING; 5374 final int userId = mStartedUsers.keyAt(i); 5375 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 5376 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 5377 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT); 5378 broadcastIntentLocked(null, null, intent, null, 5379 new IIntentReceiver.Stub() { 5380 @Override 5381 public void performReceive(Intent intent, int resultCode, 5382 String data, Bundle extras, boolean ordered, 5383 boolean sticky, int sendingUser) { 5384 synchronized (ActivityManagerService.this) { 5385 requestPssAllProcsLocked(SystemClock.uptimeMillis(), 5386 true, false); 5387 } 5388 } 5389 }, 5390 0, null, null, 5391 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, 5392 AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID, 5393 userId); 5394 } 5395 } 5396 scheduleStartProfilesLocked(); 5397 } 5398 } 5399 } 5400 5401 final void ensureBootCompleted() { 5402 boolean booting; 5403 boolean enableScreen; 5404 synchronized (this) { 5405 booting = mBooting; 5406 mBooting = false; 5407 enableScreen = !mBooted; 5408 mBooted = true; 5409 } 5410 5411 if (booting) { 5412 finishBooting(); 5413 } 5414 5415 if (enableScreen) { 5416 enableScreenAfterBoot(); 5417 } 5418 } 5419 5420 @Override 5421 public final void activityResumed(IBinder token) { 5422 final long origId = Binder.clearCallingIdentity(); 5423 synchronized(this) { 5424 ActivityStack stack = ActivityRecord.getStackLocked(token); 5425 if (stack != null) { 5426 ActivityRecord.activityResumedLocked(token); 5427 } 5428 } 5429 Binder.restoreCallingIdentity(origId); 5430 } 5431 5432 @Override 5433 public final void activityPaused(IBinder token, PersistableBundle persistentState) { 5434 final long origId = Binder.clearCallingIdentity(); 5435 synchronized(this) { 5436 ActivityStack stack = ActivityRecord.getStackLocked(token); 5437 if (stack != null) { 5438 stack.activityPausedLocked(token, false, persistentState); 5439 } 5440 } 5441 Binder.restoreCallingIdentity(origId); 5442 } 5443 5444 @Override 5445 public final void activityStopped(IBinder token, Bundle icicle, 5446 PersistableBundle persistentState, CharSequence description) { 5447 if (localLOGV) Slog.v(TAG, "Activity stopped: token=" + token); 5448 5449 // Refuse possible leaked file descriptors 5450 if (icicle != null && icicle.hasFileDescriptors()) { 5451 throw new IllegalArgumentException("File descriptors passed in Bundle"); 5452 } 5453 5454 final long origId = Binder.clearCallingIdentity(); 5455 5456 synchronized (this) { 5457 ActivityRecord r = ActivityRecord.isInStackLocked(token); 5458 if (r != null) { 5459 r.task.stack.activityStoppedLocked(r, icicle, persistentState, description); 5460 } 5461 } 5462 5463 trimApplications(); 5464 5465 Binder.restoreCallingIdentity(origId); 5466 } 5467 5468 @Override 5469 public final void activityDestroyed(IBinder token) { 5470 if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token); 5471 synchronized (this) { 5472 ActivityStack stack = ActivityRecord.getStackLocked(token); 5473 if (stack != null) { 5474 stack.activityDestroyedLocked(token); 5475 } 5476 } 5477 } 5478 5479 @Override 5480 public String getCallingPackage(IBinder token) { 5481 synchronized (this) { 5482 ActivityRecord r = getCallingRecordLocked(token); 5483 return r != null ? r.info.packageName : null; 5484 } 5485 } 5486 5487 @Override 5488 public ComponentName getCallingActivity(IBinder token) { 5489 synchronized (this) { 5490 ActivityRecord r = getCallingRecordLocked(token); 5491 return r != null ? r.intent.getComponent() : null; 5492 } 5493 } 5494 5495 private ActivityRecord getCallingRecordLocked(IBinder token) { 5496 ActivityRecord r = ActivityRecord.isInStackLocked(token); 5497 if (r == null) { 5498 return null; 5499 } 5500 return r.resultTo; 5501 } 5502 5503 @Override 5504 public ComponentName getActivityClassForToken(IBinder token) { 5505 synchronized(this) { 5506 ActivityRecord r = ActivityRecord.isInStackLocked(token); 5507 if (r == null) { 5508 return null; 5509 } 5510 return r.intent.getComponent(); 5511 } 5512 } 5513 5514 @Override 5515 public String getPackageForToken(IBinder token) { 5516 synchronized(this) { 5517 ActivityRecord r = ActivityRecord.isInStackLocked(token); 5518 if (r == null) { 5519 return null; 5520 } 5521 return r.packageName; 5522 } 5523 } 5524 5525 @Override 5526 public IIntentSender getIntentSender(int type, 5527 String packageName, IBinder token, String resultWho, 5528 int requestCode, Intent[] intents, String[] resolvedTypes, 5529 int flags, Bundle options, int userId) { 5530 enforceNotIsolatedCaller("getIntentSender"); 5531 // Refuse possible leaked file descriptors 5532 if (intents != null) { 5533 if (intents.length < 1) { 5534 throw new IllegalArgumentException("Intents array length must be >= 1"); 5535 } 5536 for (int i=0; i<intents.length; i++) { 5537 Intent intent = intents[i]; 5538 if (intent != null) { 5539 if (intent.hasFileDescriptors()) { 5540 throw new IllegalArgumentException("File descriptors passed in Intent"); 5541 } 5542 if (type == ActivityManager.INTENT_SENDER_BROADCAST && 5543 (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 5544 throw new IllegalArgumentException( 5545 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 5546 } 5547 intents[i] = new Intent(intent); 5548 } 5549 } 5550 if (resolvedTypes != null && resolvedTypes.length != intents.length) { 5551 throw new IllegalArgumentException( 5552 "Intent array length does not match resolvedTypes length"); 5553 } 5554 } 5555 if (options != null) { 5556 if (options.hasFileDescriptors()) { 5557 throw new IllegalArgumentException("File descriptors passed in options"); 5558 } 5559 } 5560 5561 synchronized(this) { 5562 int callingUid = Binder.getCallingUid(); 5563 int origUserId = userId; 5564 userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId, 5565 type == ActivityManager.INTENT_SENDER_BROADCAST, false, 5566 "getIntentSender", null); 5567 if (origUserId == UserHandle.USER_CURRENT) { 5568 // We don't want to evaluate this until the pending intent is 5569 // actually executed. However, we do want to always do the 5570 // security checking for it above. 5571 userId = UserHandle.USER_CURRENT; 5572 } 5573 try { 5574 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 5575 int uid = AppGlobals.getPackageManager() 5576 .getPackageUid(packageName, UserHandle.getUserId(callingUid)); 5577 if (!UserHandle.isSameApp(callingUid, uid)) { 5578 String msg = "Permission Denial: getIntentSender() from pid=" 5579 + Binder.getCallingPid() 5580 + ", uid=" + Binder.getCallingUid() 5581 + ", (need uid=" + uid + ")" 5582 + " is not allowed to send as package " + packageName; 5583 Slog.w(TAG, msg); 5584 throw new SecurityException(msg); 5585 } 5586 } 5587 5588 return getIntentSenderLocked(type, packageName, callingUid, userId, 5589 token, resultWho, requestCode, intents, resolvedTypes, flags, options); 5590 5591 } catch (RemoteException e) { 5592 throw new SecurityException(e); 5593 } 5594 } 5595 } 5596 5597 IIntentSender getIntentSenderLocked(int type, String packageName, 5598 int callingUid, int userId, IBinder token, String resultWho, 5599 int requestCode, Intent[] intents, String[] resolvedTypes, int flags, 5600 Bundle options) { 5601 if (DEBUG_MU) 5602 Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid); 5603 ActivityRecord activity = null; 5604 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 5605 activity = ActivityRecord.isInStackLocked(token); 5606 if (activity == null) { 5607 return null; 5608 } 5609 if (activity.finishing) { 5610 return null; 5611 } 5612 } 5613 5614 final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0; 5615 final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0; 5616 final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0; 5617 flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT 5618 |PendingIntent.FLAG_UPDATE_CURRENT); 5619 5620 PendingIntentRecord.Key key = new PendingIntentRecord.Key( 5621 type, packageName, activity, resultWho, 5622 requestCode, intents, resolvedTypes, flags, options, userId); 5623 WeakReference<PendingIntentRecord> ref; 5624 ref = mIntentSenderRecords.get(key); 5625 PendingIntentRecord rec = ref != null ? ref.get() : null; 5626 if (rec != null) { 5627 if (!cancelCurrent) { 5628 if (updateCurrent) { 5629 if (rec.key.requestIntent != null) { 5630 rec.key.requestIntent.replaceExtras(intents != null ? 5631 intents[intents.length - 1] : null); 5632 } 5633 if (intents != null) { 5634 intents[intents.length-1] = rec.key.requestIntent; 5635 rec.key.allIntents = intents; 5636 rec.key.allResolvedTypes = resolvedTypes; 5637 } else { 5638 rec.key.allIntents = null; 5639 rec.key.allResolvedTypes = null; 5640 } 5641 } 5642 return rec; 5643 } 5644 rec.canceled = true; 5645 mIntentSenderRecords.remove(key); 5646 } 5647 if (noCreate) { 5648 return rec; 5649 } 5650 rec = new PendingIntentRecord(this, key, callingUid); 5651 mIntentSenderRecords.put(key, rec.ref); 5652 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 5653 if (activity.pendingResults == null) { 5654 activity.pendingResults 5655 = new HashSet<WeakReference<PendingIntentRecord>>(); 5656 } 5657 activity.pendingResults.add(rec.ref); 5658 } 5659 return rec; 5660 } 5661 5662 @Override 5663 public void cancelIntentSender(IIntentSender sender) { 5664 if (!(sender instanceof PendingIntentRecord)) { 5665 return; 5666 } 5667 synchronized(this) { 5668 PendingIntentRecord rec = (PendingIntentRecord)sender; 5669 try { 5670 int uid = AppGlobals.getPackageManager() 5671 .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId()); 5672 if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) { 5673 String msg = "Permission Denial: cancelIntentSender() from pid=" 5674 + Binder.getCallingPid() 5675 + ", uid=" + Binder.getCallingUid() 5676 + " is not allowed to cancel packges " 5677 + rec.key.packageName; 5678 Slog.w(TAG, msg); 5679 throw new SecurityException(msg); 5680 } 5681 } catch (RemoteException e) { 5682 throw new SecurityException(e); 5683 } 5684 cancelIntentSenderLocked(rec, true); 5685 } 5686 } 5687 5688 void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) { 5689 rec.canceled = true; 5690 mIntentSenderRecords.remove(rec.key); 5691 if (cleanActivity && rec.key.activity != null) { 5692 rec.key.activity.pendingResults.remove(rec.ref); 5693 } 5694 } 5695 5696 @Override 5697 public String getPackageForIntentSender(IIntentSender pendingResult) { 5698 if (!(pendingResult instanceof PendingIntentRecord)) { 5699 return null; 5700 } 5701 try { 5702 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5703 return res.key.packageName; 5704 } catch (ClassCastException e) { 5705 } 5706 return null; 5707 } 5708 5709 @Override 5710 public int getUidForIntentSender(IIntentSender sender) { 5711 if (sender instanceof PendingIntentRecord) { 5712 try { 5713 PendingIntentRecord res = (PendingIntentRecord)sender; 5714 return res.uid; 5715 } catch (ClassCastException e) { 5716 } 5717 } 5718 return -1; 5719 } 5720 5721 @Override 5722 public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) { 5723 if (!(pendingResult instanceof PendingIntentRecord)) { 5724 return false; 5725 } 5726 try { 5727 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5728 if (res.key.allIntents == null) { 5729 return false; 5730 } 5731 for (int i=0; i<res.key.allIntents.length; i++) { 5732 Intent intent = res.key.allIntents[i]; 5733 if (intent.getPackage() != null && intent.getComponent() != null) { 5734 return false; 5735 } 5736 } 5737 return true; 5738 } catch (ClassCastException e) { 5739 } 5740 return false; 5741 } 5742 5743 @Override 5744 public boolean isIntentSenderAnActivity(IIntentSender pendingResult) { 5745 if (!(pendingResult instanceof PendingIntentRecord)) { 5746 return false; 5747 } 5748 try { 5749 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5750 if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) { 5751 return true; 5752 } 5753 return false; 5754 } catch (ClassCastException e) { 5755 } 5756 return false; 5757 } 5758 5759 @Override 5760 public Intent getIntentForIntentSender(IIntentSender pendingResult) { 5761 if (!(pendingResult instanceof PendingIntentRecord)) { 5762 return null; 5763 } 5764 try { 5765 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5766 return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null; 5767 } catch (ClassCastException e) { 5768 } 5769 return null; 5770 } 5771 5772 @Override 5773 public String getTagForIntentSender(IIntentSender pendingResult, String prefix) { 5774 if (!(pendingResult instanceof PendingIntentRecord)) { 5775 return null; 5776 } 5777 try { 5778 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5779 Intent intent = res.key.requestIntent; 5780 if (intent != null) { 5781 if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null 5782 || res.lastTagPrefix.equals(prefix))) { 5783 return res.lastTag; 5784 } 5785 res.lastTagPrefix = prefix; 5786 StringBuilder sb = new StringBuilder(128); 5787 if (prefix != null) { 5788 sb.append(prefix); 5789 } 5790 if (intent.getAction() != null) { 5791 sb.append(intent.getAction()); 5792 } else if (intent.getComponent() != null) { 5793 intent.getComponent().appendShortString(sb); 5794 } else { 5795 sb.append("?"); 5796 } 5797 return res.lastTag = sb.toString(); 5798 } 5799 } catch (ClassCastException e) { 5800 } 5801 return null; 5802 } 5803 5804 @Override 5805 public void setProcessLimit(int max) { 5806 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 5807 "setProcessLimit()"); 5808 synchronized (this) { 5809 mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max; 5810 mProcessLimitOverride = max; 5811 } 5812 trimApplications(); 5813 } 5814 5815 @Override 5816 public int getProcessLimit() { 5817 synchronized (this) { 5818 return mProcessLimitOverride; 5819 } 5820 } 5821 5822 void foregroundTokenDied(ForegroundToken token) { 5823 synchronized (ActivityManagerService.this) { 5824 synchronized (mPidsSelfLocked) { 5825 ForegroundToken cur 5826 = mForegroundProcesses.get(token.pid); 5827 if (cur != token) { 5828 return; 5829 } 5830 mForegroundProcesses.remove(token.pid); 5831 ProcessRecord pr = mPidsSelfLocked.get(token.pid); 5832 if (pr == null) { 5833 return; 5834 } 5835 pr.forcingToForeground = null; 5836 updateProcessForegroundLocked(pr, false, false); 5837 } 5838 updateOomAdjLocked(); 5839 } 5840 } 5841 5842 @Override 5843 public void setProcessForeground(IBinder token, int pid, boolean isForeground) { 5844 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 5845 "setProcessForeground()"); 5846 synchronized(this) { 5847 boolean changed = false; 5848 5849 synchronized (mPidsSelfLocked) { 5850 ProcessRecord pr = mPidsSelfLocked.get(pid); 5851 if (pr == null && isForeground) { 5852 Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid); 5853 return; 5854 } 5855 ForegroundToken oldToken = mForegroundProcesses.get(pid); 5856 if (oldToken != null) { 5857 oldToken.token.unlinkToDeath(oldToken, 0); 5858 mForegroundProcesses.remove(pid); 5859 if (pr != null) { 5860 pr.forcingToForeground = null; 5861 } 5862 changed = true; 5863 } 5864 if (isForeground && token != null) { 5865 ForegroundToken newToken = new ForegroundToken() { 5866 @Override 5867 public void binderDied() { 5868 foregroundTokenDied(this); 5869 } 5870 }; 5871 newToken.pid = pid; 5872 newToken.token = token; 5873 try { 5874 token.linkToDeath(newToken, 0); 5875 mForegroundProcesses.put(pid, newToken); 5876 pr.forcingToForeground = token; 5877 changed = true; 5878 } catch (RemoteException e) { 5879 // If the process died while doing this, we will later 5880 // do the cleanup with the process death link. 5881 } 5882 } 5883 } 5884 5885 if (changed) { 5886 updateOomAdjLocked(); 5887 } 5888 } 5889 } 5890 5891 // ========================================================= 5892 // PERMISSIONS 5893 // ========================================================= 5894 5895 static class PermissionController extends IPermissionController.Stub { 5896 ActivityManagerService mActivityManagerService; 5897 PermissionController(ActivityManagerService activityManagerService) { 5898 mActivityManagerService = activityManagerService; 5899 } 5900 5901 @Override 5902 public boolean checkPermission(String permission, int pid, int uid) { 5903 return mActivityManagerService.checkPermission(permission, pid, 5904 uid) == PackageManager.PERMISSION_GRANTED; 5905 } 5906 } 5907 5908 class IntentFirewallInterface implements IntentFirewall.AMSInterface { 5909 @Override 5910 public int checkComponentPermission(String permission, int pid, int uid, 5911 int owningUid, boolean exported) { 5912 return ActivityManagerService.this.checkComponentPermission(permission, pid, uid, 5913 owningUid, exported); 5914 } 5915 5916 @Override 5917 public Object getAMSLock() { 5918 return ActivityManagerService.this; 5919 } 5920 } 5921 5922 /** 5923 * This can be called with or without the global lock held. 5924 */ 5925 int checkComponentPermission(String permission, int pid, int uid, 5926 int owningUid, boolean exported) { 5927 // We might be performing an operation on behalf of an indirect binder 5928 // invocation, e.g. via {@link #openContentUri}. Check and adjust the 5929 // client identity accordingly before proceeding. 5930 Identity tlsIdentity = sCallerIdentity.get(); 5931 if (tlsIdentity != null) { 5932 Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {" 5933 + tlsIdentity.pid + "," + tlsIdentity.uid + "}"); 5934 uid = tlsIdentity.uid; 5935 pid = tlsIdentity.pid; 5936 } 5937 5938 if (pid == MY_PID) { 5939 return PackageManager.PERMISSION_GRANTED; 5940 } 5941 5942 return ActivityManager.checkComponentPermission(permission, uid, 5943 owningUid, exported); 5944 } 5945 5946 /** 5947 * As the only public entry point for permissions checking, this method 5948 * can enforce the semantic that requesting a check on a null global 5949 * permission is automatically denied. (Internally a null permission 5950 * string is used when calling {@link #checkComponentPermission} in cases 5951 * when only uid-based security is needed.) 5952 * 5953 * This can be called with or without the global lock held. 5954 */ 5955 @Override 5956 public int checkPermission(String permission, int pid, int uid) { 5957 if (permission == null) { 5958 return PackageManager.PERMISSION_DENIED; 5959 } 5960 return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true); 5961 } 5962 5963 /** 5964 * Binder IPC calls go through the public entry point. 5965 * This can be called with or without the global lock held. 5966 */ 5967 int checkCallingPermission(String permission) { 5968 return checkPermission(permission, 5969 Binder.getCallingPid(), 5970 UserHandle.getAppId(Binder.getCallingUid())); 5971 } 5972 5973 /** 5974 * This can be called with or without the global lock held. 5975 */ 5976 void enforceCallingPermission(String permission, String func) { 5977 if (checkCallingPermission(permission) 5978 == PackageManager.PERMISSION_GRANTED) { 5979 return; 5980 } 5981 5982 String msg = "Permission Denial: " + func + " from pid=" 5983 + Binder.getCallingPid() 5984 + ", uid=" + Binder.getCallingUid() 5985 + " requires " + permission; 5986 Slog.w(TAG, msg); 5987 throw new SecurityException(msg); 5988 } 5989 5990 /** 5991 * Determine if UID is holding permissions required to access {@link Uri} in 5992 * the given {@link ProviderInfo}. Final permission checking is always done 5993 * in {@link ContentProvider}. 5994 */ 5995 private final boolean checkHoldingPermissionsLocked( 5996 IPackageManager pm, ProviderInfo pi, Uri uri, int uid, final int modeFlags) { 5997 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5998 "checkHoldingPermissionsLocked: uri=" + uri + " uid=" + uid); 5999 6000 if (pi.applicationInfo.uid == uid) { 6001 return true; 6002 } else if (!pi.exported) { 6003 return false; 6004 } 6005 6006 boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0; 6007 boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0; 6008 try { 6009 // check if target holds top-level <provider> permissions 6010 if (!readMet && pi.readPermission != null 6011 && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) { 6012 readMet = true; 6013 } 6014 if (!writeMet && pi.writePermission != null 6015 && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) { 6016 writeMet = true; 6017 } 6018 6019 // track if unprotected read/write is allowed; any denied 6020 // <path-permission> below removes this ability 6021 boolean allowDefaultRead = pi.readPermission == null; 6022 boolean allowDefaultWrite = pi.writePermission == null; 6023 6024 // check if target holds any <path-permission> that match uri 6025 final PathPermission[] pps = pi.pathPermissions; 6026 if (pps != null) { 6027 final String path = uri.getPath(); 6028 int i = pps.length; 6029 while (i > 0 && (!readMet || !writeMet)) { 6030 i--; 6031 PathPermission pp = pps[i]; 6032 if (pp.match(path)) { 6033 if (!readMet) { 6034 final String pprperm = pp.getReadPermission(); 6035 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for " 6036 + pprperm + " for " + pp.getPath() 6037 + ": match=" + pp.match(path) 6038 + " check=" + pm.checkUidPermission(pprperm, uid)); 6039 if (pprperm != null) { 6040 if (pm.checkUidPermission(pprperm, uid) == PERMISSION_GRANTED) { 6041 readMet = true; 6042 } else { 6043 allowDefaultRead = false; 6044 } 6045 } 6046 } 6047 if (!writeMet) { 6048 final String ppwperm = pp.getWritePermission(); 6049 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm " 6050 + ppwperm + " for " + pp.getPath() 6051 + ": match=" + pp.match(path) 6052 + " check=" + pm.checkUidPermission(ppwperm, uid)); 6053 if (ppwperm != null) { 6054 if (pm.checkUidPermission(ppwperm, uid) == PERMISSION_GRANTED) { 6055 writeMet = true; 6056 } else { 6057 allowDefaultWrite = false; 6058 } 6059 } 6060 } 6061 } 6062 } 6063 } 6064 6065 // grant unprotected <provider> read/write, if not blocked by 6066 // <path-permission> above 6067 if (allowDefaultRead) readMet = true; 6068 if (allowDefaultWrite) writeMet = true; 6069 6070 } catch (RemoteException e) { 6071 return false; 6072 } 6073 6074 return readMet && writeMet; 6075 } 6076 6077 private ProviderInfo getProviderInfoLocked(String authority, int userHandle) { 6078 ProviderInfo pi = null; 6079 ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle); 6080 if (cpr != null) { 6081 pi = cpr.info; 6082 } else { 6083 try { 6084 pi = AppGlobals.getPackageManager().resolveContentProvider( 6085 authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle); 6086 } catch (RemoteException ex) { 6087 } 6088 } 6089 return pi; 6090 } 6091 6092 private UriPermission findUriPermissionLocked(int targetUid, GrantUri uri) { 6093 final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid); 6094 if (targetUris != null) { 6095 return targetUris.get(uri); 6096 } 6097 return null; 6098 } 6099 6100 private UriPermission findOrCreateUriPermissionLocked(String sourcePkg, 6101 String targetPkg, int targetUid, GrantUri uri) { 6102 ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid); 6103 if (targetUris == null) { 6104 targetUris = Maps.newArrayMap(); 6105 mGrantedUriPermissions.put(targetUid, targetUris); 6106 } 6107 6108 UriPermission perm = targetUris.get(uri); 6109 if (perm == null) { 6110 perm = new UriPermission(sourcePkg, targetPkg, targetUid, uri); 6111 targetUris.put(uri, perm); 6112 } 6113 6114 return perm; 6115 } 6116 6117 private final boolean checkUriPermissionLocked(Uri uri, int uid, final int modeFlags) { 6118 final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0; 6119 final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE 6120 : UriPermission.STRENGTH_OWNED; 6121 6122 // Root gets to do everything. 6123 if (uid == 0) { 6124 return true; 6125 } 6126 6127 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid); 6128 if (perms == null) return false; 6129 6130 // First look for exact match 6131 final UriPermission exactPerm = perms.get(new GrantUri(uri, false)); 6132 if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) { 6133 return true; 6134 } 6135 6136 // No exact match, look for prefixes 6137 final int N = perms.size(); 6138 for (int i = 0; i < N; i++) { 6139 final UriPermission perm = perms.valueAt(i); 6140 if (perm.uri.prefix && uri.isPathPrefixMatch(perm.uri.uri) 6141 && perm.getStrength(modeFlags) >= minStrength) { 6142 return true; 6143 } 6144 } 6145 6146 return false; 6147 } 6148 6149 @Override 6150 public int checkUriPermission(Uri uri, int pid, int uid, final int modeFlags) { 6151 enforceNotIsolatedCaller("checkUriPermission"); 6152 6153 // Another redirected-binder-call permissions check as in 6154 // {@link checkComponentPermission}. 6155 Identity tlsIdentity = sCallerIdentity.get(); 6156 if (tlsIdentity != null) { 6157 uid = tlsIdentity.uid; 6158 pid = tlsIdentity.pid; 6159 } 6160 6161 // Our own process gets to do everything. 6162 if (pid == MY_PID) { 6163 return PackageManager.PERMISSION_GRANTED; 6164 } 6165 synchronized (this) { 6166 return checkUriPermissionLocked(uri, uid, modeFlags) 6167 ? PackageManager.PERMISSION_GRANTED 6168 : PackageManager.PERMISSION_DENIED; 6169 } 6170 } 6171 6172 /** 6173 * Check if the targetPkg can be granted permission to access uri by 6174 * the callingUid using the given modeFlags. Throws a security exception 6175 * if callingUid is not allowed to do this. Returns the uid of the target 6176 * if the URI permission grant should be performed; returns -1 if it is not 6177 * needed (for example targetPkg already has permission to access the URI). 6178 * If you already know the uid of the target, you can supply it in 6179 * lastTargetUid else set that to -1. 6180 */ 6181 int checkGrantUriPermissionLocked(int callingUid, String targetPkg, 6182 Uri uri, final int modeFlags, int lastTargetUid) { 6183 if (!Intent.isAccessUriMode(modeFlags)) { 6184 return -1; 6185 } 6186 6187 if (targetPkg != null) { 6188 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6189 "Checking grant " + targetPkg + " permission to " + uri); 6190 } 6191 6192 final IPackageManager pm = AppGlobals.getPackageManager(); 6193 6194 // If this is not a content: uri, we can't do anything with it. 6195 if (!ContentResolver.SCHEME_CONTENT.equals(uri.getScheme())) { 6196 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6197 "Can't grant URI permission for non-content URI: " + uri); 6198 return -1; 6199 } 6200 6201 final String authority = uri.getAuthority(); 6202 final ProviderInfo pi = getProviderInfoLocked(authority, UserHandle.getUserId(callingUid)); 6203 if (pi == null) { 6204 Slog.w(TAG, "No content provider found for permission check: " + uri.toSafeString()); 6205 return -1; 6206 } 6207 6208 int targetUid = lastTargetUid; 6209 if (targetUid < 0 && targetPkg != null) { 6210 try { 6211 targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid)); 6212 if (targetUid < 0) { 6213 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6214 "Can't grant URI permission no uid for: " + targetPkg); 6215 return -1; 6216 } 6217 } catch (RemoteException ex) { 6218 return -1; 6219 } 6220 } 6221 6222 if (targetUid >= 0) { 6223 // First... does the target actually need this permission? 6224 if (checkHoldingPermissionsLocked(pm, pi, uri, targetUid, modeFlags)) { 6225 // No need to grant the target this permission. 6226 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6227 "Target " + targetPkg + " already has full permission to " + uri); 6228 return -1; 6229 } 6230 } else { 6231 // First... there is no target package, so can anyone access it? 6232 boolean allowed = pi.exported; 6233 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) { 6234 if (pi.readPermission != null) { 6235 allowed = false; 6236 } 6237 } 6238 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) { 6239 if (pi.writePermission != null) { 6240 allowed = false; 6241 } 6242 } 6243 if (allowed) { 6244 return -1; 6245 } 6246 } 6247 6248 // Second... is the provider allowing granting of URI permissions? 6249 if (!pi.grantUriPermissions) { 6250 throw new SecurityException("Provider " + pi.packageName 6251 + "/" + pi.name 6252 + " does not allow granting of Uri permissions (uri " 6253 + uri + ")"); 6254 } 6255 if (pi.uriPermissionPatterns != null) { 6256 final int N = pi.uriPermissionPatterns.length; 6257 boolean allowed = false; 6258 for (int i=0; i<N; i++) { 6259 if (pi.uriPermissionPatterns[i] != null 6260 && pi.uriPermissionPatterns[i].match(uri.getPath())) { 6261 allowed = true; 6262 break; 6263 } 6264 } 6265 if (!allowed) { 6266 throw new SecurityException("Provider " + pi.packageName 6267 + "/" + pi.name 6268 + " does not allow granting of permission to path of Uri " 6269 + uri); 6270 } 6271 } 6272 6273 // Third... does the caller itself have permission to access 6274 // this uri? 6275 if (callingUid != Process.myUid()) { 6276 if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) { 6277 // Require they hold a strong enough Uri permission 6278 if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) { 6279 throw new SecurityException("Uid " + callingUid 6280 + " does not have permission to uri " + uri); 6281 } 6282 } 6283 } 6284 6285 return targetUid; 6286 } 6287 6288 @Override 6289 public int checkGrantUriPermission(int callingUid, String targetPkg, 6290 Uri uri, final int modeFlags) { 6291 enforceNotIsolatedCaller("checkGrantUriPermission"); 6292 synchronized(this) { 6293 return checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1); 6294 } 6295 } 6296 6297 void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, Uri uri, 6298 final int modeFlags, UriPermissionOwner owner) { 6299 if (!Intent.isAccessUriMode(modeFlags)) { 6300 return; 6301 } 6302 6303 // So here we are: the caller has the assumed permission 6304 // to the uri, and the target doesn't. Let's now give this to 6305 // the target. 6306 6307 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6308 "Granting " + targetPkg + "/" + targetUid + " permission to " + uri); 6309 6310 final String authority = uri.getAuthority(); 6311 final ProviderInfo pi = getProviderInfoLocked(authority, UserHandle.getUserId(targetUid)); 6312 if (pi == null) { 6313 Slog.w(TAG, "No content provider found for grant: " + uri.toSafeString()); 6314 return; 6315 } 6316 6317 final boolean prefix = (modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0; 6318 final UriPermission perm = findOrCreateUriPermissionLocked( 6319 pi.packageName, targetPkg, targetUid, new GrantUri(uri, prefix)); 6320 perm.grantModes(modeFlags, owner); 6321 } 6322 6323 void grantUriPermissionLocked(int callingUid, String targetPkg, Uri uri, 6324 final int modeFlags, UriPermissionOwner owner) { 6325 if (targetPkg == null) { 6326 throw new NullPointerException("targetPkg"); 6327 } 6328 6329 int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1); 6330 if (targetUid < 0) { 6331 return; 6332 } 6333 6334 grantUriPermissionUncheckedLocked(targetUid, targetPkg, uri, modeFlags, owner); 6335 } 6336 6337 static class NeededUriGrants extends ArrayList<Uri> { 6338 final String targetPkg; 6339 final int targetUid; 6340 final int flags; 6341 6342 NeededUriGrants(String targetPkg, int targetUid, int flags) { 6343 this.targetPkg = targetPkg; 6344 this.targetUid = targetUid; 6345 this.flags = flags; 6346 } 6347 } 6348 6349 /** 6350 * Like checkGrantUriPermissionLocked, but takes an Intent. 6351 */ 6352 NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid, 6353 String targetPkg, Intent intent, int mode, NeededUriGrants needed) { 6354 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6355 "Checking URI perm to data=" + (intent != null ? intent.getData() : null) 6356 + " clip=" + (intent != null ? intent.getClipData() : null) 6357 + " from " + intent + "; flags=0x" 6358 + Integer.toHexString(intent != null ? intent.getFlags() : 0)); 6359 6360 if (targetPkg == null) { 6361 throw new NullPointerException("targetPkg"); 6362 } 6363 6364 if (intent == null) { 6365 return null; 6366 } 6367 Uri data = intent.getData(); 6368 ClipData clip = intent.getClipData(); 6369 if (data == null && clip == null) { 6370 return null; 6371 } 6372 6373 if (data != null) { 6374 int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, data, 6375 mode, needed != null ? needed.targetUid : -1); 6376 if (targetUid > 0) { 6377 if (needed == null) { 6378 needed = new NeededUriGrants(targetPkg, targetUid, mode); 6379 } 6380 needed.add(data); 6381 } 6382 } 6383 if (clip != null) { 6384 for (int i=0; i<clip.getItemCount(); i++) { 6385 Uri uri = clip.getItemAt(i).getUri(); 6386 if (uri != null) { 6387 int targetUid = -1; 6388 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri, 6389 mode, needed != null ? needed.targetUid : -1); 6390 if (targetUid > 0) { 6391 if (needed == null) { 6392 needed = new NeededUriGrants(targetPkg, targetUid, mode); 6393 } 6394 needed.add(uri); 6395 } 6396 } else { 6397 Intent clipIntent = clip.getItemAt(i).getIntent(); 6398 if (clipIntent != null) { 6399 NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked( 6400 callingUid, targetPkg, clipIntent, mode, needed); 6401 if (newNeeded != null) { 6402 needed = newNeeded; 6403 } 6404 } 6405 } 6406 } 6407 } 6408 6409 return needed; 6410 } 6411 6412 /** 6413 * Like grantUriPermissionUncheckedLocked, but takes an Intent. 6414 */ 6415 void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed, 6416 UriPermissionOwner owner) { 6417 if (needed != null) { 6418 for (int i=0; i<needed.size(); i++) { 6419 grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg, 6420 needed.get(i), needed.flags, owner); 6421 } 6422 } 6423 } 6424 6425 void grantUriPermissionFromIntentLocked(int callingUid, 6426 String targetPkg, Intent intent, UriPermissionOwner owner) { 6427 NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg, 6428 intent, intent != null ? intent.getFlags() : 0, null); 6429 if (needed == null) { 6430 return; 6431 } 6432 6433 grantUriPermissionUncheckedFromIntentLocked(needed, owner); 6434 } 6435 6436 @Override 6437 public void grantUriPermission(IApplicationThread caller, String targetPkg, 6438 Uri uri, final int modeFlags) { 6439 enforceNotIsolatedCaller("grantUriPermission"); 6440 synchronized(this) { 6441 final ProcessRecord r = getRecordForAppLocked(caller); 6442 if (r == null) { 6443 throw new SecurityException("Unable to find app for caller " 6444 + caller 6445 + " when granting permission to uri " + uri); 6446 } 6447 if (targetPkg == null) { 6448 throw new IllegalArgumentException("null target"); 6449 } 6450 if (uri == null) { 6451 throw new IllegalArgumentException("null uri"); 6452 } 6453 6454 Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION 6455 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION 6456 | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION 6457 | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION); 6458 6459 grantUriPermissionLocked(r.uid, targetPkg, uri, modeFlags, null); 6460 } 6461 } 6462 6463 void removeUriPermissionIfNeededLocked(UriPermission perm) { 6464 if (perm.modeFlags == 0) { 6465 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get( 6466 perm.targetUid); 6467 if (perms != null) { 6468 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6469 "Removing " + perm.targetUid + " permission to " + perm.uri); 6470 6471 perms.remove(perm.uri); 6472 if (perms.isEmpty()) { 6473 mGrantedUriPermissions.remove(perm.targetUid); 6474 } 6475 } 6476 } 6477 } 6478 6479 private void revokeUriPermissionLocked(int callingUid, Uri uri, final int modeFlags) { 6480 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + uri); 6481 6482 final IPackageManager pm = AppGlobals.getPackageManager(); 6483 final String authority = uri.getAuthority(); 6484 final ProviderInfo pi = getProviderInfoLocked(authority, UserHandle.getUserId(callingUid)); 6485 if (pi == null) { 6486 Slog.w(TAG, "No content provider found for permission revoke: " + uri.toSafeString()); 6487 return; 6488 } 6489 6490 // Does the caller have this permission on the URI? 6491 if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) { 6492 // Right now, if you are not the original owner of the permission, 6493 // you are not allowed to revoke it. 6494 //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) { 6495 throw new SecurityException("Uid " + callingUid 6496 + " does not have permission to uri " + uri); 6497 //} 6498 } 6499 6500 boolean persistChanged = false; 6501 6502 // Go through all of the permissions and remove any that match. 6503 int N = mGrantedUriPermissions.size(); 6504 for (int i = 0; i < N; i++) { 6505 final int targetUid = mGrantedUriPermissions.keyAt(i); 6506 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 6507 6508 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) { 6509 final UriPermission perm = it.next(); 6510 if (perm.uri.uri.isPathPrefixMatch(uri)) { 6511 if (DEBUG_URI_PERMISSION) 6512 Slog.v(TAG, 6513 "Revoking " + perm.targetUid + " permission to " + perm.uri); 6514 persistChanged |= perm.revokeModes( 6515 modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION); 6516 if (perm.modeFlags == 0) { 6517 it.remove(); 6518 } 6519 } 6520 } 6521 6522 if (perms.isEmpty()) { 6523 mGrantedUriPermissions.remove(targetUid); 6524 N--; 6525 i--; 6526 } 6527 } 6528 6529 if (persistChanged) { 6530 schedulePersistUriGrants(); 6531 } 6532 } 6533 6534 @Override 6535 public void revokeUriPermission(IApplicationThread caller, Uri uri, 6536 final int modeFlags) { 6537 enforceNotIsolatedCaller("revokeUriPermission"); 6538 synchronized(this) { 6539 final ProcessRecord r = getRecordForAppLocked(caller); 6540 if (r == null) { 6541 throw new SecurityException("Unable to find app for caller " 6542 + caller 6543 + " when revoking permission to uri " + uri); 6544 } 6545 if (uri == null) { 6546 Slog.w(TAG, "revokeUriPermission: null uri"); 6547 return; 6548 } 6549 6550 if (!Intent.isAccessUriMode(modeFlags)) { 6551 return; 6552 } 6553 6554 final IPackageManager pm = AppGlobals.getPackageManager(); 6555 final String authority = uri.getAuthority(); 6556 final ProviderInfo pi = getProviderInfoLocked(authority, r.userId); 6557 if (pi == null) { 6558 Slog.w(TAG, "No content provider found for permission revoke: " 6559 + uri.toSafeString()); 6560 return; 6561 } 6562 6563 revokeUriPermissionLocked(r.uid, uri, modeFlags); 6564 } 6565 } 6566 6567 /** 6568 * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the 6569 * given package. 6570 * 6571 * @param packageName Package name to match, or {@code null} to apply to all 6572 * packages. 6573 * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply 6574 * to all users. 6575 * @param persistable If persistable grants should be removed. 6576 */ 6577 private void removeUriPermissionsForPackageLocked( 6578 String packageName, int userHandle, boolean persistable) { 6579 if (userHandle == UserHandle.USER_ALL && packageName == null) { 6580 throw new IllegalArgumentException("Must narrow by either package or user"); 6581 } 6582 6583 boolean persistChanged = false; 6584 6585 int N = mGrantedUriPermissions.size(); 6586 for (int i = 0; i < N; i++) { 6587 final int targetUid = mGrantedUriPermissions.keyAt(i); 6588 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 6589 6590 // Only inspect grants matching user 6591 if (userHandle == UserHandle.USER_ALL 6592 || userHandle == UserHandle.getUserId(targetUid)) { 6593 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) { 6594 final UriPermission perm = it.next(); 6595 6596 // Only inspect grants matching package 6597 if (packageName == null || perm.sourcePkg.equals(packageName) 6598 || perm.targetPkg.equals(packageName)) { 6599 persistChanged |= perm.revokeModes( 6600 persistable ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION); 6601 6602 // Only remove when no modes remain; any persisted grants 6603 // will keep this alive. 6604 if (perm.modeFlags == 0) { 6605 it.remove(); 6606 } 6607 } 6608 } 6609 6610 if (perms.isEmpty()) { 6611 mGrantedUriPermissions.remove(targetUid); 6612 N--; 6613 i--; 6614 } 6615 } 6616 } 6617 6618 if (persistChanged) { 6619 schedulePersistUriGrants(); 6620 } 6621 } 6622 6623 @Override 6624 public IBinder newUriPermissionOwner(String name) { 6625 enforceNotIsolatedCaller("newUriPermissionOwner"); 6626 synchronized(this) { 6627 UriPermissionOwner owner = new UriPermissionOwner(this, name); 6628 return owner.getExternalTokenLocked(); 6629 } 6630 } 6631 6632 @Override 6633 public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, 6634 Uri uri, final int modeFlags) { 6635 synchronized(this) { 6636 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 6637 if (owner == null) { 6638 throw new IllegalArgumentException("Unknown owner: " + token); 6639 } 6640 if (fromUid != Binder.getCallingUid()) { 6641 if (Binder.getCallingUid() != Process.myUid()) { 6642 // Only system code can grant URI permissions on behalf 6643 // of other users. 6644 throw new SecurityException("nice try"); 6645 } 6646 } 6647 if (targetPkg == null) { 6648 throw new IllegalArgumentException("null target"); 6649 } 6650 if (uri == null) { 6651 throw new IllegalArgumentException("null uri"); 6652 } 6653 6654 grantUriPermissionLocked(fromUid, targetPkg, uri, modeFlags, owner); 6655 } 6656 } 6657 6658 @Override 6659 public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode) { 6660 synchronized(this) { 6661 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 6662 if (owner == null) { 6663 throw new IllegalArgumentException("Unknown owner: " + token); 6664 } 6665 6666 if (uri == null) { 6667 owner.removeUriPermissionsLocked(mode); 6668 } else { 6669 owner.removeUriPermissionLocked(uri, mode); 6670 } 6671 } 6672 } 6673 6674 private void schedulePersistUriGrants() { 6675 if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) { 6676 mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG), 6677 10 * DateUtils.SECOND_IN_MILLIS); 6678 } 6679 } 6680 6681 private void writeGrantedUriPermissions() { 6682 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()"); 6683 6684 // Snapshot permissions so we can persist without lock 6685 ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList(); 6686 synchronized (this) { 6687 final int size = mGrantedUriPermissions.size(); 6688 for (int i = 0; i < size; i++) { 6689 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 6690 for (UriPermission perm : perms.values()) { 6691 if (perm.persistedModeFlags != 0) { 6692 persist.add(perm.snapshot()); 6693 } 6694 } 6695 } 6696 } 6697 6698 FileOutputStream fos = null; 6699 try { 6700 fos = mGrantFile.startWrite(); 6701 6702 XmlSerializer out = new FastXmlSerializer(); 6703 out.setOutput(fos, "utf-8"); 6704 out.startDocument(null, true); 6705 out.startTag(null, TAG_URI_GRANTS); 6706 for (UriPermission.Snapshot perm : persist) { 6707 out.startTag(null, TAG_URI_GRANT); 6708 writeIntAttribute(out, ATTR_USER_HANDLE, perm.userHandle); 6709 out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg); 6710 out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg); 6711 out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri)); 6712 writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix); 6713 writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags); 6714 writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime); 6715 out.endTag(null, TAG_URI_GRANT); 6716 } 6717 out.endTag(null, TAG_URI_GRANTS); 6718 out.endDocument(); 6719 6720 mGrantFile.finishWrite(fos); 6721 } catch (IOException e) { 6722 if (fos != null) { 6723 mGrantFile.failWrite(fos); 6724 } 6725 } 6726 } 6727 6728 private void readGrantedUriPermissionsLocked() { 6729 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()"); 6730 6731 final long now = System.currentTimeMillis(); 6732 6733 FileInputStream fis = null; 6734 try { 6735 fis = mGrantFile.openRead(); 6736 final XmlPullParser in = Xml.newPullParser(); 6737 in.setInput(fis, null); 6738 6739 int type; 6740 while ((type = in.next()) != END_DOCUMENT) { 6741 final String tag = in.getName(); 6742 if (type == START_TAG) { 6743 if (TAG_URI_GRANT.equals(tag)) { 6744 final int userHandle = readIntAttribute(in, ATTR_USER_HANDLE); 6745 final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG); 6746 final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG); 6747 final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI)); 6748 final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX); 6749 final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS); 6750 final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now); 6751 6752 // Sanity check that provider still belongs to source package 6753 final ProviderInfo pi = getProviderInfoLocked( 6754 uri.getAuthority(), userHandle); 6755 if (pi != null && sourcePkg.equals(pi.packageName)) { 6756 int targetUid = -1; 6757 try { 6758 targetUid = AppGlobals.getPackageManager() 6759 .getPackageUid(targetPkg, userHandle); 6760 } catch (RemoteException e) { 6761 } 6762 if (targetUid != -1) { 6763 final UriPermission perm = findOrCreateUriPermissionLocked( 6764 sourcePkg, targetPkg, targetUid, new GrantUri(uri, prefix)); 6765 perm.initPersistedModes(modeFlags, createdTime); 6766 } 6767 } else { 6768 Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg 6769 + " but instead found " + pi); 6770 } 6771 } 6772 } 6773 } 6774 } catch (FileNotFoundException e) { 6775 // Missing grants is okay 6776 } catch (IOException e) { 6777 Log.wtf(TAG, "Failed reading Uri grants", e); 6778 } catch (XmlPullParserException e) { 6779 Log.wtf(TAG, "Failed reading Uri grants", e); 6780 } finally { 6781 IoUtils.closeQuietly(fis); 6782 } 6783 } 6784 6785 @Override 6786 public void takePersistableUriPermission(Uri uri, final int modeFlags) { 6787 enforceNotIsolatedCaller("takePersistableUriPermission"); 6788 6789 Preconditions.checkFlagsArgument(modeFlags, 6790 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 6791 6792 synchronized (this) { 6793 final int callingUid = Binder.getCallingUid(); 6794 boolean persistChanged = false; 6795 6796 UriPermission exactPerm = findUriPermissionLocked(callingUid, new GrantUri(uri, false)); 6797 UriPermission prefixPerm = findUriPermissionLocked(callingUid, new GrantUri(uri, true)); 6798 6799 final boolean exactValid = (exactPerm != null) 6800 && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags); 6801 final boolean prefixValid = (prefixPerm != null) 6802 && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags); 6803 6804 if (!(exactValid || prefixValid)) { 6805 throw new SecurityException("No persistable permission grants found for UID " 6806 + callingUid + " and Uri " + uri.toSafeString()); 6807 } 6808 6809 if (exactValid) { 6810 persistChanged |= exactPerm.takePersistableModes(modeFlags); 6811 } 6812 if (prefixValid) { 6813 persistChanged |= prefixPerm.takePersistableModes(modeFlags); 6814 } 6815 6816 persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid); 6817 6818 if (persistChanged) { 6819 schedulePersistUriGrants(); 6820 } 6821 } 6822 } 6823 6824 @Override 6825 public void releasePersistableUriPermission(Uri uri, final int modeFlags) { 6826 enforceNotIsolatedCaller("releasePersistableUriPermission"); 6827 6828 Preconditions.checkFlagsArgument(modeFlags, 6829 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 6830 6831 synchronized (this) { 6832 final int callingUid = Binder.getCallingUid(); 6833 boolean persistChanged = false; 6834 6835 UriPermission exactPerm = findUriPermissionLocked(callingUid, new GrantUri(uri, false)); 6836 UriPermission prefixPerm = findUriPermissionLocked(callingUid, new GrantUri(uri, true)); 6837 if (exactPerm == null && prefixPerm == null) { 6838 throw new SecurityException("No permission grants found for UID " + callingUid 6839 + " and Uri " + uri.toSafeString()); 6840 } 6841 6842 if (exactPerm != null) { 6843 persistChanged |= exactPerm.releasePersistableModes(modeFlags); 6844 removeUriPermissionIfNeededLocked(exactPerm); 6845 } 6846 if (prefixPerm != null) { 6847 persistChanged |= prefixPerm.releasePersistableModes(modeFlags); 6848 removeUriPermissionIfNeededLocked(prefixPerm); 6849 } 6850 6851 if (persistChanged) { 6852 schedulePersistUriGrants(); 6853 } 6854 } 6855 } 6856 6857 /** 6858 * Prune any older {@link UriPermission} for the given UID until outstanding 6859 * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}. 6860 * 6861 * @return if any mutations occured that require persisting. 6862 */ 6863 private boolean maybePrunePersistedUriGrantsLocked(int uid) { 6864 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid); 6865 if (perms == null) return false; 6866 if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false; 6867 6868 final ArrayList<UriPermission> persisted = Lists.newArrayList(); 6869 for (UriPermission perm : perms.values()) { 6870 if (perm.persistedModeFlags != 0) { 6871 persisted.add(perm); 6872 } 6873 } 6874 6875 final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS; 6876 if (trimCount <= 0) return false; 6877 6878 Collections.sort(persisted, new UriPermission.PersistedTimeComparator()); 6879 for (int i = 0; i < trimCount; i++) { 6880 final UriPermission perm = persisted.get(i); 6881 6882 if (DEBUG_URI_PERMISSION) { 6883 Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime); 6884 } 6885 6886 perm.releasePersistableModes(~0); 6887 removeUriPermissionIfNeededLocked(perm); 6888 } 6889 6890 return true; 6891 } 6892 6893 @Override 6894 public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions( 6895 String packageName, boolean incoming) { 6896 enforceNotIsolatedCaller("getPersistedUriPermissions"); 6897 Preconditions.checkNotNull(packageName, "packageName"); 6898 6899 final int callingUid = Binder.getCallingUid(); 6900 final IPackageManager pm = AppGlobals.getPackageManager(); 6901 try { 6902 final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid)); 6903 if (packageUid != callingUid) { 6904 throw new SecurityException( 6905 "Package " + packageName + " does not belong to calling UID " + callingUid); 6906 } 6907 } catch (RemoteException e) { 6908 throw new SecurityException("Failed to verify package name ownership"); 6909 } 6910 6911 final ArrayList<android.content.UriPermission> result = Lists.newArrayList(); 6912 synchronized (this) { 6913 if (incoming) { 6914 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get( 6915 callingUid); 6916 if (perms == null) { 6917 Slog.w(TAG, "No permission grants found for " + packageName); 6918 } else { 6919 for (UriPermission perm : perms.values()) { 6920 if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) { 6921 result.add(perm.buildPersistedPublicApiObject()); 6922 } 6923 } 6924 } 6925 } else { 6926 final int size = mGrantedUriPermissions.size(); 6927 for (int i = 0; i < size; i++) { 6928 final ArrayMap<GrantUri, UriPermission> perms = 6929 mGrantedUriPermissions.valueAt(i); 6930 for (UriPermission perm : perms.values()) { 6931 if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) { 6932 result.add(perm.buildPersistedPublicApiObject()); 6933 } 6934 } 6935 } 6936 } 6937 } 6938 return new ParceledListSlice<android.content.UriPermission>(result); 6939 } 6940 6941 @Override 6942 public void showWaitingForDebugger(IApplicationThread who, boolean waiting) { 6943 synchronized (this) { 6944 ProcessRecord app = 6945 who != null ? getRecordForAppLocked(who) : null; 6946 if (app == null) return; 6947 6948 Message msg = Message.obtain(); 6949 msg.what = WAIT_FOR_DEBUGGER_MSG; 6950 msg.obj = app; 6951 msg.arg1 = waiting ? 1 : 0; 6952 mHandler.sendMessage(msg); 6953 } 6954 } 6955 6956 @Override 6957 public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) { 6958 final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ); 6959 final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ); 6960 outInfo.availMem = Process.getFreeMemory(); 6961 outInfo.totalMem = Process.getTotalMemory(); 6962 outInfo.threshold = homeAppMem; 6963 outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2)); 6964 outInfo.hiddenAppThreshold = cachedAppMem; 6965 outInfo.secondaryServerThreshold = mProcessList.getMemLevel( 6966 ProcessList.SERVICE_ADJ); 6967 outInfo.visibleAppThreshold = mProcessList.getMemLevel( 6968 ProcessList.VISIBLE_APP_ADJ); 6969 outInfo.foregroundAppThreshold = mProcessList.getMemLevel( 6970 ProcessList.FOREGROUND_APP_ADJ); 6971 } 6972 6973 // ========================================================= 6974 // TASK MANAGEMENT 6975 // ========================================================= 6976 6977 @Override 6978 public List<RunningTaskInfo> getTasks(int maxNum, int flags) { 6979 final int callingUid = Binder.getCallingUid(); 6980 ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>(); 6981 6982 synchronized(this) { 6983 if (localLOGV) Slog.v( 6984 TAG, "getTasks: max=" + maxNum + ", flags=" + flags); 6985 6986 final boolean allowed = checkCallingPermission( 6987 android.Manifest.permission.GET_TASKS) 6988 == PackageManager.PERMISSION_GRANTED; 6989 if (!allowed) { 6990 Slog.w(TAG, "getTasks: caller " + callingUid 6991 + " does not hold GET_TASKS; limiting output"); 6992 } 6993 6994 // TODO: Improve with MRU list from all ActivityStacks. 6995 mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed); 6996 } 6997 6998 return list; 6999 } 7000 7001 TaskRecord getMostRecentTask() { 7002 return mRecentTasks.get(0); 7003 } 7004 7005 @Override 7006 public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, 7007 int flags, int userId) { 7008 final int callingUid = Binder.getCallingUid(); 7009 userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId, 7010 false, true, "getRecentTasks", null); 7011 7012 synchronized (this) { 7013 final boolean allowed = checkCallingPermission( 7014 android.Manifest.permission.GET_TASKS) 7015 == PackageManager.PERMISSION_GRANTED; 7016 if (!allowed) { 7017 Slog.w(TAG, "getRecentTasks: caller " + callingUid 7018 + " does not hold GET_TASKS; limiting output"); 7019 } 7020 final boolean detailed = checkCallingPermission( 7021 android.Manifest.permission.GET_DETAILED_TASKS) 7022 == PackageManager.PERMISSION_GRANTED; 7023 7024 IPackageManager pm = AppGlobals.getPackageManager(); 7025 7026 final int N = mRecentTasks.size(); 7027 ArrayList<ActivityManager.RecentTaskInfo> res 7028 = new ArrayList<ActivityManager.RecentTaskInfo>( 7029 maxNum < N ? maxNum : N); 7030 7031 final Set<Integer> includedUsers; 7032 if ((flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0) { 7033 includedUsers = getProfileIdsLocked(userId); 7034 } else { 7035 includedUsers = new HashSet<Integer>(); 7036 } 7037 includedUsers.add(Integer.valueOf(userId)); 7038 for (int i=0; i<N && maxNum > 0; i++) { 7039 TaskRecord tr = mRecentTasks.get(i); 7040 // Only add calling user or related users recent tasks 7041 if (!includedUsers.contains(Integer.valueOf(tr.userId))) continue; 7042 7043 // Return the entry if desired by the caller. We always return 7044 // the first entry, because callers always expect this to be the 7045 // foreground app. We may filter others if the caller has 7046 // not supplied RECENT_WITH_EXCLUDED and there is some reason 7047 // we should exclude the entry. 7048 7049 if (i == 0 7050 || ((flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0) 7051 || (tr.intent == null) 7052 || ((tr.intent.getFlags() 7053 &Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0)) { 7054 if (!allowed) { 7055 // If the caller doesn't have the GET_TASKS permission, then only 7056 // allow them to see a small subset of tasks -- their own and home. 7057 if (!tr.isHomeTask() && tr.creatorUid != callingUid) { 7058 continue; 7059 } 7060 } 7061 ActivityManager.RecentTaskInfo rti 7062 = new ActivityManager.RecentTaskInfo(); 7063 rti.id = tr.numActivities > 0 ? tr.taskId : -1; 7064 rti.persistentId = tr.taskId; 7065 rti.baseIntent = new Intent( 7066 tr.intent != null ? tr.intent : tr.affinityIntent); 7067 if (!detailed) { 7068 rti.baseIntent.replaceExtras((Bundle)null); 7069 } 7070 rti.origActivity = tr.origActivity; 7071 rti.description = tr.lastDescription; 7072 rti.stackId = tr.stack.mStackId; 7073 rti.userId = tr.userId; 7074 7075 // Traverse upwards looking for any break between main task activities and 7076 // utility activities. 7077 final ArrayList<ActivityRecord> activities = tr.mActivities; 7078 int activityNdx; 7079 final int numActivities = activities.size(); 7080 for (activityNdx = Math.min(numActivities, 1); activityNdx < numActivities; 7081 ++activityNdx) { 7082 final ActivityRecord r = activities.get(activityNdx); 7083 if (r.intent != null && 7084 (r.intent.getFlags() & Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET) 7085 != 0) { 7086 break; 7087 } 7088 } 7089 if (activityNdx > 0) { 7090 // Traverse downwards starting below break looking for set label, icon. 7091 // Note that if there are activities in the task but none of them set the 7092 // recent activity values, then we do not fall back to the last set 7093 // values in the TaskRecord. 7094 rti.activityValues = new ActivityManager.RecentsActivityValues(); 7095 for (--activityNdx; activityNdx >= 0; --activityNdx) { 7096 final ActivityRecord r = activities.get(activityNdx); 7097 if (r.activityValues != null) { 7098 if (rti.activityValues.label == null) { 7099 rti.activityValues.label = r.activityValues.label; 7100 tr.lastActivityValues.label = r.activityValues.label; 7101 } 7102 if (rti.activityValues.icon == null) { 7103 rti.activityValues.icon = r.activityValues.icon; 7104 tr.lastActivityValues.icon = r.activityValues.icon; 7105 } 7106 if (rti.activityValues.colorPrimary == 0) { 7107 rti.activityValues.colorPrimary = r.activityValues.colorPrimary; 7108 tr.lastActivityValues.colorPrimary = r.activityValues.colorPrimary; 7109 } 7110 } 7111 } 7112 } else { 7113 // If there are no activity records in this task, then we use the last 7114 // resolved values 7115 rti.activityValues = 7116 new ActivityManager.RecentsActivityValues(tr.lastActivityValues); 7117 } 7118 7119 if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) { 7120 // Check whether this activity is currently available. 7121 try { 7122 if (rti.origActivity != null) { 7123 if (pm.getActivityInfo(rti.origActivity, 0, userId) 7124 == null) { 7125 continue; 7126 } 7127 } else if (rti.baseIntent != null) { 7128 if (pm.queryIntentActivities(rti.baseIntent, 7129 null, 0, userId) == null) { 7130 continue; 7131 } 7132 } 7133 } catch (RemoteException e) { 7134 // Will never happen. 7135 } 7136 } 7137 7138 res.add(rti); 7139 maxNum--; 7140 } 7141 } 7142 return res; 7143 } 7144 } 7145 7146 private TaskRecord recentTaskForIdLocked(int id) { 7147 final int N = mRecentTasks.size(); 7148 for (int i=0; i<N; i++) { 7149 TaskRecord tr = mRecentTasks.get(i); 7150 if (tr.taskId == id) { 7151 return tr; 7152 } 7153 } 7154 return null; 7155 } 7156 7157 @Override 7158 public ActivityManager.TaskThumbnails getTaskThumbnails(int id) { 7159 synchronized (this) { 7160 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER, 7161 "getTaskThumbnails()"); 7162 TaskRecord tr = recentTaskForIdLocked(id); 7163 if (tr != null) { 7164 return tr.getTaskThumbnailsLocked(); 7165 } 7166 } 7167 return null; 7168 } 7169 7170 @Override 7171 public Bitmap getTaskTopThumbnail(int id) { 7172 synchronized (this) { 7173 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER, 7174 "getTaskTopThumbnail()"); 7175 TaskRecord tr = recentTaskForIdLocked(id); 7176 if (tr != null) { 7177 return tr.getTaskTopThumbnailLocked(); 7178 } 7179 } 7180 return null; 7181 } 7182 7183 @Override 7184 public void setRecentsActivityValues(IBinder token, ActivityManager.RecentsActivityValues rav) { 7185 synchronized (this) { 7186 ActivityRecord r = ActivityRecord.isInStackLocked(token); 7187 if (r != null) { 7188 r.activityValues = rav; 7189 } 7190 } 7191 } 7192 7193 @Override 7194 public boolean removeSubTask(int taskId, int subTaskIndex) { 7195 synchronized (this) { 7196 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, 7197 "removeSubTask()"); 7198 long ident = Binder.clearCallingIdentity(); 7199 try { 7200 TaskRecord tr = recentTaskForIdLocked(taskId); 7201 if (tr != null) { 7202 return tr.removeTaskActivitiesLocked(subTaskIndex, true) != null; 7203 } 7204 return false; 7205 } finally { 7206 Binder.restoreCallingIdentity(ident); 7207 } 7208 } 7209 } 7210 7211 private void killUnneededProcessLocked(ProcessRecord pr, String reason) { 7212 if (!pr.killedByAm) { 7213 Slog.i(TAG, "Killing " + pr.toShortString() + " (adj " + pr.setAdj + "): " + reason); 7214 EventLog.writeEvent(EventLogTags.AM_KILL, pr.userId, pr.pid, 7215 pr.processName, pr.setAdj, reason); 7216 pr.killedByAm = true; 7217 Process.killProcessQuiet(pr.pid); 7218 } 7219 } 7220 7221 private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) { 7222 tr.disposeThumbnail(); 7223 mRecentTasks.remove(tr); 7224 final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0; 7225 Intent baseIntent = new Intent( 7226 tr.intent != null ? tr.intent : tr.affinityIntent); 7227 ComponentName component = baseIntent.getComponent(); 7228 if (component == null) { 7229 Slog.w(TAG, "Now component for base intent of task: " + tr); 7230 return; 7231 } 7232 7233 // Find any running services associated with this app. 7234 mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent); 7235 7236 if (killProcesses) { 7237 // Find any running processes associated with this app. 7238 final String pkg = component.getPackageName(); 7239 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 7240 ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap(); 7241 for (int i=0; i<pmap.size(); i++) { 7242 SparseArray<ProcessRecord> uids = pmap.valueAt(i); 7243 for (int j=0; j<uids.size(); j++) { 7244 ProcessRecord proc = uids.valueAt(j); 7245 if (proc.userId != tr.userId) { 7246 continue; 7247 } 7248 if (!proc.pkgList.containsKey(pkg)) { 7249 continue; 7250 } 7251 procs.add(proc); 7252 } 7253 } 7254 7255 // Kill the running processes. 7256 for (int i=0; i<procs.size(); i++) { 7257 ProcessRecord pr = procs.get(i); 7258 if (pr == mHomeProcess) { 7259 // Don't kill the home process along with tasks from the same package. 7260 continue; 7261 } 7262 if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 7263 killUnneededProcessLocked(pr, "remove task"); 7264 } else { 7265 pr.waitingToKill = "remove task"; 7266 } 7267 } 7268 } 7269 } 7270 7271 /** 7272 * Removes the task with the specified task id. 7273 * 7274 * @param taskId Identifier of the task to be removed. 7275 * @param flags Additional operational flags. May be 0 or 7276 * {@link ActivityManager#REMOVE_TASK_KILL_PROCESS}. 7277 * @return Returns true if the given task was found and removed. 7278 */ 7279 private boolean removeTaskByIdLocked(int taskId, int flags) { 7280 TaskRecord tr = recentTaskForIdLocked(taskId); 7281 if (tr != null) { 7282 tr.removeTaskActivitiesLocked(-1, false); 7283 cleanUpRemovedTaskLocked(tr, flags); 7284 return true; 7285 } 7286 return false; 7287 } 7288 7289 @Override 7290 public boolean removeTask(int taskId, int flags) { 7291 synchronized (this) { 7292 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, 7293 "removeTask()"); 7294 long ident = Binder.clearCallingIdentity(); 7295 try { 7296 return removeTaskByIdLocked(taskId, flags); 7297 } finally { 7298 Binder.restoreCallingIdentity(ident); 7299 } 7300 } 7301 } 7302 7303 /** 7304 * TODO: Add mController hook 7305 */ 7306 @Override 7307 public void moveTaskToFront(int taskId, int flags, Bundle options) { 7308 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 7309 "moveTaskToFront()"); 7310 7311 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId); 7312 synchronized(this) { 7313 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 7314 Binder.getCallingUid(), "Task to front")) { 7315 ActivityOptions.abort(options); 7316 return; 7317 } 7318 final long origId = Binder.clearCallingIdentity(); 7319 try { 7320 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId); 7321 if (task == null) { 7322 return; 7323 } 7324 if (mStackSupervisor.isLockTaskModeViolation(task)) { 7325 Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode"); 7326 return; 7327 } 7328 mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options); 7329 } finally { 7330 Binder.restoreCallingIdentity(origId); 7331 } 7332 ActivityOptions.abort(options); 7333 } 7334 } 7335 7336 @Override 7337 public void moveTaskToBack(int taskId) { 7338 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 7339 "moveTaskToBack()"); 7340 7341 synchronized(this) { 7342 TaskRecord tr = recentTaskForIdLocked(taskId); 7343 if (tr != null) { 7344 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr); 7345 ActivityStack stack = tr.stack; 7346 if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) { 7347 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 7348 Binder.getCallingUid(), "Task to back")) { 7349 return; 7350 } 7351 } 7352 final long origId = Binder.clearCallingIdentity(); 7353 try { 7354 stack.moveTaskToBackLocked(taskId, null); 7355 } finally { 7356 Binder.restoreCallingIdentity(origId); 7357 } 7358 } 7359 } 7360 } 7361 7362 /** 7363 * Moves an activity, and all of the other activities within the same task, to the bottom 7364 * of the history stack. The activity's order within the task is unchanged. 7365 * 7366 * @param token A reference to the activity we wish to move 7367 * @param nonRoot If false then this only works if the activity is the root 7368 * of a task; if true it will work for any activity in a task. 7369 * @return Returns true if the move completed, false if not. 7370 */ 7371 @Override 7372 public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) { 7373 enforceNotIsolatedCaller("moveActivityTaskToBack"); 7374 synchronized(this) { 7375 final long origId = Binder.clearCallingIdentity(); 7376 int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot); 7377 if (taskId >= 0) { 7378 return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null); 7379 } 7380 Binder.restoreCallingIdentity(origId); 7381 } 7382 return false; 7383 } 7384 7385 @Override 7386 public void moveTaskBackwards(int task) { 7387 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 7388 "moveTaskBackwards()"); 7389 7390 synchronized(this) { 7391 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 7392 Binder.getCallingUid(), "Task backwards")) { 7393 return; 7394 } 7395 final long origId = Binder.clearCallingIdentity(); 7396 moveTaskBackwardsLocked(task); 7397 Binder.restoreCallingIdentity(origId); 7398 } 7399 } 7400 7401 private final void moveTaskBackwardsLocked(int task) { 7402 Slog.e(TAG, "moveTaskBackwards not yet implemented!"); 7403 } 7404 7405 @Override 7406 public IBinder getHomeActivityToken() throws RemoteException { 7407 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7408 "getHomeActivityToken()"); 7409 synchronized (this) { 7410 return mStackSupervisor.getHomeActivityToken(); 7411 } 7412 } 7413 7414 @Override 7415 public IActivityContainer createActivityContainer(IBinder parentActivityToken, 7416 IActivityContainerCallback callback) throws RemoteException { 7417 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7418 "createActivityContainer()"); 7419 synchronized (this) { 7420 if (parentActivityToken == null) { 7421 throw new IllegalArgumentException("parent token must not be null"); 7422 } 7423 ActivityRecord r = ActivityRecord.forToken(parentActivityToken); 7424 if (r == null) { 7425 return null; 7426 } 7427 if (callback == null) { 7428 throw new IllegalArgumentException("callback must not be null"); 7429 } 7430 return mStackSupervisor.createActivityContainer(r, callback); 7431 } 7432 } 7433 7434 @Override 7435 public void deleteActivityContainer(IActivityContainer container) throws RemoteException { 7436 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7437 "deleteActivityContainer()"); 7438 synchronized (this) { 7439 mStackSupervisor.deleteActivityContainer(container); 7440 } 7441 } 7442 7443 @Override 7444 public IActivityContainer getEnclosingActivityContainer(IBinder activityToken) 7445 throws RemoteException { 7446 synchronized (this) { 7447 ActivityStack stack = ActivityRecord.getStackLocked(activityToken); 7448 if (stack != null) { 7449 return stack.mActivityContainer; 7450 } 7451 return null; 7452 } 7453 } 7454 7455 @Override 7456 public void moveTaskToStack(int taskId, int stackId, boolean toTop) { 7457 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7458 "moveTaskToStack()"); 7459 if (stackId == HOME_STACK_ID) { 7460 Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack", 7461 new RuntimeException("here").fillInStackTrace()); 7462 } 7463 synchronized (this) { 7464 long ident = Binder.clearCallingIdentity(); 7465 try { 7466 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId=" 7467 + stackId + " toTop=" + toTop); 7468 mStackSupervisor.moveTaskToStack(taskId, stackId, toTop); 7469 } finally { 7470 Binder.restoreCallingIdentity(ident); 7471 } 7472 } 7473 } 7474 7475 @Override 7476 public void resizeStack(int stackBoxId, Rect bounds) { 7477 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7478 "resizeStackBox()"); 7479 long ident = Binder.clearCallingIdentity(); 7480 try { 7481 mWindowManager.resizeStack(stackBoxId, bounds); 7482 } finally { 7483 Binder.restoreCallingIdentity(ident); 7484 } 7485 } 7486 7487 @Override 7488 public List<StackInfo> getAllStackInfos() { 7489 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7490 "getAllStackInfos()"); 7491 long ident = Binder.clearCallingIdentity(); 7492 try { 7493 synchronized (this) { 7494 return mStackSupervisor.getAllStackInfosLocked(); 7495 } 7496 } finally { 7497 Binder.restoreCallingIdentity(ident); 7498 } 7499 } 7500 7501 @Override 7502 public StackInfo getStackInfo(int stackId) { 7503 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7504 "getStackInfo()"); 7505 long ident = Binder.clearCallingIdentity(); 7506 try { 7507 synchronized (this) { 7508 return mStackSupervisor.getStackInfoLocked(stackId); 7509 } 7510 } finally { 7511 Binder.restoreCallingIdentity(ident); 7512 } 7513 } 7514 7515 @Override 7516 public boolean isInHomeStack(int taskId) { 7517 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7518 "getStackInfo()"); 7519 long ident = Binder.clearCallingIdentity(); 7520 try { 7521 synchronized (this) { 7522 TaskRecord tr = recentTaskForIdLocked(taskId); 7523 if (tr != null) { 7524 return tr.stack.isHomeStack(); 7525 } 7526 } 7527 } finally { 7528 Binder.restoreCallingIdentity(ident); 7529 } 7530 return false; 7531 } 7532 7533 @Override 7534 public int getTaskForActivity(IBinder token, boolean onlyRoot) { 7535 synchronized(this) { 7536 return ActivityRecord.getTaskForActivityLocked(token, onlyRoot); 7537 } 7538 } 7539 7540 private boolean isLockTaskAuthorized(ComponentName name) { 7541// enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 7542// "startLockTaskMode()"); 7543// DevicePolicyManager dpm = (DevicePolicyManager) 7544// mContext.getSystemService(Context.DEVICE_POLICY_SERVICE); 7545// return dpm != null && dpm.isLockTaskPermitted(name); 7546 return true; 7547 } 7548 7549 private void startLockTaskMode(TaskRecord task) { 7550 if (!isLockTaskAuthorized(task.intent.getComponent())) { 7551 return; 7552 } 7553 long ident = Binder.clearCallingIdentity(); 7554 try { 7555 synchronized (this) { 7556 // Since we lost lock on task, make sure it is still there. 7557 task = mStackSupervisor.anyTaskForIdLocked(task.taskId); 7558 if (task != null) { 7559 mStackSupervisor.setLockTaskModeLocked(task); 7560 } 7561 } 7562 } finally { 7563 Binder.restoreCallingIdentity(ident); 7564 } 7565 } 7566 7567 @Override 7568 public void startLockTaskMode(int taskId) { 7569 long ident = Binder.clearCallingIdentity(); 7570 try { 7571 final TaskRecord task; 7572 synchronized (this) { 7573 task = mStackSupervisor.anyTaskForIdLocked(taskId); 7574 } 7575 if (task != null) { 7576 startLockTaskMode(task); 7577 } 7578 } finally { 7579 Binder.restoreCallingIdentity(ident); 7580 } 7581 } 7582 7583 @Override 7584 public void startLockTaskMode(IBinder token) { 7585 long ident = Binder.clearCallingIdentity(); 7586 try { 7587 final TaskRecord task; 7588 synchronized (this) { 7589 final ActivityRecord r = ActivityRecord.forToken(token); 7590 if (r == null) { 7591 return; 7592 } 7593 task = r.task; 7594 } 7595 if (task != null) { 7596 startLockTaskMode(task); 7597 } 7598 } finally { 7599 Binder.restoreCallingIdentity(ident); 7600 } 7601 } 7602 7603 @Override 7604 public void stopLockTaskMode() { 7605// enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 7606// "stopLockTaskMode()"); 7607 synchronized (this) { 7608 mStackSupervisor.setLockTaskModeLocked(null); 7609 } 7610 } 7611 7612 @Override 7613 public boolean isInLockTaskMode() { 7614 synchronized (this) { 7615 return mStackSupervisor.isInLockTaskMode(); 7616 } 7617 } 7618 7619 // ========================================================= 7620 // CONTENT PROVIDERS 7621 // ========================================================= 7622 7623 private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) { 7624 List<ProviderInfo> providers = null; 7625 try { 7626 providers = AppGlobals.getPackageManager(). 7627 queryContentProviders(app.processName, app.uid, 7628 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS); 7629 } catch (RemoteException ex) { 7630 } 7631 if (DEBUG_MU) 7632 Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid); 7633 int userId = app.userId; 7634 if (providers != null) { 7635 int N = providers.size(); 7636 app.pubProviders.ensureCapacity(N + app.pubProviders.size()); 7637 for (int i=0; i<N; i++) { 7638 ProviderInfo cpi = 7639 (ProviderInfo)providers.get(i); 7640 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo, 7641 cpi.name, cpi.flags); 7642 if (singleton && UserHandle.getUserId(app.uid) != 0) { 7643 // This is a singleton provider, but a user besides the 7644 // default user is asking to initialize a process it runs 7645 // in... well, no, it doesn't actually run in this process, 7646 // it runs in the process of the default user. Get rid of it. 7647 providers.remove(i); 7648 N--; 7649 i--; 7650 continue; 7651 } 7652 7653 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 7654 ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId); 7655 if (cpr == null) { 7656 cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton); 7657 mProviderMap.putProviderByClass(comp, cpr); 7658 } 7659 if (DEBUG_MU) 7660 Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid); 7661 app.pubProviders.put(cpi.name, cpr); 7662 if (!cpi.multiprocess || !"android".equals(cpi.packageName)) { 7663 // Don't add this if it is a platform component that is marked 7664 // to run in multiple processes, because this is actually 7665 // part of the framework so doesn't make sense to track as a 7666 // separate apk in the process. 7667 app.addPackage(cpi.applicationInfo.packageName, mProcessStats); 7668 } 7669 ensurePackageDexOpt(cpi.applicationInfo.packageName); 7670 } 7671 } 7672 return providers; 7673 } 7674 7675 /** 7676 * Check if {@link ProcessRecord} has a possible chance at accessing the 7677 * given {@link ProviderInfo}. Final permission checking is always done 7678 * in {@link ContentProvider}. 7679 */ 7680 private final String checkContentProviderPermissionLocked( 7681 ProviderInfo cpi, ProcessRecord r) { 7682 final int callingPid = (r != null) ? r.pid : Binder.getCallingPid(); 7683 final int callingUid = (r != null) ? r.uid : Binder.getCallingUid(); 7684 if (checkComponentPermission(cpi.readPermission, callingPid, callingUid, 7685 cpi.applicationInfo.uid, cpi.exported) 7686 == PackageManager.PERMISSION_GRANTED) { 7687 return null; 7688 } 7689 if (checkComponentPermission(cpi.writePermission, callingPid, callingUid, 7690 cpi.applicationInfo.uid, cpi.exported) 7691 == PackageManager.PERMISSION_GRANTED) { 7692 return null; 7693 } 7694 7695 PathPermission[] pps = cpi.pathPermissions; 7696 if (pps != null) { 7697 int i = pps.length; 7698 while (i > 0) { 7699 i--; 7700 PathPermission pp = pps[i]; 7701 if (checkComponentPermission(pp.getReadPermission(), callingPid, callingUid, 7702 cpi.applicationInfo.uid, cpi.exported) 7703 == PackageManager.PERMISSION_GRANTED) { 7704 return null; 7705 } 7706 if (checkComponentPermission(pp.getWritePermission(), callingPid, callingUid, 7707 cpi.applicationInfo.uid, cpi.exported) 7708 == PackageManager.PERMISSION_GRANTED) { 7709 return null; 7710 } 7711 } 7712 } 7713 7714 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid); 7715 if (perms != null) { 7716 for (GrantUri uri : perms.keySet()) { 7717 if (uri.uri.getAuthority().equals(cpi.authority)) { 7718 return null; 7719 } 7720 } 7721 } 7722 7723 String msg; 7724 if (!cpi.exported) { 7725 msg = "Permission Denial: opening provider " + cpi.name 7726 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 7727 + ", uid=" + callingUid + ") that is not exported from uid " 7728 + cpi.applicationInfo.uid; 7729 } else { 7730 msg = "Permission Denial: opening provider " + cpi.name 7731 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 7732 + ", uid=" + callingUid + ") requires " 7733 + cpi.readPermission + " or " + cpi.writePermission; 7734 } 7735 Slog.w(TAG, msg); 7736 return msg; 7737 } 7738 7739 ContentProviderConnection incProviderCountLocked(ProcessRecord r, 7740 final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 7741 if (r != null) { 7742 for (int i=0; i<r.conProviders.size(); i++) { 7743 ContentProviderConnection conn = r.conProviders.get(i); 7744 if (conn.provider == cpr) { 7745 if (DEBUG_PROVIDER) Slog.v(TAG, 7746 "Adding provider requested by " 7747 + r.processName + " from process " 7748 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 7749 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 7750 if (stable) { 7751 conn.stableCount++; 7752 conn.numStableIncs++; 7753 } else { 7754 conn.unstableCount++; 7755 conn.numUnstableIncs++; 7756 } 7757 return conn; 7758 } 7759 } 7760 ContentProviderConnection conn = new ContentProviderConnection(cpr, r); 7761 if (stable) { 7762 conn.stableCount = 1; 7763 conn.numStableIncs = 1; 7764 } else { 7765 conn.unstableCount = 1; 7766 conn.numUnstableIncs = 1; 7767 } 7768 cpr.connections.add(conn); 7769 r.conProviders.add(conn); 7770 return conn; 7771 } 7772 cpr.addExternalProcessHandleLocked(externalProcessToken); 7773 return null; 7774 } 7775 7776 boolean decProviderCountLocked(ContentProviderConnection conn, 7777 ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 7778 if (conn != null) { 7779 cpr = conn.provider; 7780 if (DEBUG_PROVIDER) Slog.v(TAG, 7781 "Removing provider requested by " 7782 + conn.client.processName + " from process " 7783 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 7784 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 7785 if (stable) { 7786 conn.stableCount--; 7787 } else { 7788 conn.unstableCount--; 7789 } 7790 if (conn.stableCount == 0 && conn.unstableCount == 0) { 7791 cpr.connections.remove(conn); 7792 conn.client.conProviders.remove(conn); 7793 return true; 7794 } 7795 return false; 7796 } 7797 cpr.removeExternalProcessHandleLocked(externalProcessToken); 7798 return false; 7799 } 7800 7801 private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller, 7802 String name, IBinder token, boolean stable, int userId) { 7803 ContentProviderRecord cpr; 7804 ContentProviderConnection conn = null; 7805 ProviderInfo cpi = null; 7806 7807 synchronized(this) { 7808 ProcessRecord r = null; 7809 if (caller != null) { 7810 r = getRecordForAppLocked(caller); 7811 if (r == null) { 7812 throw new SecurityException( 7813 "Unable to find app for caller " + caller 7814 + " (pid=" + Binder.getCallingPid() 7815 + ") when getting content provider " + name); 7816 } 7817 } 7818 7819 // First check if this content provider has been published... 7820 cpr = mProviderMap.getProviderByName(name, userId); 7821 boolean providerRunning = cpr != null; 7822 if (providerRunning) { 7823 cpi = cpr.info; 7824 String msg; 7825 if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) { 7826 throw new SecurityException(msg); 7827 } 7828 7829 if (r != null && cpr.canRunHere(r)) { 7830 // This provider has been published or is in the process 7831 // of being published... but it is also allowed to run 7832 // in the caller's process, so don't make a connection 7833 // and just let the caller instantiate its own instance. 7834 ContentProviderHolder holder = cpr.newHolder(null); 7835 // don't give caller the provider object, it needs 7836 // to make its own. 7837 holder.provider = null; 7838 return holder; 7839 } 7840 7841 final long origId = Binder.clearCallingIdentity(); 7842 7843 // In this case the provider instance already exists, so we can 7844 // return it right away. 7845 conn = incProviderCountLocked(r, cpr, token, stable); 7846 if (conn != null && (conn.stableCount+conn.unstableCount) == 1) { 7847 if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 7848 // If this is a perceptible app accessing the provider, 7849 // make sure to count it as being accessed and thus 7850 // back up on the LRU list. This is good because 7851 // content providers are often expensive to start. 7852 updateLruProcessLocked(cpr.proc, false, null); 7853 } 7854 } 7855 7856 if (cpr.proc != null) { 7857 if (false) { 7858 if (cpr.name.flattenToShortString().equals( 7859 "com.android.providers.calendar/.CalendarProvider2")) { 7860 Slog.v(TAG, "****************** KILLING " 7861 + cpr.name.flattenToShortString()); 7862 Process.killProcess(cpr.proc.pid); 7863 } 7864 } 7865 boolean success = updateOomAdjLocked(cpr.proc); 7866 if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success); 7867 // NOTE: there is still a race here where a signal could be 7868 // pending on the process even though we managed to update its 7869 // adj level. Not sure what to do about this, but at least 7870 // the race is now smaller. 7871 if (!success) { 7872 // Uh oh... it looks like the provider's process 7873 // has been killed on us. We need to wait for a new 7874 // process to be started, and make sure its death 7875 // doesn't kill our process. 7876 Slog.i(TAG, 7877 "Existing provider " + cpr.name.flattenToShortString() 7878 + " is crashing; detaching " + r); 7879 boolean lastRef = decProviderCountLocked(conn, cpr, token, stable); 7880 appDiedLocked(cpr.proc, cpr.proc.pid, cpr.proc.thread); 7881 if (!lastRef) { 7882 // This wasn't the last ref our process had on 7883 // the provider... we have now been killed, bail. 7884 return null; 7885 } 7886 providerRunning = false; 7887 conn = null; 7888 } 7889 } 7890 7891 Binder.restoreCallingIdentity(origId); 7892 } 7893 7894 boolean singleton; 7895 if (!providerRunning) { 7896 try { 7897 cpi = AppGlobals.getPackageManager(). 7898 resolveContentProvider(name, 7899 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId); 7900 } catch (RemoteException ex) { 7901 } 7902 if (cpi == null) { 7903 return null; 7904 } 7905 singleton = isSingleton(cpi.processName, cpi.applicationInfo, 7906 cpi.name, cpi.flags); 7907 if (singleton) { 7908 userId = 0; 7909 } 7910 cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId); 7911 7912 String msg; 7913 if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) { 7914 throw new SecurityException(msg); 7915 } 7916 7917 if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate 7918 && !cpi.processName.equals("system")) { 7919 // If this content provider does not run in the system 7920 // process, and the system is not yet ready to run other 7921 // processes, then fail fast instead of hanging. 7922 throw new IllegalArgumentException( 7923 "Attempt to launch content provider before system ready"); 7924 } 7925 7926 // Make sure that the user who owns this provider is started. If not, 7927 // we don't want to allow it to run. 7928 if (mStartedUsers.get(userId) == null) { 7929 Slog.w(TAG, "Unable to launch app " 7930 + cpi.applicationInfo.packageName + "/" 7931 + cpi.applicationInfo.uid + " for provider " 7932 + name + ": user " + userId + " is stopped"); 7933 return null; 7934 } 7935 7936 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 7937 cpr = mProviderMap.getProviderByClass(comp, userId); 7938 final boolean firstClass = cpr == null; 7939 if (firstClass) { 7940 try { 7941 ApplicationInfo ai = 7942 AppGlobals.getPackageManager(). 7943 getApplicationInfo( 7944 cpi.applicationInfo.packageName, 7945 STOCK_PM_FLAGS, userId); 7946 if (ai == null) { 7947 Slog.w(TAG, "No package info for content provider " 7948 + cpi.name); 7949 return null; 7950 } 7951 ai = getAppInfoForUser(ai, userId); 7952 cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton); 7953 } catch (RemoteException ex) { 7954 // pm is in same process, this will never happen. 7955 } 7956 } 7957 7958 if (r != null && cpr.canRunHere(r)) { 7959 // If this is a multiprocess provider, then just return its 7960 // info and allow the caller to instantiate it. Only do 7961 // this if the provider is the same user as the caller's 7962 // process, or can run as root (so can be in any process). 7963 return cpr.newHolder(null); 7964 } 7965 7966 if (DEBUG_PROVIDER) { 7967 RuntimeException e = new RuntimeException("here"); 7968 Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null) 7969 + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e); 7970 } 7971 7972 // This is single process, and our app is now connecting to it. 7973 // See if we are already in the process of launching this 7974 // provider. 7975 final int N = mLaunchingProviders.size(); 7976 int i; 7977 for (i=0; i<N; i++) { 7978 if (mLaunchingProviders.get(i) == cpr) { 7979 break; 7980 } 7981 } 7982 7983 // If the provider is not already being launched, then get it 7984 // started. 7985 if (i >= N) { 7986 final long origId = Binder.clearCallingIdentity(); 7987 7988 try { 7989 // Content provider is now in use, its package can't be stopped. 7990 try { 7991 AppGlobals.getPackageManager().setPackageStoppedState( 7992 cpr.appInfo.packageName, false, userId); 7993 } catch (RemoteException e) { 7994 } catch (IllegalArgumentException e) { 7995 Slog.w(TAG, "Failed trying to unstop package " 7996 + cpr.appInfo.packageName + ": " + e); 7997 } 7998 7999 // Use existing process if already started 8000 ProcessRecord proc = getProcessRecordLocked( 8001 cpi.processName, cpr.appInfo.uid, false); 8002 if (proc != null && proc.thread != null) { 8003 if (DEBUG_PROVIDER) { 8004 Slog.d(TAG, "Installing in existing process " + proc); 8005 } 8006 proc.pubProviders.put(cpi.name, cpr); 8007 try { 8008 proc.thread.scheduleInstallProvider(cpi); 8009 } catch (RemoteException e) { 8010 } 8011 } else { 8012 proc = startProcessLocked(cpi.processName, 8013 cpr.appInfo, false, 0, "content provider", 8014 new ComponentName(cpi.applicationInfo.packageName, 8015 cpi.name), false, false, false); 8016 if (proc == null) { 8017 Slog.w(TAG, "Unable to launch app " 8018 + cpi.applicationInfo.packageName + "/" 8019 + cpi.applicationInfo.uid + " for provider " 8020 + name + ": process is bad"); 8021 return null; 8022 } 8023 } 8024 cpr.launchingApp = proc; 8025 mLaunchingProviders.add(cpr); 8026 } finally { 8027 Binder.restoreCallingIdentity(origId); 8028 } 8029 } 8030 8031 // Make sure the provider is published (the same provider class 8032 // may be published under multiple names). 8033 if (firstClass) { 8034 mProviderMap.putProviderByClass(comp, cpr); 8035 } 8036 8037 mProviderMap.putProviderByName(name, cpr); 8038 conn = incProviderCountLocked(r, cpr, token, stable); 8039 if (conn != null) { 8040 conn.waiting = true; 8041 } 8042 } 8043 } 8044 8045 // Wait for the provider to be published... 8046 synchronized (cpr) { 8047 while (cpr.provider == null) { 8048 if (cpr.launchingApp == null) { 8049 Slog.w(TAG, "Unable to launch app " 8050 + cpi.applicationInfo.packageName + "/" 8051 + cpi.applicationInfo.uid + " for provider " 8052 + name + ": launching app became null"); 8053 EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS, 8054 UserHandle.getUserId(cpi.applicationInfo.uid), 8055 cpi.applicationInfo.packageName, 8056 cpi.applicationInfo.uid, name); 8057 return null; 8058 } 8059 try { 8060 if (DEBUG_MU) { 8061 Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp=" 8062 + cpr.launchingApp); 8063 } 8064 if (conn != null) { 8065 conn.waiting = true; 8066 } 8067 cpr.wait(); 8068 } catch (InterruptedException ex) { 8069 } finally { 8070 if (conn != null) { 8071 conn.waiting = false; 8072 } 8073 } 8074 } 8075 } 8076 return cpr != null ? cpr.newHolder(conn) : null; 8077 } 8078 8079 public final ContentProviderHolder getContentProvider( 8080 IApplicationThread caller, String name, int userId, boolean stable) { 8081 enforceNotIsolatedCaller("getContentProvider"); 8082 if (caller == null) { 8083 String msg = "null IApplicationThread when getting content provider " 8084 + name; 8085 Slog.w(TAG, msg); 8086 throw new SecurityException(msg); 8087 } 8088 8089 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 8090 false, true, "getContentProvider", null); 8091 return getContentProviderImpl(caller, name, null, stable, userId); 8092 } 8093 8094 public ContentProviderHolder getContentProviderExternal( 8095 String name, int userId, IBinder token) { 8096 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 8097 "Do not have permission in call getContentProviderExternal()"); 8098 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 8099 false, true, "getContentProvider", null); 8100 return getContentProviderExternalUnchecked(name, token, userId); 8101 } 8102 8103 private ContentProviderHolder getContentProviderExternalUnchecked(String name, 8104 IBinder token, int userId) { 8105 return getContentProviderImpl(null, name, token, true, userId); 8106 } 8107 8108 /** 8109 * Drop a content provider from a ProcessRecord's bookkeeping 8110 */ 8111 public void removeContentProvider(IBinder connection, boolean stable) { 8112 enforceNotIsolatedCaller("removeContentProvider"); 8113 long ident = Binder.clearCallingIdentity(); 8114 try { 8115 synchronized (this) { 8116 ContentProviderConnection conn; 8117 try { 8118 conn = (ContentProviderConnection)connection; 8119 } catch (ClassCastException e) { 8120 String msg ="removeContentProvider: " + connection 8121 + " not a ContentProviderConnection"; 8122 Slog.w(TAG, msg); 8123 throw new IllegalArgumentException(msg); 8124 } 8125 if (conn == null) { 8126 throw new NullPointerException("connection is null"); 8127 } 8128 if (decProviderCountLocked(conn, null, null, stable)) { 8129 updateOomAdjLocked(); 8130 } 8131 } 8132 } finally { 8133 Binder.restoreCallingIdentity(ident); 8134 } 8135 } 8136 8137 public void removeContentProviderExternal(String name, IBinder token) { 8138 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 8139 "Do not have permission in call removeContentProviderExternal()"); 8140 removeContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId()); 8141 } 8142 8143 private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) { 8144 synchronized (this) { 8145 ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId); 8146 if(cpr == null) { 8147 //remove from mProvidersByClass 8148 if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list"); 8149 return; 8150 } 8151 8152 //update content provider record entry info 8153 ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name); 8154 ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId); 8155 if (localCpr.hasExternalProcessHandles()) { 8156 if (localCpr.removeExternalProcessHandleLocked(token)) { 8157 updateOomAdjLocked(); 8158 } else { 8159 Slog.e(TAG, "Attmpt to remove content provider " + localCpr 8160 + " with no external reference for token: " 8161 + token + "."); 8162 } 8163 } else { 8164 Slog.e(TAG, "Attmpt to remove content provider: " + localCpr 8165 + " with no external references."); 8166 } 8167 } 8168 } 8169 8170 public final void publishContentProviders(IApplicationThread caller, 8171 List<ContentProviderHolder> providers) { 8172 if (providers == null) { 8173 return; 8174 } 8175 8176 enforceNotIsolatedCaller("publishContentProviders"); 8177 synchronized (this) { 8178 final ProcessRecord r = getRecordForAppLocked(caller); 8179 if (DEBUG_MU) 8180 Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid); 8181 if (r == null) { 8182 throw new SecurityException( 8183 "Unable to find app for caller " + caller 8184 + " (pid=" + Binder.getCallingPid() 8185 + ") when publishing content providers"); 8186 } 8187 8188 final long origId = Binder.clearCallingIdentity(); 8189 8190 final int N = providers.size(); 8191 for (int i=0; i<N; i++) { 8192 ContentProviderHolder src = providers.get(i); 8193 if (src == null || src.info == null || src.provider == null) { 8194 continue; 8195 } 8196 ContentProviderRecord dst = r.pubProviders.get(src.info.name); 8197 if (DEBUG_MU) 8198 Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid); 8199 if (dst != null) { 8200 ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name); 8201 mProviderMap.putProviderByClass(comp, dst); 8202 String names[] = dst.info.authority.split(";"); 8203 for (int j = 0; j < names.length; j++) { 8204 mProviderMap.putProviderByName(names[j], dst); 8205 } 8206 8207 int NL = mLaunchingProviders.size(); 8208 int j; 8209 for (j=0; j<NL; j++) { 8210 if (mLaunchingProviders.get(j) == dst) { 8211 mLaunchingProviders.remove(j); 8212 j--; 8213 NL--; 8214 } 8215 } 8216 synchronized (dst) { 8217 dst.provider = src.provider; 8218 dst.proc = r; 8219 dst.notifyAll(); 8220 } 8221 updateOomAdjLocked(r); 8222 } 8223 } 8224 8225 Binder.restoreCallingIdentity(origId); 8226 } 8227 } 8228 8229 public boolean refContentProvider(IBinder connection, int stable, int unstable) { 8230 ContentProviderConnection conn; 8231 try { 8232 conn = (ContentProviderConnection)connection; 8233 } catch (ClassCastException e) { 8234 String msg ="refContentProvider: " + connection 8235 + " not a ContentProviderConnection"; 8236 Slog.w(TAG, msg); 8237 throw new IllegalArgumentException(msg); 8238 } 8239 if (conn == null) { 8240 throw new NullPointerException("connection is null"); 8241 } 8242 8243 synchronized (this) { 8244 if (stable > 0) { 8245 conn.numStableIncs += stable; 8246 } 8247 stable = conn.stableCount + stable; 8248 if (stable < 0) { 8249 throw new IllegalStateException("stableCount < 0: " + stable); 8250 } 8251 8252 if (unstable > 0) { 8253 conn.numUnstableIncs += unstable; 8254 } 8255 unstable = conn.unstableCount + unstable; 8256 if (unstable < 0) { 8257 throw new IllegalStateException("unstableCount < 0: " + unstable); 8258 } 8259 8260 if ((stable+unstable) <= 0) { 8261 throw new IllegalStateException("ref counts can't go to zero here: stable=" 8262 + stable + " unstable=" + unstable); 8263 } 8264 conn.stableCount = stable; 8265 conn.unstableCount = unstable; 8266 return !conn.dead; 8267 } 8268 } 8269 8270 public void unstableProviderDied(IBinder connection) { 8271 ContentProviderConnection conn; 8272 try { 8273 conn = (ContentProviderConnection)connection; 8274 } catch (ClassCastException e) { 8275 String msg ="refContentProvider: " + connection 8276 + " not a ContentProviderConnection"; 8277 Slog.w(TAG, msg); 8278 throw new IllegalArgumentException(msg); 8279 } 8280 if (conn == null) { 8281 throw new NullPointerException("connection is null"); 8282 } 8283 8284 // Safely retrieve the content provider associated with the connection. 8285 IContentProvider provider; 8286 synchronized (this) { 8287 provider = conn.provider.provider; 8288 } 8289 8290 if (provider == null) { 8291 // Um, yeah, we're way ahead of you. 8292 return; 8293 } 8294 8295 // Make sure the caller is being honest with us. 8296 if (provider.asBinder().pingBinder()) { 8297 // Er, no, still looks good to us. 8298 synchronized (this) { 8299 Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid() 8300 + " says " + conn + " died, but we don't agree"); 8301 return; 8302 } 8303 } 8304 8305 // Well look at that! It's dead! 8306 synchronized (this) { 8307 if (conn.provider.provider != provider) { 8308 // But something changed... good enough. 8309 return; 8310 } 8311 8312 ProcessRecord proc = conn.provider.proc; 8313 if (proc == null || proc.thread == null) { 8314 // Seems like the process is already cleaned up. 8315 return; 8316 } 8317 8318 // As far as we're concerned, this is just like receiving a 8319 // death notification... just a bit prematurely. 8320 Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid 8321 + ") early provider death"); 8322 final long ident = Binder.clearCallingIdentity(); 8323 try { 8324 appDiedLocked(proc, proc.pid, proc.thread); 8325 } finally { 8326 Binder.restoreCallingIdentity(ident); 8327 } 8328 } 8329 } 8330 8331 @Override 8332 public void appNotRespondingViaProvider(IBinder connection) { 8333 enforceCallingPermission( 8334 android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()"); 8335 8336 final ContentProviderConnection conn = (ContentProviderConnection) connection; 8337 if (conn == null) { 8338 Slog.w(TAG, "ContentProviderConnection is null"); 8339 return; 8340 } 8341 8342 final ProcessRecord host = conn.provider.proc; 8343 if (host == null) { 8344 Slog.w(TAG, "Failed to find hosting ProcessRecord"); 8345 return; 8346 } 8347 8348 final long token = Binder.clearCallingIdentity(); 8349 try { 8350 appNotResponding(host, null, null, false, "ContentProvider not responding"); 8351 } finally { 8352 Binder.restoreCallingIdentity(token); 8353 } 8354 } 8355 8356 public final void installSystemProviders() { 8357 List<ProviderInfo> providers; 8358 synchronized (this) { 8359 ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID); 8360 providers = generateApplicationProvidersLocked(app); 8361 if (providers != null) { 8362 for (int i=providers.size()-1; i>=0; i--) { 8363 ProviderInfo pi = (ProviderInfo)providers.get(i); 8364 if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) { 8365 Slog.w(TAG, "Not installing system proc provider " + pi.name 8366 + ": not system .apk"); 8367 providers.remove(i); 8368 } 8369 } 8370 } 8371 } 8372 if (providers != null) { 8373 mSystemThread.installSystemProviders(providers); 8374 } 8375 8376 mCoreSettingsObserver = new CoreSettingsObserver(this); 8377 8378 mUsageStatsService.monitorPackages(); 8379 } 8380 8381 /** 8382 * Allows app to retrieve the MIME type of a URI without having permission 8383 * to access its content provider. 8384 * 8385 * CTS tests for this functionality can be run with "runtest cts-appsecurity". 8386 * 8387 * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/ 8388 * src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java 8389 */ 8390 public String getProviderMimeType(Uri uri, int userId) { 8391 enforceNotIsolatedCaller("getProviderMimeType"); 8392 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 8393 userId, false, true, "getProviderMimeType", null); 8394 final String name = uri.getAuthority(); 8395 final long ident = Binder.clearCallingIdentity(); 8396 ContentProviderHolder holder = null; 8397 8398 try { 8399 holder = getContentProviderExternalUnchecked(name, null, userId); 8400 if (holder != null) { 8401 return holder.provider.getType(uri); 8402 } 8403 } catch (RemoteException e) { 8404 Log.w(TAG, "Content provider dead retrieving " + uri, e); 8405 return null; 8406 } finally { 8407 if (holder != null) { 8408 removeContentProviderExternalUnchecked(name, null, userId); 8409 } 8410 Binder.restoreCallingIdentity(ident); 8411 } 8412 8413 return null; 8414 } 8415 8416 // ========================================================= 8417 // GLOBAL MANAGEMENT 8418 // ========================================================= 8419 8420 final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess, 8421 boolean isolated) { 8422 String proc = customProcess != null ? customProcess : info.processName; 8423 BatteryStatsImpl.Uid.Proc ps = null; 8424 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 8425 int uid = info.uid; 8426 if (isolated) { 8427 int userId = UserHandle.getUserId(uid); 8428 int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1; 8429 while (true) { 8430 if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID 8431 || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) { 8432 mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID; 8433 } 8434 uid = UserHandle.getUid(userId, mNextIsolatedProcessUid); 8435 mNextIsolatedProcessUid++; 8436 if (mIsolatedProcesses.indexOfKey(uid) < 0) { 8437 // No process for this uid, use it. 8438 break; 8439 } 8440 stepsLeft--; 8441 if (stepsLeft <= 0) { 8442 return null; 8443 } 8444 } 8445 } 8446 return new ProcessRecord(stats, info, proc, uid); 8447 } 8448 8449 final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated) { 8450 ProcessRecord app; 8451 if (!isolated) { 8452 app = getProcessRecordLocked(info.processName, info.uid, true); 8453 } else { 8454 app = null; 8455 } 8456 8457 if (app == null) { 8458 app = newProcessRecordLocked(info, null, isolated); 8459 mProcessNames.put(info.processName, app.uid, app); 8460 if (isolated) { 8461 mIsolatedProcesses.put(app.uid, app); 8462 } 8463 updateLruProcessLocked(app, false, null); 8464 updateOomAdjLocked(); 8465 } 8466 8467 // This package really, really can not be stopped. 8468 try { 8469 AppGlobals.getPackageManager().setPackageStoppedState( 8470 info.packageName, false, UserHandle.getUserId(app.uid)); 8471 } catch (RemoteException e) { 8472 } catch (IllegalArgumentException e) { 8473 Slog.w(TAG, "Failed trying to unstop package " 8474 + info.packageName + ": " + e); 8475 } 8476 8477 if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) 8478 == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) { 8479 app.persistent = true; 8480 app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ; 8481 } 8482 if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) { 8483 mPersistentStartingProcesses.add(app); 8484 startProcessLocked(app, "added application", app.processName); 8485 } 8486 8487 return app; 8488 } 8489 8490 public void unhandledBack() { 8491 enforceCallingPermission(android.Manifest.permission.FORCE_BACK, 8492 "unhandledBack()"); 8493 8494 synchronized(this) { 8495 final long origId = Binder.clearCallingIdentity(); 8496 try { 8497 getFocusedStack().unhandledBackLocked(); 8498 } finally { 8499 Binder.restoreCallingIdentity(origId); 8500 } 8501 } 8502 } 8503 8504 public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException { 8505 enforceNotIsolatedCaller("openContentUri"); 8506 final int userId = UserHandle.getCallingUserId(); 8507 String name = uri.getAuthority(); 8508 ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId); 8509 ParcelFileDescriptor pfd = null; 8510 if (cph != null) { 8511 // We record the binder invoker's uid in thread-local storage before 8512 // going to the content provider to open the file. Later, in the code 8513 // that handles all permissions checks, we look for this uid and use 8514 // that rather than the Activity Manager's own uid. The effect is that 8515 // we do the check against the caller's permissions even though it looks 8516 // to the content provider like the Activity Manager itself is making 8517 // the request. 8518 sCallerIdentity.set(new Identity( 8519 Binder.getCallingPid(), Binder.getCallingUid())); 8520 try { 8521 pfd = cph.provider.openFile(null, uri, "r", null); 8522 } catch (FileNotFoundException e) { 8523 // do nothing; pfd will be returned null 8524 } finally { 8525 // Ensure that whatever happens, we clean up the identity state 8526 sCallerIdentity.remove(); 8527 } 8528 8529 // We've got the fd now, so we're done with the provider. 8530 removeContentProviderExternalUnchecked(name, null, userId); 8531 } else { 8532 Slog.d(TAG, "Failed to get provider for authority '" + name + "'"); 8533 } 8534 return pfd; 8535 } 8536 8537 // Actually is sleeping or shutting down or whatever else in the future 8538 // is an inactive state. 8539 public boolean isSleepingOrShuttingDown() { 8540 return mSleeping || mShuttingDown; 8541 } 8542 8543 public boolean isSleeping() { 8544 return mSleeping; 8545 } 8546 8547 void goingToSleep() { 8548 synchronized(this) { 8549 mWentToSleep = true; 8550 updateEventDispatchingLocked(); 8551 goToSleepIfNeededLocked(); 8552 } 8553 } 8554 8555 void finishRunningVoiceLocked() { 8556 if (mRunningVoice) { 8557 mRunningVoice = false; 8558 goToSleepIfNeededLocked(); 8559 } 8560 } 8561 8562 void goToSleepIfNeededLocked() { 8563 if (mWentToSleep && !mRunningVoice) { 8564 if (!mSleeping) { 8565 mSleeping = true; 8566 mStackSupervisor.goingToSleepLocked(); 8567 8568 // Initialize the wake times of all processes. 8569 checkExcessivePowerUsageLocked(false); 8570 mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 8571 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 8572 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 8573 } 8574 } 8575 } 8576 8577 @Override 8578 public boolean shutdown(int timeout) { 8579 if (checkCallingPermission(android.Manifest.permission.SHUTDOWN) 8580 != PackageManager.PERMISSION_GRANTED) { 8581 throw new SecurityException("Requires permission " 8582 + android.Manifest.permission.SHUTDOWN); 8583 } 8584 8585 boolean timedout = false; 8586 8587 synchronized(this) { 8588 mShuttingDown = true; 8589 updateEventDispatchingLocked(); 8590 timedout = mStackSupervisor.shutdownLocked(timeout); 8591 } 8592 8593 mAppOpsService.shutdown(); 8594 mUsageStatsService.shutdown(); 8595 mBatteryStatsService.shutdown(); 8596 synchronized (this) { 8597 mProcessStats.shutdownLocked(); 8598 } 8599 8600 return timedout; 8601 } 8602 8603 public final void activitySlept(IBinder token) { 8604 if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token); 8605 8606 final long origId = Binder.clearCallingIdentity(); 8607 8608 synchronized (this) { 8609 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 8610 if (r != null) { 8611 mStackSupervisor.activitySleptLocked(r); 8612 } 8613 } 8614 8615 Binder.restoreCallingIdentity(origId); 8616 } 8617 8618 void logLockScreen(String msg) { 8619 if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg + 8620 " mLockScreenShown=" + mLockScreenShown + " mWentToSleep=" + 8621 mWentToSleep + " mSleeping=" + mSleeping + " mDismissKeyguardOnNextActivity=" + 8622 mStackSupervisor.mDismissKeyguardOnNextActivity); 8623 } 8624 8625 private void comeOutOfSleepIfNeededLocked() { 8626 if ((!mWentToSleep && !mLockScreenShown) || mRunningVoice) { 8627 if (mSleeping) { 8628 mSleeping = false; 8629 mStackSupervisor.comeOutOfSleepIfNeededLocked(); 8630 } 8631 } 8632 } 8633 8634 void wakingUp() { 8635 synchronized(this) { 8636 mWentToSleep = false; 8637 updateEventDispatchingLocked(); 8638 comeOutOfSleepIfNeededLocked(); 8639 } 8640 } 8641 8642 void startRunningVoiceLocked() { 8643 if (!mRunningVoice) { 8644 mRunningVoice = true; 8645 comeOutOfSleepIfNeededLocked(); 8646 } 8647 } 8648 8649 private void updateEventDispatchingLocked() { 8650 mWindowManager.setEventDispatching(mBooted && !mWentToSleep && !mShuttingDown); 8651 } 8652 8653 public void setLockScreenShown(boolean shown) { 8654 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER) 8655 != PackageManager.PERMISSION_GRANTED) { 8656 throw new SecurityException("Requires permission " 8657 + android.Manifest.permission.DEVICE_POWER); 8658 } 8659 8660 synchronized(this) { 8661 long ident = Binder.clearCallingIdentity(); 8662 try { 8663 if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown); 8664 mLockScreenShown = shown; 8665 comeOutOfSleepIfNeededLocked(); 8666 } finally { 8667 Binder.restoreCallingIdentity(ident); 8668 } 8669 } 8670 } 8671 8672 public void stopAppSwitches() { 8673 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 8674 != PackageManager.PERMISSION_GRANTED) { 8675 throw new SecurityException("Requires permission " 8676 + android.Manifest.permission.STOP_APP_SWITCHES); 8677 } 8678 8679 synchronized(this) { 8680 mAppSwitchesAllowedTime = SystemClock.uptimeMillis() 8681 + APP_SWITCH_DELAY_TIME; 8682 mDidAppSwitch = false; 8683 mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 8684 Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 8685 mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME); 8686 } 8687 } 8688 8689 public void resumeAppSwitches() { 8690 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 8691 != PackageManager.PERMISSION_GRANTED) { 8692 throw new SecurityException("Requires permission " 8693 + android.Manifest.permission.STOP_APP_SWITCHES); 8694 } 8695 8696 synchronized(this) { 8697 // Note that we don't execute any pending app switches... we will 8698 // let those wait until either the timeout, or the next start 8699 // activity request. 8700 mAppSwitchesAllowedTime = 0; 8701 } 8702 } 8703 8704 boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid, 8705 String name) { 8706 if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) { 8707 return true; 8708 } 8709 8710 final int perm = checkComponentPermission( 8711 android.Manifest.permission.STOP_APP_SWITCHES, callingPid, 8712 callingUid, -1, true); 8713 if (perm == PackageManager.PERMISSION_GRANTED) { 8714 return true; 8715 } 8716 8717 Slog.w(TAG, name + " request from " + callingUid + " stopped"); 8718 return false; 8719 } 8720 8721 public void setDebugApp(String packageName, boolean waitForDebugger, 8722 boolean persistent) { 8723 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP, 8724 "setDebugApp()"); 8725 8726 long ident = Binder.clearCallingIdentity(); 8727 try { 8728 // Note that this is not really thread safe if there are multiple 8729 // callers into it at the same time, but that's not a situation we 8730 // care about. 8731 if (persistent) { 8732 final ContentResolver resolver = mContext.getContentResolver(); 8733 Settings.Global.putString( 8734 resolver, Settings.Global.DEBUG_APP, 8735 packageName); 8736 Settings.Global.putInt( 8737 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 8738 waitForDebugger ? 1 : 0); 8739 } 8740 8741 synchronized (this) { 8742 if (!persistent) { 8743 mOrigDebugApp = mDebugApp; 8744 mOrigWaitForDebugger = mWaitForDebugger; 8745 } 8746 mDebugApp = packageName; 8747 mWaitForDebugger = waitForDebugger; 8748 mDebugTransient = !persistent; 8749 if (packageName != null) { 8750 forceStopPackageLocked(packageName, -1, false, false, true, true, 8751 false, UserHandle.USER_ALL, "set debug app"); 8752 } 8753 } 8754 } finally { 8755 Binder.restoreCallingIdentity(ident); 8756 } 8757 } 8758 8759 void setOpenGlTraceApp(ApplicationInfo app, String processName) { 8760 synchronized (this) { 8761 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 8762 if (!isDebuggable) { 8763 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 8764 throw new SecurityException("Process not debuggable: " + app.packageName); 8765 } 8766 } 8767 8768 mOpenGlTraceApp = processName; 8769 } 8770 } 8771 8772 void setProfileApp(ApplicationInfo app, String processName, String profileFile, 8773 ParcelFileDescriptor profileFd, boolean autoStopProfiler) { 8774 synchronized (this) { 8775 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 8776 if (!isDebuggable) { 8777 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 8778 throw new SecurityException("Process not debuggable: " + app.packageName); 8779 } 8780 } 8781 mProfileApp = processName; 8782 mProfileFile = profileFile; 8783 if (mProfileFd != null) { 8784 try { 8785 mProfileFd.close(); 8786 } catch (IOException e) { 8787 } 8788 mProfileFd = null; 8789 } 8790 mProfileFd = profileFd; 8791 mProfileType = 0; 8792 mAutoStopProfiler = autoStopProfiler; 8793 } 8794 } 8795 8796 @Override 8797 public void setAlwaysFinish(boolean enabled) { 8798 enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH, 8799 "setAlwaysFinish()"); 8800 8801 Settings.Global.putInt( 8802 mContext.getContentResolver(), 8803 Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0); 8804 8805 synchronized (this) { 8806 mAlwaysFinishActivities = enabled; 8807 } 8808 } 8809 8810 @Override 8811 public void setActivityController(IActivityController controller) { 8812 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 8813 "setActivityController()"); 8814 synchronized (this) { 8815 mController = controller; 8816 Watchdog.getInstance().setActivityController(controller); 8817 } 8818 } 8819 8820 @Override 8821 public void setUserIsMonkey(boolean userIsMonkey) { 8822 synchronized (this) { 8823 synchronized (mPidsSelfLocked) { 8824 final int callingPid = Binder.getCallingPid(); 8825 ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid); 8826 if (precessRecord == null) { 8827 throw new SecurityException("Unknown process: " + callingPid); 8828 } 8829 if (precessRecord.instrumentationUiAutomationConnection == null) { 8830 throw new SecurityException("Only an instrumentation process " 8831 + "with a UiAutomation can call setUserIsMonkey"); 8832 } 8833 } 8834 mUserIsMonkey = userIsMonkey; 8835 } 8836 } 8837 8838 @Override 8839 public boolean isUserAMonkey() { 8840 synchronized (this) { 8841 // If there is a controller also implies the user is a monkey. 8842 return (mUserIsMonkey || mController != null); 8843 } 8844 } 8845 8846 public void requestBugReport() { 8847 enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport"); 8848 SystemProperties.set("ctl.start", "bugreport"); 8849 } 8850 8851 public static long getInputDispatchingTimeoutLocked(ActivityRecord r) { 8852 return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT; 8853 } 8854 8855 public static long getInputDispatchingTimeoutLocked(ProcessRecord r) { 8856 if (r != null && (r.instrumentationClass != null || r.usingWrapper)) { 8857 return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT; 8858 } 8859 return KEY_DISPATCHING_TIMEOUT; 8860 } 8861 8862 @Override 8863 public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) { 8864 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS) 8865 != PackageManager.PERMISSION_GRANTED) { 8866 throw new SecurityException("Requires permission " 8867 + android.Manifest.permission.FILTER_EVENTS); 8868 } 8869 ProcessRecord proc; 8870 long timeout; 8871 synchronized (this) { 8872 synchronized (mPidsSelfLocked) { 8873 proc = mPidsSelfLocked.get(pid); 8874 } 8875 timeout = getInputDispatchingTimeoutLocked(proc); 8876 } 8877 8878 if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) { 8879 return -1; 8880 } 8881 8882 return timeout; 8883 } 8884 8885 /** 8886 * Handle input dispatching timeouts. 8887 * Returns whether input dispatching should be aborted or not. 8888 */ 8889 public boolean inputDispatchingTimedOut(final ProcessRecord proc, 8890 final ActivityRecord activity, final ActivityRecord parent, 8891 final boolean aboveSystem, String reason) { 8892 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS) 8893 != PackageManager.PERMISSION_GRANTED) { 8894 throw new SecurityException("Requires permission " 8895 + android.Manifest.permission.FILTER_EVENTS); 8896 } 8897 8898 final String annotation; 8899 if (reason == null) { 8900 annotation = "Input dispatching timed out"; 8901 } else { 8902 annotation = "Input dispatching timed out (" + reason + ")"; 8903 } 8904 8905 if (proc != null) { 8906 synchronized (this) { 8907 if (proc.debugging) { 8908 return false; 8909 } 8910 8911 if (mDidDexOpt) { 8912 // Give more time since we were dexopting. 8913 mDidDexOpt = false; 8914 return false; 8915 } 8916 8917 if (proc.instrumentationClass != null) { 8918 Bundle info = new Bundle(); 8919 info.putString("shortMsg", "keyDispatchingTimedOut"); 8920 info.putString("longMsg", annotation); 8921 finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info); 8922 return true; 8923 } 8924 } 8925 mHandler.post(new Runnable() { 8926 @Override 8927 public void run() { 8928 appNotResponding(proc, activity, parent, aboveSystem, annotation); 8929 } 8930 }); 8931 } 8932 8933 return true; 8934 } 8935 8936 public Bundle getAssistContextExtras(int requestType) { 8937 enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO, 8938 "getAssistContextExtras()"); 8939 PendingAssistExtras pae; 8940 Bundle extras = new Bundle(); 8941 synchronized (this) { 8942 ActivityRecord activity = getFocusedStack().mResumedActivity; 8943 if (activity == null) { 8944 Slog.w(TAG, "getAssistContextExtras failed: no resumed activity"); 8945 return null; 8946 } 8947 extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName); 8948 if (activity.app == null || activity.app.thread == null) { 8949 Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity); 8950 return extras; 8951 } 8952 if (activity.app.pid == Binder.getCallingPid()) { 8953 Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity); 8954 return extras; 8955 } 8956 pae = new PendingAssistExtras(activity); 8957 try { 8958 activity.app.thread.requestAssistContextExtras(activity.appToken, pae, 8959 requestType); 8960 mPendingAssistExtras.add(pae); 8961 mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT); 8962 } catch (RemoteException e) { 8963 Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity); 8964 return extras; 8965 } 8966 } 8967 synchronized (pae) { 8968 while (!pae.haveResult) { 8969 try { 8970 pae.wait(); 8971 } catch (InterruptedException e) { 8972 } 8973 } 8974 if (pae.result != null) { 8975 extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result); 8976 } 8977 } 8978 synchronized (this) { 8979 mPendingAssistExtras.remove(pae); 8980 mHandler.removeCallbacks(pae); 8981 } 8982 return extras; 8983 } 8984 8985 public void reportAssistContextExtras(IBinder token, Bundle extras) { 8986 PendingAssistExtras pae = (PendingAssistExtras)token; 8987 synchronized (pae) { 8988 pae.result = extras; 8989 pae.haveResult = true; 8990 pae.notifyAll(); 8991 } 8992 } 8993 8994 public void registerProcessObserver(IProcessObserver observer) { 8995 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 8996 "registerProcessObserver()"); 8997 synchronized (this) { 8998 mProcessObservers.register(observer); 8999 } 9000 } 9001 9002 @Override 9003 public void unregisterProcessObserver(IProcessObserver observer) { 9004 synchronized (this) { 9005 mProcessObservers.unregister(observer); 9006 } 9007 } 9008 9009 @Override 9010 public boolean convertFromTranslucent(IBinder token) { 9011 final long origId = Binder.clearCallingIdentity(); 9012 try { 9013 synchronized (this) { 9014 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 9015 if (r == null) { 9016 return false; 9017 } 9018 if (r.changeWindowTranslucency(true)) { 9019 mWindowManager.setAppFullscreen(token, true); 9020 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 9021 return true; 9022 } 9023 return false; 9024 } 9025 } finally { 9026 Binder.restoreCallingIdentity(origId); 9027 } 9028 } 9029 9030 @Override 9031 public boolean convertToTranslucent(IBinder token) { 9032 final long origId = Binder.clearCallingIdentity(); 9033 try { 9034 synchronized (this) { 9035 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 9036 if (r == null) { 9037 return false; 9038 } 9039 if (r.changeWindowTranslucency(false)) { 9040 r.task.stack.convertToTranslucent(r); 9041 mWindowManager.setAppFullscreen(token, false); 9042 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 9043 return true; 9044 } 9045 return false; 9046 } 9047 } finally { 9048 Binder.restoreCallingIdentity(origId); 9049 } 9050 } 9051 9052 @Override 9053 public void setImmersive(IBinder token, boolean immersive) { 9054 synchronized(this) { 9055 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 9056 if (r == null) { 9057 throw new IllegalArgumentException(); 9058 } 9059 r.immersive = immersive; 9060 9061 // update associated state if we're frontmost 9062 if (r == mFocusedActivity) { 9063 if (DEBUG_IMMERSIVE) { 9064 Slog.d(TAG, "Frontmost changed immersion: "+ r); 9065 } 9066 applyUpdateLockStateLocked(r); 9067 } 9068 } 9069 } 9070 9071 @Override 9072 public boolean isImmersive(IBinder token) { 9073 synchronized (this) { 9074 ActivityRecord r = ActivityRecord.isInStackLocked(token); 9075 if (r == null) { 9076 throw new IllegalArgumentException(); 9077 } 9078 return r.immersive; 9079 } 9080 } 9081 9082 public boolean isTopActivityImmersive() { 9083 enforceNotIsolatedCaller("startActivity"); 9084 synchronized (this) { 9085 ActivityRecord r = getFocusedStack().topRunningActivityLocked(null); 9086 return (r != null) ? r.immersive : false; 9087 } 9088 } 9089 9090 public final void enterSafeMode() { 9091 synchronized(this) { 9092 // It only makes sense to do this before the system is ready 9093 // and started launching other packages. 9094 if (!mSystemReady) { 9095 try { 9096 AppGlobals.getPackageManager().enterSafeMode(); 9097 } catch (RemoteException e) { 9098 } 9099 } 9100 9101 mSafeMode = true; 9102 } 9103 } 9104 9105 public final void showSafeModeOverlay() { 9106 View v = LayoutInflater.from(mContext).inflate( 9107 com.android.internal.R.layout.safe_mode, null); 9108 WindowManager.LayoutParams lp = new WindowManager.LayoutParams(); 9109 lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY; 9110 lp.width = WindowManager.LayoutParams.WRAP_CONTENT; 9111 lp.height = WindowManager.LayoutParams.WRAP_CONTENT; 9112 lp.gravity = Gravity.BOTTOM | Gravity.START; 9113 lp.format = v.getBackground().getOpacity(); 9114 lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE 9115 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE; 9116 lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS; 9117 ((WindowManager)mContext.getSystemService( 9118 Context.WINDOW_SERVICE)).addView(v, lp); 9119 } 9120 9121 public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) { 9122 if (!(sender instanceof PendingIntentRecord)) { 9123 return; 9124 } 9125 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 9126 synchronized (stats) { 9127 if (mBatteryStatsService.isOnBattery()) { 9128 mBatteryStatsService.enforceCallingPermission(); 9129 PendingIntentRecord rec = (PendingIntentRecord)sender; 9130 int MY_UID = Binder.getCallingUid(); 9131 int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid; 9132 BatteryStatsImpl.Uid.Pkg pkg = 9133 stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid, 9134 sourcePkg != null ? sourcePkg : rec.key.packageName); 9135 pkg.incWakeupsLocked(); 9136 } 9137 } 9138 } 9139 9140 public boolean killPids(int[] pids, String pReason, boolean secure) { 9141 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 9142 throw new SecurityException("killPids only available to the system"); 9143 } 9144 String reason = (pReason == null) ? "Unknown" : pReason; 9145 // XXX Note: don't acquire main activity lock here, because the window 9146 // manager calls in with its locks held. 9147 9148 boolean killed = false; 9149 synchronized (mPidsSelfLocked) { 9150 int[] types = new int[pids.length]; 9151 int worstType = 0; 9152 for (int i=0; i<pids.length; i++) { 9153 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 9154 if (proc != null) { 9155 int type = proc.setAdj; 9156 types[i] = type; 9157 if (type > worstType) { 9158 worstType = type; 9159 } 9160 } 9161 } 9162 9163 // If the worst oom_adj is somewhere in the cached proc LRU range, 9164 // then constrain it so we will kill all cached procs. 9165 if (worstType < ProcessList.CACHED_APP_MAX_ADJ 9166 && worstType > ProcessList.CACHED_APP_MIN_ADJ) { 9167 worstType = ProcessList.CACHED_APP_MIN_ADJ; 9168 } 9169 9170 // If this is not a secure call, don't let it kill processes that 9171 // are important. 9172 if (!secure && worstType < ProcessList.SERVICE_ADJ) { 9173 worstType = ProcessList.SERVICE_ADJ; 9174 } 9175 9176 Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType); 9177 for (int i=0; i<pids.length; i++) { 9178 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 9179 if (proc == null) { 9180 continue; 9181 } 9182 int adj = proc.setAdj; 9183 if (adj >= worstType && !proc.killedByAm) { 9184 killUnneededProcessLocked(proc, reason); 9185 killed = true; 9186 } 9187 } 9188 } 9189 return killed; 9190 } 9191 9192 @Override 9193 public void killUid(int uid, String reason) { 9194 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 9195 throw new SecurityException("killUid only available to the system"); 9196 } 9197 synchronized (this) { 9198 killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid), 9199 ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false, 9200 reason != null ? reason : "kill uid"); 9201 } 9202 } 9203 9204 @Override 9205 public boolean killProcessesBelowForeground(String reason) { 9206 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 9207 throw new SecurityException("killProcessesBelowForeground() only available to system"); 9208 } 9209 9210 return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason); 9211 } 9212 9213 private boolean killProcessesBelowAdj(int belowAdj, String reason) { 9214 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 9215 throw new SecurityException("killProcessesBelowAdj() only available to system"); 9216 } 9217 9218 boolean killed = false; 9219 synchronized (mPidsSelfLocked) { 9220 final int size = mPidsSelfLocked.size(); 9221 for (int i = 0; i < size; i++) { 9222 final int pid = mPidsSelfLocked.keyAt(i); 9223 final ProcessRecord proc = mPidsSelfLocked.valueAt(i); 9224 if (proc == null) continue; 9225 9226 final int adj = proc.setAdj; 9227 if (adj > belowAdj && !proc.killedByAm) { 9228 killUnneededProcessLocked(proc, reason); 9229 killed = true; 9230 } 9231 } 9232 } 9233 return killed; 9234 } 9235 9236 @Override 9237 public void hang(final IBinder who, boolean allowRestart) { 9238 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 9239 != PackageManager.PERMISSION_GRANTED) { 9240 throw new SecurityException("Requires permission " 9241 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 9242 } 9243 9244 final IBinder.DeathRecipient death = new DeathRecipient() { 9245 @Override 9246 public void binderDied() { 9247 synchronized (this) { 9248 notifyAll(); 9249 } 9250 } 9251 }; 9252 9253 try { 9254 who.linkToDeath(death, 0); 9255 } catch (RemoteException e) { 9256 Slog.w(TAG, "hang: given caller IBinder is already dead."); 9257 return; 9258 } 9259 9260 synchronized (this) { 9261 Watchdog.getInstance().setAllowRestart(allowRestart); 9262 Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid()); 9263 synchronized (death) { 9264 while (who.isBinderAlive()) { 9265 try { 9266 death.wait(); 9267 } catch (InterruptedException e) { 9268 } 9269 } 9270 } 9271 Watchdog.getInstance().setAllowRestart(true); 9272 } 9273 } 9274 9275 @Override 9276 public void restart() { 9277 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 9278 != PackageManager.PERMISSION_GRANTED) { 9279 throw new SecurityException("Requires permission " 9280 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 9281 } 9282 9283 Log.i(TAG, "Sending shutdown broadcast..."); 9284 9285 BroadcastReceiver br = new BroadcastReceiver() { 9286 @Override public void onReceive(Context context, Intent intent) { 9287 // Now the broadcast is done, finish up the low-level shutdown. 9288 Log.i(TAG, "Shutting down activity manager..."); 9289 shutdown(10000); 9290 Log.i(TAG, "Shutdown complete, restarting!"); 9291 Process.killProcess(Process.myPid()); 9292 System.exit(10); 9293 } 9294 }; 9295 9296 // First send the high-level shut down broadcast. 9297 Intent intent = new Intent(Intent.ACTION_SHUTDOWN); 9298 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 9299 intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true); 9300 /* For now we are not doing a clean shutdown, because things seem to get unhappy. 9301 mContext.sendOrderedBroadcastAsUser(intent, 9302 UserHandle.ALL, null, br, mHandler, 0, null, null); 9303 */ 9304 br.onReceive(mContext, intent); 9305 } 9306 9307 private long getLowRamTimeSinceIdle(long now) { 9308 return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0); 9309 } 9310 9311 @Override 9312 public void performIdleMaintenance() { 9313 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 9314 != PackageManager.PERMISSION_GRANTED) { 9315 throw new SecurityException("Requires permission " 9316 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 9317 } 9318 9319 synchronized (this) { 9320 final long now = SystemClock.uptimeMillis(); 9321 final long timeSinceLastIdle = now - mLastIdleTime; 9322 final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now); 9323 mLastIdleTime = now; 9324 mLowRamTimeSinceLastIdle = 0; 9325 if (mLowRamStartTime != 0) { 9326 mLowRamStartTime = now; 9327 } 9328 9329 StringBuilder sb = new StringBuilder(128); 9330 sb.append("Idle maintenance over "); 9331 TimeUtils.formatDuration(timeSinceLastIdle, sb); 9332 sb.append(" low RAM for "); 9333 TimeUtils.formatDuration(lowRamSinceLastIdle, sb); 9334 Slog.i(TAG, sb.toString()); 9335 9336 // If at least 1/3 of our time since the last idle period has been spent 9337 // with RAM low, then we want to kill processes. 9338 boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3); 9339 9340 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 9341 ProcessRecord proc = mLruProcesses.get(i); 9342 if (proc.notCachedSinceIdle) { 9343 if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP 9344 && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) { 9345 if (doKilling && proc.initialIdlePss != 0 9346 && proc.lastPss > ((proc.initialIdlePss*3)/2)) { 9347 killUnneededProcessLocked(proc, "idle maint (pss " + proc.lastPss 9348 + " from " + proc.initialIdlePss + ")"); 9349 } 9350 } 9351 } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) { 9352 proc.notCachedSinceIdle = true; 9353 proc.initialIdlePss = 0; 9354 proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true, 9355 isSleeping(), now); 9356 } 9357 } 9358 9359 mHandler.removeMessages(REQUEST_ALL_PSS_MSG); 9360 mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000); 9361 } 9362 } 9363 9364 private void retrieveSettings() { 9365 final ContentResolver resolver = mContext.getContentResolver(); 9366 String debugApp = Settings.Global.getString( 9367 resolver, Settings.Global.DEBUG_APP); 9368 boolean waitForDebugger = Settings.Global.getInt( 9369 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0; 9370 boolean alwaysFinishActivities = Settings.Global.getInt( 9371 resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0; 9372 boolean forceRtl = Settings.Global.getInt( 9373 resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0; 9374 // Transfer any global setting for forcing RTL layout, into a System Property 9375 SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0"); 9376 9377 Configuration configuration = new Configuration(); 9378 Settings.System.getConfiguration(resolver, configuration); 9379 if (forceRtl) { 9380 // This will take care of setting the correct layout direction flags 9381 configuration.setLayoutDirection(configuration.locale); 9382 } 9383 9384 synchronized (this) { 9385 mDebugApp = mOrigDebugApp = debugApp; 9386 mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger; 9387 mAlwaysFinishActivities = alwaysFinishActivities; 9388 // This happens before any activities are started, so we can 9389 // change mConfiguration in-place. 9390 updateConfigurationLocked(configuration, null, false, true); 9391 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration); 9392 } 9393 } 9394 9395 public boolean testIsSystemReady() { 9396 // no need to synchronize(this) just to read & return the value 9397 return mSystemReady; 9398 } 9399 9400 private static File getCalledPreBootReceiversFile() { 9401 File dataDir = Environment.getDataDirectory(); 9402 File systemDir = new File(dataDir, "system"); 9403 File fname = new File(systemDir, "called_pre_boots.dat"); 9404 return fname; 9405 } 9406 9407 static final int LAST_DONE_VERSION = 10000; 9408 9409 private static ArrayList<ComponentName> readLastDonePreBootReceivers() { 9410 ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>(); 9411 File file = getCalledPreBootReceiversFile(); 9412 FileInputStream fis = null; 9413 try { 9414 fis = new FileInputStream(file); 9415 DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048)); 9416 int fvers = dis.readInt(); 9417 if (fvers == LAST_DONE_VERSION) { 9418 String vers = dis.readUTF(); 9419 String codename = dis.readUTF(); 9420 String build = dis.readUTF(); 9421 if (android.os.Build.VERSION.RELEASE.equals(vers) 9422 && android.os.Build.VERSION.CODENAME.equals(codename) 9423 && android.os.Build.VERSION.INCREMENTAL.equals(build)) { 9424 int num = dis.readInt(); 9425 while (num > 0) { 9426 num--; 9427 String pkg = dis.readUTF(); 9428 String cls = dis.readUTF(); 9429 lastDoneReceivers.add(new ComponentName(pkg, cls)); 9430 } 9431 } 9432 } 9433 } catch (FileNotFoundException e) { 9434 } catch (IOException e) { 9435 Slog.w(TAG, "Failure reading last done pre-boot receivers", e); 9436 } finally { 9437 if (fis != null) { 9438 try { 9439 fis.close(); 9440 } catch (IOException e) { 9441 } 9442 } 9443 } 9444 return lastDoneReceivers; 9445 } 9446 9447 private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) { 9448 File file = getCalledPreBootReceiversFile(); 9449 FileOutputStream fos = null; 9450 DataOutputStream dos = null; 9451 try { 9452 Slog.i(TAG, "Writing new set of last done pre-boot receivers..."); 9453 fos = new FileOutputStream(file); 9454 dos = new DataOutputStream(new BufferedOutputStream(fos, 2048)); 9455 dos.writeInt(LAST_DONE_VERSION); 9456 dos.writeUTF(android.os.Build.VERSION.RELEASE); 9457 dos.writeUTF(android.os.Build.VERSION.CODENAME); 9458 dos.writeUTF(android.os.Build.VERSION.INCREMENTAL); 9459 dos.writeInt(list.size()); 9460 for (int i=0; i<list.size(); i++) { 9461 dos.writeUTF(list.get(i).getPackageName()); 9462 dos.writeUTF(list.get(i).getClassName()); 9463 } 9464 } catch (IOException e) { 9465 Slog.w(TAG, "Failure writing last done pre-boot receivers", e); 9466 file.delete(); 9467 } finally { 9468 FileUtils.sync(fos); 9469 if (dos != null) { 9470 try { 9471 dos.close(); 9472 } catch (IOException e) { 9473 // TODO Auto-generated catch block 9474 e.printStackTrace(); 9475 } 9476 } 9477 } 9478 } 9479 9480 public void systemReady(final Runnable goingCallback) { 9481 synchronized(this) { 9482 if (mSystemReady) { 9483 if (goingCallback != null) goingCallback.run(); 9484 return; 9485 } 9486 9487 // Check to see if there are any update receivers to run. 9488 if (!mDidUpdate) { 9489 if (mWaitingUpdate) { 9490 return; 9491 } 9492 Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED); 9493 List<ResolveInfo> ris = null; 9494 try { 9495 ris = AppGlobals.getPackageManager().queryIntentReceivers( 9496 intent, null, 0, 0); 9497 } catch (RemoteException e) { 9498 } 9499 if (ris != null) { 9500 for (int i=ris.size()-1; i>=0; i--) { 9501 if ((ris.get(i).activityInfo.applicationInfo.flags 9502 &ApplicationInfo.FLAG_SYSTEM) == 0) { 9503 ris.remove(i); 9504 } 9505 } 9506 intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE); 9507 9508 ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers(); 9509 9510 final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>(); 9511 for (int i=0; i<ris.size(); i++) { 9512 ActivityInfo ai = ris.get(i).activityInfo; 9513 ComponentName comp = new ComponentName(ai.packageName, ai.name); 9514 if (lastDoneReceivers.contains(comp)) { 9515 // We already did the pre boot receiver for this app with the current 9516 // platform version, so don't do it again... 9517 ris.remove(i); 9518 i--; 9519 // ...however, do keep it as one that has been done, so we don't 9520 // forget about it when rewriting the file of last done receivers. 9521 doneReceivers.add(comp); 9522 } 9523 } 9524 9525 final int[] users = getUsersLocked(); 9526 for (int i=0; i<ris.size(); i++) { 9527 ActivityInfo ai = ris.get(i).activityInfo; 9528 ComponentName comp = new ComponentName(ai.packageName, ai.name); 9529 doneReceivers.add(comp); 9530 intent.setComponent(comp); 9531 for (int j=0; j<users.length; j++) { 9532 IIntentReceiver finisher = null; 9533 if (i == ris.size()-1 && j == users.length-1) { 9534 finisher = new IIntentReceiver.Stub() { 9535 public void performReceive(Intent intent, int resultCode, 9536 String data, Bundle extras, boolean ordered, 9537 boolean sticky, int sendingUser) { 9538 // The raw IIntentReceiver interface is called 9539 // with the AM lock held, so redispatch to 9540 // execute our code without the lock. 9541 mHandler.post(new Runnable() { 9542 public void run() { 9543 synchronized (ActivityManagerService.this) { 9544 mDidUpdate = true; 9545 } 9546 writeLastDonePreBootReceivers(doneReceivers); 9547 showBootMessage(mContext.getText( 9548 R.string.android_upgrading_complete), 9549 false); 9550 systemReady(goingCallback); 9551 } 9552 }); 9553 } 9554 }; 9555 } 9556 Slog.i(TAG, "Sending system update to " + intent.getComponent() 9557 + " for user " + users[j]); 9558 broadcastIntentLocked(null, null, intent, null, finisher, 9559 0, null, null, null, AppOpsManager.OP_NONE, 9560 true, false, MY_PID, Process.SYSTEM_UID, 9561 users[j]); 9562 if (finisher != null) { 9563 mWaitingUpdate = true; 9564 } 9565 } 9566 } 9567 } 9568 if (mWaitingUpdate) { 9569 return; 9570 } 9571 mDidUpdate = true; 9572 } 9573 9574 mAppOpsService.systemReady(); 9575 mUsageStatsService.systemReady(); 9576 mSystemReady = true; 9577 } 9578 9579 ArrayList<ProcessRecord> procsToKill = null; 9580 synchronized(mPidsSelfLocked) { 9581 for (int i=mPidsSelfLocked.size()-1; i>=0; i--) { 9582 ProcessRecord proc = mPidsSelfLocked.valueAt(i); 9583 if (!isAllowedWhileBooting(proc.info)){ 9584 if (procsToKill == null) { 9585 procsToKill = new ArrayList<ProcessRecord>(); 9586 } 9587 procsToKill.add(proc); 9588 } 9589 } 9590 } 9591 9592 synchronized(this) { 9593 if (procsToKill != null) { 9594 for (int i=procsToKill.size()-1; i>=0; i--) { 9595 ProcessRecord proc = procsToKill.get(i); 9596 Slog.i(TAG, "Removing system update proc: " + proc); 9597 removeProcessLocked(proc, true, false, "system update done"); 9598 } 9599 } 9600 9601 // Now that we have cleaned up any update processes, we 9602 // are ready to start launching real processes and know that 9603 // we won't trample on them any more. 9604 mProcessesReady = true; 9605 } 9606 9607 Slog.i(TAG, "System now ready"); 9608 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY, 9609 SystemClock.uptimeMillis()); 9610 9611 synchronized(this) { 9612 // Make sure we have no pre-ready processes sitting around. 9613 9614 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) { 9615 ResolveInfo ri = mContext.getPackageManager() 9616 .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST), 9617 STOCK_PM_FLAGS); 9618 CharSequence errorMsg = null; 9619 if (ri != null) { 9620 ActivityInfo ai = ri.activityInfo; 9621 ApplicationInfo app = ai.applicationInfo; 9622 if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) { 9623 mTopAction = Intent.ACTION_FACTORY_TEST; 9624 mTopData = null; 9625 mTopComponent = new ComponentName(app.packageName, 9626 ai.name); 9627 } else { 9628 errorMsg = mContext.getResources().getText( 9629 com.android.internal.R.string.factorytest_not_system); 9630 } 9631 } else { 9632 errorMsg = mContext.getResources().getText( 9633 com.android.internal.R.string.factorytest_no_action); 9634 } 9635 if (errorMsg != null) { 9636 mTopAction = null; 9637 mTopData = null; 9638 mTopComponent = null; 9639 Message msg = Message.obtain(); 9640 msg.what = SHOW_FACTORY_ERROR_MSG; 9641 msg.getData().putCharSequence("msg", errorMsg); 9642 mHandler.sendMessage(msg); 9643 } 9644 } 9645 } 9646 9647 retrieveSettings(); 9648 9649 synchronized (this) { 9650 readGrantedUriPermissionsLocked(); 9651 } 9652 9653 if (goingCallback != null) goingCallback.run(); 9654 9655 mSystemServiceManager.startUser(mCurrentUserId); 9656 9657 synchronized (this) { 9658 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 9659 try { 9660 List apps = AppGlobals.getPackageManager(). 9661 getPersistentApplications(STOCK_PM_FLAGS); 9662 if (apps != null) { 9663 int N = apps.size(); 9664 int i; 9665 for (i=0; i<N; i++) { 9666 ApplicationInfo info 9667 = (ApplicationInfo)apps.get(i); 9668 if (info != null && 9669 !info.packageName.equals("android")) { 9670 addAppLocked(info, false); 9671 } 9672 } 9673 } 9674 } catch (RemoteException ex) { 9675 // pm is in same process, this will never happen. 9676 } 9677 } 9678 9679 // Start up initial activity. 9680 mBooting = true; 9681 9682 try { 9683 if (AppGlobals.getPackageManager().hasSystemUidErrors()) { 9684 Message msg = Message.obtain(); 9685 msg.what = SHOW_UID_ERROR_MSG; 9686 mHandler.sendMessage(msg); 9687 } 9688 } catch (RemoteException e) { 9689 } 9690 9691 long ident = Binder.clearCallingIdentity(); 9692 try { 9693 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 9694 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 9695 | Intent.FLAG_RECEIVER_FOREGROUND); 9696 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); 9697 broadcastIntentLocked(null, null, intent, 9698 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 9699 false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId); 9700 intent = new Intent(Intent.ACTION_USER_STARTING); 9701 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 9702 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); 9703 broadcastIntentLocked(null, null, intent, 9704 null, new IIntentReceiver.Stub() { 9705 @Override 9706 public void performReceive(Intent intent, int resultCode, String data, 9707 Bundle extras, boolean ordered, boolean sticky, int sendingUser) 9708 throws RemoteException { 9709 } 9710 }, 0, null, null, 9711 android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 9712 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 9713 } catch (Throwable t) { 9714 Slog.wtf(TAG, "Failed sending first user broadcasts", t); 9715 } finally { 9716 Binder.restoreCallingIdentity(ident); 9717 } 9718 mStackSupervisor.resumeTopActivitiesLocked(); 9719 sendUserSwitchBroadcastsLocked(-1, mCurrentUserId); 9720 } 9721 } 9722 9723 private boolean makeAppCrashingLocked(ProcessRecord app, 9724 String shortMsg, String longMsg, String stackTrace) { 9725 app.crashing = true; 9726 app.crashingReport = generateProcessError(app, 9727 ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace); 9728 startAppProblemLocked(app); 9729 app.stopFreezingAllLocked(); 9730 return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace); 9731 } 9732 9733 private void makeAppNotRespondingLocked(ProcessRecord app, 9734 String activity, String shortMsg, String longMsg) { 9735 app.notResponding = true; 9736 app.notRespondingReport = generateProcessError(app, 9737 ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING, 9738 activity, shortMsg, longMsg, null); 9739 startAppProblemLocked(app); 9740 app.stopFreezingAllLocked(); 9741 } 9742 9743 /** 9744 * Generate a process error record, suitable for attachment to a ProcessRecord. 9745 * 9746 * @param app The ProcessRecord in which the error occurred. 9747 * @param condition Crashing, Application Not Responding, etc. Values are defined in 9748 * ActivityManager.AppErrorStateInfo 9749 * @param activity The activity associated with the crash, if known. 9750 * @param shortMsg Short message describing the crash. 9751 * @param longMsg Long message describing the crash. 9752 * @param stackTrace Full crash stack trace, may be null. 9753 * 9754 * @return Returns a fully-formed AppErrorStateInfo record. 9755 */ 9756 private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app, 9757 int condition, String activity, String shortMsg, String longMsg, String stackTrace) { 9758 ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo(); 9759 9760 report.condition = condition; 9761 report.processName = app.processName; 9762 report.pid = app.pid; 9763 report.uid = app.info.uid; 9764 report.tag = activity; 9765 report.shortMsg = shortMsg; 9766 report.longMsg = longMsg; 9767 report.stackTrace = stackTrace; 9768 9769 return report; 9770 } 9771 9772 void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) { 9773 synchronized (this) { 9774 app.crashing = false; 9775 app.crashingReport = null; 9776 app.notResponding = false; 9777 app.notRespondingReport = null; 9778 if (app.anrDialog == fromDialog) { 9779 app.anrDialog = null; 9780 } 9781 if (app.waitDialog == fromDialog) { 9782 app.waitDialog = null; 9783 } 9784 if (app.pid > 0 && app.pid != MY_PID) { 9785 handleAppCrashLocked(app, null, null, null); 9786 killUnneededProcessLocked(app, "user request after error"); 9787 } 9788 } 9789 } 9790 9791 private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg, 9792 String stackTrace) { 9793 long now = SystemClock.uptimeMillis(); 9794 9795 Long crashTime; 9796 if (!app.isolated) { 9797 crashTime = mProcessCrashTimes.get(app.info.processName, app.uid); 9798 } else { 9799 crashTime = null; 9800 } 9801 if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) { 9802 // This process loses! 9803 Slog.w(TAG, "Process " + app.info.processName 9804 + " has crashed too many times: killing!"); 9805 EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH, 9806 app.userId, app.info.processName, app.uid); 9807 mStackSupervisor.handleAppCrashLocked(app); 9808 if (!app.persistent) { 9809 // We don't want to start this process again until the user 9810 // explicitly does so... but for persistent process, we really 9811 // need to keep it running. If a persistent process is actually 9812 // repeatedly crashing, then badness for everyone. 9813 EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid, 9814 app.info.processName); 9815 if (!app.isolated) { 9816 // XXX We don't have a way to mark isolated processes 9817 // as bad, since they don't have a peristent identity. 9818 mBadProcesses.put(app.info.processName, app.uid, 9819 new BadProcessInfo(now, shortMsg, longMsg, stackTrace)); 9820 mProcessCrashTimes.remove(app.info.processName, app.uid); 9821 } 9822 app.bad = true; 9823 app.removed = true; 9824 // Don't let services in this process be restarted and potentially 9825 // annoy the user repeatedly. Unless it is persistent, since those 9826 // processes run critical code. 9827 removeProcessLocked(app, false, false, "crash"); 9828 mStackSupervisor.resumeTopActivitiesLocked(); 9829 return false; 9830 } 9831 mStackSupervisor.resumeTopActivitiesLocked(); 9832 } else { 9833 mStackSupervisor.finishTopRunningActivityLocked(app); 9834 } 9835 9836 // Bump up the crash count of any services currently running in the proc. 9837 for (int i=app.services.size()-1; i>=0; i--) { 9838 // Any services running in the application need to be placed 9839 // back in the pending list. 9840 ServiceRecord sr = app.services.valueAt(i); 9841 sr.crashCount++; 9842 } 9843 9844 // If the crashing process is what we consider to be the "home process" and it has been 9845 // replaced by a third-party app, clear the package preferred activities from packages 9846 // with a home activity running in the process to prevent a repeatedly crashing app 9847 // from blocking the user to manually clear the list. 9848 final ArrayList<ActivityRecord> activities = app.activities; 9849 if (app == mHomeProcess && activities.size() > 0 9850 && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) { 9851 for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) { 9852 final ActivityRecord r = activities.get(activityNdx); 9853 if (r.isHomeActivity()) { 9854 Log.i(TAG, "Clearing package preferred activities from " + r.packageName); 9855 try { 9856 ActivityThread.getPackageManager() 9857 .clearPackagePreferredActivities(r.packageName); 9858 } catch (RemoteException c) { 9859 // pm is in same process, this will never happen. 9860 } 9861 } 9862 } 9863 } 9864 9865 if (!app.isolated) { 9866 // XXX Can't keep track of crash times for isolated processes, 9867 // because they don't have a perisistent identity. 9868 mProcessCrashTimes.put(app.info.processName, app.uid, now); 9869 } 9870 9871 return true; 9872 } 9873 9874 void startAppProblemLocked(ProcessRecord app) { 9875 if (app.userId == mCurrentUserId) { 9876 app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver( 9877 mContext, app.info.packageName, app.info.flags); 9878 } else { 9879 // If this app is not running under the current user, then we 9880 // can't give it a report button because that would require 9881 // launching the report UI under a different user. 9882 app.errorReportReceiver = null; 9883 } 9884 skipCurrentReceiverLocked(app); 9885 } 9886 9887 void skipCurrentReceiverLocked(ProcessRecord app) { 9888 for (BroadcastQueue queue : mBroadcastQueues) { 9889 queue.skipCurrentReceiverLocked(app); 9890 } 9891 } 9892 9893 /** 9894 * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes. 9895 * The application process will exit immediately after this call returns. 9896 * @param app object of the crashing app, null for the system server 9897 * @param crashInfo describing the exception 9898 */ 9899 public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) { 9900 ProcessRecord r = findAppProcess(app, "Crash"); 9901 final String processName = app == null ? "system_server" 9902 : (r == null ? "unknown" : r.processName); 9903 9904 handleApplicationCrashInner("crash", r, processName, crashInfo); 9905 } 9906 9907 /* Native crash reporting uses this inner version because it needs to be somewhat 9908 * decoupled from the AM-managed cleanup lifecycle 9909 */ 9910 void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName, 9911 ApplicationErrorReport.CrashInfo crashInfo) { 9912 EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(), 9913 UserHandle.getUserId(Binder.getCallingUid()), processName, 9914 r == null ? -1 : r.info.flags, 9915 crashInfo.exceptionClassName, 9916 crashInfo.exceptionMessage, 9917 crashInfo.throwFileName, 9918 crashInfo.throwLineNumber); 9919 9920 addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo); 9921 9922 crashApplication(r, crashInfo); 9923 } 9924 9925 public void handleApplicationStrictModeViolation( 9926 IBinder app, 9927 int violationMask, 9928 StrictMode.ViolationInfo info) { 9929 ProcessRecord r = findAppProcess(app, "StrictMode"); 9930 if (r == null) { 9931 return; 9932 } 9933 9934 if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) { 9935 Integer stackFingerprint = info.hashCode(); 9936 boolean logIt = true; 9937 synchronized (mAlreadyLoggedViolatedStacks) { 9938 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) { 9939 logIt = false; 9940 // TODO: sub-sample into EventLog for these, with 9941 // the info.durationMillis? Then we'd get 9942 // the relative pain numbers, without logging all 9943 // the stack traces repeatedly. We'd want to do 9944 // likewise in the client code, which also does 9945 // dup suppression, before the Binder call. 9946 } else { 9947 if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) { 9948 mAlreadyLoggedViolatedStacks.clear(); 9949 } 9950 mAlreadyLoggedViolatedStacks.add(stackFingerprint); 9951 } 9952 } 9953 if (logIt) { 9954 logStrictModeViolationToDropBox(r, info); 9955 } 9956 } 9957 9958 if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) { 9959 AppErrorResult result = new AppErrorResult(); 9960 synchronized (this) { 9961 final long origId = Binder.clearCallingIdentity(); 9962 9963 Message msg = Message.obtain(); 9964 msg.what = SHOW_STRICT_MODE_VIOLATION_MSG; 9965 HashMap<String, Object> data = new HashMap<String, Object>(); 9966 data.put("result", result); 9967 data.put("app", r); 9968 data.put("violationMask", violationMask); 9969 data.put("info", info); 9970 msg.obj = data; 9971 mHandler.sendMessage(msg); 9972 9973 Binder.restoreCallingIdentity(origId); 9974 } 9975 int res = result.get(); 9976 Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res); 9977 } 9978 } 9979 9980 // Depending on the policy in effect, there could be a bunch of 9981 // these in quick succession so we try to batch these together to 9982 // minimize disk writes, number of dropbox entries, and maximize 9983 // compression, by having more fewer, larger records. 9984 private void logStrictModeViolationToDropBox( 9985 ProcessRecord process, 9986 StrictMode.ViolationInfo info) { 9987 if (info == null) { 9988 return; 9989 } 9990 final boolean isSystemApp = process == null || 9991 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM | 9992 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0; 9993 final String processName = process == null ? "unknown" : process.processName; 9994 final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode"; 9995 final DropBoxManager dbox = (DropBoxManager) 9996 mContext.getSystemService(Context.DROPBOX_SERVICE); 9997 9998 // Exit early if the dropbox isn't configured to accept this report type. 9999 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 10000 10001 boolean bufferWasEmpty; 10002 boolean needsFlush; 10003 final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024); 10004 synchronized (sb) { 10005 bufferWasEmpty = sb.length() == 0; 10006 appendDropBoxProcessHeaders(process, processName, sb); 10007 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 10008 sb.append("System-App: ").append(isSystemApp).append("\n"); 10009 sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n"); 10010 if (info.violationNumThisLoop != 0) { 10011 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n"); 10012 } 10013 if (info.numAnimationsRunning != 0) { 10014 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n"); 10015 } 10016 if (info.broadcastIntentAction != null) { 10017 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n"); 10018 } 10019 if (info.durationMillis != -1) { 10020 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n"); 10021 } 10022 if (info.numInstances != -1) { 10023 sb.append("Instance-Count: ").append(info.numInstances).append("\n"); 10024 } 10025 if (info.tags != null) { 10026 for (String tag : info.tags) { 10027 sb.append("Span-Tag: ").append(tag).append("\n"); 10028 } 10029 } 10030 sb.append("\n"); 10031 if (info.crashInfo != null && info.crashInfo.stackTrace != null) { 10032 sb.append(info.crashInfo.stackTrace); 10033 } 10034 sb.append("\n"); 10035 10036 // Only buffer up to ~64k. Various logging bits truncate 10037 // things at 128k. 10038 needsFlush = (sb.length() > 64 * 1024); 10039 } 10040 10041 // Flush immediately if the buffer's grown too large, or this 10042 // is a non-system app. Non-system apps are isolated with a 10043 // different tag & policy and not batched. 10044 // 10045 // Batching is useful during internal testing with 10046 // StrictMode settings turned up high. Without batching, 10047 // thousands of separate files could be created on boot. 10048 if (!isSystemApp || needsFlush) { 10049 new Thread("Error dump: " + dropboxTag) { 10050 @Override 10051 public void run() { 10052 String report; 10053 synchronized (sb) { 10054 report = sb.toString(); 10055 sb.delete(0, sb.length()); 10056 sb.trimToSize(); 10057 } 10058 if (report.length() != 0) { 10059 dbox.addText(dropboxTag, report); 10060 } 10061 } 10062 }.start(); 10063 return; 10064 } 10065 10066 // System app batching: 10067 if (!bufferWasEmpty) { 10068 // An existing dropbox-writing thread is outstanding, so 10069 // we don't need to start it up. The existing thread will 10070 // catch the buffer appends we just did. 10071 return; 10072 } 10073 10074 // Worker thread to both batch writes and to avoid blocking the caller on I/O. 10075 // (After this point, we shouldn't access AMS internal data structures.) 10076 new Thread("Error dump: " + dropboxTag) { 10077 @Override 10078 public void run() { 10079 // 5 second sleep to let stacks arrive and be batched together 10080 try { 10081 Thread.sleep(5000); // 5 seconds 10082 } catch (InterruptedException e) {} 10083 10084 String errorReport; 10085 synchronized (mStrictModeBuffer) { 10086 errorReport = mStrictModeBuffer.toString(); 10087 if (errorReport.length() == 0) { 10088 return; 10089 } 10090 mStrictModeBuffer.delete(0, mStrictModeBuffer.length()); 10091 mStrictModeBuffer.trimToSize(); 10092 } 10093 dbox.addText(dropboxTag, errorReport); 10094 } 10095 }.start(); 10096 } 10097 10098 /** 10099 * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors. 10100 * @param app object of the crashing app, null for the system server 10101 * @param tag reported by the caller 10102 * @param crashInfo describing the context of the error 10103 * @return true if the process should exit immediately (WTF is fatal) 10104 */ 10105 public boolean handleApplicationWtf(IBinder app, String tag, 10106 ApplicationErrorReport.CrashInfo crashInfo) { 10107 ProcessRecord r = findAppProcess(app, "WTF"); 10108 final String processName = app == null ? "system_server" 10109 : (r == null ? "unknown" : r.processName); 10110 10111 EventLog.writeEvent(EventLogTags.AM_WTF, 10112 UserHandle.getUserId(Binder.getCallingUid()), Binder.getCallingPid(), 10113 processName, 10114 r == null ? -1 : r.info.flags, 10115 tag, crashInfo.exceptionMessage); 10116 10117 addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo); 10118 10119 if (r != null && r.pid != Process.myPid() && 10120 Settings.Global.getInt(mContext.getContentResolver(), 10121 Settings.Global.WTF_IS_FATAL, 0) != 0) { 10122 crashApplication(r, crashInfo); 10123 return true; 10124 } else { 10125 return false; 10126 } 10127 } 10128 10129 /** 10130 * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit}) 10131 * @return the corresponding {@link ProcessRecord} object, or null if none could be found 10132 */ 10133 private ProcessRecord findAppProcess(IBinder app, String reason) { 10134 if (app == null) { 10135 return null; 10136 } 10137 10138 synchronized (this) { 10139 final int NP = mProcessNames.getMap().size(); 10140 for (int ip=0; ip<NP; ip++) { 10141 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 10142 final int NA = apps.size(); 10143 for (int ia=0; ia<NA; ia++) { 10144 ProcessRecord p = apps.valueAt(ia); 10145 if (p.thread != null && p.thread.asBinder() == app) { 10146 return p; 10147 } 10148 } 10149 } 10150 10151 Slog.w(TAG, "Can't find mystery application for " + reason 10152 + " from pid=" + Binder.getCallingPid() 10153 + " uid=" + Binder.getCallingUid() + ": " + app); 10154 return null; 10155 } 10156 } 10157 10158 /** 10159 * Utility function for addErrorToDropBox and handleStrictModeViolation's logging 10160 * to append various headers to the dropbox log text. 10161 */ 10162 private void appendDropBoxProcessHeaders(ProcessRecord process, String processName, 10163 StringBuilder sb) { 10164 // Watchdog thread ends up invoking this function (with 10165 // a null ProcessRecord) to add the stack file to dropbox. 10166 // Do not acquire a lock on this (am) in such cases, as it 10167 // could cause a potential deadlock, if and when watchdog 10168 // is invoked due to unavailability of lock on am and it 10169 // would prevent watchdog from killing system_server. 10170 if (process == null) { 10171 sb.append("Process: ").append(processName).append("\n"); 10172 return; 10173 } 10174 // Note: ProcessRecord 'process' is guarded by the service 10175 // instance. (notably process.pkgList, which could otherwise change 10176 // concurrently during execution of this method) 10177 synchronized (this) { 10178 sb.append("Process: ").append(processName).append("\n"); 10179 int flags = process.info.flags; 10180 IPackageManager pm = AppGlobals.getPackageManager(); 10181 sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n"); 10182 for (int ip=0; ip<process.pkgList.size(); ip++) { 10183 String pkg = process.pkgList.keyAt(ip); 10184 sb.append("Package: ").append(pkg); 10185 try { 10186 PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId()); 10187 if (pi != null) { 10188 sb.append(" v").append(pi.versionCode); 10189 if (pi.versionName != null) { 10190 sb.append(" (").append(pi.versionName).append(")"); 10191 } 10192 } 10193 } catch (RemoteException e) { 10194 Slog.e(TAG, "Error getting package info: " + pkg, e); 10195 } 10196 sb.append("\n"); 10197 } 10198 } 10199 } 10200 10201 private static String processClass(ProcessRecord process) { 10202 if (process == null || process.pid == MY_PID) { 10203 return "system_server"; 10204 } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) { 10205 return "system_app"; 10206 } else { 10207 return "data_app"; 10208 } 10209 } 10210 10211 /** 10212 * Write a description of an error (crash, WTF, ANR) to the drop box. 10213 * @param eventType to include in the drop box tag ("crash", "wtf", etc.) 10214 * @param process which caused the error, null means the system server 10215 * @param activity which triggered the error, null if unknown 10216 * @param parent activity related to the error, null if unknown 10217 * @param subject line related to the error, null if absent 10218 * @param report in long form describing the error, null if absent 10219 * @param logFile to include in the report, null if none 10220 * @param crashInfo giving an application stack trace, null if absent 10221 */ 10222 public void addErrorToDropBox(String eventType, 10223 ProcessRecord process, String processName, ActivityRecord activity, 10224 ActivityRecord parent, String subject, 10225 final String report, final File logFile, 10226 final ApplicationErrorReport.CrashInfo crashInfo) { 10227 // NOTE -- this must never acquire the ActivityManagerService lock, 10228 // otherwise the watchdog may be prevented from resetting the system. 10229 10230 final String dropboxTag = processClass(process) + "_" + eventType; 10231 final DropBoxManager dbox = (DropBoxManager) 10232 mContext.getSystemService(Context.DROPBOX_SERVICE); 10233 10234 // Exit early if the dropbox isn't configured to accept this report type. 10235 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 10236 10237 final StringBuilder sb = new StringBuilder(1024); 10238 appendDropBoxProcessHeaders(process, processName, sb); 10239 if (activity != null) { 10240 sb.append("Activity: ").append(activity.shortComponentName).append("\n"); 10241 } 10242 if (parent != null && parent.app != null && parent.app.pid != process.pid) { 10243 sb.append("Parent-Process: ").append(parent.app.processName).append("\n"); 10244 } 10245 if (parent != null && parent != activity) { 10246 sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n"); 10247 } 10248 if (subject != null) { 10249 sb.append("Subject: ").append(subject).append("\n"); 10250 } 10251 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 10252 if (Debug.isDebuggerConnected()) { 10253 sb.append("Debugger: Connected\n"); 10254 } 10255 sb.append("\n"); 10256 10257 // Do the rest in a worker thread to avoid blocking the caller on I/O 10258 // (After this point, we shouldn't access AMS internal data structures.) 10259 Thread worker = new Thread("Error dump: " + dropboxTag) { 10260 @Override 10261 public void run() { 10262 if (report != null) { 10263 sb.append(report); 10264 } 10265 if (logFile != null) { 10266 try { 10267 sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE, 10268 "\n\n[[TRUNCATED]]")); 10269 } catch (IOException e) { 10270 Slog.e(TAG, "Error reading " + logFile, e); 10271 } 10272 } 10273 if (crashInfo != null && crashInfo.stackTrace != null) { 10274 sb.append(crashInfo.stackTrace); 10275 } 10276 10277 String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag; 10278 int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0); 10279 if (lines > 0) { 10280 sb.append("\n"); 10281 10282 // Merge several logcat streams, and take the last N lines 10283 InputStreamReader input = null; 10284 try { 10285 java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat", 10286 "-v", "time", "-b", "events", "-b", "system", "-b", "main", 10287 "-t", String.valueOf(lines)).redirectErrorStream(true).start(); 10288 10289 try { logcat.getOutputStream().close(); } catch (IOException e) {} 10290 try { logcat.getErrorStream().close(); } catch (IOException e) {} 10291 input = new InputStreamReader(logcat.getInputStream()); 10292 10293 int num; 10294 char[] buf = new char[8192]; 10295 while ((num = input.read(buf)) > 0) sb.append(buf, 0, num); 10296 } catch (IOException e) { 10297 Slog.e(TAG, "Error running logcat", e); 10298 } finally { 10299 if (input != null) try { input.close(); } catch (IOException e) {} 10300 } 10301 } 10302 10303 dbox.addText(dropboxTag, sb.toString()); 10304 } 10305 }; 10306 10307 if (process == null) { 10308 // If process is null, we are being called from some internal code 10309 // and may be about to die -- run this synchronously. 10310 worker.run(); 10311 } else { 10312 worker.start(); 10313 } 10314 } 10315 10316 /** 10317 * Bring up the "unexpected error" dialog box for a crashing app. 10318 * Deal with edge cases (intercepts from instrumented applications, 10319 * ActivityController, error intent receivers, that sort of thing). 10320 * @param r the application crashing 10321 * @param crashInfo describing the failure 10322 */ 10323 private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) { 10324 long timeMillis = System.currentTimeMillis(); 10325 String shortMsg = crashInfo.exceptionClassName; 10326 String longMsg = crashInfo.exceptionMessage; 10327 String stackTrace = crashInfo.stackTrace; 10328 if (shortMsg != null && longMsg != null) { 10329 longMsg = shortMsg + ": " + longMsg; 10330 } else if (shortMsg != null) { 10331 longMsg = shortMsg; 10332 } 10333 10334 AppErrorResult result = new AppErrorResult(); 10335 synchronized (this) { 10336 if (mController != null) { 10337 try { 10338 String name = r != null ? r.processName : null; 10339 int pid = r != null ? r.pid : Binder.getCallingPid(); 10340 if (!mController.appCrashed(name, pid, 10341 shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) { 10342 Slog.w(TAG, "Force-killing crashed app " + name 10343 + " at watcher's request"); 10344 Process.killProcess(pid); 10345 return; 10346 } 10347 } catch (RemoteException e) { 10348 mController = null; 10349 Watchdog.getInstance().setActivityController(null); 10350 } 10351 } 10352 10353 final long origId = Binder.clearCallingIdentity(); 10354 10355 // If this process is running instrumentation, finish it. 10356 if (r != null && r.instrumentationClass != null) { 10357 Slog.w(TAG, "Error in app " + r.processName 10358 + " running instrumentation " + r.instrumentationClass + ":"); 10359 if (shortMsg != null) Slog.w(TAG, " " + shortMsg); 10360 if (longMsg != null) Slog.w(TAG, " " + longMsg); 10361 Bundle info = new Bundle(); 10362 info.putString("shortMsg", shortMsg); 10363 info.putString("longMsg", longMsg); 10364 finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info); 10365 Binder.restoreCallingIdentity(origId); 10366 return; 10367 } 10368 10369 // If we can't identify the process or it's already exceeded its crash quota, 10370 // quit right away without showing a crash dialog. 10371 if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) { 10372 Binder.restoreCallingIdentity(origId); 10373 return; 10374 } 10375 10376 Message msg = Message.obtain(); 10377 msg.what = SHOW_ERROR_MSG; 10378 HashMap data = new HashMap(); 10379 data.put("result", result); 10380 data.put("app", r); 10381 msg.obj = data; 10382 mHandler.sendMessage(msg); 10383 10384 Binder.restoreCallingIdentity(origId); 10385 } 10386 10387 int res = result.get(); 10388 10389 Intent appErrorIntent = null; 10390 synchronized (this) { 10391 if (r != null && !r.isolated) { 10392 // XXX Can't keep track of crash time for isolated processes, 10393 // since they don't have a persistent identity. 10394 mProcessCrashTimes.put(r.info.processName, r.uid, 10395 SystemClock.uptimeMillis()); 10396 } 10397 if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) { 10398 appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo); 10399 } 10400 } 10401 10402 if (appErrorIntent != null) { 10403 try { 10404 mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId)); 10405 } catch (ActivityNotFoundException e) { 10406 Slog.w(TAG, "bug report receiver dissappeared", e); 10407 } 10408 } 10409 } 10410 10411 Intent createAppErrorIntentLocked(ProcessRecord r, 10412 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 10413 ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo); 10414 if (report == null) { 10415 return null; 10416 } 10417 Intent result = new Intent(Intent.ACTION_APP_ERROR); 10418 result.setComponent(r.errorReportReceiver); 10419 result.putExtra(Intent.EXTRA_BUG_REPORT, report); 10420 result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 10421 return result; 10422 } 10423 10424 private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r, 10425 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 10426 if (r.errorReportReceiver == null) { 10427 return null; 10428 } 10429 10430 if (!r.crashing && !r.notResponding && !r.forceCrashReport) { 10431 return null; 10432 } 10433 10434 ApplicationErrorReport report = new ApplicationErrorReport(); 10435 report.packageName = r.info.packageName; 10436 report.installerPackageName = r.errorReportReceiver.getPackageName(); 10437 report.processName = r.processName; 10438 report.time = timeMillis; 10439 report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0; 10440 10441 if (r.crashing || r.forceCrashReport) { 10442 report.type = ApplicationErrorReport.TYPE_CRASH; 10443 report.crashInfo = crashInfo; 10444 } else if (r.notResponding) { 10445 report.type = ApplicationErrorReport.TYPE_ANR; 10446 report.anrInfo = new ApplicationErrorReport.AnrInfo(); 10447 10448 report.anrInfo.activity = r.notRespondingReport.tag; 10449 report.anrInfo.cause = r.notRespondingReport.shortMsg; 10450 report.anrInfo.info = r.notRespondingReport.longMsg; 10451 } 10452 10453 return report; 10454 } 10455 10456 public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() { 10457 enforceNotIsolatedCaller("getProcessesInErrorState"); 10458 // assume our apps are happy - lazy create the list 10459 List<ActivityManager.ProcessErrorStateInfo> errList = null; 10460 10461 final boolean allUsers = ActivityManager.checkUidPermission( 10462 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 10463 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 10464 int userId = UserHandle.getUserId(Binder.getCallingUid()); 10465 10466 synchronized (this) { 10467 10468 // iterate across all processes 10469 for (int i=mLruProcesses.size()-1; i>=0; i--) { 10470 ProcessRecord app = mLruProcesses.get(i); 10471 if (!allUsers && app.userId != userId) { 10472 continue; 10473 } 10474 if ((app.thread != null) && (app.crashing || app.notResponding)) { 10475 // This one's in trouble, so we'll generate a report for it 10476 // crashes are higher priority (in case there's a crash *and* an anr) 10477 ActivityManager.ProcessErrorStateInfo report = null; 10478 if (app.crashing) { 10479 report = app.crashingReport; 10480 } else if (app.notResponding) { 10481 report = app.notRespondingReport; 10482 } 10483 10484 if (report != null) { 10485 if (errList == null) { 10486 errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1); 10487 } 10488 errList.add(report); 10489 } else { 10490 Slog.w(TAG, "Missing app error report, app = " + app.processName + 10491 " crashing = " + app.crashing + 10492 " notResponding = " + app.notResponding); 10493 } 10494 } 10495 } 10496 } 10497 10498 return errList; 10499 } 10500 10501 static int oomAdjToImportance(int adj, ActivityManager.RunningAppProcessInfo currApp) { 10502 if (adj >= ProcessList.CACHED_APP_MIN_ADJ) { 10503 if (currApp != null) { 10504 currApp.lru = adj - ProcessList.CACHED_APP_MIN_ADJ + 1; 10505 } 10506 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 10507 } else if (adj >= ProcessList.SERVICE_B_ADJ) { 10508 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 10509 } else if (adj >= ProcessList.HOME_APP_ADJ) { 10510 if (currApp != null) { 10511 currApp.lru = 0; 10512 } 10513 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 10514 } else if (adj >= ProcessList.SERVICE_ADJ) { 10515 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 10516 } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 10517 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE; 10518 } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) { 10519 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE; 10520 } else if (adj >= ProcessList.VISIBLE_APP_ADJ) { 10521 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE; 10522 } else { 10523 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND; 10524 } 10525 } 10526 10527 private void fillInProcMemInfo(ProcessRecord app, 10528 ActivityManager.RunningAppProcessInfo outInfo) { 10529 outInfo.pid = app.pid; 10530 outInfo.uid = app.info.uid; 10531 if (mHeavyWeightProcess == app) { 10532 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE; 10533 } 10534 if (app.persistent) { 10535 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT; 10536 } 10537 if (app.activities.size() > 0) { 10538 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES; 10539 } 10540 outInfo.lastTrimLevel = app.trimMemoryLevel; 10541 int adj = app.curAdj; 10542 outInfo.importance = oomAdjToImportance(adj, outInfo); 10543 outInfo.importanceReasonCode = app.adjTypeCode; 10544 outInfo.processState = app.curProcState; 10545 } 10546 10547 public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() { 10548 enforceNotIsolatedCaller("getRunningAppProcesses"); 10549 // Lazy instantiation of list 10550 List<ActivityManager.RunningAppProcessInfo> runList = null; 10551 final boolean allUsers = ActivityManager.checkUidPermission( 10552 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 10553 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 10554 int userId = UserHandle.getUserId(Binder.getCallingUid()); 10555 synchronized (this) { 10556 // Iterate across all processes 10557 for (int i=mLruProcesses.size()-1; i>=0; i--) { 10558 ProcessRecord app = mLruProcesses.get(i); 10559 if (!allUsers && app.userId != userId) { 10560 continue; 10561 } 10562 if ((app.thread != null) && (!app.crashing && !app.notResponding)) { 10563 // Generate process state info for running application 10564 ActivityManager.RunningAppProcessInfo currApp = 10565 new ActivityManager.RunningAppProcessInfo(app.processName, 10566 app.pid, app.getPackageList()); 10567 fillInProcMemInfo(app, currApp); 10568 if (app.adjSource instanceof ProcessRecord) { 10569 currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid; 10570 currApp.importanceReasonImportance = oomAdjToImportance( 10571 app.adjSourceOom, null); 10572 } else if (app.adjSource instanceof ActivityRecord) { 10573 ActivityRecord r = (ActivityRecord)app.adjSource; 10574 if (r.app != null) currApp.importanceReasonPid = r.app.pid; 10575 } 10576 if (app.adjTarget instanceof ComponentName) { 10577 currApp.importanceReasonComponent = (ComponentName)app.adjTarget; 10578 } 10579 //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance 10580 // + " lru=" + currApp.lru); 10581 if (runList == null) { 10582 runList = new ArrayList<ActivityManager.RunningAppProcessInfo>(); 10583 } 10584 runList.add(currApp); 10585 } 10586 } 10587 } 10588 return runList; 10589 } 10590 10591 public List<ApplicationInfo> getRunningExternalApplications() { 10592 enforceNotIsolatedCaller("getRunningExternalApplications"); 10593 List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses(); 10594 List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>(); 10595 if (runningApps != null && runningApps.size() > 0) { 10596 Set<String> extList = new HashSet<String>(); 10597 for (ActivityManager.RunningAppProcessInfo app : runningApps) { 10598 if (app.pkgList != null) { 10599 for (String pkg : app.pkgList) { 10600 extList.add(pkg); 10601 } 10602 } 10603 } 10604 IPackageManager pm = AppGlobals.getPackageManager(); 10605 for (String pkg : extList) { 10606 try { 10607 ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId()); 10608 if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) { 10609 retList.add(info); 10610 } 10611 } catch (RemoteException e) { 10612 } 10613 } 10614 } 10615 return retList; 10616 } 10617 10618 @Override 10619 public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) { 10620 enforceNotIsolatedCaller("getMyMemoryState"); 10621 synchronized (this) { 10622 ProcessRecord proc; 10623 synchronized (mPidsSelfLocked) { 10624 proc = mPidsSelfLocked.get(Binder.getCallingPid()); 10625 } 10626 fillInProcMemInfo(proc, outInfo); 10627 } 10628 } 10629 10630 @Override 10631 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 10632 if (checkCallingPermission(android.Manifest.permission.DUMP) 10633 != PackageManager.PERMISSION_GRANTED) { 10634 pw.println("Permission Denial: can't dump ActivityManager from from pid=" 10635 + Binder.getCallingPid() 10636 + ", uid=" + Binder.getCallingUid() 10637 + " without permission " 10638 + android.Manifest.permission.DUMP); 10639 return; 10640 } 10641 10642 boolean dumpAll = false; 10643 boolean dumpClient = false; 10644 String dumpPackage = null; 10645 10646 int opti = 0; 10647 while (opti < args.length) { 10648 String opt = args[opti]; 10649 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 10650 break; 10651 } 10652 opti++; 10653 if ("-a".equals(opt)) { 10654 dumpAll = true; 10655 } else if ("-c".equals(opt)) { 10656 dumpClient = true; 10657 } else if ("-h".equals(opt)) { 10658 pw.println("Activity manager dump options:"); 10659 pw.println(" [-a] [-c] [-h] [cmd] ..."); 10660 pw.println(" cmd may be one of:"); 10661 pw.println(" a[ctivities]: activity stack state"); 10662 pw.println(" b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state"); 10663 pw.println(" i[ntents] [PACKAGE_NAME]: pending intent state"); 10664 pw.println(" p[rocesses] [PACKAGE_NAME]: process state"); 10665 pw.println(" o[om]: out of memory management"); 10666 pw.println(" prov[iders] [COMP_SPEC ...]: content provider state"); 10667 pw.println(" provider [COMP_SPEC]: provider client-side state"); 10668 pw.println(" s[ervices] [COMP_SPEC ...]: service state"); 10669 pw.println(" service [COMP_SPEC]: service client-side state"); 10670 pw.println(" package [PACKAGE_NAME]: all state related to given package"); 10671 pw.println(" all: dump all activities"); 10672 pw.println(" top: dump the top activity"); 10673 pw.println(" cmd may also be a COMP_SPEC to dump activities."); 10674 pw.println(" COMP_SPEC may be a component name (com.foo/.myApp),"); 10675 pw.println(" a partial substring in a component name, a"); 10676 pw.println(" hex object identifier."); 10677 pw.println(" -a: include all available server state."); 10678 pw.println(" -c: include client state."); 10679 return; 10680 } else { 10681 pw.println("Unknown argument: " + opt + "; use -h for help"); 10682 } 10683 } 10684 10685 long origId = Binder.clearCallingIdentity(); 10686 boolean more = false; 10687 // Is the caller requesting to dump a particular piece of data? 10688 if (opti < args.length) { 10689 String cmd = args[opti]; 10690 opti++; 10691 if ("activities".equals(cmd) || "a".equals(cmd)) { 10692 synchronized (this) { 10693 dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null); 10694 } 10695 } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) { 10696 String[] newArgs; 10697 String name; 10698 if (opti >= args.length) { 10699 name = null; 10700 newArgs = EMPTY_STRING_ARRAY; 10701 } else { 10702 name = args[opti]; 10703 opti++; 10704 newArgs = new String[args.length - opti]; 10705 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 10706 args.length - opti); 10707 } 10708 synchronized (this) { 10709 dumpBroadcastsLocked(fd, pw, args, opti, true, name); 10710 } 10711 } else if ("intents".equals(cmd) || "i".equals(cmd)) { 10712 String[] newArgs; 10713 String name; 10714 if (opti >= args.length) { 10715 name = null; 10716 newArgs = EMPTY_STRING_ARRAY; 10717 } else { 10718 name = args[opti]; 10719 opti++; 10720 newArgs = new String[args.length - opti]; 10721 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 10722 args.length - opti); 10723 } 10724 synchronized (this) { 10725 dumpPendingIntentsLocked(fd, pw, args, opti, true, name); 10726 } 10727 } else if ("processes".equals(cmd) || "p".equals(cmd)) { 10728 String[] newArgs; 10729 String name; 10730 if (opti >= args.length) { 10731 name = null; 10732 newArgs = EMPTY_STRING_ARRAY; 10733 } else { 10734 name = args[opti]; 10735 opti++; 10736 newArgs = new String[args.length - opti]; 10737 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 10738 args.length - opti); 10739 } 10740 synchronized (this) { 10741 dumpProcessesLocked(fd, pw, args, opti, true, name); 10742 } 10743 } else if ("oom".equals(cmd) || "o".equals(cmd)) { 10744 synchronized (this) { 10745 dumpOomLocked(fd, pw, args, opti, true); 10746 } 10747 } else if ("provider".equals(cmd)) { 10748 String[] newArgs; 10749 String name; 10750 if (opti >= args.length) { 10751 name = null; 10752 newArgs = EMPTY_STRING_ARRAY; 10753 } else { 10754 name = args[opti]; 10755 opti++; 10756 newArgs = new String[args.length - opti]; 10757 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti); 10758 } 10759 if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) { 10760 pw.println("No providers match: " + name); 10761 pw.println("Use -h for help."); 10762 } 10763 } else if ("providers".equals(cmd) || "prov".equals(cmd)) { 10764 synchronized (this) { 10765 dumpProvidersLocked(fd, pw, args, opti, true, null); 10766 } 10767 } else if ("service".equals(cmd)) { 10768 String[] newArgs; 10769 String name; 10770 if (opti >= args.length) { 10771 name = null; 10772 newArgs = EMPTY_STRING_ARRAY; 10773 } else { 10774 name = args[opti]; 10775 opti++; 10776 newArgs = new String[args.length - opti]; 10777 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 10778 args.length - opti); 10779 } 10780 if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) { 10781 pw.println("No services match: " + name); 10782 pw.println("Use -h for help."); 10783 } 10784 } else if ("package".equals(cmd)) { 10785 String[] newArgs; 10786 if (opti >= args.length) { 10787 pw.println("package: no package name specified"); 10788 pw.println("Use -h for help."); 10789 } else { 10790 dumpPackage = args[opti]; 10791 opti++; 10792 newArgs = new String[args.length - opti]; 10793 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 10794 args.length - opti); 10795 args = newArgs; 10796 opti = 0; 10797 more = true; 10798 } 10799 } else if ("services".equals(cmd) || "s".equals(cmd)) { 10800 synchronized (this) { 10801 mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null); 10802 } 10803 } else { 10804 // Dumping a single activity? 10805 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) { 10806 pw.println("Bad activity command, or no activities match: " + cmd); 10807 pw.println("Use -h for help."); 10808 } 10809 } 10810 if (!more) { 10811 Binder.restoreCallingIdentity(origId); 10812 return; 10813 } 10814 } 10815 10816 // No piece of data specified, dump everything. 10817 synchronized (this) { 10818 dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 10819 pw.println(); 10820 if (dumpAll) { 10821 pw.println("-------------------------------------------------------------------------------"); 10822 } 10823 dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 10824 pw.println(); 10825 if (dumpAll) { 10826 pw.println("-------------------------------------------------------------------------------"); 10827 } 10828 dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage); 10829 pw.println(); 10830 if (dumpAll) { 10831 pw.println("-------------------------------------------------------------------------------"); 10832 } 10833 mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 10834 pw.println(); 10835 if (dumpAll) { 10836 pw.println("-------------------------------------------------------------------------------"); 10837 } 10838 dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 10839 pw.println(); 10840 if (dumpAll) { 10841 pw.println("-------------------------------------------------------------------------------"); 10842 } 10843 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage); 10844 } 10845 Binder.restoreCallingIdentity(origId); 10846 } 10847 10848 void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 10849 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) { 10850 pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)"); 10851 10852 boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient, 10853 dumpPackage); 10854 boolean needSep = printedAnything; 10855 10856 boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity, 10857 dumpPackage, needSep, " mFocusedActivity: "); 10858 if (printed) { 10859 printedAnything = true; 10860 needSep = false; 10861 } 10862 10863 if (dumpPackage == null) { 10864 if (needSep) { 10865 pw.println(); 10866 } 10867 needSep = true; 10868 printedAnything = true; 10869 mStackSupervisor.dump(pw, " "); 10870 } 10871 10872 if (mRecentTasks.size() > 0) { 10873 boolean printedHeader = false; 10874 10875 final int N = mRecentTasks.size(); 10876 for (int i=0; i<N; i++) { 10877 TaskRecord tr = mRecentTasks.get(i); 10878 if (dumpPackage != null) { 10879 if (tr.realActivity == null || 10880 !dumpPackage.equals(tr.realActivity)) { 10881 continue; 10882 } 10883 } 10884 if (!printedHeader) { 10885 if (needSep) { 10886 pw.println(); 10887 } 10888 pw.println(" Recent tasks:"); 10889 printedHeader = true; 10890 printedAnything = true; 10891 } 10892 pw.print(" * Recent #"); pw.print(i); pw.print(": "); 10893 pw.println(tr); 10894 if (dumpAll) { 10895 mRecentTasks.get(i).dump(pw, " "); 10896 } 10897 } 10898 } 10899 10900 if (!printedAnything) { 10901 pw.println(" (nothing)"); 10902 } 10903 } 10904 10905 void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 10906 int opti, boolean dumpAll, String dumpPackage) { 10907 boolean needSep = false; 10908 boolean printedAnything = false; 10909 int numPers = 0; 10910 10911 pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)"); 10912 10913 if (dumpAll) { 10914 final int NP = mProcessNames.getMap().size(); 10915 for (int ip=0; ip<NP; ip++) { 10916 SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip); 10917 final int NA = procs.size(); 10918 for (int ia=0; ia<NA; ia++) { 10919 ProcessRecord r = procs.valueAt(ia); 10920 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 10921 continue; 10922 } 10923 if (!needSep) { 10924 pw.println(" All known processes:"); 10925 needSep = true; 10926 printedAnything = true; 10927 } 10928 pw.print(r.persistent ? " *PERS*" : " *APP*"); 10929 pw.print(" UID "); pw.print(procs.keyAt(ia)); 10930 pw.print(" "); pw.println(r); 10931 r.dump(pw, " "); 10932 if (r.persistent) { 10933 numPers++; 10934 } 10935 } 10936 } 10937 } 10938 10939 if (mIsolatedProcesses.size() > 0) { 10940 boolean printed = false; 10941 for (int i=0; i<mIsolatedProcesses.size(); i++) { 10942 ProcessRecord r = mIsolatedProcesses.valueAt(i); 10943 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 10944 continue; 10945 } 10946 if (!printed) { 10947 if (needSep) { 10948 pw.println(); 10949 } 10950 pw.println(" Isolated process list (sorted by uid):"); 10951 printedAnything = true; 10952 printed = true; 10953 needSep = true; 10954 } 10955 pw.println(String.format("%sIsolated #%2d: %s", 10956 " ", i, r.toString())); 10957 } 10958 } 10959 10960 if (mLruProcesses.size() > 0) { 10961 if (needSep) { 10962 pw.println(); 10963 } 10964 pw.print(" Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size()); 10965 pw.print(" total, non-act at "); 10966 pw.print(mLruProcesses.size()-mLruProcessActivityStart); 10967 pw.print(", non-svc at "); 10968 pw.print(mLruProcesses.size()-mLruProcessServiceStart); 10969 pw.println("):"); 10970 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", false, dumpPackage); 10971 needSep = true; 10972 printedAnything = true; 10973 } 10974 10975 if (dumpAll || dumpPackage != null) { 10976 synchronized (mPidsSelfLocked) { 10977 boolean printed = false; 10978 for (int i=0; i<mPidsSelfLocked.size(); i++) { 10979 ProcessRecord r = mPidsSelfLocked.valueAt(i); 10980 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 10981 continue; 10982 } 10983 if (!printed) { 10984 if (needSep) pw.println(); 10985 needSep = true; 10986 pw.println(" PID mappings:"); 10987 printed = true; 10988 printedAnything = true; 10989 } 10990 pw.print(" PID #"); pw.print(mPidsSelfLocked.keyAt(i)); 10991 pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i)); 10992 } 10993 } 10994 } 10995 10996 if (mForegroundProcesses.size() > 0) { 10997 synchronized (mPidsSelfLocked) { 10998 boolean printed = false; 10999 for (int i=0; i<mForegroundProcesses.size(); i++) { 11000 ProcessRecord r = mPidsSelfLocked.get( 11001 mForegroundProcesses.valueAt(i).pid); 11002 if (dumpPackage != null && (r == null 11003 || !r.pkgList.containsKey(dumpPackage))) { 11004 continue; 11005 } 11006 if (!printed) { 11007 if (needSep) pw.println(); 11008 needSep = true; 11009 pw.println(" Foreground Processes:"); 11010 printed = true; 11011 printedAnything = true; 11012 } 11013 pw.print(" PID #"); pw.print(mForegroundProcesses.keyAt(i)); 11014 pw.print(": "); pw.println(mForegroundProcesses.valueAt(i)); 11015 } 11016 } 11017 } 11018 11019 if (mPersistentStartingProcesses.size() > 0) { 11020 if (needSep) pw.println(); 11021 needSep = true; 11022 printedAnything = true; 11023 pw.println(" Persisent processes that are starting:"); 11024 dumpProcessList(pw, this, mPersistentStartingProcesses, " ", 11025 "Starting Norm", "Restarting PERS", dumpPackage); 11026 } 11027 11028 if (mRemovedProcesses.size() > 0) { 11029 if (needSep) pw.println(); 11030 needSep = true; 11031 printedAnything = true; 11032 pw.println(" Processes that are being removed:"); 11033 dumpProcessList(pw, this, mRemovedProcesses, " ", 11034 "Removed Norm", "Removed PERS", dumpPackage); 11035 } 11036 11037 if (mProcessesOnHold.size() > 0) { 11038 if (needSep) pw.println(); 11039 needSep = true; 11040 printedAnything = true; 11041 pw.println(" Processes that are on old until the system is ready:"); 11042 dumpProcessList(pw, this, mProcessesOnHold, " ", 11043 "OnHold Norm", "OnHold PERS", dumpPackage); 11044 } 11045 11046 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage); 11047 11048 if (mProcessCrashTimes.getMap().size() > 0) { 11049 boolean printed = false; 11050 long now = SystemClock.uptimeMillis(); 11051 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap(); 11052 final int NP = pmap.size(); 11053 for (int ip=0; ip<NP; ip++) { 11054 String pname = pmap.keyAt(ip); 11055 SparseArray<Long> uids = pmap.valueAt(ip); 11056 final int N = uids.size(); 11057 for (int i=0; i<N; i++) { 11058 int puid = uids.keyAt(i); 11059 ProcessRecord r = mProcessNames.get(pname, puid); 11060 if (dumpPackage != null && (r == null 11061 || !r.pkgList.containsKey(dumpPackage))) { 11062 continue; 11063 } 11064 if (!printed) { 11065 if (needSep) pw.println(); 11066 needSep = true; 11067 pw.println(" Time since processes crashed:"); 11068 printed = true; 11069 printedAnything = true; 11070 } 11071 pw.print(" Process "); pw.print(pname); 11072 pw.print(" uid "); pw.print(puid); 11073 pw.print(": last crashed "); 11074 TimeUtils.formatDuration(now-uids.valueAt(i), pw); 11075 pw.println(" ago"); 11076 } 11077 } 11078 } 11079 11080 if (mBadProcesses.getMap().size() > 0) { 11081 boolean printed = false; 11082 final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap(); 11083 final int NP = pmap.size(); 11084 for (int ip=0; ip<NP; ip++) { 11085 String pname = pmap.keyAt(ip); 11086 SparseArray<BadProcessInfo> uids = pmap.valueAt(ip); 11087 final int N = uids.size(); 11088 for (int i=0; i<N; i++) { 11089 int puid = uids.keyAt(i); 11090 ProcessRecord r = mProcessNames.get(pname, puid); 11091 if (dumpPackage != null && (r == null 11092 || !r.pkgList.containsKey(dumpPackage))) { 11093 continue; 11094 } 11095 if (!printed) { 11096 if (needSep) pw.println(); 11097 needSep = true; 11098 pw.println(" Bad processes:"); 11099 printedAnything = true; 11100 } 11101 BadProcessInfo info = uids.valueAt(i); 11102 pw.print(" Bad process "); pw.print(pname); 11103 pw.print(" uid "); pw.print(puid); 11104 pw.print(": crashed at time "); pw.println(info.time); 11105 if (info.shortMsg != null) { 11106 pw.print(" Short msg: "); pw.println(info.shortMsg); 11107 } 11108 if (info.longMsg != null) { 11109 pw.print(" Long msg: "); pw.println(info.longMsg); 11110 } 11111 if (info.stack != null) { 11112 pw.println(" Stack:"); 11113 int lastPos = 0; 11114 for (int pos=0; pos<info.stack.length(); pos++) { 11115 if (info.stack.charAt(pos) == '\n') { 11116 pw.print(" "); 11117 pw.write(info.stack, lastPos, pos-lastPos); 11118 pw.println(); 11119 lastPos = pos+1; 11120 } 11121 } 11122 if (lastPos < info.stack.length()) { 11123 pw.print(" "); 11124 pw.write(info.stack, lastPos, info.stack.length()-lastPos); 11125 pw.println(); 11126 } 11127 } 11128 } 11129 } 11130 } 11131 11132 if (dumpPackage == null) { 11133 pw.println(); 11134 needSep = false; 11135 pw.println(" mStartedUsers:"); 11136 for (int i=0; i<mStartedUsers.size(); i++) { 11137 UserStartedState uss = mStartedUsers.valueAt(i); 11138 pw.print(" User #"); pw.print(uss.mHandle.getIdentifier()); 11139 pw.print(": "); uss.dump("", pw); 11140 } 11141 pw.print(" mStartedUserArray: ["); 11142 for (int i=0; i<mStartedUserArray.length; i++) { 11143 if (i > 0) pw.print(", "); 11144 pw.print(mStartedUserArray[i]); 11145 } 11146 pw.println("]"); 11147 pw.print(" mUserLru: ["); 11148 for (int i=0; i<mUserLru.size(); i++) { 11149 if (i > 0) pw.print(", "); 11150 pw.print(mUserLru.get(i)); 11151 } 11152 pw.println("]"); 11153 if (dumpAll) { 11154 pw.print(" mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray)); 11155 } 11156 } 11157 if (mHomeProcess != null && (dumpPackage == null 11158 || mHomeProcess.pkgList.containsKey(dumpPackage))) { 11159 if (needSep) { 11160 pw.println(); 11161 needSep = false; 11162 } 11163 pw.println(" mHomeProcess: " + mHomeProcess); 11164 } 11165 if (mPreviousProcess != null && (dumpPackage == null 11166 || mPreviousProcess.pkgList.containsKey(dumpPackage))) { 11167 if (needSep) { 11168 pw.println(); 11169 needSep = false; 11170 } 11171 pw.println(" mPreviousProcess: " + mPreviousProcess); 11172 } 11173 if (dumpAll) { 11174 StringBuilder sb = new StringBuilder(128); 11175 sb.append(" mPreviousProcessVisibleTime: "); 11176 TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb); 11177 pw.println(sb); 11178 } 11179 if (mHeavyWeightProcess != null && (dumpPackage == null 11180 || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) { 11181 if (needSep) { 11182 pw.println(); 11183 needSep = false; 11184 } 11185 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 11186 } 11187 if (dumpPackage == null) { 11188 pw.println(" mConfiguration: " + mConfiguration); 11189 } 11190 if (dumpAll) { 11191 pw.println(" mConfigWillChange: " + getFocusedStack().mConfigWillChange); 11192 if (mCompatModePackages.getPackages().size() > 0) { 11193 boolean printed = false; 11194 for (Map.Entry<String, Integer> entry 11195 : mCompatModePackages.getPackages().entrySet()) { 11196 String pkg = entry.getKey(); 11197 int mode = entry.getValue(); 11198 if (dumpPackage != null && !dumpPackage.equals(pkg)) { 11199 continue; 11200 } 11201 if (!printed) { 11202 pw.println(" mScreenCompatPackages:"); 11203 printed = true; 11204 } 11205 pw.print(" "); pw.print(pkg); pw.print(": "); 11206 pw.print(mode); pw.println(); 11207 } 11208 } 11209 } 11210 if (dumpPackage == null) { 11211 if (mSleeping || mWentToSleep || mLockScreenShown) { 11212 pw.println(" mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep 11213 + " mLockScreenShown " + mLockScreenShown); 11214 } 11215 if (mShuttingDown || mRunningVoice) { 11216 pw.print(" mShuttingDown=" + mShuttingDown + " mRunningVoice=" + mRunningVoice); 11217 } 11218 } 11219 if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient 11220 || mOrigWaitForDebugger) { 11221 if (dumpPackage == null || dumpPackage.equals(mDebugApp) 11222 || dumpPackage.equals(mOrigDebugApp)) { 11223 if (needSep) { 11224 pw.println(); 11225 needSep = false; 11226 } 11227 pw.println(" mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp 11228 + " mDebugTransient=" + mDebugTransient 11229 + " mOrigWaitForDebugger=" + mOrigWaitForDebugger); 11230 } 11231 } 11232 if (mOpenGlTraceApp != null) { 11233 if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) { 11234 if (needSep) { 11235 pw.println(); 11236 needSep = false; 11237 } 11238 pw.println(" mOpenGlTraceApp=" + mOpenGlTraceApp); 11239 } 11240 } 11241 if (mProfileApp != null || mProfileProc != null || mProfileFile != null 11242 || mProfileFd != null) { 11243 if (dumpPackage == null || dumpPackage.equals(mProfileApp)) { 11244 if (needSep) { 11245 pw.println(); 11246 needSep = false; 11247 } 11248 pw.println(" mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc); 11249 pw.println(" mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd); 11250 pw.println(" mProfileType=" + mProfileType + " mAutoStopProfiler=" 11251 + mAutoStopProfiler); 11252 } 11253 } 11254 if (dumpPackage == null) { 11255 if (mAlwaysFinishActivities || mController != null) { 11256 pw.println(" mAlwaysFinishActivities=" + mAlwaysFinishActivities 11257 + " mController=" + mController); 11258 } 11259 if (dumpAll) { 11260 pw.println(" Total persistent processes: " + numPers); 11261 pw.println(" mProcessesReady=" + mProcessesReady 11262 + " mSystemReady=" + mSystemReady); 11263 pw.println(" mBooting=" + mBooting 11264 + " mBooted=" + mBooted 11265 + " mFactoryTest=" + mFactoryTest); 11266 pw.print(" mLastPowerCheckRealtime="); 11267 TimeUtils.formatDuration(mLastPowerCheckRealtime, pw); 11268 pw.println(""); 11269 pw.print(" mLastPowerCheckUptime="); 11270 TimeUtils.formatDuration(mLastPowerCheckUptime, pw); 11271 pw.println(""); 11272 pw.println(" mGoingToSleep=" + mStackSupervisor.mGoingToSleep); 11273 pw.println(" mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity); 11274 pw.println(" mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq); 11275 pw.println(" mNumNonCachedProcs=" + mNumNonCachedProcs 11276 + " (" + mLruProcesses.size() + " total)" 11277 + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs 11278 + " mNumServiceProcs=" + mNumServiceProcs 11279 + " mNewNumServiceProcs=" + mNewNumServiceProcs); 11280 pw.println(" mAllowLowerMemLevel=" + mAllowLowerMemLevel 11281 + " mLastMemoryLevel" + mLastMemoryLevel 11282 + " mLastNumProcesses" + mLastNumProcesses); 11283 long now = SystemClock.uptimeMillis(); 11284 pw.print(" mLastIdleTime="); 11285 TimeUtils.formatDuration(now, mLastIdleTime, pw); 11286 pw.print(" mLowRamSinceLastIdle="); 11287 TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw); 11288 pw.println(); 11289 } 11290 } 11291 11292 if (!printedAnything) { 11293 pw.println(" (nothing)"); 11294 } 11295 } 11296 11297 boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args, 11298 int opti, boolean needSep, boolean dumpAll, String dumpPackage) { 11299 if (mProcessesToGc.size() > 0) { 11300 boolean printed = false; 11301 long now = SystemClock.uptimeMillis(); 11302 for (int i=0; i<mProcessesToGc.size(); i++) { 11303 ProcessRecord proc = mProcessesToGc.get(i); 11304 if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) { 11305 continue; 11306 } 11307 if (!printed) { 11308 if (needSep) pw.println(); 11309 needSep = true; 11310 pw.println(" Processes that are waiting to GC:"); 11311 printed = true; 11312 } 11313 pw.print(" Process "); pw.println(proc); 11314 pw.print(" lowMem="); pw.print(proc.reportLowMemory); 11315 pw.print(", last gced="); 11316 pw.print(now-proc.lastRequestedGc); 11317 pw.print(" ms ago, last lowMem="); 11318 pw.print(now-proc.lastLowMemory); 11319 pw.println(" ms ago"); 11320 11321 } 11322 } 11323 return needSep; 11324 } 11325 11326 void printOomLevel(PrintWriter pw, String name, int adj) { 11327 pw.print(" "); 11328 if (adj >= 0) { 11329 pw.print(' '); 11330 if (adj < 10) pw.print(' '); 11331 } else { 11332 if (adj > -10) pw.print(' '); 11333 } 11334 pw.print(adj); 11335 pw.print(": "); 11336 pw.print(name); 11337 pw.print(" ("); 11338 pw.print(mProcessList.getMemLevel(adj)/1024); 11339 pw.println(" kB)"); 11340 } 11341 11342 boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args, 11343 int opti, boolean dumpAll) { 11344 boolean needSep = false; 11345 11346 if (mLruProcesses.size() > 0) { 11347 if (needSep) pw.println(); 11348 needSep = true; 11349 pw.println(" OOM levels:"); 11350 printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ); 11351 printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ); 11352 printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ); 11353 printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ); 11354 printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ); 11355 printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ); 11356 printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ); 11357 printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ); 11358 printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ); 11359 printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ); 11360 printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ); 11361 printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ); 11362 printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ); 11363 11364 if (needSep) pw.println(); 11365 pw.print(" Process OOM control ("); pw.print(mLruProcesses.size()); 11366 pw.print(" total, non-act at "); 11367 pw.print(mLruProcesses.size()-mLruProcessActivityStart); 11368 pw.print(", non-svc at "); 11369 pw.print(mLruProcesses.size()-mLruProcessServiceStart); 11370 pw.println("):"); 11371 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", true, null); 11372 needSep = true; 11373 } 11374 11375 dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null); 11376 11377 pw.println(); 11378 pw.println(" mHomeProcess: " + mHomeProcess); 11379 pw.println(" mPreviousProcess: " + mPreviousProcess); 11380 if (mHeavyWeightProcess != null) { 11381 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 11382 } 11383 11384 return true; 11385 } 11386 11387 /** 11388 * There are three ways to call this: 11389 * - no provider specified: dump all the providers 11390 * - a flattened component name that matched an existing provider was specified as the 11391 * first arg: dump that one provider 11392 * - the first arg isn't the flattened component name of an existing provider: 11393 * dump all providers whose component contains the first arg as a substring 11394 */ 11395 protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args, 11396 int opti, boolean dumpAll) { 11397 return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll); 11398 } 11399 11400 static class ItemMatcher { 11401 ArrayList<ComponentName> components; 11402 ArrayList<String> strings; 11403 ArrayList<Integer> objects; 11404 boolean all; 11405 11406 ItemMatcher() { 11407 all = true; 11408 } 11409 11410 void build(String name) { 11411 ComponentName componentName = ComponentName.unflattenFromString(name); 11412 if (componentName != null) { 11413 if (components == null) { 11414 components = new ArrayList<ComponentName>(); 11415 } 11416 components.add(componentName); 11417 all = false; 11418 } else { 11419 int objectId = 0; 11420 // Not a '/' separated full component name; maybe an object ID? 11421 try { 11422 objectId = Integer.parseInt(name, 16); 11423 if (objects == null) { 11424 objects = new ArrayList<Integer>(); 11425 } 11426 objects.add(objectId); 11427 all = false; 11428 } catch (RuntimeException e) { 11429 // Not an integer; just do string match. 11430 if (strings == null) { 11431 strings = new ArrayList<String>(); 11432 } 11433 strings.add(name); 11434 all = false; 11435 } 11436 } 11437 } 11438 11439 int build(String[] args, int opti) { 11440 for (; opti<args.length; opti++) { 11441 String name = args[opti]; 11442 if ("--".equals(name)) { 11443 return opti+1; 11444 } 11445 build(name); 11446 } 11447 return opti; 11448 } 11449 11450 boolean match(Object object, ComponentName comp) { 11451 if (all) { 11452 return true; 11453 } 11454 if (components != null) { 11455 for (int i=0; i<components.size(); i++) { 11456 if (components.get(i).equals(comp)) { 11457 return true; 11458 } 11459 } 11460 } 11461 if (objects != null) { 11462 for (int i=0; i<objects.size(); i++) { 11463 if (System.identityHashCode(object) == objects.get(i)) { 11464 return true; 11465 } 11466 } 11467 } 11468 if (strings != null) { 11469 String flat = comp.flattenToString(); 11470 for (int i=0; i<strings.size(); i++) { 11471 if (flat.contains(strings.get(i))) { 11472 return true; 11473 } 11474 } 11475 } 11476 return false; 11477 } 11478 } 11479 11480 /** 11481 * There are three things that cmd can be: 11482 * - a flattened component name that matches an existing activity 11483 * - the cmd arg isn't the flattened component name of an existing activity: 11484 * dump all activity whose component contains the cmd as a substring 11485 * - A hex number of the ActivityRecord object instance. 11486 */ 11487 protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args, 11488 int opti, boolean dumpAll) { 11489 ArrayList<ActivityRecord> activities; 11490 11491 synchronized (this) { 11492 activities = mStackSupervisor.getDumpActivitiesLocked(name); 11493 } 11494 11495 if (activities.size() <= 0) { 11496 return false; 11497 } 11498 11499 String[] newArgs = new String[args.length - opti]; 11500 System.arraycopy(args, opti, newArgs, 0, args.length - opti); 11501 11502 TaskRecord lastTask = null; 11503 boolean needSep = false; 11504 for (int i=activities.size()-1; i>=0; i--) { 11505 ActivityRecord r = activities.get(i); 11506 if (needSep) { 11507 pw.println(); 11508 } 11509 needSep = true; 11510 synchronized (this) { 11511 if (lastTask != r.task) { 11512 lastTask = r.task; 11513 pw.print("TASK "); pw.print(lastTask.affinity); 11514 pw.print(" id="); pw.println(lastTask.taskId); 11515 if (dumpAll) { 11516 lastTask.dump(pw, " "); 11517 } 11518 } 11519 } 11520 dumpActivity(" ", fd, pw, activities.get(i), newArgs, dumpAll); 11521 } 11522 return true; 11523 } 11524 11525 /** 11526 * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if 11527 * there is a thread associated with the activity. 11528 */ 11529 private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw, 11530 final ActivityRecord r, String[] args, boolean dumpAll) { 11531 String innerPrefix = prefix + " "; 11532 synchronized (this) { 11533 pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName); 11534 pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r))); 11535 pw.print(" pid="); 11536 if (r.app != null) pw.println(r.app.pid); 11537 else pw.println("(not running)"); 11538 if (dumpAll) { 11539 r.dump(pw, innerPrefix); 11540 } 11541 } 11542 if (r.app != null && r.app.thread != null) { 11543 // flush anything that is already in the PrintWriter since the thread is going 11544 // to write to the file descriptor directly 11545 pw.flush(); 11546 try { 11547 TransferPipe tp = new TransferPipe(); 11548 try { 11549 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(), 11550 r.appToken, innerPrefix, args); 11551 tp.go(fd); 11552 } finally { 11553 tp.kill(); 11554 } 11555 } catch (IOException e) { 11556 pw.println(innerPrefix + "Failure while dumping the activity: " + e); 11557 } catch (RemoteException e) { 11558 pw.println(innerPrefix + "Got a RemoteException while dumping the activity"); 11559 } 11560 } 11561 } 11562 11563 void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 11564 int opti, boolean dumpAll, String dumpPackage) { 11565 boolean needSep = false; 11566 boolean onlyHistory = false; 11567 boolean printedAnything = false; 11568 11569 if ("history".equals(dumpPackage)) { 11570 if (opti < args.length && "-s".equals(args[opti])) { 11571 dumpAll = false; 11572 } 11573 onlyHistory = true; 11574 dumpPackage = null; 11575 } 11576 11577 pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)"); 11578 if (!onlyHistory && dumpAll) { 11579 if (mRegisteredReceivers.size() > 0) { 11580 boolean printed = false; 11581 Iterator it = mRegisteredReceivers.values().iterator(); 11582 while (it.hasNext()) { 11583 ReceiverList r = (ReceiverList)it.next(); 11584 if (dumpPackage != null && (r.app == null || 11585 !dumpPackage.equals(r.app.info.packageName))) { 11586 continue; 11587 } 11588 if (!printed) { 11589 pw.println(" Registered Receivers:"); 11590 needSep = true; 11591 printed = true; 11592 printedAnything = true; 11593 } 11594 pw.print(" * "); pw.println(r); 11595 r.dump(pw, " "); 11596 } 11597 } 11598 11599 if (mReceiverResolver.dump(pw, needSep ? 11600 "\n Receiver Resolver Table:" : " Receiver Resolver Table:", 11601 " ", dumpPackage, false)) { 11602 needSep = true; 11603 printedAnything = true; 11604 } 11605 } 11606 11607 for (BroadcastQueue q : mBroadcastQueues) { 11608 needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep); 11609 printedAnything |= needSep; 11610 } 11611 11612 needSep = true; 11613 11614 if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) { 11615 for (int user=0; user<mStickyBroadcasts.size(); user++) { 11616 if (needSep) { 11617 pw.println(); 11618 } 11619 needSep = true; 11620 printedAnything = true; 11621 pw.print(" Sticky broadcasts for user "); 11622 pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":"); 11623 StringBuilder sb = new StringBuilder(128); 11624 for (Map.Entry<String, ArrayList<Intent>> ent 11625 : mStickyBroadcasts.valueAt(user).entrySet()) { 11626 pw.print(" * Sticky action "); pw.print(ent.getKey()); 11627 if (dumpAll) { 11628 pw.println(":"); 11629 ArrayList<Intent> intents = ent.getValue(); 11630 final int N = intents.size(); 11631 for (int i=0; i<N; i++) { 11632 sb.setLength(0); 11633 sb.append(" Intent: "); 11634 intents.get(i).toShortString(sb, false, true, false, false); 11635 pw.println(sb.toString()); 11636 Bundle bundle = intents.get(i).getExtras(); 11637 if (bundle != null) { 11638 pw.print(" "); 11639 pw.println(bundle.toString()); 11640 } 11641 } 11642 } else { 11643 pw.println(""); 11644 } 11645 } 11646 } 11647 } 11648 11649 if (!onlyHistory && dumpAll) { 11650 pw.println(); 11651 for (BroadcastQueue queue : mBroadcastQueues) { 11652 pw.println(" mBroadcastsScheduled [" + queue.mQueueName + "]=" 11653 + queue.mBroadcastsScheduled); 11654 } 11655 pw.println(" mHandler:"); 11656 mHandler.dump(new PrintWriterPrinter(pw), " "); 11657 needSep = true; 11658 printedAnything = true; 11659 } 11660 11661 if (!printedAnything) { 11662 pw.println(" (nothing)"); 11663 } 11664 } 11665 11666 void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args, 11667 int opti, boolean dumpAll, String dumpPackage) { 11668 boolean needSep; 11669 boolean printedAnything = false; 11670 11671 ItemMatcher matcher = new ItemMatcher(); 11672 matcher.build(args, opti); 11673 11674 pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)"); 11675 11676 needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage); 11677 printedAnything |= needSep; 11678 11679 if (mLaunchingProviders.size() > 0) { 11680 boolean printed = false; 11681 for (int i=mLaunchingProviders.size()-1; i>=0; i--) { 11682 ContentProviderRecord r = mLaunchingProviders.get(i); 11683 if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) { 11684 continue; 11685 } 11686 if (!printed) { 11687 if (needSep) pw.println(); 11688 needSep = true; 11689 pw.println(" Launching content providers:"); 11690 printed = true; 11691 printedAnything = true; 11692 } 11693 pw.print(" Launching #"); pw.print(i); pw.print(": "); 11694 pw.println(r); 11695 } 11696 } 11697 11698 if (mGrantedUriPermissions.size() > 0) { 11699 boolean printed = false; 11700 int dumpUid = -2; 11701 if (dumpPackage != null) { 11702 try { 11703 dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0); 11704 } catch (NameNotFoundException e) { 11705 dumpUid = -1; 11706 } 11707 } 11708 for (int i=0; i<mGrantedUriPermissions.size(); i++) { 11709 int uid = mGrantedUriPermissions.keyAt(i); 11710 if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) { 11711 continue; 11712 } 11713 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 11714 if (!printed) { 11715 if (needSep) pw.println(); 11716 needSep = true; 11717 pw.println(" Granted Uri Permissions:"); 11718 printed = true; 11719 printedAnything = true; 11720 } 11721 pw.print(" * UID "); pw.print(uid); pw.println(" holds:"); 11722 for (UriPermission perm : perms.values()) { 11723 pw.print(" "); pw.println(perm); 11724 if (dumpAll) { 11725 perm.dump(pw, " "); 11726 } 11727 } 11728 } 11729 } 11730 11731 if (!printedAnything) { 11732 pw.println(" (nothing)"); 11733 } 11734 } 11735 11736 void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 11737 int opti, boolean dumpAll, String dumpPackage) { 11738 boolean printed = false; 11739 11740 pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)"); 11741 11742 if (mIntentSenderRecords.size() > 0) { 11743 Iterator<WeakReference<PendingIntentRecord>> it 11744 = mIntentSenderRecords.values().iterator(); 11745 while (it.hasNext()) { 11746 WeakReference<PendingIntentRecord> ref = it.next(); 11747 PendingIntentRecord rec = ref != null ? ref.get(): null; 11748 if (dumpPackage != null && (rec == null 11749 || !dumpPackage.equals(rec.key.packageName))) { 11750 continue; 11751 } 11752 printed = true; 11753 if (rec != null) { 11754 pw.print(" * "); pw.println(rec); 11755 if (dumpAll) { 11756 rec.dump(pw, " "); 11757 } 11758 } else { 11759 pw.print(" * "); pw.println(ref); 11760 } 11761 } 11762 } 11763 11764 if (!printed) { 11765 pw.println(" (nothing)"); 11766 } 11767 } 11768 11769 private static final int dumpProcessList(PrintWriter pw, 11770 ActivityManagerService service, List list, 11771 String prefix, String normalLabel, String persistentLabel, 11772 String dumpPackage) { 11773 int numPers = 0; 11774 final int N = list.size()-1; 11775 for (int i=N; i>=0; i--) { 11776 ProcessRecord r = (ProcessRecord)list.get(i); 11777 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 11778 continue; 11779 } 11780 pw.println(String.format("%s%s #%2d: %s", 11781 prefix, (r.persistent ? persistentLabel : normalLabel), 11782 i, r.toString())); 11783 if (r.persistent) { 11784 numPers++; 11785 } 11786 } 11787 return numPers; 11788 } 11789 11790 private static final boolean dumpProcessOomList(PrintWriter pw, 11791 ActivityManagerService service, List<ProcessRecord> origList, 11792 String prefix, String normalLabel, String persistentLabel, 11793 boolean inclDetails, String dumpPackage) { 11794 11795 ArrayList<Pair<ProcessRecord, Integer>> list 11796 = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size()); 11797 for (int i=0; i<origList.size(); i++) { 11798 ProcessRecord r = origList.get(i); 11799 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 11800 continue; 11801 } 11802 list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i)); 11803 } 11804 11805 if (list.size() <= 0) { 11806 return false; 11807 } 11808 11809 Comparator<Pair<ProcessRecord, Integer>> comparator 11810 = new Comparator<Pair<ProcessRecord, Integer>>() { 11811 @Override 11812 public int compare(Pair<ProcessRecord, Integer> object1, 11813 Pair<ProcessRecord, Integer> object2) { 11814 if (object1.first.setAdj != object2.first.setAdj) { 11815 return object1.first.setAdj > object2.first.setAdj ? -1 : 1; 11816 } 11817 if (object1.second.intValue() != object2.second.intValue()) { 11818 return object1.second.intValue() > object2.second.intValue() ? -1 : 1; 11819 } 11820 return 0; 11821 } 11822 }; 11823 11824 Collections.sort(list, comparator); 11825 11826 final long curRealtime = SystemClock.elapsedRealtime(); 11827 final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime; 11828 final long curUptime = SystemClock.uptimeMillis(); 11829 final long uptimeSince = curUptime - service.mLastPowerCheckUptime; 11830 11831 for (int i=list.size()-1; i>=0; i--) { 11832 ProcessRecord r = list.get(i).first; 11833 String oomAdj = ProcessList.makeOomAdjString(r.setAdj); 11834 char schedGroup; 11835 switch (r.setSchedGroup) { 11836 case Process.THREAD_GROUP_BG_NONINTERACTIVE: 11837 schedGroup = 'B'; 11838 break; 11839 case Process.THREAD_GROUP_DEFAULT: 11840 schedGroup = 'F'; 11841 break; 11842 default: 11843 schedGroup = '?'; 11844 break; 11845 } 11846 char foreground; 11847 if (r.foregroundActivities) { 11848 foreground = 'A'; 11849 } else if (r.foregroundServices) { 11850 foreground = 'S'; 11851 } else { 11852 foreground = ' '; 11853 } 11854 String procState = ProcessList.makeProcStateString(r.curProcState); 11855 pw.print(prefix); 11856 pw.print(r.persistent ? persistentLabel : normalLabel); 11857 pw.print(" #"); 11858 int num = (origList.size()-1)-list.get(i).second; 11859 if (num < 10) pw.print(' '); 11860 pw.print(num); 11861 pw.print(": "); 11862 pw.print(oomAdj); 11863 pw.print(' '); 11864 pw.print(schedGroup); 11865 pw.print('/'); 11866 pw.print(foreground); 11867 pw.print('/'); 11868 pw.print(procState); 11869 pw.print(" trm:"); 11870 if (r.trimMemoryLevel < 10) pw.print(' '); 11871 pw.print(r.trimMemoryLevel); 11872 pw.print(' '); 11873 pw.print(r.toShortString()); 11874 pw.print(" ("); 11875 pw.print(r.adjType); 11876 pw.println(')'); 11877 if (r.adjSource != null || r.adjTarget != null) { 11878 pw.print(prefix); 11879 pw.print(" "); 11880 if (r.adjTarget instanceof ComponentName) { 11881 pw.print(((ComponentName)r.adjTarget).flattenToShortString()); 11882 } else if (r.adjTarget != null) { 11883 pw.print(r.adjTarget.toString()); 11884 } else { 11885 pw.print("{null}"); 11886 } 11887 pw.print("<="); 11888 if (r.adjSource instanceof ProcessRecord) { 11889 pw.print("Proc{"); 11890 pw.print(((ProcessRecord)r.adjSource).toShortString()); 11891 pw.println("}"); 11892 } else if (r.adjSource != null) { 11893 pw.println(r.adjSource.toString()); 11894 } else { 11895 pw.println("{null}"); 11896 } 11897 } 11898 if (inclDetails) { 11899 pw.print(prefix); 11900 pw.print(" "); 11901 pw.print("oom: max="); pw.print(r.maxAdj); 11902 pw.print(" curRaw="); pw.print(r.curRawAdj); 11903 pw.print(" setRaw="); pw.print(r.setRawAdj); 11904 pw.print(" cur="); pw.print(r.curAdj); 11905 pw.print(" set="); pw.println(r.setAdj); 11906 pw.print(prefix); 11907 pw.print(" "); 11908 pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState)); 11909 pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState)); 11910 pw.print(" lastPss="); pw.print(r.lastPss); 11911 pw.print(" lastCachedPss="); pw.println(r.lastCachedPss); 11912 pw.print(prefix); 11913 pw.print(" "); 11914 pw.print("keeping="); pw.print(r.keeping); 11915 pw.print(" cached="); pw.print(r.cached); 11916 pw.print(" empty="); pw.print(r.empty); 11917 pw.print(" hasAboveClient="); pw.println(r.hasAboveClient); 11918 11919 if (!r.keeping) { 11920 if (r.lastWakeTime != 0) { 11921 long wtime; 11922 BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics(); 11923 synchronized (stats) { 11924 wtime = stats.getProcessWakeTime(r.info.uid, 11925 r.pid, curRealtime); 11926 } 11927 long timeUsed = wtime - r.lastWakeTime; 11928 pw.print(prefix); 11929 pw.print(" "); 11930 pw.print("keep awake over "); 11931 TimeUtils.formatDuration(realtimeSince, pw); 11932 pw.print(" used "); 11933 TimeUtils.formatDuration(timeUsed, pw); 11934 pw.print(" ("); 11935 pw.print((timeUsed*100)/realtimeSince); 11936 pw.println("%)"); 11937 } 11938 if (r.lastCpuTime != 0) { 11939 long timeUsed = r.curCpuTime - r.lastCpuTime; 11940 pw.print(prefix); 11941 pw.print(" "); 11942 pw.print("run cpu over "); 11943 TimeUtils.formatDuration(uptimeSince, pw); 11944 pw.print(" used "); 11945 TimeUtils.formatDuration(timeUsed, pw); 11946 pw.print(" ("); 11947 pw.print((timeUsed*100)/uptimeSince); 11948 pw.println("%)"); 11949 } 11950 } 11951 } 11952 } 11953 return true; 11954 } 11955 11956 ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) { 11957 ArrayList<ProcessRecord> procs; 11958 synchronized (this) { 11959 if (args != null && args.length > start 11960 && args[start].charAt(0) != '-') { 11961 procs = new ArrayList<ProcessRecord>(); 11962 int pid = -1; 11963 try { 11964 pid = Integer.parseInt(args[start]); 11965 } catch (NumberFormatException e) { 11966 } 11967 for (int i=mLruProcesses.size()-1; i>=0; i--) { 11968 ProcessRecord proc = mLruProcesses.get(i); 11969 if (proc.pid == pid) { 11970 procs.add(proc); 11971 } else if (proc.processName.equals(args[start])) { 11972 procs.add(proc); 11973 } 11974 } 11975 if (procs.size() <= 0) { 11976 return null; 11977 } 11978 } else { 11979 procs = new ArrayList<ProcessRecord>(mLruProcesses); 11980 } 11981 } 11982 return procs; 11983 } 11984 11985 final void dumpGraphicsHardwareUsage(FileDescriptor fd, 11986 PrintWriter pw, String[] args) { 11987 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args); 11988 if (procs == null) { 11989 pw.println("No process found for: " + args[0]); 11990 return; 11991 } 11992 11993 long uptime = SystemClock.uptimeMillis(); 11994 long realtime = SystemClock.elapsedRealtime(); 11995 pw.println("Applications Graphics Acceleration Info:"); 11996 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 11997 11998 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 11999 ProcessRecord r = procs.get(i); 12000 if (r.thread != null) { 12001 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **"); 12002 pw.flush(); 12003 try { 12004 TransferPipe tp = new TransferPipe(); 12005 try { 12006 r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args); 12007 tp.go(fd); 12008 } finally { 12009 tp.kill(); 12010 } 12011 } catch (IOException e) { 12012 pw.println("Failure while dumping the app: " + r); 12013 pw.flush(); 12014 } catch (RemoteException e) { 12015 pw.println("Got a RemoteException while dumping the app " + r); 12016 pw.flush(); 12017 } 12018 } 12019 } 12020 } 12021 12022 final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) { 12023 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args); 12024 if (procs == null) { 12025 pw.println("No process found for: " + args[0]); 12026 return; 12027 } 12028 12029 pw.println("Applications Database Info:"); 12030 12031 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 12032 ProcessRecord r = procs.get(i); 12033 if (r.thread != null) { 12034 pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **"); 12035 pw.flush(); 12036 try { 12037 TransferPipe tp = new TransferPipe(); 12038 try { 12039 r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args); 12040 tp.go(fd); 12041 } finally { 12042 tp.kill(); 12043 } 12044 } catch (IOException e) { 12045 pw.println("Failure while dumping the app: " + r); 12046 pw.flush(); 12047 } catch (RemoteException e) { 12048 pw.println("Got a RemoteException while dumping the app " + r); 12049 pw.flush(); 12050 } 12051 } 12052 } 12053 } 12054 12055 final static class MemItem { 12056 final boolean isProc; 12057 final String label; 12058 final String shortLabel; 12059 final long pss; 12060 final int id; 12061 final boolean hasActivities; 12062 ArrayList<MemItem> subitems; 12063 12064 public MemItem(String _label, String _shortLabel, long _pss, int _id, 12065 boolean _hasActivities) { 12066 isProc = true; 12067 label = _label; 12068 shortLabel = _shortLabel; 12069 pss = _pss; 12070 id = _id; 12071 hasActivities = _hasActivities; 12072 } 12073 12074 public MemItem(String _label, String _shortLabel, long _pss, int _id) { 12075 isProc = false; 12076 label = _label; 12077 shortLabel = _shortLabel; 12078 pss = _pss; 12079 id = _id; 12080 hasActivities = false; 12081 } 12082 } 12083 12084 static final void dumpMemItems(PrintWriter pw, String prefix, String tag, 12085 ArrayList<MemItem> items, boolean sort, boolean isCompact) { 12086 if (sort && !isCompact) { 12087 Collections.sort(items, new Comparator<MemItem>() { 12088 @Override 12089 public int compare(MemItem lhs, MemItem rhs) { 12090 if (lhs.pss < rhs.pss) { 12091 return 1; 12092 } else if (lhs.pss > rhs.pss) { 12093 return -1; 12094 } 12095 return 0; 12096 } 12097 }); 12098 } 12099 12100 for (int i=0; i<items.size(); i++) { 12101 MemItem mi = items.get(i); 12102 if (!isCompact) { 12103 pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label); 12104 } else if (mi.isProc) { 12105 pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel); 12106 pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss); 12107 pw.println(mi.hasActivities ? ",a" : ",e"); 12108 } else { 12109 pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(","); 12110 pw.println(mi.pss); 12111 } 12112 if (mi.subitems != null) { 12113 dumpMemItems(pw, prefix + " ", mi.shortLabel, mi.subitems, 12114 true, isCompact); 12115 } 12116 } 12117 } 12118 12119 // These are in KB. 12120 static final long[] DUMP_MEM_BUCKETS = new long[] { 12121 5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024, 12122 120*1024, 160*1024, 200*1024, 12123 250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024, 12124 1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024 12125 }; 12126 12127 static final void appendMemBucket(StringBuilder out, long memKB, String label, 12128 boolean stackLike) { 12129 int start = label.lastIndexOf('.'); 12130 if (start >= 0) start++; 12131 else start = 0; 12132 int end = label.length(); 12133 for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) { 12134 if (DUMP_MEM_BUCKETS[i] >= memKB) { 12135 long bucket = DUMP_MEM_BUCKETS[i]/1024; 12136 out.append(bucket); 12137 out.append(stackLike ? "MB." : "MB "); 12138 out.append(label, start, end); 12139 return; 12140 } 12141 } 12142 out.append(memKB/1024); 12143 out.append(stackLike ? "MB." : "MB "); 12144 out.append(label, start, end); 12145 } 12146 12147 static final int[] DUMP_MEM_OOM_ADJ = new int[] { 12148 ProcessList.NATIVE_ADJ, 12149 ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ, 12150 ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ, 12151 ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ, 12152 ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ, 12153 ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ 12154 }; 12155 static final String[] DUMP_MEM_OOM_LABEL = new String[] { 12156 "Native", 12157 "System", "Persistent", "Foreground", 12158 "Visible", "Perceptible", 12159 "Heavy Weight", "Backup", 12160 "A Services", "Home", 12161 "Previous", "B Services", "Cached" 12162 }; 12163 static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] { 12164 "native", 12165 "sys", "pers", "fore", 12166 "vis", "percept", 12167 "heavy", "backup", 12168 "servicea", "home", 12169 "prev", "serviceb", "cached" 12170 }; 12171 12172 private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime, 12173 long realtime, boolean isCheckinRequest, boolean isCompact) { 12174 if (isCheckinRequest || isCompact) { 12175 // short checkin version 12176 pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime); 12177 } else { 12178 pw.println("Applications Memory Usage (kB):"); 12179 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 12180 } 12181 } 12182 12183 final void dumpApplicationMemoryUsage(FileDescriptor fd, 12184 PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) { 12185 boolean dumpDetails = false; 12186 boolean dumpFullDetails = false; 12187 boolean dumpDalvik = false; 12188 boolean oomOnly = false; 12189 boolean isCompact = false; 12190 boolean localOnly = false; 12191 12192 int opti = 0; 12193 while (opti < args.length) { 12194 String opt = args[opti]; 12195 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 12196 break; 12197 } 12198 opti++; 12199 if ("-a".equals(opt)) { 12200 dumpDetails = true; 12201 dumpFullDetails = true; 12202 dumpDalvik = true; 12203 } else if ("-d".equals(opt)) { 12204 dumpDalvik = true; 12205 } else if ("-c".equals(opt)) { 12206 isCompact = true; 12207 } else if ("--oom".equals(opt)) { 12208 oomOnly = true; 12209 } else if ("--local".equals(opt)) { 12210 localOnly = true; 12211 } else if ("-h".equals(opt)) { 12212 pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]"); 12213 pw.println(" -a: include all available information for each process."); 12214 pw.println(" -d: include dalvik details when dumping process details."); 12215 pw.println(" -c: dump in a compact machine-parseable representation."); 12216 pw.println(" --oom: only show processes organized by oom adj."); 12217 pw.println(" --local: only collect details locally, don't call process."); 12218 pw.println("If [process] is specified it can be the name or "); 12219 pw.println("pid of a specific process to dump."); 12220 return; 12221 } else { 12222 pw.println("Unknown argument: " + opt + "; use -h for help"); 12223 } 12224 } 12225 12226 final boolean isCheckinRequest = scanArgs(args, "--checkin"); 12227 long uptime = SystemClock.uptimeMillis(); 12228 long realtime = SystemClock.elapsedRealtime(); 12229 final long[] tmpLong = new long[1]; 12230 12231 ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args); 12232 if (procs == null) { 12233 // No Java processes. Maybe they want to print a native process. 12234 if (args != null && args.length > opti 12235 && args[opti].charAt(0) != '-') { 12236 ArrayList<ProcessCpuTracker.Stats> nativeProcs 12237 = new ArrayList<ProcessCpuTracker.Stats>(); 12238 updateCpuStatsNow(); 12239 int findPid = -1; 12240 try { 12241 findPid = Integer.parseInt(args[opti]); 12242 } catch (NumberFormatException e) { 12243 } 12244 synchronized (mProcessCpuThread) { 12245 final int N = mProcessCpuTracker.countStats(); 12246 for (int i=0; i<N; i++) { 12247 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 12248 if (st.pid == findPid || (st.baseName != null 12249 && st.baseName.equals(args[opti]))) { 12250 nativeProcs.add(st); 12251 } 12252 } 12253 } 12254 if (nativeProcs.size() > 0) { 12255 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, 12256 isCompact); 12257 Debug.MemoryInfo mi = null; 12258 for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) { 12259 final ProcessCpuTracker.Stats r = nativeProcs.get(i); 12260 final int pid = r.pid; 12261 if (!isCheckinRequest && dumpDetails) { 12262 pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **"); 12263 } 12264 if (mi == null) { 12265 mi = new Debug.MemoryInfo(); 12266 } 12267 if (dumpDetails || (!brief && !oomOnly)) { 12268 Debug.getMemoryInfo(pid, mi); 12269 } else { 12270 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong); 12271 mi.dalvikPrivateDirty = (int)tmpLong[0]; 12272 } 12273 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails, 12274 dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0); 12275 if (isCheckinRequest) { 12276 pw.println(); 12277 } 12278 } 12279 return; 12280 } 12281 } 12282 pw.println("No process found for: " + args[opti]); 12283 return; 12284 } 12285 12286 if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest)) { 12287 dumpDetails = true; 12288 } 12289 12290 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact); 12291 12292 String[] innerArgs = new String[args.length-opti]; 12293 System.arraycopy(args, opti, innerArgs, 0, args.length-opti); 12294 12295 ArrayList<MemItem> procMems = new ArrayList<MemItem>(); 12296 final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>(); 12297 long nativePss=0, dalvikPss=0, otherPss=0; 12298 long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS]; 12299 12300 long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length]; 12301 ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[]) 12302 new ArrayList[DUMP_MEM_OOM_LABEL.length]; 12303 12304 long totalPss = 0; 12305 long cachedPss = 0; 12306 12307 Debug.MemoryInfo mi = null; 12308 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 12309 final ProcessRecord r = procs.get(i); 12310 final IApplicationThread thread; 12311 final int pid; 12312 final int oomAdj; 12313 final boolean hasActivities; 12314 synchronized (this) { 12315 thread = r.thread; 12316 pid = r.pid; 12317 oomAdj = r.getSetAdjWithServices(); 12318 hasActivities = r.activities.size() > 0; 12319 } 12320 if (thread != null) { 12321 if (!isCheckinRequest && dumpDetails) { 12322 pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **"); 12323 } 12324 if (mi == null) { 12325 mi = new Debug.MemoryInfo(); 12326 } 12327 if (dumpDetails || (!brief && !oomOnly)) { 12328 Debug.getMemoryInfo(pid, mi); 12329 } else { 12330 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong); 12331 mi.dalvikPrivateDirty = (int)tmpLong[0]; 12332 } 12333 if (dumpDetails) { 12334 if (localOnly) { 12335 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails, 12336 dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0); 12337 if (isCheckinRequest) { 12338 pw.println(); 12339 } 12340 } else { 12341 try { 12342 pw.flush(); 12343 thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails, 12344 dumpDalvik, innerArgs); 12345 } catch (RemoteException e) { 12346 if (!isCheckinRequest) { 12347 pw.println("Got RemoteException!"); 12348 pw.flush(); 12349 } 12350 } 12351 } 12352 } 12353 12354 final long myTotalPss = mi.getTotalPss(); 12355 final long myTotalUss = mi.getTotalUss(); 12356 12357 synchronized (this) { 12358 if (r.thread != null && oomAdj == r.getSetAdjWithServices()) { 12359 // Record this for posterity if the process has been stable. 12360 r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList); 12361 } 12362 } 12363 12364 if (!isCheckinRequest && mi != null) { 12365 totalPss += myTotalPss; 12366 MemItem pssItem = new MemItem(r.processName + " (pid " + pid + 12367 (hasActivities ? " / activities)" : ")"), 12368 r.processName, myTotalPss, pid, hasActivities); 12369 procMems.add(pssItem); 12370 procMemsMap.put(pid, pssItem); 12371 12372 nativePss += mi.nativePss; 12373 dalvikPss += mi.dalvikPss; 12374 otherPss += mi.otherPss; 12375 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 12376 long mem = mi.getOtherPss(j); 12377 miscPss[j] += mem; 12378 otherPss -= mem; 12379 } 12380 12381 if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 12382 cachedPss += myTotalPss; 12383 } 12384 12385 for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) { 12386 if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex] 12387 || oomIndex == (oomPss.length-1)) { 12388 oomPss[oomIndex] += myTotalPss; 12389 if (oomProcs[oomIndex] == null) { 12390 oomProcs[oomIndex] = new ArrayList<MemItem>(); 12391 } 12392 oomProcs[oomIndex].add(pssItem); 12393 break; 12394 } 12395 } 12396 } 12397 } 12398 } 12399 12400 if (!isCheckinRequest && procs.size() > 1) { 12401 // If we are showing aggregations, also look for native processes to 12402 // include so that our aggregations are more accurate. 12403 updateCpuStatsNow(); 12404 synchronized (mProcessCpuThread) { 12405 final int N = mProcessCpuTracker.countStats(); 12406 for (int i=0; i<N; i++) { 12407 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 12408 if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) { 12409 if (mi == null) { 12410 mi = new Debug.MemoryInfo(); 12411 } 12412 if (!brief && !oomOnly) { 12413 Debug.getMemoryInfo(st.pid, mi); 12414 } else { 12415 mi.nativePss = (int)Debug.getPss(st.pid, tmpLong); 12416 mi.nativePrivateDirty = (int)tmpLong[0]; 12417 } 12418 12419 final long myTotalPss = mi.getTotalPss(); 12420 totalPss += myTotalPss; 12421 12422 MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")", 12423 st.name, myTotalPss, st.pid, false); 12424 procMems.add(pssItem); 12425 12426 nativePss += mi.nativePss; 12427 dalvikPss += mi.dalvikPss; 12428 otherPss += mi.otherPss; 12429 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 12430 long mem = mi.getOtherPss(j); 12431 miscPss[j] += mem; 12432 otherPss -= mem; 12433 } 12434 oomPss[0] += myTotalPss; 12435 if (oomProcs[0] == null) { 12436 oomProcs[0] = new ArrayList<MemItem>(); 12437 } 12438 oomProcs[0].add(pssItem); 12439 } 12440 } 12441 } 12442 12443 ArrayList<MemItem> catMems = new ArrayList<MemItem>(); 12444 12445 catMems.add(new MemItem("Native", "Native", nativePss, -1)); 12446 catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2)); 12447 catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3)); 12448 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 12449 String label = Debug.MemoryInfo.getOtherLabel(j); 12450 catMems.add(new MemItem(label, label, miscPss[j], j)); 12451 } 12452 12453 ArrayList<MemItem> oomMems = new ArrayList<MemItem>(); 12454 for (int j=0; j<oomPss.length; j++) { 12455 if (oomPss[j] != 0) { 12456 String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j] 12457 : DUMP_MEM_OOM_LABEL[j]; 12458 MemItem item = new MemItem(label, label, oomPss[j], 12459 DUMP_MEM_OOM_ADJ[j]); 12460 item.subitems = oomProcs[j]; 12461 oomMems.add(item); 12462 } 12463 } 12464 12465 if (!brief && !oomOnly && !isCompact) { 12466 pw.println(); 12467 pw.println("Total PSS by process:"); 12468 dumpMemItems(pw, " ", "proc", procMems, true, isCompact); 12469 pw.println(); 12470 } 12471 if (!isCompact) { 12472 pw.println("Total PSS by OOM adjustment:"); 12473 } 12474 dumpMemItems(pw, " ", "oom", oomMems, false, isCompact); 12475 if (!brief && !oomOnly) { 12476 PrintWriter out = categoryPw != null ? categoryPw : pw; 12477 if (!isCompact) { 12478 out.println(); 12479 out.println("Total PSS by category:"); 12480 } 12481 dumpMemItems(out, " ", "cat", catMems, true, isCompact); 12482 } 12483 if (!isCompact) { 12484 pw.println(); 12485 } 12486 MemInfoReader memInfo = new MemInfoReader(); 12487 memInfo.readMemInfo(); 12488 if (!brief) { 12489 if (!isCompact) { 12490 pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb()); 12491 pw.print(" kB (status "); 12492 switch (mLastMemoryLevel) { 12493 case ProcessStats.ADJ_MEM_FACTOR_NORMAL: 12494 pw.println("normal)"); 12495 break; 12496 case ProcessStats.ADJ_MEM_FACTOR_MODERATE: 12497 pw.println("moderate)"); 12498 break; 12499 case ProcessStats.ADJ_MEM_FACTOR_LOW: 12500 pw.println("low)"); 12501 break; 12502 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL: 12503 pw.println("critical)"); 12504 break; 12505 default: 12506 pw.print(mLastMemoryLevel); 12507 pw.println(")"); 12508 break; 12509 } 12510 pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb() 12511 + memInfo.getFreeSizeKb()); pw.print(" kB ("); 12512 pw.print(cachedPss); pw.print(" cached pss + "); 12513 pw.print(memInfo.getCachedSizeKb()); pw.print(" cached + "); 12514 pw.print(memInfo.getFreeSizeKb()); pw.println(" free)"); 12515 } else { 12516 pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(","); 12517 pw.print(cachedPss + memInfo.getCachedSizeKb() 12518 + memInfo.getFreeSizeKb()); pw.print(","); 12519 pw.println(totalPss - cachedPss); 12520 } 12521 } 12522 if (!isCompact) { 12523 pw.print(" Used RAM: "); pw.print(totalPss - cachedPss 12524 + memInfo.getBuffersSizeKb() + memInfo.getShmemSizeKb() 12525 + memInfo.getSlabSizeKb()); pw.print(" kB ("); 12526 pw.print(totalPss - cachedPss); pw.print(" used pss + "); 12527 pw.print(memInfo.getBuffersSizeKb()); pw.print(" buffers + "); 12528 pw.print(memInfo.getShmemSizeKb()); pw.print(" shmem + "); 12529 pw.print(memInfo.getSlabSizeKb()); pw.println(" slab)"); 12530 pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb() 12531 - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb() 12532 - memInfo.getBuffersSizeKb() - memInfo.getShmemSizeKb() 12533 - memInfo.getSlabSizeKb()); pw.println(" kB"); 12534 } 12535 if (!brief) { 12536 if (memInfo.getZramTotalSizeKb() != 0) { 12537 if (!isCompact) { 12538 pw.print(" ZRAM: "); pw.print(memInfo.getZramTotalSizeKb()); 12539 pw.print(" kB physical used for "); 12540 pw.print(memInfo.getSwapTotalSizeKb() 12541 - memInfo.getSwapFreeSizeKb()); 12542 pw.print(" kB in swap ("); 12543 pw.print(memInfo.getSwapTotalSizeKb()); 12544 pw.println(" kB total swap)"); 12545 } else { 12546 pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(","); 12547 pw.print(memInfo.getSwapTotalSizeKb()); pw.print(","); 12548 pw.println(memInfo.getSwapFreeSizeKb()); 12549 } 12550 } 12551 final int[] SINGLE_LONG_FORMAT = new int[] { 12552 Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG 12553 }; 12554 long[] longOut = new long[1]; 12555 Process.readProcFile("/sys/kernel/mm/ksm/pages_shared", 12556 SINGLE_LONG_FORMAT, null, longOut, null); 12557 long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024; 12558 longOut[0] = 0; 12559 Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing", 12560 SINGLE_LONG_FORMAT, null, longOut, null); 12561 long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024; 12562 longOut[0] = 0; 12563 Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared", 12564 SINGLE_LONG_FORMAT, null, longOut, null); 12565 long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024; 12566 longOut[0] = 0; 12567 Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile", 12568 SINGLE_LONG_FORMAT, null, longOut, null); 12569 long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024; 12570 if (!isCompact) { 12571 if (sharing != 0 || shared != 0 || unshared != 0 || voltile != 0) { 12572 pw.print(" KSM: "); pw.print(sharing); 12573 pw.print(" kB saved from shared "); 12574 pw.print(shared); pw.println(" kB"); 12575 pw.print(" "); pw.print(unshared); pw.print(" kB unshared; "); 12576 pw.print(voltile); pw.println(" kB volatile"); 12577 } 12578 pw.print(" Tuning: "); 12579 pw.print(ActivityManager.staticGetMemoryClass()); 12580 pw.print(" (large "); 12581 pw.print(ActivityManager.staticGetLargeMemoryClass()); 12582 pw.print("), oom "); 12583 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024); 12584 pw.print(" kB"); 12585 pw.print(", restore limit "); 12586 pw.print(mProcessList.getCachedRestoreThresholdKb()); 12587 pw.print(" kB"); 12588 if (ActivityManager.isLowRamDeviceStatic()) { 12589 pw.print(" (low-ram)"); 12590 } 12591 if (ActivityManager.isHighEndGfx()) { 12592 pw.print(" (high-end-gfx)"); 12593 } 12594 pw.println(); 12595 } else { 12596 pw.print("ksm,"); pw.print(sharing); pw.print(","); 12597 pw.print(shared); pw.print(","); pw.print(unshared); pw.print(","); 12598 pw.println(voltile); 12599 pw.print("tuning,"); 12600 pw.print(ActivityManager.staticGetMemoryClass()); 12601 pw.print(','); 12602 pw.print(ActivityManager.staticGetLargeMemoryClass()); 12603 pw.print(','); 12604 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024); 12605 if (ActivityManager.isLowRamDeviceStatic()) { 12606 pw.print(",low-ram"); 12607 } 12608 if (ActivityManager.isHighEndGfx()) { 12609 pw.print(",high-end-gfx"); 12610 } 12611 pw.println(); 12612 } 12613 } 12614 } 12615 } 12616 12617 /** 12618 * Searches array of arguments for the specified string 12619 * @param args array of argument strings 12620 * @param value value to search for 12621 * @return true if the value is contained in the array 12622 */ 12623 private static boolean scanArgs(String[] args, String value) { 12624 if (args != null) { 12625 for (String arg : args) { 12626 if (value.equals(arg)) { 12627 return true; 12628 } 12629 } 12630 } 12631 return false; 12632 } 12633 12634 private final boolean removeDyingProviderLocked(ProcessRecord proc, 12635 ContentProviderRecord cpr, boolean always) { 12636 final boolean inLaunching = mLaunchingProviders.contains(cpr); 12637 12638 if (!inLaunching || always) { 12639 synchronized (cpr) { 12640 cpr.launchingApp = null; 12641 cpr.notifyAll(); 12642 } 12643 mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid)); 12644 String names[] = cpr.info.authority.split(";"); 12645 for (int j = 0; j < names.length; j++) { 12646 mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid)); 12647 } 12648 } 12649 12650 for (int i=0; i<cpr.connections.size(); i++) { 12651 ContentProviderConnection conn = cpr.connections.get(i); 12652 if (conn.waiting) { 12653 // If this connection is waiting for the provider, then we don't 12654 // need to mess with its process unless we are always removing 12655 // or for some reason the provider is not currently launching. 12656 if (inLaunching && !always) { 12657 continue; 12658 } 12659 } 12660 ProcessRecord capp = conn.client; 12661 conn.dead = true; 12662 if (conn.stableCount > 0) { 12663 if (!capp.persistent && capp.thread != null 12664 && capp.pid != 0 12665 && capp.pid != MY_PID) { 12666 killUnneededProcessLocked(capp, "depends on provider " 12667 + cpr.name.flattenToShortString() 12668 + " in dying proc " + (proc != null ? proc.processName : "??")); 12669 } 12670 } else if (capp.thread != null && conn.provider.provider != null) { 12671 try { 12672 capp.thread.unstableProviderDied(conn.provider.provider.asBinder()); 12673 } catch (RemoteException e) { 12674 } 12675 // In the protocol here, we don't expect the client to correctly 12676 // clean up this connection, we'll just remove it. 12677 cpr.connections.remove(i); 12678 conn.client.conProviders.remove(conn); 12679 } 12680 } 12681 12682 if (inLaunching && always) { 12683 mLaunchingProviders.remove(cpr); 12684 } 12685 return inLaunching; 12686 } 12687 12688 /** 12689 * Main code for cleaning up a process when it has gone away. This is 12690 * called both as a result of the process dying, or directly when stopping 12691 * a process when running in single process mode. 12692 */ 12693 private final void cleanUpApplicationRecordLocked(ProcessRecord app, 12694 boolean restarting, boolean allowRestart, int index) { 12695 if (index >= 0) { 12696 removeLruProcessLocked(app); 12697 ProcessList.remove(app.pid); 12698 } 12699 12700 mProcessesToGc.remove(app); 12701 mPendingPssProcesses.remove(app); 12702 12703 // Dismiss any open dialogs. 12704 if (app.crashDialog != null && !app.forceCrashReport) { 12705 app.crashDialog.dismiss(); 12706 app.crashDialog = null; 12707 } 12708 if (app.anrDialog != null) { 12709 app.anrDialog.dismiss(); 12710 app.anrDialog = null; 12711 } 12712 if (app.waitDialog != null) { 12713 app.waitDialog.dismiss(); 12714 app.waitDialog = null; 12715 } 12716 12717 app.crashing = false; 12718 app.notResponding = false; 12719 12720 app.resetPackageList(mProcessStats); 12721 app.unlinkDeathRecipient(); 12722 app.makeInactive(mProcessStats); 12723 app.forcingToForeground = null; 12724 updateProcessForegroundLocked(app, false, false); 12725 app.foregroundActivities = false; 12726 app.hasShownUi = false; 12727 app.treatLikeActivity = false; 12728 app.hasAboveClient = false; 12729 app.hasClientActivities = false; 12730 12731 mServices.killServicesLocked(app, allowRestart); 12732 12733 boolean restart = false; 12734 12735 // Remove published content providers. 12736 for (int i=app.pubProviders.size()-1; i>=0; i--) { 12737 ContentProviderRecord cpr = app.pubProviders.valueAt(i); 12738 final boolean always = app.bad || !allowRestart; 12739 if (removeDyingProviderLocked(app, cpr, always) || always) { 12740 // We left the provider in the launching list, need to 12741 // restart it. 12742 restart = true; 12743 } 12744 12745 cpr.provider = null; 12746 cpr.proc = null; 12747 } 12748 app.pubProviders.clear(); 12749 12750 // Take care of any launching providers waiting for this process. 12751 if (checkAppInLaunchingProvidersLocked(app, false)) { 12752 restart = true; 12753 } 12754 12755 // Unregister from connected content providers. 12756 if (!app.conProviders.isEmpty()) { 12757 for (int i=0; i<app.conProviders.size(); i++) { 12758 ContentProviderConnection conn = app.conProviders.get(i); 12759 conn.provider.connections.remove(conn); 12760 } 12761 app.conProviders.clear(); 12762 } 12763 12764 // At this point there may be remaining entries in mLaunchingProviders 12765 // where we were the only one waiting, so they are no longer of use. 12766 // Look for these and clean up if found. 12767 // XXX Commented out for now. Trying to figure out a way to reproduce 12768 // the actual situation to identify what is actually going on. 12769 if (false) { 12770 for (int i=0; i<mLaunchingProviders.size(); i++) { 12771 ContentProviderRecord cpr = (ContentProviderRecord) 12772 mLaunchingProviders.get(i); 12773 if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) { 12774 synchronized (cpr) { 12775 cpr.launchingApp = null; 12776 cpr.notifyAll(); 12777 } 12778 } 12779 } 12780 } 12781 12782 skipCurrentReceiverLocked(app); 12783 12784 // Unregister any receivers. 12785 for (int i=app.receivers.size()-1; i>=0; i--) { 12786 removeReceiverLocked(app.receivers.valueAt(i)); 12787 } 12788 app.receivers.clear(); 12789 12790 // If the app is undergoing backup, tell the backup manager about it 12791 if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) { 12792 if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App " 12793 + mBackupTarget.appInfo + " died during backup"); 12794 try { 12795 IBackupManager bm = IBackupManager.Stub.asInterface( 12796 ServiceManager.getService(Context.BACKUP_SERVICE)); 12797 bm.agentDisconnected(app.info.packageName); 12798 } catch (RemoteException e) { 12799 // can't happen; backup manager is local 12800 } 12801 } 12802 12803 for (int i = mPendingProcessChanges.size()-1; i>=0; i--) { 12804 ProcessChangeItem item = mPendingProcessChanges.get(i); 12805 if (item.pid == app.pid) { 12806 mPendingProcessChanges.remove(i); 12807 mAvailProcessChanges.add(item); 12808 } 12809 } 12810 mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget(); 12811 12812 // If the caller is restarting this app, then leave it in its 12813 // current lists and let the caller take care of it. 12814 if (restarting) { 12815 return; 12816 } 12817 12818 if (!app.persistent || app.isolated) { 12819 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, 12820 "Removing non-persistent process during cleanup: " + app); 12821 mProcessNames.remove(app.processName, app.uid); 12822 mIsolatedProcesses.remove(app.uid); 12823 if (mHeavyWeightProcess == app) { 12824 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 12825 mHeavyWeightProcess.userId, 0)); 12826 mHeavyWeightProcess = null; 12827 } 12828 } else if (!app.removed) { 12829 // This app is persistent, so we need to keep its record around. 12830 // If it is not already on the pending app list, add it there 12831 // and start a new process for it. 12832 if (mPersistentStartingProcesses.indexOf(app) < 0) { 12833 mPersistentStartingProcesses.add(app); 12834 restart = true; 12835 } 12836 } 12837 if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG, 12838 "Clean-up removing on hold: " + app); 12839 mProcessesOnHold.remove(app); 12840 12841 if (app == mHomeProcess) { 12842 mHomeProcess = null; 12843 } 12844 if (app == mPreviousProcess) { 12845 mPreviousProcess = null; 12846 } 12847 12848 if (restart && !app.isolated) { 12849 // We have components that still need to be running in the 12850 // process, so re-launch it. 12851 mProcessNames.put(app.processName, app.uid, app); 12852 startProcessLocked(app, "restart", app.processName); 12853 } else if (app.pid > 0 && app.pid != MY_PID) { 12854 // Goodbye! 12855 boolean removed; 12856 synchronized (mPidsSelfLocked) { 12857 mPidsSelfLocked.remove(app.pid); 12858 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 12859 } 12860 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH, 12861 app.processName, app.info.uid); 12862 if (app.isolated) { 12863 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 12864 } 12865 app.setPid(0); 12866 } 12867 } 12868 12869 boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) { 12870 // Look through the content providers we are waiting to have launched, 12871 // and if any run in this process then either schedule a restart of 12872 // the process or kill the client waiting for it if this process has 12873 // gone bad. 12874 int NL = mLaunchingProviders.size(); 12875 boolean restart = false; 12876 for (int i=0; i<NL; i++) { 12877 ContentProviderRecord cpr = mLaunchingProviders.get(i); 12878 if (cpr.launchingApp == app) { 12879 if (!alwaysBad && !app.bad) { 12880 restart = true; 12881 } else { 12882 removeDyingProviderLocked(app, cpr, true); 12883 // cpr should have been removed from mLaunchingProviders 12884 NL = mLaunchingProviders.size(); 12885 i--; 12886 } 12887 } 12888 } 12889 return restart; 12890 } 12891 12892 // ========================================================= 12893 // SERVICES 12894 // ========================================================= 12895 12896 public List<ActivityManager.RunningServiceInfo> getServices(int maxNum, 12897 int flags) { 12898 enforceNotIsolatedCaller("getServices"); 12899 synchronized (this) { 12900 return mServices.getRunningServiceInfoLocked(maxNum, flags); 12901 } 12902 } 12903 12904 public PendingIntent getRunningServiceControlPanel(ComponentName name) { 12905 enforceNotIsolatedCaller("getRunningServiceControlPanel"); 12906 synchronized (this) { 12907 return mServices.getRunningServiceControlPanelLocked(name); 12908 } 12909 } 12910 12911 public ComponentName startService(IApplicationThread caller, Intent service, 12912 String resolvedType, int userId) { 12913 enforceNotIsolatedCaller("startService"); 12914 // Refuse possible leaked file descriptors 12915 if (service != null && service.hasFileDescriptors() == true) { 12916 throw new IllegalArgumentException("File descriptors passed in Intent"); 12917 } 12918 12919 if (DEBUG_SERVICE) 12920 Slog.v(TAG, "startService: " + service + " type=" + resolvedType); 12921 synchronized(this) { 12922 final int callingPid = Binder.getCallingPid(); 12923 final int callingUid = Binder.getCallingUid(); 12924 final long origId = Binder.clearCallingIdentity(); 12925 ComponentName res = mServices.startServiceLocked(caller, service, 12926 resolvedType, callingPid, callingUid, userId); 12927 Binder.restoreCallingIdentity(origId); 12928 return res; 12929 } 12930 } 12931 12932 ComponentName startServiceInPackage(int uid, 12933 Intent service, String resolvedType, int userId) { 12934 synchronized(this) { 12935 if (DEBUG_SERVICE) 12936 Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType); 12937 final long origId = Binder.clearCallingIdentity(); 12938 ComponentName res = mServices.startServiceLocked(null, service, 12939 resolvedType, -1, uid, userId); 12940 Binder.restoreCallingIdentity(origId); 12941 return res; 12942 } 12943 } 12944 12945 public int stopService(IApplicationThread caller, Intent service, 12946 String resolvedType, int userId) { 12947 enforceNotIsolatedCaller("stopService"); 12948 // Refuse possible leaked file descriptors 12949 if (service != null && service.hasFileDescriptors() == true) { 12950 throw new IllegalArgumentException("File descriptors passed in Intent"); 12951 } 12952 12953 synchronized(this) { 12954 return mServices.stopServiceLocked(caller, service, resolvedType, userId); 12955 } 12956 } 12957 12958 public IBinder peekService(Intent service, String resolvedType) { 12959 enforceNotIsolatedCaller("peekService"); 12960 // Refuse possible leaked file descriptors 12961 if (service != null && service.hasFileDescriptors() == true) { 12962 throw new IllegalArgumentException("File descriptors passed in Intent"); 12963 } 12964 synchronized(this) { 12965 return mServices.peekServiceLocked(service, resolvedType); 12966 } 12967 } 12968 12969 public boolean stopServiceToken(ComponentName className, IBinder token, 12970 int startId) { 12971 synchronized(this) { 12972 return mServices.stopServiceTokenLocked(className, token, startId); 12973 } 12974 } 12975 12976 public void setServiceForeground(ComponentName className, IBinder token, 12977 int id, Notification notification, boolean removeNotification) { 12978 synchronized(this) { 12979 mServices.setServiceForegroundLocked(className, token, id, notification, 12980 removeNotification); 12981 } 12982 } 12983 12984 public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll, 12985 boolean requireFull, String name, String callerPackage) { 12986 final int callingUserId = UserHandle.getUserId(callingUid); 12987 if (callingUserId != userId) { 12988 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 12989 if ((requireFull || checkComponentPermission( 12990 android.Manifest.permission.INTERACT_ACROSS_USERS, 12991 callingPid, callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) 12992 && checkComponentPermission( 12993 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 12994 callingPid, callingUid, -1, true) 12995 != PackageManager.PERMISSION_GRANTED) { 12996 if (userId == UserHandle.USER_CURRENT_OR_SELF) { 12997 // In this case, they would like to just execute as their 12998 // owner user instead of failing. 12999 userId = callingUserId; 13000 } else { 13001 StringBuilder builder = new StringBuilder(128); 13002 builder.append("Permission Denial: "); 13003 builder.append(name); 13004 if (callerPackage != null) { 13005 builder.append(" from "); 13006 builder.append(callerPackage); 13007 } 13008 builder.append(" asks to run as user "); 13009 builder.append(userId); 13010 builder.append(" but is calling from user "); 13011 builder.append(UserHandle.getUserId(callingUid)); 13012 builder.append("; this requires "); 13013 builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL); 13014 if (!requireFull) { 13015 builder.append(" or "); 13016 builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS); 13017 } 13018 String msg = builder.toString(); 13019 Slog.w(TAG, msg); 13020 throw new SecurityException(msg); 13021 } 13022 } 13023 } 13024 if (userId == UserHandle.USER_CURRENT 13025 || userId == UserHandle.USER_CURRENT_OR_SELF) { 13026 // Note that we may be accessing this outside of a lock... 13027 // shouldn't be a big deal, if this is being called outside 13028 // of a locked context there is intrinsically a race with 13029 // the value the caller will receive and someone else changing it. 13030 userId = mCurrentUserId; 13031 } 13032 if (!allowAll && userId < 0) { 13033 throw new IllegalArgumentException( 13034 "Call does not support special user #" + userId); 13035 } 13036 } 13037 return userId; 13038 } 13039 13040 boolean isSingleton(String componentProcessName, ApplicationInfo aInfo, 13041 String className, int flags) { 13042 boolean result = false; 13043 if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) { 13044 if ((flags&ServiceInfo.FLAG_SINGLE_USER) != 0) { 13045 if (ActivityManager.checkUidPermission( 13046 android.Manifest.permission.INTERACT_ACROSS_USERS, 13047 aInfo.uid) != PackageManager.PERMISSION_GRANTED) { 13048 ComponentName comp = new ComponentName(aInfo.packageName, className); 13049 String msg = "Permission Denial: Component " + comp.flattenToShortString() 13050 + " requests FLAG_SINGLE_USER, but app does not hold " 13051 + android.Manifest.permission.INTERACT_ACROSS_USERS; 13052 Slog.w(TAG, msg); 13053 throw new SecurityException(msg); 13054 } 13055 result = true; 13056 } 13057 } else if (componentProcessName == aInfo.packageName) { 13058 result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0; 13059 } else if ("system".equals(componentProcessName)) { 13060 result = true; 13061 } 13062 if (DEBUG_MU) { 13063 Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo 13064 + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result); 13065 } 13066 return result; 13067 } 13068 13069 public int bindService(IApplicationThread caller, IBinder token, 13070 Intent service, String resolvedType, 13071 IServiceConnection connection, int flags, int userId) { 13072 enforceNotIsolatedCaller("bindService"); 13073 // Refuse possible leaked file descriptors 13074 if (service != null && service.hasFileDescriptors() == true) { 13075 throw new IllegalArgumentException("File descriptors passed in Intent"); 13076 } 13077 13078 synchronized(this) { 13079 return mServices.bindServiceLocked(caller, token, service, resolvedType, 13080 connection, flags, userId); 13081 } 13082 } 13083 13084 public boolean unbindService(IServiceConnection connection) { 13085 synchronized (this) { 13086 return mServices.unbindServiceLocked(connection); 13087 } 13088 } 13089 13090 public void publishService(IBinder token, Intent intent, IBinder service) { 13091 // Refuse possible leaked file descriptors 13092 if (intent != null && intent.hasFileDescriptors() == true) { 13093 throw new IllegalArgumentException("File descriptors passed in Intent"); 13094 } 13095 13096 synchronized(this) { 13097 if (!(token instanceof ServiceRecord)) { 13098 throw new IllegalArgumentException("Invalid service token"); 13099 } 13100 mServices.publishServiceLocked((ServiceRecord)token, intent, service); 13101 } 13102 } 13103 13104 public void unbindFinished(IBinder token, Intent intent, boolean doRebind) { 13105 // Refuse possible leaked file descriptors 13106 if (intent != null && intent.hasFileDescriptors() == true) { 13107 throw new IllegalArgumentException("File descriptors passed in Intent"); 13108 } 13109 13110 synchronized(this) { 13111 mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind); 13112 } 13113 } 13114 13115 public void serviceDoneExecuting(IBinder token, int type, int startId, int res) { 13116 synchronized(this) { 13117 if (!(token instanceof ServiceRecord)) { 13118 throw new IllegalArgumentException("Invalid service token"); 13119 } 13120 mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res); 13121 } 13122 } 13123 13124 // ========================================================= 13125 // BACKUP AND RESTORE 13126 // ========================================================= 13127 13128 // Cause the target app to be launched if necessary and its backup agent 13129 // instantiated. The backup agent will invoke backupAgentCreated() on the 13130 // activity manager to announce its creation. 13131 public boolean bindBackupAgent(ApplicationInfo app, int backupMode) { 13132 if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode); 13133 enforceCallingPermission("android.permission.BACKUP", "bindBackupAgent"); 13134 13135 synchronized(this) { 13136 // !!! TODO: currently no check here that we're already bound 13137 BatteryStatsImpl.Uid.Pkg.Serv ss = null; 13138 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 13139 synchronized (stats) { 13140 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name); 13141 } 13142 13143 // Backup agent is now in use, its package can't be stopped. 13144 try { 13145 AppGlobals.getPackageManager().setPackageStoppedState( 13146 app.packageName, false, UserHandle.getUserId(app.uid)); 13147 } catch (RemoteException e) { 13148 } catch (IllegalArgumentException e) { 13149 Slog.w(TAG, "Failed trying to unstop package " 13150 + app.packageName + ": " + e); 13151 } 13152 13153 BackupRecord r = new BackupRecord(ss, app, backupMode); 13154 ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL) 13155 ? new ComponentName(app.packageName, app.backupAgentName) 13156 : new ComponentName("android", "FullBackupAgent"); 13157 // startProcessLocked() returns existing proc's record if it's already running 13158 ProcessRecord proc = startProcessLocked(app.processName, app, 13159 false, 0, "backup", hostingName, false, false, false); 13160 if (proc == null) { 13161 Slog.e(TAG, "Unable to start backup agent process " + r); 13162 return false; 13163 } 13164 13165 r.app = proc; 13166 mBackupTarget = r; 13167 mBackupAppName = app.packageName; 13168 13169 // Try not to kill the process during backup 13170 updateOomAdjLocked(proc); 13171 13172 // If the process is already attached, schedule the creation of the backup agent now. 13173 // If it is not yet live, this will be done when it attaches to the framework. 13174 if (proc.thread != null) { 13175 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc); 13176 try { 13177 proc.thread.scheduleCreateBackupAgent(app, 13178 compatibilityInfoForPackageLocked(app), backupMode); 13179 } catch (RemoteException e) { 13180 // Will time out on the backup manager side 13181 } 13182 } else { 13183 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach"); 13184 } 13185 // Invariants: at this point, the target app process exists and the application 13186 // is either already running or in the process of coming up. mBackupTarget and 13187 // mBackupAppName describe the app, so that when it binds back to the AM we 13188 // know that it's scheduled for a backup-agent operation. 13189 } 13190 13191 return true; 13192 } 13193 13194 @Override 13195 public void clearPendingBackup() { 13196 if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup"); 13197 enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup"); 13198 13199 synchronized (this) { 13200 mBackupTarget = null; 13201 mBackupAppName = null; 13202 } 13203 } 13204 13205 // A backup agent has just come up 13206 public void backupAgentCreated(String agentPackageName, IBinder agent) { 13207 if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName 13208 + " = " + agent); 13209 13210 synchronized(this) { 13211 if (!agentPackageName.equals(mBackupAppName)) { 13212 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!"); 13213 return; 13214 } 13215 } 13216 13217 long oldIdent = Binder.clearCallingIdentity(); 13218 try { 13219 IBackupManager bm = IBackupManager.Stub.asInterface( 13220 ServiceManager.getService(Context.BACKUP_SERVICE)); 13221 bm.agentConnected(agentPackageName, agent); 13222 } catch (RemoteException e) { 13223 // can't happen; the backup manager service is local 13224 } catch (Exception e) { 13225 Slog.w(TAG, "Exception trying to deliver BackupAgent binding: "); 13226 e.printStackTrace(); 13227 } finally { 13228 Binder.restoreCallingIdentity(oldIdent); 13229 } 13230 } 13231 13232 // done with this agent 13233 public void unbindBackupAgent(ApplicationInfo appInfo) { 13234 if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo); 13235 if (appInfo == null) { 13236 Slog.w(TAG, "unbind backup agent for null app"); 13237 return; 13238 } 13239 13240 synchronized(this) { 13241 try { 13242 if (mBackupAppName == null) { 13243 Slog.w(TAG, "Unbinding backup agent with no active backup"); 13244 return; 13245 } 13246 13247 if (!mBackupAppName.equals(appInfo.packageName)) { 13248 Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target"); 13249 return; 13250 } 13251 13252 // Not backing this app up any more; reset its OOM adjustment 13253 final ProcessRecord proc = mBackupTarget.app; 13254 updateOomAdjLocked(proc); 13255 13256 // If the app crashed during backup, 'thread' will be null here 13257 if (proc.thread != null) { 13258 try { 13259 proc.thread.scheduleDestroyBackupAgent(appInfo, 13260 compatibilityInfoForPackageLocked(appInfo)); 13261 } catch (Exception e) { 13262 Slog.e(TAG, "Exception when unbinding backup agent:"); 13263 e.printStackTrace(); 13264 } 13265 } 13266 } finally { 13267 mBackupTarget = null; 13268 mBackupAppName = null; 13269 } 13270 } 13271 } 13272 // ========================================================= 13273 // BROADCASTS 13274 // ========================================================= 13275 13276 private final List getStickiesLocked(String action, IntentFilter filter, 13277 List cur, int userId) { 13278 final ContentResolver resolver = mContext.getContentResolver(); 13279 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 13280 if (stickies == null) { 13281 return cur; 13282 } 13283 final ArrayList<Intent> list = stickies.get(action); 13284 if (list == null) { 13285 return cur; 13286 } 13287 int N = list.size(); 13288 for (int i=0; i<N; i++) { 13289 Intent intent = list.get(i); 13290 if (filter.match(resolver, intent, true, TAG) >= 0) { 13291 if (cur == null) { 13292 cur = new ArrayList<Intent>(); 13293 } 13294 cur.add(intent); 13295 } 13296 } 13297 return cur; 13298 } 13299 13300 boolean isPendingBroadcastProcessLocked(int pid) { 13301 return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid) 13302 || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid); 13303 } 13304 13305 void skipPendingBroadcastLocked(int pid) { 13306 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 13307 for (BroadcastQueue queue : mBroadcastQueues) { 13308 queue.skipPendingBroadcastLocked(pid); 13309 } 13310 } 13311 13312 // The app just attached; send any pending broadcasts that it should receive 13313 boolean sendPendingBroadcastsLocked(ProcessRecord app) { 13314 boolean didSomething = false; 13315 for (BroadcastQueue queue : mBroadcastQueues) { 13316 didSomething |= queue.sendPendingBroadcastsLocked(app); 13317 } 13318 return didSomething; 13319 } 13320 13321 public Intent registerReceiver(IApplicationThread caller, String callerPackage, 13322 IIntentReceiver receiver, IntentFilter filter, String permission, int userId) { 13323 enforceNotIsolatedCaller("registerReceiver"); 13324 int callingUid; 13325 int callingPid; 13326 synchronized(this) { 13327 ProcessRecord callerApp = null; 13328 if (caller != null) { 13329 callerApp = getRecordForAppLocked(caller); 13330 if (callerApp == null) { 13331 throw new SecurityException( 13332 "Unable to find app for caller " + caller 13333 + " (pid=" + Binder.getCallingPid() 13334 + ") when registering receiver " + receiver); 13335 } 13336 if (callerApp.info.uid != Process.SYSTEM_UID && 13337 !callerApp.pkgList.containsKey(callerPackage) && 13338 !"android".equals(callerPackage)) { 13339 throw new SecurityException("Given caller package " + callerPackage 13340 + " is not running in process " + callerApp); 13341 } 13342 callingUid = callerApp.info.uid; 13343 callingPid = callerApp.pid; 13344 } else { 13345 callerPackage = null; 13346 callingUid = Binder.getCallingUid(); 13347 callingPid = Binder.getCallingPid(); 13348 } 13349 13350 userId = this.handleIncomingUser(callingPid, callingUid, userId, 13351 true, true, "registerReceiver", callerPackage); 13352 13353 List allSticky = null; 13354 13355 // Look for any matching sticky broadcasts... 13356 Iterator actions = filter.actionsIterator(); 13357 if (actions != null) { 13358 while (actions.hasNext()) { 13359 String action = (String)actions.next(); 13360 allSticky = getStickiesLocked(action, filter, allSticky, 13361 UserHandle.USER_ALL); 13362 allSticky = getStickiesLocked(action, filter, allSticky, 13363 UserHandle.getUserId(callingUid)); 13364 } 13365 } else { 13366 allSticky = getStickiesLocked(null, filter, allSticky, 13367 UserHandle.USER_ALL); 13368 allSticky = getStickiesLocked(null, filter, allSticky, 13369 UserHandle.getUserId(callingUid)); 13370 } 13371 13372 // The first sticky in the list is returned directly back to 13373 // the client. 13374 Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null; 13375 13376 if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter 13377 + ": " + sticky); 13378 13379 if (receiver == null) { 13380 return sticky; 13381 } 13382 13383 ReceiverList rl 13384 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder()); 13385 if (rl == null) { 13386 rl = new ReceiverList(this, callerApp, callingPid, callingUid, 13387 userId, receiver); 13388 if (rl.app != null) { 13389 rl.app.receivers.add(rl); 13390 } else { 13391 try { 13392 receiver.asBinder().linkToDeath(rl, 0); 13393 } catch (RemoteException e) { 13394 return sticky; 13395 } 13396 rl.linkedToDeath = true; 13397 } 13398 mRegisteredReceivers.put(receiver.asBinder(), rl); 13399 } else if (rl.uid != callingUid) { 13400 throw new IllegalArgumentException( 13401 "Receiver requested to register for uid " + callingUid 13402 + " was previously registered for uid " + rl.uid); 13403 } else if (rl.pid != callingPid) { 13404 throw new IllegalArgumentException( 13405 "Receiver requested to register for pid " + callingPid 13406 + " was previously registered for pid " + rl.pid); 13407 } else if (rl.userId != userId) { 13408 throw new IllegalArgumentException( 13409 "Receiver requested to register for user " + userId 13410 + " was previously registered for user " + rl.userId); 13411 } 13412 BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage, 13413 permission, callingUid, userId); 13414 rl.add(bf); 13415 if (!bf.debugCheck()) { 13416 Slog.w(TAG, "==> For Dynamic broadast"); 13417 } 13418 mReceiverResolver.addFilter(bf); 13419 13420 // Enqueue broadcasts for all existing stickies that match 13421 // this filter. 13422 if (allSticky != null) { 13423 ArrayList receivers = new ArrayList(); 13424 receivers.add(bf); 13425 13426 int N = allSticky.size(); 13427 for (int i=0; i<N; i++) { 13428 Intent intent = (Intent)allSticky.get(i); 13429 BroadcastQueue queue = broadcastQueueForIntent(intent); 13430 BroadcastRecord r = new BroadcastRecord(queue, intent, null, 13431 null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0, 13432 null, null, false, true, true, -1); 13433 queue.enqueueParallelBroadcastLocked(r); 13434 queue.scheduleBroadcastsLocked(); 13435 } 13436 } 13437 13438 return sticky; 13439 } 13440 } 13441 13442 public void unregisterReceiver(IIntentReceiver receiver) { 13443 if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver); 13444 13445 final long origId = Binder.clearCallingIdentity(); 13446 try { 13447 boolean doTrim = false; 13448 13449 synchronized(this) { 13450 ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder()); 13451 if (rl != null) { 13452 if (rl.curBroadcast != null) { 13453 BroadcastRecord r = rl.curBroadcast; 13454 final boolean doNext = finishReceiverLocked( 13455 receiver.asBinder(), r.resultCode, r.resultData, 13456 r.resultExtras, r.resultAbort); 13457 if (doNext) { 13458 doTrim = true; 13459 r.queue.processNextBroadcast(false); 13460 } 13461 } 13462 13463 if (rl.app != null) { 13464 rl.app.receivers.remove(rl); 13465 } 13466 removeReceiverLocked(rl); 13467 if (rl.linkedToDeath) { 13468 rl.linkedToDeath = false; 13469 rl.receiver.asBinder().unlinkToDeath(rl, 0); 13470 } 13471 } 13472 } 13473 13474 // If we actually concluded any broadcasts, we might now be able 13475 // to trim the recipients' apps from our working set 13476 if (doTrim) { 13477 trimApplications(); 13478 return; 13479 } 13480 13481 } finally { 13482 Binder.restoreCallingIdentity(origId); 13483 } 13484 } 13485 13486 void removeReceiverLocked(ReceiverList rl) { 13487 mRegisteredReceivers.remove(rl.receiver.asBinder()); 13488 int N = rl.size(); 13489 for (int i=0; i<N; i++) { 13490 mReceiverResolver.removeFilter(rl.get(i)); 13491 } 13492 } 13493 13494 private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) { 13495 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 13496 ProcessRecord r = mLruProcesses.get(i); 13497 if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) { 13498 try { 13499 r.thread.dispatchPackageBroadcast(cmd, packages); 13500 } catch (RemoteException ex) { 13501 } 13502 } 13503 } 13504 } 13505 13506 private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType, 13507 int[] users) { 13508 List<ResolveInfo> receivers = null; 13509 try { 13510 HashSet<ComponentName> singleUserReceivers = null; 13511 boolean scannedFirstReceivers = false; 13512 for (int user : users) { 13513 List<ResolveInfo> newReceivers = AppGlobals.getPackageManager() 13514 .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user); 13515 if (user != 0 && newReceivers != null) { 13516 // If this is not the primary user, we need to check for 13517 // any receivers that should be filtered out. 13518 for (int i=0; i<newReceivers.size(); i++) { 13519 ResolveInfo ri = newReceivers.get(i); 13520 if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) { 13521 newReceivers.remove(i); 13522 i--; 13523 } 13524 } 13525 } 13526 if (newReceivers != null && newReceivers.size() == 0) { 13527 newReceivers = null; 13528 } 13529 if (receivers == null) { 13530 receivers = newReceivers; 13531 } else if (newReceivers != null) { 13532 // We need to concatenate the additional receivers 13533 // found with what we have do far. This would be easy, 13534 // but we also need to de-dup any receivers that are 13535 // singleUser. 13536 if (!scannedFirstReceivers) { 13537 // Collect any single user receivers we had already retrieved. 13538 scannedFirstReceivers = true; 13539 for (int i=0; i<receivers.size(); i++) { 13540 ResolveInfo ri = receivers.get(i); 13541 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 13542 ComponentName cn = new ComponentName( 13543 ri.activityInfo.packageName, ri.activityInfo.name); 13544 if (singleUserReceivers == null) { 13545 singleUserReceivers = new HashSet<ComponentName>(); 13546 } 13547 singleUserReceivers.add(cn); 13548 } 13549 } 13550 } 13551 // Add the new results to the existing results, tracking 13552 // and de-dupping single user receivers. 13553 for (int i=0; i<newReceivers.size(); i++) { 13554 ResolveInfo ri = newReceivers.get(i); 13555 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 13556 ComponentName cn = new ComponentName( 13557 ri.activityInfo.packageName, ri.activityInfo.name); 13558 if (singleUserReceivers == null) { 13559 singleUserReceivers = new HashSet<ComponentName>(); 13560 } 13561 if (!singleUserReceivers.contains(cn)) { 13562 singleUserReceivers.add(cn); 13563 receivers.add(ri); 13564 } 13565 } else { 13566 receivers.add(ri); 13567 } 13568 } 13569 } 13570 } 13571 } catch (RemoteException ex) { 13572 // pm is in same process, this will never happen. 13573 } 13574 return receivers; 13575 } 13576 13577 private final int broadcastIntentLocked(ProcessRecord callerApp, 13578 String callerPackage, Intent intent, String resolvedType, 13579 IIntentReceiver resultTo, int resultCode, String resultData, 13580 Bundle map, String requiredPermission, int appOp, 13581 boolean ordered, boolean sticky, int callingPid, int callingUid, 13582 int userId) { 13583 intent = new Intent(intent); 13584 13585 // By default broadcasts do not go to stopped apps. 13586 intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES); 13587 13588 if (DEBUG_BROADCAST_LIGHT) Slog.v( 13589 TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent 13590 + " ordered=" + ordered + " userid=" + userId); 13591 if ((resultTo != null) && !ordered) { 13592 Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!"); 13593 } 13594 13595 userId = handleIncomingUser(callingPid, callingUid, userId, 13596 true, false, "broadcast", callerPackage); 13597 13598 // Make sure that the user who is receiving this broadcast is started. 13599 // If not, we will just skip it. 13600 if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) { 13601 if (callingUid != Process.SYSTEM_UID || (intent.getFlags() 13602 & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) { 13603 Slog.w(TAG, "Skipping broadcast of " + intent 13604 + ": user " + userId + " is stopped"); 13605 return ActivityManager.BROADCAST_SUCCESS; 13606 } 13607 } 13608 13609 /* 13610 * Prevent non-system code (defined here to be non-persistent 13611 * processes) from sending protected broadcasts. 13612 */ 13613 int callingAppId = UserHandle.getAppId(callingUid); 13614 if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID 13615 || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID || 13616 callingUid == 0) { 13617 // Always okay. 13618 } else if (callerApp == null || !callerApp.persistent) { 13619 try { 13620 if (AppGlobals.getPackageManager().isProtectedBroadcast( 13621 intent.getAction())) { 13622 String msg = "Permission Denial: not allowed to send broadcast " 13623 + intent.getAction() + " from pid=" 13624 + callingPid + ", uid=" + callingUid; 13625 Slog.w(TAG, msg); 13626 throw new SecurityException(msg); 13627 } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) { 13628 // Special case for compatibility: we don't want apps to send this, 13629 // but historically it has not been protected and apps may be using it 13630 // to poke their own app widget. So, instead of making it protected, 13631 // just limit it to the caller. 13632 if (callerApp == null) { 13633 String msg = "Permission Denial: not allowed to send broadcast " 13634 + intent.getAction() + " from unknown caller."; 13635 Slog.w(TAG, msg); 13636 throw new SecurityException(msg); 13637 } else if (intent.getComponent() != null) { 13638 // They are good enough to send to an explicit component... verify 13639 // it is being sent to the calling app. 13640 if (!intent.getComponent().getPackageName().equals( 13641 callerApp.info.packageName)) { 13642 String msg = "Permission Denial: not allowed to send broadcast " 13643 + intent.getAction() + " to " 13644 + intent.getComponent().getPackageName() + " from " 13645 + callerApp.info.packageName; 13646 Slog.w(TAG, msg); 13647 throw new SecurityException(msg); 13648 } 13649 } else { 13650 // Limit broadcast to their own package. 13651 intent.setPackage(callerApp.info.packageName); 13652 } 13653 } 13654 } catch (RemoteException e) { 13655 Slog.w(TAG, "Remote exception", e); 13656 return ActivityManager.BROADCAST_SUCCESS; 13657 } 13658 } 13659 13660 // Handle special intents: if this broadcast is from the package 13661 // manager about a package being removed, we need to remove all of 13662 // its activities from the history stack. 13663 final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals( 13664 intent.getAction()); 13665 if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction()) 13666 || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction()) 13667 || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction()) 13668 || uidRemoved) { 13669 if (checkComponentPermission( 13670 android.Manifest.permission.BROADCAST_PACKAGE_REMOVED, 13671 callingPid, callingUid, -1, true) 13672 == PackageManager.PERMISSION_GRANTED) { 13673 if (uidRemoved) { 13674 final Bundle intentExtras = intent.getExtras(); 13675 final int uid = intentExtras != null 13676 ? intentExtras.getInt(Intent.EXTRA_UID) : -1; 13677 if (uid >= 0) { 13678 BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics(); 13679 synchronized (bs) { 13680 bs.removeUidStatsLocked(uid); 13681 } 13682 mAppOpsService.uidRemoved(uid); 13683 } 13684 } else { 13685 // If resources are unavailable just force stop all 13686 // those packages and flush the attribute cache as well. 13687 if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) { 13688 String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 13689 if (list != null && (list.length > 0)) { 13690 for (String pkg : list) { 13691 forceStopPackageLocked(pkg, -1, false, true, true, false, false, userId, 13692 "storage unmount"); 13693 } 13694 sendPackageBroadcastLocked( 13695 IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId); 13696 } 13697 } else { 13698 Uri data = intent.getData(); 13699 String ssp; 13700 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 13701 boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals( 13702 intent.getAction()); 13703 boolean fullUninstall = removed && 13704 !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false); 13705 if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) { 13706 forceStopPackageLocked(ssp, UserHandle.getAppId( 13707 intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true, 13708 false, fullUninstall, userId, 13709 removed ? "pkg removed" : "pkg changed"); 13710 } 13711 if (removed) { 13712 sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED, 13713 new String[] {ssp}, userId); 13714 if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) { 13715 mAppOpsService.packageRemoved( 13716 intent.getIntExtra(Intent.EXTRA_UID, -1), ssp); 13717 13718 // Remove all permissions granted from/to this package 13719 removeUriPermissionsForPackageLocked(ssp, userId, true); 13720 } 13721 } 13722 } 13723 } 13724 } 13725 } else { 13726 String msg = "Permission Denial: " + intent.getAction() 13727 + " broadcast from " + callerPackage + " (pid=" + callingPid 13728 + ", uid=" + callingUid + ")" 13729 + " requires " 13730 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED; 13731 Slog.w(TAG, msg); 13732 throw new SecurityException(msg); 13733 } 13734 13735 // Special case for adding a package: by default turn on compatibility 13736 // mode. 13737 } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) { 13738 Uri data = intent.getData(); 13739 String ssp; 13740 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 13741 mCompatModePackages.handlePackageAddedLocked(ssp, 13742 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)); 13743 } 13744 } 13745 13746 /* 13747 * If this is the time zone changed action, queue up a message that will reset the timezone 13748 * of all currently running processes. This message will get queued up before the broadcast 13749 * happens. 13750 */ 13751 if (Intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) { 13752 mHandler.sendEmptyMessage(UPDATE_TIME_ZONE); 13753 } 13754 13755 /* 13756 * If the user set the time, let all running processes know. 13757 */ 13758 if (Intent.ACTION_TIME_CHANGED.equals(intent.getAction())) { 13759 final int is24Hour = intent.getBooleanExtra( 13760 Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1 : 0; 13761 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0)); 13762 } 13763 13764 if (Intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) { 13765 mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG); 13766 } 13767 13768 if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) { 13769 ProxyInfo proxy = intent.getParcelableExtra("proxy"); 13770 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy)); 13771 } 13772 13773 // Add to the sticky list if requested. 13774 if (sticky) { 13775 if (checkPermission(android.Manifest.permission.BROADCAST_STICKY, 13776 callingPid, callingUid) 13777 != PackageManager.PERMISSION_GRANTED) { 13778 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid=" 13779 + callingPid + ", uid=" + callingUid 13780 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 13781 Slog.w(TAG, msg); 13782 throw new SecurityException(msg); 13783 } 13784 if (requiredPermission != null) { 13785 Slog.w(TAG, "Can't broadcast sticky intent " + intent 13786 + " and enforce permission " + requiredPermission); 13787 return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION; 13788 } 13789 if (intent.getComponent() != null) { 13790 throw new SecurityException( 13791 "Sticky broadcasts can't target a specific component"); 13792 } 13793 // We use userId directly here, since the "all" target is maintained 13794 // as a separate set of sticky broadcasts. 13795 if (userId != UserHandle.USER_ALL) { 13796 // But first, if this is not a broadcast to all users, then 13797 // make sure it doesn't conflict with an existing broadcast to 13798 // all users. 13799 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get( 13800 UserHandle.USER_ALL); 13801 if (stickies != null) { 13802 ArrayList<Intent> list = stickies.get(intent.getAction()); 13803 if (list != null) { 13804 int N = list.size(); 13805 int i; 13806 for (i=0; i<N; i++) { 13807 if (intent.filterEquals(list.get(i))) { 13808 throw new IllegalArgumentException( 13809 "Sticky broadcast " + intent + " for user " 13810 + userId + " conflicts with existing global broadcast"); 13811 } 13812 } 13813 } 13814 } 13815 } 13816 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 13817 if (stickies == null) { 13818 stickies = new ArrayMap<String, ArrayList<Intent>>(); 13819 mStickyBroadcasts.put(userId, stickies); 13820 } 13821 ArrayList<Intent> list = stickies.get(intent.getAction()); 13822 if (list == null) { 13823 list = new ArrayList<Intent>(); 13824 stickies.put(intent.getAction(), list); 13825 } 13826 int N = list.size(); 13827 int i; 13828 for (i=0; i<N; i++) { 13829 if (intent.filterEquals(list.get(i))) { 13830 // This sticky already exists, replace it. 13831 list.set(i, new Intent(intent)); 13832 break; 13833 } 13834 } 13835 if (i >= N) { 13836 list.add(new Intent(intent)); 13837 } 13838 } 13839 13840 int[] users; 13841 if (userId == UserHandle.USER_ALL) { 13842 // Caller wants broadcast to go to all started users. 13843 users = mStartedUserArray; 13844 } else { 13845 // Caller wants broadcast to go to one specific user. 13846 users = new int[] {userId}; 13847 } 13848 13849 // Figure out who all will receive this broadcast. 13850 List receivers = null; 13851 List<BroadcastFilter> registeredReceivers = null; 13852 // Need to resolve the intent to interested receivers... 13853 if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) 13854 == 0) { 13855 receivers = collectReceiverComponents(intent, resolvedType, users); 13856 } 13857 if (intent.getComponent() == null) { 13858 registeredReceivers = mReceiverResolver.queryIntent(intent, 13859 resolvedType, false, userId); 13860 } 13861 13862 final boolean replacePending = 13863 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0; 13864 13865 if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction() 13866 + " replacePending=" + replacePending); 13867 13868 int NR = registeredReceivers != null ? registeredReceivers.size() : 0; 13869 if (!ordered && NR > 0) { 13870 // If we are not serializing this broadcast, then send the 13871 // registered receivers separately so they don't wait for the 13872 // components to be launched. 13873 final BroadcastQueue queue = broadcastQueueForIntent(intent); 13874 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 13875 callerPackage, callingPid, callingUid, resolvedType, requiredPermission, 13876 appOp, registeredReceivers, resultTo, resultCode, resultData, map, 13877 ordered, sticky, false, userId); 13878 if (DEBUG_BROADCAST) Slog.v( 13879 TAG, "Enqueueing parallel broadcast " + r); 13880 final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r); 13881 if (!replaced) { 13882 queue.enqueueParallelBroadcastLocked(r); 13883 queue.scheduleBroadcastsLocked(); 13884 } 13885 registeredReceivers = null; 13886 NR = 0; 13887 } 13888 13889 // Merge into one list. 13890 int ir = 0; 13891 if (receivers != null) { 13892 // A special case for PACKAGE_ADDED: do not allow the package 13893 // being added to see this broadcast. This prevents them from 13894 // using this as a back door to get run as soon as they are 13895 // installed. Maybe in the future we want to have a special install 13896 // broadcast or such for apps, but we'd like to deliberately make 13897 // this decision. 13898 String skipPackages[] = null; 13899 if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction()) 13900 || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction()) 13901 || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) { 13902 Uri data = intent.getData(); 13903 if (data != null) { 13904 String pkgName = data.getSchemeSpecificPart(); 13905 if (pkgName != null) { 13906 skipPackages = new String[] { pkgName }; 13907 } 13908 } 13909 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) { 13910 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 13911 } 13912 if (skipPackages != null && (skipPackages.length > 0)) { 13913 for (String skipPackage : skipPackages) { 13914 if (skipPackage != null) { 13915 int NT = receivers.size(); 13916 for (int it=0; it<NT; it++) { 13917 ResolveInfo curt = (ResolveInfo)receivers.get(it); 13918 if (curt.activityInfo.packageName.equals(skipPackage)) { 13919 receivers.remove(it); 13920 it--; 13921 NT--; 13922 } 13923 } 13924 } 13925 } 13926 } 13927 13928 int NT = receivers != null ? receivers.size() : 0; 13929 int it = 0; 13930 ResolveInfo curt = null; 13931 BroadcastFilter curr = null; 13932 while (it < NT && ir < NR) { 13933 if (curt == null) { 13934 curt = (ResolveInfo)receivers.get(it); 13935 } 13936 if (curr == null) { 13937 curr = registeredReceivers.get(ir); 13938 } 13939 if (curr.getPriority() >= curt.priority) { 13940 // Insert this broadcast record into the final list. 13941 receivers.add(it, curr); 13942 ir++; 13943 curr = null; 13944 it++; 13945 NT++; 13946 } else { 13947 // Skip to the next ResolveInfo in the final list. 13948 it++; 13949 curt = null; 13950 } 13951 } 13952 } 13953 while (ir < NR) { 13954 if (receivers == null) { 13955 receivers = new ArrayList(); 13956 } 13957 receivers.add(registeredReceivers.get(ir)); 13958 ir++; 13959 } 13960 13961 if ((receivers != null && receivers.size() > 0) 13962 || resultTo != null) { 13963 BroadcastQueue queue = broadcastQueueForIntent(intent); 13964 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 13965 callerPackage, callingPid, callingUid, resolvedType, 13966 requiredPermission, appOp, receivers, resultTo, resultCode, 13967 resultData, map, ordered, sticky, false, userId); 13968 if (DEBUG_BROADCAST) Slog.v( 13969 TAG, "Enqueueing ordered broadcast " + r 13970 + ": prev had " + queue.mOrderedBroadcasts.size()); 13971 if (DEBUG_BROADCAST) { 13972 int seq = r.intent.getIntExtra("seq", -1); 13973 Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq); 13974 } 13975 boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r); 13976 if (!replaced) { 13977 queue.enqueueOrderedBroadcastLocked(r); 13978 queue.scheduleBroadcastsLocked(); 13979 } 13980 } 13981 13982 return ActivityManager.BROADCAST_SUCCESS; 13983 } 13984 13985 final Intent verifyBroadcastLocked(Intent intent) { 13986 // Refuse possible leaked file descriptors 13987 if (intent != null && intent.hasFileDescriptors() == true) { 13988 throw new IllegalArgumentException("File descriptors passed in Intent"); 13989 } 13990 13991 int flags = intent.getFlags(); 13992 13993 if (!mProcessesReady) { 13994 // if the caller really truly claims to know what they're doing, go 13995 // ahead and allow the broadcast without launching any receivers 13996 if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) { 13997 intent = new Intent(intent); 13998 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 13999 } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) { 14000 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent 14001 + " before boot completion"); 14002 throw new IllegalStateException("Cannot broadcast before boot completed"); 14003 } 14004 } 14005 14006 if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 14007 throw new IllegalArgumentException( 14008 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 14009 } 14010 14011 return intent; 14012 } 14013 14014 public final int broadcastIntent(IApplicationThread caller, 14015 Intent intent, String resolvedType, IIntentReceiver resultTo, 14016 int resultCode, String resultData, Bundle map, 14017 String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) { 14018 enforceNotIsolatedCaller("broadcastIntent"); 14019 synchronized(this) { 14020 intent = verifyBroadcastLocked(intent); 14021 14022 final ProcessRecord callerApp = getRecordForAppLocked(caller); 14023 final int callingPid = Binder.getCallingPid(); 14024 final int callingUid = Binder.getCallingUid(); 14025 final long origId = Binder.clearCallingIdentity(); 14026 int res = broadcastIntentLocked(callerApp, 14027 callerApp != null ? callerApp.info.packageName : null, 14028 intent, resolvedType, resultTo, 14029 resultCode, resultData, map, requiredPermission, appOp, serialized, sticky, 14030 callingPid, callingUid, userId); 14031 Binder.restoreCallingIdentity(origId); 14032 return res; 14033 } 14034 } 14035 14036 int broadcastIntentInPackage(String packageName, int uid, 14037 Intent intent, String resolvedType, IIntentReceiver resultTo, 14038 int resultCode, String resultData, Bundle map, 14039 String requiredPermission, boolean serialized, boolean sticky, int userId) { 14040 synchronized(this) { 14041 intent = verifyBroadcastLocked(intent); 14042 14043 final long origId = Binder.clearCallingIdentity(); 14044 int res = broadcastIntentLocked(null, packageName, intent, resolvedType, 14045 resultTo, resultCode, resultData, map, requiredPermission, 14046 AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId); 14047 Binder.restoreCallingIdentity(origId); 14048 return res; 14049 } 14050 } 14051 14052 public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) { 14053 // Refuse possible leaked file descriptors 14054 if (intent != null && intent.hasFileDescriptors() == true) { 14055 throw new IllegalArgumentException("File descriptors passed in Intent"); 14056 } 14057 14058 userId = handleIncomingUser(Binder.getCallingPid(), 14059 Binder.getCallingUid(), userId, true, false, "removeStickyBroadcast", null); 14060 14061 synchronized(this) { 14062 if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY) 14063 != PackageManager.PERMISSION_GRANTED) { 14064 String msg = "Permission Denial: unbroadcastIntent() from pid=" 14065 + Binder.getCallingPid() 14066 + ", uid=" + Binder.getCallingUid() 14067 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 14068 Slog.w(TAG, msg); 14069 throw new SecurityException(msg); 14070 } 14071 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 14072 if (stickies != null) { 14073 ArrayList<Intent> list = stickies.get(intent.getAction()); 14074 if (list != null) { 14075 int N = list.size(); 14076 int i; 14077 for (i=0; i<N; i++) { 14078 if (intent.filterEquals(list.get(i))) { 14079 list.remove(i); 14080 break; 14081 } 14082 } 14083 if (list.size() <= 0) { 14084 stickies.remove(intent.getAction()); 14085 } 14086 } 14087 if (stickies.size() <= 0) { 14088 mStickyBroadcasts.remove(userId); 14089 } 14090 } 14091 } 14092 } 14093 14094 private final boolean finishReceiverLocked(IBinder receiver, int resultCode, 14095 String resultData, Bundle resultExtras, boolean resultAbort) { 14096 final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver); 14097 if (r == null) { 14098 Slog.w(TAG, "finishReceiver called but not found on queue"); 14099 return false; 14100 } 14101 14102 return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false); 14103 } 14104 14105 void backgroundServicesFinishedLocked(int userId) { 14106 for (BroadcastQueue queue : mBroadcastQueues) { 14107 queue.backgroundServicesFinishedLocked(userId); 14108 } 14109 } 14110 14111 public void finishReceiver(IBinder who, int resultCode, String resultData, 14112 Bundle resultExtras, boolean resultAbort) { 14113 if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who); 14114 14115 // Refuse possible leaked file descriptors 14116 if (resultExtras != null && resultExtras.hasFileDescriptors()) { 14117 throw new IllegalArgumentException("File descriptors passed in Bundle"); 14118 } 14119 14120 final long origId = Binder.clearCallingIdentity(); 14121 try { 14122 boolean doNext = false; 14123 BroadcastRecord r; 14124 14125 synchronized(this) { 14126 r = broadcastRecordForReceiverLocked(who); 14127 if (r != null) { 14128 doNext = r.queue.finishReceiverLocked(r, resultCode, 14129 resultData, resultExtras, resultAbort, true); 14130 } 14131 } 14132 14133 if (doNext) { 14134 r.queue.processNextBroadcast(false); 14135 } 14136 trimApplications(); 14137 } finally { 14138 Binder.restoreCallingIdentity(origId); 14139 } 14140 } 14141 14142 // ========================================================= 14143 // INSTRUMENTATION 14144 // ========================================================= 14145 14146 public boolean startInstrumentation(ComponentName className, 14147 String profileFile, int flags, Bundle arguments, 14148 IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection, 14149 int userId) { 14150 enforceNotIsolatedCaller("startInstrumentation"); 14151 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 14152 userId, false, true, "startInstrumentation", null); 14153 // Refuse possible leaked file descriptors 14154 if (arguments != null && arguments.hasFileDescriptors()) { 14155 throw new IllegalArgumentException("File descriptors passed in Bundle"); 14156 } 14157 14158 synchronized(this) { 14159 InstrumentationInfo ii = null; 14160 ApplicationInfo ai = null; 14161 try { 14162 ii = mContext.getPackageManager().getInstrumentationInfo( 14163 className, STOCK_PM_FLAGS); 14164 ai = AppGlobals.getPackageManager().getApplicationInfo( 14165 ii.targetPackage, STOCK_PM_FLAGS, userId); 14166 } catch (PackageManager.NameNotFoundException e) { 14167 } catch (RemoteException e) { 14168 } 14169 if (ii == null) { 14170 reportStartInstrumentationFailure(watcher, className, 14171 "Unable to find instrumentation info for: " + className); 14172 return false; 14173 } 14174 if (ai == null) { 14175 reportStartInstrumentationFailure(watcher, className, 14176 "Unable to find instrumentation target package: " + ii.targetPackage); 14177 return false; 14178 } 14179 14180 int match = mContext.getPackageManager().checkSignatures( 14181 ii.targetPackage, ii.packageName); 14182 if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) { 14183 String msg = "Permission Denial: starting instrumentation " 14184 + className + " from pid=" 14185 + Binder.getCallingPid() 14186 + ", uid=" + Binder.getCallingPid() 14187 + " not allowed because package " + ii.packageName 14188 + " does not have a signature matching the target " 14189 + ii.targetPackage; 14190 reportStartInstrumentationFailure(watcher, className, msg); 14191 throw new SecurityException(msg); 14192 } 14193 14194 final long origId = Binder.clearCallingIdentity(); 14195 // Instrumentation can kill and relaunch even persistent processes 14196 forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId, 14197 "start instr"); 14198 ProcessRecord app = addAppLocked(ai, false); 14199 app.instrumentationClass = className; 14200 app.instrumentationInfo = ai; 14201 app.instrumentationProfileFile = profileFile; 14202 app.instrumentationArguments = arguments; 14203 app.instrumentationWatcher = watcher; 14204 app.instrumentationUiAutomationConnection = uiAutomationConnection; 14205 app.instrumentationResultClass = className; 14206 Binder.restoreCallingIdentity(origId); 14207 } 14208 14209 return true; 14210 } 14211 14212 /** 14213 * Report errors that occur while attempting to start Instrumentation. Always writes the 14214 * error to the logs, but if somebody is watching, send the report there too. This enables 14215 * the "am" command to report errors with more information. 14216 * 14217 * @param watcher The IInstrumentationWatcher. Null if there isn't one. 14218 * @param cn The component name of the instrumentation. 14219 * @param report The error report. 14220 */ 14221 private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher, 14222 ComponentName cn, String report) { 14223 Slog.w(TAG, report); 14224 try { 14225 if (watcher != null) { 14226 Bundle results = new Bundle(); 14227 results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService"); 14228 results.putString("Error", report); 14229 watcher.instrumentationStatus(cn, -1, results); 14230 } 14231 } catch (RemoteException e) { 14232 Slog.w(TAG, e); 14233 } 14234 } 14235 14236 void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) { 14237 if (app.instrumentationWatcher != null) { 14238 try { 14239 // NOTE: IInstrumentationWatcher *must* be oneway here 14240 app.instrumentationWatcher.instrumentationFinished( 14241 app.instrumentationClass, 14242 resultCode, 14243 results); 14244 } catch (RemoteException e) { 14245 } 14246 } 14247 if (app.instrumentationUiAutomationConnection != null) { 14248 try { 14249 app.instrumentationUiAutomationConnection.shutdown(); 14250 } catch (RemoteException re) { 14251 /* ignore */ 14252 } 14253 // Only a UiAutomation can set this flag and now that 14254 // it is finished we make sure it is reset to its default. 14255 mUserIsMonkey = false; 14256 } 14257 app.instrumentationWatcher = null; 14258 app.instrumentationUiAutomationConnection = null; 14259 app.instrumentationClass = null; 14260 app.instrumentationInfo = null; 14261 app.instrumentationProfileFile = null; 14262 app.instrumentationArguments = null; 14263 14264 forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId, 14265 "finished inst"); 14266 } 14267 14268 public void finishInstrumentation(IApplicationThread target, 14269 int resultCode, Bundle results) { 14270 int userId = UserHandle.getCallingUserId(); 14271 // Refuse possible leaked file descriptors 14272 if (results != null && results.hasFileDescriptors()) { 14273 throw new IllegalArgumentException("File descriptors passed in Intent"); 14274 } 14275 14276 synchronized(this) { 14277 ProcessRecord app = getRecordForAppLocked(target); 14278 if (app == null) { 14279 Slog.w(TAG, "finishInstrumentation: no app for " + target); 14280 return; 14281 } 14282 final long origId = Binder.clearCallingIdentity(); 14283 finishInstrumentationLocked(app, resultCode, results); 14284 Binder.restoreCallingIdentity(origId); 14285 } 14286 } 14287 14288 // ========================================================= 14289 // CONFIGURATION 14290 // ========================================================= 14291 14292 public ConfigurationInfo getDeviceConfigurationInfo() { 14293 ConfigurationInfo config = new ConfigurationInfo(); 14294 synchronized (this) { 14295 config.reqTouchScreen = mConfiguration.touchscreen; 14296 config.reqKeyboardType = mConfiguration.keyboard; 14297 config.reqNavigation = mConfiguration.navigation; 14298 if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD 14299 || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) { 14300 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV; 14301 } 14302 if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED 14303 && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) { 14304 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD; 14305 } 14306 config.reqGlEsVersion = GL_ES_VERSION; 14307 } 14308 return config; 14309 } 14310 14311 ActivityStack getFocusedStack() { 14312 return mStackSupervisor.getFocusedStack(); 14313 } 14314 14315 public Configuration getConfiguration() { 14316 Configuration ci; 14317 synchronized(this) { 14318 ci = new Configuration(mConfiguration); 14319 } 14320 return ci; 14321 } 14322 14323 public void updatePersistentConfiguration(Configuration values) { 14324 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 14325 "updateConfiguration()"); 14326 enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS, 14327 "updateConfiguration()"); 14328 if (values == null) { 14329 throw new NullPointerException("Configuration must not be null"); 14330 } 14331 14332 synchronized(this) { 14333 final long origId = Binder.clearCallingIdentity(); 14334 updateConfigurationLocked(values, null, true, false); 14335 Binder.restoreCallingIdentity(origId); 14336 } 14337 } 14338 14339 public void updateConfiguration(Configuration values) { 14340 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 14341 "updateConfiguration()"); 14342 14343 synchronized(this) { 14344 if (values == null && mWindowManager != null) { 14345 // sentinel: fetch the current configuration from the window manager 14346 values = mWindowManager.computeNewConfiguration(); 14347 } 14348 14349 if (mWindowManager != null) { 14350 mProcessList.applyDisplaySize(mWindowManager); 14351 } 14352 14353 final long origId = Binder.clearCallingIdentity(); 14354 if (values != null) { 14355 Settings.System.clearConfiguration(values); 14356 } 14357 updateConfigurationLocked(values, null, false, false); 14358 Binder.restoreCallingIdentity(origId); 14359 } 14360 } 14361 14362 /** 14363 * Do either or both things: (1) change the current configuration, and (2) 14364 * make sure the given activity is running with the (now) current 14365 * configuration. Returns true if the activity has been left running, or 14366 * false if <var>starting</var> is being destroyed to match the new 14367 * configuration. 14368 * @param persistent TODO 14369 */ 14370 boolean updateConfigurationLocked(Configuration values, 14371 ActivityRecord starting, boolean persistent, boolean initLocale) { 14372 int changes = 0; 14373 14374 if (values != null) { 14375 Configuration newConfig = new Configuration(mConfiguration); 14376 changes = newConfig.updateFrom(values); 14377 if (changes != 0) { 14378 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) { 14379 Slog.i(TAG, "Updating configuration to: " + values); 14380 } 14381 14382 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes); 14383 14384 if (values.locale != null && !initLocale) { 14385 saveLocaleLocked(values.locale, 14386 !values.locale.equals(mConfiguration.locale), 14387 values.userSetLocale); 14388 } 14389 14390 mConfigurationSeq++; 14391 if (mConfigurationSeq <= 0) { 14392 mConfigurationSeq = 1; 14393 } 14394 newConfig.seq = mConfigurationSeq; 14395 mConfiguration = newConfig; 14396 Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig); 14397 mUsageStatsService.noteStartConfig(newConfig); 14398 14399 final Configuration configCopy = new Configuration(mConfiguration); 14400 14401 // TODO: If our config changes, should we auto dismiss any currently 14402 // showing dialogs? 14403 mShowDialogs = shouldShowDialogs(newConfig); 14404 14405 AttributeCache ac = AttributeCache.instance(); 14406 if (ac != null) { 14407 ac.updateConfiguration(configCopy); 14408 } 14409 14410 // Make sure all resources in our process are updated 14411 // right now, so that anyone who is going to retrieve 14412 // resource values after we return will be sure to get 14413 // the new ones. This is especially important during 14414 // boot, where the first config change needs to guarantee 14415 // all resources have that config before following boot 14416 // code is executed. 14417 mSystemThread.applyConfigurationToResources(configCopy); 14418 14419 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) { 14420 Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG); 14421 msg.obj = new Configuration(configCopy); 14422 mHandler.sendMessage(msg); 14423 } 14424 14425 for (int i=mLruProcesses.size()-1; i>=0; i--) { 14426 ProcessRecord app = mLruProcesses.get(i); 14427 try { 14428 if (app.thread != null) { 14429 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc " 14430 + app.processName + " new config " + mConfiguration); 14431 app.thread.scheduleConfigurationChanged(configCopy); 14432 } 14433 } catch (Exception e) { 14434 } 14435 } 14436 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED); 14437 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 14438 | Intent.FLAG_RECEIVER_REPLACE_PENDING 14439 | Intent.FLAG_RECEIVER_FOREGROUND); 14440 broadcastIntentLocked(null, null, intent, null, null, 0, null, null, 14441 null, AppOpsManager.OP_NONE, false, false, MY_PID, 14442 Process.SYSTEM_UID, UserHandle.USER_ALL); 14443 if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) { 14444 intent = new Intent(Intent.ACTION_LOCALE_CHANGED); 14445 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 14446 broadcastIntentLocked(null, null, intent, 14447 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 14448 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 14449 } 14450 } 14451 } 14452 14453 boolean kept = true; 14454 final ActivityStack mainStack = mStackSupervisor.getFocusedStack(); 14455 // mainStack is null during startup. 14456 if (mainStack != null) { 14457 if (changes != 0 && starting == null) { 14458 // If the configuration changed, and the caller is not already 14459 // in the process of starting an activity, then find the top 14460 // activity to check if its configuration needs to change. 14461 starting = mainStack.topRunningActivityLocked(null); 14462 } 14463 14464 if (starting != null) { 14465 kept = mainStack.ensureActivityConfigurationLocked(starting, changes); 14466 // And we need to make sure at this point that all other activities 14467 // are made visible with the correct configuration. 14468 mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes); 14469 } 14470 } 14471 14472 if (values != null && mWindowManager != null) { 14473 mWindowManager.setNewConfiguration(mConfiguration); 14474 } 14475 14476 return kept; 14477 } 14478 14479 /** 14480 * Decide based on the configuration whether we should shouw the ANR, 14481 * crash, etc dialogs. The idea is that if there is no affordnace to 14482 * press the on-screen buttons, we shouldn't show the dialog. 14483 * 14484 * A thought: SystemUI might also want to get told about this, the Power 14485 * dialog / global actions also might want different behaviors. 14486 */ 14487 private static final boolean shouldShowDialogs(Configuration config) { 14488 return !(config.keyboard == Configuration.KEYBOARD_NOKEYS 14489 && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH); 14490 } 14491 14492 /** 14493 * Save the locale. You must be inside a synchronized (this) block. 14494 */ 14495 private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) { 14496 if(isDiff) { 14497 SystemProperties.set("user.language", l.getLanguage()); 14498 SystemProperties.set("user.region", l.getCountry()); 14499 } 14500 14501 if(isPersist) { 14502 SystemProperties.set("persist.sys.language", l.getLanguage()); 14503 SystemProperties.set("persist.sys.country", l.getCountry()); 14504 SystemProperties.set("persist.sys.localevar", l.getVariant()); 14505 } 14506 } 14507 14508 @Override 14509 public boolean targetTaskAffinityMatchesActivity(IBinder token, String destAffinity) { 14510 ActivityRecord srec = ActivityRecord.forToken(token); 14511 return srec != null && srec.task.affinity != null && 14512 srec.task.affinity.equals(destAffinity); 14513 } 14514 14515 public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode, 14516 Intent resultData) { 14517 14518 synchronized (this) { 14519 final ActivityStack stack = ActivityRecord.getStackLocked(token); 14520 if (stack != null) { 14521 return stack.navigateUpToLocked(token, destIntent, resultCode, resultData); 14522 } 14523 return false; 14524 } 14525 } 14526 14527 public int getLaunchedFromUid(IBinder activityToken) { 14528 ActivityRecord srec = ActivityRecord.forToken(activityToken); 14529 if (srec == null) { 14530 return -1; 14531 } 14532 return srec.launchedFromUid; 14533 } 14534 14535 public String getLaunchedFromPackage(IBinder activityToken) { 14536 ActivityRecord srec = ActivityRecord.forToken(activityToken); 14537 if (srec == null) { 14538 return null; 14539 } 14540 return srec.launchedFromPackage; 14541 } 14542 14543 // ========================================================= 14544 // LIFETIME MANAGEMENT 14545 // ========================================================= 14546 14547 // Returns which broadcast queue the app is the current [or imminent] receiver 14548 // on, or 'null' if the app is not an active broadcast recipient. 14549 private BroadcastQueue isReceivingBroadcast(ProcessRecord app) { 14550 BroadcastRecord r = app.curReceiver; 14551 if (r != null) { 14552 return r.queue; 14553 } 14554 14555 // It's not the current receiver, but it might be starting up to become one 14556 synchronized (this) { 14557 for (BroadcastQueue queue : mBroadcastQueues) { 14558 r = queue.mPendingBroadcast; 14559 if (r != null && r.curApp == app) { 14560 // found it; report which queue it's in 14561 return queue; 14562 } 14563 } 14564 } 14565 14566 return null; 14567 } 14568 14569 private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP, 14570 boolean doingAll, long now) { 14571 if (mAdjSeq == app.adjSeq) { 14572 // This adjustment has already been computed. 14573 return app.curRawAdj; 14574 } 14575 14576 if (app.thread == null) { 14577 app.adjSeq = mAdjSeq; 14578 app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 14579 app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 14580 return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ); 14581 } 14582 14583 app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN; 14584 app.adjSource = null; 14585 app.adjTarget = null; 14586 app.empty = false; 14587 app.cached = false; 14588 14589 final int activitiesSize = app.activities.size(); 14590 14591 if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) { 14592 // The max adjustment doesn't allow this app to be anything 14593 // below foreground, so it is not worth doing work for it. 14594 app.adjType = "fixed"; 14595 app.adjSeq = mAdjSeq; 14596 app.curRawAdj = app.maxAdj; 14597 app.foregroundActivities = false; 14598 app.keeping = true; 14599 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT; 14600 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT; 14601 // System processes can do UI, and when they do we want to have 14602 // them trim their memory after the user leaves the UI. To 14603 // facilitate this, here we need to determine whether or not it 14604 // is currently showing UI. 14605 app.systemNoUi = true; 14606 if (app == TOP_APP) { 14607 app.systemNoUi = false; 14608 } else if (activitiesSize > 0) { 14609 for (int j = 0; j < activitiesSize; j++) { 14610 final ActivityRecord r = app.activities.get(j); 14611 if (r.visible) { 14612 app.systemNoUi = false; 14613 } 14614 } 14615 } 14616 if (!app.systemNoUi) { 14617 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI; 14618 } 14619 return (app.curAdj=app.maxAdj); 14620 } 14621 14622 app.keeping = false; 14623 app.systemNoUi = false; 14624 14625 // Determine the importance of the process, starting with most 14626 // important to least, and assign an appropriate OOM adjustment. 14627 int adj; 14628 int schedGroup; 14629 int procState; 14630 boolean foregroundActivities = false; 14631 boolean interesting = false; 14632 BroadcastQueue queue; 14633 if (app == TOP_APP) { 14634 // The last app on the list is the foreground app. 14635 adj = ProcessList.FOREGROUND_APP_ADJ; 14636 schedGroup = Process.THREAD_GROUP_DEFAULT; 14637 app.adjType = "top-activity"; 14638 foregroundActivities = true; 14639 interesting = true; 14640 procState = ActivityManager.PROCESS_STATE_TOP; 14641 } else if (app.instrumentationClass != null) { 14642 // Don't want to kill running instrumentation. 14643 adj = ProcessList.FOREGROUND_APP_ADJ; 14644 schedGroup = Process.THREAD_GROUP_DEFAULT; 14645 app.adjType = "instrumentation"; 14646 interesting = true; 14647 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14648 } else if ((queue = isReceivingBroadcast(app)) != null) { 14649 // An app that is currently receiving a broadcast also 14650 // counts as being in the foreground for OOM killer purposes. 14651 // It's placed in a sched group based on the nature of the 14652 // broadcast as reflected by which queue it's active in. 14653 adj = ProcessList.FOREGROUND_APP_ADJ; 14654 schedGroup = (queue == mFgBroadcastQueue) 14655 ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 14656 app.adjType = "broadcast"; 14657 procState = ActivityManager.PROCESS_STATE_RECEIVER; 14658 } else if (app.executingServices.size() > 0) { 14659 // An app that is currently executing a service callback also 14660 // counts as being in the foreground. 14661 adj = ProcessList.FOREGROUND_APP_ADJ; 14662 schedGroup = app.execServicesFg ? 14663 Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 14664 app.adjType = "exec-service"; 14665 procState = ActivityManager.PROCESS_STATE_SERVICE; 14666 //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app); 14667 } else { 14668 // As far as we know the process is empty. We may change our mind later. 14669 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 14670 // At this point we don't actually know the adjustment. Use the cached adj 14671 // value that the caller wants us to. 14672 adj = cachedAdj; 14673 procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 14674 app.cached = true; 14675 app.empty = true; 14676 app.adjType = "cch-empty"; 14677 } 14678 14679 // Examine all activities if not already foreground. 14680 if (!foregroundActivities && activitiesSize > 0) { 14681 for (int j = 0; j < activitiesSize; j++) { 14682 final ActivityRecord r = app.activities.get(j); 14683 if (r.app != app) { 14684 Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc " 14685 + app + "?!?"); 14686 continue; 14687 } 14688 if (r.visible) { 14689 // App has a visible activity; only upgrade adjustment. 14690 if (adj > ProcessList.VISIBLE_APP_ADJ) { 14691 adj = ProcessList.VISIBLE_APP_ADJ; 14692 app.adjType = "visible"; 14693 } 14694 if (procState > ActivityManager.PROCESS_STATE_TOP) { 14695 procState = ActivityManager.PROCESS_STATE_TOP; 14696 } 14697 schedGroup = Process.THREAD_GROUP_DEFAULT; 14698 app.cached = false; 14699 app.empty = false; 14700 foregroundActivities = true; 14701 break; 14702 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) { 14703 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14704 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 14705 app.adjType = "pausing"; 14706 } 14707 if (procState > ActivityManager.PROCESS_STATE_TOP) { 14708 procState = ActivityManager.PROCESS_STATE_TOP; 14709 } 14710 schedGroup = Process.THREAD_GROUP_DEFAULT; 14711 app.cached = false; 14712 app.empty = false; 14713 foregroundActivities = true; 14714 } else if (r.state == ActivityState.STOPPING) { 14715 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14716 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 14717 app.adjType = "stopping"; 14718 } 14719 // For the process state, we will at this point consider the 14720 // process to be cached. It will be cached either as an activity 14721 // or empty depending on whether the activity is finishing. We do 14722 // this so that we can treat the process as cached for purposes of 14723 // memory trimming (determing current memory level, trim command to 14724 // send to process) since there can be an arbitrary number of stopping 14725 // processes and they should soon all go into the cached state. 14726 if (!r.finishing) { 14727 if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 14728 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 14729 } 14730 } 14731 app.cached = false; 14732 app.empty = false; 14733 foregroundActivities = true; 14734 } else { 14735 if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 14736 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 14737 app.adjType = "cch-act"; 14738 } 14739 } 14740 } 14741 } 14742 14743 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14744 if (app.foregroundServices) { 14745 // The user is aware of this app, so make it visible. 14746 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 14747 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14748 app.cached = false; 14749 app.adjType = "fg-service"; 14750 schedGroup = Process.THREAD_GROUP_DEFAULT; 14751 } else if (app.forcingToForeground != null) { 14752 // The user is aware of this app, so make it visible. 14753 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 14754 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14755 app.cached = false; 14756 app.adjType = "force-fg"; 14757 app.adjSource = app.forcingToForeground; 14758 schedGroup = Process.THREAD_GROUP_DEFAULT; 14759 } 14760 } 14761 14762 if (app.foregroundServices) { 14763 interesting = true; 14764 } 14765 14766 if (app == mHeavyWeightProcess) { 14767 if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) { 14768 // We don't want to kill the current heavy-weight process. 14769 adj = ProcessList.HEAVY_WEIGHT_APP_ADJ; 14770 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 14771 app.cached = false; 14772 app.adjType = "heavy"; 14773 } 14774 if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) { 14775 procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT; 14776 } 14777 } 14778 14779 if (app == mHomeProcess) { 14780 if (adj > ProcessList.HOME_APP_ADJ) { 14781 // This process is hosting what we currently consider to be the 14782 // home app, so we don't want to let it go into the background. 14783 adj = ProcessList.HOME_APP_ADJ; 14784 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 14785 app.cached = false; 14786 app.adjType = "home"; 14787 } 14788 if (procState > ActivityManager.PROCESS_STATE_HOME) { 14789 procState = ActivityManager.PROCESS_STATE_HOME; 14790 } 14791 } 14792 14793 if (app == mPreviousProcess && app.activities.size() > 0) { 14794 if (adj > ProcessList.PREVIOUS_APP_ADJ) { 14795 // This was the previous process that showed UI to the user. 14796 // We want to try to keep it around more aggressively, to give 14797 // a good experience around switching between two apps. 14798 adj = ProcessList.PREVIOUS_APP_ADJ; 14799 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 14800 app.cached = false; 14801 app.adjType = "previous"; 14802 } 14803 if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) { 14804 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY; 14805 } 14806 } 14807 14808 if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj 14809 + " reason=" + app.adjType); 14810 14811 // By default, we use the computed adjustment. It may be changed if 14812 // there are applications dependent on our services or providers, but 14813 // this gives us a baseline and makes sure we don't get into an 14814 // infinite recursion. 14815 app.adjSeq = mAdjSeq; 14816 app.curRawAdj = adj; 14817 app.hasStartedServices = false; 14818 14819 if (mBackupTarget != null && app == mBackupTarget.app) { 14820 // If possible we want to avoid killing apps while they're being backed up 14821 if (adj > ProcessList.BACKUP_APP_ADJ) { 14822 if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app); 14823 adj = ProcessList.BACKUP_APP_ADJ; 14824 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) { 14825 procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND; 14826 } 14827 app.adjType = "backup"; 14828 app.cached = false; 14829 } 14830 if (procState > ActivityManager.PROCESS_STATE_BACKUP) { 14831 procState = ActivityManager.PROCESS_STATE_BACKUP; 14832 } 14833 } 14834 14835 boolean mayBeTop = false; 14836 14837 for (int is = app.services.size()-1; 14838 is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 14839 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 14840 || procState > ActivityManager.PROCESS_STATE_TOP); 14841 is--) { 14842 ServiceRecord s = app.services.valueAt(is); 14843 if (s.startRequested) { 14844 app.hasStartedServices = true; 14845 if (procState > ActivityManager.PROCESS_STATE_SERVICE) { 14846 procState = ActivityManager.PROCESS_STATE_SERVICE; 14847 } 14848 if (app.hasShownUi && app != mHomeProcess) { 14849 // If this process has shown some UI, let it immediately 14850 // go to the LRU list because it may be pretty heavy with 14851 // UI stuff. We'll tag it with a label just to help 14852 // debug and understand what is going on. 14853 if (adj > ProcessList.SERVICE_ADJ) { 14854 app.adjType = "cch-started-ui-services"; 14855 } 14856 } else { 14857 if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) { 14858 // This service has seen some activity within 14859 // recent memory, so we will keep its process ahead 14860 // of the background processes. 14861 if (adj > ProcessList.SERVICE_ADJ) { 14862 adj = ProcessList.SERVICE_ADJ; 14863 app.adjType = "started-services"; 14864 app.cached = false; 14865 } 14866 } 14867 // If we have let the service slide into the background 14868 // state, still have some text describing what it is doing 14869 // even though the service no longer has an impact. 14870 if (adj > ProcessList.SERVICE_ADJ) { 14871 app.adjType = "cch-started-services"; 14872 } 14873 } 14874 // Don't kill this process because it is doing work; it 14875 // has said it is doing work. 14876 app.keeping = true; 14877 } 14878 for (int conni = s.connections.size()-1; 14879 conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 14880 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 14881 || procState > ActivityManager.PROCESS_STATE_TOP); 14882 conni--) { 14883 ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni); 14884 for (int i = 0; 14885 i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ 14886 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 14887 || procState > ActivityManager.PROCESS_STATE_TOP); 14888 i++) { 14889 // XXX should compute this based on the max of 14890 // all connected clients. 14891 ConnectionRecord cr = clist.get(i); 14892 if (cr.binding.client == app) { 14893 // Binding to ourself is not interesting. 14894 continue; 14895 } 14896 if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) { 14897 ProcessRecord client = cr.binding.client; 14898 int clientAdj = computeOomAdjLocked(client, cachedAdj, 14899 TOP_APP, doingAll, now); 14900 int clientProcState = client.curProcState; 14901 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 14902 // If the other app is cached for any reason, for purposes here 14903 // we are going to consider it empty. The specific cached state 14904 // doesn't propagate except under certain conditions. 14905 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 14906 } 14907 String adjType = null; 14908 if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) { 14909 // Not doing bind OOM management, so treat 14910 // this guy more like a started service. 14911 if (app.hasShownUi && app != mHomeProcess) { 14912 // If this process has shown some UI, let it immediately 14913 // go to the LRU list because it may be pretty heavy with 14914 // UI stuff. We'll tag it with a label just to help 14915 // debug and understand what is going on. 14916 if (adj > clientAdj) { 14917 adjType = "cch-bound-ui-services"; 14918 } 14919 app.cached = false; 14920 clientAdj = adj; 14921 clientProcState = procState; 14922 } else { 14923 if (now >= (s.lastActivity 14924 + ActiveServices.MAX_SERVICE_INACTIVITY)) { 14925 // This service has not seen activity within 14926 // recent memory, so allow it to drop to the 14927 // LRU list if there is no other reason to keep 14928 // it around. We'll also tag it with a label just 14929 // to help debug and undertand what is going on. 14930 if (adj > clientAdj) { 14931 adjType = "cch-bound-services"; 14932 } 14933 clientAdj = adj; 14934 } 14935 } 14936 } 14937 if (adj > clientAdj) { 14938 // If this process has recently shown UI, and 14939 // the process that is binding to it is less 14940 // important than being visible, then we don't 14941 // care about the binding as much as we care 14942 // about letting this process get into the LRU 14943 // list to be killed and restarted if needed for 14944 // memory. 14945 if (app.hasShownUi && app != mHomeProcess 14946 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14947 adjType = "cch-bound-ui-services"; 14948 } else { 14949 if ((cr.flags&(Context.BIND_ABOVE_CLIENT 14950 |Context.BIND_IMPORTANT)) != 0) { 14951 adj = clientAdj; 14952 } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0 14953 && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ 14954 && adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14955 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 14956 } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) { 14957 adj = clientAdj; 14958 } else { 14959 if (adj > ProcessList.VISIBLE_APP_ADJ) { 14960 adj = ProcessList.VISIBLE_APP_ADJ; 14961 } 14962 } 14963 if (!client.cached) { 14964 app.cached = false; 14965 } 14966 if (client.keeping) { 14967 app.keeping = true; 14968 } 14969 adjType = "service"; 14970 } 14971 } 14972 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 14973 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 14974 schedGroup = Process.THREAD_GROUP_DEFAULT; 14975 } 14976 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) { 14977 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) { 14978 // Special handling of clients who are in the top state. 14979 // We *may* want to consider this process to be in the 14980 // top state as well, but only if there is not another 14981 // reason for it to be running. Being on the top is a 14982 // special state, meaning you are specifically running 14983 // for the current top app. If the process is already 14984 // running in the background for some other reason, it 14985 // is more important to continue considering it to be 14986 // in the background state. 14987 mayBeTop = true; 14988 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 14989 } else { 14990 // Special handling for above-top states (persistent 14991 // processes). These should not bring the current process 14992 // into the top state, since they are not on top. Instead 14993 // give them the best state after that. 14994 clientProcState = 14995 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14996 } 14997 } 14998 } else { 14999 if (clientProcState < 15000 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) { 15001 clientProcState = 15002 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND; 15003 } 15004 } 15005 if (procState > clientProcState) { 15006 procState = clientProcState; 15007 } 15008 if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 15009 && (cr.flags&Context.BIND_SHOWING_UI) != 0) { 15010 app.pendingUiClean = true; 15011 } 15012 if (adjType != null) { 15013 app.adjType = adjType; 15014 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 15015 .REASON_SERVICE_IN_USE; 15016 app.adjSource = cr.binding.client; 15017 app.adjSourceOom = clientAdj; 15018 app.adjTarget = s.name; 15019 } 15020 } 15021 if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) { 15022 app.treatLikeActivity = true; 15023 } 15024 final ActivityRecord a = cr.activity; 15025 if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) { 15026 if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ && 15027 (a.visible || a.state == ActivityState.RESUMED 15028 || a.state == ActivityState.PAUSING)) { 15029 adj = ProcessList.FOREGROUND_APP_ADJ; 15030 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 15031 schedGroup = Process.THREAD_GROUP_DEFAULT; 15032 } 15033 app.cached = false; 15034 app.adjType = "service"; 15035 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 15036 .REASON_SERVICE_IN_USE; 15037 app.adjSource = a; 15038 app.adjSourceOom = adj; 15039 app.adjTarget = s.name; 15040 } 15041 } 15042 } 15043 } 15044 } 15045 15046 for (int provi = app.pubProviders.size()-1; 15047 provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 15048 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 15049 || procState > ActivityManager.PROCESS_STATE_TOP); 15050 provi--) { 15051 ContentProviderRecord cpr = app.pubProviders.valueAt(provi); 15052 for (int i = cpr.connections.size()-1; 15053 i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 15054 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 15055 || procState > ActivityManager.PROCESS_STATE_TOP); 15056 i--) { 15057 ContentProviderConnection conn = cpr.connections.get(i); 15058 ProcessRecord client = conn.client; 15059 if (client == app) { 15060 // Being our own client is not interesting. 15061 continue; 15062 } 15063 int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now); 15064 int clientProcState = client.curProcState; 15065 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 15066 // If the other app is cached for any reason, for purposes here 15067 // we are going to consider it empty. 15068 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 15069 } 15070 if (adj > clientAdj) { 15071 if (app.hasShownUi && app != mHomeProcess 15072 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 15073 app.adjType = "cch-ui-provider"; 15074 } else { 15075 adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ 15076 ? clientAdj : ProcessList.FOREGROUND_APP_ADJ; 15077 app.adjType = "provider"; 15078 } 15079 app.cached &= client.cached; 15080 app.keeping |= client.keeping; 15081 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 15082 .REASON_PROVIDER_IN_USE; 15083 app.adjSource = client; 15084 app.adjSourceOom = clientAdj; 15085 app.adjTarget = cpr.name; 15086 } 15087 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) { 15088 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) { 15089 // Special handling of clients who are in the top state. 15090 // We *may* want to consider this process to be in the 15091 // top state as well, but only if there is not another 15092 // reason for it to be running. Being on the top is a 15093 // special state, meaning you are specifically running 15094 // for the current top app. If the process is already 15095 // running in the background for some other reason, it 15096 // is more important to continue considering it to be 15097 // in the background state. 15098 mayBeTop = true; 15099 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 15100 } else { 15101 // Special handling for above-top states (persistent 15102 // processes). These should not bring the current process 15103 // into the top state, since they are not on top. Instead 15104 // give them the best state after that. 15105 clientProcState = 15106 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 15107 } 15108 } 15109 if (procState > clientProcState) { 15110 procState = clientProcState; 15111 } 15112 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 15113 schedGroup = Process.THREAD_GROUP_DEFAULT; 15114 } 15115 } 15116 // If the provider has external (non-framework) process 15117 // dependencies, ensure that its adjustment is at least 15118 // FOREGROUND_APP_ADJ. 15119 if (cpr.hasExternalProcessHandles()) { 15120 if (adj > ProcessList.FOREGROUND_APP_ADJ) { 15121 adj = ProcessList.FOREGROUND_APP_ADJ; 15122 schedGroup = Process.THREAD_GROUP_DEFAULT; 15123 app.cached = false; 15124 app.keeping = true; 15125 app.adjType = "provider"; 15126 app.adjTarget = cpr.name; 15127 } 15128 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) { 15129 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 15130 } 15131 } 15132 } 15133 15134 if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) { 15135 // A client of one of our services or providers is in the top state. We 15136 // *may* want to be in the top state, but not if we are already running in 15137 // the background for some other reason. For the decision here, we are going 15138 // to pick out a few specific states that we want to remain in when a client 15139 // is top (states that tend to be longer-term) and otherwise allow it to go 15140 // to the top state. 15141 switch (procState) { 15142 case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND: 15143 case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND: 15144 case ActivityManager.PROCESS_STATE_SERVICE: 15145 // These all are longer-term states, so pull them up to the top 15146 // of the background states, but not all the way to the top state. 15147 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 15148 break; 15149 default: 15150 // Otherwise, top is a better choice, so take it. 15151 procState = ActivityManager.PROCESS_STATE_TOP; 15152 break; 15153 } 15154 } 15155 15156 if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) { 15157 if (app.hasClientActivities) { 15158 // This is a cached process, but with client activities. Mark it so. 15159 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT; 15160 app.adjType = "cch-client-act"; 15161 } else if (app.treatLikeActivity) { 15162 // This is a cached process, but somebody wants us to treat it like it has 15163 // an activity, okay! 15164 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 15165 app.adjType = "cch-as-act"; 15166 } 15167 } 15168 15169 if (adj == ProcessList.SERVICE_ADJ) { 15170 if (doingAll) { 15171 app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3); 15172 mNewNumServiceProcs++; 15173 //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb); 15174 if (!app.serviceb) { 15175 // This service isn't far enough down on the LRU list to 15176 // normally be a B service, but if we are low on RAM and it 15177 // is large we want to force it down since we would prefer to 15178 // keep launcher over it. 15179 if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL 15180 && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) { 15181 app.serviceHighRam = true; 15182 app.serviceb = true; 15183 //Slog.i(TAG, "ADJ " + app + " high ram!"); 15184 } else { 15185 mNewNumAServiceProcs++; 15186 //Slog.i(TAG, "ADJ " + app + " not high ram!"); 15187 } 15188 } else { 15189 app.serviceHighRam = false; 15190 } 15191 } 15192 if (app.serviceb) { 15193 adj = ProcessList.SERVICE_B_ADJ; 15194 } 15195 } 15196 15197 app.curRawAdj = adj; 15198 15199 //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid + 15200 // " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj); 15201 if (adj > app.maxAdj) { 15202 adj = app.maxAdj; 15203 if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 15204 schedGroup = Process.THREAD_GROUP_DEFAULT; 15205 } 15206 } 15207 if (adj < ProcessList.CACHED_APP_MIN_ADJ) { 15208 app.keeping = true; 15209 } 15210 15211 // Do final modification to adj. Everything we do between here and applying 15212 // the final setAdj must be done in this function, because we will also use 15213 // it when computing the final cached adj later. Note that we don't need to 15214 // worry about this for max adj above, since max adj will always be used to 15215 // keep it out of the cached vaues. 15216 app.curAdj = app.modifyRawOomAdj(adj); 15217 app.curSchedGroup = schedGroup; 15218 app.curProcState = procState; 15219 app.foregroundActivities = foregroundActivities; 15220 15221 return app.curRawAdj; 15222 } 15223 15224 /** 15225 * Schedule PSS collection of a process. 15226 */ 15227 void requestPssLocked(ProcessRecord proc, int procState) { 15228 if (mPendingPssProcesses.contains(proc)) { 15229 return; 15230 } 15231 if (mPendingPssProcesses.size() == 0) { 15232 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG); 15233 } 15234 if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc); 15235 proc.pssProcState = procState; 15236 mPendingPssProcesses.add(proc); 15237 } 15238 15239 /** 15240 * Schedule PSS collection of all processes. 15241 */ 15242 void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) { 15243 if (!always) { 15244 if (now < (mLastFullPssTime + 15245 (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) { 15246 return; 15247 } 15248 } 15249 if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs! memLowered=" + memLowered); 15250 mLastFullPssTime = now; 15251 mPendingPssProcesses.ensureCapacity(mLruProcesses.size()); 15252 mPendingPssProcesses.clear(); 15253 for (int i=mLruProcesses.size()-1; i>=0; i--) { 15254 ProcessRecord app = mLruProcesses.get(i); 15255 if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) { 15256 app.pssProcState = app.setProcState; 15257 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true, 15258 isSleeping(), now); 15259 mPendingPssProcesses.add(app); 15260 } 15261 } 15262 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG); 15263 } 15264 15265 /** 15266 * Ask a given process to GC right now. 15267 */ 15268 final void performAppGcLocked(ProcessRecord app) { 15269 try { 15270 app.lastRequestedGc = SystemClock.uptimeMillis(); 15271 if (app.thread != null) { 15272 if (app.reportLowMemory) { 15273 app.reportLowMemory = false; 15274 app.thread.scheduleLowMemory(); 15275 } else { 15276 app.thread.processInBackground(); 15277 } 15278 } 15279 } catch (Exception e) { 15280 // whatever. 15281 } 15282 } 15283 15284 /** 15285 * Returns true if things are idle enough to perform GCs. 15286 */ 15287 private final boolean canGcNowLocked() { 15288 boolean processingBroadcasts = false; 15289 for (BroadcastQueue q : mBroadcastQueues) { 15290 if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) { 15291 processingBroadcasts = true; 15292 } 15293 } 15294 return !processingBroadcasts 15295 && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle()); 15296 } 15297 15298 /** 15299 * Perform GCs on all processes that are waiting for it, but only 15300 * if things are idle. 15301 */ 15302 final void performAppGcsLocked() { 15303 final int N = mProcessesToGc.size(); 15304 if (N <= 0) { 15305 return; 15306 } 15307 if (canGcNowLocked()) { 15308 while (mProcessesToGc.size() > 0) { 15309 ProcessRecord proc = mProcessesToGc.remove(0); 15310 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) { 15311 if ((proc.lastRequestedGc+GC_MIN_INTERVAL) 15312 <= SystemClock.uptimeMillis()) { 15313 // To avoid spamming the system, we will GC processes one 15314 // at a time, waiting a few seconds between each. 15315 performAppGcLocked(proc); 15316 scheduleAppGcsLocked(); 15317 return; 15318 } else { 15319 // It hasn't been long enough since we last GCed this 15320 // process... put it in the list to wait for its time. 15321 addProcessToGcListLocked(proc); 15322 break; 15323 } 15324 } 15325 } 15326 15327 scheduleAppGcsLocked(); 15328 } 15329 } 15330 15331 /** 15332 * If all looks good, perform GCs on all processes waiting for them. 15333 */ 15334 final void performAppGcsIfAppropriateLocked() { 15335 if (canGcNowLocked()) { 15336 performAppGcsLocked(); 15337 return; 15338 } 15339 // Still not idle, wait some more. 15340 scheduleAppGcsLocked(); 15341 } 15342 15343 /** 15344 * Schedule the execution of all pending app GCs. 15345 */ 15346 final void scheduleAppGcsLocked() { 15347 mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG); 15348 15349 if (mProcessesToGc.size() > 0) { 15350 // Schedule a GC for the time to the next process. 15351 ProcessRecord proc = mProcessesToGc.get(0); 15352 Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG); 15353 15354 long when = proc.lastRequestedGc + GC_MIN_INTERVAL; 15355 long now = SystemClock.uptimeMillis(); 15356 if (when < (now+GC_TIMEOUT)) { 15357 when = now + GC_TIMEOUT; 15358 } 15359 mHandler.sendMessageAtTime(msg, when); 15360 } 15361 } 15362 15363 /** 15364 * Add a process to the array of processes waiting to be GCed. Keeps the 15365 * list in sorted order by the last GC time. The process can't already be 15366 * on the list. 15367 */ 15368 final void addProcessToGcListLocked(ProcessRecord proc) { 15369 boolean added = false; 15370 for (int i=mProcessesToGc.size()-1; i>=0; i--) { 15371 if (mProcessesToGc.get(i).lastRequestedGc < 15372 proc.lastRequestedGc) { 15373 added = true; 15374 mProcessesToGc.add(i+1, proc); 15375 break; 15376 } 15377 } 15378 if (!added) { 15379 mProcessesToGc.add(0, proc); 15380 } 15381 } 15382 15383 /** 15384 * Set up to ask a process to GC itself. This will either do it 15385 * immediately, or put it on the list of processes to gc the next 15386 * time things are idle. 15387 */ 15388 final void scheduleAppGcLocked(ProcessRecord app) { 15389 long now = SystemClock.uptimeMillis(); 15390 if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) { 15391 return; 15392 } 15393 if (!mProcessesToGc.contains(app)) { 15394 addProcessToGcListLocked(app); 15395 scheduleAppGcsLocked(); 15396 } 15397 } 15398 15399 final void checkExcessivePowerUsageLocked(boolean doKills) { 15400 updateCpuStatsNow(); 15401 15402 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 15403 boolean doWakeKills = doKills; 15404 boolean doCpuKills = doKills; 15405 if (mLastPowerCheckRealtime == 0) { 15406 doWakeKills = false; 15407 } 15408 if (mLastPowerCheckUptime == 0) { 15409 doCpuKills = false; 15410 } 15411 if (stats.isScreenOn()) { 15412 doWakeKills = false; 15413 } 15414 final long curRealtime = SystemClock.elapsedRealtime(); 15415 final long realtimeSince = curRealtime - mLastPowerCheckRealtime; 15416 final long curUptime = SystemClock.uptimeMillis(); 15417 final long uptimeSince = curUptime - mLastPowerCheckUptime; 15418 mLastPowerCheckRealtime = curRealtime; 15419 mLastPowerCheckUptime = curUptime; 15420 if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) { 15421 doWakeKills = false; 15422 } 15423 if (uptimeSince < CPU_MIN_CHECK_DURATION) { 15424 doCpuKills = false; 15425 } 15426 int i = mLruProcesses.size(); 15427 while (i > 0) { 15428 i--; 15429 ProcessRecord app = mLruProcesses.get(i); 15430 if (!app.keeping) { 15431 long wtime; 15432 synchronized (stats) { 15433 wtime = stats.getProcessWakeTime(app.info.uid, 15434 app.pid, curRealtime); 15435 } 15436 long wtimeUsed = wtime - app.lastWakeTime; 15437 long cputimeUsed = app.curCpuTime - app.lastCpuTime; 15438 if (DEBUG_POWER) { 15439 StringBuilder sb = new StringBuilder(128); 15440 sb.append("Wake for "); 15441 app.toShortString(sb); 15442 sb.append(": over "); 15443 TimeUtils.formatDuration(realtimeSince, sb); 15444 sb.append(" used "); 15445 TimeUtils.formatDuration(wtimeUsed, sb); 15446 sb.append(" ("); 15447 sb.append((wtimeUsed*100)/realtimeSince); 15448 sb.append("%)"); 15449 Slog.i(TAG, sb.toString()); 15450 sb.setLength(0); 15451 sb.append("CPU for "); 15452 app.toShortString(sb); 15453 sb.append(": over "); 15454 TimeUtils.formatDuration(uptimeSince, sb); 15455 sb.append(" used "); 15456 TimeUtils.formatDuration(cputimeUsed, sb); 15457 sb.append(" ("); 15458 sb.append((cputimeUsed*100)/uptimeSince); 15459 sb.append("%)"); 15460 Slog.i(TAG, sb.toString()); 15461 } 15462 // If a process has held a wake lock for more 15463 // than 50% of the time during this period, 15464 // that sounds bad. Kill! 15465 if (doWakeKills && realtimeSince > 0 15466 && ((wtimeUsed*100)/realtimeSince) >= 50) { 15467 synchronized (stats) { 15468 stats.reportExcessiveWakeLocked(app.info.uid, app.processName, 15469 realtimeSince, wtimeUsed); 15470 } 15471 killUnneededProcessLocked(app, "excessive wake held " + wtimeUsed 15472 + " during " + realtimeSince); 15473 app.baseProcessTracker.reportExcessiveWake(app.pkgList); 15474 } else if (doCpuKills && uptimeSince > 0 15475 && ((cputimeUsed*100)/uptimeSince) >= 50) { 15476 synchronized (stats) { 15477 stats.reportExcessiveCpuLocked(app.info.uid, app.processName, 15478 uptimeSince, cputimeUsed); 15479 } 15480 killUnneededProcessLocked(app, "excessive cpu " + cputimeUsed 15481 + " during " + uptimeSince); 15482 app.baseProcessTracker.reportExcessiveCpu(app.pkgList); 15483 } else { 15484 app.lastWakeTime = wtime; 15485 app.lastCpuTime = app.curCpuTime; 15486 } 15487 } 15488 } 15489 } 15490 15491 private final boolean applyOomAdjLocked(ProcessRecord app, boolean wasKeeping, 15492 ProcessRecord TOP_APP, boolean doingAll, long now) { 15493 boolean success = true; 15494 15495 if (app.curRawAdj != app.setRawAdj) { 15496 if (wasKeeping && !app.keeping) { 15497 // This app is no longer something we want to keep. Note 15498 // its current wake lock time to later know to kill it if 15499 // it is not behaving well. 15500 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 15501 synchronized (stats) { 15502 app.lastWakeTime = stats.getProcessWakeTime(app.info.uid, 15503 app.pid, SystemClock.elapsedRealtime()); 15504 } 15505 app.lastCpuTime = app.curCpuTime; 15506 } 15507 15508 app.setRawAdj = app.curRawAdj; 15509 } 15510 15511 int changes = 0; 15512 15513 if (app.curAdj != app.setAdj) { 15514 ProcessList.setOomAdj(app.pid, app.curAdj); 15515 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v( 15516 TAG, "Set " + app.pid + " " + app.processName + 15517 " adj " + app.curAdj + ": " + app.adjType); 15518 app.setAdj = app.curAdj; 15519 } 15520 15521 if (app.setSchedGroup != app.curSchedGroup) { 15522 app.setSchedGroup = app.curSchedGroup; 15523 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 15524 "Setting process group of " + app.processName 15525 + " to " + app.curSchedGroup); 15526 if (app.waitingToKill != null && 15527 app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 15528 killUnneededProcessLocked(app, app.waitingToKill); 15529 success = false; 15530 } else { 15531 if (true) { 15532 long oldId = Binder.clearCallingIdentity(); 15533 try { 15534 Process.setProcessGroup(app.pid, app.curSchedGroup); 15535 } catch (Exception e) { 15536 Slog.w(TAG, "Failed setting process group of " + app.pid 15537 + " to " + app.curSchedGroup); 15538 e.printStackTrace(); 15539 } finally { 15540 Binder.restoreCallingIdentity(oldId); 15541 } 15542 } else { 15543 if (app.thread != null) { 15544 try { 15545 app.thread.setSchedulingGroup(app.curSchedGroup); 15546 } catch (RemoteException e) { 15547 } 15548 } 15549 } 15550 Process.setSwappiness(app.pid, 15551 app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE); 15552 } 15553 } 15554 if (app.repForegroundActivities != app.foregroundActivities) { 15555 app.repForegroundActivities = app.foregroundActivities; 15556 changes |= ProcessChangeItem.CHANGE_ACTIVITIES; 15557 } 15558 if (app.repProcState != app.curProcState) { 15559 app.repProcState = app.curProcState; 15560 changes |= ProcessChangeItem.CHANGE_PROCESS_STATE; 15561 if (app.thread != null) { 15562 try { 15563 if (false) { 15564 //RuntimeException h = new RuntimeException("here"); 15565 Slog.i(TAG, "Sending new process state " + app.repProcState 15566 + " to " + app /*, h*/); 15567 } 15568 app.thread.setProcessState(app.repProcState); 15569 } catch (RemoteException e) { 15570 } 15571 } 15572 } 15573 if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState, 15574 app.setProcState)) { 15575 app.lastStateTime = now; 15576 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true, 15577 isSleeping(), now); 15578 if (DEBUG_PSS) Slog.d(TAG, "Process state change from " 15579 + ProcessList.makeProcStateString(app.setProcState) + " to " 15580 + ProcessList.makeProcStateString(app.curProcState) + " next pss in " 15581 + (app.nextPssTime-now) + ": " + app); 15582 } else { 15583 if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL) 15584 && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) { 15585 requestPssLocked(app, app.setProcState); 15586 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false, 15587 isSleeping(), now); 15588 } else if (false && DEBUG_PSS) { 15589 Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now)); 15590 } 15591 } 15592 if (app.setProcState != app.curProcState) { 15593 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 15594 "Proc state change of " + app.processName 15595 + " to " + app.curProcState); 15596 app.setProcState = app.curProcState; 15597 if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) { 15598 app.notCachedSinceIdle = false; 15599 } 15600 if (!doingAll) { 15601 setProcessTrackerState(app, mProcessStats.getMemFactorLocked(), now); 15602 } else { 15603 app.procStateChanged = true; 15604 } 15605 } 15606 15607 if (changes != 0) { 15608 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes); 15609 int i = mPendingProcessChanges.size()-1; 15610 ProcessChangeItem item = null; 15611 while (i >= 0) { 15612 item = mPendingProcessChanges.get(i); 15613 if (item.pid == app.pid) { 15614 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item); 15615 break; 15616 } 15617 i--; 15618 } 15619 if (i < 0) { 15620 // No existing item in pending changes; need a new one. 15621 final int NA = mAvailProcessChanges.size(); 15622 if (NA > 0) { 15623 item = mAvailProcessChanges.remove(NA-1); 15624 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item); 15625 } else { 15626 item = new ProcessChangeItem(); 15627 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item); 15628 } 15629 item.changes = 0; 15630 item.pid = app.pid; 15631 item.uid = app.info.uid; 15632 if (mPendingProcessChanges.size() == 0) { 15633 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, 15634 "*** Enqueueing dispatch processes changed!"); 15635 mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget(); 15636 } 15637 mPendingProcessChanges.add(item); 15638 } 15639 item.changes |= changes; 15640 item.processState = app.repProcState; 15641 item.foregroundActivities = app.repForegroundActivities; 15642 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item " 15643 + Integer.toHexString(System.identityHashCode(item)) 15644 + " " + app.toShortString() + ": changes=" + item.changes 15645 + " procState=" + item.processState 15646 + " foreground=" + item.foregroundActivities 15647 + " type=" + app.adjType + " source=" + app.adjSource 15648 + " target=" + app.adjTarget); 15649 } 15650 15651 return success; 15652 } 15653 15654 private final void setProcessTrackerState(ProcessRecord proc, int memFactor, long now) { 15655 if (proc.thread != null && proc.baseProcessTracker != null) { 15656 proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList); 15657 } 15658 } 15659 15660 private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj, 15661 ProcessRecord TOP_APP, boolean doingAll, long now) { 15662 if (app.thread == null) { 15663 return false; 15664 } 15665 15666 final boolean wasKeeping = app.keeping; 15667 15668 computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now); 15669 15670 return applyOomAdjLocked(app, wasKeeping, TOP_APP, doingAll, now); 15671 } 15672 15673 final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground, 15674 boolean oomAdj) { 15675 if (isForeground != proc.foregroundServices) { 15676 proc.foregroundServices = isForeground; 15677 ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName, 15678 proc.info.uid); 15679 if (isForeground) { 15680 if (curProcs == null) { 15681 curProcs = new ArrayList<ProcessRecord>(); 15682 mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs); 15683 } 15684 if (!curProcs.contains(proc)) { 15685 curProcs.add(proc); 15686 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START, 15687 proc.info.packageName, proc.info.uid); 15688 } 15689 } else { 15690 if (curProcs != null) { 15691 if (curProcs.remove(proc)) { 15692 mBatteryStatsService.noteEvent( 15693 BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH, 15694 proc.info.packageName, proc.info.uid); 15695 if (curProcs.size() <= 0) { 15696 mForegroundPackages.remove(proc.info.packageName, proc.info.uid); 15697 } 15698 } 15699 } 15700 } 15701 if (oomAdj) { 15702 updateOomAdjLocked(); 15703 } 15704 } 15705 } 15706 15707 private final ActivityRecord resumedAppLocked() { 15708 ActivityRecord act = mStackSupervisor.resumedAppLocked(); 15709 String pkg; 15710 int uid; 15711 if (act != null && !act.sleeping) { 15712 pkg = act.packageName; 15713 uid = act.info.applicationInfo.uid; 15714 } else { 15715 pkg = null; 15716 uid = -1; 15717 } 15718 // Has the UID or resumed package name changed? 15719 if (uid != mCurResumedUid || (pkg != mCurResumedPackage 15720 && (pkg == null || !pkg.equals(mCurResumedPackage)))) { 15721 if (mCurResumedPackage != null) { 15722 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH, 15723 mCurResumedPackage, mCurResumedUid); 15724 } 15725 mCurResumedPackage = pkg; 15726 mCurResumedUid = uid; 15727 if (mCurResumedPackage != null) { 15728 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START, 15729 mCurResumedPackage, mCurResumedUid); 15730 } 15731 } 15732 return act; 15733 } 15734 15735 final boolean updateOomAdjLocked(ProcessRecord app) { 15736 final ActivityRecord TOP_ACT = resumedAppLocked(); 15737 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 15738 final boolean wasCached = app.cached; 15739 15740 mAdjSeq++; 15741 15742 // This is the desired cached adjusment we want to tell it to use. 15743 // If our app is currently cached, we know it, and that is it. Otherwise, 15744 // we don't know it yet, and it needs to now be cached we will then 15745 // need to do a complete oom adj. 15746 final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ 15747 ? app.curRawAdj : ProcessList.UNKNOWN_ADJ; 15748 boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false, 15749 SystemClock.uptimeMillis()); 15750 if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) { 15751 // Changed to/from cached state, so apps after it in the LRU 15752 // list may also be changed. 15753 updateOomAdjLocked(); 15754 } 15755 return success; 15756 } 15757 15758 final void updateOomAdjLocked() { 15759 final ActivityRecord TOP_ACT = resumedAppLocked(); 15760 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 15761 final long now = SystemClock.uptimeMillis(); 15762 final long oldTime = now - ProcessList.MAX_EMPTY_TIME; 15763 final int N = mLruProcesses.size(); 15764 15765 if (false) { 15766 RuntimeException e = new RuntimeException(); 15767 e.fillInStackTrace(); 15768 Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e); 15769 } 15770 15771 mAdjSeq++; 15772 mNewNumServiceProcs = 0; 15773 mNewNumAServiceProcs = 0; 15774 15775 final int emptyProcessLimit; 15776 final int cachedProcessLimit; 15777 if (mProcessLimit <= 0) { 15778 emptyProcessLimit = cachedProcessLimit = 0; 15779 } else if (mProcessLimit == 1) { 15780 emptyProcessLimit = 1; 15781 cachedProcessLimit = 0; 15782 } else { 15783 emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit); 15784 cachedProcessLimit = mProcessLimit - emptyProcessLimit; 15785 } 15786 15787 // Let's determine how many processes we have running vs. 15788 // how many slots we have for background processes; we may want 15789 // to put multiple processes in a slot of there are enough of 15790 // them. 15791 int numSlots = (ProcessList.CACHED_APP_MAX_ADJ 15792 - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2; 15793 int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs; 15794 if (numEmptyProcs > cachedProcessLimit) { 15795 // If there are more empty processes than our limit on cached 15796 // processes, then use the cached process limit for the factor. 15797 // This ensures that the really old empty processes get pushed 15798 // down to the bottom, so if we are running low on memory we will 15799 // have a better chance at keeping around more cached processes 15800 // instead of a gazillion empty processes. 15801 numEmptyProcs = cachedProcessLimit; 15802 } 15803 int emptyFactor = numEmptyProcs/numSlots; 15804 if (emptyFactor < 1) emptyFactor = 1; 15805 int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots; 15806 if (cachedFactor < 1) cachedFactor = 1; 15807 int stepCached = 0; 15808 int stepEmpty = 0; 15809 int numCached = 0; 15810 int numEmpty = 0; 15811 int numTrimming = 0; 15812 15813 mNumNonCachedProcs = 0; 15814 mNumCachedHiddenProcs = 0; 15815 15816 // First update the OOM adjustment for each of the 15817 // application processes based on their current state. 15818 int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ; 15819 int nextCachedAdj = curCachedAdj+1; 15820 int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ; 15821 int nextEmptyAdj = curEmptyAdj+2; 15822 for (int i=N-1; i>=0; i--) { 15823 ProcessRecord app = mLruProcesses.get(i); 15824 if (!app.killedByAm && app.thread != null) { 15825 app.procStateChanged = false; 15826 final boolean wasKeeping = app.keeping; 15827 computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now); 15828 15829 // If we haven't yet assigned the final cached adj 15830 // to the process, do that now. 15831 if (app.curAdj >= ProcessList.UNKNOWN_ADJ) { 15832 switch (app.curProcState) { 15833 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY: 15834 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: 15835 // This process is a cached process holding activities... 15836 // assign it the next cached value for that type, and then 15837 // step that cached level. 15838 app.curRawAdj = curCachedAdj; 15839 app.curAdj = app.modifyRawOomAdj(curCachedAdj); 15840 if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i 15841 + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj 15842 + ")"); 15843 if (curCachedAdj != nextCachedAdj) { 15844 stepCached++; 15845 if (stepCached >= cachedFactor) { 15846 stepCached = 0; 15847 curCachedAdj = nextCachedAdj; 15848 nextCachedAdj += 2; 15849 if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) { 15850 nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ; 15851 } 15852 } 15853 } 15854 break; 15855 default: 15856 // For everything else, assign next empty cached process 15857 // level and bump that up. Note that this means that 15858 // long-running services that have dropped down to the 15859 // cached level will be treated as empty (since their process 15860 // state is still as a service), which is what we want. 15861 app.curRawAdj = curEmptyAdj; 15862 app.curAdj = app.modifyRawOomAdj(curEmptyAdj); 15863 if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i 15864 + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj 15865 + ")"); 15866 if (curEmptyAdj != nextEmptyAdj) { 15867 stepEmpty++; 15868 if (stepEmpty >= emptyFactor) { 15869 stepEmpty = 0; 15870 curEmptyAdj = nextEmptyAdj; 15871 nextEmptyAdj += 2; 15872 if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) { 15873 nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ; 15874 } 15875 } 15876 } 15877 break; 15878 } 15879 } 15880 15881 applyOomAdjLocked(app, wasKeeping, TOP_APP, true, now); 15882 15883 // Count the number of process types. 15884 switch (app.curProcState) { 15885 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY: 15886 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: 15887 mNumCachedHiddenProcs++; 15888 numCached++; 15889 if (numCached > cachedProcessLimit) { 15890 killUnneededProcessLocked(app, "cached #" + numCached); 15891 } 15892 break; 15893 case ActivityManager.PROCESS_STATE_CACHED_EMPTY: 15894 if (numEmpty > ProcessList.TRIM_EMPTY_APPS 15895 && app.lastActivityTime < oldTime) { 15896 killUnneededProcessLocked(app, "empty for " 15897 + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime) 15898 / 1000) + "s"); 15899 } else { 15900 numEmpty++; 15901 if (numEmpty > emptyProcessLimit) { 15902 killUnneededProcessLocked(app, "empty #" + numEmpty); 15903 } 15904 } 15905 break; 15906 default: 15907 mNumNonCachedProcs++; 15908 break; 15909 } 15910 15911 if (app.isolated && app.services.size() <= 0) { 15912 // If this is an isolated process, and there are no 15913 // services running in it, then the process is no longer 15914 // needed. We agressively kill these because we can by 15915 // definition not re-use the same process again, and it is 15916 // good to avoid having whatever code was running in them 15917 // left sitting around after no longer needed. 15918 killUnneededProcessLocked(app, "isolated not needed"); 15919 } 15920 15921 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME 15922 && !app.killedByAm) { 15923 numTrimming++; 15924 } 15925 } 15926 } 15927 15928 mNumServiceProcs = mNewNumServiceProcs; 15929 15930 // Now determine the memory trimming level of background processes. 15931 // Unfortunately we need to start at the back of the list to do this 15932 // properly. We only do this if the number of background apps we 15933 // are managing to keep around is less than half the maximum we desire; 15934 // if we are keeping a good number around, we'll let them use whatever 15935 // memory they want. 15936 final int numCachedAndEmpty = numCached + numEmpty; 15937 int memFactor; 15938 if (numCached <= ProcessList.TRIM_CACHED_APPS 15939 && numEmpty <= ProcessList.TRIM_EMPTY_APPS) { 15940 if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) { 15941 memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL; 15942 } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) { 15943 memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW; 15944 } else { 15945 memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE; 15946 } 15947 } else { 15948 memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL; 15949 } 15950 // We always allow the memory level to go up (better). We only allow it to go 15951 // down if we are in a state where that is allowed, *and* the total number of processes 15952 // has gone down since last time. 15953 if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel 15954 + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size() 15955 + " last=" + mLastNumProcesses); 15956 if (memFactor > mLastMemoryLevel) { 15957 if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) { 15958 memFactor = mLastMemoryLevel; 15959 if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!"); 15960 } 15961 } 15962 mLastMemoryLevel = memFactor; 15963 mLastNumProcesses = mLruProcesses.size(); 15964 boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now); 15965 final int trackerMemFactor = mProcessStats.getMemFactorLocked(); 15966 if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) { 15967 if (mLowRamStartTime == 0) { 15968 mLowRamStartTime = now; 15969 } 15970 int step = 0; 15971 int fgTrimLevel; 15972 switch (memFactor) { 15973 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL: 15974 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL; 15975 break; 15976 case ProcessStats.ADJ_MEM_FACTOR_LOW: 15977 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW; 15978 break; 15979 default: 15980 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE; 15981 break; 15982 } 15983 int factor = numTrimming/3; 15984 int minFactor = 2; 15985 if (mHomeProcess != null) minFactor++; 15986 if (mPreviousProcess != null) minFactor++; 15987 if (factor < minFactor) factor = minFactor; 15988 int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE; 15989 for (int i=N-1; i>=0; i--) { 15990 ProcessRecord app = mLruProcesses.get(i); 15991 if (allChanged || app.procStateChanged) { 15992 setProcessTrackerState(app, trackerMemFactor, now); 15993 app.procStateChanged = false; 15994 } 15995 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME 15996 && !app.killedByAm) { 15997 if (app.trimMemoryLevel < curLevel && app.thread != null) { 15998 try { 15999 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 16000 "Trimming memory of " + app.processName 16001 + " to " + curLevel); 16002 app.thread.scheduleTrimMemory(curLevel); 16003 } catch (RemoteException e) { 16004 } 16005 if (false) { 16006 // For now we won't do this; our memory trimming seems 16007 // to be good enough at this point that destroying 16008 // activities causes more harm than good. 16009 if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE 16010 && app != mHomeProcess && app != mPreviousProcess) { 16011 // Need to do this on its own message because the stack may not 16012 // be in a consistent state at this point. 16013 // For these apps we will also finish their activities 16014 // to help them free memory. 16015 mStackSupervisor.scheduleDestroyAllActivities(app, "trim"); 16016 } 16017 } 16018 } 16019 app.trimMemoryLevel = curLevel; 16020 step++; 16021 if (step >= factor) { 16022 step = 0; 16023 switch (curLevel) { 16024 case ComponentCallbacks2.TRIM_MEMORY_COMPLETE: 16025 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE; 16026 break; 16027 case ComponentCallbacks2.TRIM_MEMORY_MODERATE: 16028 curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 16029 break; 16030 } 16031 } 16032 } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) { 16033 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND 16034 && app.thread != null) { 16035 try { 16036 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 16037 "Trimming memory of heavy-weight " + app.processName 16038 + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 16039 app.thread.scheduleTrimMemory( 16040 ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 16041 } catch (RemoteException e) { 16042 } 16043 } 16044 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 16045 } else { 16046 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 16047 || app.systemNoUi) && app.pendingUiClean) { 16048 // If this application is now in the background and it 16049 // had done UI, then give it the special trim level to 16050 // have it free UI resources. 16051 final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN; 16052 if (app.trimMemoryLevel < level && app.thread != null) { 16053 try { 16054 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 16055 "Trimming memory of bg-ui " + app.processName 16056 + " to " + level); 16057 app.thread.scheduleTrimMemory(level); 16058 } catch (RemoteException e) { 16059 } 16060 } 16061 app.pendingUiClean = false; 16062 } 16063 if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) { 16064 try { 16065 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 16066 "Trimming memory of fg " + app.processName 16067 + " to " + fgTrimLevel); 16068 app.thread.scheduleTrimMemory(fgTrimLevel); 16069 } catch (RemoteException e) { 16070 } 16071 } 16072 app.trimMemoryLevel = fgTrimLevel; 16073 } 16074 } 16075 } else { 16076 if (mLowRamStartTime != 0) { 16077 mLowRamTimeSinceLastIdle += now - mLowRamStartTime; 16078 mLowRamStartTime = 0; 16079 } 16080 for (int i=N-1; i>=0; i--) { 16081 ProcessRecord app = mLruProcesses.get(i); 16082 if (allChanged || app.procStateChanged) { 16083 setProcessTrackerState(app, trackerMemFactor, now); 16084 app.procStateChanged = false; 16085 } 16086 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 16087 || app.systemNoUi) && app.pendingUiClean) { 16088 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN 16089 && app.thread != null) { 16090 try { 16091 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 16092 "Trimming memory of ui hidden " + app.processName 16093 + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 16094 app.thread.scheduleTrimMemory( 16095 ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 16096 } catch (RemoteException e) { 16097 } 16098 } 16099 app.pendingUiClean = false; 16100 } 16101 app.trimMemoryLevel = 0; 16102 } 16103 } 16104 16105 if (mAlwaysFinishActivities) { 16106 // Need to do this on its own message because the stack may not 16107 // be in a consistent state at this point. 16108 mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish"); 16109 } 16110 16111 if (allChanged) { 16112 requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered()); 16113 } 16114 16115 if (mProcessStats.shouldWriteNowLocked(now)) { 16116 mHandler.post(new Runnable() { 16117 @Override public void run() { 16118 synchronized (ActivityManagerService.this) { 16119 mProcessStats.writeStateAsyncLocked(); 16120 } 16121 } 16122 }); 16123 } 16124 16125 if (DEBUG_OOM_ADJ) { 16126 Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms"); 16127 } 16128 } 16129 16130 final void trimApplications() { 16131 synchronized (this) { 16132 int i; 16133 16134 // First remove any unused application processes whose package 16135 // has been removed. 16136 for (i=mRemovedProcesses.size()-1; i>=0; i--) { 16137 final ProcessRecord app = mRemovedProcesses.get(i); 16138 if (app.activities.size() == 0 16139 && app.curReceiver == null && app.services.size() == 0) { 16140 Slog.i( 16141 TAG, "Exiting empty application process " 16142 + app.processName + " (" 16143 + (app.thread != null ? app.thread.asBinder() : null) 16144 + ")\n"); 16145 if (app.pid > 0 && app.pid != MY_PID) { 16146 EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid, 16147 app.processName, app.setAdj, "empty"); 16148 app.killedByAm = true; 16149 Process.killProcessQuiet(app.pid); 16150 } else { 16151 try { 16152 app.thread.scheduleExit(); 16153 } catch (Exception e) { 16154 // Ignore exceptions. 16155 } 16156 } 16157 cleanUpApplicationRecordLocked(app, false, true, -1); 16158 mRemovedProcesses.remove(i); 16159 16160 if (app.persistent) { 16161 if (app.persistent) { 16162 addAppLocked(app.info, false); 16163 } 16164 } 16165 } 16166 } 16167 16168 // Now update the oom adj for all processes. 16169 updateOomAdjLocked(); 16170 } 16171 } 16172 16173 /** This method sends the specified signal to each of the persistent apps */ 16174 public void signalPersistentProcesses(int sig) throws RemoteException { 16175 if (sig != Process.SIGNAL_USR1) { 16176 throw new SecurityException("Only SIGNAL_USR1 is allowed"); 16177 } 16178 16179 synchronized (this) { 16180 if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES) 16181 != PackageManager.PERMISSION_GRANTED) { 16182 throw new SecurityException("Requires permission " 16183 + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES); 16184 } 16185 16186 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 16187 ProcessRecord r = mLruProcesses.get(i); 16188 if (r.thread != null && r.persistent) { 16189 Process.sendSignal(r.pid, sig); 16190 } 16191 } 16192 } 16193 } 16194 16195 private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) { 16196 if (proc == null || proc == mProfileProc) { 16197 proc = mProfileProc; 16198 path = mProfileFile; 16199 profileType = mProfileType; 16200 clearProfilerLocked(); 16201 } 16202 if (proc == null) { 16203 return; 16204 } 16205 try { 16206 proc.thread.profilerControl(false, path, null, profileType); 16207 } catch (RemoteException e) { 16208 throw new IllegalStateException("Process disappeared"); 16209 } 16210 } 16211 16212 private void clearProfilerLocked() { 16213 if (mProfileFd != null) { 16214 try { 16215 mProfileFd.close(); 16216 } catch (IOException e) { 16217 } 16218 } 16219 mProfileApp = null; 16220 mProfileProc = null; 16221 mProfileFile = null; 16222 mProfileType = 0; 16223 mAutoStopProfiler = false; 16224 } 16225 16226 public boolean profileControl(String process, int userId, boolean start, 16227 String path, ParcelFileDescriptor fd, int profileType) throws RemoteException { 16228 16229 try { 16230 synchronized (this) { 16231 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 16232 // its own permission. 16233 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 16234 != PackageManager.PERMISSION_GRANTED) { 16235 throw new SecurityException("Requires permission " 16236 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 16237 } 16238 16239 if (start && fd == null) { 16240 throw new IllegalArgumentException("null fd"); 16241 } 16242 16243 ProcessRecord proc = null; 16244 if (process != null) { 16245 proc = findProcessLocked(process, userId, "profileControl"); 16246 } 16247 16248 if (start && (proc == null || proc.thread == null)) { 16249 throw new IllegalArgumentException("Unknown process: " + process); 16250 } 16251 16252 if (start) { 16253 stopProfilerLocked(null, null, 0); 16254 setProfileApp(proc.info, proc.processName, path, fd, false); 16255 mProfileProc = proc; 16256 mProfileType = profileType; 16257 try { 16258 fd = fd.dup(); 16259 } catch (IOException e) { 16260 fd = null; 16261 } 16262 proc.thread.profilerControl(start, path, fd, profileType); 16263 fd = null; 16264 mProfileFd = null; 16265 } else { 16266 stopProfilerLocked(proc, path, profileType); 16267 if (fd != null) { 16268 try { 16269 fd.close(); 16270 } catch (IOException e) { 16271 } 16272 } 16273 } 16274 16275 return true; 16276 } 16277 } catch (RemoteException e) { 16278 throw new IllegalStateException("Process disappeared"); 16279 } finally { 16280 if (fd != null) { 16281 try { 16282 fd.close(); 16283 } catch (IOException e) { 16284 } 16285 } 16286 } 16287 } 16288 16289 private ProcessRecord findProcessLocked(String process, int userId, String callName) { 16290 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 16291 userId, true, true, callName, null); 16292 ProcessRecord proc = null; 16293 try { 16294 int pid = Integer.parseInt(process); 16295 synchronized (mPidsSelfLocked) { 16296 proc = mPidsSelfLocked.get(pid); 16297 } 16298 } catch (NumberFormatException e) { 16299 } 16300 16301 if (proc == null) { 16302 ArrayMap<String, SparseArray<ProcessRecord>> all 16303 = mProcessNames.getMap(); 16304 SparseArray<ProcessRecord> procs = all.get(process); 16305 if (procs != null && procs.size() > 0) { 16306 proc = procs.valueAt(0); 16307 if (userId != UserHandle.USER_ALL && proc.userId != userId) { 16308 for (int i=1; i<procs.size(); i++) { 16309 ProcessRecord thisProc = procs.valueAt(i); 16310 if (thisProc.userId == userId) { 16311 proc = thisProc; 16312 break; 16313 } 16314 } 16315 } 16316 } 16317 } 16318 16319 return proc; 16320 } 16321 16322 public boolean dumpHeap(String process, int userId, boolean managed, 16323 String path, ParcelFileDescriptor fd) throws RemoteException { 16324 16325 try { 16326 synchronized (this) { 16327 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 16328 // its own permission (same as profileControl). 16329 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 16330 != PackageManager.PERMISSION_GRANTED) { 16331 throw new SecurityException("Requires permission " 16332 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 16333 } 16334 16335 if (fd == null) { 16336 throw new IllegalArgumentException("null fd"); 16337 } 16338 16339 ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap"); 16340 if (proc == null || proc.thread == null) { 16341 throw new IllegalArgumentException("Unknown process: " + process); 16342 } 16343 16344 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 16345 if (!isDebuggable) { 16346 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 16347 throw new SecurityException("Process not debuggable: " + proc); 16348 } 16349 } 16350 16351 proc.thread.dumpHeap(managed, path, fd); 16352 fd = null; 16353 return true; 16354 } 16355 } catch (RemoteException e) { 16356 throw new IllegalStateException("Process disappeared"); 16357 } finally { 16358 if (fd != null) { 16359 try { 16360 fd.close(); 16361 } catch (IOException e) { 16362 } 16363 } 16364 } 16365 } 16366 16367 /** In this method we try to acquire our lock to make sure that we have not deadlocked */ 16368 public void monitor() { 16369 synchronized (this) { } 16370 } 16371 16372 void onCoreSettingsChange(Bundle settings) { 16373 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 16374 ProcessRecord processRecord = mLruProcesses.get(i); 16375 try { 16376 if (processRecord.thread != null) { 16377 processRecord.thread.setCoreSettings(settings); 16378 } 16379 } catch (RemoteException re) { 16380 /* ignore */ 16381 } 16382 } 16383 } 16384 16385 // Multi-user methods 16386 16387 /** 16388 * Start user, if its not already running, but don't bring it to foreground. 16389 */ 16390 @Override 16391 public boolean startUserInBackground(final int userId) { 16392 return startUser(userId, /* foreground */ false); 16393 } 16394 16395 /** 16396 * Refreshes the list of users related to the current user when either a 16397 * user switch happens or when a new related user is started in the 16398 * background. 16399 */ 16400 private void updateCurrentProfileIdsLocked() { 16401 final List<UserInfo> profiles = getUserManagerLocked().getProfiles( 16402 mCurrentUserId, false /* enabledOnly */); 16403 int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null 16404 for (int i = 0; i < currentProfileIds.length; i++) { 16405 currentProfileIds[i] = profiles.get(i).id; 16406 } 16407 mCurrentProfileIds = currentProfileIds; 16408 } 16409 16410 private Set getProfileIdsLocked(int userId) { 16411 Set userIds = new HashSet<Integer>(); 16412 final List<UserInfo> profiles = getUserManagerLocked().getProfiles( 16413 userId, false /* enabledOnly */); 16414 for (UserInfo user : profiles) { 16415 userIds.add(Integer.valueOf(user.id)); 16416 } 16417 return userIds; 16418 } 16419 16420 @Override 16421 public boolean switchUser(final int userId) { 16422 return startUser(userId, /* foregound */ true); 16423 } 16424 16425 private boolean startUser(final int userId, boolean foreground) { 16426 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 16427 != PackageManager.PERMISSION_GRANTED) { 16428 String msg = "Permission Denial: switchUser() from pid=" 16429 + Binder.getCallingPid() 16430 + ", uid=" + Binder.getCallingUid() 16431 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 16432 Slog.w(TAG, msg); 16433 throw new SecurityException(msg); 16434 } 16435 16436 if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground); 16437 16438 final long ident = Binder.clearCallingIdentity(); 16439 try { 16440 synchronized (this) { 16441 final int oldUserId = mCurrentUserId; 16442 if (oldUserId == userId) { 16443 return true; 16444 } 16445 16446 mStackSupervisor.setLockTaskModeLocked(null); 16447 16448 final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId); 16449 if (userInfo == null) { 16450 Slog.w(TAG, "No user info for user #" + userId); 16451 return false; 16452 } 16453 16454 if (foreground) { 16455 mWindowManager.startFreezingScreen(R.anim.screen_user_exit, 16456 R.anim.screen_user_enter); 16457 } 16458 16459 boolean needStart = false; 16460 16461 // If the user we are switching to is not currently started, then 16462 // we need to start it now. 16463 if (mStartedUsers.get(userId) == null) { 16464 mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false)); 16465 updateStartedUserArrayLocked(); 16466 needStart = true; 16467 } 16468 16469 final Integer userIdInt = Integer.valueOf(userId); 16470 mUserLru.remove(userIdInt); 16471 mUserLru.add(userIdInt); 16472 16473 if (foreground) { 16474 mCurrentUserId = userId; 16475 updateCurrentProfileIdsLocked(); 16476 mWindowManager.setCurrentUser(userId, mCurrentProfileIds); 16477 // Once the internal notion of the active user has switched, we lock the device 16478 // with the option to show the user switcher on the keyguard. 16479 mWindowManager.lockNow(null); 16480 } else { 16481 final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId); 16482 updateCurrentProfileIdsLocked(); 16483 mWindowManager.setCurrentProfileIds(mCurrentProfileIds); 16484 mUserLru.remove(currentUserIdInt); 16485 mUserLru.add(currentUserIdInt); 16486 } 16487 16488 final UserStartedState uss = mStartedUsers.get(userId); 16489 16490 // Make sure user is in the started state. If it is currently 16491 // stopping, we need to knock that off. 16492 if (uss.mState == UserStartedState.STATE_STOPPING) { 16493 // If we are stopping, we haven't sent ACTION_SHUTDOWN, 16494 // so we can just fairly silently bring the user back from 16495 // the almost-dead. 16496 uss.mState = UserStartedState.STATE_RUNNING; 16497 updateStartedUserArrayLocked(); 16498 needStart = true; 16499 } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) { 16500 // This means ACTION_SHUTDOWN has been sent, so we will 16501 // need to treat this as a new boot of the user. 16502 uss.mState = UserStartedState.STATE_BOOTING; 16503 updateStartedUserArrayLocked(); 16504 needStart = true; 16505 } 16506 16507 if (uss.mState == UserStartedState.STATE_BOOTING) { 16508 // Booting up a new user, need to tell system services about it. 16509 // Note that this is on the same handler as scheduling of broadcasts, 16510 // which is important because it needs to go first. 16511 mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId)); 16512 } 16513 16514 if (foreground) { 16515 mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId)); 16516 mHandler.removeMessages(REPORT_USER_SWITCH_MSG); 16517 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 16518 mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG, 16519 oldUserId, userId, uss)); 16520 mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG, 16521 oldUserId, userId, uss), USER_SWITCH_TIMEOUT); 16522 } 16523 16524 if (needStart) { 16525 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 16526 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16527 | Intent.FLAG_RECEIVER_FOREGROUND); 16528 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 16529 broadcastIntentLocked(null, null, intent, 16530 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 16531 false, false, MY_PID, Process.SYSTEM_UID, userId); 16532 } 16533 16534 if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) { 16535 if (userId != UserHandle.USER_OWNER) { 16536 Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE); 16537 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 16538 broadcastIntentLocked(null, null, intent, null, 16539 new IIntentReceiver.Stub() { 16540 public void performReceive(Intent intent, int resultCode, 16541 String data, Bundle extras, boolean ordered, 16542 boolean sticky, int sendingUser) { 16543 userInitialized(uss, userId); 16544 } 16545 }, 0, null, null, null, AppOpsManager.OP_NONE, 16546 true, false, MY_PID, Process.SYSTEM_UID, 16547 userId); 16548 uss.initializing = true; 16549 } else { 16550 getUserManagerLocked().makeInitialized(userInfo.id); 16551 } 16552 } 16553 16554 if (foreground) { 16555 boolean homeInFront = mStackSupervisor.switchUserLocked(userId, uss); 16556 if (homeInFront) { 16557 startHomeActivityLocked(userId); 16558 } else { 16559 mStackSupervisor.resumeTopActivitiesLocked(); 16560 } 16561 EventLogTags.writeAmSwitchUser(userId); 16562 getUserManagerLocked().userForeground(userId); 16563 sendUserSwitchBroadcastsLocked(oldUserId, userId); 16564 } else { 16565 mStackSupervisor.startBackgroundUserLocked(userId, uss); 16566 } 16567 16568 if (needStart) { 16569 Intent intent = new Intent(Intent.ACTION_USER_STARTING); 16570 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 16571 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 16572 broadcastIntentLocked(null, null, intent, 16573 null, new IIntentReceiver.Stub() { 16574 @Override 16575 public void performReceive(Intent intent, int resultCode, String data, 16576 Bundle extras, boolean ordered, boolean sticky, int sendingUser) 16577 throws RemoteException { 16578 } 16579 }, 0, null, null, 16580 android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 16581 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 16582 } 16583 } 16584 } finally { 16585 Binder.restoreCallingIdentity(ident); 16586 } 16587 16588 return true; 16589 } 16590 16591 void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) { 16592 long ident = Binder.clearCallingIdentity(); 16593 try { 16594 Intent intent; 16595 if (oldUserId >= 0) { 16596 intent = new Intent(Intent.ACTION_USER_BACKGROUND); 16597 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16598 | Intent.FLAG_RECEIVER_FOREGROUND); 16599 intent.putExtra(Intent.EXTRA_USER_HANDLE, oldUserId); 16600 broadcastIntentLocked(null, null, intent, 16601 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 16602 false, false, MY_PID, Process.SYSTEM_UID, oldUserId); 16603 } 16604 if (newUserId >= 0) { 16605 intent = new Intent(Intent.ACTION_USER_FOREGROUND); 16606 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16607 | Intent.FLAG_RECEIVER_FOREGROUND); 16608 intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId); 16609 broadcastIntentLocked(null, null, intent, 16610 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 16611 false, false, MY_PID, Process.SYSTEM_UID, newUserId); 16612 intent = new Intent(Intent.ACTION_USER_SWITCHED); 16613 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16614 | Intent.FLAG_RECEIVER_FOREGROUND); 16615 intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId); 16616 broadcastIntentLocked(null, null, intent, 16617 null, null, 0, null, null, 16618 android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE, 16619 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 16620 } 16621 } finally { 16622 Binder.restoreCallingIdentity(ident); 16623 } 16624 } 16625 16626 void dispatchUserSwitch(final UserStartedState uss, final int oldUserId, 16627 final int newUserId) { 16628 final int N = mUserSwitchObservers.beginBroadcast(); 16629 if (N > 0) { 16630 final IRemoteCallback callback = new IRemoteCallback.Stub() { 16631 int mCount = 0; 16632 @Override 16633 public void sendResult(Bundle data) throws RemoteException { 16634 synchronized (ActivityManagerService.this) { 16635 if (mCurUserSwitchCallback == this) { 16636 mCount++; 16637 if (mCount == N) { 16638 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 16639 } 16640 } 16641 } 16642 } 16643 }; 16644 synchronized (this) { 16645 uss.switching = true; 16646 mCurUserSwitchCallback = callback; 16647 } 16648 for (int i=0; i<N; i++) { 16649 try { 16650 mUserSwitchObservers.getBroadcastItem(i).onUserSwitching( 16651 newUserId, callback); 16652 } catch (RemoteException e) { 16653 } 16654 } 16655 } else { 16656 synchronized (this) { 16657 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 16658 } 16659 } 16660 mUserSwitchObservers.finishBroadcast(); 16661 } 16662 16663 void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 16664 synchronized (this) { 16665 Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId); 16666 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 16667 } 16668 } 16669 16670 void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) { 16671 mCurUserSwitchCallback = null; 16672 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 16673 mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG, 16674 oldUserId, newUserId, uss)); 16675 } 16676 16677 void userInitialized(UserStartedState uss, int newUserId) { 16678 completeSwitchAndInitalize(uss, newUserId, true, false); 16679 } 16680 16681 void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 16682 completeSwitchAndInitalize(uss, newUserId, false, true); 16683 } 16684 16685 void completeSwitchAndInitalize(UserStartedState uss, int newUserId, 16686 boolean clearInitializing, boolean clearSwitching) { 16687 boolean unfrozen = false; 16688 synchronized (this) { 16689 if (clearInitializing) { 16690 uss.initializing = false; 16691 getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier()); 16692 } 16693 if (clearSwitching) { 16694 uss.switching = false; 16695 } 16696 if (!uss.switching && !uss.initializing) { 16697 mWindowManager.stopFreezingScreen(); 16698 unfrozen = true; 16699 } 16700 } 16701 if (unfrozen) { 16702 final int N = mUserSwitchObservers.beginBroadcast(); 16703 for (int i=0; i<N; i++) { 16704 try { 16705 mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId); 16706 } catch (RemoteException e) { 16707 } 16708 } 16709 mUserSwitchObservers.finishBroadcast(); 16710 } 16711 } 16712 16713 void scheduleStartProfilesLocked() { 16714 if (!mHandler.hasMessages(START_PROFILES_MSG)) { 16715 mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG), 16716 DateUtils.SECOND_IN_MILLIS); 16717 } 16718 } 16719 16720 void startProfilesLocked() { 16721 if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked"); 16722 List<UserInfo> profiles = getUserManagerLocked().getProfiles( 16723 mCurrentUserId, false /* enabledOnly */); 16724 List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size()); 16725 for (UserInfo user : profiles) { 16726 if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED 16727 && user.id != mCurrentUserId) { 16728 toStart.add(user); 16729 } 16730 } 16731 final int n = toStart.size(); 16732 int i = 0; 16733 for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) { 16734 startUserInBackground(toStart.get(i).id); 16735 } 16736 if (i < n) { 16737 Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS"); 16738 } 16739 } 16740 16741 void finishUserBoot(UserStartedState uss) { 16742 synchronized (this) { 16743 if (uss.mState == UserStartedState.STATE_BOOTING 16744 && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) { 16745 uss.mState = UserStartedState.STATE_RUNNING; 16746 final int userId = uss.mHandle.getIdentifier(); 16747 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 16748 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 16749 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT); 16750 broadcastIntentLocked(null, null, intent, 16751 null, null, 0, null, null, 16752 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE, 16753 true, false, MY_PID, Process.SYSTEM_UID, userId); 16754 } 16755 } 16756 } 16757 16758 void finishUserSwitch(UserStartedState uss) { 16759 synchronized (this) { 16760 finishUserBoot(uss); 16761 16762 startProfilesLocked(); 16763 16764 int num = mUserLru.size(); 16765 int i = 0; 16766 while (num > MAX_RUNNING_USERS && i < mUserLru.size()) { 16767 Integer oldUserId = mUserLru.get(i); 16768 UserStartedState oldUss = mStartedUsers.get(oldUserId); 16769 if (oldUss == null) { 16770 // Shouldn't happen, but be sane if it does. 16771 mUserLru.remove(i); 16772 num--; 16773 continue; 16774 } 16775 if (oldUss.mState == UserStartedState.STATE_STOPPING 16776 || oldUss.mState == UserStartedState.STATE_SHUTDOWN) { 16777 // This user is already stopping, doesn't count. 16778 num--; 16779 i++; 16780 continue; 16781 } 16782 if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) { 16783 // Owner and current can't be stopped, but count as running. 16784 i++; 16785 continue; 16786 } 16787 // This is a user to be stopped. 16788 stopUserLocked(oldUserId, null); 16789 num--; 16790 i++; 16791 } 16792 } 16793 } 16794 16795 @Override 16796 public int stopUser(final int userId, final IStopUserCallback callback) { 16797 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 16798 != PackageManager.PERMISSION_GRANTED) { 16799 String msg = "Permission Denial: switchUser() from pid=" 16800 + Binder.getCallingPid() 16801 + ", uid=" + Binder.getCallingUid() 16802 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 16803 Slog.w(TAG, msg); 16804 throw new SecurityException(msg); 16805 } 16806 if (userId <= 0) { 16807 throw new IllegalArgumentException("Can't stop primary user " + userId); 16808 } 16809 synchronized (this) { 16810 return stopUserLocked(userId, callback); 16811 } 16812 } 16813 16814 private int stopUserLocked(final int userId, final IStopUserCallback callback) { 16815 if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId); 16816 if (mCurrentUserId == userId) { 16817 return ActivityManager.USER_OP_IS_CURRENT; 16818 } 16819 16820 final UserStartedState uss = mStartedUsers.get(userId); 16821 if (uss == null) { 16822 // User is not started, nothing to do... but we do need to 16823 // callback if requested. 16824 if (callback != null) { 16825 mHandler.post(new Runnable() { 16826 @Override 16827 public void run() { 16828 try { 16829 callback.userStopped(userId); 16830 } catch (RemoteException e) { 16831 } 16832 } 16833 }); 16834 } 16835 return ActivityManager.USER_OP_SUCCESS; 16836 } 16837 16838 if (callback != null) { 16839 uss.mStopCallbacks.add(callback); 16840 } 16841 16842 if (uss.mState != UserStartedState.STATE_STOPPING 16843 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 16844 uss.mState = UserStartedState.STATE_STOPPING; 16845 updateStartedUserArrayLocked(); 16846 16847 long ident = Binder.clearCallingIdentity(); 16848 try { 16849 // We are going to broadcast ACTION_USER_STOPPING and then 16850 // once that is done send a final ACTION_SHUTDOWN and then 16851 // stop the user. 16852 final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING); 16853 stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 16854 stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 16855 stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true); 16856 final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN); 16857 // This is the result receiver for the final shutdown broadcast. 16858 final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() { 16859 @Override 16860 public void performReceive(Intent intent, int resultCode, String data, 16861 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 16862 finishUserStop(uss); 16863 } 16864 }; 16865 // This is the result receiver for the initial stopping broadcast. 16866 final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() { 16867 @Override 16868 public void performReceive(Intent intent, int resultCode, String data, 16869 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 16870 // On to the next. 16871 synchronized (ActivityManagerService.this) { 16872 if (uss.mState != UserStartedState.STATE_STOPPING) { 16873 // Whoops, we are being started back up. Abort, abort! 16874 return; 16875 } 16876 uss.mState = UserStartedState.STATE_SHUTDOWN; 16877 } 16878 mSystemServiceManager.stopUser(userId); 16879 broadcastIntentLocked(null, null, shutdownIntent, 16880 null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE, 16881 true, false, MY_PID, Process.SYSTEM_UID, userId); 16882 } 16883 }; 16884 // Kick things off. 16885 broadcastIntentLocked(null, null, stoppingIntent, 16886 null, stoppingReceiver, 0, null, null, 16887 android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 16888 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 16889 } finally { 16890 Binder.restoreCallingIdentity(ident); 16891 } 16892 } 16893 16894 return ActivityManager.USER_OP_SUCCESS; 16895 } 16896 16897 void finishUserStop(UserStartedState uss) { 16898 final int userId = uss.mHandle.getIdentifier(); 16899 boolean stopped; 16900 ArrayList<IStopUserCallback> callbacks; 16901 synchronized (this) { 16902 callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks); 16903 if (mStartedUsers.get(userId) != uss) { 16904 stopped = false; 16905 } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) { 16906 stopped = false; 16907 } else { 16908 stopped = true; 16909 // User can no longer run. 16910 mStartedUsers.remove(userId); 16911 mUserLru.remove(Integer.valueOf(userId)); 16912 updateStartedUserArrayLocked(); 16913 16914 // Clean up all state and processes associated with the user. 16915 // Kill all the processes for the user. 16916 forceStopUserLocked(userId, "finish user"); 16917 } 16918 } 16919 16920 for (int i=0; i<callbacks.size(); i++) { 16921 try { 16922 if (stopped) callbacks.get(i).userStopped(userId); 16923 else callbacks.get(i).userStopAborted(userId); 16924 } catch (RemoteException e) { 16925 } 16926 } 16927 16928 if (stopped) { 16929 mSystemServiceManager.cleanupUser(userId); 16930 synchronized (this) { 16931 mStackSupervisor.removeUserLocked(userId); 16932 } 16933 } 16934 } 16935 16936 @Override 16937 public UserInfo getCurrentUser() { 16938 if ((checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) 16939 != PackageManager.PERMISSION_GRANTED) && ( 16940 checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 16941 != PackageManager.PERMISSION_GRANTED)) { 16942 String msg = "Permission Denial: getCurrentUser() from pid=" 16943 + Binder.getCallingPid() 16944 + ", uid=" + Binder.getCallingUid() 16945 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS; 16946 Slog.w(TAG, msg); 16947 throw new SecurityException(msg); 16948 } 16949 synchronized (this) { 16950 return getUserManagerLocked().getUserInfo(mCurrentUserId); 16951 } 16952 } 16953 16954 int getCurrentUserIdLocked() { 16955 return mCurrentUserId; 16956 } 16957 16958 @Override 16959 public boolean isUserRunning(int userId, boolean orStopped) { 16960 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) 16961 != PackageManager.PERMISSION_GRANTED) { 16962 String msg = "Permission Denial: isUserRunning() from pid=" 16963 + Binder.getCallingPid() 16964 + ", uid=" + Binder.getCallingUid() 16965 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS; 16966 Slog.w(TAG, msg); 16967 throw new SecurityException(msg); 16968 } 16969 synchronized (this) { 16970 return isUserRunningLocked(userId, orStopped); 16971 } 16972 } 16973 16974 boolean isUserRunningLocked(int userId, boolean orStopped) { 16975 UserStartedState state = mStartedUsers.get(userId); 16976 if (state == null) { 16977 return false; 16978 } 16979 if (orStopped) { 16980 return true; 16981 } 16982 return state.mState != UserStartedState.STATE_STOPPING 16983 && state.mState != UserStartedState.STATE_SHUTDOWN; 16984 } 16985 16986 @Override 16987 public int[] getRunningUserIds() { 16988 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) 16989 != PackageManager.PERMISSION_GRANTED) { 16990 String msg = "Permission Denial: isUserRunning() from pid=" 16991 + Binder.getCallingPid() 16992 + ", uid=" + Binder.getCallingUid() 16993 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS; 16994 Slog.w(TAG, msg); 16995 throw new SecurityException(msg); 16996 } 16997 synchronized (this) { 16998 return mStartedUserArray; 16999 } 17000 } 17001 17002 private void updateStartedUserArrayLocked() { 17003 int num = 0; 17004 for (int i=0; i<mStartedUsers.size(); i++) { 17005 UserStartedState uss = mStartedUsers.valueAt(i); 17006 // This list does not include stopping users. 17007 if (uss.mState != UserStartedState.STATE_STOPPING 17008 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 17009 num++; 17010 } 17011 } 17012 mStartedUserArray = new int[num]; 17013 num = 0; 17014 for (int i=0; i<mStartedUsers.size(); i++) { 17015 UserStartedState uss = mStartedUsers.valueAt(i); 17016 if (uss.mState != UserStartedState.STATE_STOPPING 17017 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 17018 mStartedUserArray[num] = mStartedUsers.keyAt(i); 17019 num++; 17020 } 17021 } 17022 } 17023 17024 @Override 17025 public void registerUserSwitchObserver(IUserSwitchObserver observer) { 17026 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 17027 != PackageManager.PERMISSION_GRANTED) { 17028 String msg = "Permission Denial: registerUserSwitchObserver() from pid=" 17029 + Binder.getCallingPid() 17030 + ", uid=" + Binder.getCallingUid() 17031 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 17032 Slog.w(TAG, msg); 17033 throw new SecurityException(msg); 17034 } 17035 17036 mUserSwitchObservers.register(observer); 17037 } 17038 17039 @Override 17040 public void unregisterUserSwitchObserver(IUserSwitchObserver observer) { 17041 mUserSwitchObservers.unregister(observer); 17042 } 17043 17044 private boolean userExists(int userId) { 17045 if (userId == 0) { 17046 return true; 17047 } 17048 UserManagerService ums = getUserManagerLocked(); 17049 return ums != null ? (ums.getUserInfo(userId) != null) : false; 17050 } 17051 17052 int[] getUsersLocked() { 17053 UserManagerService ums = getUserManagerLocked(); 17054 return ums != null ? ums.getUserIds() : new int[] { 0 }; 17055 } 17056 17057 UserManagerService getUserManagerLocked() { 17058 if (mUserManager == null) { 17059 IBinder b = ServiceManager.getService(Context.USER_SERVICE); 17060 mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b); 17061 } 17062 return mUserManager; 17063 } 17064 17065 private int applyUserId(int uid, int userId) { 17066 return UserHandle.getUid(userId, uid); 17067 } 17068 17069 ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) { 17070 if (info == null) return null; 17071 ApplicationInfo newInfo = new ApplicationInfo(info); 17072 newInfo.uid = applyUserId(info.uid, userId); 17073 newInfo.dataDir = USER_DATA_DIR + userId + "/" 17074 + info.packageName; 17075 return newInfo; 17076 } 17077 17078 ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) { 17079 if (aInfo == null 17080 || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) { 17081 return aInfo; 17082 } 17083 17084 ActivityInfo info = new ActivityInfo(aInfo); 17085 info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId); 17086 return info; 17087 } 17088 17089 private final class LocalService extends ActivityManagerInternal { 17090 @Override 17091 public void goingToSleep() { 17092 ActivityManagerService.this.goingToSleep(); 17093 } 17094 17095 @Override 17096 public void wakingUp() { 17097 ActivityManagerService.this.wakingUp(); 17098 } 17099 } 17100} 17101