ActivityManagerService.java revision f233a7b8b22ad5605c968cedd2822fa4e80c09f7
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.app.IAppTask; 36import android.app.admin.DevicePolicyManager; 37import android.appwidget.AppWidgetManager; 38import android.graphics.Rect; 39import android.os.BatteryStats; 40import android.os.PersistableBundle; 41import android.service.voice.IVoiceInteractionSession; 42import android.util.ArrayMap; 43 44import com.android.internal.R; 45import com.android.internal.annotations.GuardedBy; 46import com.android.internal.app.IAppOpsService; 47import com.android.internal.app.IVoiceInteractor; 48import com.android.internal.app.ProcessMap; 49import com.android.internal.app.ProcessStats; 50import com.android.internal.content.PackageMonitor; 51import com.android.internal.os.BackgroundThread; 52import com.android.internal.os.BatteryStatsImpl; 53import com.android.internal.os.ProcessCpuTracker; 54import com.android.internal.os.TransferPipe; 55import com.android.internal.os.Zygote; 56import com.android.internal.util.FastPrintWriter; 57import com.android.internal.util.FastXmlSerializer; 58import com.android.internal.util.MemInfoReader; 59import com.android.internal.util.Preconditions; 60import com.android.server.AppOpsService; 61import com.android.server.AttributeCache; 62import com.android.server.IntentResolver; 63import com.android.server.LocalServices; 64import com.android.server.ServiceThread; 65import com.android.server.SystemService; 66import com.android.server.SystemServiceManager; 67import com.android.server.Watchdog; 68import com.android.server.am.ActivityStack.ActivityState; 69import com.android.server.firewall.IntentFirewall; 70import com.android.server.pm.UserManagerService; 71import com.android.server.wm.AppTransition; 72import com.android.server.wm.WindowManagerService; 73import com.google.android.collect.Lists; 74import com.google.android.collect.Maps; 75 76import libcore.io.IoUtils; 77 78import org.xmlpull.v1.XmlPullParser; 79import org.xmlpull.v1.XmlPullParserException; 80import org.xmlpull.v1.XmlSerializer; 81 82import android.app.Activity; 83import android.app.ActivityManager; 84import android.app.ActivityManager.RunningTaskInfo; 85import android.app.ActivityManager.StackInfo; 86import android.app.ActivityManagerInternal; 87import android.app.ActivityManagerNative; 88import android.app.ActivityOptions; 89import android.app.ActivityThread; 90import android.app.AlertDialog; 91import android.app.AppGlobals; 92import android.app.ApplicationErrorReport; 93import android.app.Dialog; 94import android.app.IActivityController; 95import android.app.IApplicationThread; 96import android.app.IInstrumentationWatcher; 97import android.app.INotificationManager; 98import android.app.IProcessObserver; 99import android.app.IServiceConnection; 100import android.app.IStopUserCallback; 101import android.app.IUiAutomationConnection; 102import android.app.IUserSwitchObserver; 103import android.app.Instrumentation; 104import android.app.Notification; 105import android.app.NotificationManager; 106import android.app.PendingIntent; 107import android.app.backup.IBackupManager; 108import android.content.ActivityNotFoundException; 109import android.content.BroadcastReceiver; 110import android.content.ClipData; 111import android.content.ComponentCallbacks2; 112import android.content.ComponentName; 113import android.content.ContentProvider; 114import android.content.ContentResolver; 115import android.content.Context; 116import android.content.DialogInterface; 117import android.content.IContentProvider; 118import android.content.IIntentReceiver; 119import android.content.IIntentSender; 120import android.content.Intent; 121import android.content.IntentFilter; 122import android.content.IntentSender; 123import android.content.pm.ActivityInfo; 124import android.content.pm.ApplicationInfo; 125import android.content.pm.ConfigurationInfo; 126import android.content.pm.IPackageDataObserver; 127import android.content.pm.IPackageManager; 128import android.content.pm.InstrumentationInfo; 129import android.content.pm.PackageInfo; 130import android.content.pm.PackageManager; 131import android.content.pm.ParceledListSlice; 132import android.content.pm.UserInfo; 133import android.content.pm.PackageManager.NameNotFoundException; 134import android.content.pm.PathPermission; 135import android.content.pm.ProviderInfo; 136import android.content.pm.ResolveInfo; 137import android.content.pm.ServiceInfo; 138import android.content.res.CompatibilityInfo; 139import android.content.res.Configuration; 140import android.graphics.Bitmap; 141import android.net.Proxy; 142import android.net.ProxyInfo; 143import android.net.Uri; 144import android.os.Binder; 145import android.os.Build; 146import android.os.Bundle; 147import android.os.Debug; 148import android.os.DropBoxManager; 149import android.os.Environment; 150import android.os.FactoryTest; 151import android.os.FileObserver; 152import android.os.FileUtils; 153import android.os.Handler; 154import android.os.IBinder; 155import android.os.IPermissionController; 156import android.os.IRemoteCallback; 157import android.os.IUserManager; 158import android.os.Looper; 159import android.os.Message; 160import android.os.Parcel; 161import android.os.ParcelFileDescriptor; 162import android.os.Process; 163import android.os.RemoteCallbackList; 164import android.os.RemoteException; 165import android.os.SELinux; 166import android.os.ServiceManager; 167import android.os.StrictMode; 168import android.os.SystemClock; 169import android.os.SystemProperties; 170import android.os.UpdateLock; 171import android.os.UserHandle; 172import android.provider.Settings; 173import android.text.format.DateUtils; 174import android.text.format.Time; 175import android.util.AtomicFile; 176import android.util.EventLog; 177import android.util.Log; 178import android.util.Pair; 179import android.util.PrintWriterPrinter; 180import android.util.Slog; 181import android.util.SparseArray; 182import android.util.TimeUtils; 183import android.util.Xml; 184import android.view.Gravity; 185import android.view.LayoutInflater; 186import android.view.View; 187import android.view.WindowManager; 188 189import java.io.BufferedInputStream; 190import java.io.BufferedOutputStream; 191import java.io.DataInputStream; 192import java.io.DataOutputStream; 193import java.io.File; 194import java.io.FileDescriptor; 195import java.io.FileInputStream; 196import java.io.FileNotFoundException; 197import java.io.FileOutputStream; 198import java.io.IOException; 199import java.io.InputStreamReader; 200import java.io.PrintWriter; 201import java.io.StringWriter; 202import java.lang.ref.WeakReference; 203import java.util.ArrayList; 204import java.util.Arrays; 205import java.util.Collections; 206import java.util.Comparator; 207import java.util.HashMap; 208import java.util.HashSet; 209import java.util.Iterator; 210import java.util.List; 211import java.util.Locale; 212import java.util.Map; 213import java.util.Set; 214import java.util.concurrent.atomic.AtomicBoolean; 215import java.util.concurrent.atomic.AtomicLong; 216 217public final class ActivityManagerService extends ActivityManagerNative 218 implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback { 219 private static final String USER_DATA_DIR = "/data/user/"; 220 static final String TAG = "ActivityManager"; 221 static final String TAG_MU = "ActivityManagerServiceMU"; 222 static final boolean DEBUG = false; 223 static final boolean localLOGV = DEBUG; 224 static final boolean DEBUG_BACKUP = localLOGV || false; 225 static final boolean DEBUG_BROADCAST = localLOGV || false; 226 static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false; 227 static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false; 228 static final boolean DEBUG_CLEANUP = localLOGV || false; 229 static final boolean DEBUG_CONFIGURATION = localLOGV || false; 230 static final boolean DEBUG_FOCUS = false; 231 static final boolean DEBUG_IMMERSIVE = localLOGV || false; 232 static final boolean DEBUG_MU = localLOGV || false; 233 static final boolean DEBUG_OOM_ADJ = localLOGV || false; 234 static final boolean DEBUG_LRU = localLOGV || false; 235 static final boolean DEBUG_PAUSE = localLOGV || false; 236 static final boolean DEBUG_POWER = localLOGV || false; 237 static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false; 238 static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false; 239 static final boolean DEBUG_PROCESSES = localLOGV || false; 240 static final boolean DEBUG_PROVIDER = localLOGV || false; 241 static final boolean DEBUG_RESULTS = localLOGV || false; 242 static final boolean DEBUG_SERVICE = localLOGV || false; 243 static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false; 244 static final boolean DEBUG_STACK = localLOGV || false; 245 static final boolean DEBUG_SWITCH = localLOGV || false; 246 static final boolean DEBUG_TASKS = localLOGV || false; 247 static final boolean DEBUG_THUMBNAILS = localLOGV || false; 248 static final boolean DEBUG_TRANSITION = localLOGV || false; 249 static final boolean DEBUG_URI_PERMISSION = localLOGV || false; 250 static final boolean DEBUG_USER_LEAVING = localLOGV || false; 251 static final boolean DEBUG_VISBILITY = localLOGV || false; 252 static final boolean DEBUG_PSS = localLOGV || false; 253 static final boolean DEBUG_LOCKSCREEN = localLOGV || false; 254 static final boolean VALIDATE_TOKENS = false; 255 static final boolean SHOW_ACTIVITY_START_TIME = true; 256 257 // Control over CPU and battery monitoring. 258 static final long BATTERY_STATS_TIME = 30*60*1000; // write battery stats every 30 minutes. 259 static final boolean MONITOR_CPU_USAGE = true; 260 static final long MONITOR_CPU_MIN_TIME = 5*1000; // don't sample cpu less than every 5 seconds. 261 static final long MONITOR_CPU_MAX_TIME = 0x0fffffff; // wait possibly forever for next cpu sample. 262 static final boolean MONITOR_THREAD_CPU_USAGE = false; 263 264 // The flags that are set for all calls we make to the package manager. 265 static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES; 266 267 private static final String SYSTEM_DEBUGGABLE = "ro.debuggable"; 268 269 static final boolean IS_USER_BUILD = "user".equals(Build.TYPE); 270 271 // Maximum number of recent tasks that we can remember. 272 static final int MAX_RECENT_TASKS = ActivityManager.isLowRamDeviceStatic() ? 10 : 200; 273 274 // Amount of time after a call to stopAppSwitches() during which we will 275 // prevent further untrusted switches from happening. 276 static final long APP_SWITCH_DELAY_TIME = 5*1000; 277 278 // How long we wait for a launched process to attach to the activity manager 279 // before we decide it's never going to come up for real. 280 static final int PROC_START_TIMEOUT = 10*1000; 281 282 // How long we wait for a launched process to attach to the activity manager 283 // before we decide it's never going to come up for real, when the process was 284 // started with a wrapper for instrumentation (such as Valgrind) because it 285 // could take much longer than usual. 286 static final int PROC_START_TIMEOUT_WITH_WRAPPER = 300*1000; 287 288 // How long to wait after going idle before forcing apps to GC. 289 static final int GC_TIMEOUT = 5*1000; 290 291 // The minimum amount of time between successive GC requests for a process. 292 static final int GC_MIN_INTERVAL = 60*1000; 293 294 // The minimum amount of time between successive PSS requests for a process. 295 static final int FULL_PSS_MIN_INTERVAL = 10*60*1000; 296 297 // The minimum amount of time between successive PSS requests for a process 298 // when the request is due to the memory state being lowered. 299 static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000; 300 301 // The rate at which we check for apps using excessive power -- 15 mins. 302 static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000; 303 304 // The minimum sample duration we will allow before deciding we have 305 // enough data on wake locks to start killing things. 306 static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000; 307 308 // The minimum sample duration we will allow before deciding we have 309 // enough data on CPU usage to start killing things. 310 static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000; 311 312 // How long we allow a receiver to run before giving up on it. 313 static final int BROADCAST_FG_TIMEOUT = 10*1000; 314 static final int BROADCAST_BG_TIMEOUT = 60*1000; 315 316 // How long we wait until we timeout on key dispatching. 317 static final int KEY_DISPATCHING_TIMEOUT = 5*1000; 318 319 // How long we wait until we timeout on key dispatching during instrumentation. 320 static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000; 321 322 // Amount of time we wait for observers to handle a user switch before 323 // giving up on them and unfreezing the screen. 324 static final int USER_SWITCH_TIMEOUT = 2*1000; 325 326 // Maximum number of users we allow to be running at a time. 327 static final int MAX_RUNNING_USERS = 3; 328 329 // How long to wait in getAssistContextExtras for the activity and foreground services 330 // to respond with the result. 331 static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500; 332 333 // Maximum number of persisted Uri grants a package is allowed 334 static final int MAX_PERSISTED_URI_GRANTS = 128; 335 336 static final int MY_PID = Process.myPid(); 337 338 static final String[] EMPTY_STRING_ARRAY = new String[0]; 339 340 // How many bytes to write into the dropbox log before truncating 341 static final int DROPBOX_MAX_SIZE = 256 * 1024; 342 343 /** All system services */ 344 SystemServiceManager mSystemServiceManager; 345 346 /** Run all ActivityStacks through this */ 347 ActivityStackSupervisor mStackSupervisor; 348 349 public IntentFirewall mIntentFirewall; 350 351 // Whether we should show our dialogs (ANR, crash, etc) or just perform their 352 // default actuion automatically. Important for devices without direct input 353 // devices. 354 private boolean mShowDialogs = true; 355 356 /** 357 * Description of a request to start a new activity, which has been held 358 * due to app switches being disabled. 359 */ 360 static class PendingActivityLaunch { 361 final ActivityRecord r; 362 final ActivityRecord sourceRecord; 363 final int startFlags; 364 final ActivityStack stack; 365 366 PendingActivityLaunch(ActivityRecord _r, ActivityRecord _sourceRecord, 367 int _startFlags, ActivityStack _stack) { 368 r = _r; 369 sourceRecord = _sourceRecord; 370 startFlags = _startFlags; 371 stack = _stack; 372 } 373 } 374 375 final ArrayList<PendingActivityLaunch> mPendingActivityLaunches 376 = new ArrayList<PendingActivityLaunch>(); 377 378 BroadcastQueue mFgBroadcastQueue; 379 BroadcastQueue mBgBroadcastQueue; 380 // Convenient for easy iteration over the queues. Foreground is first 381 // so that dispatch of foreground broadcasts gets precedence. 382 final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2]; 383 384 BroadcastQueue broadcastQueueForIntent(Intent intent) { 385 final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0; 386 if (DEBUG_BACKGROUND_BROADCAST) { 387 Slog.i(TAG, "Broadcast intent " + intent + " on " 388 + (isFg ? "foreground" : "background") 389 + " queue"); 390 } 391 return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue; 392 } 393 394 BroadcastRecord broadcastRecordForReceiverLocked(IBinder receiver) { 395 for (BroadcastQueue queue : mBroadcastQueues) { 396 BroadcastRecord r = queue.getMatchingOrderedReceiver(receiver); 397 if (r != null) { 398 return r; 399 } 400 } 401 return null; 402 } 403 404 /** 405 * Activity we have told the window manager to have key focus. 406 */ 407 ActivityRecord mFocusedActivity = null; 408 409 /** 410 * List of intents that were used to start the most recent tasks. 411 */ 412 ArrayList<TaskRecord> mRecentTasks; 413 414 public class PendingAssistExtras extends Binder implements Runnable { 415 public final ActivityRecord activity; 416 public boolean haveResult = false; 417 public Bundle result = null; 418 public PendingAssistExtras(ActivityRecord _activity) { 419 activity = _activity; 420 } 421 @Override 422 public void run() { 423 Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity); 424 synchronized (this) { 425 haveResult = true; 426 notifyAll(); 427 } 428 } 429 } 430 431 final ArrayList<PendingAssistExtras> mPendingAssistExtras 432 = new ArrayList<PendingAssistExtras>(); 433 434 /** 435 * Process management. 436 */ 437 final ProcessList mProcessList = new ProcessList(); 438 439 /** 440 * All of the applications we currently have running organized by name. 441 * The keys are strings of the application package name (as 442 * returned by the package manager), and the keys are ApplicationRecord 443 * objects. 444 */ 445 final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>(); 446 447 /** 448 * Tracking long-term execution of processes to look for abuse and other 449 * bad app behavior. 450 */ 451 final ProcessStatsService mProcessStats; 452 453 /** 454 * The currently running isolated processes. 455 */ 456 final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>(); 457 458 /** 459 * Counter for assigning isolated process uids, to avoid frequently reusing the 460 * same ones. 461 */ 462 int mNextIsolatedProcessUid = 0; 463 464 /** 465 * The currently running heavy-weight process, if any. 466 */ 467 ProcessRecord mHeavyWeightProcess = null; 468 469 /** 470 * The last time that various processes have crashed. 471 */ 472 final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>(); 473 474 /** 475 * Information about a process that is currently marked as bad. 476 */ 477 static final class BadProcessInfo { 478 BadProcessInfo(long time, String shortMsg, String longMsg, String stack) { 479 this.time = time; 480 this.shortMsg = shortMsg; 481 this.longMsg = longMsg; 482 this.stack = stack; 483 } 484 485 final long time; 486 final String shortMsg; 487 final String longMsg; 488 final String stack; 489 } 490 491 /** 492 * Set of applications that we consider to be bad, and will reject 493 * incoming broadcasts from (which the user has no control over). 494 * Processes are added to this set when they have crashed twice within 495 * a minimum amount of time; they are removed from it when they are 496 * later restarted (hopefully due to some user action). The value is the 497 * time it was added to the list. 498 */ 499 final ProcessMap<BadProcessInfo> mBadProcesses = new ProcessMap<BadProcessInfo>(); 500 501 /** 502 * All of the processes we currently have running organized by pid. 503 * The keys are the pid running the application. 504 * 505 * <p>NOTE: This object is protected by its own lock, NOT the global 506 * activity manager lock! 507 */ 508 final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>(); 509 510 /** 511 * All of the processes that have been forced to be foreground. The key 512 * is the pid of the caller who requested it (we hold a death 513 * link on it). 514 */ 515 abstract class ForegroundToken implements IBinder.DeathRecipient { 516 int pid; 517 IBinder token; 518 } 519 final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>(); 520 521 /** 522 * List of records for processes that someone had tried to start before the 523 * system was ready. We don't start them at that point, but ensure they 524 * are started by the time booting is complete. 525 */ 526 final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>(); 527 528 /** 529 * List of persistent applications that are in the process 530 * of being started. 531 */ 532 final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>(); 533 534 /** 535 * Processes that are being forcibly torn down. 536 */ 537 final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>(); 538 539 /** 540 * List of running applications, sorted by recent usage. 541 * The first entry in the list is the least recently used. 542 */ 543 final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>(); 544 545 /** 546 * Where in mLruProcesses that the processes hosting activities start. 547 */ 548 int mLruProcessActivityStart = 0; 549 550 /** 551 * Where in mLruProcesses that the processes hosting services start. 552 * This is after (lower index) than mLruProcessesActivityStart. 553 */ 554 int mLruProcessServiceStart = 0; 555 556 /** 557 * List of processes that should gc as soon as things are idle. 558 */ 559 final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>(); 560 561 /** 562 * Processes we want to collect PSS data from. 563 */ 564 final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>(); 565 566 /** 567 * Last time we requested PSS data of all processes. 568 */ 569 long mLastFullPssTime = SystemClock.uptimeMillis(); 570 571 /** 572 * This is the process holding what we currently consider to be 573 * the "home" activity. 574 */ 575 ProcessRecord mHomeProcess; 576 577 /** 578 * This is the process holding the activity the user last visited that 579 * is in a different process from the one they are currently in. 580 */ 581 ProcessRecord mPreviousProcess; 582 583 /** 584 * The time at which the previous process was last visible. 585 */ 586 long mPreviousProcessVisibleTime; 587 588 /** 589 * Which uses have been started, so are allowed to run code. 590 */ 591 final SparseArray<UserStartedState> mStartedUsers = new SparseArray<UserStartedState>(); 592 593 /** 594 * LRU list of history of current users. Most recently current is at the end. 595 */ 596 final ArrayList<Integer> mUserLru = new ArrayList<Integer>(); 597 598 /** 599 * Constant array of the users that are currently started. 600 */ 601 int[] mStartedUserArray = new int[] { 0 }; 602 603 /** 604 * Registered observers of the user switching mechanics. 605 */ 606 final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers 607 = new RemoteCallbackList<IUserSwitchObserver>(); 608 609 /** 610 * Currently active user switch. 611 */ 612 Object mCurUserSwitchCallback; 613 614 /** 615 * Packages that the user has asked to have run in screen size 616 * compatibility mode instead of filling the screen. 617 */ 618 final CompatModePackages mCompatModePackages; 619 620 /** 621 * Set of IntentSenderRecord objects that are currently active. 622 */ 623 final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords 624 = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>(); 625 626 /** 627 * Fingerprints (hashCode()) of stack traces that we've 628 * already logged DropBox entries for. Guarded by itself. If 629 * something (rogue user app) forces this over 630 * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared. 631 */ 632 private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>(); 633 private static final int MAX_DUP_SUPPRESSED_STACKS = 5000; 634 635 /** 636 * Strict Mode background batched logging state. 637 * 638 * The string buffer is guarded by itself, and its lock is also 639 * used to determine if another batched write is already 640 * in-flight. 641 */ 642 private final StringBuilder mStrictModeBuffer = new StringBuilder(); 643 644 /** 645 * Keeps track of all IIntentReceivers that have been registered for 646 * broadcasts. Hash keys are the receiver IBinder, hash value is 647 * a ReceiverList. 648 */ 649 final HashMap<IBinder, ReceiverList> mRegisteredReceivers = 650 new HashMap<IBinder, ReceiverList>(); 651 652 /** 653 * Resolver for broadcast intents to registered receivers. 654 * Holds BroadcastFilter (subclass of IntentFilter). 655 */ 656 final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver 657 = new IntentResolver<BroadcastFilter, BroadcastFilter>() { 658 @Override 659 protected boolean allowFilterResult( 660 BroadcastFilter filter, List<BroadcastFilter> dest) { 661 IBinder target = filter.receiverList.receiver.asBinder(); 662 for (int i=dest.size()-1; i>=0; i--) { 663 if (dest.get(i).receiverList.receiver.asBinder() == target) { 664 return false; 665 } 666 } 667 return true; 668 } 669 670 @Override 671 protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) { 672 if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL 673 || userId == filter.owningUserId) { 674 return super.newResult(filter, match, userId); 675 } 676 return null; 677 } 678 679 @Override 680 protected BroadcastFilter[] newArray(int size) { 681 return new BroadcastFilter[size]; 682 } 683 684 @Override 685 protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) { 686 return packageName.equals(filter.packageName); 687 } 688 }; 689 690 /** 691 * State of all active sticky broadcasts per user. Keys are the action of the 692 * sticky Intent, values are an ArrayList of all broadcasted intents with 693 * that action (which should usually be one). The SparseArray is keyed 694 * by the user ID the sticky is for, and can include UserHandle.USER_ALL 695 * for stickies that are sent to all users. 696 */ 697 final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts = 698 new SparseArray<ArrayMap<String, ArrayList<Intent>>>(); 699 700 final ActiveServices mServices; 701 702 /** 703 * Backup/restore process management 704 */ 705 String mBackupAppName = null; 706 BackupRecord mBackupTarget = null; 707 708 final ProviderMap mProviderMap; 709 710 /** 711 * List of content providers who have clients waiting for them. The 712 * application is currently being launched and the provider will be 713 * removed from this list once it is published. 714 */ 715 final ArrayList<ContentProviderRecord> mLaunchingProviders 716 = new ArrayList<ContentProviderRecord>(); 717 718 /** 719 * File storing persisted {@link #mGrantedUriPermissions}. 720 */ 721 private final AtomicFile mGrantFile; 722 723 /** XML constants used in {@link #mGrantFile} */ 724 private static final String TAG_URI_GRANTS = "uri-grants"; 725 private static final String TAG_URI_GRANT = "uri-grant"; 726 private static final String ATTR_USER_HANDLE = "userHandle"; 727 private static final String ATTR_SOURCE_USER_ID = "sourceUserId"; 728 private static final String ATTR_TARGET_USER_ID = "targetUserId"; 729 private static final String ATTR_SOURCE_PKG = "sourcePkg"; 730 private static final String ATTR_TARGET_PKG = "targetPkg"; 731 private static final String ATTR_URI = "uri"; 732 private static final String ATTR_MODE_FLAGS = "modeFlags"; 733 private static final String ATTR_CREATED_TIME = "createdTime"; 734 private static final String ATTR_PREFIX = "prefix"; 735 736 /** 737 * Global set of specific {@link Uri} permissions that have been granted. 738 * This optimized lookup structure maps from {@link UriPermission#targetUid} 739 * to {@link UriPermission#uri} to {@link UriPermission}. 740 */ 741 @GuardedBy("this") 742 private final SparseArray<ArrayMap<GrantUri, UriPermission>> 743 mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>(); 744 745 public static class GrantUri { 746 public final int sourceUserId; 747 public final Uri uri; 748 public boolean prefix; 749 750 public GrantUri(int sourceUserId, Uri uri, boolean prefix) { 751 this.sourceUserId = sourceUserId; 752 this.uri = uri; 753 this.prefix = prefix; 754 } 755 756 @Override 757 public int hashCode() { 758 return toString().hashCode(); 759 } 760 761 @Override 762 public boolean equals(Object o) { 763 if (o instanceof GrantUri) { 764 GrantUri other = (GrantUri) o; 765 return uri.equals(other.uri) && (sourceUserId == other.sourceUserId) 766 && prefix == other.prefix; 767 } 768 return false; 769 } 770 771 @Override 772 public String toString() { 773 String result = Integer.toString(sourceUserId) + " @ " + uri.toString(); 774 if (prefix) result += " [prefix]"; 775 return result; 776 } 777 778 public String toSafeString() { 779 String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString(); 780 if (prefix) result += " [prefix]"; 781 return result; 782 } 783 784 public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) { 785 return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle), 786 ContentProvider.getUriWithoutUserId(uri), false); 787 } 788 } 789 790 CoreSettingsObserver mCoreSettingsObserver; 791 792 /** 793 * Thread-local storage used to carry caller permissions over through 794 * indirect content-provider access. 795 */ 796 private class Identity { 797 public int pid; 798 public int uid; 799 800 Identity(int _pid, int _uid) { 801 pid = _pid; 802 uid = _uid; 803 } 804 } 805 806 private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>(); 807 808 /** 809 * All information we have collected about the runtime performance of 810 * any user id that can impact battery performance. 811 */ 812 final BatteryStatsService mBatteryStatsService; 813 814 /** 815 * Information about component usage 816 */ 817 final UsageStatsService mUsageStatsService; 818 819 /** 820 * Information about and control over application operations 821 */ 822 final AppOpsService mAppOpsService; 823 824 /** 825 * Save recent tasks information across reboots. 826 */ 827 final TaskPersister mTaskPersister; 828 829 /** 830 * Current configuration information. HistoryRecord objects are given 831 * a reference to this object to indicate which configuration they are 832 * currently running in, so this object must be kept immutable. 833 */ 834 Configuration mConfiguration = new Configuration(); 835 836 /** 837 * Current sequencing integer of the configuration, for skipping old 838 * configurations. 839 */ 840 int mConfigurationSeq = 0; 841 842 /** 843 * Hardware-reported OpenGLES version. 844 */ 845 final int GL_ES_VERSION; 846 847 /** 848 * List of initialization arguments to pass to all processes when binding applications to them. 849 * For example, references to the commonly used services. 850 */ 851 HashMap<String, IBinder> mAppBindArgs; 852 853 /** 854 * Temporary to avoid allocations. Protected by main lock. 855 */ 856 final StringBuilder mStringBuilder = new StringBuilder(256); 857 858 /** 859 * Used to control how we initialize the service. 860 */ 861 ComponentName mTopComponent; 862 String mTopAction = Intent.ACTION_MAIN; 863 String mTopData; 864 boolean mProcessesReady = false; 865 boolean mSystemReady = false; 866 boolean mBooting = false; 867 boolean mWaitingUpdate = false; 868 boolean mDidUpdate = false; 869 boolean mOnBattery = false; 870 boolean mLaunchWarningShown = false; 871 872 Context mContext; 873 874 int mFactoryTest; 875 876 boolean mCheckedForSetup; 877 878 /** 879 * The time at which we will allow normal application switches again, 880 * after a call to {@link #stopAppSwitches()}. 881 */ 882 long mAppSwitchesAllowedTime; 883 884 /** 885 * This is set to true after the first switch after mAppSwitchesAllowedTime 886 * is set; any switches after that will clear the time. 887 */ 888 boolean mDidAppSwitch; 889 890 /** 891 * Last time (in realtime) at which we checked for power usage. 892 */ 893 long mLastPowerCheckRealtime; 894 895 /** 896 * Last time (in uptime) at which we checked for power usage. 897 */ 898 long mLastPowerCheckUptime; 899 900 /** 901 * Set while we are wanting to sleep, to prevent any 902 * activities from being started/resumed. 903 */ 904 private boolean mSleeping = false; 905 906 /** 907 * Set while we are running a voice interaction. This overrides 908 * sleeping while it is active. 909 */ 910 private boolean mRunningVoice = false; 911 912 /** 913 * State of external calls telling us if the device is asleep. 914 */ 915 private boolean mWentToSleep = false; 916 917 /** 918 * State of external call telling us if the lock screen is shown. 919 */ 920 private boolean mLockScreenShown = false; 921 922 /** 923 * Set if we are shutting down the system, similar to sleeping. 924 */ 925 boolean mShuttingDown = false; 926 927 /** 928 * Current sequence id for oom_adj computation traversal. 929 */ 930 int mAdjSeq = 0; 931 932 /** 933 * Current sequence id for process LRU updating. 934 */ 935 int mLruSeq = 0; 936 937 /** 938 * Keep track of the non-cached/empty process we last found, to help 939 * determine how to distribute cached/empty processes next time. 940 */ 941 int mNumNonCachedProcs = 0; 942 943 /** 944 * Keep track of the number of cached hidden procs, to balance oom adj 945 * distribution between those and empty procs. 946 */ 947 int mNumCachedHiddenProcs = 0; 948 949 /** 950 * Keep track of the number of service processes we last found, to 951 * determine on the next iteration which should be B services. 952 */ 953 int mNumServiceProcs = 0; 954 int mNewNumAServiceProcs = 0; 955 int mNewNumServiceProcs = 0; 956 957 /** 958 * Allow the current computed overall memory level of the system to go down? 959 * This is set to false when we are killing processes for reasons other than 960 * memory management, so that the now smaller process list will not be taken as 961 * an indication that memory is tighter. 962 */ 963 boolean mAllowLowerMemLevel = false; 964 965 /** 966 * The last computed memory level, for holding when we are in a state that 967 * processes are going away for other reasons. 968 */ 969 int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL; 970 971 /** 972 * The last total number of process we have, to determine if changes actually look 973 * like a shrinking number of process due to lower RAM. 974 */ 975 int mLastNumProcesses; 976 977 /** 978 * The uptime of the last time we performed idle maintenance. 979 */ 980 long mLastIdleTime = SystemClock.uptimeMillis(); 981 982 /** 983 * Total time spent with RAM that has been added in the past since the last idle time. 984 */ 985 long mLowRamTimeSinceLastIdle = 0; 986 987 /** 988 * If RAM is currently low, when that horrible situation started. 989 */ 990 long mLowRamStartTime = 0; 991 992 /** 993 * For reporting to battery stats the current top application. 994 */ 995 private String mCurResumedPackage = null; 996 private int mCurResumedUid = -1; 997 998 /** 999 * For reporting to battery stats the apps currently running foreground 1000 * service. The ProcessMap is package/uid tuples; each of these contain 1001 * an array of the currently foreground processes. 1002 */ 1003 final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages 1004 = new ProcessMap<ArrayList<ProcessRecord>>(); 1005 1006 /** 1007 * This is set if we had to do a delayed dexopt of an app before launching 1008 * it, to increase the ANR timeouts in that case. 1009 */ 1010 boolean mDidDexOpt; 1011 1012 /** 1013 * Set if the systemServer made a call to enterSafeMode. 1014 */ 1015 boolean mSafeMode; 1016 1017 String mDebugApp = null; 1018 boolean mWaitForDebugger = false; 1019 boolean mDebugTransient = false; 1020 String mOrigDebugApp = null; 1021 boolean mOrigWaitForDebugger = false; 1022 boolean mAlwaysFinishActivities = false; 1023 IActivityController mController = null; 1024 String mProfileApp = null; 1025 ProcessRecord mProfileProc = null; 1026 String mProfileFile; 1027 ParcelFileDescriptor mProfileFd; 1028 int mProfileType = 0; 1029 boolean mAutoStopProfiler = false; 1030 String mOpenGlTraceApp = null; 1031 1032 static class ProcessChangeItem { 1033 static final int CHANGE_ACTIVITIES = 1<<0; 1034 static final int CHANGE_PROCESS_STATE = 1<<1; 1035 int changes; 1036 int uid; 1037 int pid; 1038 int processState; 1039 boolean foregroundActivities; 1040 } 1041 1042 final RemoteCallbackList<IProcessObserver> mProcessObservers 1043 = new RemoteCallbackList<IProcessObserver>(); 1044 ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5]; 1045 1046 final ArrayList<ProcessChangeItem> mPendingProcessChanges 1047 = new ArrayList<ProcessChangeItem>(); 1048 final ArrayList<ProcessChangeItem> mAvailProcessChanges 1049 = new ArrayList<ProcessChangeItem>(); 1050 1051 /** 1052 * Runtime CPU use collection thread. This object's lock is used to 1053 * protect all related state. 1054 */ 1055 final Thread mProcessCpuThread; 1056 1057 /** 1058 * Used to collect process stats when showing not responding dialog. 1059 * Protected by mProcessCpuThread. 1060 */ 1061 final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker( 1062 MONITOR_THREAD_CPU_USAGE); 1063 final AtomicLong mLastCpuTime = new AtomicLong(0); 1064 final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true); 1065 1066 long mLastWriteTime = 0; 1067 1068 /** 1069 * Used to retain an update lock when the foreground activity is in 1070 * immersive mode. 1071 */ 1072 final UpdateLock mUpdateLock = new UpdateLock("immersive"); 1073 1074 /** 1075 * Set to true after the system has finished booting. 1076 */ 1077 boolean mBooted = false; 1078 1079 int mProcessLimit = ProcessList.MAX_CACHED_APPS; 1080 int mProcessLimitOverride = -1; 1081 1082 WindowManagerService mWindowManager; 1083 1084 final ActivityThread mSystemThread; 1085 1086 int mCurrentUserId = 0; 1087 int[] mCurrentProfileIds = new int[] {UserHandle.USER_OWNER}; // Accessed by ActivityStack 1088 private UserManagerService mUserManager; 1089 1090 private final class AppDeathRecipient implements IBinder.DeathRecipient { 1091 final ProcessRecord mApp; 1092 final int mPid; 1093 final IApplicationThread mAppThread; 1094 1095 AppDeathRecipient(ProcessRecord app, int pid, 1096 IApplicationThread thread) { 1097 if (localLOGV) Slog.v( 1098 TAG, "New death recipient " + this 1099 + " for thread " + thread.asBinder()); 1100 mApp = app; 1101 mPid = pid; 1102 mAppThread = thread; 1103 } 1104 1105 @Override 1106 public void binderDied() { 1107 if (localLOGV) Slog.v( 1108 TAG, "Death received in " + this 1109 + " for thread " + mAppThread.asBinder()); 1110 synchronized(ActivityManagerService.this) { 1111 appDiedLocked(mApp, mPid, mAppThread); 1112 } 1113 } 1114 } 1115 1116 static final int SHOW_ERROR_MSG = 1; 1117 static final int SHOW_NOT_RESPONDING_MSG = 2; 1118 static final int SHOW_FACTORY_ERROR_MSG = 3; 1119 static final int UPDATE_CONFIGURATION_MSG = 4; 1120 static final int GC_BACKGROUND_PROCESSES_MSG = 5; 1121 static final int WAIT_FOR_DEBUGGER_MSG = 6; 1122 static final int SERVICE_TIMEOUT_MSG = 12; 1123 static final int UPDATE_TIME_ZONE = 13; 1124 static final int SHOW_UID_ERROR_MSG = 14; 1125 static final int IM_FEELING_LUCKY_MSG = 15; 1126 static final int PROC_START_TIMEOUT_MSG = 20; 1127 static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21; 1128 static final int KILL_APPLICATION_MSG = 22; 1129 static final int FINALIZE_PENDING_INTENT_MSG = 23; 1130 static final int POST_HEAVY_NOTIFICATION_MSG = 24; 1131 static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25; 1132 static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26; 1133 static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27; 1134 static final int CLEAR_DNS_CACHE_MSG = 28; 1135 static final int UPDATE_HTTP_PROXY_MSG = 29; 1136 static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30; 1137 static final int DISPATCH_PROCESSES_CHANGED = 31; 1138 static final int DISPATCH_PROCESS_DIED = 32; 1139 static final int REPORT_MEM_USAGE_MSG = 33; 1140 static final int REPORT_USER_SWITCH_MSG = 34; 1141 static final int CONTINUE_USER_SWITCH_MSG = 35; 1142 static final int USER_SWITCH_TIMEOUT_MSG = 36; 1143 static final int IMMERSIVE_MODE_LOCK_MSG = 37; 1144 static final int PERSIST_URI_GRANTS_MSG = 38; 1145 static final int REQUEST_ALL_PSS_MSG = 39; 1146 static final int START_PROFILES_MSG = 40; 1147 static final int UPDATE_TIME = 41; 1148 static final int SYSTEM_USER_START_MSG = 42; 1149 static final int SYSTEM_USER_CURRENT_MSG = 43; 1150 1151 static final int FIRST_ACTIVITY_STACK_MSG = 100; 1152 static final int FIRST_BROADCAST_QUEUE_MSG = 200; 1153 static final int FIRST_COMPAT_MODE_MSG = 300; 1154 static final int FIRST_SUPERVISOR_STACK_MSG = 100; 1155 1156 AlertDialog mUidAlert; 1157 CompatModeDialog mCompatModeDialog; 1158 long mLastMemUsageReportTime = 0; 1159 1160 /** 1161 * Flag whether the current user is a "monkey", i.e. whether 1162 * the UI is driven by a UI automation tool. 1163 */ 1164 private boolean mUserIsMonkey; 1165 1166 final ServiceThread mHandlerThread; 1167 final MainHandler mHandler; 1168 1169 final class MainHandler extends Handler { 1170 public MainHandler(Looper looper) { 1171 super(looper, null, true); 1172 } 1173 1174 @Override 1175 public void handleMessage(Message msg) { 1176 switch (msg.what) { 1177 case SHOW_ERROR_MSG: { 1178 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1179 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), 1180 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; 1181 synchronized (ActivityManagerService.this) { 1182 ProcessRecord proc = (ProcessRecord)data.get("app"); 1183 AppErrorResult res = (AppErrorResult) data.get("result"); 1184 if (proc != null && proc.crashDialog != null) { 1185 Slog.e(TAG, "App already has crash dialog: " + proc); 1186 if (res != null) { 1187 res.set(0); 1188 } 1189 return; 1190 } 1191 if (!showBackground && UserHandle.getAppId(proc.uid) 1192 >= Process.FIRST_APPLICATION_UID && proc.userId != mCurrentUserId 1193 && proc.pid != MY_PID) { 1194 Slog.w(TAG, "Skipping crash dialog of " + proc + ": background"); 1195 if (res != null) { 1196 res.set(0); 1197 } 1198 return; 1199 } 1200 if (mShowDialogs && !mSleeping && !mShuttingDown) { 1201 Dialog d = new AppErrorDialog(mContext, 1202 ActivityManagerService.this, res, proc); 1203 d.show(); 1204 proc.crashDialog = d; 1205 } else { 1206 // The device is asleep, so just pretend that the user 1207 // saw a crash dialog and hit "force quit". 1208 if (res != null) { 1209 res.set(0); 1210 } 1211 } 1212 } 1213 1214 ensureBootCompleted(); 1215 } break; 1216 case SHOW_NOT_RESPONDING_MSG: { 1217 synchronized (ActivityManagerService.this) { 1218 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1219 ProcessRecord proc = (ProcessRecord)data.get("app"); 1220 if (proc != null && proc.anrDialog != null) { 1221 Slog.e(TAG, "App already has anr dialog: " + proc); 1222 return; 1223 } 1224 1225 Intent intent = new Intent("android.intent.action.ANR"); 1226 if (!mProcessesReady) { 1227 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 1228 | Intent.FLAG_RECEIVER_FOREGROUND); 1229 } 1230 broadcastIntentLocked(null, null, intent, 1231 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 1232 false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */); 1233 1234 if (mShowDialogs) { 1235 Dialog d = new AppNotRespondingDialog(ActivityManagerService.this, 1236 mContext, proc, (ActivityRecord)data.get("activity"), 1237 msg.arg1 != 0); 1238 d.show(); 1239 proc.anrDialog = d; 1240 } else { 1241 // Just kill the app if there is no dialog to be shown. 1242 killAppAtUsersRequest(proc, null); 1243 } 1244 } 1245 1246 ensureBootCompleted(); 1247 } break; 1248 case SHOW_STRICT_MODE_VIOLATION_MSG: { 1249 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1250 synchronized (ActivityManagerService.this) { 1251 ProcessRecord proc = (ProcessRecord) data.get("app"); 1252 if (proc == null) { 1253 Slog.e(TAG, "App not found when showing strict mode dialog."); 1254 break; 1255 } 1256 if (proc.crashDialog != null) { 1257 Slog.e(TAG, "App already has strict mode dialog: " + proc); 1258 return; 1259 } 1260 AppErrorResult res = (AppErrorResult) data.get("result"); 1261 if (mShowDialogs && !mSleeping && !mShuttingDown) { 1262 Dialog d = new StrictModeViolationDialog(mContext, 1263 ActivityManagerService.this, res, proc); 1264 d.show(); 1265 proc.crashDialog = d; 1266 } else { 1267 // The device is asleep, so just pretend that the user 1268 // saw a crash dialog and hit "force quit". 1269 res.set(0); 1270 } 1271 } 1272 ensureBootCompleted(); 1273 } break; 1274 case SHOW_FACTORY_ERROR_MSG: { 1275 Dialog d = new FactoryErrorDialog( 1276 mContext, msg.getData().getCharSequence("msg")); 1277 d.show(); 1278 ensureBootCompleted(); 1279 } break; 1280 case UPDATE_CONFIGURATION_MSG: { 1281 final ContentResolver resolver = mContext.getContentResolver(); 1282 Settings.System.putConfiguration(resolver, (Configuration)msg.obj); 1283 } break; 1284 case GC_BACKGROUND_PROCESSES_MSG: { 1285 synchronized (ActivityManagerService.this) { 1286 performAppGcsIfAppropriateLocked(); 1287 } 1288 } break; 1289 case WAIT_FOR_DEBUGGER_MSG: { 1290 synchronized (ActivityManagerService.this) { 1291 ProcessRecord app = (ProcessRecord)msg.obj; 1292 if (msg.arg1 != 0) { 1293 if (!app.waitedForDebugger) { 1294 Dialog d = new AppWaitingForDebuggerDialog( 1295 ActivityManagerService.this, 1296 mContext, app); 1297 app.waitDialog = d; 1298 app.waitedForDebugger = true; 1299 d.show(); 1300 } 1301 } else { 1302 if (app.waitDialog != null) { 1303 app.waitDialog.dismiss(); 1304 app.waitDialog = null; 1305 } 1306 } 1307 } 1308 } break; 1309 case SERVICE_TIMEOUT_MSG: { 1310 if (mDidDexOpt) { 1311 mDidDexOpt = false; 1312 Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG); 1313 nmsg.obj = msg.obj; 1314 mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT); 1315 return; 1316 } 1317 mServices.serviceTimeout((ProcessRecord)msg.obj); 1318 } break; 1319 case UPDATE_TIME_ZONE: { 1320 synchronized (ActivityManagerService.this) { 1321 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1322 ProcessRecord r = mLruProcesses.get(i); 1323 if (r.thread != null) { 1324 try { 1325 r.thread.updateTimeZone(); 1326 } catch (RemoteException ex) { 1327 Slog.w(TAG, "Failed to update time zone for: " + r.info.processName); 1328 } 1329 } 1330 } 1331 } 1332 } break; 1333 case CLEAR_DNS_CACHE_MSG: { 1334 synchronized (ActivityManagerService.this) { 1335 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1336 ProcessRecord r = mLruProcesses.get(i); 1337 if (r.thread != null) { 1338 try { 1339 r.thread.clearDnsCache(); 1340 } catch (RemoteException ex) { 1341 Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName); 1342 } 1343 } 1344 } 1345 } 1346 } break; 1347 case UPDATE_HTTP_PROXY_MSG: { 1348 ProxyInfo proxy = (ProxyInfo)msg.obj; 1349 String host = ""; 1350 String port = ""; 1351 String exclList = ""; 1352 Uri pacFileUrl = Uri.EMPTY; 1353 if (proxy != null) { 1354 host = proxy.getHost(); 1355 port = Integer.toString(proxy.getPort()); 1356 exclList = proxy.getExclusionListAsString(); 1357 pacFileUrl = proxy.getPacFileUrl(); 1358 } 1359 synchronized (ActivityManagerService.this) { 1360 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1361 ProcessRecord r = mLruProcesses.get(i); 1362 if (r.thread != null) { 1363 try { 1364 r.thread.setHttpProxy(host, port, exclList, pacFileUrl); 1365 } catch (RemoteException ex) { 1366 Slog.w(TAG, "Failed to update http proxy for: " + 1367 r.info.processName); 1368 } 1369 } 1370 } 1371 } 1372 } break; 1373 case SHOW_UID_ERROR_MSG: { 1374 String title = "System UIDs Inconsistent"; 1375 String text = "UIDs on the system are inconsistent, you need to wipe your" 1376 + " data partition or your device will be unstable."; 1377 Log.e(TAG, title + ": " + text); 1378 if (mShowDialogs) { 1379 // XXX This is a temporary dialog, no need to localize. 1380 AlertDialog d = new BaseErrorDialog(mContext); 1381 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR); 1382 d.setCancelable(false); 1383 d.setTitle(title); 1384 d.setMessage(text); 1385 d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky", 1386 mHandler.obtainMessage(IM_FEELING_LUCKY_MSG)); 1387 mUidAlert = d; 1388 d.show(); 1389 } 1390 } break; 1391 case IM_FEELING_LUCKY_MSG: { 1392 if (mUidAlert != null) { 1393 mUidAlert.dismiss(); 1394 mUidAlert = null; 1395 } 1396 } break; 1397 case PROC_START_TIMEOUT_MSG: { 1398 if (mDidDexOpt) { 1399 mDidDexOpt = false; 1400 Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 1401 nmsg.obj = msg.obj; 1402 mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT); 1403 return; 1404 } 1405 ProcessRecord app = (ProcessRecord)msg.obj; 1406 synchronized (ActivityManagerService.this) { 1407 processStartTimedOutLocked(app); 1408 } 1409 } break; 1410 case DO_PENDING_ACTIVITY_LAUNCHES_MSG: { 1411 synchronized (ActivityManagerService.this) { 1412 doPendingActivityLaunchesLocked(true); 1413 } 1414 } break; 1415 case KILL_APPLICATION_MSG: { 1416 synchronized (ActivityManagerService.this) { 1417 int appid = msg.arg1; 1418 boolean restart = (msg.arg2 == 1); 1419 Bundle bundle = (Bundle)msg.obj; 1420 String pkg = bundle.getString("pkg"); 1421 String reason = bundle.getString("reason"); 1422 forceStopPackageLocked(pkg, appid, restart, false, true, false, 1423 false, UserHandle.USER_ALL, reason); 1424 } 1425 } break; 1426 case FINALIZE_PENDING_INTENT_MSG: { 1427 ((PendingIntentRecord)msg.obj).completeFinalize(); 1428 } break; 1429 case POST_HEAVY_NOTIFICATION_MSG: { 1430 INotificationManager inm = NotificationManager.getService(); 1431 if (inm == null) { 1432 return; 1433 } 1434 1435 ActivityRecord root = (ActivityRecord)msg.obj; 1436 ProcessRecord process = root.app; 1437 if (process == null) { 1438 return; 1439 } 1440 1441 try { 1442 Context context = mContext.createPackageContext(process.info.packageName, 0); 1443 String text = mContext.getString(R.string.heavy_weight_notification, 1444 context.getApplicationInfo().loadLabel(context.getPackageManager())); 1445 Notification notification = new Notification(); 1446 notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon; 1447 notification.when = 0; 1448 notification.flags = Notification.FLAG_ONGOING_EVENT; 1449 notification.tickerText = text; 1450 notification.defaults = 0; // please be quiet 1451 notification.sound = null; 1452 notification.vibrate = null; 1453 notification.setLatestEventInfo(context, text, 1454 mContext.getText(R.string.heavy_weight_notification_detail), 1455 PendingIntent.getActivityAsUser(mContext, 0, root.intent, 1456 PendingIntent.FLAG_CANCEL_CURRENT, null, 1457 new UserHandle(root.userId))); 1458 1459 try { 1460 int[] outId = new int[1]; 1461 inm.enqueueNotificationWithTag("android", "android", null, 1462 R.string.heavy_weight_notification, 1463 notification, outId, root.userId); 1464 } catch (RuntimeException e) { 1465 Slog.w(ActivityManagerService.TAG, 1466 "Error showing notification for heavy-weight app", e); 1467 } catch (RemoteException e) { 1468 } 1469 } catch (NameNotFoundException e) { 1470 Slog.w(TAG, "Unable to create context for heavy notification", e); 1471 } 1472 } break; 1473 case CANCEL_HEAVY_NOTIFICATION_MSG: { 1474 INotificationManager inm = NotificationManager.getService(); 1475 if (inm == null) { 1476 return; 1477 } 1478 try { 1479 inm.cancelNotificationWithTag("android", null, 1480 R.string.heavy_weight_notification, msg.arg1); 1481 } catch (RuntimeException e) { 1482 Slog.w(ActivityManagerService.TAG, 1483 "Error canceling notification for service", e); 1484 } catch (RemoteException e) { 1485 } 1486 } break; 1487 case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: { 1488 synchronized (ActivityManagerService.this) { 1489 checkExcessivePowerUsageLocked(true); 1490 removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1491 Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1492 sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 1493 } 1494 } break; 1495 case SHOW_COMPAT_MODE_DIALOG_MSG: { 1496 synchronized (ActivityManagerService.this) { 1497 ActivityRecord ar = (ActivityRecord)msg.obj; 1498 if (mCompatModeDialog != null) { 1499 if (mCompatModeDialog.mAppInfo.packageName.equals( 1500 ar.info.applicationInfo.packageName)) { 1501 return; 1502 } 1503 mCompatModeDialog.dismiss(); 1504 mCompatModeDialog = null; 1505 } 1506 if (ar != null && false) { 1507 if (mCompatModePackages.getPackageAskCompatModeLocked( 1508 ar.packageName)) { 1509 int mode = mCompatModePackages.computeCompatModeLocked( 1510 ar.info.applicationInfo); 1511 if (mode == ActivityManager.COMPAT_MODE_DISABLED 1512 || mode == ActivityManager.COMPAT_MODE_ENABLED) { 1513 mCompatModeDialog = new CompatModeDialog( 1514 ActivityManagerService.this, mContext, 1515 ar.info.applicationInfo); 1516 mCompatModeDialog.show(); 1517 } 1518 } 1519 } 1520 } 1521 break; 1522 } 1523 case DISPATCH_PROCESSES_CHANGED: { 1524 dispatchProcessesChanged(); 1525 break; 1526 } 1527 case DISPATCH_PROCESS_DIED: { 1528 final int pid = msg.arg1; 1529 final int uid = msg.arg2; 1530 dispatchProcessDied(pid, uid); 1531 break; 1532 } 1533 case REPORT_MEM_USAGE_MSG: { 1534 final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj; 1535 Thread thread = new Thread() { 1536 @Override public void run() { 1537 final SparseArray<ProcessMemInfo> infoMap 1538 = new SparseArray<ProcessMemInfo>(memInfos.size()); 1539 for (int i=0, N=memInfos.size(); i<N; i++) { 1540 ProcessMemInfo mi = memInfos.get(i); 1541 infoMap.put(mi.pid, mi); 1542 } 1543 updateCpuStatsNow(); 1544 synchronized (mProcessCpuThread) { 1545 final int N = mProcessCpuTracker.countStats(); 1546 for (int i=0; i<N; i++) { 1547 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 1548 if (st.vsize > 0) { 1549 long pss = Debug.getPss(st.pid, null); 1550 if (pss > 0) { 1551 if (infoMap.indexOfKey(st.pid) < 0) { 1552 ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid, 1553 ProcessList.NATIVE_ADJ, -1, "native", null); 1554 mi.pss = pss; 1555 memInfos.add(mi); 1556 } 1557 } 1558 } 1559 } 1560 } 1561 1562 long totalPss = 0; 1563 for (int i=0, N=memInfos.size(); i<N; i++) { 1564 ProcessMemInfo mi = memInfos.get(i); 1565 if (mi.pss == 0) { 1566 mi.pss = Debug.getPss(mi.pid, null); 1567 } 1568 totalPss += mi.pss; 1569 } 1570 Collections.sort(memInfos, new Comparator<ProcessMemInfo>() { 1571 @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) { 1572 if (lhs.oomAdj != rhs.oomAdj) { 1573 return lhs.oomAdj < rhs.oomAdj ? -1 : 1; 1574 } 1575 if (lhs.pss != rhs.pss) { 1576 return lhs.pss < rhs.pss ? 1 : -1; 1577 } 1578 return 0; 1579 } 1580 }); 1581 1582 StringBuilder tag = new StringBuilder(128); 1583 StringBuilder stack = new StringBuilder(128); 1584 tag.append("Low on memory -- "); 1585 appendMemBucket(tag, totalPss, "total", false); 1586 appendMemBucket(stack, totalPss, "total", true); 1587 1588 StringBuilder logBuilder = new StringBuilder(1024); 1589 logBuilder.append("Low on memory:\n"); 1590 1591 boolean firstLine = true; 1592 int lastOomAdj = Integer.MIN_VALUE; 1593 for (int i=0, N=memInfos.size(); i<N; i++) { 1594 ProcessMemInfo mi = memInfos.get(i); 1595 1596 if (mi.oomAdj != ProcessList.NATIVE_ADJ 1597 && (mi.oomAdj < ProcessList.SERVICE_ADJ 1598 || mi.oomAdj == ProcessList.HOME_APP_ADJ 1599 || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) { 1600 if (lastOomAdj != mi.oomAdj) { 1601 lastOomAdj = mi.oomAdj; 1602 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) { 1603 tag.append(" / "); 1604 } 1605 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) { 1606 if (firstLine) { 1607 stack.append(":"); 1608 firstLine = false; 1609 } 1610 stack.append("\n\t at "); 1611 } else { 1612 stack.append("$"); 1613 } 1614 } else { 1615 tag.append(" "); 1616 stack.append("$"); 1617 } 1618 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) { 1619 appendMemBucket(tag, mi.pss, mi.name, false); 1620 } 1621 appendMemBucket(stack, mi.pss, mi.name, true); 1622 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ 1623 && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) { 1624 stack.append("("); 1625 for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) { 1626 if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) { 1627 stack.append(DUMP_MEM_OOM_LABEL[k]); 1628 stack.append(":"); 1629 stack.append(DUMP_MEM_OOM_ADJ[k]); 1630 } 1631 } 1632 stack.append(")"); 1633 } 1634 } 1635 1636 logBuilder.append(" "); 1637 logBuilder.append(ProcessList.makeOomAdjString(mi.oomAdj)); 1638 logBuilder.append(' '); 1639 logBuilder.append(ProcessList.makeProcStateString(mi.procState)); 1640 logBuilder.append(' '); 1641 ProcessList.appendRamKb(logBuilder, mi.pss); 1642 logBuilder.append(" kB: "); 1643 logBuilder.append(mi.name); 1644 logBuilder.append(" ("); 1645 logBuilder.append(mi.pid); 1646 logBuilder.append(") "); 1647 logBuilder.append(mi.adjType); 1648 logBuilder.append('\n'); 1649 if (mi.adjReason != null) { 1650 logBuilder.append(" "); 1651 logBuilder.append(mi.adjReason); 1652 logBuilder.append('\n'); 1653 } 1654 } 1655 1656 logBuilder.append(" "); 1657 ProcessList.appendRamKb(logBuilder, totalPss); 1658 logBuilder.append(" kB: TOTAL\n"); 1659 1660 long[] infos = new long[Debug.MEMINFO_COUNT]; 1661 Debug.getMemInfo(infos); 1662 logBuilder.append(" MemInfo: "); 1663 logBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, "); 1664 logBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, "); 1665 logBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, "); 1666 logBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, "); 1667 logBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n"); 1668 if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) { 1669 logBuilder.append(" ZRAM: "); 1670 logBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]); 1671 logBuilder.append(" kB RAM, "); 1672 logBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]); 1673 logBuilder.append(" kB swap total, "); 1674 logBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]); 1675 logBuilder.append(" kB swap free\n"); 1676 } 1677 Slog.i(TAG, logBuilder.toString()); 1678 1679 StringBuilder dropBuilder = new StringBuilder(1024); 1680 /* 1681 StringWriter oomSw = new StringWriter(); 1682 PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256); 1683 StringWriter catSw = new StringWriter(); 1684 PrintWriter catPw = new FastPrintWriter(catSw, false, 256); 1685 String[] emptyArgs = new String[] { }; 1686 dumpApplicationMemoryUsage(null, oomPw, " ", emptyArgs, true, catPw); 1687 oomPw.flush(); 1688 String oomString = oomSw.toString(); 1689 */ 1690 dropBuilder.append(stack); 1691 dropBuilder.append('\n'); 1692 dropBuilder.append('\n'); 1693 dropBuilder.append(logBuilder); 1694 dropBuilder.append('\n'); 1695 /* 1696 dropBuilder.append(oomString); 1697 dropBuilder.append('\n'); 1698 */ 1699 StringWriter catSw = new StringWriter(); 1700 synchronized (ActivityManagerService.this) { 1701 PrintWriter catPw = new FastPrintWriter(catSw, false, 256); 1702 String[] emptyArgs = new String[] { }; 1703 catPw.println(); 1704 dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null); 1705 catPw.println(); 1706 mServices.dumpServicesLocked(null, catPw, emptyArgs, 0, 1707 false, false, null); 1708 catPw.println(); 1709 dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null); 1710 catPw.flush(); 1711 } 1712 dropBuilder.append(catSw.toString()); 1713 addErrorToDropBox("lowmem", null, "system_server", null, 1714 null, tag.toString(), dropBuilder.toString(), null, null); 1715 //Slog.i(TAG, "Sent to dropbox:"); 1716 //Slog.i(TAG, dropBuilder.toString()); 1717 synchronized (ActivityManagerService.this) { 1718 long now = SystemClock.uptimeMillis(); 1719 if (mLastMemUsageReportTime < now) { 1720 mLastMemUsageReportTime = now; 1721 } 1722 } 1723 } 1724 }; 1725 thread.start(); 1726 break; 1727 } 1728 case REPORT_USER_SWITCH_MSG: { 1729 dispatchUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2); 1730 break; 1731 } 1732 case CONTINUE_USER_SWITCH_MSG: { 1733 continueUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2); 1734 break; 1735 } 1736 case USER_SWITCH_TIMEOUT_MSG: { 1737 timeoutUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2); 1738 break; 1739 } 1740 case IMMERSIVE_MODE_LOCK_MSG: { 1741 final boolean nextState = (msg.arg1 != 0); 1742 if (mUpdateLock.isHeld() != nextState) { 1743 if (DEBUG_IMMERSIVE) { 1744 final ActivityRecord r = (ActivityRecord) msg.obj; 1745 Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r); 1746 } 1747 if (nextState) { 1748 mUpdateLock.acquire(); 1749 } else { 1750 mUpdateLock.release(); 1751 } 1752 } 1753 break; 1754 } 1755 case PERSIST_URI_GRANTS_MSG: { 1756 writeGrantedUriPermissions(); 1757 break; 1758 } 1759 case REQUEST_ALL_PSS_MSG: { 1760 requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false); 1761 break; 1762 } 1763 case START_PROFILES_MSG: { 1764 synchronized (ActivityManagerService.this) { 1765 startProfilesLocked(); 1766 } 1767 break; 1768 } 1769 case UPDATE_TIME: { 1770 synchronized (ActivityManagerService.this) { 1771 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1772 ProcessRecord r = mLruProcesses.get(i); 1773 if (r.thread != null) { 1774 try { 1775 r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true); 1776 } catch (RemoteException ex) { 1777 Slog.w(TAG, "Failed to update preferences for: " + r.info.processName); 1778 } 1779 } 1780 } 1781 } 1782 break; 1783 } 1784 case SYSTEM_USER_START_MSG: { 1785 mSystemServiceManager.startUser(msg.arg1); 1786 break; 1787 } 1788 case SYSTEM_USER_CURRENT_MSG: { 1789 mSystemServiceManager.switchUser(msg.arg1); 1790 break; 1791 } 1792 } 1793 } 1794 }; 1795 1796 static final int COLLECT_PSS_BG_MSG = 1; 1797 1798 final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) { 1799 @Override 1800 public void handleMessage(Message msg) { 1801 switch (msg.what) { 1802 case COLLECT_PSS_BG_MSG: { 1803 int i=0, num=0; 1804 long start = SystemClock.uptimeMillis(); 1805 long[] tmp = new long[1]; 1806 do { 1807 ProcessRecord proc; 1808 int procState; 1809 int pid; 1810 synchronized (ActivityManagerService.this) { 1811 if (i >= mPendingPssProcesses.size()) { 1812 if (DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num + " of " + i 1813 + " processes in " + (SystemClock.uptimeMillis()-start) + "ms"); 1814 mPendingPssProcesses.clear(); 1815 return; 1816 } 1817 proc = mPendingPssProcesses.get(i); 1818 procState = proc.pssProcState; 1819 if (proc.thread != null && procState == proc.setProcState) { 1820 pid = proc.pid; 1821 } else { 1822 proc = null; 1823 pid = 0; 1824 } 1825 i++; 1826 } 1827 if (proc != null) { 1828 long pss = Debug.getPss(pid, tmp); 1829 synchronized (ActivityManagerService.this) { 1830 if (proc.thread != null && proc.setProcState == procState 1831 && proc.pid == pid) { 1832 num++; 1833 proc.lastPssTime = SystemClock.uptimeMillis(); 1834 proc.baseProcessTracker.addPss(pss, tmp[0], true, proc.pkgList); 1835 if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString() 1836 + ": " + pss + " lastPss=" + proc.lastPss 1837 + " state=" + ProcessList.makeProcStateString(procState)); 1838 if (proc.initialIdlePss == 0) { 1839 proc.initialIdlePss = pss; 1840 } 1841 proc.lastPss = pss; 1842 if (procState >= ActivityManager.PROCESS_STATE_HOME) { 1843 proc.lastCachedPss = pss; 1844 } 1845 } 1846 } 1847 } 1848 } while (true); 1849 } 1850 } 1851 } 1852 }; 1853 1854 /** 1855 * Monitor for package changes and update our internal state. 1856 */ 1857 private final PackageMonitor mPackageMonitor = new PackageMonitor() { 1858 @Override 1859 public void onPackageRemoved(String packageName, int uid) { 1860 // Remove all tasks with activities in the specified package from the list of recent tasks 1861 synchronized (ActivityManagerService.this) { 1862 for (int i = mRecentTasks.size() - 1; i >= 0; i--) { 1863 TaskRecord tr = mRecentTasks.get(i); 1864 ComponentName cn = tr.intent.getComponent(); 1865 if (cn != null && cn.getPackageName().equals(packageName)) { 1866 // If the package name matches, remove the task and kill the process 1867 removeTaskByIdLocked(tr.taskId, ActivityManager.REMOVE_TASK_KILL_PROCESS); 1868 } 1869 } 1870 } 1871 } 1872 1873 @Override 1874 public boolean onPackageChanged(String packageName, int uid, String[] components) { 1875 onPackageModified(packageName); 1876 return true; 1877 } 1878 1879 @Override 1880 public void onPackageModified(String packageName) { 1881 final PackageManager pm = mContext.getPackageManager(); 1882 final ArrayList<Pair<Intent, Integer>> recentTaskIntents = 1883 new ArrayList<Pair<Intent, Integer>>(); 1884 final ArrayList<Integer> tasksToRemove = new ArrayList<Integer>(); 1885 // Copy the list of recent tasks so that we don't hold onto the lock on 1886 // ActivityManagerService for long periods while checking if components exist. 1887 synchronized (ActivityManagerService.this) { 1888 for (int i = mRecentTasks.size() - 1; i >= 0; i--) { 1889 TaskRecord tr = mRecentTasks.get(i); 1890 recentTaskIntents.add(new Pair<Intent, Integer>(tr.intent, tr.taskId)); 1891 } 1892 } 1893 // Check the recent tasks and filter out all tasks with components that no longer exist. 1894 Intent tmpI = new Intent(); 1895 for (int i = recentTaskIntents.size() - 1; i >= 0; i--) { 1896 Pair<Intent, Integer> p = recentTaskIntents.get(i); 1897 ComponentName cn = p.first.getComponent(); 1898 if (cn != null && cn.getPackageName().equals(packageName)) { 1899 try { 1900 // Add the task to the list to remove if the component no longer exists 1901 tmpI.setComponent(cn); 1902 if (pm.queryIntentActivities(tmpI, PackageManager.MATCH_DEFAULT_ONLY).isEmpty()) { 1903 tasksToRemove.add(p.second); 1904 } 1905 } catch (Exception e) {} 1906 } 1907 } 1908 // Prune all the tasks with removed components from the list of recent tasks 1909 synchronized (ActivityManagerService.this) { 1910 for (int i = tasksToRemove.size() - 1; i >= 0; i--) { 1911 // Remove the task but don't kill the process (since other components in that 1912 // package may still be running and in the background) 1913 removeTaskByIdLocked(tasksToRemove.get(i), 0); 1914 } 1915 } 1916 } 1917 1918 @Override 1919 public boolean onHandleForceStop(Intent intent, String[] packages, int uid, boolean doit) { 1920 // Force stop the specified packages 1921 if (packages != null) { 1922 for (String pkg : packages) { 1923 synchronized (ActivityManagerService.this) { 1924 if (forceStopPackageLocked(pkg, -1, false, false, false, false, false, 0, 1925 "finished booting")) { 1926 return true; 1927 } 1928 } 1929 } 1930 } 1931 return false; 1932 } 1933 }; 1934 1935 public void setSystemProcess() { 1936 try { 1937 ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true); 1938 ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats); 1939 ServiceManager.addService("meminfo", new MemBinder(this)); 1940 ServiceManager.addService("gfxinfo", new GraphicsBinder(this)); 1941 ServiceManager.addService("dbinfo", new DbBinder(this)); 1942 if (MONITOR_CPU_USAGE) { 1943 ServiceManager.addService("cpuinfo", new CpuBinder(this)); 1944 } 1945 ServiceManager.addService("permission", new PermissionController(this)); 1946 1947 ApplicationInfo info = mContext.getPackageManager().getApplicationInfo( 1948 "android", STOCK_PM_FLAGS); 1949 mSystemThread.installSystemApplicationInfo(info); 1950 1951 synchronized (this) { 1952 ProcessRecord app = newProcessRecordLocked(info, info.processName, false); 1953 app.persistent = true; 1954 app.pid = MY_PID; 1955 app.maxAdj = ProcessList.SYSTEM_ADJ; 1956 app.makeActive(mSystemThread.getApplicationThread(), mProcessStats); 1957 mProcessNames.put(app.processName, app.uid, app); 1958 synchronized (mPidsSelfLocked) { 1959 mPidsSelfLocked.put(app.pid, app); 1960 } 1961 updateLruProcessLocked(app, false, null); 1962 updateOomAdjLocked(); 1963 } 1964 } catch (PackageManager.NameNotFoundException e) { 1965 throw new RuntimeException( 1966 "Unable to find android system package", e); 1967 } 1968 } 1969 1970 public void setWindowManager(WindowManagerService wm) { 1971 mWindowManager = wm; 1972 mStackSupervisor.setWindowManager(wm); 1973 } 1974 1975 public void startObservingNativeCrashes() { 1976 final NativeCrashListener ncl = new NativeCrashListener(this); 1977 ncl.start(); 1978 } 1979 1980 public IAppOpsService getAppOpsService() { 1981 return mAppOpsService; 1982 } 1983 1984 static class MemBinder extends Binder { 1985 ActivityManagerService mActivityManagerService; 1986 MemBinder(ActivityManagerService activityManagerService) { 1987 mActivityManagerService = activityManagerService; 1988 } 1989 1990 @Override 1991 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1992 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1993 != PackageManager.PERMISSION_GRANTED) { 1994 pw.println("Permission Denial: can't dump meminfo from from pid=" 1995 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1996 + " without permission " + android.Manifest.permission.DUMP); 1997 return; 1998 } 1999 2000 mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, " ", args, false, null); 2001 } 2002 } 2003 2004 static class GraphicsBinder extends Binder { 2005 ActivityManagerService mActivityManagerService; 2006 GraphicsBinder(ActivityManagerService activityManagerService) { 2007 mActivityManagerService = activityManagerService; 2008 } 2009 2010 @Override 2011 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 2012 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 2013 != PackageManager.PERMISSION_GRANTED) { 2014 pw.println("Permission Denial: can't dump gfxinfo from from pid=" 2015 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 2016 + " without permission " + android.Manifest.permission.DUMP); 2017 return; 2018 } 2019 2020 mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args); 2021 } 2022 } 2023 2024 static class DbBinder extends Binder { 2025 ActivityManagerService mActivityManagerService; 2026 DbBinder(ActivityManagerService activityManagerService) { 2027 mActivityManagerService = activityManagerService; 2028 } 2029 2030 @Override 2031 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 2032 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 2033 != PackageManager.PERMISSION_GRANTED) { 2034 pw.println("Permission Denial: can't dump dbinfo from from pid=" 2035 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 2036 + " without permission " + android.Manifest.permission.DUMP); 2037 return; 2038 } 2039 2040 mActivityManagerService.dumpDbInfo(fd, pw, args); 2041 } 2042 } 2043 2044 static class CpuBinder extends Binder { 2045 ActivityManagerService mActivityManagerService; 2046 CpuBinder(ActivityManagerService activityManagerService) { 2047 mActivityManagerService = activityManagerService; 2048 } 2049 2050 @Override 2051 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 2052 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 2053 != PackageManager.PERMISSION_GRANTED) { 2054 pw.println("Permission Denial: can't dump cpuinfo from from pid=" 2055 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 2056 + " without permission " + android.Manifest.permission.DUMP); 2057 return; 2058 } 2059 2060 synchronized (mActivityManagerService.mProcessCpuThread) { 2061 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad()); 2062 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState( 2063 SystemClock.uptimeMillis())); 2064 } 2065 } 2066 } 2067 2068 public static final class Lifecycle extends SystemService { 2069 private final ActivityManagerService mService; 2070 2071 public Lifecycle(Context context) { 2072 super(context); 2073 mService = new ActivityManagerService(context); 2074 } 2075 2076 @Override 2077 public void onStart() { 2078 mService.start(); 2079 } 2080 2081 public ActivityManagerService getService() { 2082 return mService; 2083 } 2084 } 2085 2086 // Note: This method is invoked on the main thread but may need to attach various 2087 // handlers to other threads. So take care to be explicit about the looper. 2088 public ActivityManagerService(Context systemContext) { 2089 mContext = systemContext; 2090 mFactoryTest = FactoryTest.getMode(); 2091 mSystemThread = ActivityThread.currentActivityThread(); 2092 2093 Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass()); 2094 2095 mHandlerThread = new ServiceThread(TAG, 2096 android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/); 2097 mHandlerThread.start(); 2098 mHandler = new MainHandler(mHandlerThread.getLooper()); 2099 2100 mFgBroadcastQueue = new BroadcastQueue(this, mHandler, 2101 "foreground", BROADCAST_FG_TIMEOUT, false); 2102 mBgBroadcastQueue = new BroadcastQueue(this, mHandler, 2103 "background", BROADCAST_BG_TIMEOUT, true); 2104 mBroadcastQueues[0] = mFgBroadcastQueue; 2105 mBroadcastQueues[1] = mBgBroadcastQueue; 2106 2107 mServices = new ActiveServices(this); 2108 mProviderMap = new ProviderMap(this); 2109 2110 // TODO: Move creation of battery stats service outside of activity manager service. 2111 File dataDir = Environment.getDataDirectory(); 2112 File systemDir = new File(dataDir, "system"); 2113 systemDir.mkdirs(); 2114 mBatteryStatsService = new BatteryStatsService(new File( 2115 systemDir, "batterystats.bin").toString(), mHandler); 2116 mBatteryStatsService.getActiveStatistics().readLocked(); 2117 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 2118 mOnBattery = DEBUG_POWER ? true 2119 : mBatteryStatsService.getActiveStatistics().getIsOnBattery(); 2120 mBatteryStatsService.getActiveStatistics().setCallback(this); 2121 2122 mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats")); 2123 2124 mUsageStatsService = new UsageStatsService(new File(systemDir, "usagestats").toString()); 2125 mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler); 2126 2127 mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml")); 2128 2129 // User 0 is the first and only user that runs at boot. 2130 mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true)); 2131 mUserLru.add(Integer.valueOf(0)); 2132 updateStartedUserArrayLocked(); 2133 2134 GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version", 2135 ConfigurationInfo.GL_ES_VERSION_UNDEFINED); 2136 2137 mConfiguration.setToDefaults(); 2138 mConfiguration.setLocale(Locale.getDefault()); 2139 2140 mConfigurationSeq = mConfiguration.seq = 1; 2141 mProcessCpuTracker.init(); 2142 2143 mCompatModePackages = new CompatModePackages(this, systemDir, mHandler); 2144 mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler); 2145 mStackSupervisor = new ActivityStackSupervisor(this); 2146 mTaskPersister = new TaskPersister(systemDir, mStackSupervisor); 2147 2148 mProcessCpuThread = new Thread("CpuTracker") { 2149 @Override 2150 public void run() { 2151 while (true) { 2152 try { 2153 try { 2154 synchronized(this) { 2155 final long now = SystemClock.uptimeMillis(); 2156 long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now; 2157 long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now; 2158 //Slog.i(TAG, "Cpu delay=" + nextCpuDelay 2159 // + ", write delay=" + nextWriteDelay); 2160 if (nextWriteDelay < nextCpuDelay) { 2161 nextCpuDelay = nextWriteDelay; 2162 } 2163 if (nextCpuDelay > 0) { 2164 mProcessCpuMutexFree.set(true); 2165 this.wait(nextCpuDelay); 2166 } 2167 } 2168 } catch (InterruptedException e) { 2169 } 2170 updateCpuStatsNow(); 2171 } catch (Exception e) { 2172 Slog.e(TAG, "Unexpected exception collecting process stats", e); 2173 } 2174 } 2175 } 2176 }; 2177 2178 Watchdog.getInstance().addMonitor(this); 2179 Watchdog.getInstance().addThread(mHandler); 2180 } 2181 2182 public void setSystemServiceManager(SystemServiceManager mgr) { 2183 mSystemServiceManager = mgr; 2184 } 2185 2186 private void start() { 2187 mProcessCpuThread.start(); 2188 2189 mBatteryStatsService.publish(mContext); 2190 mUsageStatsService.publish(mContext); 2191 mAppOpsService.publish(mContext); 2192 2193 LocalServices.addService(ActivityManagerInternal.class, new LocalService()); 2194 } 2195 2196 @Override 2197 public boolean onTransact(int code, Parcel data, Parcel reply, int flags) 2198 throws RemoteException { 2199 if (code == SYSPROPS_TRANSACTION) { 2200 // We need to tell all apps about the system property change. 2201 ArrayList<IBinder> procs = new ArrayList<IBinder>(); 2202 synchronized(this) { 2203 final int NP = mProcessNames.getMap().size(); 2204 for (int ip=0; ip<NP; ip++) { 2205 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 2206 final int NA = apps.size(); 2207 for (int ia=0; ia<NA; ia++) { 2208 ProcessRecord app = apps.valueAt(ia); 2209 if (app.thread != null) { 2210 procs.add(app.thread.asBinder()); 2211 } 2212 } 2213 } 2214 } 2215 2216 int N = procs.size(); 2217 for (int i=0; i<N; i++) { 2218 Parcel data2 = Parcel.obtain(); 2219 try { 2220 procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0); 2221 } catch (RemoteException e) { 2222 } 2223 data2.recycle(); 2224 } 2225 } 2226 try { 2227 return super.onTransact(code, data, reply, flags); 2228 } catch (RuntimeException e) { 2229 // The activity manager only throws security exceptions, so let's 2230 // log all others. 2231 if (!(e instanceof SecurityException)) { 2232 Slog.wtf(TAG, "Activity Manager Crash", e); 2233 } 2234 throw e; 2235 } 2236 } 2237 2238 void updateCpuStats() { 2239 final long now = SystemClock.uptimeMillis(); 2240 if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) { 2241 return; 2242 } 2243 if (mProcessCpuMutexFree.compareAndSet(true, false)) { 2244 synchronized (mProcessCpuThread) { 2245 mProcessCpuThread.notify(); 2246 } 2247 } 2248 } 2249 2250 void updateCpuStatsNow() { 2251 synchronized (mProcessCpuThread) { 2252 mProcessCpuMutexFree.set(false); 2253 final long now = SystemClock.uptimeMillis(); 2254 boolean haveNewCpuStats = false; 2255 2256 if (MONITOR_CPU_USAGE && 2257 mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) { 2258 mLastCpuTime.set(now); 2259 haveNewCpuStats = true; 2260 mProcessCpuTracker.update(); 2261 //Slog.i(TAG, mProcessCpu.printCurrentState()); 2262 //Slog.i(TAG, "Total CPU usage: " 2263 // + mProcessCpu.getTotalCpuPercent() + "%"); 2264 2265 // Slog the cpu usage if the property is set. 2266 if ("true".equals(SystemProperties.get("events.cpu"))) { 2267 int user = mProcessCpuTracker.getLastUserTime(); 2268 int system = mProcessCpuTracker.getLastSystemTime(); 2269 int iowait = mProcessCpuTracker.getLastIoWaitTime(); 2270 int irq = mProcessCpuTracker.getLastIrqTime(); 2271 int softIrq = mProcessCpuTracker.getLastSoftIrqTime(); 2272 int idle = mProcessCpuTracker.getLastIdleTime(); 2273 2274 int total = user + system + iowait + irq + softIrq + idle; 2275 if (total == 0) total = 1; 2276 2277 EventLog.writeEvent(EventLogTags.CPU, 2278 ((user+system+iowait+irq+softIrq) * 100) / total, 2279 (user * 100) / total, 2280 (system * 100) / total, 2281 (iowait * 100) / total, 2282 (irq * 100) / total, 2283 (softIrq * 100) / total); 2284 } 2285 } 2286 2287 long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes(); 2288 final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics(); 2289 synchronized(bstats) { 2290 synchronized(mPidsSelfLocked) { 2291 if (haveNewCpuStats) { 2292 if (mOnBattery) { 2293 int perc = bstats.startAddingCpuLocked(); 2294 int totalUTime = 0; 2295 int totalSTime = 0; 2296 final int N = mProcessCpuTracker.countStats(); 2297 for (int i=0; i<N; i++) { 2298 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 2299 if (!st.working) { 2300 continue; 2301 } 2302 ProcessRecord pr = mPidsSelfLocked.get(st.pid); 2303 int otherUTime = (st.rel_utime*perc)/100; 2304 int otherSTime = (st.rel_stime*perc)/100; 2305 totalUTime += otherUTime; 2306 totalSTime += otherSTime; 2307 if (pr != null) { 2308 BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats; 2309 if (ps == null || !ps.isActive()) { 2310 pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked( 2311 pr.info.uid, pr.processName); 2312 } 2313 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 2314 st.rel_stime-otherSTime); 2315 ps.addSpeedStepTimes(cpuSpeedTimes); 2316 pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10; 2317 } else { 2318 BatteryStatsImpl.Uid.Proc ps = st.batteryStats; 2319 if (ps == null || !ps.isActive()) { 2320 st.batteryStats = ps = bstats.getProcessStatsLocked( 2321 bstats.mapUid(st.uid), st.name); 2322 } 2323 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 2324 st.rel_stime-otherSTime); 2325 ps.addSpeedStepTimes(cpuSpeedTimes); 2326 } 2327 } 2328 bstats.finishAddingCpuLocked(perc, totalUTime, 2329 totalSTime, cpuSpeedTimes); 2330 } 2331 } 2332 } 2333 2334 if (mLastWriteTime < (now-BATTERY_STATS_TIME)) { 2335 mLastWriteTime = now; 2336 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 2337 } 2338 } 2339 } 2340 } 2341 2342 @Override 2343 public void batteryNeedsCpuUpdate() { 2344 updateCpuStatsNow(); 2345 } 2346 2347 @Override 2348 public void batteryPowerChanged(boolean onBattery) { 2349 // When plugging in, update the CPU stats first before changing 2350 // the plug state. 2351 updateCpuStatsNow(); 2352 synchronized (this) { 2353 synchronized(mPidsSelfLocked) { 2354 mOnBattery = DEBUG_POWER ? true : onBattery; 2355 } 2356 } 2357 } 2358 2359 /** 2360 * Initialize the application bind args. These are passed to each 2361 * process when the bindApplication() IPC is sent to the process. They're 2362 * lazily setup to make sure the services are running when they're asked for. 2363 */ 2364 private HashMap<String, IBinder> getCommonServicesLocked() { 2365 if (mAppBindArgs == null) { 2366 mAppBindArgs = new HashMap<String, IBinder>(); 2367 2368 // Setup the application init args 2369 mAppBindArgs.put("package", ServiceManager.getService("package")); 2370 mAppBindArgs.put("window", ServiceManager.getService("window")); 2371 mAppBindArgs.put(Context.ALARM_SERVICE, 2372 ServiceManager.getService(Context.ALARM_SERVICE)); 2373 } 2374 return mAppBindArgs; 2375 } 2376 2377 final void setFocusedActivityLocked(ActivityRecord r) { 2378 if (mFocusedActivity != r) { 2379 if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r); 2380 mFocusedActivity = r; 2381 if (r.task != null && r.task.voiceInteractor != null) { 2382 startRunningVoiceLocked(); 2383 } else { 2384 finishRunningVoiceLocked(); 2385 } 2386 mStackSupervisor.setFocusedStack(r); 2387 if (r != null) { 2388 mWindowManager.setFocusedApp(r.appToken, true); 2389 } 2390 applyUpdateLockStateLocked(r); 2391 } 2392 } 2393 2394 final void clearFocusedActivity(ActivityRecord r) { 2395 if (mFocusedActivity == r) { 2396 mFocusedActivity = null; 2397 } 2398 } 2399 2400 @Override 2401 public void setFocusedStack(int stackId) { 2402 if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId); 2403 synchronized (ActivityManagerService.this) { 2404 ActivityStack stack = mStackSupervisor.getStack(stackId); 2405 if (stack != null) { 2406 ActivityRecord r = stack.topRunningActivityLocked(null); 2407 if (r != null) { 2408 setFocusedActivityLocked(r); 2409 } 2410 } 2411 } 2412 } 2413 2414 @Override 2415 public void notifyActivityDrawn(IBinder token) { 2416 if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token); 2417 synchronized (this) { 2418 ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token); 2419 if (r != null) { 2420 r.task.stack.notifyActivityDrawnLocked(r); 2421 } 2422 } 2423 } 2424 2425 final void applyUpdateLockStateLocked(ActivityRecord r) { 2426 // Modifications to the UpdateLock state are done on our handler, outside 2427 // the activity manager's locks. The new state is determined based on the 2428 // state *now* of the relevant activity record. The object is passed to 2429 // the handler solely for logging detail, not to be consulted/modified. 2430 final boolean nextState = r != null && r.immersive; 2431 mHandler.sendMessage( 2432 mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r)); 2433 } 2434 2435 final void showAskCompatModeDialogLocked(ActivityRecord r) { 2436 Message msg = Message.obtain(); 2437 msg.what = SHOW_COMPAT_MODE_DIALOG_MSG; 2438 msg.obj = r.task.askedCompatMode ? null : r; 2439 mHandler.sendMessage(msg); 2440 } 2441 2442 private final int updateLruProcessInternalLocked(ProcessRecord app, long now, int index, 2443 String what, Object obj, ProcessRecord srcApp) { 2444 app.lastActivityTime = now; 2445 2446 if (app.activities.size() > 0) { 2447 // Don't want to touch dependent processes that are hosting activities. 2448 return index; 2449 } 2450 2451 int lrui = mLruProcesses.lastIndexOf(app); 2452 if (lrui < 0) { 2453 Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: " 2454 + what + " " + obj + " from " + srcApp); 2455 return index; 2456 } 2457 2458 if (lrui >= index) { 2459 // Don't want to cause this to move dependent processes *back* in the 2460 // list as if they were less frequently used. 2461 return index; 2462 } 2463 2464 if (lrui >= mLruProcessActivityStart) { 2465 // Don't want to touch dependent processes that are hosting activities. 2466 return index; 2467 } 2468 2469 mLruProcesses.remove(lrui); 2470 if (index > 0) { 2471 index--; 2472 } 2473 if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index 2474 + " in LRU list: " + app); 2475 mLruProcesses.add(index, app); 2476 return index; 2477 } 2478 2479 final void removeLruProcessLocked(ProcessRecord app) { 2480 int lrui = mLruProcesses.lastIndexOf(app); 2481 if (lrui >= 0) { 2482 if (lrui <= mLruProcessActivityStart) { 2483 mLruProcessActivityStart--; 2484 } 2485 if (lrui <= mLruProcessServiceStart) { 2486 mLruProcessServiceStart--; 2487 } 2488 mLruProcesses.remove(lrui); 2489 } 2490 } 2491 2492 final void updateLruProcessLocked(ProcessRecord app, boolean activityChange, 2493 ProcessRecord client) { 2494 final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities 2495 || app.treatLikeActivity; 2496 final boolean hasService = false; // not impl yet. app.services.size() > 0; 2497 if (!activityChange && hasActivity) { 2498 // The process has activities, so we are only allowing activity-based adjustments 2499 // to move it. It should be kept in the front of the list with other 2500 // processes that have activities, and we don't want those to change their 2501 // order except due to activity operations. 2502 return; 2503 } 2504 2505 mLruSeq++; 2506 final long now = SystemClock.uptimeMillis(); 2507 app.lastActivityTime = now; 2508 2509 // First a quick reject: if the app is already at the position we will 2510 // put it, then there is nothing to do. 2511 if (hasActivity) { 2512 final int N = mLruProcesses.size(); 2513 if (N > 0 && mLruProcesses.get(N-1) == app) { 2514 if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app); 2515 return; 2516 } 2517 } else { 2518 if (mLruProcessServiceStart > 0 2519 && mLruProcesses.get(mLruProcessServiceStart-1) == app) { 2520 if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app); 2521 return; 2522 } 2523 } 2524 2525 int lrui = mLruProcesses.lastIndexOf(app); 2526 2527 if (app.persistent && lrui >= 0) { 2528 // We don't care about the position of persistent processes, as long as 2529 // they are in the list. 2530 if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app); 2531 return; 2532 } 2533 2534 /* In progress: compute new position first, so we can avoid doing work 2535 if the process is not actually going to move. Not yet working. 2536 int addIndex; 2537 int nextIndex; 2538 boolean inActivity = false, inService = false; 2539 if (hasActivity) { 2540 // Process has activities, put it at the very tipsy-top. 2541 addIndex = mLruProcesses.size(); 2542 nextIndex = mLruProcessServiceStart; 2543 inActivity = true; 2544 } else if (hasService) { 2545 // Process has services, put it at the top of the service list. 2546 addIndex = mLruProcessActivityStart; 2547 nextIndex = mLruProcessServiceStart; 2548 inActivity = true; 2549 inService = true; 2550 } else { 2551 // Process not otherwise of interest, it goes to the top of the non-service area. 2552 addIndex = mLruProcessServiceStart; 2553 if (client != null) { 2554 int clientIndex = mLruProcesses.lastIndexOf(client); 2555 if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating " 2556 + app); 2557 if (clientIndex >= 0 && addIndex > clientIndex) { 2558 addIndex = clientIndex; 2559 } 2560 } 2561 nextIndex = addIndex > 0 ? addIndex-1 : addIndex; 2562 } 2563 2564 Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act=" 2565 + mLruProcessActivityStart + "): " + app); 2566 */ 2567 2568 if (lrui >= 0) { 2569 if (lrui < mLruProcessActivityStart) { 2570 mLruProcessActivityStart--; 2571 } 2572 if (lrui < mLruProcessServiceStart) { 2573 mLruProcessServiceStart--; 2574 } 2575 /* 2576 if (addIndex > lrui) { 2577 addIndex--; 2578 } 2579 if (nextIndex > lrui) { 2580 nextIndex--; 2581 } 2582 */ 2583 mLruProcesses.remove(lrui); 2584 } 2585 2586 /* 2587 mLruProcesses.add(addIndex, app); 2588 if (inActivity) { 2589 mLruProcessActivityStart++; 2590 } 2591 if (inService) { 2592 mLruProcessActivityStart++; 2593 } 2594 */ 2595 2596 int nextIndex; 2597 if (hasActivity) { 2598 final int N = mLruProcesses.size(); 2599 if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) { 2600 // Process doesn't have activities, but has clients with 2601 // activities... move it up, but one below the top (the top 2602 // should always have a real activity). 2603 if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app); 2604 mLruProcesses.add(N-1, app); 2605 // To keep it from spamming the LRU list (by making a bunch of clients), 2606 // we will push down any other entries owned by the app. 2607 final int uid = app.info.uid; 2608 for (int i=N-2; i>mLruProcessActivityStart; i--) { 2609 ProcessRecord subProc = mLruProcesses.get(i); 2610 if (subProc.info.uid == uid) { 2611 // We want to push this one down the list. If the process after 2612 // it is for the same uid, however, don't do so, because we don't 2613 // want them internally to be re-ordered. 2614 if (mLruProcesses.get(i-1).info.uid != uid) { 2615 if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i 2616 + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1)); 2617 ProcessRecord tmp = mLruProcesses.get(i); 2618 mLruProcesses.set(i, mLruProcesses.get(i-1)); 2619 mLruProcesses.set(i-1, tmp); 2620 i--; 2621 } 2622 } else { 2623 // A gap, we can stop here. 2624 break; 2625 } 2626 } 2627 } else { 2628 // Process has activities, put it at the very tipsy-top. 2629 if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app); 2630 mLruProcesses.add(app); 2631 } 2632 nextIndex = mLruProcessServiceStart; 2633 } else if (hasService) { 2634 // Process has services, put it at the top of the service list. 2635 if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app); 2636 mLruProcesses.add(mLruProcessActivityStart, app); 2637 nextIndex = mLruProcessServiceStart; 2638 mLruProcessActivityStart++; 2639 } else { 2640 // Process not otherwise of interest, it goes to the top of the non-service area. 2641 int index = mLruProcessServiceStart; 2642 if (client != null) { 2643 // If there is a client, don't allow the process to be moved up higher 2644 // in the list than that client. 2645 int clientIndex = mLruProcesses.lastIndexOf(client); 2646 if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client 2647 + " when updating " + app); 2648 if (clientIndex <= lrui) { 2649 // Don't allow the client index restriction to push it down farther in the 2650 // list than it already is. 2651 clientIndex = lrui; 2652 } 2653 if (clientIndex >= 0 && index > clientIndex) { 2654 index = clientIndex; 2655 } 2656 } 2657 if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app); 2658 mLruProcesses.add(index, app); 2659 nextIndex = index-1; 2660 mLruProcessActivityStart++; 2661 mLruProcessServiceStart++; 2662 } 2663 2664 // If the app is currently using a content provider or service, 2665 // bump those processes as well. 2666 for (int j=app.connections.size()-1; j>=0; j--) { 2667 ConnectionRecord cr = app.connections.valueAt(j); 2668 if (cr.binding != null && !cr.serviceDead && cr.binding.service != null 2669 && cr.binding.service.app != null 2670 && cr.binding.service.app.lruSeq != mLruSeq 2671 && !cr.binding.service.app.persistent) { 2672 nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex, 2673 "service connection", cr, app); 2674 } 2675 } 2676 for (int j=app.conProviders.size()-1; j>=0; j--) { 2677 ContentProviderRecord cpr = app.conProviders.get(j).provider; 2678 if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) { 2679 nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex, 2680 "provider reference", cpr, app); 2681 } 2682 } 2683 } 2684 2685 final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) { 2686 if (uid == Process.SYSTEM_UID) { 2687 // The system gets to run in any process. If there are multiple 2688 // processes with the same uid, just pick the first (this 2689 // should never happen). 2690 SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName); 2691 if (procs == null) return null; 2692 final int N = procs.size(); 2693 for (int i = 0; i < N; i++) { 2694 if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i); 2695 } 2696 } 2697 ProcessRecord proc = mProcessNames.get(processName, uid); 2698 if (false && proc != null && !keepIfLarge 2699 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY 2700 && proc.lastCachedPss >= 4000) { 2701 // Turn this condition on to cause killing to happen regularly, for testing. 2702 if (proc.baseProcessTracker != null) { 2703 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss); 2704 } 2705 killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss) 2706 + "k from cached"); 2707 } else if (proc != null && !keepIfLarge 2708 && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL 2709 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) { 2710 if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss); 2711 if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) { 2712 if (proc.baseProcessTracker != null) { 2713 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss); 2714 } 2715 killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss) 2716 + "k from cached"); 2717 } 2718 } 2719 return proc; 2720 } 2721 2722 void ensurePackageDexOpt(String packageName) { 2723 IPackageManager pm = AppGlobals.getPackageManager(); 2724 try { 2725 if (pm.performDexOpt(packageName)) { 2726 mDidDexOpt = true; 2727 } 2728 } catch (RemoteException e) { 2729 } 2730 } 2731 2732 boolean isNextTransitionForward() { 2733 int transit = mWindowManager.getPendingAppTransition(); 2734 return transit == AppTransition.TRANSIT_ACTIVITY_OPEN 2735 || transit == AppTransition.TRANSIT_TASK_OPEN 2736 || transit == AppTransition.TRANSIT_TASK_TO_FRONT; 2737 } 2738 2739 final ProcessRecord startProcessLocked(String processName, 2740 ApplicationInfo info, boolean knownToBeDead, int intentFlags, 2741 String hostingType, ComponentName hostingName, boolean allowWhileBooting, 2742 boolean isolated, boolean keepIfLarge) { 2743 ProcessRecord app; 2744 if (!isolated) { 2745 app = getProcessRecordLocked(processName, info.uid, keepIfLarge); 2746 } else { 2747 // If this is an isolated process, it can't re-use an existing process. 2748 app = null; 2749 } 2750 // We don't have to do anything more if: 2751 // (1) There is an existing application record; and 2752 // (2) The caller doesn't think it is dead, OR there is no thread 2753 // object attached to it so we know it couldn't have crashed; and 2754 // (3) There is a pid assigned to it, so it is either starting or 2755 // already running. 2756 if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName 2757 + " app=" + app + " knownToBeDead=" + knownToBeDead 2758 + " thread=" + (app != null ? app.thread : null) 2759 + " pid=" + (app != null ? app.pid : -1)); 2760 if (app != null && app.pid > 0) { 2761 if (!knownToBeDead || app.thread == null) { 2762 // We already have the app running, or are waiting for it to 2763 // come up (we have a pid but not yet its thread), so keep it. 2764 if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app); 2765 // If this is a new package in the process, add the package to the list 2766 app.addPackage(info.packageName, mProcessStats); 2767 return app; 2768 } 2769 2770 // An application record is attached to a previous process, 2771 // clean it up now. 2772 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app); 2773 handleAppDiedLocked(app, true, true); 2774 } 2775 2776 String hostingNameStr = hostingName != null 2777 ? hostingName.flattenToShortString() : null; 2778 2779 if (!isolated) { 2780 if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) { 2781 // If we are in the background, then check to see if this process 2782 // is bad. If so, we will just silently fail. 2783 if (mBadProcesses.get(info.processName, info.uid) != null) { 2784 if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid 2785 + "/" + info.processName); 2786 return null; 2787 } 2788 } else { 2789 // When the user is explicitly starting a process, then clear its 2790 // crash count so that we won't make it bad until they see at 2791 // least one crash dialog again, and make the process good again 2792 // if it had been bad. 2793 if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid 2794 + "/" + info.processName); 2795 mProcessCrashTimes.remove(info.processName, info.uid); 2796 if (mBadProcesses.get(info.processName, info.uid) != null) { 2797 EventLog.writeEvent(EventLogTags.AM_PROC_GOOD, 2798 UserHandle.getUserId(info.uid), info.uid, 2799 info.processName); 2800 mBadProcesses.remove(info.processName, info.uid); 2801 if (app != null) { 2802 app.bad = false; 2803 } 2804 } 2805 } 2806 } 2807 2808 if (app == null) { 2809 app = newProcessRecordLocked(info, processName, isolated); 2810 if (app == null) { 2811 Slog.w(TAG, "Failed making new process record for " 2812 + processName + "/" + info.uid + " isolated=" + isolated); 2813 return null; 2814 } 2815 mProcessNames.put(processName, app.uid, app); 2816 if (isolated) { 2817 mIsolatedProcesses.put(app.uid, app); 2818 } 2819 } else { 2820 // If this is a new package in the process, add the package to the list 2821 app.addPackage(info.packageName, mProcessStats); 2822 } 2823 2824 // If the system is not ready yet, then hold off on starting this 2825 // process until it is. 2826 if (!mProcessesReady 2827 && !isAllowedWhileBooting(info) 2828 && !allowWhileBooting) { 2829 if (!mProcessesOnHold.contains(app)) { 2830 mProcessesOnHold.add(app); 2831 } 2832 if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app); 2833 return app; 2834 } 2835 2836 startProcessLocked(app, hostingType, hostingNameStr); 2837 return (app.pid != 0) ? app : null; 2838 } 2839 2840 boolean isAllowedWhileBooting(ApplicationInfo ai) { 2841 return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0; 2842 } 2843 2844 private final void startProcessLocked(ProcessRecord app, 2845 String hostingType, String hostingNameStr) { 2846 if (app.pid > 0 && app.pid != MY_PID) { 2847 synchronized (mPidsSelfLocked) { 2848 mPidsSelfLocked.remove(app.pid); 2849 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 2850 } 2851 app.setPid(0); 2852 } 2853 2854 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 2855 "startProcessLocked removing on hold: " + app); 2856 mProcessesOnHold.remove(app); 2857 2858 updateCpuStats(); 2859 2860 try { 2861 int uid = app.uid; 2862 2863 int[] gids = null; 2864 int mountExternal = Zygote.MOUNT_EXTERNAL_NONE; 2865 if (!app.isolated) { 2866 int[] permGids = null; 2867 try { 2868 final PackageManager pm = mContext.getPackageManager(); 2869 permGids = pm.getPackageGids(app.info.packageName); 2870 2871 if (Environment.isExternalStorageEmulated()) { 2872 if (pm.checkPermission( 2873 android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE, 2874 app.info.packageName) == PERMISSION_GRANTED) { 2875 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL; 2876 } else { 2877 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER; 2878 } 2879 } 2880 } catch (PackageManager.NameNotFoundException e) { 2881 Slog.w(TAG, "Unable to retrieve gids", e); 2882 } 2883 2884 /* 2885 * Add shared application GID so applications can share some 2886 * resources like shared libraries 2887 */ 2888 if (permGids == null) { 2889 gids = new int[1]; 2890 } else { 2891 gids = new int[permGids.length + 1]; 2892 System.arraycopy(permGids, 0, gids, 1, permGids.length); 2893 } 2894 gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid)); 2895 } 2896 if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) { 2897 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL 2898 && mTopComponent != null 2899 && app.processName.equals(mTopComponent.getPackageName())) { 2900 uid = 0; 2901 } 2902 if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL 2903 && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) { 2904 uid = 0; 2905 } 2906 } 2907 int debugFlags = 0; 2908 if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) { 2909 debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER; 2910 // Also turn on CheckJNI for debuggable apps. It's quite 2911 // awkward to turn on otherwise. 2912 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 2913 } 2914 // Run the app in safe mode if its manifest requests so or the 2915 // system is booted in safe mode. 2916 if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 || 2917 mSafeMode == true) { 2918 debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE; 2919 } 2920 if ("1".equals(SystemProperties.get("debug.checkjni"))) { 2921 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 2922 } 2923 if ("1".equals(SystemProperties.get("debug.jni.logging"))) { 2924 debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING; 2925 } 2926 if ("1".equals(SystemProperties.get("debug.assert"))) { 2927 debugFlags |= Zygote.DEBUG_ENABLE_ASSERT; 2928 } 2929 2930 String requiredAbi = app.info.cpuAbi; 2931 if (requiredAbi == null) { 2932 requiredAbi = Build.SUPPORTED_ABIS[0]; 2933 } 2934 2935 // Start the process. It will either succeed and return a result containing 2936 // the PID of the new process, or else throw a RuntimeException. 2937 Process.ProcessStartResult startResult = Process.start("android.app.ActivityThread", 2938 app.processName, uid, uid, gids, debugFlags, mountExternal, 2939 app.info.targetSdkVersion, app.info.seinfo, requiredAbi, null); 2940 2941 BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics(); 2942 synchronized (bs) { 2943 if (bs.isOnBattery()) { 2944 bs.getProcessStatsLocked(app.uid, app.processName).incStartsLocked(); 2945 } 2946 } 2947 2948 EventLog.writeEvent(EventLogTags.AM_PROC_START, 2949 UserHandle.getUserId(uid), startResult.pid, uid, 2950 app.processName, hostingType, 2951 hostingNameStr != null ? hostingNameStr : ""); 2952 2953 if (app.persistent) { 2954 Watchdog.getInstance().processStarted(app.processName, startResult.pid); 2955 } 2956 2957 StringBuilder buf = mStringBuilder; 2958 buf.setLength(0); 2959 buf.append("Start proc "); 2960 buf.append(app.processName); 2961 buf.append(" for "); 2962 buf.append(hostingType); 2963 if (hostingNameStr != null) { 2964 buf.append(" "); 2965 buf.append(hostingNameStr); 2966 } 2967 buf.append(": pid="); 2968 buf.append(startResult.pid); 2969 buf.append(" uid="); 2970 buf.append(uid); 2971 buf.append(" gids={"); 2972 if (gids != null) { 2973 for (int gi=0; gi<gids.length; gi++) { 2974 if (gi != 0) buf.append(", "); 2975 buf.append(gids[gi]); 2976 2977 } 2978 } 2979 buf.append("}"); 2980 Slog.i(TAG, buf.toString()); 2981 app.setPid(startResult.pid); 2982 app.usingWrapper = startResult.usingWrapper; 2983 app.removed = false; 2984 synchronized (mPidsSelfLocked) { 2985 this.mPidsSelfLocked.put(startResult.pid, app); 2986 Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 2987 msg.obj = app; 2988 mHandler.sendMessageDelayed(msg, startResult.usingWrapper 2989 ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT); 2990 } 2991 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_START, 2992 app.processName, app.info.uid); 2993 if (app.isolated) { 2994 mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid); 2995 } 2996 } catch (RuntimeException e) { 2997 // XXX do better error recovery. 2998 app.setPid(0); 2999 Slog.e(TAG, "Failure starting process " + app.processName, e); 3000 } 3001 } 3002 3003 void updateUsageStats(ActivityRecord component, boolean resumed) { 3004 if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed); 3005 final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 3006 if (resumed) { 3007 mUsageStatsService.noteResumeComponent(component.realActivity); 3008 synchronized (stats) { 3009 stats.noteActivityResumedLocked(component.app.uid); 3010 } 3011 } else { 3012 mUsageStatsService.notePauseComponent(component.realActivity); 3013 synchronized (stats) { 3014 stats.noteActivityPausedLocked(component.app.uid); 3015 } 3016 } 3017 } 3018 3019 Intent getHomeIntent() { 3020 Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null); 3021 intent.setComponent(mTopComponent); 3022 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 3023 intent.addCategory(Intent.CATEGORY_HOME); 3024 } 3025 return intent; 3026 } 3027 3028 boolean startHomeActivityLocked(int userId) { 3029 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL 3030 && mTopAction == null) { 3031 // We are running in factory test mode, but unable to find 3032 // the factory test app, so just sit around displaying the 3033 // error message and don't try to start anything. 3034 return false; 3035 } 3036 Intent intent = getHomeIntent(); 3037 ActivityInfo aInfo = 3038 resolveActivityInfo(intent, STOCK_PM_FLAGS, userId); 3039 if (aInfo != null) { 3040 intent.setComponent(new ComponentName( 3041 aInfo.applicationInfo.packageName, aInfo.name)); 3042 // Don't do this if the home app is currently being 3043 // instrumented. 3044 aInfo = new ActivityInfo(aInfo); 3045 aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId); 3046 ProcessRecord app = getProcessRecordLocked(aInfo.processName, 3047 aInfo.applicationInfo.uid, true); 3048 if (app == null || app.instrumentationClass == null) { 3049 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK); 3050 mStackSupervisor.startHomeActivity(intent, aInfo); 3051 } 3052 } 3053 3054 return true; 3055 } 3056 3057 private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) { 3058 ActivityInfo ai = null; 3059 ComponentName comp = intent.getComponent(); 3060 try { 3061 if (comp != null) { 3062 ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId); 3063 } else { 3064 ResolveInfo info = AppGlobals.getPackageManager().resolveIntent( 3065 intent, 3066 intent.resolveTypeIfNeeded(mContext.getContentResolver()), 3067 flags, userId); 3068 3069 if (info != null) { 3070 ai = info.activityInfo; 3071 } 3072 } 3073 } catch (RemoteException e) { 3074 // ignore 3075 } 3076 3077 return ai; 3078 } 3079 3080 /** 3081 * Starts the "new version setup screen" if appropriate. 3082 */ 3083 void startSetupActivityLocked() { 3084 // Only do this once per boot. 3085 if (mCheckedForSetup) { 3086 return; 3087 } 3088 3089 // We will show this screen if the current one is a different 3090 // version than the last one shown, and we are not running in 3091 // low-level factory test mode. 3092 final ContentResolver resolver = mContext.getContentResolver(); 3093 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL && 3094 Settings.Global.getInt(resolver, 3095 Settings.Global.DEVICE_PROVISIONED, 0) != 0) { 3096 mCheckedForSetup = true; 3097 3098 // See if we should be showing the platform update setup UI. 3099 Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP); 3100 List<ResolveInfo> ris = mContext.getPackageManager() 3101 .queryIntentActivities(intent, PackageManager.GET_META_DATA); 3102 3103 // We don't allow third party apps to replace this. 3104 ResolveInfo ri = null; 3105 for (int i=0; ris != null && i<ris.size(); i++) { 3106 if ((ris.get(i).activityInfo.applicationInfo.flags 3107 & ApplicationInfo.FLAG_SYSTEM) != 0) { 3108 ri = ris.get(i); 3109 break; 3110 } 3111 } 3112 3113 if (ri != null) { 3114 String vers = ri.activityInfo.metaData != null 3115 ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION) 3116 : null; 3117 if (vers == null && ri.activityInfo.applicationInfo.metaData != null) { 3118 vers = ri.activityInfo.applicationInfo.metaData.getString( 3119 Intent.METADATA_SETUP_VERSION); 3120 } 3121 String lastVers = Settings.Secure.getString( 3122 resolver, Settings.Secure.LAST_SETUP_SHOWN); 3123 if (vers != null && !vers.equals(lastVers)) { 3124 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 3125 intent.setComponent(new ComponentName( 3126 ri.activityInfo.packageName, ri.activityInfo.name)); 3127 mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo, 3128 null, null, null, null, 0, 0, 0, null, 0, null, false, null, null); 3129 } 3130 } 3131 } 3132 } 3133 3134 CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) { 3135 return mCompatModePackages.compatibilityInfoForPackageLocked(ai); 3136 } 3137 3138 void enforceNotIsolatedCaller(String caller) { 3139 if (UserHandle.isIsolated(Binder.getCallingUid())) { 3140 throw new SecurityException("Isolated process not allowed to call " + caller); 3141 } 3142 } 3143 3144 @Override 3145 public int getFrontActivityScreenCompatMode() { 3146 enforceNotIsolatedCaller("getFrontActivityScreenCompatMode"); 3147 synchronized (this) { 3148 return mCompatModePackages.getFrontActivityScreenCompatModeLocked(); 3149 } 3150 } 3151 3152 @Override 3153 public void setFrontActivityScreenCompatMode(int mode) { 3154 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3155 "setFrontActivityScreenCompatMode"); 3156 synchronized (this) { 3157 mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode); 3158 } 3159 } 3160 3161 @Override 3162 public int getPackageScreenCompatMode(String packageName) { 3163 enforceNotIsolatedCaller("getPackageScreenCompatMode"); 3164 synchronized (this) { 3165 return mCompatModePackages.getPackageScreenCompatModeLocked(packageName); 3166 } 3167 } 3168 3169 @Override 3170 public void setPackageScreenCompatMode(String packageName, int mode) { 3171 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3172 "setPackageScreenCompatMode"); 3173 synchronized (this) { 3174 mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode); 3175 } 3176 } 3177 3178 @Override 3179 public boolean getPackageAskScreenCompat(String packageName) { 3180 enforceNotIsolatedCaller("getPackageAskScreenCompat"); 3181 synchronized (this) { 3182 return mCompatModePackages.getPackageAskCompatModeLocked(packageName); 3183 } 3184 } 3185 3186 @Override 3187 public void setPackageAskScreenCompat(String packageName, boolean ask) { 3188 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3189 "setPackageAskScreenCompat"); 3190 synchronized (this) { 3191 mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask); 3192 } 3193 } 3194 3195 private void dispatchProcessesChanged() { 3196 int N; 3197 synchronized (this) { 3198 N = mPendingProcessChanges.size(); 3199 if (mActiveProcessChanges.length < N) { 3200 mActiveProcessChanges = new ProcessChangeItem[N]; 3201 } 3202 mPendingProcessChanges.toArray(mActiveProcessChanges); 3203 mAvailProcessChanges.addAll(mPendingProcessChanges); 3204 mPendingProcessChanges.clear(); 3205 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes"); 3206 } 3207 3208 int i = mProcessObservers.beginBroadcast(); 3209 while (i > 0) { 3210 i--; 3211 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 3212 if (observer != null) { 3213 try { 3214 for (int j=0; j<N; j++) { 3215 ProcessChangeItem item = mActiveProcessChanges[j]; 3216 if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) { 3217 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid=" 3218 + item.pid + " uid=" + item.uid + ": " 3219 + item.foregroundActivities); 3220 observer.onForegroundActivitiesChanged(item.pid, item.uid, 3221 item.foregroundActivities); 3222 } 3223 if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) { 3224 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "PROCSTATE CHANGED pid=" 3225 + item.pid + " uid=" + item.uid + ": " + item.processState); 3226 observer.onProcessStateChanged(item.pid, item.uid, item.processState); 3227 } 3228 } 3229 } catch (RemoteException e) { 3230 } 3231 } 3232 } 3233 mProcessObservers.finishBroadcast(); 3234 } 3235 3236 private void dispatchProcessDied(int pid, int uid) { 3237 int i = mProcessObservers.beginBroadcast(); 3238 while (i > 0) { 3239 i--; 3240 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 3241 if (observer != null) { 3242 try { 3243 observer.onProcessDied(pid, uid); 3244 } catch (RemoteException e) { 3245 } 3246 } 3247 } 3248 mProcessObservers.finishBroadcast(); 3249 } 3250 3251 final void doPendingActivityLaunchesLocked(boolean doResume) { 3252 final int N = mPendingActivityLaunches.size(); 3253 if (N <= 0) { 3254 return; 3255 } 3256 for (int i=0; i<N; i++) { 3257 PendingActivityLaunch pal = mPendingActivityLaunches.get(i); 3258 mStackSupervisor.startActivityUncheckedLocked(pal.r, pal.sourceRecord, null, null, pal.startFlags, 3259 doResume && i == (N-1), null); 3260 } 3261 mPendingActivityLaunches.clear(); 3262 } 3263 3264 @Override 3265 public final int startActivity(IApplicationThread caller, String callingPackage, 3266 Intent intent, String resolvedType, IBinder resultTo, 3267 String resultWho, int requestCode, int startFlags, 3268 String profileFile, ParcelFileDescriptor profileFd, Bundle options) { 3269 return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo, 3270 resultWho, requestCode, 3271 startFlags, profileFile, profileFd, options, UserHandle.getCallingUserId()); 3272 } 3273 3274 @Override 3275 public final int startActivityAsUser(IApplicationThread caller, String callingPackage, 3276 Intent intent, String resolvedType, IBinder resultTo, 3277 String resultWho, int requestCode, int startFlags, 3278 String profileFile, ParcelFileDescriptor profileFd, Bundle options, int userId) { 3279 enforceNotIsolatedCaller("startActivity"); 3280 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3281 false, true, "startActivity", null); 3282 // TODO: Switch to user app stacks here. 3283 return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType, 3284 null, null, resultTo, resultWho, requestCode, startFlags, profileFile, profileFd, 3285 null, null, options, userId, null); 3286 } 3287 3288 @Override 3289 public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage, 3290 Intent intent, String resolvedType, IBinder resultTo, 3291 String resultWho, int requestCode, int startFlags, String profileFile, 3292 ParcelFileDescriptor profileFd, Bundle options, int userId) { 3293 enforceNotIsolatedCaller("startActivityAndWait"); 3294 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3295 false, true, "startActivityAndWait", null); 3296 WaitResult res = new WaitResult(); 3297 // TODO: Switch to user app stacks here. 3298 mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType, 3299 null, null, resultTo, resultWho, requestCode, startFlags, profileFile, profileFd, 3300 res, null, options, UserHandle.getCallingUserId(), null); 3301 return res; 3302 } 3303 3304 @Override 3305 public final int startActivityWithConfig(IApplicationThread caller, String callingPackage, 3306 Intent intent, String resolvedType, IBinder resultTo, 3307 String resultWho, int requestCode, int startFlags, Configuration config, 3308 Bundle options, int userId) { 3309 enforceNotIsolatedCaller("startActivityWithConfig"); 3310 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3311 false, true, "startActivityWithConfig", null); 3312 // TODO: Switch to user app stacks here. 3313 int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, 3314 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, 3315 null, null, null, config, options, userId, null); 3316 return ret; 3317 } 3318 3319 @Override 3320 public int startActivityIntentSender(IApplicationThread caller, 3321 IntentSender intent, Intent fillInIntent, String resolvedType, 3322 IBinder resultTo, String resultWho, int requestCode, 3323 int flagsMask, int flagsValues, Bundle options) { 3324 enforceNotIsolatedCaller("startActivityIntentSender"); 3325 // Refuse possible leaked file descriptors 3326 if (fillInIntent != null && fillInIntent.hasFileDescriptors()) { 3327 throw new IllegalArgumentException("File descriptors passed in Intent"); 3328 } 3329 3330 IIntentSender sender = intent.getTarget(); 3331 if (!(sender instanceof PendingIntentRecord)) { 3332 throw new IllegalArgumentException("Bad PendingIntent object"); 3333 } 3334 3335 PendingIntentRecord pir = (PendingIntentRecord)sender; 3336 3337 synchronized (this) { 3338 // If this is coming from the currently resumed activity, it is 3339 // effectively saying that app switches are allowed at this point. 3340 final ActivityStack stack = getFocusedStack(); 3341 if (stack.mResumedActivity != null && 3342 stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) { 3343 mAppSwitchesAllowedTime = 0; 3344 } 3345 } 3346 int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null, 3347 resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null); 3348 return ret; 3349 } 3350 3351 @Override 3352 public int startVoiceActivity(String callingPackage, int callingPid, int callingUid, 3353 Intent intent, String resolvedType, IVoiceInteractionSession session, 3354 IVoiceInteractor interactor, int startFlags, String profileFile, 3355 ParcelFileDescriptor profileFd, Bundle options, int userId) { 3356 if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION) 3357 != PackageManager.PERMISSION_GRANTED) { 3358 String msg = "Permission Denial: startVoiceActivity() from pid=" 3359 + Binder.getCallingPid() 3360 + ", uid=" + Binder.getCallingUid() 3361 + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION; 3362 Slog.w(TAG, msg); 3363 throw new SecurityException(msg); 3364 } 3365 if (session == null || interactor == null) { 3366 throw new NullPointerException("null session or interactor"); 3367 } 3368 userId = handleIncomingUser(callingPid, callingUid, userId, 3369 false, true, "startVoiceActivity", null); 3370 // TODO: Switch to user app stacks here. 3371 return mStackSupervisor.startActivityMayWait(null, callingUid, callingPackage, intent, 3372 resolvedType, session, interactor, null, null, 0, startFlags, 3373 profileFile, profileFd, null, null, options, userId, null); 3374 } 3375 3376 @Override 3377 public boolean startNextMatchingActivity(IBinder callingActivity, 3378 Intent intent, Bundle options) { 3379 // Refuse possible leaked file descriptors 3380 if (intent != null && intent.hasFileDescriptors() == true) { 3381 throw new IllegalArgumentException("File descriptors passed in Intent"); 3382 } 3383 3384 synchronized (this) { 3385 final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity); 3386 if (r == null) { 3387 ActivityOptions.abort(options); 3388 return false; 3389 } 3390 if (r.app == null || r.app.thread == null) { 3391 // The caller is not running... d'oh! 3392 ActivityOptions.abort(options); 3393 return false; 3394 } 3395 intent = new Intent(intent); 3396 // The caller is not allowed to change the data. 3397 intent.setDataAndType(r.intent.getData(), r.intent.getType()); 3398 // And we are resetting to find the next component... 3399 intent.setComponent(null); 3400 3401 final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0); 3402 3403 ActivityInfo aInfo = null; 3404 try { 3405 List<ResolveInfo> resolves = 3406 AppGlobals.getPackageManager().queryIntentActivities( 3407 intent, r.resolvedType, 3408 PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS, 3409 UserHandle.getCallingUserId()); 3410 3411 // Look for the original activity in the list... 3412 final int N = resolves != null ? resolves.size() : 0; 3413 for (int i=0; i<N; i++) { 3414 ResolveInfo rInfo = resolves.get(i); 3415 if (rInfo.activityInfo.packageName.equals(r.packageName) 3416 && rInfo.activityInfo.name.equals(r.info.name)) { 3417 // We found the current one... the next matching is 3418 // after it. 3419 i++; 3420 if (i<N) { 3421 aInfo = resolves.get(i).activityInfo; 3422 } 3423 if (debug) { 3424 Slog.v(TAG, "Next matching activity: found current " + r.packageName 3425 + "/" + r.info.name); 3426 Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName 3427 + "/" + aInfo.name); 3428 } 3429 break; 3430 } 3431 } 3432 } catch (RemoteException e) { 3433 } 3434 3435 if (aInfo == null) { 3436 // Nobody who is next! 3437 ActivityOptions.abort(options); 3438 if (debug) Slog.d(TAG, "Next matching activity: nothing found"); 3439 return false; 3440 } 3441 3442 intent.setComponent(new ComponentName( 3443 aInfo.applicationInfo.packageName, aInfo.name)); 3444 intent.setFlags(intent.getFlags()&~( 3445 Intent.FLAG_ACTIVITY_FORWARD_RESULT| 3446 Intent.FLAG_ACTIVITY_CLEAR_TOP| 3447 Intent.FLAG_ACTIVITY_MULTIPLE_TASK| 3448 Intent.FLAG_ACTIVITY_NEW_TASK)); 3449 3450 // Okay now we need to start the new activity, replacing the 3451 // currently running activity. This is a little tricky because 3452 // we want to start the new one as if the current one is finished, 3453 // but not finish the current one first so that there is no flicker. 3454 // And thus... 3455 final boolean wasFinishing = r.finishing; 3456 r.finishing = true; 3457 3458 // Propagate reply information over to the new activity. 3459 final ActivityRecord resultTo = r.resultTo; 3460 final String resultWho = r.resultWho; 3461 final int requestCode = r.requestCode; 3462 r.resultTo = null; 3463 if (resultTo != null) { 3464 resultTo.removeResultsLocked(r, resultWho, requestCode); 3465 } 3466 3467 final long origId = Binder.clearCallingIdentity(); 3468 int res = mStackSupervisor.startActivityLocked(r.app.thread, intent, 3469 r.resolvedType, aInfo, null, null, resultTo != null ? resultTo.appToken : null, 3470 resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage, 0, 3471 options, false, null, null); 3472 Binder.restoreCallingIdentity(origId); 3473 3474 r.finishing = wasFinishing; 3475 if (res != ActivityManager.START_SUCCESS) { 3476 return false; 3477 } 3478 return true; 3479 } 3480 } 3481 3482 final int startActivityInPackage(int uid, String callingPackage, 3483 Intent intent, String resolvedType, IBinder resultTo, 3484 String resultWho, int requestCode, int startFlags, Bundle options, int userId, 3485 IActivityContainer container) { 3486 3487 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3488 false, true, "startActivityInPackage", null); 3489 3490 // TODO: Switch to user app stacks here. 3491 int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent, resolvedType, 3492 null, null, resultTo, resultWho, requestCode, startFlags, 3493 null, null, null, null, options, userId, container); 3494 return ret; 3495 } 3496 3497 @Override 3498 public final int startActivities(IApplicationThread caller, String callingPackage, 3499 Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options, 3500 int userId) { 3501 enforceNotIsolatedCaller("startActivities"); 3502 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3503 false, true, "startActivity", null); 3504 // TODO: Switch to user app stacks here. 3505 int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents, 3506 resolvedTypes, resultTo, options, userId); 3507 return ret; 3508 } 3509 3510 final int startActivitiesInPackage(int uid, String callingPackage, 3511 Intent[] intents, String[] resolvedTypes, IBinder resultTo, 3512 Bundle options, int userId) { 3513 3514 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3515 false, true, "startActivityInPackage", null); 3516 // TODO: Switch to user app stacks here. 3517 int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes, 3518 resultTo, options, userId); 3519 return ret; 3520 } 3521 3522 final void addRecentTaskLocked(TaskRecord task) { 3523 int N = mRecentTasks.size(); 3524 // Quick case: check if the top-most recent task is the same. 3525 if (N > 0 && mRecentTasks.get(0) == task) { 3526 return; 3527 } 3528 // Another quick case: never add voice sessions. 3529 if (task.voiceSession != null) { 3530 return; 3531 } 3532 // Remove any existing entries that are the same kind of task. 3533 final Intent intent = task.intent; 3534 final boolean document = intent != null && intent.isDocument(); 3535 final ComponentName comp = intent.getComponent(); 3536 3537 int maxRecents = task.maxRecents - 1; 3538 for (int i=0; i<N; i++) { 3539 TaskRecord tr = mRecentTasks.get(i); 3540 if (task != tr) { 3541 if (task.userId != tr.userId) { 3542 continue; 3543 } 3544 final Intent trIntent = tr.intent; 3545 if ((task.affinity == null || !task.affinity.equals(tr.affinity)) && 3546 (intent == null || !intent.filterEquals(trIntent))) { 3547 continue; 3548 } 3549 final boolean trIsDocument = trIntent != null && trIntent.isDocument(); 3550 if (document && trIsDocument) { 3551 // These are the same document activity (not necessarily the same doc). 3552 if (maxRecents > 0) { 3553 --maxRecents; 3554 continue; 3555 } 3556 // Hit the maximum number of documents for this task. Fall through 3557 // and remove this document from recents. 3558 } else if (document || trIsDocument) { 3559 // Only one of these is a document. Not the droid we're looking for. 3560 continue; 3561 } 3562 } 3563 3564 // Either task and tr are the same or, their affinities match or their intents match 3565 // and neither of them is a document, or they are documents using the same activity 3566 // and their maxRecents has been reached. 3567 tr.disposeThumbnail(); 3568 mRecentTasks.remove(i); 3569 i--; 3570 N--; 3571 if (task.intent == null) { 3572 // If the new recent task we are adding is not fully 3573 // specified, then replace it with the existing recent task. 3574 task = tr; 3575 } 3576 mTaskPersister.notify(tr, false); 3577 } 3578 if (N >= MAX_RECENT_TASKS) { 3579 mRecentTasks.remove(N-1).disposeThumbnail(); 3580 } 3581 mRecentTasks.add(0, task); 3582 } 3583 3584 @Override 3585 public void reportActivityFullyDrawn(IBinder token) { 3586 synchronized (this) { 3587 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3588 if (r == null) { 3589 return; 3590 } 3591 r.reportFullyDrawnLocked(); 3592 } 3593 } 3594 3595 @Override 3596 public void setRequestedOrientation(IBinder token, int requestedOrientation) { 3597 synchronized (this) { 3598 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3599 if (r == null) { 3600 return; 3601 } 3602 final long origId = Binder.clearCallingIdentity(); 3603 mWindowManager.setAppOrientation(r.appToken, requestedOrientation); 3604 Configuration config = mWindowManager.updateOrientationFromAppTokens( 3605 mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null); 3606 if (config != null) { 3607 r.frozenBeforeDestroy = true; 3608 if (!updateConfigurationLocked(config, r, false, false)) { 3609 mStackSupervisor.resumeTopActivitiesLocked(); 3610 } 3611 } 3612 Binder.restoreCallingIdentity(origId); 3613 } 3614 } 3615 3616 @Override 3617 public int getRequestedOrientation(IBinder token) { 3618 synchronized (this) { 3619 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3620 if (r == null) { 3621 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; 3622 } 3623 return mWindowManager.getAppOrientation(r.appToken); 3624 } 3625 } 3626 3627 /** 3628 * This is the internal entry point for handling Activity.finish(). 3629 * 3630 * @param token The Binder token referencing the Activity we want to finish. 3631 * @param resultCode Result code, if any, from this Activity. 3632 * @param resultData Result data (Intent), if any, from this Activity. 3633 * @param finishTask Whether to finish the task associated with this Activity. Only applies to 3634 * the root Activity in the task. 3635 * 3636 * @return Returns true if the activity successfully finished, or false if it is still running. 3637 */ 3638 @Override 3639 public final boolean finishActivity(IBinder token, int resultCode, Intent resultData, 3640 boolean finishTask) { 3641 // Refuse possible leaked file descriptors 3642 if (resultData != null && resultData.hasFileDescriptors() == true) { 3643 throw new IllegalArgumentException("File descriptors passed in Intent"); 3644 } 3645 3646 synchronized(this) { 3647 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3648 if (r == null) { 3649 return true; 3650 } 3651 // Keep track of the root activity of the task before we finish it 3652 TaskRecord tr = r.task; 3653 ActivityRecord rootR = tr.getRootActivity(); 3654 if (mController != null) { 3655 // Find the first activity that is not finishing. 3656 ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0); 3657 if (next != null) { 3658 // ask watcher if this is allowed 3659 boolean resumeOK = true; 3660 try { 3661 resumeOK = mController.activityResuming(next.packageName); 3662 } catch (RemoteException e) { 3663 mController = null; 3664 Watchdog.getInstance().setActivityController(null); 3665 } 3666 3667 if (!resumeOK) { 3668 return false; 3669 } 3670 } 3671 } 3672 final long origId = Binder.clearCallingIdentity(); 3673 try { 3674 boolean res; 3675 if (finishTask && r == rootR) { 3676 // If requested, remove the task that is associated to this activity only if it 3677 // was the root activity in the task. The result code and data is ignored because 3678 // we don't support returning them across task boundaries. 3679 res = removeTaskByIdLocked(tr.taskId, 0); 3680 } else { 3681 res = tr.stack.requestFinishActivityLocked(token, resultCode, 3682 resultData, "app-request", true); 3683 } 3684 return res; 3685 } finally { 3686 Binder.restoreCallingIdentity(origId); 3687 } 3688 } 3689 } 3690 3691 @Override 3692 public final void finishHeavyWeightApp() { 3693 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 3694 != PackageManager.PERMISSION_GRANTED) { 3695 String msg = "Permission Denial: finishHeavyWeightApp() 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 if (mHeavyWeightProcess == null) { 3705 return; 3706 } 3707 3708 ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>( 3709 mHeavyWeightProcess.activities); 3710 for (int i=0; i<activities.size(); i++) { 3711 ActivityRecord r = activities.get(i); 3712 if (!r.finishing) { 3713 r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED, 3714 null, "finish-heavy", true); 3715 } 3716 } 3717 3718 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 3719 mHeavyWeightProcess.userId, 0)); 3720 mHeavyWeightProcess = null; 3721 } 3722 } 3723 3724 @Override 3725 public void crashApplication(int uid, int initialPid, String packageName, 3726 String message) { 3727 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 3728 != PackageManager.PERMISSION_GRANTED) { 3729 String msg = "Permission Denial: crashApplication() from pid=" 3730 + Binder.getCallingPid() 3731 + ", uid=" + Binder.getCallingUid() 3732 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 3733 Slog.w(TAG, msg); 3734 throw new SecurityException(msg); 3735 } 3736 3737 synchronized(this) { 3738 ProcessRecord proc = null; 3739 3740 // Figure out which process to kill. We don't trust that initialPid 3741 // still has any relation to current pids, so must scan through the 3742 // list. 3743 synchronized (mPidsSelfLocked) { 3744 for (int i=0; i<mPidsSelfLocked.size(); i++) { 3745 ProcessRecord p = mPidsSelfLocked.valueAt(i); 3746 if (p.uid != uid) { 3747 continue; 3748 } 3749 if (p.pid == initialPid) { 3750 proc = p; 3751 break; 3752 } 3753 if (p.pkgList.containsKey(packageName)) { 3754 proc = p; 3755 } 3756 } 3757 } 3758 3759 if (proc == null) { 3760 Slog.w(TAG, "crashApplication: nothing for uid=" + uid 3761 + " initialPid=" + initialPid 3762 + " packageName=" + packageName); 3763 return; 3764 } 3765 3766 if (proc.thread != null) { 3767 if (proc.pid == Process.myPid()) { 3768 Log.w(TAG, "crashApplication: trying to crash self!"); 3769 return; 3770 } 3771 long ident = Binder.clearCallingIdentity(); 3772 try { 3773 proc.thread.scheduleCrash(message); 3774 } catch (RemoteException e) { 3775 } 3776 Binder.restoreCallingIdentity(ident); 3777 } 3778 } 3779 } 3780 3781 @Override 3782 public final void finishSubActivity(IBinder token, String resultWho, 3783 int requestCode) { 3784 synchronized(this) { 3785 final long origId = Binder.clearCallingIdentity(); 3786 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3787 if (r != null) { 3788 r.task.stack.finishSubActivityLocked(r, resultWho, requestCode); 3789 } 3790 Binder.restoreCallingIdentity(origId); 3791 } 3792 } 3793 3794 @Override 3795 public boolean finishActivityAffinity(IBinder token) { 3796 synchronized(this) { 3797 final long origId = Binder.clearCallingIdentity(); 3798 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3799 boolean res = false; 3800 if (r != null) { 3801 res = r.task.stack.finishActivityAffinityLocked(r); 3802 } 3803 Binder.restoreCallingIdentity(origId); 3804 return res; 3805 } 3806 } 3807 3808 @Override 3809 public boolean willActivityBeVisible(IBinder token) { 3810 synchronized(this) { 3811 ActivityStack stack = ActivityRecord.getStackLocked(token); 3812 if (stack != null) { 3813 return stack.willActivityBeVisibleLocked(token); 3814 } 3815 return false; 3816 } 3817 } 3818 3819 @Override 3820 public void overridePendingTransition(IBinder token, String packageName, 3821 int enterAnim, int exitAnim) { 3822 synchronized(this) { 3823 ActivityRecord self = ActivityRecord.isInStackLocked(token); 3824 if (self == null) { 3825 return; 3826 } 3827 3828 final long origId = Binder.clearCallingIdentity(); 3829 3830 if (self.state == ActivityState.RESUMED 3831 || self.state == ActivityState.PAUSING) { 3832 mWindowManager.overridePendingAppTransition(packageName, 3833 enterAnim, exitAnim, null); 3834 } 3835 3836 Binder.restoreCallingIdentity(origId); 3837 } 3838 } 3839 3840 /** 3841 * Main function for removing an existing process from the activity manager 3842 * as a result of that process going away. Clears out all connections 3843 * to the process. 3844 */ 3845 private final void handleAppDiedLocked(ProcessRecord app, 3846 boolean restarting, boolean allowRestart) { 3847 int pid = app.pid; 3848 cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1); 3849 if (!restarting) { 3850 removeLruProcessLocked(app); 3851 if (pid > 0) { 3852 ProcessList.remove(pid); 3853 } 3854 } 3855 3856 if (mProfileProc == app) { 3857 clearProfilerLocked(); 3858 } 3859 3860 // Remove this application's activities from active lists. 3861 boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app); 3862 3863 app.activities.clear(); 3864 3865 if (app.instrumentationClass != null) { 3866 Slog.w(TAG, "Crash of app " + app.processName 3867 + " running instrumentation " + app.instrumentationClass); 3868 Bundle info = new Bundle(); 3869 info.putString("shortMsg", "Process crashed."); 3870 finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info); 3871 } 3872 3873 if (!restarting) { 3874 if (!mStackSupervisor.resumeTopActivitiesLocked()) { 3875 // If there was nothing to resume, and we are not already 3876 // restarting this process, but there is a visible activity that 3877 // is hosted by the process... then make sure all visible 3878 // activities are running, taking care of restarting this 3879 // process. 3880 if (hasVisibleActivities) { 3881 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 3882 } 3883 } 3884 } 3885 } 3886 3887 private final int getLRURecordIndexForAppLocked(IApplicationThread thread) { 3888 IBinder threadBinder = thread.asBinder(); 3889 // Find the application record. 3890 for (int i=mLruProcesses.size()-1; i>=0; i--) { 3891 ProcessRecord rec = mLruProcesses.get(i); 3892 if (rec.thread != null && rec.thread.asBinder() == threadBinder) { 3893 return i; 3894 } 3895 } 3896 return -1; 3897 } 3898 3899 final ProcessRecord getRecordForAppLocked( 3900 IApplicationThread thread) { 3901 if (thread == null) { 3902 return null; 3903 } 3904 3905 int appIndex = getLRURecordIndexForAppLocked(thread); 3906 return appIndex >= 0 ? mLruProcesses.get(appIndex) : null; 3907 } 3908 3909 final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) { 3910 // If there are no longer any background processes running, 3911 // and the app that died was not running instrumentation, 3912 // then tell everyone we are now low on memory. 3913 boolean haveBg = false; 3914 for (int i=mLruProcesses.size()-1; i>=0; i--) { 3915 ProcessRecord rec = mLruProcesses.get(i); 3916 if (rec.thread != null 3917 && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 3918 haveBg = true; 3919 break; 3920 } 3921 } 3922 3923 if (!haveBg) { 3924 boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 3925 if (doReport) { 3926 long now = SystemClock.uptimeMillis(); 3927 if (now < (mLastMemUsageReportTime+5*60*1000)) { 3928 doReport = false; 3929 } else { 3930 mLastMemUsageReportTime = now; 3931 } 3932 } 3933 final ArrayList<ProcessMemInfo> memInfos 3934 = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null; 3935 EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size()); 3936 long now = SystemClock.uptimeMillis(); 3937 for (int i=mLruProcesses.size()-1; i>=0; i--) { 3938 ProcessRecord rec = mLruProcesses.get(i); 3939 if (rec == dyingProc || rec.thread == null) { 3940 continue; 3941 } 3942 if (doReport) { 3943 memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj, 3944 rec.setProcState, rec.adjType, rec.makeAdjReason())); 3945 } 3946 if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) { 3947 // The low memory report is overriding any current 3948 // state for a GC request. Make sure to do 3949 // heavy/important/visible/foreground processes first. 3950 if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 3951 rec.lastRequestedGc = 0; 3952 } else { 3953 rec.lastRequestedGc = rec.lastLowMemory; 3954 } 3955 rec.reportLowMemory = true; 3956 rec.lastLowMemory = now; 3957 mProcessesToGc.remove(rec); 3958 addProcessToGcListLocked(rec); 3959 } 3960 } 3961 if (doReport) { 3962 Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos); 3963 mHandler.sendMessage(msg); 3964 } 3965 scheduleAppGcsLocked(); 3966 } 3967 } 3968 3969 final void appDiedLocked(ProcessRecord app, int pid, 3970 IApplicationThread thread) { 3971 3972 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 3973 synchronized (stats) { 3974 stats.noteProcessDiedLocked(app.info.uid, pid); 3975 } 3976 3977 // Clean up already done if the process has been re-started. 3978 if (app.pid == pid && app.thread != null && 3979 app.thread.asBinder() == thread.asBinder()) { 3980 boolean doLowMem = app.instrumentationClass == null; 3981 boolean doOomAdj = doLowMem; 3982 if (!app.killedByAm) { 3983 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 3984 + ") has died."); 3985 mAllowLowerMemLevel = true; 3986 } else { 3987 // Note that we always want to do oom adj to update our state with the 3988 // new number of procs. 3989 mAllowLowerMemLevel = false; 3990 doLowMem = false; 3991 } 3992 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName); 3993 if (DEBUG_CLEANUP) Slog.v( 3994 TAG, "Dying app: " + app + ", pid: " + pid 3995 + ", thread: " + thread.asBinder()); 3996 handleAppDiedLocked(app, false, true); 3997 3998 if (doOomAdj) { 3999 updateOomAdjLocked(); 4000 } 4001 if (doLowMem) { 4002 doLowMemReportIfNeededLocked(app); 4003 } 4004 } else if (app.pid != pid) { 4005 // A new process has already been started. 4006 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 4007 + ") has died and restarted (pid " + app.pid + ")."); 4008 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName); 4009 } else if (DEBUG_PROCESSES) { 4010 Slog.d(TAG, "Received spurious death notification for thread " 4011 + thread.asBinder()); 4012 } 4013 } 4014 4015 /** 4016 * If a stack trace dump file is configured, dump process stack traces. 4017 * @param clearTraces causes the dump file to be erased prior to the new 4018 * traces being written, if true; when false, the new traces will be 4019 * appended to any existing file content. 4020 * @param firstPids of dalvik VM processes to dump stack traces for first 4021 * @param lastPids of dalvik VM processes to dump stack traces for last 4022 * @param nativeProcs optional list of native process names to dump stack crawls 4023 * @return file containing stack traces, or null if no dump file is configured 4024 */ 4025 public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids, 4026 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) { 4027 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 4028 if (tracesPath == null || tracesPath.length() == 0) { 4029 return null; 4030 } 4031 4032 File tracesFile = new File(tracesPath); 4033 try { 4034 File tracesDir = tracesFile.getParentFile(); 4035 if (!tracesDir.exists()) { 4036 tracesFile.mkdirs(); 4037 if (!SELinux.restorecon(tracesDir)) { 4038 return null; 4039 } 4040 } 4041 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 4042 4043 if (clearTraces && tracesFile.exists()) tracesFile.delete(); 4044 tracesFile.createNewFile(); 4045 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 4046 } catch (IOException e) { 4047 Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e); 4048 return null; 4049 } 4050 4051 dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs); 4052 return tracesFile; 4053 } 4054 4055 private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids, 4056 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) { 4057 // Use a FileObserver to detect when traces finish writing. 4058 // The order of traces is considered important to maintain for legibility. 4059 FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) { 4060 @Override 4061 public synchronized void onEvent(int event, String path) { notify(); } 4062 }; 4063 4064 try { 4065 observer.startWatching(); 4066 4067 // First collect all of the stacks of the most important pids. 4068 if (firstPids != null) { 4069 try { 4070 int num = firstPids.size(); 4071 for (int i = 0; i < num; i++) { 4072 synchronized (observer) { 4073 Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT); 4074 observer.wait(200); // Wait for write-close, give up after 200msec 4075 } 4076 } 4077 } catch (InterruptedException e) { 4078 Log.wtf(TAG, e); 4079 } 4080 } 4081 4082 // Next collect the stacks of the native pids 4083 if (nativeProcs != null) { 4084 int[] pids = Process.getPidsForCommands(nativeProcs); 4085 if (pids != null) { 4086 for (int pid : pids) { 4087 Debug.dumpNativeBacktraceToFile(pid, tracesPath); 4088 } 4089 } 4090 } 4091 4092 // Lastly, measure CPU usage. 4093 if (processCpuTracker != null) { 4094 processCpuTracker.init(); 4095 System.gc(); 4096 processCpuTracker.update(); 4097 try { 4098 synchronized (processCpuTracker) { 4099 processCpuTracker.wait(500); // measure over 1/2 second. 4100 } 4101 } catch (InterruptedException e) { 4102 } 4103 processCpuTracker.update(); 4104 4105 // We'll take the stack crawls of just the top apps using CPU. 4106 final int N = processCpuTracker.countWorkingStats(); 4107 int numProcs = 0; 4108 for (int i=0; i<N && numProcs<5; i++) { 4109 ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i); 4110 if (lastPids.indexOfKey(stats.pid) >= 0) { 4111 numProcs++; 4112 try { 4113 synchronized (observer) { 4114 Process.sendSignal(stats.pid, Process.SIGNAL_QUIT); 4115 observer.wait(200); // Wait for write-close, give up after 200msec 4116 } 4117 } catch (InterruptedException e) { 4118 Log.wtf(TAG, e); 4119 } 4120 4121 } 4122 } 4123 } 4124 } finally { 4125 observer.stopWatching(); 4126 } 4127 } 4128 4129 final void logAppTooSlow(ProcessRecord app, long startTime, String msg) { 4130 if (true || IS_USER_BUILD) { 4131 return; 4132 } 4133 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 4134 if (tracesPath == null || tracesPath.length() == 0) { 4135 return; 4136 } 4137 4138 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads(); 4139 StrictMode.allowThreadDiskWrites(); 4140 try { 4141 final File tracesFile = new File(tracesPath); 4142 final File tracesDir = tracesFile.getParentFile(); 4143 final File tracesTmp = new File(tracesDir, "__tmp__"); 4144 try { 4145 if (!tracesDir.exists()) { 4146 tracesFile.mkdirs(); 4147 if (!SELinux.restorecon(tracesDir.getPath())) { 4148 return; 4149 } 4150 } 4151 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 4152 4153 if (tracesFile.exists()) { 4154 tracesTmp.delete(); 4155 tracesFile.renameTo(tracesTmp); 4156 } 4157 StringBuilder sb = new StringBuilder(); 4158 Time tobj = new Time(); 4159 tobj.set(System.currentTimeMillis()); 4160 sb.append(tobj.format("%Y-%m-%d %H:%M:%S")); 4161 sb.append(": "); 4162 TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb); 4163 sb.append(" since "); 4164 sb.append(msg); 4165 FileOutputStream fos = new FileOutputStream(tracesFile); 4166 fos.write(sb.toString().getBytes()); 4167 if (app == null) { 4168 fos.write("\n*** No application process!".getBytes()); 4169 } 4170 fos.close(); 4171 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 4172 } catch (IOException e) { 4173 Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e); 4174 return; 4175 } 4176 4177 if (app != null) { 4178 ArrayList<Integer> firstPids = new ArrayList<Integer>(); 4179 firstPids.add(app.pid); 4180 dumpStackTraces(tracesPath, firstPids, null, null, null); 4181 } 4182 4183 File lastTracesFile = null; 4184 File curTracesFile = null; 4185 for (int i=9; i>=0; i--) { 4186 String name = String.format(Locale.US, "slow%02d.txt", i); 4187 curTracesFile = new File(tracesDir, name); 4188 if (curTracesFile.exists()) { 4189 if (lastTracesFile != null) { 4190 curTracesFile.renameTo(lastTracesFile); 4191 } else { 4192 curTracesFile.delete(); 4193 } 4194 } 4195 lastTracesFile = curTracesFile; 4196 } 4197 tracesFile.renameTo(curTracesFile); 4198 if (tracesTmp.exists()) { 4199 tracesTmp.renameTo(tracesFile); 4200 } 4201 } finally { 4202 StrictMode.setThreadPolicy(oldPolicy); 4203 } 4204 } 4205 4206 final void appNotResponding(ProcessRecord app, ActivityRecord activity, 4207 ActivityRecord parent, boolean aboveSystem, final String annotation) { 4208 ArrayList<Integer> firstPids = new ArrayList<Integer>(5); 4209 SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20); 4210 4211 if (mController != null) { 4212 try { 4213 // 0 == continue, -1 = kill process immediately 4214 int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation); 4215 if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid); 4216 } catch (RemoteException e) { 4217 mController = null; 4218 Watchdog.getInstance().setActivityController(null); 4219 } 4220 } 4221 4222 long anrTime = SystemClock.uptimeMillis(); 4223 if (MONITOR_CPU_USAGE) { 4224 updateCpuStatsNow(); 4225 } 4226 4227 synchronized (this) { 4228 // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down. 4229 if (mShuttingDown) { 4230 Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation); 4231 return; 4232 } else if (app.notResponding) { 4233 Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation); 4234 return; 4235 } else if (app.crashing) { 4236 Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation); 4237 return; 4238 } 4239 4240 // In case we come through here for the same app before completing 4241 // this one, mark as anring now so we will bail out. 4242 app.notResponding = true; 4243 4244 // Log the ANR to the event log. 4245 EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid, 4246 app.processName, app.info.flags, annotation); 4247 4248 // Dump thread traces as quickly as we can, starting with "interesting" processes. 4249 firstPids.add(app.pid); 4250 4251 int parentPid = app.pid; 4252 if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid; 4253 if (parentPid != app.pid) firstPids.add(parentPid); 4254 4255 if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID); 4256 4257 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 4258 ProcessRecord r = mLruProcesses.get(i); 4259 if (r != null && r.thread != null) { 4260 int pid = r.pid; 4261 if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) { 4262 if (r.persistent) { 4263 firstPids.add(pid); 4264 } else { 4265 lastPids.put(pid, Boolean.TRUE); 4266 } 4267 } 4268 } 4269 } 4270 } 4271 4272 // Log the ANR to the main log. 4273 StringBuilder info = new StringBuilder(); 4274 info.setLength(0); 4275 info.append("ANR in ").append(app.processName); 4276 if (activity != null && activity.shortComponentName != null) { 4277 info.append(" (").append(activity.shortComponentName).append(")"); 4278 } 4279 info.append("\n"); 4280 info.append("PID: ").append(app.pid).append("\n"); 4281 if (annotation != null) { 4282 info.append("Reason: ").append(annotation).append("\n"); 4283 } 4284 if (parent != null && parent != activity) { 4285 info.append("Parent: ").append(parent.shortComponentName).append("\n"); 4286 } 4287 4288 final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true); 4289 4290 File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids, 4291 NATIVE_STACKS_OF_INTEREST); 4292 4293 String cpuInfo = null; 4294 if (MONITOR_CPU_USAGE) { 4295 updateCpuStatsNow(); 4296 synchronized (mProcessCpuThread) { 4297 cpuInfo = mProcessCpuTracker.printCurrentState(anrTime); 4298 } 4299 info.append(processCpuTracker.printCurrentLoad()); 4300 info.append(cpuInfo); 4301 } 4302 4303 info.append(processCpuTracker.printCurrentState(anrTime)); 4304 4305 Slog.e(TAG, info.toString()); 4306 if (tracesFile == null) { 4307 // There is no trace file, so dump (only) the alleged culprit's threads to the log 4308 Process.sendSignal(app.pid, Process.SIGNAL_QUIT); 4309 } 4310 4311 addErrorToDropBox("anr", app, app.processName, activity, parent, annotation, 4312 cpuInfo, tracesFile, null); 4313 4314 if (mController != null) { 4315 try { 4316 // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately 4317 int res = mController.appNotResponding(app.processName, app.pid, info.toString()); 4318 if (res != 0) { 4319 if (res < 0 && app.pid != MY_PID) { 4320 Process.killProcess(app.pid); 4321 } else { 4322 synchronized (this) { 4323 mServices.scheduleServiceTimeoutLocked(app); 4324 } 4325 } 4326 return; 4327 } 4328 } catch (RemoteException e) { 4329 mController = null; 4330 Watchdog.getInstance().setActivityController(null); 4331 } 4332 } 4333 4334 // Unless configured otherwise, swallow ANRs in background processes & kill the process. 4335 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), 4336 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; 4337 4338 synchronized (this) { 4339 if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) { 4340 killUnneededProcessLocked(app, "background ANR"); 4341 return; 4342 } 4343 4344 // Set the app's notResponding state, and look up the errorReportReceiver 4345 makeAppNotRespondingLocked(app, 4346 activity != null ? activity.shortComponentName : null, 4347 annotation != null ? "ANR " + annotation : "ANR", 4348 info.toString()); 4349 4350 // Bring up the infamous App Not Responding dialog 4351 Message msg = Message.obtain(); 4352 HashMap<String, Object> map = new HashMap<String, Object>(); 4353 msg.what = SHOW_NOT_RESPONDING_MSG; 4354 msg.obj = map; 4355 msg.arg1 = aboveSystem ? 1 : 0; 4356 map.put("app", app); 4357 if (activity != null) { 4358 map.put("activity", activity); 4359 } 4360 4361 mHandler.sendMessage(msg); 4362 } 4363 } 4364 4365 final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) { 4366 if (!mLaunchWarningShown) { 4367 mLaunchWarningShown = true; 4368 mHandler.post(new Runnable() { 4369 @Override 4370 public void run() { 4371 synchronized (ActivityManagerService.this) { 4372 final Dialog d = new LaunchWarningWindow(mContext, cur, next); 4373 d.show(); 4374 mHandler.postDelayed(new Runnable() { 4375 @Override 4376 public void run() { 4377 synchronized (ActivityManagerService.this) { 4378 d.dismiss(); 4379 mLaunchWarningShown = false; 4380 } 4381 } 4382 }, 4000); 4383 } 4384 } 4385 }); 4386 } 4387 } 4388 4389 @Override 4390 public boolean clearApplicationUserData(final String packageName, 4391 final IPackageDataObserver observer, int userId) { 4392 enforceNotIsolatedCaller("clearApplicationUserData"); 4393 int uid = Binder.getCallingUid(); 4394 int pid = Binder.getCallingPid(); 4395 userId = handleIncomingUser(pid, uid, 4396 userId, false, true, "clearApplicationUserData", null); 4397 long callingId = Binder.clearCallingIdentity(); 4398 try { 4399 IPackageManager pm = AppGlobals.getPackageManager(); 4400 int pkgUid = -1; 4401 synchronized(this) { 4402 try { 4403 pkgUid = pm.getPackageUid(packageName, userId); 4404 } catch (RemoteException e) { 4405 } 4406 if (pkgUid == -1) { 4407 Slog.w(TAG, "Invalid packageName: " + packageName); 4408 if (observer != null) { 4409 try { 4410 observer.onRemoveCompleted(packageName, false); 4411 } catch (RemoteException e) { 4412 Slog.i(TAG, "Observer no longer exists."); 4413 } 4414 } 4415 return false; 4416 } 4417 if (uid == pkgUid || checkComponentPermission( 4418 android.Manifest.permission.CLEAR_APP_USER_DATA, 4419 pid, uid, -1, true) 4420 == PackageManager.PERMISSION_GRANTED) { 4421 forceStopPackageLocked(packageName, pkgUid, "clear data"); 4422 } else { 4423 throw new SecurityException("PID " + pid + " does not have permission " 4424 + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data" 4425 + " of package " + packageName); 4426 } 4427 } 4428 4429 try { 4430 // Clear application user data 4431 pm.clearApplicationUserData(packageName, observer, userId); 4432 4433 // Remove all permissions granted from/to this package 4434 removeUriPermissionsForPackageLocked(packageName, userId, true); 4435 4436 Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED, 4437 Uri.fromParts("package", packageName, null)); 4438 intent.putExtra(Intent.EXTRA_UID, pkgUid); 4439 broadcastIntentInPackage("android", Process.SYSTEM_UID, intent, 4440 null, null, 0, null, null, null, false, false, userId); 4441 } catch (RemoteException e) { 4442 } 4443 } finally { 4444 Binder.restoreCallingIdentity(callingId); 4445 } 4446 return true; 4447 } 4448 4449 @Override 4450 public void killBackgroundProcesses(final String packageName, int userId) { 4451 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 4452 != PackageManager.PERMISSION_GRANTED && 4453 checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES) 4454 != PackageManager.PERMISSION_GRANTED) { 4455 String msg = "Permission Denial: killBackgroundProcesses() from pid=" 4456 + Binder.getCallingPid() 4457 + ", uid=" + Binder.getCallingUid() 4458 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 4459 Slog.w(TAG, msg); 4460 throw new SecurityException(msg); 4461 } 4462 4463 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 4464 userId, true, true, "killBackgroundProcesses", null); 4465 long callingId = Binder.clearCallingIdentity(); 4466 try { 4467 IPackageManager pm = AppGlobals.getPackageManager(); 4468 synchronized(this) { 4469 int appId = -1; 4470 try { 4471 appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0)); 4472 } catch (RemoteException e) { 4473 } 4474 if (appId == -1) { 4475 Slog.w(TAG, "Invalid packageName: " + packageName); 4476 return; 4477 } 4478 killPackageProcessesLocked(packageName, appId, userId, 4479 ProcessList.SERVICE_ADJ, false, true, true, false, "kill background"); 4480 } 4481 } finally { 4482 Binder.restoreCallingIdentity(callingId); 4483 } 4484 } 4485 4486 @Override 4487 public void killAllBackgroundProcesses() { 4488 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 4489 != PackageManager.PERMISSION_GRANTED) { 4490 String msg = "Permission Denial: killAllBackgroundProcesses() from pid=" 4491 + Binder.getCallingPid() 4492 + ", uid=" + Binder.getCallingUid() 4493 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 4494 Slog.w(TAG, msg); 4495 throw new SecurityException(msg); 4496 } 4497 4498 long callingId = Binder.clearCallingIdentity(); 4499 try { 4500 synchronized(this) { 4501 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 4502 final int NP = mProcessNames.getMap().size(); 4503 for (int ip=0; ip<NP; ip++) { 4504 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 4505 final int NA = apps.size(); 4506 for (int ia=0; ia<NA; ia++) { 4507 ProcessRecord app = apps.valueAt(ia); 4508 if (app.persistent) { 4509 // we don't kill persistent processes 4510 continue; 4511 } 4512 if (app.removed) { 4513 procs.add(app); 4514 } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 4515 app.removed = true; 4516 procs.add(app); 4517 } 4518 } 4519 } 4520 4521 int N = procs.size(); 4522 for (int i=0; i<N; i++) { 4523 removeProcessLocked(procs.get(i), false, true, "kill all background"); 4524 } 4525 mAllowLowerMemLevel = true; 4526 updateOomAdjLocked(); 4527 doLowMemReportIfNeededLocked(null); 4528 } 4529 } finally { 4530 Binder.restoreCallingIdentity(callingId); 4531 } 4532 } 4533 4534 @Override 4535 public void forceStopPackage(final String packageName, int userId) { 4536 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 4537 != PackageManager.PERMISSION_GRANTED) { 4538 String msg = "Permission Denial: forceStopPackage() from pid=" 4539 + Binder.getCallingPid() 4540 + ", uid=" + Binder.getCallingUid() 4541 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 4542 Slog.w(TAG, msg); 4543 throw new SecurityException(msg); 4544 } 4545 final int callingPid = Binder.getCallingPid(); 4546 userId = handleIncomingUser(callingPid, Binder.getCallingUid(), 4547 userId, true, true, "forceStopPackage", null); 4548 long callingId = Binder.clearCallingIdentity(); 4549 try { 4550 IPackageManager pm = AppGlobals.getPackageManager(); 4551 synchronized(this) { 4552 int[] users = userId == UserHandle.USER_ALL 4553 ? getUsersLocked() : new int[] { userId }; 4554 for (int user : users) { 4555 int pkgUid = -1; 4556 try { 4557 pkgUid = pm.getPackageUid(packageName, user); 4558 } catch (RemoteException e) { 4559 } 4560 if (pkgUid == -1) { 4561 Slog.w(TAG, "Invalid packageName: " + packageName); 4562 continue; 4563 } 4564 try { 4565 pm.setPackageStoppedState(packageName, true, user); 4566 } catch (RemoteException e) { 4567 } catch (IllegalArgumentException e) { 4568 Slog.w(TAG, "Failed trying to unstop package " 4569 + packageName + ": " + e); 4570 } 4571 if (isUserRunningLocked(user, false)) { 4572 forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid); 4573 } 4574 } 4575 } 4576 } finally { 4577 Binder.restoreCallingIdentity(callingId); 4578 } 4579 } 4580 4581 /* 4582 * The pkg name and app id have to be specified. 4583 */ 4584 @Override 4585 public void killApplicationWithAppId(String pkg, int appid, String reason) { 4586 if (pkg == null) { 4587 return; 4588 } 4589 // Make sure the uid is valid. 4590 if (appid < 0) { 4591 Slog.w(TAG, "Invalid appid specified for pkg : " + pkg); 4592 return; 4593 } 4594 int callerUid = Binder.getCallingUid(); 4595 // Only the system server can kill an application 4596 if (callerUid == Process.SYSTEM_UID) { 4597 // Post an aysnc message to kill the application 4598 Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG); 4599 msg.arg1 = appid; 4600 msg.arg2 = 0; 4601 Bundle bundle = new Bundle(); 4602 bundle.putString("pkg", pkg); 4603 bundle.putString("reason", reason); 4604 msg.obj = bundle; 4605 mHandler.sendMessage(msg); 4606 } else { 4607 throw new SecurityException(callerUid + " cannot kill pkg: " + 4608 pkg); 4609 } 4610 } 4611 4612 @Override 4613 public void closeSystemDialogs(String reason) { 4614 enforceNotIsolatedCaller("closeSystemDialogs"); 4615 4616 final int pid = Binder.getCallingPid(); 4617 final int uid = Binder.getCallingUid(); 4618 final long origId = Binder.clearCallingIdentity(); 4619 try { 4620 synchronized (this) { 4621 // Only allow this from foreground processes, so that background 4622 // applications can't abuse it to prevent system UI from being shown. 4623 if (uid >= Process.FIRST_APPLICATION_UID) { 4624 ProcessRecord proc; 4625 synchronized (mPidsSelfLocked) { 4626 proc = mPidsSelfLocked.get(pid); 4627 } 4628 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 4629 Slog.w(TAG, "Ignoring closeSystemDialogs " + reason 4630 + " from background process " + proc); 4631 return; 4632 } 4633 } 4634 closeSystemDialogsLocked(reason); 4635 } 4636 } finally { 4637 Binder.restoreCallingIdentity(origId); 4638 } 4639 } 4640 4641 void closeSystemDialogsLocked(String reason) { 4642 Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS); 4643 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 4644 | Intent.FLAG_RECEIVER_FOREGROUND); 4645 if (reason != null) { 4646 intent.putExtra("reason", reason); 4647 } 4648 mWindowManager.closeSystemDialogs(reason); 4649 4650 mStackSupervisor.closeSystemDialogsLocked(); 4651 4652 broadcastIntentLocked(null, null, intent, null, 4653 null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1, 4654 Process.SYSTEM_UID, UserHandle.USER_ALL); 4655 } 4656 4657 @Override 4658 public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) { 4659 enforceNotIsolatedCaller("getProcessMemoryInfo"); 4660 Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length]; 4661 for (int i=pids.length-1; i>=0; i--) { 4662 ProcessRecord proc; 4663 int oomAdj; 4664 synchronized (this) { 4665 synchronized (mPidsSelfLocked) { 4666 proc = mPidsSelfLocked.get(pids[i]); 4667 oomAdj = proc != null ? proc.setAdj : 0; 4668 } 4669 } 4670 infos[i] = new Debug.MemoryInfo(); 4671 Debug.getMemoryInfo(pids[i], infos[i]); 4672 if (proc != null) { 4673 synchronized (this) { 4674 if (proc.thread != null && proc.setAdj == oomAdj) { 4675 // Record this for posterity if the process has been stable. 4676 proc.baseProcessTracker.addPss(infos[i].getTotalPss(), 4677 infos[i].getTotalUss(), false, proc.pkgList); 4678 } 4679 } 4680 } 4681 } 4682 return infos; 4683 } 4684 4685 @Override 4686 public long[] getProcessPss(int[] pids) { 4687 enforceNotIsolatedCaller("getProcessPss"); 4688 long[] pss = new long[pids.length]; 4689 for (int i=pids.length-1; i>=0; i--) { 4690 ProcessRecord proc; 4691 int oomAdj; 4692 synchronized (this) { 4693 synchronized (mPidsSelfLocked) { 4694 proc = mPidsSelfLocked.get(pids[i]); 4695 oomAdj = proc != null ? proc.setAdj : 0; 4696 } 4697 } 4698 long[] tmpUss = new long[1]; 4699 pss[i] = Debug.getPss(pids[i], tmpUss); 4700 if (proc != null) { 4701 synchronized (this) { 4702 if (proc.thread != null && proc.setAdj == oomAdj) { 4703 // Record this for posterity if the process has been stable. 4704 proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList); 4705 } 4706 } 4707 } 4708 } 4709 return pss; 4710 } 4711 4712 @Override 4713 public void killApplicationProcess(String processName, int uid) { 4714 if (processName == null) { 4715 return; 4716 } 4717 4718 int callerUid = Binder.getCallingUid(); 4719 // Only the system server can kill an application 4720 if (callerUid == Process.SYSTEM_UID) { 4721 synchronized (this) { 4722 ProcessRecord app = getProcessRecordLocked(processName, uid, true); 4723 if (app != null && app.thread != null) { 4724 try { 4725 app.thread.scheduleSuicide(); 4726 } catch (RemoteException e) { 4727 // If the other end already died, then our work here is done. 4728 } 4729 } else { 4730 Slog.w(TAG, "Process/uid not found attempting kill of " 4731 + processName + " / " + uid); 4732 } 4733 } 4734 } else { 4735 throw new SecurityException(callerUid + " cannot kill app process: " + 4736 processName); 4737 } 4738 } 4739 4740 private void forceStopPackageLocked(final String packageName, int uid, String reason) { 4741 forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false, 4742 false, true, false, false, UserHandle.getUserId(uid), reason); 4743 Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED, 4744 Uri.fromParts("package", packageName, null)); 4745 if (!mProcessesReady) { 4746 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 4747 | Intent.FLAG_RECEIVER_FOREGROUND); 4748 } 4749 intent.putExtra(Intent.EXTRA_UID, uid); 4750 intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid)); 4751 broadcastIntentLocked(null, null, intent, 4752 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 4753 false, false, 4754 MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid)); 4755 } 4756 4757 private void forceStopUserLocked(int userId, String reason) { 4758 forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason); 4759 Intent intent = new Intent(Intent.ACTION_USER_STOPPED); 4760 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 4761 | Intent.FLAG_RECEIVER_FOREGROUND); 4762 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 4763 broadcastIntentLocked(null, null, intent, 4764 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 4765 false, false, 4766 MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 4767 } 4768 4769 private final boolean killPackageProcessesLocked(String packageName, int appId, 4770 int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart, 4771 boolean doit, boolean evenPersistent, String reason) { 4772 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 4773 4774 // Remove all processes this package may have touched: all with the 4775 // same UID (except for the system or root user), and all whose name 4776 // matches the package name. 4777 final String procNamePrefix = packageName != null ? (packageName + ":") : null; 4778 final int NP = mProcessNames.getMap().size(); 4779 for (int ip=0; ip<NP; ip++) { 4780 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 4781 final int NA = apps.size(); 4782 for (int ia=0; ia<NA; ia++) { 4783 ProcessRecord app = apps.valueAt(ia); 4784 if (app.persistent && !evenPersistent) { 4785 // we don't kill persistent processes 4786 continue; 4787 } 4788 if (app.removed) { 4789 if (doit) { 4790 procs.add(app); 4791 } 4792 continue; 4793 } 4794 4795 // Skip process if it doesn't meet our oom adj requirement. 4796 if (app.setAdj < minOomAdj) { 4797 continue; 4798 } 4799 4800 // If no package is specified, we call all processes under the 4801 // give user id. 4802 if (packageName == null) { 4803 if (app.userId != userId) { 4804 continue; 4805 } 4806 if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) { 4807 continue; 4808 } 4809 // Package has been specified, we want to hit all processes 4810 // that match it. We need to qualify this by the processes 4811 // that are running under the specified app and user ID. 4812 } else { 4813 if (UserHandle.getAppId(app.uid) != appId) { 4814 continue; 4815 } 4816 if (userId != UserHandle.USER_ALL && app.userId != userId) { 4817 continue; 4818 } 4819 if (!app.pkgList.containsKey(packageName)) { 4820 continue; 4821 } 4822 } 4823 4824 // Process has passed all conditions, kill it! 4825 if (!doit) { 4826 return true; 4827 } 4828 app.removed = true; 4829 procs.add(app); 4830 } 4831 } 4832 4833 int N = procs.size(); 4834 for (int i=0; i<N; i++) { 4835 removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason); 4836 } 4837 updateOomAdjLocked(); 4838 return N > 0; 4839 } 4840 4841 private final boolean forceStopPackageLocked(String name, int appId, 4842 boolean callerWillRestart, boolean purgeCache, boolean doit, 4843 boolean evenPersistent, boolean uninstalling, int userId, String reason) { 4844 int i; 4845 int N; 4846 4847 if (userId == UserHandle.USER_ALL && name == null) { 4848 Slog.w(TAG, "Can't force stop all processes of all users, that is insane!"); 4849 } 4850 4851 if (appId < 0 && name != null) { 4852 try { 4853 appId = UserHandle.getAppId( 4854 AppGlobals.getPackageManager().getPackageUid(name, 0)); 4855 } catch (RemoteException e) { 4856 } 4857 } 4858 4859 if (doit) { 4860 if (name != null) { 4861 Slog.i(TAG, "Force stopping " + name + " appid=" + appId 4862 + " user=" + userId + ": " + reason); 4863 } else { 4864 Slog.i(TAG, "Force stopping u" + userId + ": " + reason); 4865 } 4866 4867 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap(); 4868 for (int ip=pmap.size()-1; ip>=0; ip--) { 4869 SparseArray<Long> ba = pmap.valueAt(ip); 4870 for (i=ba.size()-1; i>=0; i--) { 4871 boolean remove = false; 4872 final int entUid = ba.keyAt(i); 4873 if (name != null) { 4874 if (userId == UserHandle.USER_ALL) { 4875 if (UserHandle.getAppId(entUid) == appId) { 4876 remove = true; 4877 } 4878 } else { 4879 if (entUid == UserHandle.getUid(userId, appId)) { 4880 remove = true; 4881 } 4882 } 4883 } else if (UserHandle.getUserId(entUid) == userId) { 4884 remove = true; 4885 } 4886 if (remove) { 4887 ba.removeAt(i); 4888 } 4889 } 4890 if (ba.size() == 0) { 4891 pmap.removeAt(ip); 4892 } 4893 } 4894 } 4895 4896 boolean didSomething = killPackageProcessesLocked(name, appId, userId, 4897 -100, callerWillRestart, true, doit, evenPersistent, 4898 name == null ? ("stop user " + userId) : ("stop " + name)); 4899 4900 if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) { 4901 if (!doit) { 4902 return true; 4903 } 4904 didSomething = true; 4905 } 4906 4907 if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) { 4908 if (!doit) { 4909 return true; 4910 } 4911 didSomething = true; 4912 } 4913 4914 if (name == null) { 4915 // Remove all sticky broadcasts from this user. 4916 mStickyBroadcasts.remove(userId); 4917 } 4918 4919 ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>(); 4920 if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent, 4921 userId, providers)) { 4922 if (!doit) { 4923 return true; 4924 } 4925 didSomething = true; 4926 } 4927 N = providers.size(); 4928 for (i=0; i<N; i++) { 4929 removeDyingProviderLocked(null, providers.get(i), true); 4930 } 4931 4932 // Remove transient permissions granted from/to this package/user 4933 removeUriPermissionsForPackageLocked(name, userId, false); 4934 4935 if (name == null || uninstalling) { 4936 // Remove pending intents. For now we only do this when force 4937 // stopping users, because we have some problems when doing this 4938 // for packages -- app widgets are not currently cleaned up for 4939 // such packages, so they can be left with bad pending intents. 4940 if (mIntentSenderRecords.size() > 0) { 4941 Iterator<WeakReference<PendingIntentRecord>> it 4942 = mIntentSenderRecords.values().iterator(); 4943 while (it.hasNext()) { 4944 WeakReference<PendingIntentRecord> wpir = it.next(); 4945 if (wpir == null) { 4946 it.remove(); 4947 continue; 4948 } 4949 PendingIntentRecord pir = wpir.get(); 4950 if (pir == null) { 4951 it.remove(); 4952 continue; 4953 } 4954 if (name == null) { 4955 // Stopping user, remove all objects for the user. 4956 if (pir.key.userId != userId) { 4957 // Not the same user, skip it. 4958 continue; 4959 } 4960 } else { 4961 if (UserHandle.getAppId(pir.uid) != appId) { 4962 // Different app id, skip it. 4963 continue; 4964 } 4965 if (userId != UserHandle.USER_ALL && pir.key.userId != userId) { 4966 // Different user, skip it. 4967 continue; 4968 } 4969 if (!pir.key.packageName.equals(name)) { 4970 // Different package, skip it. 4971 continue; 4972 } 4973 } 4974 if (!doit) { 4975 return true; 4976 } 4977 didSomething = true; 4978 it.remove(); 4979 pir.canceled = true; 4980 if (pir.key.activity != null) { 4981 pir.key.activity.pendingResults.remove(pir.ref); 4982 } 4983 } 4984 } 4985 } 4986 4987 if (doit) { 4988 if (purgeCache && name != null) { 4989 AttributeCache ac = AttributeCache.instance(); 4990 if (ac != null) { 4991 ac.removePackage(name); 4992 } 4993 } 4994 if (mBooted) { 4995 mStackSupervisor.resumeTopActivitiesLocked(); 4996 mStackSupervisor.scheduleIdleLocked(); 4997 } 4998 } 4999 5000 return didSomething; 5001 } 5002 5003 private final boolean removeProcessLocked(ProcessRecord app, 5004 boolean callerWillRestart, boolean allowRestart, String reason) { 5005 final String name = app.processName; 5006 final int uid = app.uid; 5007 if (DEBUG_PROCESSES) Slog.d( 5008 TAG, "Force removing proc " + app.toShortString() + " (" + name 5009 + "/" + uid + ")"); 5010 5011 mProcessNames.remove(name, uid); 5012 mIsolatedProcesses.remove(app.uid); 5013 if (mHeavyWeightProcess == app) { 5014 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 5015 mHeavyWeightProcess.userId, 0)); 5016 mHeavyWeightProcess = null; 5017 } 5018 boolean needRestart = false; 5019 if (app.pid > 0 && app.pid != MY_PID) { 5020 int pid = app.pid; 5021 synchronized (mPidsSelfLocked) { 5022 mPidsSelfLocked.remove(pid); 5023 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 5024 } 5025 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH, 5026 app.processName, app.info.uid); 5027 if (app.isolated) { 5028 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 5029 } 5030 killUnneededProcessLocked(app, reason); 5031 handleAppDiedLocked(app, true, allowRestart); 5032 removeLruProcessLocked(app); 5033 5034 if (app.persistent && !app.isolated) { 5035 if (!callerWillRestart) { 5036 addAppLocked(app.info, false); 5037 } else { 5038 needRestart = true; 5039 } 5040 } 5041 } else { 5042 mRemovedProcesses.add(app); 5043 } 5044 5045 return needRestart; 5046 } 5047 5048 private final void processStartTimedOutLocked(ProcessRecord app) { 5049 final int pid = app.pid; 5050 boolean gone = false; 5051 synchronized (mPidsSelfLocked) { 5052 ProcessRecord knownApp = mPidsSelfLocked.get(pid); 5053 if (knownApp != null && knownApp.thread == null) { 5054 mPidsSelfLocked.remove(pid); 5055 gone = true; 5056 } 5057 } 5058 5059 if (gone) { 5060 Slog.w(TAG, "Process " + app + " failed to attach"); 5061 EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId, 5062 pid, app.uid, app.processName); 5063 mProcessNames.remove(app.processName, app.uid); 5064 mIsolatedProcesses.remove(app.uid); 5065 if (mHeavyWeightProcess == app) { 5066 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 5067 mHeavyWeightProcess.userId, 0)); 5068 mHeavyWeightProcess = null; 5069 } 5070 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH, 5071 app.processName, app.info.uid); 5072 if (app.isolated) { 5073 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 5074 } 5075 // Take care of any launching providers waiting for this process. 5076 checkAppInLaunchingProvidersLocked(app, true); 5077 // Take care of any services that are waiting for the process. 5078 mServices.processStartTimedOutLocked(app); 5079 killUnneededProcessLocked(app, "start timeout"); 5080 if (mBackupTarget != null && mBackupTarget.app.pid == pid) { 5081 Slog.w(TAG, "Unattached app died before backup, skipping"); 5082 try { 5083 IBackupManager bm = IBackupManager.Stub.asInterface( 5084 ServiceManager.getService(Context.BACKUP_SERVICE)); 5085 bm.agentDisconnected(app.info.packageName); 5086 } catch (RemoteException e) { 5087 // Can't happen; the backup manager is local 5088 } 5089 } 5090 if (isPendingBroadcastProcessLocked(pid)) { 5091 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 5092 skipPendingBroadcastLocked(pid); 5093 } 5094 } else { 5095 Slog.w(TAG, "Spurious process start timeout - pid not known for " + app); 5096 } 5097 } 5098 5099 private final boolean attachApplicationLocked(IApplicationThread thread, 5100 int pid) { 5101 5102 // Find the application record that is being attached... either via 5103 // the pid if we are running in multiple processes, or just pull the 5104 // next app record if we are emulating process with anonymous threads. 5105 ProcessRecord app; 5106 if (pid != MY_PID && pid >= 0) { 5107 synchronized (mPidsSelfLocked) { 5108 app = mPidsSelfLocked.get(pid); 5109 } 5110 } else { 5111 app = null; 5112 } 5113 5114 if (app == null) { 5115 Slog.w(TAG, "No pending application record for pid " + pid 5116 + " (IApplicationThread " + thread + "); dropping process"); 5117 EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid); 5118 if (pid > 0 && pid != MY_PID) { 5119 Process.killProcessQuiet(pid); 5120 } else { 5121 try { 5122 thread.scheduleExit(); 5123 } catch (Exception e) { 5124 // Ignore exceptions. 5125 } 5126 } 5127 return false; 5128 } 5129 5130 // If this application record is still attached to a previous 5131 // process, clean it up now. 5132 if (app.thread != null) { 5133 handleAppDiedLocked(app, true, true); 5134 } 5135 5136 // Tell the process all about itself. 5137 5138 if (localLOGV) Slog.v( 5139 TAG, "Binding process pid " + pid + " to record " + app); 5140 5141 final String processName = app.processName; 5142 try { 5143 AppDeathRecipient adr = new AppDeathRecipient( 5144 app, pid, thread); 5145 thread.asBinder().linkToDeath(adr, 0); 5146 app.deathRecipient = adr; 5147 } catch (RemoteException e) { 5148 app.resetPackageList(mProcessStats); 5149 startProcessLocked(app, "link fail", processName); 5150 return false; 5151 } 5152 5153 EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName); 5154 5155 app.makeActive(thread, mProcessStats); 5156 app.curAdj = app.setAdj = -100; 5157 app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT; 5158 app.forcingToForeground = null; 5159 updateProcessForegroundLocked(app, false, false); 5160 app.hasShownUi = false; 5161 app.debugging = false; 5162 app.cached = false; 5163 5164 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 5165 5166 boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info); 5167 List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null; 5168 5169 if (!normalMode) { 5170 Slog.i(TAG, "Launching preboot mode app: " + app); 5171 } 5172 5173 if (localLOGV) Slog.v( 5174 TAG, "New app record " + app 5175 + " thread=" + thread.asBinder() + " pid=" + pid); 5176 try { 5177 int testMode = IApplicationThread.DEBUG_OFF; 5178 if (mDebugApp != null && mDebugApp.equals(processName)) { 5179 testMode = mWaitForDebugger 5180 ? IApplicationThread.DEBUG_WAIT 5181 : IApplicationThread.DEBUG_ON; 5182 app.debugging = true; 5183 if (mDebugTransient) { 5184 mDebugApp = mOrigDebugApp; 5185 mWaitForDebugger = mOrigWaitForDebugger; 5186 } 5187 } 5188 String profileFile = app.instrumentationProfileFile; 5189 ParcelFileDescriptor profileFd = null; 5190 boolean profileAutoStop = false; 5191 if (mProfileApp != null && mProfileApp.equals(processName)) { 5192 mProfileProc = app; 5193 profileFile = mProfileFile; 5194 profileFd = mProfileFd; 5195 profileAutoStop = mAutoStopProfiler; 5196 } 5197 boolean enableOpenGlTrace = false; 5198 if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) { 5199 enableOpenGlTrace = true; 5200 mOpenGlTraceApp = null; 5201 } 5202 5203 // If the app is being launched for restore or full backup, set it up specially 5204 boolean isRestrictedBackupMode = false; 5205 if (mBackupTarget != null && mBackupAppName.equals(processName)) { 5206 isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE) 5207 || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL) 5208 || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL); 5209 } 5210 5211 ensurePackageDexOpt(app.instrumentationInfo != null 5212 ? app.instrumentationInfo.packageName 5213 : app.info.packageName); 5214 if (app.instrumentationClass != null) { 5215 ensurePackageDexOpt(app.instrumentationClass.getPackageName()); 5216 } 5217 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc " 5218 + processName + " with config " + mConfiguration); 5219 ApplicationInfo appInfo = app.instrumentationInfo != null 5220 ? app.instrumentationInfo : app.info; 5221 app.compat = compatibilityInfoForPackageLocked(appInfo); 5222 if (profileFd != null) { 5223 profileFd = profileFd.dup(); 5224 } 5225 thread.bindApplication(processName, appInfo, providers, 5226 app.instrumentationClass, profileFile, profileFd, profileAutoStop, 5227 app.instrumentationArguments, app.instrumentationWatcher, 5228 app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace, 5229 isRestrictedBackupMode || !normalMode, app.persistent, 5230 new Configuration(mConfiguration), app.compat, getCommonServicesLocked(), 5231 mCoreSettingsObserver.getCoreSettingsLocked()); 5232 updateLruProcessLocked(app, false, null); 5233 app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis(); 5234 } catch (Exception e) { 5235 // todo: Yikes! What should we do? For now we will try to 5236 // start another process, but that could easily get us in 5237 // an infinite loop of restarting processes... 5238 Slog.w(TAG, "Exception thrown during bind!", e); 5239 5240 app.resetPackageList(mProcessStats); 5241 app.unlinkDeathRecipient(); 5242 startProcessLocked(app, "bind fail", processName); 5243 return false; 5244 } 5245 5246 // Remove this record from the list of starting applications. 5247 mPersistentStartingProcesses.remove(app); 5248 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 5249 "Attach application locked removing on hold: " + app); 5250 mProcessesOnHold.remove(app); 5251 5252 boolean badApp = false; 5253 boolean didSomething = false; 5254 5255 // See if the top visible activity is waiting to run in this process... 5256 if (normalMode) { 5257 try { 5258 if (mStackSupervisor.attachApplicationLocked(app)) { 5259 didSomething = true; 5260 } 5261 } catch (Exception e) { 5262 badApp = true; 5263 } 5264 } 5265 5266 // Find any services that should be running in this process... 5267 if (!badApp) { 5268 try { 5269 didSomething |= mServices.attachApplicationLocked(app, processName); 5270 } catch (Exception e) { 5271 badApp = true; 5272 } 5273 } 5274 5275 // Check if a next-broadcast receiver is in this process... 5276 if (!badApp && isPendingBroadcastProcessLocked(pid)) { 5277 try { 5278 didSomething |= sendPendingBroadcastsLocked(app); 5279 } catch (Exception e) { 5280 // If the app died trying to launch the receiver we declare it 'bad' 5281 badApp = true; 5282 } 5283 } 5284 5285 // Check whether the next backup agent is in this process... 5286 if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) { 5287 if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app); 5288 ensurePackageDexOpt(mBackupTarget.appInfo.packageName); 5289 try { 5290 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo, 5291 compatibilityInfoForPackageLocked(mBackupTarget.appInfo), 5292 mBackupTarget.backupMode); 5293 } catch (Exception e) { 5294 Slog.w(TAG, "Exception scheduling backup agent creation: "); 5295 e.printStackTrace(); 5296 } 5297 } 5298 5299 if (badApp) { 5300 // todo: Also need to kill application to deal with all 5301 // kinds of exceptions. 5302 handleAppDiedLocked(app, false, true); 5303 return false; 5304 } 5305 5306 if (!didSomething) { 5307 updateOomAdjLocked(); 5308 } 5309 5310 return true; 5311 } 5312 5313 @Override 5314 public final void attachApplication(IApplicationThread thread) { 5315 synchronized (this) { 5316 int callingPid = Binder.getCallingPid(); 5317 final long origId = Binder.clearCallingIdentity(); 5318 attachApplicationLocked(thread, callingPid); 5319 Binder.restoreCallingIdentity(origId); 5320 } 5321 } 5322 5323 @Override 5324 public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) { 5325 final long origId = Binder.clearCallingIdentity(); 5326 synchronized (this) { 5327 ActivityStack stack = ActivityRecord.getStackLocked(token); 5328 if (stack != null) { 5329 ActivityRecord r = 5330 mStackSupervisor.activityIdleInternalLocked(token, false, config); 5331 if (stopProfiling) { 5332 if ((mProfileProc == r.app) && (mProfileFd != null)) { 5333 try { 5334 mProfileFd.close(); 5335 } catch (IOException e) { 5336 } 5337 clearProfilerLocked(); 5338 } 5339 } 5340 } 5341 } 5342 Binder.restoreCallingIdentity(origId); 5343 } 5344 5345 void enableScreenAfterBoot() { 5346 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN, 5347 SystemClock.uptimeMillis()); 5348 mWindowManager.enableScreenAfterBoot(); 5349 5350 synchronized (this) { 5351 updateEventDispatchingLocked(); 5352 } 5353 } 5354 5355 @Override 5356 public void showBootMessage(final CharSequence msg, final boolean always) { 5357 enforceNotIsolatedCaller("showBootMessage"); 5358 mWindowManager.showBootMessage(msg, always); 5359 } 5360 5361 @Override 5362 public void dismissKeyguardOnNextActivity() { 5363 enforceNotIsolatedCaller("dismissKeyguardOnNextActivity"); 5364 final long token = Binder.clearCallingIdentity(); 5365 try { 5366 synchronized (this) { 5367 if (DEBUG_LOCKSCREEN) logLockScreen(""); 5368 if (mLockScreenShown) { 5369 mLockScreenShown = false; 5370 comeOutOfSleepIfNeededLocked(); 5371 } 5372 mStackSupervisor.setDismissKeyguard(true); 5373 } 5374 } finally { 5375 Binder.restoreCallingIdentity(token); 5376 } 5377 } 5378 5379 final void finishBooting() { 5380 // Register receivers to handle package update events 5381 mPackageMonitor.register(mContext, Looper.getMainLooper(), false); 5382 5383 synchronized (this) { 5384 // Ensure that any processes we had put on hold are now started 5385 // up. 5386 final int NP = mProcessesOnHold.size(); 5387 if (NP > 0) { 5388 ArrayList<ProcessRecord> procs = 5389 new ArrayList<ProcessRecord>(mProcessesOnHold); 5390 for (int ip=0; ip<NP; ip++) { 5391 if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: " 5392 + procs.get(ip)); 5393 startProcessLocked(procs.get(ip), "on-hold", null); 5394 } 5395 } 5396 5397 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 5398 // Start looking for apps that are abusing wake locks. 5399 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 5400 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 5401 // Tell anyone interested that we are done booting! 5402 SystemProperties.set("sys.boot_completed", "1"); 5403 SystemProperties.set("dev.bootcomplete", "1"); 5404 for (int i=0; i<mStartedUsers.size(); i++) { 5405 UserStartedState uss = mStartedUsers.valueAt(i); 5406 if (uss.mState == UserStartedState.STATE_BOOTING) { 5407 uss.mState = UserStartedState.STATE_RUNNING; 5408 final int userId = mStartedUsers.keyAt(i); 5409 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 5410 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 5411 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT); 5412 broadcastIntentLocked(null, null, intent, null, 5413 new IIntentReceiver.Stub() { 5414 @Override 5415 public void performReceive(Intent intent, int resultCode, 5416 String data, Bundle extras, boolean ordered, 5417 boolean sticky, int sendingUser) { 5418 synchronized (ActivityManagerService.this) { 5419 requestPssAllProcsLocked(SystemClock.uptimeMillis(), 5420 true, false); 5421 } 5422 } 5423 }, 5424 0, null, null, 5425 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, 5426 AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID, 5427 userId); 5428 } 5429 } 5430 scheduleStartProfilesLocked(); 5431 } 5432 } 5433 } 5434 5435 final void ensureBootCompleted() { 5436 boolean booting; 5437 boolean enableScreen; 5438 synchronized (this) { 5439 booting = mBooting; 5440 mBooting = false; 5441 enableScreen = !mBooted; 5442 mBooted = true; 5443 } 5444 5445 if (booting) { 5446 finishBooting(); 5447 } 5448 5449 if (enableScreen) { 5450 enableScreenAfterBoot(); 5451 } 5452 } 5453 5454 @Override 5455 public final void activityResumed(IBinder token) { 5456 final long origId = Binder.clearCallingIdentity(); 5457 synchronized(this) { 5458 ActivityStack stack = ActivityRecord.getStackLocked(token); 5459 if (stack != null) { 5460 ActivityRecord.activityResumedLocked(token); 5461 } 5462 } 5463 Binder.restoreCallingIdentity(origId); 5464 } 5465 5466 @Override 5467 public final void activityPaused(IBinder token, PersistableBundle persistentState) { 5468 final long origId = Binder.clearCallingIdentity(); 5469 synchronized(this) { 5470 ActivityStack stack = ActivityRecord.getStackLocked(token); 5471 if (stack != null) { 5472 stack.activityPausedLocked(token, false, persistentState); 5473 } 5474 } 5475 Binder.restoreCallingIdentity(origId); 5476 } 5477 5478 @Override 5479 public final void activityStopped(IBinder token, Bundle icicle, 5480 PersistableBundle persistentState, CharSequence description) { 5481 if (localLOGV) Slog.v(TAG, "Activity stopped: token=" + token); 5482 5483 // Refuse possible leaked file descriptors 5484 if (icicle != null && icicle.hasFileDescriptors()) { 5485 throw new IllegalArgumentException("File descriptors passed in Bundle"); 5486 } 5487 5488 final long origId = Binder.clearCallingIdentity(); 5489 5490 synchronized (this) { 5491 ActivityRecord r = ActivityRecord.isInStackLocked(token); 5492 if (r != null) { 5493 r.task.stack.activityStoppedLocked(r, icicle, persistentState, description); 5494 } 5495 } 5496 5497 trimApplications(); 5498 5499 Binder.restoreCallingIdentity(origId); 5500 } 5501 5502 @Override 5503 public final void activityDestroyed(IBinder token) { 5504 if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token); 5505 synchronized (this) { 5506 ActivityStack stack = ActivityRecord.getStackLocked(token); 5507 if (stack != null) { 5508 stack.activityDestroyedLocked(token); 5509 } 5510 } 5511 } 5512 5513 @Override 5514 public String getCallingPackage(IBinder token) { 5515 synchronized (this) { 5516 ActivityRecord r = getCallingRecordLocked(token); 5517 return r != null ? r.info.packageName : null; 5518 } 5519 } 5520 5521 @Override 5522 public ComponentName getCallingActivity(IBinder token) { 5523 synchronized (this) { 5524 ActivityRecord r = getCallingRecordLocked(token); 5525 return r != null ? r.intent.getComponent() : null; 5526 } 5527 } 5528 5529 private ActivityRecord getCallingRecordLocked(IBinder token) { 5530 ActivityRecord r = ActivityRecord.isInStackLocked(token); 5531 if (r == null) { 5532 return null; 5533 } 5534 return r.resultTo; 5535 } 5536 5537 @Override 5538 public ComponentName getActivityClassForToken(IBinder token) { 5539 synchronized(this) { 5540 ActivityRecord r = ActivityRecord.isInStackLocked(token); 5541 if (r == null) { 5542 return null; 5543 } 5544 return r.intent.getComponent(); 5545 } 5546 } 5547 5548 @Override 5549 public String getPackageForToken(IBinder token) { 5550 synchronized(this) { 5551 ActivityRecord r = ActivityRecord.isInStackLocked(token); 5552 if (r == null) { 5553 return null; 5554 } 5555 return r.packageName; 5556 } 5557 } 5558 5559 @Override 5560 public IIntentSender getIntentSender(int type, 5561 String packageName, IBinder token, String resultWho, 5562 int requestCode, Intent[] intents, String[] resolvedTypes, 5563 int flags, Bundle options, int userId) { 5564 enforceNotIsolatedCaller("getIntentSender"); 5565 // Refuse possible leaked file descriptors 5566 if (intents != null) { 5567 if (intents.length < 1) { 5568 throw new IllegalArgumentException("Intents array length must be >= 1"); 5569 } 5570 for (int i=0; i<intents.length; i++) { 5571 Intent intent = intents[i]; 5572 if (intent != null) { 5573 if (intent.hasFileDescriptors()) { 5574 throw new IllegalArgumentException("File descriptors passed in Intent"); 5575 } 5576 if (type == ActivityManager.INTENT_SENDER_BROADCAST && 5577 (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 5578 throw new IllegalArgumentException( 5579 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 5580 } 5581 intents[i] = new Intent(intent); 5582 } 5583 } 5584 if (resolvedTypes != null && resolvedTypes.length != intents.length) { 5585 throw new IllegalArgumentException( 5586 "Intent array length does not match resolvedTypes length"); 5587 } 5588 } 5589 if (options != null) { 5590 if (options.hasFileDescriptors()) { 5591 throw new IllegalArgumentException("File descriptors passed in options"); 5592 } 5593 } 5594 5595 synchronized(this) { 5596 int callingUid = Binder.getCallingUid(); 5597 int origUserId = userId; 5598 userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId, 5599 type == ActivityManager.INTENT_SENDER_BROADCAST, false, 5600 "getIntentSender", null); 5601 if (origUserId == UserHandle.USER_CURRENT) { 5602 // We don't want to evaluate this until the pending intent is 5603 // actually executed. However, we do want to always do the 5604 // security checking for it above. 5605 userId = UserHandle.USER_CURRENT; 5606 } 5607 try { 5608 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 5609 int uid = AppGlobals.getPackageManager() 5610 .getPackageUid(packageName, UserHandle.getUserId(callingUid)); 5611 if (!UserHandle.isSameApp(callingUid, uid)) { 5612 String msg = "Permission Denial: getIntentSender() from pid=" 5613 + Binder.getCallingPid() 5614 + ", uid=" + Binder.getCallingUid() 5615 + ", (need uid=" + uid + ")" 5616 + " is not allowed to send as package " + packageName; 5617 Slog.w(TAG, msg); 5618 throw new SecurityException(msg); 5619 } 5620 } 5621 5622 return getIntentSenderLocked(type, packageName, callingUid, userId, 5623 token, resultWho, requestCode, intents, resolvedTypes, flags, options); 5624 5625 } catch (RemoteException e) { 5626 throw new SecurityException(e); 5627 } 5628 } 5629 } 5630 5631 IIntentSender getIntentSenderLocked(int type, String packageName, 5632 int callingUid, int userId, IBinder token, String resultWho, 5633 int requestCode, Intent[] intents, String[] resolvedTypes, int flags, 5634 Bundle options) { 5635 if (DEBUG_MU) 5636 Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid); 5637 ActivityRecord activity = null; 5638 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 5639 activity = ActivityRecord.isInStackLocked(token); 5640 if (activity == null) { 5641 return null; 5642 } 5643 if (activity.finishing) { 5644 return null; 5645 } 5646 } 5647 5648 final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0; 5649 final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0; 5650 final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0; 5651 flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT 5652 |PendingIntent.FLAG_UPDATE_CURRENT); 5653 5654 PendingIntentRecord.Key key = new PendingIntentRecord.Key( 5655 type, packageName, activity, resultWho, 5656 requestCode, intents, resolvedTypes, flags, options, userId); 5657 WeakReference<PendingIntentRecord> ref; 5658 ref = mIntentSenderRecords.get(key); 5659 PendingIntentRecord rec = ref != null ? ref.get() : null; 5660 if (rec != null) { 5661 if (!cancelCurrent) { 5662 if (updateCurrent) { 5663 if (rec.key.requestIntent != null) { 5664 rec.key.requestIntent.replaceExtras(intents != null ? 5665 intents[intents.length - 1] : null); 5666 } 5667 if (intents != null) { 5668 intents[intents.length-1] = rec.key.requestIntent; 5669 rec.key.allIntents = intents; 5670 rec.key.allResolvedTypes = resolvedTypes; 5671 } else { 5672 rec.key.allIntents = null; 5673 rec.key.allResolvedTypes = null; 5674 } 5675 } 5676 return rec; 5677 } 5678 rec.canceled = true; 5679 mIntentSenderRecords.remove(key); 5680 } 5681 if (noCreate) { 5682 return rec; 5683 } 5684 rec = new PendingIntentRecord(this, key, callingUid); 5685 mIntentSenderRecords.put(key, rec.ref); 5686 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 5687 if (activity.pendingResults == null) { 5688 activity.pendingResults 5689 = new HashSet<WeakReference<PendingIntentRecord>>(); 5690 } 5691 activity.pendingResults.add(rec.ref); 5692 } 5693 return rec; 5694 } 5695 5696 @Override 5697 public void cancelIntentSender(IIntentSender sender) { 5698 if (!(sender instanceof PendingIntentRecord)) { 5699 return; 5700 } 5701 synchronized(this) { 5702 PendingIntentRecord rec = (PendingIntentRecord)sender; 5703 try { 5704 int uid = AppGlobals.getPackageManager() 5705 .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId()); 5706 if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) { 5707 String msg = "Permission Denial: cancelIntentSender() from pid=" 5708 + Binder.getCallingPid() 5709 + ", uid=" + Binder.getCallingUid() 5710 + " is not allowed to cancel packges " 5711 + rec.key.packageName; 5712 Slog.w(TAG, msg); 5713 throw new SecurityException(msg); 5714 } 5715 } catch (RemoteException e) { 5716 throw new SecurityException(e); 5717 } 5718 cancelIntentSenderLocked(rec, true); 5719 } 5720 } 5721 5722 void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) { 5723 rec.canceled = true; 5724 mIntentSenderRecords.remove(rec.key); 5725 if (cleanActivity && rec.key.activity != null) { 5726 rec.key.activity.pendingResults.remove(rec.ref); 5727 } 5728 } 5729 5730 @Override 5731 public String getPackageForIntentSender(IIntentSender pendingResult) { 5732 if (!(pendingResult instanceof PendingIntentRecord)) { 5733 return null; 5734 } 5735 try { 5736 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5737 return res.key.packageName; 5738 } catch (ClassCastException e) { 5739 } 5740 return null; 5741 } 5742 5743 @Override 5744 public int getUidForIntentSender(IIntentSender sender) { 5745 if (sender instanceof PendingIntentRecord) { 5746 try { 5747 PendingIntentRecord res = (PendingIntentRecord)sender; 5748 return res.uid; 5749 } catch (ClassCastException e) { 5750 } 5751 } 5752 return -1; 5753 } 5754 5755 @Override 5756 public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) { 5757 if (!(pendingResult instanceof PendingIntentRecord)) { 5758 return false; 5759 } 5760 try { 5761 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5762 if (res.key.allIntents == null) { 5763 return false; 5764 } 5765 for (int i=0; i<res.key.allIntents.length; i++) { 5766 Intent intent = res.key.allIntents[i]; 5767 if (intent.getPackage() != null && intent.getComponent() != null) { 5768 return false; 5769 } 5770 } 5771 return true; 5772 } catch (ClassCastException e) { 5773 } 5774 return false; 5775 } 5776 5777 @Override 5778 public boolean isIntentSenderAnActivity(IIntentSender pendingResult) { 5779 if (!(pendingResult instanceof PendingIntentRecord)) { 5780 return false; 5781 } 5782 try { 5783 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5784 if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) { 5785 return true; 5786 } 5787 return false; 5788 } catch (ClassCastException e) { 5789 } 5790 return false; 5791 } 5792 5793 @Override 5794 public Intent getIntentForIntentSender(IIntentSender pendingResult) { 5795 if (!(pendingResult instanceof PendingIntentRecord)) { 5796 return null; 5797 } 5798 try { 5799 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5800 return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null; 5801 } catch (ClassCastException e) { 5802 } 5803 return null; 5804 } 5805 5806 @Override 5807 public String getTagForIntentSender(IIntentSender pendingResult, String prefix) { 5808 if (!(pendingResult instanceof PendingIntentRecord)) { 5809 return null; 5810 } 5811 try { 5812 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5813 Intent intent = res.key.requestIntent; 5814 if (intent != null) { 5815 if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null 5816 || res.lastTagPrefix.equals(prefix))) { 5817 return res.lastTag; 5818 } 5819 res.lastTagPrefix = prefix; 5820 StringBuilder sb = new StringBuilder(128); 5821 if (prefix != null) { 5822 sb.append(prefix); 5823 } 5824 if (intent.getAction() != null) { 5825 sb.append(intent.getAction()); 5826 } else if (intent.getComponent() != null) { 5827 intent.getComponent().appendShortString(sb); 5828 } else { 5829 sb.append("?"); 5830 } 5831 return res.lastTag = sb.toString(); 5832 } 5833 } catch (ClassCastException e) { 5834 } 5835 return null; 5836 } 5837 5838 @Override 5839 public void setProcessLimit(int max) { 5840 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 5841 "setProcessLimit()"); 5842 synchronized (this) { 5843 mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max; 5844 mProcessLimitOverride = max; 5845 } 5846 trimApplications(); 5847 } 5848 5849 @Override 5850 public int getProcessLimit() { 5851 synchronized (this) { 5852 return mProcessLimitOverride; 5853 } 5854 } 5855 5856 void foregroundTokenDied(ForegroundToken token) { 5857 synchronized (ActivityManagerService.this) { 5858 synchronized (mPidsSelfLocked) { 5859 ForegroundToken cur 5860 = mForegroundProcesses.get(token.pid); 5861 if (cur != token) { 5862 return; 5863 } 5864 mForegroundProcesses.remove(token.pid); 5865 ProcessRecord pr = mPidsSelfLocked.get(token.pid); 5866 if (pr == null) { 5867 return; 5868 } 5869 pr.forcingToForeground = null; 5870 updateProcessForegroundLocked(pr, false, false); 5871 } 5872 updateOomAdjLocked(); 5873 } 5874 } 5875 5876 @Override 5877 public void setProcessForeground(IBinder token, int pid, boolean isForeground) { 5878 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 5879 "setProcessForeground()"); 5880 synchronized(this) { 5881 boolean changed = false; 5882 5883 synchronized (mPidsSelfLocked) { 5884 ProcessRecord pr = mPidsSelfLocked.get(pid); 5885 if (pr == null && isForeground) { 5886 Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid); 5887 return; 5888 } 5889 ForegroundToken oldToken = mForegroundProcesses.get(pid); 5890 if (oldToken != null) { 5891 oldToken.token.unlinkToDeath(oldToken, 0); 5892 mForegroundProcesses.remove(pid); 5893 if (pr != null) { 5894 pr.forcingToForeground = null; 5895 } 5896 changed = true; 5897 } 5898 if (isForeground && token != null) { 5899 ForegroundToken newToken = new ForegroundToken() { 5900 @Override 5901 public void binderDied() { 5902 foregroundTokenDied(this); 5903 } 5904 }; 5905 newToken.pid = pid; 5906 newToken.token = token; 5907 try { 5908 token.linkToDeath(newToken, 0); 5909 mForegroundProcesses.put(pid, newToken); 5910 pr.forcingToForeground = token; 5911 changed = true; 5912 } catch (RemoteException e) { 5913 // If the process died while doing this, we will later 5914 // do the cleanup with the process death link. 5915 } 5916 } 5917 } 5918 5919 if (changed) { 5920 updateOomAdjLocked(); 5921 } 5922 } 5923 } 5924 5925 // ========================================================= 5926 // PERMISSIONS 5927 // ========================================================= 5928 5929 static class PermissionController extends IPermissionController.Stub { 5930 ActivityManagerService mActivityManagerService; 5931 PermissionController(ActivityManagerService activityManagerService) { 5932 mActivityManagerService = activityManagerService; 5933 } 5934 5935 @Override 5936 public boolean checkPermission(String permission, int pid, int uid) { 5937 return mActivityManagerService.checkPermission(permission, pid, 5938 uid) == PackageManager.PERMISSION_GRANTED; 5939 } 5940 } 5941 5942 class IntentFirewallInterface implements IntentFirewall.AMSInterface { 5943 @Override 5944 public int checkComponentPermission(String permission, int pid, int uid, 5945 int owningUid, boolean exported) { 5946 return ActivityManagerService.this.checkComponentPermission(permission, pid, uid, 5947 owningUid, exported); 5948 } 5949 5950 @Override 5951 public Object getAMSLock() { 5952 return ActivityManagerService.this; 5953 } 5954 } 5955 5956 /** 5957 * This can be called with or without the global lock held. 5958 */ 5959 int checkComponentPermission(String permission, int pid, int uid, 5960 int owningUid, boolean exported) { 5961 // We might be performing an operation on behalf of an indirect binder 5962 // invocation, e.g. via {@link #openContentUri}. Check and adjust the 5963 // client identity accordingly before proceeding. 5964 Identity tlsIdentity = sCallerIdentity.get(); 5965 if (tlsIdentity != null) { 5966 Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {" 5967 + tlsIdentity.pid + "," + tlsIdentity.uid + "}"); 5968 uid = tlsIdentity.uid; 5969 pid = tlsIdentity.pid; 5970 } 5971 5972 if (pid == MY_PID) { 5973 return PackageManager.PERMISSION_GRANTED; 5974 } 5975 5976 return ActivityManager.checkComponentPermission(permission, uid, 5977 owningUid, exported); 5978 } 5979 5980 /** 5981 * As the only public entry point for permissions checking, this method 5982 * can enforce the semantic that requesting a check on a null global 5983 * permission is automatically denied. (Internally a null permission 5984 * string is used when calling {@link #checkComponentPermission} in cases 5985 * when only uid-based security is needed.) 5986 * 5987 * This can be called with or without the global lock held. 5988 */ 5989 @Override 5990 public int checkPermission(String permission, int pid, int uid) { 5991 if (permission == null) { 5992 return PackageManager.PERMISSION_DENIED; 5993 } 5994 return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true); 5995 } 5996 5997 /** 5998 * Binder IPC calls go through the public entry point. 5999 * This can be called with or without the global lock held. 6000 */ 6001 int checkCallingPermission(String permission) { 6002 return checkPermission(permission, 6003 Binder.getCallingPid(), 6004 UserHandle.getAppId(Binder.getCallingUid())); 6005 } 6006 6007 /** 6008 * This can be called with or without the global lock held. 6009 */ 6010 void enforceCallingPermission(String permission, String func) { 6011 if (checkCallingPermission(permission) 6012 == PackageManager.PERMISSION_GRANTED) { 6013 return; 6014 } 6015 6016 String msg = "Permission Denial: " + func + " from pid=" 6017 + Binder.getCallingPid() 6018 + ", uid=" + Binder.getCallingUid() 6019 + " requires " + permission; 6020 Slog.w(TAG, msg); 6021 throw new SecurityException(msg); 6022 } 6023 6024 /** 6025 * Determine if UID is holding permissions required to access {@link Uri} in 6026 * the given {@link ProviderInfo}. Final permission checking is always done 6027 * in {@link ContentProvider}. 6028 */ 6029 private final boolean checkHoldingPermissionsLocked( 6030 IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) { 6031 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6032 "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid); 6033 if (UserHandle.getUserId(uid) != grantUri.sourceUserId) { 6034 return false; 6035 } 6036 6037 if (pi.applicationInfo.uid == uid) { 6038 return true; 6039 } else if (!pi.exported) { 6040 return false; 6041 } 6042 6043 boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0; 6044 boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0; 6045 try { 6046 // check if target holds top-level <provider> permissions 6047 if (!readMet && pi.readPermission != null 6048 && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) { 6049 readMet = true; 6050 } 6051 if (!writeMet && pi.writePermission != null 6052 && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) { 6053 writeMet = true; 6054 } 6055 6056 // track if unprotected read/write is allowed; any denied 6057 // <path-permission> below removes this ability 6058 boolean allowDefaultRead = pi.readPermission == null; 6059 boolean allowDefaultWrite = pi.writePermission == null; 6060 6061 // check if target holds any <path-permission> that match uri 6062 final PathPermission[] pps = pi.pathPermissions; 6063 if (pps != null) { 6064 final String path = grantUri.uri.getPath(); 6065 int i = pps.length; 6066 while (i > 0 && (!readMet || !writeMet)) { 6067 i--; 6068 PathPermission pp = pps[i]; 6069 if (pp.match(path)) { 6070 if (!readMet) { 6071 final String pprperm = pp.getReadPermission(); 6072 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for " 6073 + pprperm + " for " + pp.getPath() 6074 + ": match=" + pp.match(path) 6075 + " check=" + pm.checkUidPermission(pprperm, uid)); 6076 if (pprperm != null) { 6077 if (pm.checkUidPermission(pprperm, uid) == PERMISSION_GRANTED) { 6078 readMet = true; 6079 } else { 6080 allowDefaultRead = false; 6081 } 6082 } 6083 } 6084 if (!writeMet) { 6085 final String ppwperm = pp.getWritePermission(); 6086 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm " 6087 + ppwperm + " for " + pp.getPath() 6088 + ": match=" + pp.match(path) 6089 + " check=" + pm.checkUidPermission(ppwperm, uid)); 6090 if (ppwperm != null) { 6091 if (pm.checkUidPermission(ppwperm, uid) == PERMISSION_GRANTED) { 6092 writeMet = true; 6093 } else { 6094 allowDefaultWrite = false; 6095 } 6096 } 6097 } 6098 } 6099 } 6100 } 6101 6102 // grant unprotected <provider> read/write, if not blocked by 6103 // <path-permission> above 6104 if (allowDefaultRead) readMet = true; 6105 if (allowDefaultWrite) writeMet = true; 6106 6107 } catch (RemoteException e) { 6108 return false; 6109 } 6110 6111 return readMet && writeMet; 6112 } 6113 6114 private ProviderInfo getProviderInfoLocked(String authority, int userHandle) { 6115 ProviderInfo pi = null; 6116 ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle); 6117 if (cpr != null) { 6118 pi = cpr.info; 6119 } else { 6120 try { 6121 pi = AppGlobals.getPackageManager().resolveContentProvider( 6122 authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle); 6123 } catch (RemoteException ex) { 6124 } 6125 } 6126 return pi; 6127 } 6128 6129 private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) { 6130 final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid); 6131 if (targetUris != null) { 6132 return targetUris.get(grantUri); 6133 } 6134 return null; 6135 } 6136 6137 private UriPermission findOrCreateUriPermissionLocked(String sourcePkg, 6138 String targetPkg, int targetUid, GrantUri grantUri) { 6139 ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid); 6140 if (targetUris == null) { 6141 targetUris = Maps.newArrayMap(); 6142 mGrantedUriPermissions.put(targetUid, targetUris); 6143 } 6144 6145 UriPermission perm = targetUris.get(grantUri); 6146 if (perm == null) { 6147 perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri); 6148 targetUris.put(grantUri, perm); 6149 } 6150 6151 return perm; 6152 } 6153 6154 private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid, 6155 final int modeFlags) { 6156 final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0; 6157 final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE 6158 : UriPermission.STRENGTH_OWNED; 6159 6160 // Root gets to do everything. 6161 if (uid == 0) { 6162 return true; 6163 } 6164 6165 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid); 6166 if (perms == null) return false; 6167 6168 // First look for exact match 6169 final UriPermission exactPerm = perms.get(grantUri); 6170 if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) { 6171 return true; 6172 } 6173 6174 // No exact match, look for prefixes 6175 final int N = perms.size(); 6176 for (int i = 0; i < N; i++) { 6177 final UriPermission perm = perms.valueAt(i); 6178 if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri) 6179 && perm.getStrength(modeFlags) >= minStrength) { 6180 return true; 6181 } 6182 } 6183 6184 return false; 6185 } 6186 6187 @Override 6188 public int checkUriPermission(Uri uri, int pid, int uid, 6189 final int modeFlags, int userId) { 6190 enforceNotIsolatedCaller("checkUriPermission"); 6191 6192 // Another redirected-binder-call permissions check as in 6193 // {@link checkComponentPermission}. 6194 Identity tlsIdentity = sCallerIdentity.get(); 6195 if (tlsIdentity != null) { 6196 uid = tlsIdentity.uid; 6197 pid = tlsIdentity.pid; 6198 } 6199 6200 // Our own process gets to do everything. 6201 if (pid == MY_PID) { 6202 return PackageManager.PERMISSION_GRANTED; 6203 } 6204 synchronized (this) { 6205 return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags) 6206 ? PackageManager.PERMISSION_GRANTED 6207 : PackageManager.PERMISSION_DENIED; 6208 } 6209 } 6210 6211 /** 6212 * Check if the targetPkg can be granted permission to access uri by 6213 * the callingUid using the given modeFlags. Throws a security exception 6214 * if callingUid is not allowed to do this. Returns the uid of the target 6215 * if the URI permission grant should be performed; returns -1 if it is not 6216 * needed (for example targetPkg already has permission to access the URI). 6217 * If you already know the uid of the target, you can supply it in 6218 * lastTargetUid else set that to -1. 6219 */ 6220 int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri, 6221 final int modeFlags, int lastTargetUid) { 6222 if (!Intent.isAccessUriMode(modeFlags)) { 6223 return -1; 6224 } 6225 6226 if (targetPkg != null) { 6227 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6228 "Checking grant " + targetPkg + " permission to " + grantUri); 6229 } 6230 6231 final IPackageManager pm = AppGlobals.getPackageManager(); 6232 6233 // If this is not a content: uri, we can't do anything with it. 6234 if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) { 6235 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6236 "Can't grant URI permission for non-content URI: " + grantUri); 6237 return -1; 6238 } 6239 6240 final String authority = grantUri.uri.getAuthority(); 6241 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId); 6242 if (pi == null) { 6243 Slog.w(TAG, "No content provider found for permission check: " + 6244 grantUri.uri.toSafeString()); 6245 return -1; 6246 } 6247 6248 int targetUid = lastTargetUid; 6249 if (targetUid < 0 && targetPkg != null) { 6250 try { 6251 targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid)); 6252 if (targetUid < 0) { 6253 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6254 "Can't grant URI permission no uid for: " + targetPkg); 6255 return -1; 6256 } 6257 } catch (RemoteException ex) { 6258 return -1; 6259 } 6260 } 6261 6262 if (targetUid >= 0) { 6263 // First... does the target actually need this permission? 6264 if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) { 6265 // No need to grant the target this permission. 6266 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6267 "Target " + targetPkg + " already has full permission to " + grantUri); 6268 return -1; 6269 } 6270 } else { 6271 // First... there is no target package, so can anyone access it? 6272 boolean allowed = pi.exported; 6273 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) { 6274 if (pi.readPermission != null) { 6275 allowed = false; 6276 } 6277 } 6278 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) { 6279 if (pi.writePermission != null) { 6280 allowed = false; 6281 } 6282 } 6283 if (allowed) { 6284 return -1; 6285 } 6286 } 6287 6288 // Second... is the provider allowing granting of URI permissions? 6289 if (!pi.grantUriPermissions) { 6290 throw new SecurityException("Provider " + pi.packageName 6291 + "/" + pi.name 6292 + " does not allow granting of Uri permissions (uri " 6293 + grantUri + ")"); 6294 } 6295 if (pi.uriPermissionPatterns != null) { 6296 final int N = pi.uriPermissionPatterns.length; 6297 boolean allowed = false; 6298 for (int i=0; i<N; i++) { 6299 if (pi.uriPermissionPatterns[i] != null 6300 && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) { 6301 allowed = true; 6302 break; 6303 } 6304 } 6305 if (!allowed) { 6306 throw new SecurityException("Provider " + pi.packageName 6307 + "/" + pi.name 6308 + " does not allow granting of permission to path of Uri " 6309 + grantUri); 6310 } 6311 } 6312 6313 // Third... does the caller itself have permission to access 6314 // this uri? 6315 if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) { 6316 if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) { 6317 // Require they hold a strong enough Uri permission 6318 if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) { 6319 throw new SecurityException("Uid " + callingUid 6320 + " does not have permission to uri " + grantUri); 6321 } 6322 } 6323 } 6324 return targetUid; 6325 } 6326 6327 @Override 6328 public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri, 6329 final int modeFlags, int userId) { 6330 enforceNotIsolatedCaller("checkGrantUriPermission"); 6331 synchronized(this) { 6332 return checkGrantUriPermissionLocked(callingUid, targetPkg, 6333 new GrantUri(userId, uri, false), modeFlags, -1); 6334 } 6335 } 6336 6337 void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri, 6338 final int modeFlags, UriPermissionOwner owner) { 6339 if (!Intent.isAccessUriMode(modeFlags)) { 6340 return; 6341 } 6342 6343 // So here we are: the caller has the assumed permission 6344 // to the uri, and the target doesn't. Let's now give this to 6345 // the target. 6346 6347 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6348 "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri); 6349 6350 final String authority = grantUri.uri.getAuthority(); 6351 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId); 6352 if (pi == null) { 6353 Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString()); 6354 return; 6355 } 6356 6357 if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) { 6358 grantUri.prefix = true; 6359 } 6360 final UriPermission perm = findOrCreateUriPermissionLocked( 6361 pi.packageName, targetPkg, targetUid, grantUri); 6362 perm.grantModes(modeFlags, owner); 6363 } 6364 6365 void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri, 6366 final int modeFlags, UriPermissionOwner owner) { 6367 if (targetPkg == null) { 6368 throw new NullPointerException("targetPkg"); 6369 } 6370 6371 int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags, 6372 -1); 6373 if (targetUid < 0) { 6374 return; 6375 } 6376 6377 grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags, 6378 owner); 6379 } 6380 6381 static class NeededUriGrants extends ArrayList<GrantUri> { 6382 final String targetPkg; 6383 final int targetUid; 6384 final int flags; 6385 6386 NeededUriGrants(String targetPkg, int targetUid, int flags) { 6387 this.targetPkg = targetPkg; 6388 this.targetUid = targetUid; 6389 this.flags = flags; 6390 } 6391 } 6392 6393 /** 6394 * Like checkGrantUriPermissionLocked, but takes an Intent. 6395 */ 6396 NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid, 6397 String targetPkg, Intent intent, int mode, NeededUriGrants needed) { 6398 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6399 "Checking URI perm to data=" + (intent != null ? intent.getData() : null) 6400 + " clip=" + (intent != null ? intent.getClipData() : null) 6401 + " from " + intent + "; flags=0x" 6402 + Integer.toHexString(intent != null ? intent.getFlags() : 0)); 6403 6404 if (targetPkg == null) { 6405 throw new NullPointerException("targetPkg"); 6406 } 6407 6408 if (intent == null) { 6409 return null; 6410 } 6411 Uri data = intent.getData(); 6412 ClipData clip = intent.getClipData(); 6413 if (data == null && clip == null) { 6414 return null; 6415 } 6416 6417 if (data != null) { 6418 GrantUri grantUri = GrantUri.resolve(UserHandle.getUserId(callingUid), data); 6419 int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode, 6420 needed != null ? needed.targetUid : -1); 6421 if (targetUid > 0) { 6422 if (needed == null) { 6423 needed = new NeededUriGrants(targetPkg, targetUid, mode); 6424 } 6425 needed.add(grantUri); 6426 } 6427 } 6428 if (clip != null) { 6429 for (int i=0; i<clip.getItemCount(); i++) { 6430 Uri uri = clip.getItemAt(i).getUri(); 6431 if (uri != null) { 6432 int targetUid = -1; 6433 GrantUri grantUri = GrantUri.resolve(UserHandle.getUserId(callingUid), uri); 6434 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode, 6435 needed != null ? needed.targetUid : -1); 6436 if (targetUid > 0) { 6437 if (needed == null) { 6438 needed = new NeededUriGrants(targetPkg, targetUid, mode); 6439 } 6440 needed.add(grantUri); 6441 } 6442 } else { 6443 Intent clipIntent = clip.getItemAt(i).getIntent(); 6444 if (clipIntent != null) { 6445 NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked( 6446 callingUid, targetPkg, clipIntent, mode, needed); 6447 if (newNeeded != null) { 6448 needed = newNeeded; 6449 } 6450 } 6451 } 6452 } 6453 } 6454 6455 return needed; 6456 } 6457 6458 /** 6459 * Like grantUriPermissionUncheckedLocked, but takes an Intent. 6460 */ 6461 void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed, 6462 UriPermissionOwner owner) { 6463 if (needed != null) { 6464 for (int i=0; i<needed.size(); i++) { 6465 GrantUri grantUri = needed.get(i); 6466 grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg, 6467 grantUri, needed.flags, owner); 6468 } 6469 } 6470 } 6471 6472 void grantUriPermissionFromIntentLocked(int callingUid, 6473 String targetPkg, Intent intent, UriPermissionOwner owner) { 6474 NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg, 6475 intent, intent != null ? intent.getFlags() : 0, null); 6476 if (needed == null) { 6477 return; 6478 } 6479 6480 grantUriPermissionUncheckedFromIntentLocked(needed, owner); 6481 } 6482 6483 @Override 6484 public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri, 6485 final int modeFlags, int userId) { 6486 enforceNotIsolatedCaller("grantUriPermission"); 6487 GrantUri grantUri = new GrantUri(userId, uri, false); 6488 synchronized(this) { 6489 final ProcessRecord r = getRecordForAppLocked(caller); 6490 if (r == null) { 6491 throw new SecurityException("Unable to find app for caller " 6492 + caller 6493 + " when granting permission to uri " + grantUri); 6494 } 6495 if (targetPkg == null) { 6496 throw new IllegalArgumentException("null target"); 6497 } 6498 if (grantUri == null) { 6499 throw new IllegalArgumentException("null uri"); 6500 } 6501 6502 Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION 6503 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION 6504 | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION 6505 | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION); 6506 6507 grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null); 6508 } 6509 } 6510 6511 void removeUriPermissionIfNeededLocked(UriPermission perm) { 6512 if (perm.modeFlags == 0) { 6513 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get( 6514 perm.targetUid); 6515 if (perms != null) { 6516 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6517 "Removing " + perm.targetUid + " permission to " + perm.uri); 6518 6519 perms.remove(perm.uri); 6520 if (perms.isEmpty()) { 6521 mGrantedUriPermissions.remove(perm.targetUid); 6522 } 6523 } 6524 } 6525 } 6526 6527 private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) { 6528 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + grantUri); 6529 6530 final IPackageManager pm = AppGlobals.getPackageManager(); 6531 final String authority = grantUri.uri.getAuthority(); 6532 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId); 6533 if (pi == null) { 6534 Slog.w(TAG, "No content provider found for permission revoke: " 6535 + grantUri.toSafeString()); 6536 return; 6537 } 6538 6539 // Does the caller have this permission on the URI? 6540 if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) { 6541 // Right now, if you are not the original owner of the permission, 6542 // you are not allowed to revoke it. 6543 //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) { 6544 throw new SecurityException("Uid " + callingUid 6545 + " does not have permission to uri " + grantUri); 6546 //} 6547 } 6548 6549 boolean persistChanged = false; 6550 6551 // Go through all of the permissions and remove any that match. 6552 int N = mGrantedUriPermissions.size(); 6553 for (int i = 0; i < N; i++) { 6554 final int targetUid = mGrantedUriPermissions.keyAt(i); 6555 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 6556 6557 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) { 6558 final UriPermission perm = it.next(); 6559 if (perm.uri.sourceUserId == grantUri.sourceUserId 6560 && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) { 6561 if (DEBUG_URI_PERMISSION) 6562 Slog.v(TAG, 6563 "Revoking " + perm.targetUid + " permission to " + perm.uri); 6564 persistChanged |= perm.revokeModes( 6565 modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION); 6566 if (perm.modeFlags == 0) { 6567 it.remove(); 6568 } 6569 } 6570 } 6571 6572 if (perms.isEmpty()) { 6573 mGrantedUriPermissions.remove(targetUid); 6574 N--; 6575 i--; 6576 } 6577 } 6578 6579 if (persistChanged) { 6580 schedulePersistUriGrants(); 6581 } 6582 } 6583 6584 @Override 6585 public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags, 6586 int userId) { 6587 enforceNotIsolatedCaller("revokeUriPermission"); 6588 synchronized(this) { 6589 final ProcessRecord r = getRecordForAppLocked(caller); 6590 if (r == null) { 6591 throw new SecurityException("Unable to find app for caller " 6592 + caller 6593 + " when revoking permission to uri " + uri); 6594 } 6595 if (uri == null) { 6596 Slog.w(TAG, "revokeUriPermission: null uri"); 6597 return; 6598 } 6599 6600 if (!Intent.isAccessUriMode(modeFlags)) { 6601 return; 6602 } 6603 6604 final IPackageManager pm = AppGlobals.getPackageManager(); 6605 final String authority = uri.getAuthority(); 6606 final ProviderInfo pi = getProviderInfoLocked(authority, userId); 6607 if (pi == null) { 6608 Slog.w(TAG, "No content provider found for permission revoke: " 6609 + uri.toSafeString()); 6610 return; 6611 } 6612 6613 revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags); 6614 } 6615 } 6616 6617 /** 6618 * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the 6619 * given package. 6620 * 6621 * @param packageName Package name to match, or {@code null} to apply to all 6622 * packages. 6623 * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply 6624 * to all users. 6625 * @param persistable If persistable grants should be removed. 6626 */ 6627 private void removeUriPermissionsForPackageLocked( 6628 String packageName, int userHandle, boolean persistable) { 6629 if (userHandle == UserHandle.USER_ALL && packageName == null) { 6630 throw new IllegalArgumentException("Must narrow by either package or user"); 6631 } 6632 6633 boolean persistChanged = false; 6634 6635 int N = mGrantedUriPermissions.size(); 6636 for (int i = 0; i < N; i++) { 6637 final int targetUid = mGrantedUriPermissions.keyAt(i); 6638 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 6639 6640 // Only inspect grants matching user 6641 if (userHandle == UserHandle.USER_ALL 6642 || userHandle == UserHandle.getUserId(targetUid)) { 6643 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) { 6644 final UriPermission perm = it.next(); 6645 6646 // Only inspect grants matching package 6647 if (packageName == null || perm.sourcePkg.equals(packageName) 6648 || perm.targetPkg.equals(packageName)) { 6649 persistChanged |= perm.revokeModes( 6650 persistable ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION); 6651 6652 // Only remove when no modes remain; any persisted grants 6653 // will keep this alive. 6654 if (perm.modeFlags == 0) { 6655 it.remove(); 6656 } 6657 } 6658 } 6659 6660 if (perms.isEmpty()) { 6661 mGrantedUriPermissions.remove(targetUid); 6662 N--; 6663 i--; 6664 } 6665 } 6666 } 6667 6668 if (persistChanged) { 6669 schedulePersistUriGrants(); 6670 } 6671 } 6672 6673 @Override 6674 public IBinder newUriPermissionOwner(String name) { 6675 enforceNotIsolatedCaller("newUriPermissionOwner"); 6676 synchronized(this) { 6677 UriPermissionOwner owner = new UriPermissionOwner(this, name); 6678 return owner.getExternalTokenLocked(); 6679 } 6680 } 6681 6682 @Override 6683 public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri, 6684 final int modeFlags, int userId) { 6685 synchronized(this) { 6686 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 6687 if (owner == null) { 6688 throw new IllegalArgumentException("Unknown owner: " + token); 6689 } 6690 if (fromUid != Binder.getCallingUid()) { 6691 if (Binder.getCallingUid() != Process.myUid()) { 6692 // Only system code can grant URI permissions on behalf 6693 // of other users. 6694 throw new SecurityException("nice try"); 6695 } 6696 } 6697 if (targetPkg == null) { 6698 throw new IllegalArgumentException("null target"); 6699 } 6700 if (uri == null) { 6701 throw new IllegalArgumentException("null uri"); 6702 } 6703 6704 grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(userId, uri, false), 6705 modeFlags, owner); 6706 } 6707 } 6708 6709 @Override 6710 public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) { 6711 synchronized(this) { 6712 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 6713 if (owner == null) { 6714 throw new IllegalArgumentException("Unknown owner: " + token); 6715 } 6716 6717 if (uri == null) { 6718 owner.removeUriPermissionsLocked(mode); 6719 } else { 6720 owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode); 6721 } 6722 } 6723 } 6724 6725 private void schedulePersistUriGrants() { 6726 if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) { 6727 mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG), 6728 10 * DateUtils.SECOND_IN_MILLIS); 6729 } 6730 } 6731 6732 private void writeGrantedUriPermissions() { 6733 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()"); 6734 6735 // Snapshot permissions so we can persist without lock 6736 ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList(); 6737 synchronized (this) { 6738 final int size = mGrantedUriPermissions.size(); 6739 for (int i = 0; i < size; i++) { 6740 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 6741 for (UriPermission perm : perms.values()) { 6742 if (perm.persistedModeFlags != 0) { 6743 persist.add(perm.snapshot()); 6744 } 6745 } 6746 } 6747 } 6748 6749 FileOutputStream fos = null; 6750 try { 6751 fos = mGrantFile.startWrite(); 6752 6753 XmlSerializer out = new FastXmlSerializer(); 6754 out.setOutput(fos, "utf-8"); 6755 out.startDocument(null, true); 6756 out.startTag(null, TAG_URI_GRANTS); 6757 for (UriPermission.Snapshot perm : persist) { 6758 out.startTag(null, TAG_URI_GRANT); 6759 writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId); 6760 writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId); 6761 out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg); 6762 out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg); 6763 out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri)); 6764 writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix); 6765 writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags); 6766 writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime); 6767 out.endTag(null, TAG_URI_GRANT); 6768 } 6769 out.endTag(null, TAG_URI_GRANTS); 6770 out.endDocument(); 6771 6772 mGrantFile.finishWrite(fos); 6773 } catch (IOException e) { 6774 if (fos != null) { 6775 mGrantFile.failWrite(fos); 6776 } 6777 } 6778 } 6779 6780 private void readGrantedUriPermissionsLocked() { 6781 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()"); 6782 6783 final long now = System.currentTimeMillis(); 6784 6785 FileInputStream fis = null; 6786 try { 6787 fis = mGrantFile.openRead(); 6788 final XmlPullParser in = Xml.newPullParser(); 6789 in.setInput(fis, null); 6790 6791 int type; 6792 while ((type = in.next()) != END_DOCUMENT) { 6793 final String tag = in.getName(); 6794 if (type == START_TAG) { 6795 if (TAG_URI_GRANT.equals(tag)) { 6796 final int sourceUserId; 6797 final int targetUserId; 6798 final int userHandle = readIntAttribute(in, 6799 ATTR_USER_HANDLE, UserHandle.USER_NULL); 6800 if (userHandle != UserHandle.USER_NULL) { 6801 // For backwards compatibility. 6802 sourceUserId = userHandle; 6803 targetUserId = userHandle; 6804 } else { 6805 sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID); 6806 targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID); 6807 } 6808 final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG); 6809 final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG); 6810 final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI)); 6811 final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX); 6812 final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS); 6813 final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now); 6814 6815 // Sanity check that provider still belongs to source package 6816 final ProviderInfo pi = getProviderInfoLocked( 6817 uri.getAuthority(), sourceUserId); 6818 if (pi != null && sourcePkg.equals(pi.packageName)) { 6819 int targetUid = -1; 6820 try { 6821 targetUid = AppGlobals.getPackageManager() 6822 .getPackageUid(targetPkg, targetUserId); 6823 } catch (RemoteException e) { 6824 } 6825 if (targetUid != -1) { 6826 final UriPermission perm = findOrCreateUriPermissionLocked( 6827 sourcePkg, targetPkg, targetUid, 6828 new GrantUri(sourceUserId, uri, prefix)); 6829 perm.initPersistedModes(modeFlags, createdTime); 6830 } 6831 } else { 6832 Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg 6833 + " but instead found " + pi); 6834 } 6835 } 6836 } 6837 } 6838 } catch (FileNotFoundException e) { 6839 // Missing grants is okay 6840 } catch (IOException e) { 6841 Log.wtf(TAG, "Failed reading Uri grants", e); 6842 } catch (XmlPullParserException e) { 6843 Log.wtf(TAG, "Failed reading Uri grants", e); 6844 } finally { 6845 IoUtils.closeQuietly(fis); 6846 } 6847 } 6848 6849 @Override 6850 public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) { 6851 enforceNotIsolatedCaller("takePersistableUriPermission"); 6852 6853 Preconditions.checkFlagsArgument(modeFlags, 6854 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 6855 6856 synchronized (this) { 6857 final int callingUid = Binder.getCallingUid(); 6858 boolean persistChanged = false; 6859 GrantUri grantUri = new GrantUri(userId, uri, false); 6860 6861 UriPermission exactPerm = findUriPermissionLocked(callingUid, 6862 new GrantUri(userId, uri, false)); 6863 UriPermission prefixPerm = findUriPermissionLocked(callingUid, 6864 new GrantUri(userId, uri, true)); 6865 6866 final boolean exactValid = (exactPerm != null) 6867 && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags); 6868 final boolean prefixValid = (prefixPerm != null) 6869 && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags); 6870 6871 if (!(exactValid || prefixValid)) { 6872 throw new SecurityException("No persistable permission grants found for UID " 6873 + callingUid + " and Uri " + grantUri.toSafeString()); 6874 } 6875 6876 if (exactValid) { 6877 persistChanged |= exactPerm.takePersistableModes(modeFlags); 6878 } 6879 if (prefixValid) { 6880 persistChanged |= prefixPerm.takePersistableModes(modeFlags); 6881 } 6882 6883 persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid); 6884 6885 if (persistChanged) { 6886 schedulePersistUriGrants(); 6887 } 6888 } 6889 } 6890 6891 @Override 6892 public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) { 6893 enforceNotIsolatedCaller("releasePersistableUriPermission"); 6894 6895 Preconditions.checkFlagsArgument(modeFlags, 6896 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 6897 6898 synchronized (this) { 6899 final int callingUid = Binder.getCallingUid(); 6900 boolean persistChanged = false; 6901 6902 UriPermission exactPerm = findUriPermissionLocked(callingUid, 6903 new GrantUri(userId, uri, false)); 6904 UriPermission prefixPerm = findUriPermissionLocked(callingUid, 6905 new GrantUri(userId, uri, true)); 6906 if (exactPerm == null && prefixPerm == null) { 6907 throw new SecurityException("No permission grants found for UID " + callingUid 6908 + " and Uri " + uri.toSafeString()); 6909 } 6910 6911 if (exactPerm != null) { 6912 persistChanged |= exactPerm.releasePersistableModes(modeFlags); 6913 removeUriPermissionIfNeededLocked(exactPerm); 6914 } 6915 if (prefixPerm != null) { 6916 persistChanged |= prefixPerm.releasePersistableModes(modeFlags); 6917 removeUriPermissionIfNeededLocked(prefixPerm); 6918 } 6919 6920 if (persistChanged) { 6921 schedulePersistUriGrants(); 6922 } 6923 } 6924 } 6925 6926 /** 6927 * Prune any older {@link UriPermission} for the given UID until outstanding 6928 * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}. 6929 * 6930 * @return if any mutations occured that require persisting. 6931 */ 6932 private boolean maybePrunePersistedUriGrantsLocked(int uid) { 6933 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid); 6934 if (perms == null) return false; 6935 if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false; 6936 6937 final ArrayList<UriPermission> persisted = Lists.newArrayList(); 6938 for (UriPermission perm : perms.values()) { 6939 if (perm.persistedModeFlags != 0) { 6940 persisted.add(perm); 6941 } 6942 } 6943 6944 final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS; 6945 if (trimCount <= 0) return false; 6946 6947 Collections.sort(persisted, new UriPermission.PersistedTimeComparator()); 6948 for (int i = 0; i < trimCount; i++) { 6949 final UriPermission perm = persisted.get(i); 6950 6951 if (DEBUG_URI_PERMISSION) { 6952 Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime); 6953 } 6954 6955 perm.releasePersistableModes(~0); 6956 removeUriPermissionIfNeededLocked(perm); 6957 } 6958 6959 return true; 6960 } 6961 6962 @Override 6963 public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions( 6964 String packageName, boolean incoming) { 6965 enforceNotIsolatedCaller("getPersistedUriPermissions"); 6966 Preconditions.checkNotNull(packageName, "packageName"); 6967 6968 final int callingUid = Binder.getCallingUid(); 6969 final IPackageManager pm = AppGlobals.getPackageManager(); 6970 try { 6971 final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid)); 6972 if (packageUid != callingUid) { 6973 throw new SecurityException( 6974 "Package " + packageName + " does not belong to calling UID " + callingUid); 6975 } 6976 } catch (RemoteException e) { 6977 throw new SecurityException("Failed to verify package name ownership"); 6978 } 6979 6980 final ArrayList<android.content.UriPermission> result = Lists.newArrayList(); 6981 synchronized (this) { 6982 if (incoming) { 6983 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get( 6984 callingUid); 6985 if (perms == null) { 6986 Slog.w(TAG, "No permission grants found for " + packageName); 6987 } else { 6988 for (UriPermission perm : perms.values()) { 6989 if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) { 6990 result.add(perm.buildPersistedPublicApiObject()); 6991 } 6992 } 6993 } 6994 } else { 6995 final int size = mGrantedUriPermissions.size(); 6996 for (int i = 0; i < size; i++) { 6997 final ArrayMap<GrantUri, UriPermission> perms = 6998 mGrantedUriPermissions.valueAt(i); 6999 for (UriPermission perm : perms.values()) { 7000 if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) { 7001 result.add(perm.buildPersistedPublicApiObject()); 7002 } 7003 } 7004 } 7005 } 7006 } 7007 return new ParceledListSlice<android.content.UriPermission>(result); 7008 } 7009 7010 @Override 7011 public void showWaitingForDebugger(IApplicationThread who, boolean waiting) { 7012 synchronized (this) { 7013 ProcessRecord app = 7014 who != null ? getRecordForAppLocked(who) : null; 7015 if (app == null) return; 7016 7017 Message msg = Message.obtain(); 7018 msg.what = WAIT_FOR_DEBUGGER_MSG; 7019 msg.obj = app; 7020 msg.arg1 = waiting ? 1 : 0; 7021 mHandler.sendMessage(msg); 7022 } 7023 } 7024 7025 @Override 7026 public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) { 7027 final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ); 7028 final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ); 7029 outInfo.availMem = Process.getFreeMemory(); 7030 outInfo.totalMem = Process.getTotalMemory(); 7031 outInfo.threshold = homeAppMem; 7032 outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2)); 7033 outInfo.hiddenAppThreshold = cachedAppMem; 7034 outInfo.secondaryServerThreshold = mProcessList.getMemLevel( 7035 ProcessList.SERVICE_ADJ); 7036 outInfo.visibleAppThreshold = mProcessList.getMemLevel( 7037 ProcessList.VISIBLE_APP_ADJ); 7038 outInfo.foregroundAppThreshold = mProcessList.getMemLevel( 7039 ProcessList.FOREGROUND_APP_ADJ); 7040 } 7041 7042 // ========================================================= 7043 // TASK MANAGEMENT 7044 // ========================================================= 7045 7046 @Override 7047 public List<IAppTask> getAppTasks() { 7048 int callingUid = Binder.getCallingUid(); 7049 long ident = Binder.clearCallingIdentity(); 7050 synchronized(this) { 7051 ArrayList<IAppTask> list = new ArrayList<IAppTask>(); 7052 try { 7053 if (localLOGV) Slog.v(TAG, "getAppTasks"); 7054 7055 final int N = mRecentTasks.size(); 7056 for (int i = 0; i < N; i++) { 7057 TaskRecord tr = mRecentTasks.get(i); 7058 // Skip tasks that are not created by the caller 7059 if (tr.creatorUid == callingUid) { 7060 ActivityManager.RecentTaskInfo taskInfo = 7061 createRecentTaskInfoFromTaskRecord(tr); 7062 AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid); 7063 list.add(taskImpl); 7064 } 7065 } 7066 } finally { 7067 Binder.restoreCallingIdentity(ident); 7068 } 7069 return list; 7070 } 7071 } 7072 7073 @Override 7074 public List<RunningTaskInfo> getTasks(int maxNum, int flags) { 7075 final int callingUid = Binder.getCallingUid(); 7076 ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>(); 7077 7078 synchronized(this) { 7079 if (localLOGV) Slog.v( 7080 TAG, "getTasks: max=" + maxNum + ", flags=" + flags); 7081 7082 final boolean allowed = checkCallingPermission( 7083 android.Manifest.permission.GET_TASKS) 7084 == PackageManager.PERMISSION_GRANTED; 7085 if (!allowed) { 7086 Slog.w(TAG, "getTasks: caller " + callingUid 7087 + " does not hold GET_TASKS; limiting output"); 7088 } 7089 7090 // TODO: Improve with MRU list from all ActivityStacks. 7091 mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed); 7092 } 7093 7094 return list; 7095 } 7096 7097 TaskRecord getMostRecentTask() { 7098 return mRecentTasks.get(0); 7099 } 7100 7101 /** 7102 * Creates a new RecentTaskInfo from a TaskRecord. 7103 */ 7104 private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) { 7105 // Update the task description to reflect any changes in the task stack 7106 tr.updateTaskDescription(); 7107 7108 // Compose the recent task info 7109 ActivityManager.RecentTaskInfo rti 7110 = new ActivityManager.RecentTaskInfo(); 7111 rti.id = tr.mActivities.isEmpty() ? -1 : tr.taskId; 7112 rti.persistentId = tr.taskId; 7113 rti.baseIntent = new Intent(tr.getBaseIntent()); 7114 rti.origActivity = tr.origActivity; 7115 rti.description = tr.lastDescription; 7116 rti.stackId = tr.stack != null ? tr.stack.mStackId : -1; 7117 rti.userId = tr.userId; 7118 rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription); 7119 return rti; 7120 } 7121 7122 @Override 7123 public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, 7124 int flags, int userId) { 7125 final int callingUid = Binder.getCallingUid(); 7126 userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId, 7127 false, true, "getRecentTasks", null); 7128 7129 synchronized (this) { 7130 final boolean allowed = checkCallingPermission( 7131 android.Manifest.permission.GET_TASKS) 7132 == PackageManager.PERMISSION_GRANTED; 7133 if (!allowed) { 7134 Slog.w(TAG, "getRecentTasks: caller " + callingUid 7135 + " does not hold GET_TASKS; limiting output"); 7136 } 7137 final boolean detailed = checkCallingPermission( 7138 android.Manifest.permission.GET_DETAILED_TASKS) 7139 == PackageManager.PERMISSION_GRANTED; 7140 7141 IPackageManager pm = AppGlobals.getPackageManager(); 7142 7143 final int N = mRecentTasks.size(); 7144 ArrayList<ActivityManager.RecentTaskInfo> res 7145 = new ArrayList<ActivityManager.RecentTaskInfo>( 7146 maxNum < N ? maxNum : N); 7147 7148 final Set<Integer> includedUsers; 7149 if ((flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0) { 7150 includedUsers = getProfileIdsLocked(userId); 7151 } else { 7152 includedUsers = new HashSet<Integer>(); 7153 } 7154 includedUsers.add(Integer.valueOf(userId)); 7155 for (int i=0; i<N && maxNum > 0; i++) { 7156 TaskRecord tr = mRecentTasks.get(i); 7157 // Only add calling user or related users recent tasks 7158 if (!includedUsers.contains(Integer.valueOf(tr.userId))) continue; 7159 7160 // Return the entry if desired by the caller. We always return 7161 // the first entry, because callers always expect this to be the 7162 // foreground app. We may filter others if the caller has 7163 // not supplied RECENT_WITH_EXCLUDED and there is some reason 7164 // we should exclude the entry. 7165 7166 if (i == 0 7167 || ((flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0) 7168 || (tr.intent == null) 7169 || ((tr.intent.getFlags() 7170 &Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0)) { 7171 if (!allowed) { 7172 // If the caller doesn't have the GET_TASKS permission, then only 7173 // allow them to see a small subset of tasks -- their own and home. 7174 if (!tr.isHomeTask() && tr.creatorUid != callingUid) { 7175 continue; 7176 } 7177 } 7178 7179 ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr); 7180 if (!detailed) { 7181 rti.baseIntent.replaceExtras((Bundle)null); 7182 } 7183 7184 if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) { 7185 // Check whether this activity is currently available. 7186 try { 7187 if (rti.origActivity != null) { 7188 if (pm.getActivityInfo(rti.origActivity, 0, userId) 7189 == null) { 7190 continue; 7191 } 7192 } else if (rti.baseIntent != null) { 7193 if (pm.queryIntentActivities(rti.baseIntent, 7194 null, 0, userId) == null) { 7195 continue; 7196 } 7197 } 7198 } catch (RemoteException e) { 7199 // Will never happen. 7200 } 7201 } 7202 7203 res.add(rti); 7204 maxNum--; 7205 } 7206 } 7207 return res; 7208 } 7209 } 7210 7211 private TaskRecord recentTaskForIdLocked(int id) { 7212 final int N = mRecentTasks.size(); 7213 for (int i=0; i<N; i++) { 7214 TaskRecord tr = mRecentTasks.get(i); 7215 if (tr.taskId == id) { 7216 return tr; 7217 } 7218 } 7219 return null; 7220 } 7221 7222 @Override 7223 public ActivityManager.TaskThumbnails getTaskThumbnails(int id) { 7224 synchronized (this) { 7225 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER, 7226 "getTaskThumbnails()"); 7227 TaskRecord tr = recentTaskForIdLocked(id); 7228 if (tr != null) { 7229 return tr.getTaskThumbnailsLocked(); 7230 } 7231 } 7232 return null; 7233 } 7234 7235 @Override 7236 public Bitmap getTaskTopThumbnail(int id) { 7237 synchronized (this) { 7238 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER, 7239 "getTaskTopThumbnail()"); 7240 TaskRecord tr = recentTaskForIdLocked(id); 7241 if (tr != null) { 7242 return tr.getTaskTopThumbnailLocked(); 7243 } 7244 } 7245 return null; 7246 } 7247 7248 @Override 7249 public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) { 7250 synchronized (this) { 7251 ActivityRecord r = ActivityRecord.isInStackLocked(token); 7252 if (r != null) { 7253 r.taskDescription = td; 7254 r.task.updateTaskDescription(); 7255 } 7256 } 7257 } 7258 7259 @Override 7260 public boolean removeSubTask(int taskId, int subTaskIndex) { 7261 synchronized (this) { 7262 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, 7263 "removeSubTask()"); 7264 long ident = Binder.clearCallingIdentity(); 7265 try { 7266 TaskRecord tr = recentTaskForIdLocked(taskId); 7267 if (tr != null) { 7268 return tr.removeTaskActivitiesLocked(subTaskIndex, true) != null; 7269 } 7270 return false; 7271 } finally { 7272 Binder.restoreCallingIdentity(ident); 7273 } 7274 } 7275 } 7276 7277 private void killUnneededProcessLocked(ProcessRecord pr, String reason) { 7278 if (!pr.killedByAm) { 7279 Slog.i(TAG, "Killing " + pr.toShortString() + " (adj " + pr.setAdj + "): " + reason); 7280 EventLog.writeEvent(EventLogTags.AM_KILL, pr.userId, pr.pid, 7281 pr.processName, pr.setAdj, reason); 7282 pr.killedByAm = true; 7283 Process.killProcessQuiet(pr.pid); 7284 } 7285 } 7286 7287 private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) { 7288 tr.disposeThumbnail(); 7289 mRecentTasks.remove(tr); 7290 final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0; 7291 Intent baseIntent = new Intent( 7292 tr.intent != null ? tr.intent : tr.affinityIntent); 7293 ComponentName component = baseIntent.getComponent(); 7294 if (component == null) { 7295 Slog.w(TAG, "Now component for base intent of task: " + tr); 7296 return; 7297 } 7298 7299 // Find any running services associated with this app. 7300 mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent); 7301 7302 if (killProcesses) { 7303 // Find any running processes associated with this app. 7304 final String pkg = component.getPackageName(); 7305 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 7306 ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap(); 7307 for (int i=0; i<pmap.size(); i++) { 7308 SparseArray<ProcessRecord> uids = pmap.valueAt(i); 7309 for (int j=0; j<uids.size(); j++) { 7310 ProcessRecord proc = uids.valueAt(j); 7311 if (proc.userId != tr.userId) { 7312 continue; 7313 } 7314 if (!proc.pkgList.containsKey(pkg)) { 7315 continue; 7316 } 7317 procs.add(proc); 7318 } 7319 } 7320 7321 // Kill the running processes. 7322 for (int i=0; i<procs.size(); i++) { 7323 ProcessRecord pr = procs.get(i); 7324 if (pr == mHomeProcess) { 7325 // Don't kill the home process along with tasks from the same package. 7326 continue; 7327 } 7328 if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 7329 killUnneededProcessLocked(pr, "remove task"); 7330 } else { 7331 pr.waitingToKill = "remove task"; 7332 } 7333 } 7334 } 7335 } 7336 7337 /** 7338 * Removes the task with the specified task id. 7339 * 7340 * @param taskId Identifier of the task to be removed. 7341 * @param flags Additional operational flags. May be 0 or 7342 * {@link ActivityManager#REMOVE_TASK_KILL_PROCESS}. 7343 * @return Returns true if the given task was found and removed. 7344 */ 7345 private boolean removeTaskByIdLocked(int taskId, int flags) { 7346 TaskRecord tr = recentTaskForIdLocked(taskId); 7347 if (tr != null) { 7348 tr.removeTaskActivitiesLocked(-1, false); 7349 cleanUpRemovedTaskLocked(tr, flags); 7350 if (tr.isPersistable) { 7351 notifyTaskPersisterLocked(tr, true); 7352 } 7353 return true; 7354 } 7355 return false; 7356 } 7357 7358 @Override 7359 public boolean removeTask(int taskId, int flags) { 7360 synchronized (this) { 7361 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, 7362 "removeTask()"); 7363 long ident = Binder.clearCallingIdentity(); 7364 try { 7365 return removeTaskByIdLocked(taskId, flags); 7366 } finally { 7367 Binder.restoreCallingIdentity(ident); 7368 } 7369 } 7370 } 7371 7372 /** 7373 * TODO: Add mController hook 7374 */ 7375 @Override 7376 public void moveTaskToFront(int taskId, int flags, Bundle options) { 7377 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 7378 "moveTaskToFront()"); 7379 7380 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId); 7381 synchronized(this) { 7382 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 7383 Binder.getCallingUid(), "Task to front")) { 7384 ActivityOptions.abort(options); 7385 return; 7386 } 7387 final long origId = Binder.clearCallingIdentity(); 7388 try { 7389 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId); 7390 if (task == null) { 7391 return; 7392 } 7393 if (mStackSupervisor.isLockTaskModeViolation(task)) { 7394 Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode"); 7395 return; 7396 } 7397 mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options); 7398 } finally { 7399 Binder.restoreCallingIdentity(origId); 7400 } 7401 ActivityOptions.abort(options); 7402 } 7403 } 7404 7405 @Override 7406 public void moveTaskToBack(int taskId) { 7407 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 7408 "moveTaskToBack()"); 7409 7410 synchronized(this) { 7411 TaskRecord tr = recentTaskForIdLocked(taskId); 7412 if (tr != null) { 7413 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr); 7414 ActivityStack stack = tr.stack; 7415 if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) { 7416 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 7417 Binder.getCallingUid(), "Task to back")) { 7418 return; 7419 } 7420 } 7421 final long origId = Binder.clearCallingIdentity(); 7422 try { 7423 stack.moveTaskToBackLocked(taskId, null); 7424 } finally { 7425 Binder.restoreCallingIdentity(origId); 7426 } 7427 } 7428 } 7429 } 7430 7431 /** 7432 * Moves an activity, and all of the other activities within the same task, to the bottom 7433 * of the history stack. The activity's order within the task is unchanged. 7434 * 7435 * @param token A reference to the activity we wish to move 7436 * @param nonRoot If false then this only works if the activity is the root 7437 * of a task; if true it will work for any activity in a task. 7438 * @return Returns true if the move completed, false if not. 7439 */ 7440 @Override 7441 public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) { 7442 enforceNotIsolatedCaller("moveActivityTaskToBack"); 7443 synchronized(this) { 7444 final long origId = Binder.clearCallingIdentity(); 7445 int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot); 7446 if (taskId >= 0) { 7447 return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null); 7448 } 7449 Binder.restoreCallingIdentity(origId); 7450 } 7451 return false; 7452 } 7453 7454 @Override 7455 public void moveTaskBackwards(int task) { 7456 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 7457 "moveTaskBackwards()"); 7458 7459 synchronized(this) { 7460 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 7461 Binder.getCallingUid(), "Task backwards")) { 7462 return; 7463 } 7464 final long origId = Binder.clearCallingIdentity(); 7465 moveTaskBackwardsLocked(task); 7466 Binder.restoreCallingIdentity(origId); 7467 } 7468 } 7469 7470 private final void moveTaskBackwardsLocked(int task) { 7471 Slog.e(TAG, "moveTaskBackwards not yet implemented!"); 7472 } 7473 7474 @Override 7475 public IBinder getHomeActivityToken() throws RemoteException { 7476 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7477 "getHomeActivityToken()"); 7478 synchronized (this) { 7479 return mStackSupervisor.getHomeActivityToken(); 7480 } 7481 } 7482 7483 @Override 7484 public IActivityContainer createActivityContainer(IBinder parentActivityToken, 7485 IActivityContainerCallback callback) throws RemoteException { 7486 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7487 "createActivityContainer()"); 7488 synchronized (this) { 7489 if (parentActivityToken == null) { 7490 throw new IllegalArgumentException("parent token must not be null"); 7491 } 7492 ActivityRecord r = ActivityRecord.forToken(parentActivityToken); 7493 if (r == null) { 7494 return null; 7495 } 7496 if (callback == null) { 7497 throw new IllegalArgumentException("callback must not be null"); 7498 } 7499 return mStackSupervisor.createActivityContainer(r, callback); 7500 } 7501 } 7502 7503 @Override 7504 public void deleteActivityContainer(IActivityContainer container) throws RemoteException { 7505 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7506 "deleteActivityContainer()"); 7507 synchronized (this) { 7508 mStackSupervisor.deleteActivityContainer(container); 7509 } 7510 } 7511 7512 @Override 7513 public IActivityContainer getEnclosingActivityContainer(IBinder activityToken) 7514 throws RemoteException { 7515 synchronized (this) { 7516 ActivityStack stack = ActivityRecord.getStackLocked(activityToken); 7517 if (stack != null) { 7518 return stack.mActivityContainer; 7519 } 7520 return null; 7521 } 7522 } 7523 7524 @Override 7525 public void moveTaskToStack(int taskId, int stackId, boolean toTop) { 7526 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7527 "moveTaskToStack()"); 7528 if (stackId == HOME_STACK_ID) { 7529 Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack", 7530 new RuntimeException("here").fillInStackTrace()); 7531 } 7532 synchronized (this) { 7533 long ident = Binder.clearCallingIdentity(); 7534 try { 7535 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId=" 7536 + stackId + " toTop=" + toTop); 7537 mStackSupervisor.moveTaskToStack(taskId, stackId, toTop); 7538 } finally { 7539 Binder.restoreCallingIdentity(ident); 7540 } 7541 } 7542 } 7543 7544 @Override 7545 public void resizeStack(int stackBoxId, Rect bounds) { 7546 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7547 "resizeStackBox()"); 7548 long ident = Binder.clearCallingIdentity(); 7549 try { 7550 mWindowManager.resizeStack(stackBoxId, bounds); 7551 } finally { 7552 Binder.restoreCallingIdentity(ident); 7553 } 7554 } 7555 7556 @Override 7557 public List<StackInfo> getAllStackInfos() { 7558 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7559 "getAllStackInfos()"); 7560 long ident = Binder.clearCallingIdentity(); 7561 try { 7562 synchronized (this) { 7563 return mStackSupervisor.getAllStackInfosLocked(); 7564 } 7565 } finally { 7566 Binder.restoreCallingIdentity(ident); 7567 } 7568 } 7569 7570 @Override 7571 public StackInfo getStackInfo(int stackId) { 7572 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7573 "getStackInfo()"); 7574 long ident = Binder.clearCallingIdentity(); 7575 try { 7576 synchronized (this) { 7577 return mStackSupervisor.getStackInfoLocked(stackId); 7578 } 7579 } finally { 7580 Binder.restoreCallingIdentity(ident); 7581 } 7582 } 7583 7584 @Override 7585 public boolean isInHomeStack(int taskId) { 7586 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7587 "getStackInfo()"); 7588 long ident = Binder.clearCallingIdentity(); 7589 try { 7590 synchronized (this) { 7591 TaskRecord tr = recentTaskForIdLocked(taskId); 7592 return tr != null && tr.stack != null && tr.stack.isHomeStack(); 7593 } 7594 } finally { 7595 Binder.restoreCallingIdentity(ident); 7596 } 7597 } 7598 7599 @Override 7600 public int getTaskForActivity(IBinder token, boolean onlyRoot) { 7601 synchronized(this) { 7602 return ActivityRecord.getTaskForActivityLocked(token, onlyRoot); 7603 } 7604 } 7605 7606 private boolean isLockTaskAuthorized(ComponentName name) { 7607 final DevicePolicyManager dpm = (DevicePolicyManager) 7608 mContext.getSystemService(Context.DEVICE_POLICY_SERVICE); 7609 return dpm != null && dpm.isLockTaskPermitted(name); 7610 } 7611 7612 private void startLockTaskMode(TaskRecord task) { 7613 if (!isLockTaskAuthorized(task.intent.getComponent())) { 7614 return; 7615 } 7616 long ident = Binder.clearCallingIdentity(); 7617 try { 7618 synchronized (this) { 7619 // Since we lost lock on task, make sure it is still there. 7620 task = mStackSupervisor.anyTaskForIdLocked(task.taskId); 7621 if (task != null) { 7622 mStackSupervisor.setLockTaskModeLocked(task); 7623 } 7624 } 7625 } finally { 7626 Binder.restoreCallingIdentity(ident); 7627 } 7628 } 7629 7630 @Override 7631 public void startLockTaskMode(int taskId) { 7632 long ident = Binder.clearCallingIdentity(); 7633 try { 7634 final TaskRecord task; 7635 synchronized (this) { 7636 task = mStackSupervisor.anyTaskForIdLocked(taskId); 7637 } 7638 if (task != null) { 7639 startLockTaskMode(task); 7640 } 7641 } finally { 7642 Binder.restoreCallingIdentity(ident); 7643 } 7644 } 7645 7646 @Override 7647 public void startLockTaskMode(IBinder token) { 7648 long ident = Binder.clearCallingIdentity(); 7649 try { 7650 final TaskRecord task; 7651 synchronized (this) { 7652 final ActivityRecord r = ActivityRecord.forToken(token); 7653 if (r == null) { 7654 return; 7655 } 7656 task = r.task; 7657 } 7658 if (task != null) { 7659 startLockTaskMode(task); 7660 } 7661 } finally { 7662 Binder.restoreCallingIdentity(ident); 7663 } 7664 } 7665 7666 @Override 7667 public void stopLockTaskMode() { 7668 // Check if the calling task is eligible to use lock task 7669 final int uid = Binder.getCallingUid(); 7670 try { 7671 final String name = AppGlobals.getPackageManager().getNameForUid(uid); 7672 if (!isLockTaskAuthorized(new ComponentName(name, name))) { 7673 return; 7674 } 7675 } catch (RemoteException e) { 7676 Log.d(TAG, "stopLockTaskMode " + e); 7677 return; 7678 } 7679 // Stop lock task 7680 synchronized (this) { 7681 mStackSupervisor.setLockTaskModeLocked(null); 7682 } 7683 } 7684 7685 @Override 7686 public boolean isInLockTaskMode() { 7687 synchronized (this) { 7688 return mStackSupervisor.isInLockTaskMode(); 7689 } 7690 } 7691 7692 // ========================================================= 7693 // CONTENT PROVIDERS 7694 // ========================================================= 7695 7696 private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) { 7697 List<ProviderInfo> providers = null; 7698 try { 7699 providers = AppGlobals.getPackageManager(). 7700 queryContentProviders(app.processName, app.uid, 7701 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS); 7702 } catch (RemoteException ex) { 7703 } 7704 if (DEBUG_MU) 7705 Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid); 7706 int userId = app.userId; 7707 if (providers != null) { 7708 int N = providers.size(); 7709 app.pubProviders.ensureCapacity(N + app.pubProviders.size()); 7710 for (int i=0; i<N; i++) { 7711 ProviderInfo cpi = 7712 (ProviderInfo)providers.get(i); 7713 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo, 7714 cpi.name, cpi.flags); 7715 if (singleton && UserHandle.getUserId(app.uid) != 0) { 7716 // This is a singleton provider, but a user besides the 7717 // default user is asking to initialize a process it runs 7718 // in... well, no, it doesn't actually run in this process, 7719 // it runs in the process of the default user. Get rid of it. 7720 providers.remove(i); 7721 N--; 7722 i--; 7723 continue; 7724 } 7725 7726 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 7727 ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId); 7728 if (cpr == null) { 7729 cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton); 7730 mProviderMap.putProviderByClass(comp, cpr); 7731 } 7732 if (DEBUG_MU) 7733 Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid); 7734 app.pubProviders.put(cpi.name, cpr); 7735 if (!cpi.multiprocess || !"android".equals(cpi.packageName)) { 7736 // Don't add this if it is a platform component that is marked 7737 // to run in multiple processes, because this is actually 7738 // part of the framework so doesn't make sense to track as a 7739 // separate apk in the process. 7740 app.addPackage(cpi.applicationInfo.packageName, mProcessStats); 7741 } 7742 ensurePackageDexOpt(cpi.applicationInfo.packageName); 7743 } 7744 } 7745 return providers; 7746 } 7747 7748 /** 7749 * Check if {@link ProcessRecord} has a possible chance at accessing the 7750 * given {@link ProviderInfo}. Final permission checking is always done 7751 * in {@link ContentProvider}. 7752 */ 7753 private final String checkContentProviderPermissionLocked( 7754 ProviderInfo cpi, ProcessRecord r, int userId) { 7755 final int callingPid = (r != null) ? r.pid : Binder.getCallingPid(); 7756 final int callingUid = (r != null) ? r.uid : Binder.getCallingUid(); 7757 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid); 7758 // Looking for cross-user grants before to enforce the typical cross-users permissions 7759 if (userId != UserHandle.getUserId(callingUid)) { 7760 if (perms != null) { 7761 for (GrantUri grantUri : perms.keySet()) { 7762 if (grantUri.sourceUserId == userId) { 7763 String authority = grantUri.uri.getAuthority(); 7764 if (authority.equals(cpi.authority)) { 7765 return null; 7766 } 7767 } 7768 } 7769 } 7770 } 7771 userId = handleIncomingUser(callingPid, callingUid, userId, 7772 false, true, "checkContentProviderPermissionLocked", null); 7773 if (checkComponentPermission(cpi.readPermission, callingPid, callingUid, 7774 cpi.applicationInfo.uid, cpi.exported) 7775 == PackageManager.PERMISSION_GRANTED) { 7776 return null; 7777 } 7778 if (checkComponentPermission(cpi.writePermission, callingPid, callingUid, 7779 cpi.applicationInfo.uid, cpi.exported) 7780 == PackageManager.PERMISSION_GRANTED) { 7781 return null; 7782 } 7783 7784 PathPermission[] pps = cpi.pathPermissions; 7785 if (pps != null) { 7786 int i = pps.length; 7787 while (i > 0) { 7788 i--; 7789 PathPermission pp = pps[i]; 7790 if (checkComponentPermission(pp.getReadPermission(), callingPid, callingUid, 7791 cpi.applicationInfo.uid, cpi.exported) 7792 == PackageManager.PERMISSION_GRANTED) { 7793 return null; 7794 } 7795 if (checkComponentPermission(pp.getWritePermission(), callingPid, callingUid, 7796 cpi.applicationInfo.uid, cpi.exported) 7797 == PackageManager.PERMISSION_GRANTED) { 7798 return null; 7799 } 7800 } 7801 } 7802 7803 if (perms != null) { 7804 for (GrantUri grantUri : perms.keySet()) { 7805 if (grantUri.uri.getAuthority().equals(cpi.authority)) { 7806 return null; 7807 } 7808 } 7809 } 7810 7811 String msg; 7812 if (!cpi.exported) { 7813 msg = "Permission Denial: opening provider " + cpi.name 7814 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 7815 + ", uid=" + callingUid + ") that is not exported from uid " 7816 + cpi.applicationInfo.uid; 7817 } else { 7818 msg = "Permission Denial: opening provider " + cpi.name 7819 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 7820 + ", uid=" + callingUid + ") requires " 7821 + cpi.readPermission + " or " + cpi.writePermission; 7822 } 7823 Slog.w(TAG, msg); 7824 return msg; 7825 } 7826 7827 ContentProviderConnection incProviderCountLocked(ProcessRecord r, 7828 final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 7829 if (r != null) { 7830 for (int i=0; i<r.conProviders.size(); i++) { 7831 ContentProviderConnection conn = r.conProviders.get(i); 7832 if (conn.provider == cpr) { 7833 if (DEBUG_PROVIDER) Slog.v(TAG, 7834 "Adding provider requested by " 7835 + r.processName + " from process " 7836 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 7837 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 7838 if (stable) { 7839 conn.stableCount++; 7840 conn.numStableIncs++; 7841 } else { 7842 conn.unstableCount++; 7843 conn.numUnstableIncs++; 7844 } 7845 return conn; 7846 } 7847 } 7848 ContentProviderConnection conn = new ContentProviderConnection(cpr, r); 7849 if (stable) { 7850 conn.stableCount = 1; 7851 conn.numStableIncs = 1; 7852 } else { 7853 conn.unstableCount = 1; 7854 conn.numUnstableIncs = 1; 7855 } 7856 cpr.connections.add(conn); 7857 r.conProviders.add(conn); 7858 return conn; 7859 } 7860 cpr.addExternalProcessHandleLocked(externalProcessToken); 7861 return null; 7862 } 7863 7864 boolean decProviderCountLocked(ContentProviderConnection conn, 7865 ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 7866 if (conn != null) { 7867 cpr = conn.provider; 7868 if (DEBUG_PROVIDER) Slog.v(TAG, 7869 "Removing provider requested by " 7870 + conn.client.processName + " from process " 7871 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 7872 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 7873 if (stable) { 7874 conn.stableCount--; 7875 } else { 7876 conn.unstableCount--; 7877 } 7878 if (conn.stableCount == 0 && conn.unstableCount == 0) { 7879 cpr.connections.remove(conn); 7880 conn.client.conProviders.remove(conn); 7881 return true; 7882 } 7883 return false; 7884 } 7885 cpr.removeExternalProcessHandleLocked(externalProcessToken); 7886 return false; 7887 } 7888 7889 private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller, 7890 String name, IBinder token, boolean stable, int userId) { 7891 ContentProviderRecord cpr; 7892 ContentProviderConnection conn = null; 7893 ProviderInfo cpi = null; 7894 7895 synchronized(this) { 7896 ProcessRecord r = null; 7897 if (caller != null) { 7898 r = getRecordForAppLocked(caller); 7899 if (r == null) { 7900 throw new SecurityException( 7901 "Unable to find app for caller " + caller 7902 + " (pid=" + Binder.getCallingPid() 7903 + ") when getting content provider " + name); 7904 } 7905 } 7906 7907 // First check if this content provider has been published... 7908 cpr = mProviderMap.getProviderByName(name, userId); 7909 boolean providerRunning = cpr != null; 7910 if (providerRunning) { 7911 cpi = cpr.info; 7912 String msg; 7913 if ((msg=checkContentProviderPermissionLocked(cpi, r, userId)) != null) { 7914 throw new SecurityException(msg); 7915 } 7916 7917 if (r != null && cpr.canRunHere(r)) { 7918 // This provider has been published or is in the process 7919 // of being published... but it is also allowed to run 7920 // in the caller's process, so don't make a connection 7921 // and just let the caller instantiate its own instance. 7922 ContentProviderHolder holder = cpr.newHolder(null); 7923 // don't give caller the provider object, it needs 7924 // to make its own. 7925 holder.provider = null; 7926 return holder; 7927 } 7928 7929 final long origId = Binder.clearCallingIdentity(); 7930 7931 // In this case the provider instance already exists, so we can 7932 // return it right away. 7933 conn = incProviderCountLocked(r, cpr, token, stable); 7934 if (conn != null && (conn.stableCount+conn.unstableCount) == 1) { 7935 if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 7936 // If this is a perceptible app accessing the provider, 7937 // make sure to count it as being accessed and thus 7938 // back up on the LRU list. This is good because 7939 // content providers are often expensive to start. 7940 updateLruProcessLocked(cpr.proc, false, null); 7941 } 7942 } 7943 7944 if (cpr.proc != null) { 7945 if (false) { 7946 if (cpr.name.flattenToShortString().equals( 7947 "com.android.providers.calendar/.CalendarProvider2")) { 7948 Slog.v(TAG, "****************** KILLING " 7949 + cpr.name.flattenToShortString()); 7950 Process.killProcess(cpr.proc.pid); 7951 } 7952 } 7953 boolean success = updateOomAdjLocked(cpr.proc); 7954 if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success); 7955 // NOTE: there is still a race here where a signal could be 7956 // pending on the process even though we managed to update its 7957 // adj level. Not sure what to do about this, but at least 7958 // the race is now smaller. 7959 if (!success) { 7960 // Uh oh... it looks like the provider's process 7961 // has been killed on us. We need to wait for a new 7962 // process to be started, and make sure its death 7963 // doesn't kill our process. 7964 Slog.i(TAG, 7965 "Existing provider " + cpr.name.flattenToShortString() 7966 + " is crashing; detaching " + r); 7967 boolean lastRef = decProviderCountLocked(conn, cpr, token, stable); 7968 appDiedLocked(cpr.proc, cpr.proc.pid, cpr.proc.thread); 7969 if (!lastRef) { 7970 // This wasn't the last ref our process had on 7971 // the provider... we have now been killed, bail. 7972 return null; 7973 } 7974 providerRunning = false; 7975 conn = null; 7976 } 7977 } 7978 7979 Binder.restoreCallingIdentity(origId); 7980 } 7981 7982 boolean singleton; 7983 if (!providerRunning) { 7984 try { 7985 cpi = AppGlobals.getPackageManager(). 7986 resolveContentProvider(name, 7987 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId); 7988 } catch (RemoteException ex) { 7989 } 7990 if (cpi == null) { 7991 return null; 7992 } 7993 singleton = isSingleton(cpi.processName, cpi.applicationInfo, 7994 cpi.name, cpi.flags); 7995 if (singleton) { 7996 userId = 0; 7997 } 7998 cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId); 7999 8000 String msg; 8001 if ((msg=checkContentProviderPermissionLocked(cpi, r, userId)) != null) { 8002 throw new SecurityException(msg); 8003 } 8004 8005 if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate 8006 && !cpi.processName.equals("system")) { 8007 // If this content provider does not run in the system 8008 // process, and the system is not yet ready to run other 8009 // processes, then fail fast instead of hanging. 8010 throw new IllegalArgumentException( 8011 "Attempt to launch content provider before system ready"); 8012 } 8013 8014 // Make sure that the user who owns this provider is started. If not, 8015 // we don't want to allow it to run. 8016 if (mStartedUsers.get(userId) == null) { 8017 Slog.w(TAG, "Unable to launch app " 8018 + cpi.applicationInfo.packageName + "/" 8019 + cpi.applicationInfo.uid + " for provider " 8020 + name + ": user " + userId + " is stopped"); 8021 return null; 8022 } 8023 8024 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 8025 cpr = mProviderMap.getProviderByClass(comp, userId); 8026 final boolean firstClass = cpr == null; 8027 if (firstClass) { 8028 try { 8029 ApplicationInfo ai = 8030 AppGlobals.getPackageManager(). 8031 getApplicationInfo( 8032 cpi.applicationInfo.packageName, 8033 STOCK_PM_FLAGS, userId); 8034 if (ai == null) { 8035 Slog.w(TAG, "No package info for content provider " 8036 + cpi.name); 8037 return null; 8038 } 8039 ai = getAppInfoForUser(ai, userId); 8040 cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton); 8041 } catch (RemoteException ex) { 8042 // pm is in same process, this will never happen. 8043 } 8044 } 8045 8046 if (r != null && cpr.canRunHere(r)) { 8047 // If this is a multiprocess provider, then just return its 8048 // info and allow the caller to instantiate it. Only do 8049 // this if the provider is the same user as the caller's 8050 // process, or can run as root (so can be in any process). 8051 return cpr.newHolder(null); 8052 } 8053 8054 if (DEBUG_PROVIDER) { 8055 RuntimeException e = new RuntimeException("here"); 8056 Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null) 8057 + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e); 8058 } 8059 8060 // This is single process, and our app is now connecting to it. 8061 // See if we are already in the process of launching this 8062 // provider. 8063 final int N = mLaunchingProviders.size(); 8064 int i; 8065 for (i=0; i<N; i++) { 8066 if (mLaunchingProviders.get(i) == cpr) { 8067 break; 8068 } 8069 } 8070 8071 // If the provider is not already being launched, then get it 8072 // started. 8073 if (i >= N) { 8074 final long origId = Binder.clearCallingIdentity(); 8075 8076 try { 8077 // Content provider is now in use, its package can't be stopped. 8078 try { 8079 AppGlobals.getPackageManager().setPackageStoppedState( 8080 cpr.appInfo.packageName, false, userId); 8081 } catch (RemoteException e) { 8082 } catch (IllegalArgumentException e) { 8083 Slog.w(TAG, "Failed trying to unstop package " 8084 + cpr.appInfo.packageName + ": " + e); 8085 } 8086 8087 // Use existing process if already started 8088 ProcessRecord proc = getProcessRecordLocked( 8089 cpi.processName, cpr.appInfo.uid, false); 8090 if (proc != null && proc.thread != null) { 8091 if (DEBUG_PROVIDER) { 8092 Slog.d(TAG, "Installing in existing process " + proc); 8093 } 8094 proc.pubProviders.put(cpi.name, cpr); 8095 try { 8096 proc.thread.scheduleInstallProvider(cpi); 8097 } catch (RemoteException e) { 8098 } 8099 } else { 8100 proc = startProcessLocked(cpi.processName, 8101 cpr.appInfo, false, 0, "content provider", 8102 new ComponentName(cpi.applicationInfo.packageName, 8103 cpi.name), false, false, false); 8104 if (proc == null) { 8105 Slog.w(TAG, "Unable to launch app " 8106 + cpi.applicationInfo.packageName + "/" 8107 + cpi.applicationInfo.uid + " for provider " 8108 + name + ": process is bad"); 8109 return null; 8110 } 8111 } 8112 cpr.launchingApp = proc; 8113 mLaunchingProviders.add(cpr); 8114 } finally { 8115 Binder.restoreCallingIdentity(origId); 8116 } 8117 } 8118 8119 // Make sure the provider is published (the same provider class 8120 // may be published under multiple names). 8121 if (firstClass) { 8122 mProviderMap.putProviderByClass(comp, cpr); 8123 } 8124 8125 mProviderMap.putProviderByName(name, cpr); 8126 conn = incProviderCountLocked(r, cpr, token, stable); 8127 if (conn != null) { 8128 conn.waiting = true; 8129 } 8130 } 8131 } 8132 8133 // Wait for the provider to be published... 8134 synchronized (cpr) { 8135 while (cpr.provider == null) { 8136 if (cpr.launchingApp == null) { 8137 Slog.w(TAG, "Unable to launch app " 8138 + cpi.applicationInfo.packageName + "/" 8139 + cpi.applicationInfo.uid + " for provider " 8140 + name + ": launching app became null"); 8141 EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS, 8142 UserHandle.getUserId(cpi.applicationInfo.uid), 8143 cpi.applicationInfo.packageName, 8144 cpi.applicationInfo.uid, name); 8145 return null; 8146 } 8147 try { 8148 if (DEBUG_MU) { 8149 Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp=" 8150 + cpr.launchingApp); 8151 } 8152 if (conn != null) { 8153 conn.waiting = true; 8154 } 8155 cpr.wait(); 8156 } catch (InterruptedException ex) { 8157 } finally { 8158 if (conn != null) { 8159 conn.waiting = false; 8160 } 8161 } 8162 } 8163 } 8164 return cpr != null ? cpr.newHolder(conn) : null; 8165 } 8166 8167 @Override 8168 public final ContentProviderHolder getContentProvider( 8169 IApplicationThread caller, String name, int userId, boolean stable) { 8170 enforceNotIsolatedCaller("getContentProvider"); 8171 if (caller == null) { 8172 String msg = "null IApplicationThread when getting content provider " 8173 + name; 8174 Slog.w(TAG, msg); 8175 throw new SecurityException(msg); 8176 } 8177 // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal 8178 // with cross-user grant. 8179 return getContentProviderImpl(caller, name, null, stable, userId); 8180 } 8181 8182 public ContentProviderHolder getContentProviderExternal( 8183 String name, int userId, IBinder token) { 8184 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 8185 "Do not have permission in call getContentProviderExternal()"); 8186 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 8187 false, true, "getContentProvider", null); 8188 return getContentProviderExternalUnchecked(name, token, userId); 8189 } 8190 8191 private ContentProviderHolder getContentProviderExternalUnchecked(String name, 8192 IBinder token, int userId) { 8193 return getContentProviderImpl(null, name, token, true, userId); 8194 } 8195 8196 /** 8197 * Drop a content provider from a ProcessRecord's bookkeeping 8198 */ 8199 public void removeContentProvider(IBinder connection, boolean stable) { 8200 enforceNotIsolatedCaller("removeContentProvider"); 8201 long ident = Binder.clearCallingIdentity(); 8202 try { 8203 synchronized (this) { 8204 ContentProviderConnection conn; 8205 try { 8206 conn = (ContentProviderConnection)connection; 8207 } catch (ClassCastException e) { 8208 String msg ="removeContentProvider: " + connection 8209 + " not a ContentProviderConnection"; 8210 Slog.w(TAG, msg); 8211 throw new IllegalArgumentException(msg); 8212 } 8213 if (conn == null) { 8214 throw new NullPointerException("connection is null"); 8215 } 8216 if (decProviderCountLocked(conn, null, null, stable)) { 8217 updateOomAdjLocked(); 8218 } 8219 } 8220 } finally { 8221 Binder.restoreCallingIdentity(ident); 8222 } 8223 } 8224 8225 public void removeContentProviderExternal(String name, IBinder token) { 8226 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 8227 "Do not have permission in call removeContentProviderExternal()"); 8228 removeContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId()); 8229 } 8230 8231 private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) { 8232 synchronized (this) { 8233 ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId); 8234 if(cpr == null) { 8235 //remove from mProvidersByClass 8236 if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list"); 8237 return; 8238 } 8239 8240 //update content provider record entry info 8241 ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name); 8242 ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId); 8243 if (localCpr.hasExternalProcessHandles()) { 8244 if (localCpr.removeExternalProcessHandleLocked(token)) { 8245 updateOomAdjLocked(); 8246 } else { 8247 Slog.e(TAG, "Attmpt to remove content provider " + localCpr 8248 + " with no external reference for token: " 8249 + token + "."); 8250 } 8251 } else { 8252 Slog.e(TAG, "Attmpt to remove content provider: " + localCpr 8253 + " with no external references."); 8254 } 8255 } 8256 } 8257 8258 public final void publishContentProviders(IApplicationThread caller, 8259 List<ContentProviderHolder> providers) { 8260 if (providers == null) { 8261 return; 8262 } 8263 8264 enforceNotIsolatedCaller("publishContentProviders"); 8265 synchronized (this) { 8266 final ProcessRecord r = getRecordForAppLocked(caller); 8267 if (DEBUG_MU) 8268 Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid); 8269 if (r == null) { 8270 throw new SecurityException( 8271 "Unable to find app for caller " + caller 8272 + " (pid=" + Binder.getCallingPid() 8273 + ") when publishing content providers"); 8274 } 8275 8276 final long origId = Binder.clearCallingIdentity(); 8277 8278 final int N = providers.size(); 8279 for (int i=0; i<N; i++) { 8280 ContentProviderHolder src = providers.get(i); 8281 if (src == null || src.info == null || src.provider == null) { 8282 continue; 8283 } 8284 ContentProviderRecord dst = r.pubProviders.get(src.info.name); 8285 if (DEBUG_MU) 8286 Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid); 8287 if (dst != null) { 8288 ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name); 8289 mProviderMap.putProviderByClass(comp, dst); 8290 String names[] = dst.info.authority.split(";"); 8291 for (int j = 0; j < names.length; j++) { 8292 mProviderMap.putProviderByName(names[j], dst); 8293 } 8294 8295 int NL = mLaunchingProviders.size(); 8296 int j; 8297 for (j=0; j<NL; j++) { 8298 if (mLaunchingProviders.get(j) == dst) { 8299 mLaunchingProviders.remove(j); 8300 j--; 8301 NL--; 8302 } 8303 } 8304 synchronized (dst) { 8305 dst.provider = src.provider; 8306 dst.proc = r; 8307 dst.notifyAll(); 8308 } 8309 updateOomAdjLocked(r); 8310 } 8311 } 8312 8313 Binder.restoreCallingIdentity(origId); 8314 } 8315 } 8316 8317 public boolean refContentProvider(IBinder connection, int stable, int unstable) { 8318 ContentProviderConnection conn; 8319 try { 8320 conn = (ContentProviderConnection)connection; 8321 } catch (ClassCastException e) { 8322 String msg ="refContentProvider: " + connection 8323 + " not a ContentProviderConnection"; 8324 Slog.w(TAG, msg); 8325 throw new IllegalArgumentException(msg); 8326 } 8327 if (conn == null) { 8328 throw new NullPointerException("connection is null"); 8329 } 8330 8331 synchronized (this) { 8332 if (stable > 0) { 8333 conn.numStableIncs += stable; 8334 } 8335 stable = conn.stableCount + stable; 8336 if (stable < 0) { 8337 throw new IllegalStateException("stableCount < 0: " + stable); 8338 } 8339 8340 if (unstable > 0) { 8341 conn.numUnstableIncs += unstable; 8342 } 8343 unstable = conn.unstableCount + unstable; 8344 if (unstable < 0) { 8345 throw new IllegalStateException("unstableCount < 0: " + unstable); 8346 } 8347 8348 if ((stable+unstable) <= 0) { 8349 throw new IllegalStateException("ref counts can't go to zero here: stable=" 8350 + stable + " unstable=" + unstable); 8351 } 8352 conn.stableCount = stable; 8353 conn.unstableCount = unstable; 8354 return !conn.dead; 8355 } 8356 } 8357 8358 public void unstableProviderDied(IBinder connection) { 8359 ContentProviderConnection conn; 8360 try { 8361 conn = (ContentProviderConnection)connection; 8362 } catch (ClassCastException e) { 8363 String msg ="refContentProvider: " + connection 8364 + " not a ContentProviderConnection"; 8365 Slog.w(TAG, msg); 8366 throw new IllegalArgumentException(msg); 8367 } 8368 if (conn == null) { 8369 throw new NullPointerException("connection is null"); 8370 } 8371 8372 // Safely retrieve the content provider associated with the connection. 8373 IContentProvider provider; 8374 synchronized (this) { 8375 provider = conn.provider.provider; 8376 } 8377 8378 if (provider == null) { 8379 // Um, yeah, we're way ahead of you. 8380 return; 8381 } 8382 8383 // Make sure the caller is being honest with us. 8384 if (provider.asBinder().pingBinder()) { 8385 // Er, no, still looks good to us. 8386 synchronized (this) { 8387 Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid() 8388 + " says " + conn + " died, but we don't agree"); 8389 return; 8390 } 8391 } 8392 8393 // Well look at that! It's dead! 8394 synchronized (this) { 8395 if (conn.provider.provider != provider) { 8396 // But something changed... good enough. 8397 return; 8398 } 8399 8400 ProcessRecord proc = conn.provider.proc; 8401 if (proc == null || proc.thread == null) { 8402 // Seems like the process is already cleaned up. 8403 return; 8404 } 8405 8406 // As far as we're concerned, this is just like receiving a 8407 // death notification... just a bit prematurely. 8408 Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid 8409 + ") early provider death"); 8410 final long ident = Binder.clearCallingIdentity(); 8411 try { 8412 appDiedLocked(proc, proc.pid, proc.thread); 8413 } finally { 8414 Binder.restoreCallingIdentity(ident); 8415 } 8416 } 8417 } 8418 8419 @Override 8420 public void appNotRespondingViaProvider(IBinder connection) { 8421 enforceCallingPermission( 8422 android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()"); 8423 8424 final ContentProviderConnection conn = (ContentProviderConnection) connection; 8425 if (conn == null) { 8426 Slog.w(TAG, "ContentProviderConnection is null"); 8427 return; 8428 } 8429 8430 final ProcessRecord host = conn.provider.proc; 8431 if (host == null) { 8432 Slog.w(TAG, "Failed to find hosting ProcessRecord"); 8433 return; 8434 } 8435 8436 final long token = Binder.clearCallingIdentity(); 8437 try { 8438 appNotResponding(host, null, null, false, "ContentProvider not responding"); 8439 } finally { 8440 Binder.restoreCallingIdentity(token); 8441 } 8442 } 8443 8444 public final void installSystemProviders() { 8445 List<ProviderInfo> providers; 8446 synchronized (this) { 8447 ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID); 8448 providers = generateApplicationProvidersLocked(app); 8449 if (providers != null) { 8450 for (int i=providers.size()-1; i>=0; i--) { 8451 ProviderInfo pi = (ProviderInfo)providers.get(i); 8452 if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) { 8453 Slog.w(TAG, "Not installing system proc provider " + pi.name 8454 + ": not system .apk"); 8455 providers.remove(i); 8456 } 8457 } 8458 } 8459 } 8460 if (providers != null) { 8461 mSystemThread.installSystemProviders(providers); 8462 } 8463 8464 mCoreSettingsObserver = new CoreSettingsObserver(this); 8465 8466 mUsageStatsService.monitorPackages(); 8467 } 8468 8469 /** 8470 * Allows app to retrieve the MIME type of a URI without having permission 8471 * to access its content provider. 8472 * 8473 * CTS tests for this functionality can be run with "runtest cts-appsecurity". 8474 * 8475 * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/ 8476 * src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java 8477 */ 8478 public String getProviderMimeType(Uri uri, int userId) { 8479 enforceNotIsolatedCaller("getProviderMimeType"); 8480 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 8481 userId, false, true, "getProviderMimeType", null); 8482 final String name = uri.getAuthority(); 8483 final long ident = Binder.clearCallingIdentity(); 8484 ContentProviderHolder holder = null; 8485 8486 try { 8487 holder = getContentProviderExternalUnchecked(name, null, userId); 8488 if (holder != null) { 8489 return holder.provider.getType(uri); 8490 } 8491 } catch (RemoteException e) { 8492 Log.w(TAG, "Content provider dead retrieving " + uri, e); 8493 return null; 8494 } finally { 8495 if (holder != null) { 8496 removeContentProviderExternalUnchecked(name, null, userId); 8497 } 8498 Binder.restoreCallingIdentity(ident); 8499 } 8500 8501 return null; 8502 } 8503 8504 // ========================================================= 8505 // GLOBAL MANAGEMENT 8506 // ========================================================= 8507 8508 final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess, 8509 boolean isolated) { 8510 String proc = customProcess != null ? customProcess : info.processName; 8511 BatteryStatsImpl.Uid.Proc ps = null; 8512 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 8513 int uid = info.uid; 8514 if (isolated) { 8515 int userId = UserHandle.getUserId(uid); 8516 int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1; 8517 while (true) { 8518 if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID 8519 || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) { 8520 mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID; 8521 } 8522 uid = UserHandle.getUid(userId, mNextIsolatedProcessUid); 8523 mNextIsolatedProcessUid++; 8524 if (mIsolatedProcesses.indexOfKey(uid) < 0) { 8525 // No process for this uid, use it. 8526 break; 8527 } 8528 stepsLeft--; 8529 if (stepsLeft <= 0) { 8530 return null; 8531 } 8532 } 8533 } 8534 return new ProcessRecord(stats, info, proc, uid); 8535 } 8536 8537 final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated) { 8538 ProcessRecord app; 8539 if (!isolated) { 8540 app = getProcessRecordLocked(info.processName, info.uid, true); 8541 } else { 8542 app = null; 8543 } 8544 8545 if (app == null) { 8546 app = newProcessRecordLocked(info, null, isolated); 8547 mProcessNames.put(info.processName, app.uid, app); 8548 if (isolated) { 8549 mIsolatedProcesses.put(app.uid, app); 8550 } 8551 updateLruProcessLocked(app, false, null); 8552 updateOomAdjLocked(); 8553 } 8554 8555 // This package really, really can not be stopped. 8556 try { 8557 AppGlobals.getPackageManager().setPackageStoppedState( 8558 info.packageName, false, UserHandle.getUserId(app.uid)); 8559 } catch (RemoteException e) { 8560 } catch (IllegalArgumentException e) { 8561 Slog.w(TAG, "Failed trying to unstop package " 8562 + info.packageName + ": " + e); 8563 } 8564 8565 if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) 8566 == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) { 8567 app.persistent = true; 8568 app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ; 8569 } 8570 if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) { 8571 mPersistentStartingProcesses.add(app); 8572 startProcessLocked(app, "added application", app.processName); 8573 } 8574 8575 return app; 8576 } 8577 8578 public void unhandledBack() { 8579 enforceCallingPermission(android.Manifest.permission.FORCE_BACK, 8580 "unhandledBack()"); 8581 8582 synchronized(this) { 8583 final long origId = Binder.clearCallingIdentity(); 8584 try { 8585 getFocusedStack().unhandledBackLocked(); 8586 } finally { 8587 Binder.restoreCallingIdentity(origId); 8588 } 8589 } 8590 } 8591 8592 public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException { 8593 enforceNotIsolatedCaller("openContentUri"); 8594 final int userId = UserHandle.getCallingUserId(); 8595 String name = uri.getAuthority(); 8596 ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId); 8597 ParcelFileDescriptor pfd = null; 8598 if (cph != null) { 8599 // We record the binder invoker's uid in thread-local storage before 8600 // going to the content provider to open the file. Later, in the code 8601 // that handles all permissions checks, we look for this uid and use 8602 // that rather than the Activity Manager's own uid. The effect is that 8603 // we do the check against the caller's permissions even though it looks 8604 // to the content provider like the Activity Manager itself is making 8605 // the request. 8606 sCallerIdentity.set(new Identity( 8607 Binder.getCallingPid(), Binder.getCallingUid())); 8608 try { 8609 pfd = cph.provider.openFile(null, uri, "r", null); 8610 } catch (FileNotFoundException e) { 8611 // do nothing; pfd will be returned null 8612 } finally { 8613 // Ensure that whatever happens, we clean up the identity state 8614 sCallerIdentity.remove(); 8615 } 8616 8617 // We've got the fd now, so we're done with the provider. 8618 removeContentProviderExternalUnchecked(name, null, userId); 8619 } else { 8620 Slog.d(TAG, "Failed to get provider for authority '" + name + "'"); 8621 } 8622 return pfd; 8623 } 8624 8625 // Actually is sleeping or shutting down or whatever else in the future 8626 // is an inactive state. 8627 public boolean isSleepingOrShuttingDown() { 8628 return mSleeping || mShuttingDown; 8629 } 8630 8631 public boolean isSleeping() { 8632 return mSleeping; 8633 } 8634 8635 void goingToSleep() { 8636 synchronized(this) { 8637 mWentToSleep = true; 8638 updateEventDispatchingLocked(); 8639 goToSleepIfNeededLocked(); 8640 } 8641 } 8642 8643 void finishRunningVoiceLocked() { 8644 if (mRunningVoice) { 8645 mRunningVoice = false; 8646 goToSleepIfNeededLocked(); 8647 } 8648 } 8649 8650 void goToSleepIfNeededLocked() { 8651 if (mWentToSleep && !mRunningVoice) { 8652 if (!mSleeping) { 8653 mSleeping = true; 8654 mStackSupervisor.goingToSleepLocked(); 8655 8656 // Initialize the wake times of all processes. 8657 checkExcessivePowerUsageLocked(false); 8658 mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 8659 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 8660 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 8661 } 8662 } 8663 } 8664 8665 void notifyTaskPersisterLocked(TaskRecord task, boolean flush) { 8666 mTaskPersister.notify(task, flush); 8667 } 8668 8669 @Override 8670 public boolean shutdown(int timeout) { 8671 if (checkCallingPermission(android.Manifest.permission.SHUTDOWN) 8672 != PackageManager.PERMISSION_GRANTED) { 8673 throw new SecurityException("Requires permission " 8674 + android.Manifest.permission.SHUTDOWN); 8675 } 8676 8677 boolean timedout = false; 8678 8679 synchronized(this) { 8680 mShuttingDown = true; 8681 updateEventDispatchingLocked(); 8682 timedout = mStackSupervisor.shutdownLocked(timeout); 8683 } 8684 8685 mAppOpsService.shutdown(); 8686 mUsageStatsService.shutdown(); 8687 mBatteryStatsService.shutdown(); 8688 synchronized (this) { 8689 mProcessStats.shutdownLocked(); 8690 } 8691 notifyTaskPersisterLocked(null, true); 8692 8693 return timedout; 8694 } 8695 8696 public final void activitySlept(IBinder token) { 8697 if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token); 8698 8699 final long origId = Binder.clearCallingIdentity(); 8700 8701 synchronized (this) { 8702 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 8703 if (r != null) { 8704 mStackSupervisor.activitySleptLocked(r); 8705 } 8706 } 8707 8708 Binder.restoreCallingIdentity(origId); 8709 } 8710 8711 void logLockScreen(String msg) { 8712 if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg + 8713 " mLockScreenShown=" + mLockScreenShown + " mWentToSleep=" + 8714 mWentToSleep + " mSleeping=" + mSleeping + " mDismissKeyguardOnNextActivity=" + 8715 mStackSupervisor.mDismissKeyguardOnNextActivity); 8716 } 8717 8718 private void comeOutOfSleepIfNeededLocked() { 8719 if ((!mWentToSleep && !mLockScreenShown) || mRunningVoice) { 8720 if (mSleeping) { 8721 mSleeping = false; 8722 mStackSupervisor.comeOutOfSleepIfNeededLocked(); 8723 } 8724 } 8725 } 8726 8727 void wakingUp() { 8728 synchronized(this) { 8729 mWentToSleep = false; 8730 updateEventDispatchingLocked(); 8731 comeOutOfSleepIfNeededLocked(); 8732 } 8733 } 8734 8735 void startRunningVoiceLocked() { 8736 if (!mRunningVoice) { 8737 mRunningVoice = true; 8738 comeOutOfSleepIfNeededLocked(); 8739 } 8740 } 8741 8742 private void updateEventDispatchingLocked() { 8743 mWindowManager.setEventDispatching(mBooted && !mWentToSleep && !mShuttingDown); 8744 } 8745 8746 public void setLockScreenShown(boolean shown) { 8747 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER) 8748 != PackageManager.PERMISSION_GRANTED) { 8749 throw new SecurityException("Requires permission " 8750 + android.Manifest.permission.DEVICE_POWER); 8751 } 8752 8753 synchronized(this) { 8754 long ident = Binder.clearCallingIdentity(); 8755 try { 8756 if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown); 8757 mLockScreenShown = shown; 8758 comeOutOfSleepIfNeededLocked(); 8759 } finally { 8760 Binder.restoreCallingIdentity(ident); 8761 } 8762 } 8763 } 8764 8765 public void stopAppSwitches() { 8766 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 8767 != PackageManager.PERMISSION_GRANTED) { 8768 throw new SecurityException("Requires permission " 8769 + android.Manifest.permission.STOP_APP_SWITCHES); 8770 } 8771 8772 synchronized(this) { 8773 mAppSwitchesAllowedTime = SystemClock.uptimeMillis() 8774 + APP_SWITCH_DELAY_TIME; 8775 mDidAppSwitch = false; 8776 mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 8777 Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 8778 mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME); 8779 } 8780 } 8781 8782 public void resumeAppSwitches() { 8783 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 8784 != PackageManager.PERMISSION_GRANTED) { 8785 throw new SecurityException("Requires permission " 8786 + android.Manifest.permission.STOP_APP_SWITCHES); 8787 } 8788 8789 synchronized(this) { 8790 // Note that we don't execute any pending app switches... we will 8791 // let those wait until either the timeout, or the next start 8792 // activity request. 8793 mAppSwitchesAllowedTime = 0; 8794 } 8795 } 8796 8797 boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid, 8798 String name) { 8799 if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) { 8800 return true; 8801 } 8802 8803 final int perm = checkComponentPermission( 8804 android.Manifest.permission.STOP_APP_SWITCHES, callingPid, 8805 callingUid, -1, true); 8806 if (perm == PackageManager.PERMISSION_GRANTED) { 8807 return true; 8808 } 8809 8810 Slog.w(TAG, name + " request from " + callingUid + " stopped"); 8811 return false; 8812 } 8813 8814 public void setDebugApp(String packageName, boolean waitForDebugger, 8815 boolean persistent) { 8816 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP, 8817 "setDebugApp()"); 8818 8819 long ident = Binder.clearCallingIdentity(); 8820 try { 8821 // Note that this is not really thread safe if there are multiple 8822 // callers into it at the same time, but that's not a situation we 8823 // care about. 8824 if (persistent) { 8825 final ContentResolver resolver = mContext.getContentResolver(); 8826 Settings.Global.putString( 8827 resolver, Settings.Global.DEBUG_APP, 8828 packageName); 8829 Settings.Global.putInt( 8830 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 8831 waitForDebugger ? 1 : 0); 8832 } 8833 8834 synchronized (this) { 8835 if (!persistent) { 8836 mOrigDebugApp = mDebugApp; 8837 mOrigWaitForDebugger = mWaitForDebugger; 8838 } 8839 mDebugApp = packageName; 8840 mWaitForDebugger = waitForDebugger; 8841 mDebugTransient = !persistent; 8842 if (packageName != null) { 8843 forceStopPackageLocked(packageName, -1, false, false, true, true, 8844 false, UserHandle.USER_ALL, "set debug app"); 8845 } 8846 } 8847 } finally { 8848 Binder.restoreCallingIdentity(ident); 8849 } 8850 } 8851 8852 void setOpenGlTraceApp(ApplicationInfo app, String processName) { 8853 synchronized (this) { 8854 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 8855 if (!isDebuggable) { 8856 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 8857 throw new SecurityException("Process not debuggable: " + app.packageName); 8858 } 8859 } 8860 8861 mOpenGlTraceApp = processName; 8862 } 8863 } 8864 8865 void setProfileApp(ApplicationInfo app, String processName, String profileFile, 8866 ParcelFileDescriptor profileFd, boolean autoStopProfiler) { 8867 synchronized (this) { 8868 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 8869 if (!isDebuggable) { 8870 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 8871 throw new SecurityException("Process not debuggable: " + app.packageName); 8872 } 8873 } 8874 mProfileApp = processName; 8875 mProfileFile = profileFile; 8876 if (mProfileFd != null) { 8877 try { 8878 mProfileFd.close(); 8879 } catch (IOException e) { 8880 } 8881 mProfileFd = null; 8882 } 8883 mProfileFd = profileFd; 8884 mProfileType = 0; 8885 mAutoStopProfiler = autoStopProfiler; 8886 } 8887 } 8888 8889 @Override 8890 public void setAlwaysFinish(boolean enabled) { 8891 enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH, 8892 "setAlwaysFinish()"); 8893 8894 Settings.Global.putInt( 8895 mContext.getContentResolver(), 8896 Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0); 8897 8898 synchronized (this) { 8899 mAlwaysFinishActivities = enabled; 8900 } 8901 } 8902 8903 @Override 8904 public void setActivityController(IActivityController controller) { 8905 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 8906 "setActivityController()"); 8907 synchronized (this) { 8908 mController = controller; 8909 Watchdog.getInstance().setActivityController(controller); 8910 } 8911 } 8912 8913 @Override 8914 public void setUserIsMonkey(boolean userIsMonkey) { 8915 synchronized (this) { 8916 synchronized (mPidsSelfLocked) { 8917 final int callingPid = Binder.getCallingPid(); 8918 ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid); 8919 if (precessRecord == null) { 8920 throw new SecurityException("Unknown process: " + callingPid); 8921 } 8922 if (precessRecord.instrumentationUiAutomationConnection == null) { 8923 throw new SecurityException("Only an instrumentation process " 8924 + "with a UiAutomation can call setUserIsMonkey"); 8925 } 8926 } 8927 mUserIsMonkey = userIsMonkey; 8928 } 8929 } 8930 8931 @Override 8932 public boolean isUserAMonkey() { 8933 synchronized (this) { 8934 // If there is a controller also implies the user is a monkey. 8935 return (mUserIsMonkey || mController != null); 8936 } 8937 } 8938 8939 public void requestBugReport() { 8940 enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport"); 8941 SystemProperties.set("ctl.start", "bugreport"); 8942 } 8943 8944 public static long getInputDispatchingTimeoutLocked(ActivityRecord r) { 8945 return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT; 8946 } 8947 8948 public static long getInputDispatchingTimeoutLocked(ProcessRecord r) { 8949 if (r != null && (r.instrumentationClass != null || r.usingWrapper)) { 8950 return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT; 8951 } 8952 return KEY_DISPATCHING_TIMEOUT; 8953 } 8954 8955 @Override 8956 public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) { 8957 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS) 8958 != PackageManager.PERMISSION_GRANTED) { 8959 throw new SecurityException("Requires permission " 8960 + android.Manifest.permission.FILTER_EVENTS); 8961 } 8962 ProcessRecord proc; 8963 long timeout; 8964 synchronized (this) { 8965 synchronized (mPidsSelfLocked) { 8966 proc = mPidsSelfLocked.get(pid); 8967 } 8968 timeout = getInputDispatchingTimeoutLocked(proc); 8969 } 8970 8971 if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) { 8972 return -1; 8973 } 8974 8975 return timeout; 8976 } 8977 8978 /** 8979 * Handle input dispatching timeouts. 8980 * Returns whether input dispatching should be aborted or not. 8981 */ 8982 public boolean inputDispatchingTimedOut(final ProcessRecord proc, 8983 final ActivityRecord activity, final ActivityRecord parent, 8984 final boolean aboveSystem, String reason) { 8985 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS) 8986 != PackageManager.PERMISSION_GRANTED) { 8987 throw new SecurityException("Requires permission " 8988 + android.Manifest.permission.FILTER_EVENTS); 8989 } 8990 8991 final String annotation; 8992 if (reason == null) { 8993 annotation = "Input dispatching timed out"; 8994 } else { 8995 annotation = "Input dispatching timed out (" + reason + ")"; 8996 } 8997 8998 if (proc != null) { 8999 synchronized (this) { 9000 if (proc.debugging) { 9001 return false; 9002 } 9003 9004 if (mDidDexOpt) { 9005 // Give more time since we were dexopting. 9006 mDidDexOpt = false; 9007 return false; 9008 } 9009 9010 if (proc.instrumentationClass != null) { 9011 Bundle info = new Bundle(); 9012 info.putString("shortMsg", "keyDispatchingTimedOut"); 9013 info.putString("longMsg", annotation); 9014 finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info); 9015 return true; 9016 } 9017 } 9018 mHandler.post(new Runnable() { 9019 @Override 9020 public void run() { 9021 appNotResponding(proc, activity, parent, aboveSystem, annotation); 9022 } 9023 }); 9024 } 9025 9026 return true; 9027 } 9028 9029 public Bundle getAssistContextExtras(int requestType) { 9030 enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO, 9031 "getAssistContextExtras()"); 9032 PendingAssistExtras pae; 9033 Bundle extras = new Bundle(); 9034 synchronized (this) { 9035 ActivityRecord activity = getFocusedStack().mResumedActivity; 9036 if (activity == null) { 9037 Slog.w(TAG, "getAssistContextExtras failed: no resumed activity"); 9038 return null; 9039 } 9040 extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName); 9041 if (activity.app == null || activity.app.thread == null) { 9042 Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity); 9043 return extras; 9044 } 9045 if (activity.app.pid == Binder.getCallingPid()) { 9046 Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity); 9047 return extras; 9048 } 9049 pae = new PendingAssistExtras(activity); 9050 try { 9051 activity.app.thread.requestAssistContextExtras(activity.appToken, pae, 9052 requestType); 9053 mPendingAssistExtras.add(pae); 9054 mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT); 9055 } catch (RemoteException e) { 9056 Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity); 9057 return extras; 9058 } 9059 } 9060 synchronized (pae) { 9061 while (!pae.haveResult) { 9062 try { 9063 pae.wait(); 9064 } catch (InterruptedException e) { 9065 } 9066 } 9067 if (pae.result != null) { 9068 extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result); 9069 } 9070 } 9071 synchronized (this) { 9072 mPendingAssistExtras.remove(pae); 9073 mHandler.removeCallbacks(pae); 9074 } 9075 return extras; 9076 } 9077 9078 public void reportAssistContextExtras(IBinder token, Bundle extras) { 9079 PendingAssistExtras pae = (PendingAssistExtras)token; 9080 synchronized (pae) { 9081 pae.result = extras; 9082 pae.haveResult = true; 9083 pae.notifyAll(); 9084 } 9085 } 9086 9087 public void registerProcessObserver(IProcessObserver observer) { 9088 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 9089 "registerProcessObserver()"); 9090 synchronized (this) { 9091 mProcessObservers.register(observer); 9092 } 9093 } 9094 9095 @Override 9096 public void unregisterProcessObserver(IProcessObserver observer) { 9097 synchronized (this) { 9098 mProcessObservers.unregister(observer); 9099 } 9100 } 9101 9102 @Override 9103 public boolean convertFromTranslucent(IBinder token) { 9104 final long origId = Binder.clearCallingIdentity(); 9105 try { 9106 synchronized (this) { 9107 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 9108 if (r == null) { 9109 return false; 9110 } 9111 if (r.changeWindowTranslucency(true)) { 9112 mWindowManager.setAppFullscreen(token, true); 9113 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 9114 return true; 9115 } 9116 return false; 9117 } 9118 } finally { 9119 Binder.restoreCallingIdentity(origId); 9120 } 9121 } 9122 9123 @Override 9124 public boolean convertToTranslucent(IBinder token, ActivityOptions options) { 9125 final long origId = Binder.clearCallingIdentity(); 9126 try { 9127 synchronized (this) { 9128 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 9129 if (r == null) { 9130 return false; 9131 } 9132 if (r.changeWindowTranslucency(false)) { 9133 r.task.stack.convertToTranslucent(r, options); 9134 mWindowManager.setAppFullscreen(token, false); 9135 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 9136 return true; 9137 } 9138 return false; 9139 } 9140 } finally { 9141 Binder.restoreCallingIdentity(origId); 9142 } 9143 } 9144 9145 @Override 9146 public ActivityOptions getActivityOptions(IBinder token) { 9147 final long origId = Binder.clearCallingIdentity(); 9148 try { 9149 synchronized (this) { 9150 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 9151 if (r != null) { 9152 final ActivityOptions activityOptions = r.pendingOptions; 9153 r.pendingOptions = null; 9154 return activityOptions; 9155 } 9156 return null; 9157 } 9158 } finally { 9159 Binder.restoreCallingIdentity(origId); 9160 } 9161 } 9162 9163 @Override 9164 public void setImmersive(IBinder token, boolean immersive) { 9165 synchronized(this) { 9166 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 9167 if (r == null) { 9168 throw new IllegalArgumentException(); 9169 } 9170 r.immersive = immersive; 9171 9172 // update associated state if we're frontmost 9173 if (r == mFocusedActivity) { 9174 if (DEBUG_IMMERSIVE) { 9175 Slog.d(TAG, "Frontmost changed immersion: "+ r); 9176 } 9177 applyUpdateLockStateLocked(r); 9178 } 9179 } 9180 } 9181 9182 @Override 9183 public boolean isImmersive(IBinder token) { 9184 synchronized (this) { 9185 ActivityRecord r = ActivityRecord.isInStackLocked(token); 9186 if (r == null) { 9187 throw new IllegalArgumentException(); 9188 } 9189 return r.immersive; 9190 } 9191 } 9192 9193 public boolean isTopActivityImmersive() { 9194 enforceNotIsolatedCaller("startActivity"); 9195 synchronized (this) { 9196 ActivityRecord r = getFocusedStack().topRunningActivityLocked(null); 9197 return (r != null) ? r.immersive : false; 9198 } 9199 } 9200 9201 public final void enterSafeMode() { 9202 synchronized(this) { 9203 // It only makes sense to do this before the system is ready 9204 // and started launching other packages. 9205 if (!mSystemReady) { 9206 try { 9207 AppGlobals.getPackageManager().enterSafeMode(); 9208 } catch (RemoteException e) { 9209 } 9210 } 9211 9212 mSafeMode = true; 9213 } 9214 } 9215 9216 public final void showSafeModeOverlay() { 9217 View v = LayoutInflater.from(mContext).inflate( 9218 com.android.internal.R.layout.safe_mode, null); 9219 WindowManager.LayoutParams lp = new WindowManager.LayoutParams(); 9220 lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY; 9221 lp.width = WindowManager.LayoutParams.WRAP_CONTENT; 9222 lp.height = WindowManager.LayoutParams.WRAP_CONTENT; 9223 lp.gravity = Gravity.BOTTOM | Gravity.START; 9224 lp.format = v.getBackground().getOpacity(); 9225 lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE 9226 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE; 9227 lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS; 9228 ((WindowManager)mContext.getSystemService( 9229 Context.WINDOW_SERVICE)).addView(v, lp); 9230 } 9231 9232 public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) { 9233 if (!(sender instanceof PendingIntentRecord)) { 9234 return; 9235 } 9236 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 9237 synchronized (stats) { 9238 if (mBatteryStatsService.isOnBattery()) { 9239 mBatteryStatsService.enforceCallingPermission(); 9240 PendingIntentRecord rec = (PendingIntentRecord)sender; 9241 int MY_UID = Binder.getCallingUid(); 9242 int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid; 9243 BatteryStatsImpl.Uid.Pkg pkg = 9244 stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid, 9245 sourcePkg != null ? sourcePkg : rec.key.packageName); 9246 pkg.incWakeupsLocked(); 9247 } 9248 } 9249 } 9250 9251 public boolean killPids(int[] pids, String pReason, boolean secure) { 9252 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 9253 throw new SecurityException("killPids only available to the system"); 9254 } 9255 String reason = (pReason == null) ? "Unknown" : pReason; 9256 // XXX Note: don't acquire main activity lock here, because the window 9257 // manager calls in with its locks held. 9258 9259 boolean killed = false; 9260 synchronized (mPidsSelfLocked) { 9261 int[] types = new int[pids.length]; 9262 int worstType = 0; 9263 for (int i=0; i<pids.length; i++) { 9264 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 9265 if (proc != null) { 9266 int type = proc.setAdj; 9267 types[i] = type; 9268 if (type > worstType) { 9269 worstType = type; 9270 } 9271 } 9272 } 9273 9274 // If the worst oom_adj is somewhere in the cached proc LRU range, 9275 // then constrain it so we will kill all cached procs. 9276 if (worstType < ProcessList.CACHED_APP_MAX_ADJ 9277 && worstType > ProcessList.CACHED_APP_MIN_ADJ) { 9278 worstType = ProcessList.CACHED_APP_MIN_ADJ; 9279 } 9280 9281 // If this is not a secure call, don't let it kill processes that 9282 // are important. 9283 if (!secure && worstType < ProcessList.SERVICE_ADJ) { 9284 worstType = ProcessList.SERVICE_ADJ; 9285 } 9286 9287 Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType); 9288 for (int i=0; i<pids.length; i++) { 9289 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 9290 if (proc == null) { 9291 continue; 9292 } 9293 int adj = proc.setAdj; 9294 if (adj >= worstType && !proc.killedByAm) { 9295 killUnneededProcessLocked(proc, reason); 9296 killed = true; 9297 } 9298 } 9299 } 9300 return killed; 9301 } 9302 9303 @Override 9304 public void killUid(int uid, String reason) { 9305 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 9306 throw new SecurityException("killUid only available to the system"); 9307 } 9308 synchronized (this) { 9309 killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid), 9310 ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false, 9311 reason != null ? reason : "kill uid"); 9312 } 9313 } 9314 9315 @Override 9316 public boolean killProcessesBelowForeground(String reason) { 9317 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 9318 throw new SecurityException("killProcessesBelowForeground() only available to system"); 9319 } 9320 9321 return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason); 9322 } 9323 9324 private boolean killProcessesBelowAdj(int belowAdj, String reason) { 9325 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 9326 throw new SecurityException("killProcessesBelowAdj() only available to system"); 9327 } 9328 9329 boolean killed = false; 9330 synchronized (mPidsSelfLocked) { 9331 final int size = mPidsSelfLocked.size(); 9332 for (int i = 0; i < size; i++) { 9333 final int pid = mPidsSelfLocked.keyAt(i); 9334 final ProcessRecord proc = mPidsSelfLocked.valueAt(i); 9335 if (proc == null) continue; 9336 9337 final int adj = proc.setAdj; 9338 if (adj > belowAdj && !proc.killedByAm) { 9339 killUnneededProcessLocked(proc, reason); 9340 killed = true; 9341 } 9342 } 9343 } 9344 return killed; 9345 } 9346 9347 @Override 9348 public void hang(final IBinder who, boolean allowRestart) { 9349 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 9350 != PackageManager.PERMISSION_GRANTED) { 9351 throw new SecurityException("Requires permission " 9352 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 9353 } 9354 9355 final IBinder.DeathRecipient death = new DeathRecipient() { 9356 @Override 9357 public void binderDied() { 9358 synchronized (this) { 9359 notifyAll(); 9360 } 9361 } 9362 }; 9363 9364 try { 9365 who.linkToDeath(death, 0); 9366 } catch (RemoteException e) { 9367 Slog.w(TAG, "hang: given caller IBinder is already dead."); 9368 return; 9369 } 9370 9371 synchronized (this) { 9372 Watchdog.getInstance().setAllowRestart(allowRestart); 9373 Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid()); 9374 synchronized (death) { 9375 while (who.isBinderAlive()) { 9376 try { 9377 death.wait(); 9378 } catch (InterruptedException e) { 9379 } 9380 } 9381 } 9382 Watchdog.getInstance().setAllowRestart(true); 9383 } 9384 } 9385 9386 @Override 9387 public void restart() { 9388 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 9389 != PackageManager.PERMISSION_GRANTED) { 9390 throw new SecurityException("Requires permission " 9391 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 9392 } 9393 9394 Log.i(TAG, "Sending shutdown broadcast..."); 9395 9396 BroadcastReceiver br = new BroadcastReceiver() { 9397 @Override public void onReceive(Context context, Intent intent) { 9398 // Now the broadcast is done, finish up the low-level shutdown. 9399 Log.i(TAG, "Shutting down activity manager..."); 9400 shutdown(10000); 9401 Log.i(TAG, "Shutdown complete, restarting!"); 9402 Process.killProcess(Process.myPid()); 9403 System.exit(10); 9404 } 9405 }; 9406 9407 // First send the high-level shut down broadcast. 9408 Intent intent = new Intent(Intent.ACTION_SHUTDOWN); 9409 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 9410 intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true); 9411 /* For now we are not doing a clean shutdown, because things seem to get unhappy. 9412 mContext.sendOrderedBroadcastAsUser(intent, 9413 UserHandle.ALL, null, br, mHandler, 0, null, null); 9414 */ 9415 br.onReceive(mContext, intent); 9416 } 9417 9418 private long getLowRamTimeSinceIdle(long now) { 9419 return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0); 9420 } 9421 9422 @Override 9423 public void performIdleMaintenance() { 9424 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 9425 != PackageManager.PERMISSION_GRANTED) { 9426 throw new SecurityException("Requires permission " 9427 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 9428 } 9429 9430 synchronized (this) { 9431 final long now = SystemClock.uptimeMillis(); 9432 final long timeSinceLastIdle = now - mLastIdleTime; 9433 final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now); 9434 mLastIdleTime = now; 9435 mLowRamTimeSinceLastIdle = 0; 9436 if (mLowRamStartTime != 0) { 9437 mLowRamStartTime = now; 9438 } 9439 9440 StringBuilder sb = new StringBuilder(128); 9441 sb.append("Idle maintenance over "); 9442 TimeUtils.formatDuration(timeSinceLastIdle, sb); 9443 sb.append(" low RAM for "); 9444 TimeUtils.formatDuration(lowRamSinceLastIdle, sb); 9445 Slog.i(TAG, sb.toString()); 9446 9447 // If at least 1/3 of our time since the last idle period has been spent 9448 // with RAM low, then we want to kill processes. 9449 boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3); 9450 9451 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 9452 ProcessRecord proc = mLruProcesses.get(i); 9453 if (proc.notCachedSinceIdle) { 9454 if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP 9455 && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) { 9456 if (doKilling && proc.initialIdlePss != 0 9457 && proc.lastPss > ((proc.initialIdlePss*3)/2)) { 9458 killUnneededProcessLocked(proc, "idle maint (pss " + proc.lastPss 9459 + " from " + proc.initialIdlePss + ")"); 9460 } 9461 } 9462 } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) { 9463 proc.notCachedSinceIdle = true; 9464 proc.initialIdlePss = 0; 9465 proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true, 9466 isSleeping(), now); 9467 } 9468 } 9469 9470 mHandler.removeMessages(REQUEST_ALL_PSS_MSG); 9471 mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000); 9472 } 9473 } 9474 9475 private void retrieveSettings() { 9476 final ContentResolver resolver = mContext.getContentResolver(); 9477 String debugApp = Settings.Global.getString( 9478 resolver, Settings.Global.DEBUG_APP); 9479 boolean waitForDebugger = Settings.Global.getInt( 9480 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0; 9481 boolean alwaysFinishActivities = Settings.Global.getInt( 9482 resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0; 9483 boolean forceRtl = Settings.Global.getInt( 9484 resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0; 9485 // Transfer any global setting for forcing RTL layout, into a System Property 9486 SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0"); 9487 9488 Configuration configuration = new Configuration(); 9489 Settings.System.getConfiguration(resolver, configuration); 9490 if (forceRtl) { 9491 // This will take care of setting the correct layout direction flags 9492 configuration.setLayoutDirection(configuration.locale); 9493 } 9494 9495 synchronized (this) { 9496 mDebugApp = mOrigDebugApp = debugApp; 9497 mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger; 9498 mAlwaysFinishActivities = alwaysFinishActivities; 9499 // This happens before any activities are started, so we can 9500 // change mConfiguration in-place. 9501 updateConfigurationLocked(configuration, null, false, true); 9502 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration); 9503 } 9504 } 9505 9506 public boolean testIsSystemReady() { 9507 // no need to synchronize(this) just to read & return the value 9508 return mSystemReady; 9509 } 9510 9511 private static File getCalledPreBootReceiversFile() { 9512 File dataDir = Environment.getDataDirectory(); 9513 File systemDir = new File(dataDir, "system"); 9514 File fname = new File(systemDir, "called_pre_boots.dat"); 9515 return fname; 9516 } 9517 9518 static final int LAST_DONE_VERSION = 10000; 9519 9520 private static ArrayList<ComponentName> readLastDonePreBootReceivers() { 9521 ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>(); 9522 File file = getCalledPreBootReceiversFile(); 9523 FileInputStream fis = null; 9524 try { 9525 fis = new FileInputStream(file); 9526 DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048)); 9527 int fvers = dis.readInt(); 9528 if (fvers == LAST_DONE_VERSION) { 9529 String vers = dis.readUTF(); 9530 String codename = dis.readUTF(); 9531 String build = dis.readUTF(); 9532 if (android.os.Build.VERSION.RELEASE.equals(vers) 9533 && android.os.Build.VERSION.CODENAME.equals(codename) 9534 && android.os.Build.VERSION.INCREMENTAL.equals(build)) { 9535 int num = dis.readInt(); 9536 while (num > 0) { 9537 num--; 9538 String pkg = dis.readUTF(); 9539 String cls = dis.readUTF(); 9540 lastDoneReceivers.add(new ComponentName(pkg, cls)); 9541 } 9542 } 9543 } 9544 } catch (FileNotFoundException e) { 9545 } catch (IOException e) { 9546 Slog.w(TAG, "Failure reading last done pre-boot receivers", e); 9547 } finally { 9548 if (fis != null) { 9549 try { 9550 fis.close(); 9551 } catch (IOException e) { 9552 } 9553 } 9554 } 9555 return lastDoneReceivers; 9556 } 9557 9558 private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) { 9559 File file = getCalledPreBootReceiversFile(); 9560 FileOutputStream fos = null; 9561 DataOutputStream dos = null; 9562 try { 9563 Slog.i(TAG, "Writing new set of last done pre-boot receivers..."); 9564 fos = new FileOutputStream(file); 9565 dos = new DataOutputStream(new BufferedOutputStream(fos, 2048)); 9566 dos.writeInt(LAST_DONE_VERSION); 9567 dos.writeUTF(android.os.Build.VERSION.RELEASE); 9568 dos.writeUTF(android.os.Build.VERSION.CODENAME); 9569 dos.writeUTF(android.os.Build.VERSION.INCREMENTAL); 9570 dos.writeInt(list.size()); 9571 for (int i=0; i<list.size(); i++) { 9572 dos.writeUTF(list.get(i).getPackageName()); 9573 dos.writeUTF(list.get(i).getClassName()); 9574 } 9575 } catch (IOException e) { 9576 Slog.w(TAG, "Failure writing last done pre-boot receivers", e); 9577 file.delete(); 9578 } finally { 9579 FileUtils.sync(fos); 9580 if (dos != null) { 9581 try { 9582 dos.close(); 9583 } catch (IOException e) { 9584 // TODO Auto-generated catch block 9585 e.printStackTrace(); 9586 } 9587 } 9588 } 9589 } 9590 9591 public void systemReady(final Runnable goingCallback) { 9592 synchronized(this) { 9593 if (mSystemReady) { 9594 if (goingCallback != null) goingCallback.run(); 9595 return; 9596 } 9597 9598 if (mRecentTasks == null) { 9599 mRecentTasks = mTaskPersister.restoreTasksLocked(); 9600 if (!mRecentTasks.isEmpty()) { 9601 mStackSupervisor.createStackForRestoredTaskHistory(mRecentTasks); 9602 } 9603 mTaskPersister.startPersisting(); 9604 } 9605 9606 // Check to see if there are any update receivers to run. 9607 if (!mDidUpdate) { 9608 if (mWaitingUpdate) { 9609 return; 9610 } 9611 Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED); 9612 List<ResolveInfo> ris = null; 9613 try { 9614 ris = AppGlobals.getPackageManager().queryIntentReceivers( 9615 intent, null, 0, 0); 9616 } catch (RemoteException e) { 9617 } 9618 if (ris != null) { 9619 for (int i=ris.size()-1; i>=0; i--) { 9620 if ((ris.get(i).activityInfo.applicationInfo.flags 9621 &ApplicationInfo.FLAG_SYSTEM) == 0) { 9622 ris.remove(i); 9623 } 9624 } 9625 intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE); 9626 9627 ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers(); 9628 9629 final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>(); 9630 for (int i=0; i<ris.size(); i++) { 9631 ActivityInfo ai = ris.get(i).activityInfo; 9632 ComponentName comp = new ComponentName(ai.packageName, ai.name); 9633 if (lastDoneReceivers.contains(comp)) { 9634 // We already did the pre boot receiver for this app with the current 9635 // platform version, so don't do it again... 9636 ris.remove(i); 9637 i--; 9638 // ...however, do keep it as one that has been done, so we don't 9639 // forget about it when rewriting the file of last done receivers. 9640 doneReceivers.add(comp); 9641 } 9642 } 9643 9644 final int[] users = getUsersLocked(); 9645 for (int i=0; i<ris.size(); i++) { 9646 ActivityInfo ai = ris.get(i).activityInfo; 9647 ComponentName comp = new ComponentName(ai.packageName, ai.name); 9648 doneReceivers.add(comp); 9649 intent.setComponent(comp); 9650 for (int j=0; j<users.length; j++) { 9651 IIntentReceiver finisher = null; 9652 if (i == ris.size()-1 && j == users.length-1) { 9653 finisher = new IIntentReceiver.Stub() { 9654 public void performReceive(Intent intent, int resultCode, 9655 String data, Bundle extras, boolean ordered, 9656 boolean sticky, int sendingUser) { 9657 // The raw IIntentReceiver interface is called 9658 // with the AM lock held, so redispatch to 9659 // execute our code without the lock. 9660 mHandler.post(new Runnable() { 9661 public void run() { 9662 synchronized (ActivityManagerService.this) { 9663 mDidUpdate = true; 9664 } 9665 writeLastDonePreBootReceivers(doneReceivers); 9666 showBootMessage(mContext.getText( 9667 R.string.android_upgrading_complete), 9668 false); 9669 systemReady(goingCallback); 9670 } 9671 }); 9672 } 9673 }; 9674 } 9675 Slog.i(TAG, "Sending system update to " + intent.getComponent() 9676 + " for user " + users[j]); 9677 broadcastIntentLocked(null, null, intent, null, finisher, 9678 0, null, null, null, AppOpsManager.OP_NONE, 9679 true, false, MY_PID, Process.SYSTEM_UID, 9680 users[j]); 9681 if (finisher != null) { 9682 mWaitingUpdate = true; 9683 } 9684 } 9685 } 9686 } 9687 if (mWaitingUpdate) { 9688 return; 9689 } 9690 mDidUpdate = true; 9691 } 9692 9693 mAppOpsService.systemReady(); 9694 mUsageStatsService.systemReady(); 9695 mSystemReady = true; 9696 } 9697 9698 ArrayList<ProcessRecord> procsToKill = null; 9699 synchronized(mPidsSelfLocked) { 9700 for (int i=mPidsSelfLocked.size()-1; i>=0; i--) { 9701 ProcessRecord proc = mPidsSelfLocked.valueAt(i); 9702 if (!isAllowedWhileBooting(proc.info)){ 9703 if (procsToKill == null) { 9704 procsToKill = new ArrayList<ProcessRecord>(); 9705 } 9706 procsToKill.add(proc); 9707 } 9708 } 9709 } 9710 9711 synchronized(this) { 9712 if (procsToKill != null) { 9713 for (int i=procsToKill.size()-1; i>=0; i--) { 9714 ProcessRecord proc = procsToKill.get(i); 9715 Slog.i(TAG, "Removing system update proc: " + proc); 9716 removeProcessLocked(proc, true, false, "system update done"); 9717 } 9718 } 9719 9720 // Now that we have cleaned up any update processes, we 9721 // are ready to start launching real processes and know that 9722 // we won't trample on them any more. 9723 mProcessesReady = true; 9724 } 9725 9726 Slog.i(TAG, "System now ready"); 9727 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY, 9728 SystemClock.uptimeMillis()); 9729 9730 synchronized(this) { 9731 // Make sure we have no pre-ready processes sitting around. 9732 9733 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) { 9734 ResolveInfo ri = mContext.getPackageManager() 9735 .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST), 9736 STOCK_PM_FLAGS); 9737 CharSequence errorMsg = null; 9738 if (ri != null) { 9739 ActivityInfo ai = ri.activityInfo; 9740 ApplicationInfo app = ai.applicationInfo; 9741 if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) { 9742 mTopAction = Intent.ACTION_FACTORY_TEST; 9743 mTopData = null; 9744 mTopComponent = new ComponentName(app.packageName, 9745 ai.name); 9746 } else { 9747 errorMsg = mContext.getResources().getText( 9748 com.android.internal.R.string.factorytest_not_system); 9749 } 9750 } else { 9751 errorMsg = mContext.getResources().getText( 9752 com.android.internal.R.string.factorytest_no_action); 9753 } 9754 if (errorMsg != null) { 9755 mTopAction = null; 9756 mTopData = null; 9757 mTopComponent = null; 9758 Message msg = Message.obtain(); 9759 msg.what = SHOW_FACTORY_ERROR_MSG; 9760 msg.getData().putCharSequence("msg", errorMsg); 9761 mHandler.sendMessage(msg); 9762 } 9763 } 9764 } 9765 9766 retrieveSettings(); 9767 9768 synchronized (this) { 9769 readGrantedUriPermissionsLocked(); 9770 } 9771 9772 if (goingCallback != null) goingCallback.run(); 9773 9774 mSystemServiceManager.startUser(mCurrentUserId); 9775 9776 synchronized (this) { 9777 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 9778 try { 9779 List apps = AppGlobals.getPackageManager(). 9780 getPersistentApplications(STOCK_PM_FLAGS); 9781 if (apps != null) { 9782 int N = apps.size(); 9783 int i; 9784 for (i=0; i<N; i++) { 9785 ApplicationInfo info 9786 = (ApplicationInfo)apps.get(i); 9787 if (info != null && 9788 !info.packageName.equals("android")) { 9789 addAppLocked(info, false); 9790 } 9791 } 9792 } 9793 } catch (RemoteException ex) { 9794 // pm is in same process, this will never happen. 9795 } 9796 } 9797 9798 // Start up initial activity. 9799 mBooting = true; 9800 9801 try { 9802 if (AppGlobals.getPackageManager().hasSystemUidErrors()) { 9803 Message msg = Message.obtain(); 9804 msg.what = SHOW_UID_ERROR_MSG; 9805 mHandler.sendMessage(msg); 9806 } 9807 } catch (RemoteException e) { 9808 } 9809 9810 long ident = Binder.clearCallingIdentity(); 9811 try { 9812 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 9813 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 9814 | Intent.FLAG_RECEIVER_FOREGROUND); 9815 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); 9816 broadcastIntentLocked(null, null, intent, 9817 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 9818 false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId); 9819 intent = new Intent(Intent.ACTION_USER_STARTING); 9820 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 9821 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); 9822 broadcastIntentLocked(null, null, intent, 9823 null, new IIntentReceiver.Stub() { 9824 @Override 9825 public void performReceive(Intent intent, int resultCode, String data, 9826 Bundle extras, boolean ordered, boolean sticky, int sendingUser) 9827 throws RemoteException { 9828 } 9829 }, 0, null, null, 9830 android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 9831 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 9832 } catch (Throwable t) { 9833 Slog.wtf(TAG, "Failed sending first user broadcasts", t); 9834 } finally { 9835 Binder.restoreCallingIdentity(ident); 9836 } 9837 mStackSupervisor.resumeTopActivitiesLocked(); 9838 sendUserSwitchBroadcastsLocked(-1, mCurrentUserId); 9839 } 9840 } 9841 9842 private boolean makeAppCrashingLocked(ProcessRecord app, 9843 String shortMsg, String longMsg, String stackTrace) { 9844 app.crashing = true; 9845 app.crashingReport = generateProcessError(app, 9846 ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace); 9847 startAppProblemLocked(app); 9848 app.stopFreezingAllLocked(); 9849 return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace); 9850 } 9851 9852 private void makeAppNotRespondingLocked(ProcessRecord app, 9853 String activity, String shortMsg, String longMsg) { 9854 app.notResponding = true; 9855 app.notRespondingReport = generateProcessError(app, 9856 ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING, 9857 activity, shortMsg, longMsg, null); 9858 startAppProblemLocked(app); 9859 app.stopFreezingAllLocked(); 9860 } 9861 9862 /** 9863 * Generate a process error record, suitable for attachment to a ProcessRecord. 9864 * 9865 * @param app The ProcessRecord in which the error occurred. 9866 * @param condition Crashing, Application Not Responding, etc. Values are defined in 9867 * ActivityManager.AppErrorStateInfo 9868 * @param activity The activity associated with the crash, if known. 9869 * @param shortMsg Short message describing the crash. 9870 * @param longMsg Long message describing the crash. 9871 * @param stackTrace Full crash stack trace, may be null. 9872 * 9873 * @return Returns a fully-formed AppErrorStateInfo record. 9874 */ 9875 private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app, 9876 int condition, String activity, String shortMsg, String longMsg, String stackTrace) { 9877 ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo(); 9878 9879 report.condition = condition; 9880 report.processName = app.processName; 9881 report.pid = app.pid; 9882 report.uid = app.info.uid; 9883 report.tag = activity; 9884 report.shortMsg = shortMsg; 9885 report.longMsg = longMsg; 9886 report.stackTrace = stackTrace; 9887 9888 return report; 9889 } 9890 9891 void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) { 9892 synchronized (this) { 9893 app.crashing = false; 9894 app.crashingReport = null; 9895 app.notResponding = false; 9896 app.notRespondingReport = null; 9897 if (app.anrDialog == fromDialog) { 9898 app.anrDialog = null; 9899 } 9900 if (app.waitDialog == fromDialog) { 9901 app.waitDialog = null; 9902 } 9903 if (app.pid > 0 && app.pid != MY_PID) { 9904 handleAppCrashLocked(app, null, null, null); 9905 killUnneededProcessLocked(app, "user request after error"); 9906 } 9907 } 9908 } 9909 9910 private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg, 9911 String stackTrace) { 9912 long now = SystemClock.uptimeMillis(); 9913 9914 Long crashTime; 9915 if (!app.isolated) { 9916 crashTime = mProcessCrashTimes.get(app.info.processName, app.uid); 9917 } else { 9918 crashTime = null; 9919 } 9920 if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) { 9921 // This process loses! 9922 Slog.w(TAG, "Process " + app.info.processName 9923 + " has crashed too many times: killing!"); 9924 EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH, 9925 app.userId, app.info.processName, app.uid); 9926 mStackSupervisor.handleAppCrashLocked(app); 9927 if (!app.persistent) { 9928 // We don't want to start this process again until the user 9929 // explicitly does so... but for persistent process, we really 9930 // need to keep it running. If a persistent process is actually 9931 // repeatedly crashing, then badness for everyone. 9932 EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid, 9933 app.info.processName); 9934 if (!app.isolated) { 9935 // XXX We don't have a way to mark isolated processes 9936 // as bad, since they don't have a peristent identity. 9937 mBadProcesses.put(app.info.processName, app.uid, 9938 new BadProcessInfo(now, shortMsg, longMsg, stackTrace)); 9939 mProcessCrashTimes.remove(app.info.processName, app.uid); 9940 } 9941 app.bad = true; 9942 app.removed = true; 9943 // Don't let services in this process be restarted and potentially 9944 // annoy the user repeatedly. Unless it is persistent, since those 9945 // processes run critical code. 9946 removeProcessLocked(app, false, false, "crash"); 9947 mStackSupervisor.resumeTopActivitiesLocked(); 9948 return false; 9949 } 9950 mStackSupervisor.resumeTopActivitiesLocked(); 9951 } else { 9952 mStackSupervisor.finishTopRunningActivityLocked(app); 9953 } 9954 9955 // Bump up the crash count of any services currently running in the proc. 9956 for (int i=app.services.size()-1; i>=0; i--) { 9957 // Any services running in the application need to be placed 9958 // back in the pending list. 9959 ServiceRecord sr = app.services.valueAt(i); 9960 sr.crashCount++; 9961 } 9962 9963 // If the crashing process is what we consider to be the "home process" and it has been 9964 // replaced by a third-party app, clear the package preferred activities from packages 9965 // with a home activity running in the process to prevent a repeatedly crashing app 9966 // from blocking the user to manually clear the list. 9967 final ArrayList<ActivityRecord> activities = app.activities; 9968 if (app == mHomeProcess && activities.size() > 0 9969 && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) { 9970 for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) { 9971 final ActivityRecord r = activities.get(activityNdx); 9972 if (r.isHomeActivity()) { 9973 Log.i(TAG, "Clearing package preferred activities from " + r.packageName); 9974 try { 9975 ActivityThread.getPackageManager() 9976 .clearPackagePreferredActivities(r.packageName); 9977 } catch (RemoteException c) { 9978 // pm is in same process, this will never happen. 9979 } 9980 } 9981 } 9982 } 9983 9984 if (!app.isolated) { 9985 // XXX Can't keep track of crash times for isolated processes, 9986 // because they don't have a perisistent identity. 9987 mProcessCrashTimes.put(app.info.processName, app.uid, now); 9988 } 9989 9990 return true; 9991 } 9992 9993 void startAppProblemLocked(ProcessRecord app) { 9994 if (app.userId == mCurrentUserId) { 9995 app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver( 9996 mContext, app.info.packageName, app.info.flags); 9997 } else { 9998 // If this app is not running under the current user, then we 9999 // can't give it a report button because that would require 10000 // launching the report UI under a different user. 10001 app.errorReportReceiver = null; 10002 } 10003 skipCurrentReceiverLocked(app); 10004 } 10005 10006 void skipCurrentReceiverLocked(ProcessRecord app) { 10007 for (BroadcastQueue queue : mBroadcastQueues) { 10008 queue.skipCurrentReceiverLocked(app); 10009 } 10010 } 10011 10012 /** 10013 * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes. 10014 * The application process will exit immediately after this call returns. 10015 * @param app object of the crashing app, null for the system server 10016 * @param crashInfo describing the exception 10017 */ 10018 public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) { 10019 ProcessRecord r = findAppProcess(app, "Crash"); 10020 final String processName = app == null ? "system_server" 10021 : (r == null ? "unknown" : r.processName); 10022 10023 handleApplicationCrashInner("crash", r, processName, crashInfo); 10024 } 10025 10026 /* Native crash reporting uses this inner version because it needs to be somewhat 10027 * decoupled from the AM-managed cleanup lifecycle 10028 */ 10029 void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName, 10030 ApplicationErrorReport.CrashInfo crashInfo) { 10031 EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(), 10032 UserHandle.getUserId(Binder.getCallingUid()), processName, 10033 r == null ? -1 : r.info.flags, 10034 crashInfo.exceptionClassName, 10035 crashInfo.exceptionMessage, 10036 crashInfo.throwFileName, 10037 crashInfo.throwLineNumber); 10038 10039 addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo); 10040 10041 crashApplication(r, crashInfo); 10042 } 10043 10044 public void handleApplicationStrictModeViolation( 10045 IBinder app, 10046 int violationMask, 10047 StrictMode.ViolationInfo info) { 10048 ProcessRecord r = findAppProcess(app, "StrictMode"); 10049 if (r == null) { 10050 return; 10051 } 10052 10053 if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) { 10054 Integer stackFingerprint = info.hashCode(); 10055 boolean logIt = true; 10056 synchronized (mAlreadyLoggedViolatedStacks) { 10057 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) { 10058 logIt = false; 10059 // TODO: sub-sample into EventLog for these, with 10060 // the info.durationMillis? Then we'd get 10061 // the relative pain numbers, without logging all 10062 // the stack traces repeatedly. We'd want to do 10063 // likewise in the client code, which also does 10064 // dup suppression, before the Binder call. 10065 } else { 10066 if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) { 10067 mAlreadyLoggedViolatedStacks.clear(); 10068 } 10069 mAlreadyLoggedViolatedStacks.add(stackFingerprint); 10070 } 10071 } 10072 if (logIt) { 10073 logStrictModeViolationToDropBox(r, info); 10074 } 10075 } 10076 10077 if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) { 10078 AppErrorResult result = new AppErrorResult(); 10079 synchronized (this) { 10080 final long origId = Binder.clearCallingIdentity(); 10081 10082 Message msg = Message.obtain(); 10083 msg.what = SHOW_STRICT_MODE_VIOLATION_MSG; 10084 HashMap<String, Object> data = new HashMap<String, Object>(); 10085 data.put("result", result); 10086 data.put("app", r); 10087 data.put("violationMask", violationMask); 10088 data.put("info", info); 10089 msg.obj = data; 10090 mHandler.sendMessage(msg); 10091 10092 Binder.restoreCallingIdentity(origId); 10093 } 10094 int res = result.get(); 10095 Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res); 10096 } 10097 } 10098 10099 // Depending on the policy in effect, there could be a bunch of 10100 // these in quick succession so we try to batch these together to 10101 // minimize disk writes, number of dropbox entries, and maximize 10102 // compression, by having more fewer, larger records. 10103 private void logStrictModeViolationToDropBox( 10104 ProcessRecord process, 10105 StrictMode.ViolationInfo info) { 10106 if (info == null) { 10107 return; 10108 } 10109 final boolean isSystemApp = process == null || 10110 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM | 10111 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0; 10112 final String processName = process == null ? "unknown" : process.processName; 10113 final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode"; 10114 final DropBoxManager dbox = (DropBoxManager) 10115 mContext.getSystemService(Context.DROPBOX_SERVICE); 10116 10117 // Exit early if the dropbox isn't configured to accept this report type. 10118 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 10119 10120 boolean bufferWasEmpty; 10121 boolean needsFlush; 10122 final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024); 10123 synchronized (sb) { 10124 bufferWasEmpty = sb.length() == 0; 10125 appendDropBoxProcessHeaders(process, processName, sb); 10126 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 10127 sb.append("System-App: ").append(isSystemApp).append("\n"); 10128 sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n"); 10129 if (info.violationNumThisLoop != 0) { 10130 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n"); 10131 } 10132 if (info.numAnimationsRunning != 0) { 10133 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n"); 10134 } 10135 if (info.broadcastIntentAction != null) { 10136 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n"); 10137 } 10138 if (info.durationMillis != -1) { 10139 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n"); 10140 } 10141 if (info.numInstances != -1) { 10142 sb.append("Instance-Count: ").append(info.numInstances).append("\n"); 10143 } 10144 if (info.tags != null) { 10145 for (String tag : info.tags) { 10146 sb.append("Span-Tag: ").append(tag).append("\n"); 10147 } 10148 } 10149 sb.append("\n"); 10150 if (info.crashInfo != null && info.crashInfo.stackTrace != null) { 10151 sb.append(info.crashInfo.stackTrace); 10152 } 10153 sb.append("\n"); 10154 10155 // Only buffer up to ~64k. Various logging bits truncate 10156 // things at 128k. 10157 needsFlush = (sb.length() > 64 * 1024); 10158 } 10159 10160 // Flush immediately if the buffer's grown too large, or this 10161 // is a non-system app. Non-system apps are isolated with a 10162 // different tag & policy and not batched. 10163 // 10164 // Batching is useful during internal testing with 10165 // StrictMode settings turned up high. Without batching, 10166 // thousands of separate files could be created on boot. 10167 if (!isSystemApp || needsFlush) { 10168 new Thread("Error dump: " + dropboxTag) { 10169 @Override 10170 public void run() { 10171 String report; 10172 synchronized (sb) { 10173 report = sb.toString(); 10174 sb.delete(0, sb.length()); 10175 sb.trimToSize(); 10176 } 10177 if (report.length() != 0) { 10178 dbox.addText(dropboxTag, report); 10179 } 10180 } 10181 }.start(); 10182 return; 10183 } 10184 10185 // System app batching: 10186 if (!bufferWasEmpty) { 10187 // An existing dropbox-writing thread is outstanding, so 10188 // we don't need to start it up. The existing thread will 10189 // catch the buffer appends we just did. 10190 return; 10191 } 10192 10193 // Worker thread to both batch writes and to avoid blocking the caller on I/O. 10194 // (After this point, we shouldn't access AMS internal data structures.) 10195 new Thread("Error dump: " + dropboxTag) { 10196 @Override 10197 public void run() { 10198 // 5 second sleep to let stacks arrive and be batched together 10199 try { 10200 Thread.sleep(5000); // 5 seconds 10201 } catch (InterruptedException e) {} 10202 10203 String errorReport; 10204 synchronized (mStrictModeBuffer) { 10205 errorReport = mStrictModeBuffer.toString(); 10206 if (errorReport.length() == 0) { 10207 return; 10208 } 10209 mStrictModeBuffer.delete(0, mStrictModeBuffer.length()); 10210 mStrictModeBuffer.trimToSize(); 10211 } 10212 dbox.addText(dropboxTag, errorReport); 10213 } 10214 }.start(); 10215 } 10216 10217 /** 10218 * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors. 10219 * @param app object of the crashing app, null for the system server 10220 * @param tag reported by the caller 10221 * @param crashInfo describing the context of the error 10222 * @return true if the process should exit immediately (WTF is fatal) 10223 */ 10224 public boolean handleApplicationWtf(IBinder app, String tag, 10225 ApplicationErrorReport.CrashInfo crashInfo) { 10226 ProcessRecord r = findAppProcess(app, "WTF"); 10227 final String processName = app == null ? "system_server" 10228 : (r == null ? "unknown" : r.processName); 10229 10230 EventLog.writeEvent(EventLogTags.AM_WTF, 10231 UserHandle.getUserId(Binder.getCallingUid()), Binder.getCallingPid(), 10232 processName, 10233 r == null ? -1 : r.info.flags, 10234 tag, crashInfo.exceptionMessage); 10235 10236 addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo); 10237 10238 if (r != null && r.pid != Process.myPid() && 10239 Settings.Global.getInt(mContext.getContentResolver(), 10240 Settings.Global.WTF_IS_FATAL, 0) != 0) { 10241 crashApplication(r, crashInfo); 10242 return true; 10243 } else { 10244 return false; 10245 } 10246 } 10247 10248 /** 10249 * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit}) 10250 * @return the corresponding {@link ProcessRecord} object, or null if none could be found 10251 */ 10252 private ProcessRecord findAppProcess(IBinder app, String reason) { 10253 if (app == null) { 10254 return null; 10255 } 10256 10257 synchronized (this) { 10258 final int NP = mProcessNames.getMap().size(); 10259 for (int ip=0; ip<NP; ip++) { 10260 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 10261 final int NA = apps.size(); 10262 for (int ia=0; ia<NA; ia++) { 10263 ProcessRecord p = apps.valueAt(ia); 10264 if (p.thread != null && p.thread.asBinder() == app) { 10265 return p; 10266 } 10267 } 10268 } 10269 10270 Slog.w(TAG, "Can't find mystery application for " + reason 10271 + " from pid=" + Binder.getCallingPid() 10272 + " uid=" + Binder.getCallingUid() + ": " + app); 10273 return null; 10274 } 10275 } 10276 10277 /** 10278 * Utility function for addErrorToDropBox and handleStrictModeViolation's logging 10279 * to append various headers to the dropbox log text. 10280 */ 10281 private void appendDropBoxProcessHeaders(ProcessRecord process, String processName, 10282 StringBuilder sb) { 10283 // Watchdog thread ends up invoking this function (with 10284 // a null ProcessRecord) to add the stack file to dropbox. 10285 // Do not acquire a lock on this (am) in such cases, as it 10286 // could cause a potential deadlock, if and when watchdog 10287 // is invoked due to unavailability of lock on am and it 10288 // would prevent watchdog from killing system_server. 10289 if (process == null) { 10290 sb.append("Process: ").append(processName).append("\n"); 10291 return; 10292 } 10293 // Note: ProcessRecord 'process' is guarded by the service 10294 // instance. (notably process.pkgList, which could otherwise change 10295 // concurrently during execution of this method) 10296 synchronized (this) { 10297 sb.append("Process: ").append(processName).append("\n"); 10298 int flags = process.info.flags; 10299 IPackageManager pm = AppGlobals.getPackageManager(); 10300 sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n"); 10301 for (int ip=0; ip<process.pkgList.size(); ip++) { 10302 String pkg = process.pkgList.keyAt(ip); 10303 sb.append("Package: ").append(pkg); 10304 try { 10305 PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId()); 10306 if (pi != null) { 10307 sb.append(" v").append(pi.versionCode); 10308 if (pi.versionName != null) { 10309 sb.append(" (").append(pi.versionName).append(")"); 10310 } 10311 } 10312 } catch (RemoteException e) { 10313 Slog.e(TAG, "Error getting package info: " + pkg, e); 10314 } 10315 sb.append("\n"); 10316 } 10317 } 10318 } 10319 10320 private static String processClass(ProcessRecord process) { 10321 if (process == null || process.pid == MY_PID) { 10322 return "system_server"; 10323 } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) { 10324 return "system_app"; 10325 } else { 10326 return "data_app"; 10327 } 10328 } 10329 10330 /** 10331 * Write a description of an error (crash, WTF, ANR) to the drop box. 10332 * @param eventType to include in the drop box tag ("crash", "wtf", etc.) 10333 * @param process which caused the error, null means the system server 10334 * @param activity which triggered the error, null if unknown 10335 * @param parent activity related to the error, null if unknown 10336 * @param subject line related to the error, null if absent 10337 * @param report in long form describing the error, null if absent 10338 * @param logFile to include in the report, null if none 10339 * @param crashInfo giving an application stack trace, null if absent 10340 */ 10341 public void addErrorToDropBox(String eventType, 10342 ProcessRecord process, String processName, ActivityRecord activity, 10343 ActivityRecord parent, String subject, 10344 final String report, final File logFile, 10345 final ApplicationErrorReport.CrashInfo crashInfo) { 10346 // NOTE -- this must never acquire the ActivityManagerService lock, 10347 // otherwise the watchdog may be prevented from resetting the system. 10348 10349 final String dropboxTag = processClass(process) + "_" + eventType; 10350 final DropBoxManager dbox = (DropBoxManager) 10351 mContext.getSystemService(Context.DROPBOX_SERVICE); 10352 10353 // Exit early if the dropbox isn't configured to accept this report type. 10354 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 10355 10356 final StringBuilder sb = new StringBuilder(1024); 10357 appendDropBoxProcessHeaders(process, processName, sb); 10358 if (activity != null) { 10359 sb.append("Activity: ").append(activity.shortComponentName).append("\n"); 10360 } 10361 if (parent != null && parent.app != null && parent.app.pid != process.pid) { 10362 sb.append("Parent-Process: ").append(parent.app.processName).append("\n"); 10363 } 10364 if (parent != null && parent != activity) { 10365 sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n"); 10366 } 10367 if (subject != null) { 10368 sb.append("Subject: ").append(subject).append("\n"); 10369 } 10370 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 10371 if (Debug.isDebuggerConnected()) { 10372 sb.append("Debugger: Connected\n"); 10373 } 10374 sb.append("\n"); 10375 10376 // Do the rest in a worker thread to avoid blocking the caller on I/O 10377 // (After this point, we shouldn't access AMS internal data structures.) 10378 Thread worker = new Thread("Error dump: " + dropboxTag) { 10379 @Override 10380 public void run() { 10381 if (report != null) { 10382 sb.append(report); 10383 } 10384 if (logFile != null) { 10385 try { 10386 sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE, 10387 "\n\n[[TRUNCATED]]")); 10388 } catch (IOException e) { 10389 Slog.e(TAG, "Error reading " + logFile, e); 10390 } 10391 } 10392 if (crashInfo != null && crashInfo.stackTrace != null) { 10393 sb.append(crashInfo.stackTrace); 10394 } 10395 10396 String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag; 10397 int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0); 10398 if (lines > 0) { 10399 sb.append("\n"); 10400 10401 // Merge several logcat streams, and take the last N lines 10402 InputStreamReader input = null; 10403 try { 10404 java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat", 10405 "-v", "time", "-b", "events", "-b", "system", "-b", "main", 10406 "-t", String.valueOf(lines)).redirectErrorStream(true).start(); 10407 10408 try { logcat.getOutputStream().close(); } catch (IOException e) {} 10409 try { logcat.getErrorStream().close(); } catch (IOException e) {} 10410 input = new InputStreamReader(logcat.getInputStream()); 10411 10412 int num; 10413 char[] buf = new char[8192]; 10414 while ((num = input.read(buf)) > 0) sb.append(buf, 0, num); 10415 } catch (IOException e) { 10416 Slog.e(TAG, "Error running logcat", e); 10417 } finally { 10418 if (input != null) try { input.close(); } catch (IOException e) {} 10419 } 10420 } 10421 10422 dbox.addText(dropboxTag, sb.toString()); 10423 } 10424 }; 10425 10426 if (process == null) { 10427 // If process is null, we are being called from some internal code 10428 // and may be about to die -- run this synchronously. 10429 worker.run(); 10430 } else { 10431 worker.start(); 10432 } 10433 } 10434 10435 /** 10436 * Bring up the "unexpected error" dialog box for a crashing app. 10437 * Deal with edge cases (intercepts from instrumented applications, 10438 * ActivityController, error intent receivers, that sort of thing). 10439 * @param r the application crashing 10440 * @param crashInfo describing the failure 10441 */ 10442 private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) { 10443 long timeMillis = System.currentTimeMillis(); 10444 String shortMsg = crashInfo.exceptionClassName; 10445 String longMsg = crashInfo.exceptionMessage; 10446 String stackTrace = crashInfo.stackTrace; 10447 if (shortMsg != null && longMsg != null) { 10448 longMsg = shortMsg + ": " + longMsg; 10449 } else if (shortMsg != null) { 10450 longMsg = shortMsg; 10451 } 10452 10453 AppErrorResult result = new AppErrorResult(); 10454 synchronized (this) { 10455 if (mController != null) { 10456 try { 10457 String name = r != null ? r.processName : null; 10458 int pid = r != null ? r.pid : Binder.getCallingPid(); 10459 if (!mController.appCrashed(name, pid, 10460 shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) { 10461 Slog.w(TAG, "Force-killing crashed app " + name 10462 + " at watcher's request"); 10463 Process.killProcess(pid); 10464 return; 10465 } 10466 } catch (RemoteException e) { 10467 mController = null; 10468 Watchdog.getInstance().setActivityController(null); 10469 } 10470 } 10471 10472 final long origId = Binder.clearCallingIdentity(); 10473 10474 // If this process is running instrumentation, finish it. 10475 if (r != null && r.instrumentationClass != null) { 10476 Slog.w(TAG, "Error in app " + r.processName 10477 + " running instrumentation " + r.instrumentationClass + ":"); 10478 if (shortMsg != null) Slog.w(TAG, " " + shortMsg); 10479 if (longMsg != null) Slog.w(TAG, " " + longMsg); 10480 Bundle info = new Bundle(); 10481 info.putString("shortMsg", shortMsg); 10482 info.putString("longMsg", longMsg); 10483 finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info); 10484 Binder.restoreCallingIdentity(origId); 10485 return; 10486 } 10487 10488 // If we can't identify the process or it's already exceeded its crash quota, 10489 // quit right away without showing a crash dialog. 10490 if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) { 10491 Binder.restoreCallingIdentity(origId); 10492 return; 10493 } 10494 10495 Message msg = Message.obtain(); 10496 msg.what = SHOW_ERROR_MSG; 10497 HashMap data = new HashMap(); 10498 data.put("result", result); 10499 data.put("app", r); 10500 msg.obj = data; 10501 mHandler.sendMessage(msg); 10502 10503 Binder.restoreCallingIdentity(origId); 10504 } 10505 10506 int res = result.get(); 10507 10508 Intent appErrorIntent = null; 10509 synchronized (this) { 10510 if (r != null && !r.isolated) { 10511 // XXX Can't keep track of crash time for isolated processes, 10512 // since they don't have a persistent identity. 10513 mProcessCrashTimes.put(r.info.processName, r.uid, 10514 SystemClock.uptimeMillis()); 10515 } 10516 if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) { 10517 appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo); 10518 } 10519 } 10520 10521 if (appErrorIntent != null) { 10522 try { 10523 mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId)); 10524 } catch (ActivityNotFoundException e) { 10525 Slog.w(TAG, "bug report receiver dissappeared", e); 10526 } 10527 } 10528 } 10529 10530 Intent createAppErrorIntentLocked(ProcessRecord r, 10531 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 10532 ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo); 10533 if (report == null) { 10534 return null; 10535 } 10536 Intent result = new Intent(Intent.ACTION_APP_ERROR); 10537 result.setComponent(r.errorReportReceiver); 10538 result.putExtra(Intent.EXTRA_BUG_REPORT, report); 10539 result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 10540 return result; 10541 } 10542 10543 private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r, 10544 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 10545 if (r.errorReportReceiver == null) { 10546 return null; 10547 } 10548 10549 if (!r.crashing && !r.notResponding && !r.forceCrashReport) { 10550 return null; 10551 } 10552 10553 ApplicationErrorReport report = new ApplicationErrorReport(); 10554 report.packageName = r.info.packageName; 10555 report.installerPackageName = r.errorReportReceiver.getPackageName(); 10556 report.processName = r.processName; 10557 report.time = timeMillis; 10558 report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0; 10559 10560 if (r.crashing || r.forceCrashReport) { 10561 report.type = ApplicationErrorReport.TYPE_CRASH; 10562 report.crashInfo = crashInfo; 10563 } else if (r.notResponding) { 10564 report.type = ApplicationErrorReport.TYPE_ANR; 10565 report.anrInfo = new ApplicationErrorReport.AnrInfo(); 10566 10567 report.anrInfo.activity = r.notRespondingReport.tag; 10568 report.anrInfo.cause = r.notRespondingReport.shortMsg; 10569 report.anrInfo.info = r.notRespondingReport.longMsg; 10570 } 10571 10572 return report; 10573 } 10574 10575 public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() { 10576 enforceNotIsolatedCaller("getProcessesInErrorState"); 10577 // assume our apps are happy - lazy create the list 10578 List<ActivityManager.ProcessErrorStateInfo> errList = null; 10579 10580 final boolean allUsers = ActivityManager.checkUidPermission( 10581 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 10582 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 10583 int userId = UserHandle.getUserId(Binder.getCallingUid()); 10584 10585 synchronized (this) { 10586 10587 // iterate across all processes 10588 for (int i=mLruProcesses.size()-1; i>=0; i--) { 10589 ProcessRecord app = mLruProcesses.get(i); 10590 if (!allUsers && app.userId != userId) { 10591 continue; 10592 } 10593 if ((app.thread != null) && (app.crashing || app.notResponding)) { 10594 // This one's in trouble, so we'll generate a report for it 10595 // crashes are higher priority (in case there's a crash *and* an anr) 10596 ActivityManager.ProcessErrorStateInfo report = null; 10597 if (app.crashing) { 10598 report = app.crashingReport; 10599 } else if (app.notResponding) { 10600 report = app.notRespondingReport; 10601 } 10602 10603 if (report != null) { 10604 if (errList == null) { 10605 errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1); 10606 } 10607 errList.add(report); 10608 } else { 10609 Slog.w(TAG, "Missing app error report, app = " + app.processName + 10610 " crashing = " + app.crashing + 10611 " notResponding = " + app.notResponding); 10612 } 10613 } 10614 } 10615 } 10616 10617 return errList; 10618 } 10619 10620 static int oomAdjToImportance(int adj, ActivityManager.RunningAppProcessInfo currApp) { 10621 if (adj >= ProcessList.CACHED_APP_MIN_ADJ) { 10622 if (currApp != null) { 10623 currApp.lru = adj - ProcessList.CACHED_APP_MIN_ADJ + 1; 10624 } 10625 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 10626 } else if (adj >= ProcessList.SERVICE_B_ADJ) { 10627 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 10628 } else if (adj >= ProcessList.HOME_APP_ADJ) { 10629 if (currApp != null) { 10630 currApp.lru = 0; 10631 } 10632 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 10633 } else if (adj >= ProcessList.SERVICE_ADJ) { 10634 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 10635 } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 10636 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE; 10637 } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) { 10638 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE; 10639 } else if (adj >= ProcessList.VISIBLE_APP_ADJ) { 10640 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE; 10641 } else { 10642 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND; 10643 } 10644 } 10645 10646 private void fillInProcMemInfo(ProcessRecord app, 10647 ActivityManager.RunningAppProcessInfo outInfo) { 10648 outInfo.pid = app.pid; 10649 outInfo.uid = app.info.uid; 10650 if (mHeavyWeightProcess == app) { 10651 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE; 10652 } 10653 if (app.persistent) { 10654 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT; 10655 } 10656 if (app.activities.size() > 0) { 10657 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES; 10658 } 10659 outInfo.lastTrimLevel = app.trimMemoryLevel; 10660 int adj = app.curAdj; 10661 outInfo.importance = oomAdjToImportance(adj, outInfo); 10662 outInfo.importanceReasonCode = app.adjTypeCode; 10663 outInfo.processState = app.curProcState; 10664 } 10665 10666 public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() { 10667 enforceNotIsolatedCaller("getRunningAppProcesses"); 10668 // Lazy instantiation of list 10669 List<ActivityManager.RunningAppProcessInfo> runList = null; 10670 final boolean allUsers = ActivityManager.checkUidPermission( 10671 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 10672 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 10673 int userId = UserHandle.getUserId(Binder.getCallingUid()); 10674 synchronized (this) { 10675 // Iterate across all processes 10676 for (int i=mLruProcesses.size()-1; i>=0; i--) { 10677 ProcessRecord app = mLruProcesses.get(i); 10678 if (!allUsers && app.userId != userId) { 10679 continue; 10680 } 10681 if ((app.thread != null) && (!app.crashing && !app.notResponding)) { 10682 // Generate process state info for running application 10683 ActivityManager.RunningAppProcessInfo currApp = 10684 new ActivityManager.RunningAppProcessInfo(app.processName, 10685 app.pid, app.getPackageList()); 10686 fillInProcMemInfo(app, currApp); 10687 if (app.adjSource instanceof ProcessRecord) { 10688 currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid; 10689 currApp.importanceReasonImportance = oomAdjToImportance( 10690 app.adjSourceOom, null); 10691 } else if (app.adjSource instanceof ActivityRecord) { 10692 ActivityRecord r = (ActivityRecord)app.adjSource; 10693 if (r.app != null) currApp.importanceReasonPid = r.app.pid; 10694 } 10695 if (app.adjTarget instanceof ComponentName) { 10696 currApp.importanceReasonComponent = (ComponentName)app.adjTarget; 10697 } 10698 //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance 10699 // + " lru=" + currApp.lru); 10700 if (runList == null) { 10701 runList = new ArrayList<ActivityManager.RunningAppProcessInfo>(); 10702 } 10703 runList.add(currApp); 10704 } 10705 } 10706 } 10707 return runList; 10708 } 10709 10710 public List<ApplicationInfo> getRunningExternalApplications() { 10711 enforceNotIsolatedCaller("getRunningExternalApplications"); 10712 List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses(); 10713 List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>(); 10714 if (runningApps != null && runningApps.size() > 0) { 10715 Set<String> extList = new HashSet<String>(); 10716 for (ActivityManager.RunningAppProcessInfo app : runningApps) { 10717 if (app.pkgList != null) { 10718 for (String pkg : app.pkgList) { 10719 extList.add(pkg); 10720 } 10721 } 10722 } 10723 IPackageManager pm = AppGlobals.getPackageManager(); 10724 for (String pkg : extList) { 10725 try { 10726 ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId()); 10727 if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) { 10728 retList.add(info); 10729 } 10730 } catch (RemoteException e) { 10731 } 10732 } 10733 } 10734 return retList; 10735 } 10736 10737 @Override 10738 public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) { 10739 enforceNotIsolatedCaller("getMyMemoryState"); 10740 synchronized (this) { 10741 ProcessRecord proc; 10742 synchronized (mPidsSelfLocked) { 10743 proc = mPidsSelfLocked.get(Binder.getCallingPid()); 10744 } 10745 fillInProcMemInfo(proc, outInfo); 10746 } 10747 } 10748 10749 @Override 10750 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 10751 if (checkCallingPermission(android.Manifest.permission.DUMP) 10752 != PackageManager.PERMISSION_GRANTED) { 10753 pw.println("Permission Denial: can't dump ActivityManager from from pid=" 10754 + Binder.getCallingPid() 10755 + ", uid=" + Binder.getCallingUid() 10756 + " without permission " 10757 + android.Manifest.permission.DUMP); 10758 return; 10759 } 10760 10761 boolean dumpAll = false; 10762 boolean dumpClient = false; 10763 String dumpPackage = null; 10764 10765 int opti = 0; 10766 while (opti < args.length) { 10767 String opt = args[opti]; 10768 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 10769 break; 10770 } 10771 opti++; 10772 if ("-a".equals(opt)) { 10773 dumpAll = true; 10774 } else if ("-c".equals(opt)) { 10775 dumpClient = true; 10776 } else if ("-h".equals(opt)) { 10777 pw.println("Activity manager dump options:"); 10778 pw.println(" [-a] [-c] [-h] [cmd] ..."); 10779 pw.println(" cmd may be one of:"); 10780 pw.println(" a[ctivities]: activity stack state"); 10781 pw.println(" b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state"); 10782 pw.println(" i[ntents] [PACKAGE_NAME]: pending intent state"); 10783 pw.println(" p[rocesses] [PACKAGE_NAME]: process state"); 10784 pw.println(" o[om]: out of memory management"); 10785 pw.println(" prov[iders] [COMP_SPEC ...]: content provider state"); 10786 pw.println(" provider [COMP_SPEC]: provider client-side state"); 10787 pw.println(" s[ervices] [COMP_SPEC ...]: service state"); 10788 pw.println(" service [COMP_SPEC]: service client-side state"); 10789 pw.println(" package [PACKAGE_NAME]: all state related to given package"); 10790 pw.println(" all: dump all activities"); 10791 pw.println(" top: dump the top activity"); 10792 pw.println(" cmd may also be a COMP_SPEC to dump activities."); 10793 pw.println(" COMP_SPEC may be a component name (com.foo/.myApp),"); 10794 pw.println(" a partial substring in a component name, a"); 10795 pw.println(" hex object identifier."); 10796 pw.println(" -a: include all available server state."); 10797 pw.println(" -c: include client state."); 10798 return; 10799 } else { 10800 pw.println("Unknown argument: " + opt + "; use -h for help"); 10801 } 10802 } 10803 10804 long origId = Binder.clearCallingIdentity(); 10805 boolean more = false; 10806 // Is the caller requesting to dump a particular piece of data? 10807 if (opti < args.length) { 10808 String cmd = args[opti]; 10809 opti++; 10810 if ("activities".equals(cmd) || "a".equals(cmd)) { 10811 synchronized (this) { 10812 dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null); 10813 } 10814 } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) { 10815 String[] newArgs; 10816 String name; 10817 if (opti >= args.length) { 10818 name = null; 10819 newArgs = EMPTY_STRING_ARRAY; 10820 } else { 10821 name = args[opti]; 10822 opti++; 10823 newArgs = new String[args.length - opti]; 10824 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 10825 args.length - opti); 10826 } 10827 synchronized (this) { 10828 dumpBroadcastsLocked(fd, pw, args, opti, true, name); 10829 } 10830 } else if ("intents".equals(cmd) || "i".equals(cmd)) { 10831 String[] newArgs; 10832 String name; 10833 if (opti >= args.length) { 10834 name = null; 10835 newArgs = EMPTY_STRING_ARRAY; 10836 } else { 10837 name = args[opti]; 10838 opti++; 10839 newArgs = new String[args.length - opti]; 10840 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 10841 args.length - opti); 10842 } 10843 synchronized (this) { 10844 dumpPendingIntentsLocked(fd, pw, args, opti, true, name); 10845 } 10846 } else if ("processes".equals(cmd) || "p".equals(cmd)) { 10847 String[] newArgs; 10848 String name; 10849 if (opti >= args.length) { 10850 name = null; 10851 newArgs = EMPTY_STRING_ARRAY; 10852 } else { 10853 name = args[opti]; 10854 opti++; 10855 newArgs = new String[args.length - opti]; 10856 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 10857 args.length - opti); 10858 } 10859 synchronized (this) { 10860 dumpProcessesLocked(fd, pw, args, opti, true, name); 10861 } 10862 } else if ("oom".equals(cmd) || "o".equals(cmd)) { 10863 synchronized (this) { 10864 dumpOomLocked(fd, pw, args, opti, true); 10865 } 10866 } else if ("provider".equals(cmd)) { 10867 String[] newArgs; 10868 String name; 10869 if (opti >= args.length) { 10870 name = null; 10871 newArgs = EMPTY_STRING_ARRAY; 10872 } else { 10873 name = args[opti]; 10874 opti++; 10875 newArgs = new String[args.length - opti]; 10876 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti); 10877 } 10878 if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) { 10879 pw.println("No providers match: " + name); 10880 pw.println("Use -h for help."); 10881 } 10882 } else if ("providers".equals(cmd) || "prov".equals(cmd)) { 10883 synchronized (this) { 10884 dumpProvidersLocked(fd, pw, args, opti, true, null); 10885 } 10886 } else if ("service".equals(cmd)) { 10887 String[] newArgs; 10888 String name; 10889 if (opti >= args.length) { 10890 name = null; 10891 newArgs = EMPTY_STRING_ARRAY; 10892 } else { 10893 name = args[opti]; 10894 opti++; 10895 newArgs = new String[args.length - opti]; 10896 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 10897 args.length - opti); 10898 } 10899 if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) { 10900 pw.println("No services match: " + name); 10901 pw.println("Use -h for help."); 10902 } 10903 } else if ("package".equals(cmd)) { 10904 String[] newArgs; 10905 if (opti >= args.length) { 10906 pw.println("package: no package name specified"); 10907 pw.println("Use -h for help."); 10908 } else { 10909 dumpPackage = args[opti]; 10910 opti++; 10911 newArgs = new String[args.length - opti]; 10912 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 10913 args.length - opti); 10914 args = newArgs; 10915 opti = 0; 10916 more = true; 10917 } 10918 } else if ("services".equals(cmd) || "s".equals(cmd)) { 10919 synchronized (this) { 10920 mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null); 10921 } 10922 } else { 10923 // Dumping a single activity? 10924 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) { 10925 pw.println("Bad activity command, or no activities match: " + cmd); 10926 pw.println("Use -h for help."); 10927 } 10928 } 10929 if (!more) { 10930 Binder.restoreCallingIdentity(origId); 10931 return; 10932 } 10933 } 10934 10935 // No piece of data specified, dump everything. 10936 synchronized (this) { 10937 dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 10938 pw.println(); 10939 if (dumpAll) { 10940 pw.println("-------------------------------------------------------------------------------"); 10941 } 10942 dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 10943 pw.println(); 10944 if (dumpAll) { 10945 pw.println("-------------------------------------------------------------------------------"); 10946 } 10947 dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage); 10948 pw.println(); 10949 if (dumpAll) { 10950 pw.println("-------------------------------------------------------------------------------"); 10951 } 10952 mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 10953 pw.println(); 10954 if (dumpAll) { 10955 pw.println("-------------------------------------------------------------------------------"); 10956 } 10957 dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 10958 pw.println(); 10959 if (dumpAll) { 10960 pw.println("-------------------------------------------------------------------------------"); 10961 } 10962 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage); 10963 } 10964 Binder.restoreCallingIdentity(origId); 10965 } 10966 10967 void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 10968 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) { 10969 pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)"); 10970 10971 boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient, 10972 dumpPackage); 10973 boolean needSep = printedAnything; 10974 10975 boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity, 10976 dumpPackage, needSep, " mFocusedActivity: "); 10977 if (printed) { 10978 printedAnything = true; 10979 needSep = false; 10980 } 10981 10982 if (dumpPackage == null) { 10983 if (needSep) { 10984 pw.println(); 10985 } 10986 needSep = true; 10987 printedAnything = true; 10988 mStackSupervisor.dump(pw, " "); 10989 } 10990 10991 if (mRecentTasks.size() > 0) { 10992 boolean printedHeader = false; 10993 10994 final int N = mRecentTasks.size(); 10995 for (int i=0; i<N; i++) { 10996 TaskRecord tr = mRecentTasks.get(i); 10997 if (dumpPackage != null) { 10998 if (tr.realActivity == null || 10999 !dumpPackage.equals(tr.realActivity)) { 11000 continue; 11001 } 11002 } 11003 if (!printedHeader) { 11004 if (needSep) { 11005 pw.println(); 11006 } 11007 pw.println(" Recent tasks:"); 11008 printedHeader = true; 11009 printedAnything = true; 11010 } 11011 pw.print(" * Recent #"); pw.print(i); pw.print(": "); 11012 pw.println(tr); 11013 if (dumpAll) { 11014 mRecentTasks.get(i).dump(pw, " "); 11015 } 11016 } 11017 } 11018 11019 if (!printedAnything) { 11020 pw.println(" (nothing)"); 11021 } 11022 } 11023 11024 void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 11025 int opti, boolean dumpAll, String dumpPackage) { 11026 boolean needSep = false; 11027 boolean printedAnything = false; 11028 int numPers = 0; 11029 11030 pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)"); 11031 11032 if (dumpAll) { 11033 final int NP = mProcessNames.getMap().size(); 11034 for (int ip=0; ip<NP; ip++) { 11035 SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip); 11036 final int NA = procs.size(); 11037 for (int ia=0; ia<NA; ia++) { 11038 ProcessRecord r = procs.valueAt(ia); 11039 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 11040 continue; 11041 } 11042 if (!needSep) { 11043 pw.println(" All known processes:"); 11044 needSep = true; 11045 printedAnything = true; 11046 } 11047 pw.print(r.persistent ? " *PERS*" : " *APP*"); 11048 pw.print(" UID "); pw.print(procs.keyAt(ia)); 11049 pw.print(" "); pw.println(r); 11050 r.dump(pw, " "); 11051 if (r.persistent) { 11052 numPers++; 11053 } 11054 } 11055 } 11056 } 11057 11058 if (mIsolatedProcesses.size() > 0) { 11059 boolean printed = false; 11060 for (int i=0; i<mIsolatedProcesses.size(); i++) { 11061 ProcessRecord r = mIsolatedProcesses.valueAt(i); 11062 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 11063 continue; 11064 } 11065 if (!printed) { 11066 if (needSep) { 11067 pw.println(); 11068 } 11069 pw.println(" Isolated process list (sorted by uid):"); 11070 printedAnything = true; 11071 printed = true; 11072 needSep = true; 11073 } 11074 pw.println(String.format("%sIsolated #%2d: %s", 11075 " ", i, r.toString())); 11076 } 11077 } 11078 11079 if (mLruProcesses.size() > 0) { 11080 if (needSep) { 11081 pw.println(); 11082 } 11083 pw.print(" Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size()); 11084 pw.print(" total, non-act at "); 11085 pw.print(mLruProcesses.size()-mLruProcessActivityStart); 11086 pw.print(", non-svc at "); 11087 pw.print(mLruProcesses.size()-mLruProcessServiceStart); 11088 pw.println("):"); 11089 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", false, dumpPackage); 11090 needSep = true; 11091 printedAnything = true; 11092 } 11093 11094 if (dumpAll || dumpPackage != null) { 11095 synchronized (mPidsSelfLocked) { 11096 boolean printed = false; 11097 for (int i=0; i<mPidsSelfLocked.size(); i++) { 11098 ProcessRecord r = mPidsSelfLocked.valueAt(i); 11099 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 11100 continue; 11101 } 11102 if (!printed) { 11103 if (needSep) pw.println(); 11104 needSep = true; 11105 pw.println(" PID mappings:"); 11106 printed = true; 11107 printedAnything = true; 11108 } 11109 pw.print(" PID #"); pw.print(mPidsSelfLocked.keyAt(i)); 11110 pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i)); 11111 } 11112 } 11113 } 11114 11115 if (mForegroundProcesses.size() > 0) { 11116 synchronized (mPidsSelfLocked) { 11117 boolean printed = false; 11118 for (int i=0; i<mForegroundProcesses.size(); i++) { 11119 ProcessRecord r = mPidsSelfLocked.get( 11120 mForegroundProcesses.valueAt(i).pid); 11121 if (dumpPackage != null && (r == null 11122 || !r.pkgList.containsKey(dumpPackage))) { 11123 continue; 11124 } 11125 if (!printed) { 11126 if (needSep) pw.println(); 11127 needSep = true; 11128 pw.println(" Foreground Processes:"); 11129 printed = true; 11130 printedAnything = true; 11131 } 11132 pw.print(" PID #"); pw.print(mForegroundProcesses.keyAt(i)); 11133 pw.print(": "); pw.println(mForegroundProcesses.valueAt(i)); 11134 } 11135 } 11136 } 11137 11138 if (mPersistentStartingProcesses.size() > 0) { 11139 if (needSep) pw.println(); 11140 needSep = true; 11141 printedAnything = true; 11142 pw.println(" Persisent processes that are starting:"); 11143 dumpProcessList(pw, this, mPersistentStartingProcesses, " ", 11144 "Starting Norm", "Restarting PERS", dumpPackage); 11145 } 11146 11147 if (mRemovedProcesses.size() > 0) { 11148 if (needSep) pw.println(); 11149 needSep = true; 11150 printedAnything = true; 11151 pw.println(" Processes that are being removed:"); 11152 dumpProcessList(pw, this, mRemovedProcesses, " ", 11153 "Removed Norm", "Removed PERS", dumpPackage); 11154 } 11155 11156 if (mProcessesOnHold.size() > 0) { 11157 if (needSep) pw.println(); 11158 needSep = true; 11159 printedAnything = true; 11160 pw.println(" Processes that are on old until the system is ready:"); 11161 dumpProcessList(pw, this, mProcessesOnHold, " ", 11162 "OnHold Norm", "OnHold PERS", dumpPackage); 11163 } 11164 11165 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage); 11166 11167 if (mProcessCrashTimes.getMap().size() > 0) { 11168 boolean printed = false; 11169 long now = SystemClock.uptimeMillis(); 11170 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap(); 11171 final int NP = pmap.size(); 11172 for (int ip=0; ip<NP; ip++) { 11173 String pname = pmap.keyAt(ip); 11174 SparseArray<Long> uids = pmap.valueAt(ip); 11175 final int N = uids.size(); 11176 for (int i=0; i<N; i++) { 11177 int puid = uids.keyAt(i); 11178 ProcessRecord r = mProcessNames.get(pname, puid); 11179 if (dumpPackage != null && (r == null 11180 || !r.pkgList.containsKey(dumpPackage))) { 11181 continue; 11182 } 11183 if (!printed) { 11184 if (needSep) pw.println(); 11185 needSep = true; 11186 pw.println(" Time since processes crashed:"); 11187 printed = true; 11188 printedAnything = true; 11189 } 11190 pw.print(" Process "); pw.print(pname); 11191 pw.print(" uid "); pw.print(puid); 11192 pw.print(": last crashed "); 11193 TimeUtils.formatDuration(now-uids.valueAt(i), pw); 11194 pw.println(" ago"); 11195 } 11196 } 11197 } 11198 11199 if (mBadProcesses.getMap().size() > 0) { 11200 boolean printed = false; 11201 final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap(); 11202 final int NP = pmap.size(); 11203 for (int ip=0; ip<NP; ip++) { 11204 String pname = pmap.keyAt(ip); 11205 SparseArray<BadProcessInfo> uids = pmap.valueAt(ip); 11206 final int N = uids.size(); 11207 for (int i=0; i<N; i++) { 11208 int puid = uids.keyAt(i); 11209 ProcessRecord r = mProcessNames.get(pname, puid); 11210 if (dumpPackage != null && (r == null 11211 || !r.pkgList.containsKey(dumpPackage))) { 11212 continue; 11213 } 11214 if (!printed) { 11215 if (needSep) pw.println(); 11216 needSep = true; 11217 pw.println(" Bad processes:"); 11218 printedAnything = true; 11219 } 11220 BadProcessInfo info = uids.valueAt(i); 11221 pw.print(" Bad process "); pw.print(pname); 11222 pw.print(" uid "); pw.print(puid); 11223 pw.print(": crashed at time "); pw.println(info.time); 11224 if (info.shortMsg != null) { 11225 pw.print(" Short msg: "); pw.println(info.shortMsg); 11226 } 11227 if (info.longMsg != null) { 11228 pw.print(" Long msg: "); pw.println(info.longMsg); 11229 } 11230 if (info.stack != null) { 11231 pw.println(" Stack:"); 11232 int lastPos = 0; 11233 for (int pos=0; pos<info.stack.length(); pos++) { 11234 if (info.stack.charAt(pos) == '\n') { 11235 pw.print(" "); 11236 pw.write(info.stack, lastPos, pos-lastPos); 11237 pw.println(); 11238 lastPos = pos+1; 11239 } 11240 } 11241 if (lastPos < info.stack.length()) { 11242 pw.print(" "); 11243 pw.write(info.stack, lastPos, info.stack.length()-lastPos); 11244 pw.println(); 11245 } 11246 } 11247 } 11248 } 11249 } 11250 11251 if (dumpPackage == null) { 11252 pw.println(); 11253 needSep = false; 11254 pw.println(" mStartedUsers:"); 11255 for (int i=0; i<mStartedUsers.size(); i++) { 11256 UserStartedState uss = mStartedUsers.valueAt(i); 11257 pw.print(" User #"); pw.print(uss.mHandle.getIdentifier()); 11258 pw.print(": "); uss.dump("", pw); 11259 } 11260 pw.print(" mStartedUserArray: ["); 11261 for (int i=0; i<mStartedUserArray.length; i++) { 11262 if (i > 0) pw.print(", "); 11263 pw.print(mStartedUserArray[i]); 11264 } 11265 pw.println("]"); 11266 pw.print(" mUserLru: ["); 11267 for (int i=0; i<mUserLru.size(); i++) { 11268 if (i > 0) pw.print(", "); 11269 pw.print(mUserLru.get(i)); 11270 } 11271 pw.println("]"); 11272 if (dumpAll) { 11273 pw.print(" mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray)); 11274 } 11275 } 11276 if (mHomeProcess != null && (dumpPackage == null 11277 || mHomeProcess.pkgList.containsKey(dumpPackage))) { 11278 if (needSep) { 11279 pw.println(); 11280 needSep = false; 11281 } 11282 pw.println(" mHomeProcess: " + mHomeProcess); 11283 } 11284 if (mPreviousProcess != null && (dumpPackage == null 11285 || mPreviousProcess.pkgList.containsKey(dumpPackage))) { 11286 if (needSep) { 11287 pw.println(); 11288 needSep = false; 11289 } 11290 pw.println(" mPreviousProcess: " + mPreviousProcess); 11291 } 11292 if (dumpAll) { 11293 StringBuilder sb = new StringBuilder(128); 11294 sb.append(" mPreviousProcessVisibleTime: "); 11295 TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb); 11296 pw.println(sb); 11297 } 11298 if (mHeavyWeightProcess != null && (dumpPackage == null 11299 || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) { 11300 if (needSep) { 11301 pw.println(); 11302 needSep = false; 11303 } 11304 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 11305 } 11306 if (dumpPackage == null) { 11307 pw.println(" mConfiguration: " + mConfiguration); 11308 } 11309 if (dumpAll) { 11310 pw.println(" mConfigWillChange: " + getFocusedStack().mConfigWillChange); 11311 if (mCompatModePackages.getPackages().size() > 0) { 11312 boolean printed = false; 11313 for (Map.Entry<String, Integer> entry 11314 : mCompatModePackages.getPackages().entrySet()) { 11315 String pkg = entry.getKey(); 11316 int mode = entry.getValue(); 11317 if (dumpPackage != null && !dumpPackage.equals(pkg)) { 11318 continue; 11319 } 11320 if (!printed) { 11321 pw.println(" mScreenCompatPackages:"); 11322 printed = true; 11323 } 11324 pw.print(" "); pw.print(pkg); pw.print(": "); 11325 pw.print(mode); pw.println(); 11326 } 11327 } 11328 } 11329 if (dumpPackage == null) { 11330 if (mSleeping || mWentToSleep || mLockScreenShown) { 11331 pw.println(" mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep 11332 + " mLockScreenShown " + mLockScreenShown); 11333 } 11334 if (mShuttingDown || mRunningVoice) { 11335 pw.print(" mShuttingDown=" + mShuttingDown + " mRunningVoice=" + mRunningVoice); 11336 } 11337 } 11338 if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient 11339 || mOrigWaitForDebugger) { 11340 if (dumpPackage == null || dumpPackage.equals(mDebugApp) 11341 || dumpPackage.equals(mOrigDebugApp)) { 11342 if (needSep) { 11343 pw.println(); 11344 needSep = false; 11345 } 11346 pw.println(" mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp 11347 + " mDebugTransient=" + mDebugTransient 11348 + " mOrigWaitForDebugger=" + mOrigWaitForDebugger); 11349 } 11350 } 11351 if (mOpenGlTraceApp != null) { 11352 if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) { 11353 if (needSep) { 11354 pw.println(); 11355 needSep = false; 11356 } 11357 pw.println(" mOpenGlTraceApp=" + mOpenGlTraceApp); 11358 } 11359 } 11360 if (mProfileApp != null || mProfileProc != null || mProfileFile != null 11361 || mProfileFd != null) { 11362 if (dumpPackage == null || dumpPackage.equals(mProfileApp)) { 11363 if (needSep) { 11364 pw.println(); 11365 needSep = false; 11366 } 11367 pw.println(" mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc); 11368 pw.println(" mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd); 11369 pw.println(" mProfileType=" + mProfileType + " mAutoStopProfiler=" 11370 + mAutoStopProfiler); 11371 } 11372 } 11373 if (dumpPackage == null) { 11374 if (mAlwaysFinishActivities || mController != null) { 11375 pw.println(" mAlwaysFinishActivities=" + mAlwaysFinishActivities 11376 + " mController=" + mController); 11377 } 11378 if (dumpAll) { 11379 pw.println(" Total persistent processes: " + numPers); 11380 pw.println(" mProcessesReady=" + mProcessesReady 11381 + " mSystemReady=" + mSystemReady); 11382 pw.println(" mBooting=" + mBooting 11383 + " mBooted=" + mBooted 11384 + " mFactoryTest=" + mFactoryTest); 11385 pw.print(" mLastPowerCheckRealtime="); 11386 TimeUtils.formatDuration(mLastPowerCheckRealtime, pw); 11387 pw.println(""); 11388 pw.print(" mLastPowerCheckUptime="); 11389 TimeUtils.formatDuration(mLastPowerCheckUptime, pw); 11390 pw.println(""); 11391 pw.println(" mGoingToSleep=" + mStackSupervisor.mGoingToSleep); 11392 pw.println(" mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity); 11393 pw.println(" mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq); 11394 pw.println(" mNumNonCachedProcs=" + mNumNonCachedProcs 11395 + " (" + mLruProcesses.size() + " total)" 11396 + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs 11397 + " mNumServiceProcs=" + mNumServiceProcs 11398 + " mNewNumServiceProcs=" + mNewNumServiceProcs); 11399 pw.println(" mAllowLowerMemLevel=" + mAllowLowerMemLevel 11400 + " mLastMemoryLevel" + mLastMemoryLevel 11401 + " mLastNumProcesses" + mLastNumProcesses); 11402 long now = SystemClock.uptimeMillis(); 11403 pw.print(" mLastIdleTime="); 11404 TimeUtils.formatDuration(now, mLastIdleTime, pw); 11405 pw.print(" mLowRamSinceLastIdle="); 11406 TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw); 11407 pw.println(); 11408 } 11409 } 11410 11411 if (!printedAnything) { 11412 pw.println(" (nothing)"); 11413 } 11414 } 11415 11416 boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args, 11417 int opti, boolean needSep, boolean dumpAll, String dumpPackage) { 11418 if (mProcessesToGc.size() > 0) { 11419 boolean printed = false; 11420 long now = SystemClock.uptimeMillis(); 11421 for (int i=0; i<mProcessesToGc.size(); i++) { 11422 ProcessRecord proc = mProcessesToGc.get(i); 11423 if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) { 11424 continue; 11425 } 11426 if (!printed) { 11427 if (needSep) pw.println(); 11428 needSep = true; 11429 pw.println(" Processes that are waiting to GC:"); 11430 printed = true; 11431 } 11432 pw.print(" Process "); pw.println(proc); 11433 pw.print(" lowMem="); pw.print(proc.reportLowMemory); 11434 pw.print(", last gced="); 11435 pw.print(now-proc.lastRequestedGc); 11436 pw.print(" ms ago, last lowMem="); 11437 pw.print(now-proc.lastLowMemory); 11438 pw.println(" ms ago"); 11439 11440 } 11441 } 11442 return needSep; 11443 } 11444 11445 void printOomLevel(PrintWriter pw, String name, int adj) { 11446 pw.print(" "); 11447 if (adj >= 0) { 11448 pw.print(' '); 11449 if (adj < 10) pw.print(' '); 11450 } else { 11451 if (adj > -10) pw.print(' '); 11452 } 11453 pw.print(adj); 11454 pw.print(": "); 11455 pw.print(name); 11456 pw.print(" ("); 11457 pw.print(mProcessList.getMemLevel(adj)/1024); 11458 pw.println(" kB)"); 11459 } 11460 11461 boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args, 11462 int opti, boolean dumpAll) { 11463 boolean needSep = false; 11464 11465 if (mLruProcesses.size() > 0) { 11466 if (needSep) pw.println(); 11467 needSep = true; 11468 pw.println(" OOM levels:"); 11469 printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ); 11470 printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ); 11471 printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ); 11472 printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ); 11473 printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ); 11474 printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ); 11475 printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ); 11476 printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ); 11477 printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ); 11478 printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ); 11479 printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ); 11480 printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ); 11481 printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ); 11482 11483 if (needSep) pw.println(); 11484 pw.print(" Process OOM control ("); pw.print(mLruProcesses.size()); 11485 pw.print(" total, non-act at "); 11486 pw.print(mLruProcesses.size()-mLruProcessActivityStart); 11487 pw.print(", non-svc at "); 11488 pw.print(mLruProcesses.size()-mLruProcessServiceStart); 11489 pw.println("):"); 11490 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", true, null); 11491 needSep = true; 11492 } 11493 11494 dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null); 11495 11496 pw.println(); 11497 pw.println(" mHomeProcess: " + mHomeProcess); 11498 pw.println(" mPreviousProcess: " + mPreviousProcess); 11499 if (mHeavyWeightProcess != null) { 11500 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 11501 } 11502 11503 return true; 11504 } 11505 11506 /** 11507 * There are three ways to call this: 11508 * - no provider specified: dump all the providers 11509 * - a flattened component name that matched an existing provider was specified as the 11510 * first arg: dump that one provider 11511 * - the first arg isn't the flattened component name of an existing provider: 11512 * dump all providers whose component contains the first arg as a substring 11513 */ 11514 protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args, 11515 int opti, boolean dumpAll) { 11516 return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll); 11517 } 11518 11519 static class ItemMatcher { 11520 ArrayList<ComponentName> components; 11521 ArrayList<String> strings; 11522 ArrayList<Integer> objects; 11523 boolean all; 11524 11525 ItemMatcher() { 11526 all = true; 11527 } 11528 11529 void build(String name) { 11530 ComponentName componentName = ComponentName.unflattenFromString(name); 11531 if (componentName != null) { 11532 if (components == null) { 11533 components = new ArrayList<ComponentName>(); 11534 } 11535 components.add(componentName); 11536 all = false; 11537 } else { 11538 int objectId = 0; 11539 // Not a '/' separated full component name; maybe an object ID? 11540 try { 11541 objectId = Integer.parseInt(name, 16); 11542 if (objects == null) { 11543 objects = new ArrayList<Integer>(); 11544 } 11545 objects.add(objectId); 11546 all = false; 11547 } catch (RuntimeException e) { 11548 // Not an integer; just do string match. 11549 if (strings == null) { 11550 strings = new ArrayList<String>(); 11551 } 11552 strings.add(name); 11553 all = false; 11554 } 11555 } 11556 } 11557 11558 int build(String[] args, int opti) { 11559 for (; opti<args.length; opti++) { 11560 String name = args[opti]; 11561 if ("--".equals(name)) { 11562 return opti+1; 11563 } 11564 build(name); 11565 } 11566 return opti; 11567 } 11568 11569 boolean match(Object object, ComponentName comp) { 11570 if (all) { 11571 return true; 11572 } 11573 if (components != null) { 11574 for (int i=0; i<components.size(); i++) { 11575 if (components.get(i).equals(comp)) { 11576 return true; 11577 } 11578 } 11579 } 11580 if (objects != null) { 11581 for (int i=0; i<objects.size(); i++) { 11582 if (System.identityHashCode(object) == objects.get(i)) { 11583 return true; 11584 } 11585 } 11586 } 11587 if (strings != null) { 11588 String flat = comp.flattenToString(); 11589 for (int i=0; i<strings.size(); i++) { 11590 if (flat.contains(strings.get(i))) { 11591 return true; 11592 } 11593 } 11594 } 11595 return false; 11596 } 11597 } 11598 11599 /** 11600 * There are three things that cmd can be: 11601 * - a flattened component name that matches an existing activity 11602 * - the cmd arg isn't the flattened component name of an existing activity: 11603 * dump all activity whose component contains the cmd as a substring 11604 * - A hex number of the ActivityRecord object instance. 11605 */ 11606 protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args, 11607 int opti, boolean dumpAll) { 11608 ArrayList<ActivityRecord> activities; 11609 11610 synchronized (this) { 11611 activities = mStackSupervisor.getDumpActivitiesLocked(name); 11612 } 11613 11614 if (activities.size() <= 0) { 11615 return false; 11616 } 11617 11618 String[] newArgs = new String[args.length - opti]; 11619 System.arraycopy(args, opti, newArgs, 0, args.length - opti); 11620 11621 TaskRecord lastTask = null; 11622 boolean needSep = false; 11623 for (int i=activities.size()-1; i>=0; i--) { 11624 ActivityRecord r = activities.get(i); 11625 if (needSep) { 11626 pw.println(); 11627 } 11628 needSep = true; 11629 synchronized (this) { 11630 if (lastTask != r.task) { 11631 lastTask = r.task; 11632 pw.print("TASK "); pw.print(lastTask.affinity); 11633 pw.print(" id="); pw.println(lastTask.taskId); 11634 if (dumpAll) { 11635 lastTask.dump(pw, " "); 11636 } 11637 } 11638 } 11639 dumpActivity(" ", fd, pw, activities.get(i), newArgs, dumpAll); 11640 } 11641 return true; 11642 } 11643 11644 /** 11645 * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if 11646 * there is a thread associated with the activity. 11647 */ 11648 private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw, 11649 final ActivityRecord r, String[] args, boolean dumpAll) { 11650 String innerPrefix = prefix + " "; 11651 synchronized (this) { 11652 pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName); 11653 pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r))); 11654 pw.print(" pid="); 11655 if (r.app != null) pw.println(r.app.pid); 11656 else pw.println("(not running)"); 11657 if (dumpAll) { 11658 r.dump(pw, innerPrefix); 11659 } 11660 } 11661 if (r.app != null && r.app.thread != null) { 11662 // flush anything that is already in the PrintWriter since the thread is going 11663 // to write to the file descriptor directly 11664 pw.flush(); 11665 try { 11666 TransferPipe tp = new TransferPipe(); 11667 try { 11668 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(), 11669 r.appToken, innerPrefix, args); 11670 tp.go(fd); 11671 } finally { 11672 tp.kill(); 11673 } 11674 } catch (IOException e) { 11675 pw.println(innerPrefix + "Failure while dumping the activity: " + e); 11676 } catch (RemoteException e) { 11677 pw.println(innerPrefix + "Got a RemoteException while dumping the activity"); 11678 } 11679 } 11680 } 11681 11682 void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 11683 int opti, boolean dumpAll, String dumpPackage) { 11684 boolean needSep = false; 11685 boolean onlyHistory = false; 11686 boolean printedAnything = false; 11687 11688 if ("history".equals(dumpPackage)) { 11689 if (opti < args.length && "-s".equals(args[opti])) { 11690 dumpAll = false; 11691 } 11692 onlyHistory = true; 11693 dumpPackage = null; 11694 } 11695 11696 pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)"); 11697 if (!onlyHistory && dumpAll) { 11698 if (mRegisteredReceivers.size() > 0) { 11699 boolean printed = false; 11700 Iterator it = mRegisteredReceivers.values().iterator(); 11701 while (it.hasNext()) { 11702 ReceiverList r = (ReceiverList)it.next(); 11703 if (dumpPackage != null && (r.app == null || 11704 !dumpPackage.equals(r.app.info.packageName))) { 11705 continue; 11706 } 11707 if (!printed) { 11708 pw.println(" Registered Receivers:"); 11709 needSep = true; 11710 printed = true; 11711 printedAnything = true; 11712 } 11713 pw.print(" * "); pw.println(r); 11714 r.dump(pw, " "); 11715 } 11716 } 11717 11718 if (mReceiverResolver.dump(pw, needSep ? 11719 "\n Receiver Resolver Table:" : " Receiver Resolver Table:", 11720 " ", dumpPackage, false)) { 11721 needSep = true; 11722 printedAnything = true; 11723 } 11724 } 11725 11726 for (BroadcastQueue q : mBroadcastQueues) { 11727 needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep); 11728 printedAnything |= needSep; 11729 } 11730 11731 needSep = true; 11732 11733 if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) { 11734 for (int user=0; user<mStickyBroadcasts.size(); user++) { 11735 if (needSep) { 11736 pw.println(); 11737 } 11738 needSep = true; 11739 printedAnything = true; 11740 pw.print(" Sticky broadcasts for user "); 11741 pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":"); 11742 StringBuilder sb = new StringBuilder(128); 11743 for (Map.Entry<String, ArrayList<Intent>> ent 11744 : mStickyBroadcasts.valueAt(user).entrySet()) { 11745 pw.print(" * Sticky action "); pw.print(ent.getKey()); 11746 if (dumpAll) { 11747 pw.println(":"); 11748 ArrayList<Intent> intents = ent.getValue(); 11749 final int N = intents.size(); 11750 for (int i=0; i<N; i++) { 11751 sb.setLength(0); 11752 sb.append(" Intent: "); 11753 intents.get(i).toShortString(sb, false, true, false, false); 11754 pw.println(sb.toString()); 11755 Bundle bundle = intents.get(i).getExtras(); 11756 if (bundle != null) { 11757 pw.print(" "); 11758 pw.println(bundle.toString()); 11759 } 11760 } 11761 } else { 11762 pw.println(""); 11763 } 11764 } 11765 } 11766 } 11767 11768 if (!onlyHistory && dumpAll) { 11769 pw.println(); 11770 for (BroadcastQueue queue : mBroadcastQueues) { 11771 pw.println(" mBroadcastsScheduled [" + queue.mQueueName + "]=" 11772 + queue.mBroadcastsScheduled); 11773 } 11774 pw.println(" mHandler:"); 11775 mHandler.dump(new PrintWriterPrinter(pw), " "); 11776 needSep = true; 11777 printedAnything = true; 11778 } 11779 11780 if (!printedAnything) { 11781 pw.println(" (nothing)"); 11782 } 11783 } 11784 11785 void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args, 11786 int opti, boolean dumpAll, String dumpPackage) { 11787 boolean needSep; 11788 boolean printedAnything = false; 11789 11790 ItemMatcher matcher = new ItemMatcher(); 11791 matcher.build(args, opti); 11792 11793 pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)"); 11794 11795 needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage); 11796 printedAnything |= needSep; 11797 11798 if (mLaunchingProviders.size() > 0) { 11799 boolean printed = false; 11800 for (int i=mLaunchingProviders.size()-1; i>=0; i--) { 11801 ContentProviderRecord r = mLaunchingProviders.get(i); 11802 if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) { 11803 continue; 11804 } 11805 if (!printed) { 11806 if (needSep) pw.println(); 11807 needSep = true; 11808 pw.println(" Launching content providers:"); 11809 printed = true; 11810 printedAnything = true; 11811 } 11812 pw.print(" Launching #"); pw.print(i); pw.print(": "); 11813 pw.println(r); 11814 } 11815 } 11816 11817 if (mGrantedUriPermissions.size() > 0) { 11818 boolean printed = false; 11819 int dumpUid = -2; 11820 if (dumpPackage != null) { 11821 try { 11822 dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0); 11823 } catch (NameNotFoundException e) { 11824 dumpUid = -1; 11825 } 11826 } 11827 for (int i=0; i<mGrantedUriPermissions.size(); i++) { 11828 int uid = mGrantedUriPermissions.keyAt(i); 11829 if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) { 11830 continue; 11831 } 11832 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 11833 if (!printed) { 11834 if (needSep) pw.println(); 11835 needSep = true; 11836 pw.println(" Granted Uri Permissions:"); 11837 printed = true; 11838 printedAnything = true; 11839 } 11840 pw.print(" * UID "); pw.print(uid); pw.println(" holds:"); 11841 for (UriPermission perm : perms.values()) { 11842 pw.print(" "); pw.println(perm); 11843 if (dumpAll) { 11844 perm.dump(pw, " "); 11845 } 11846 } 11847 } 11848 } 11849 11850 if (!printedAnything) { 11851 pw.println(" (nothing)"); 11852 } 11853 } 11854 11855 void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 11856 int opti, boolean dumpAll, String dumpPackage) { 11857 boolean printed = false; 11858 11859 pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)"); 11860 11861 if (mIntentSenderRecords.size() > 0) { 11862 Iterator<WeakReference<PendingIntentRecord>> it 11863 = mIntentSenderRecords.values().iterator(); 11864 while (it.hasNext()) { 11865 WeakReference<PendingIntentRecord> ref = it.next(); 11866 PendingIntentRecord rec = ref != null ? ref.get(): null; 11867 if (dumpPackage != null && (rec == null 11868 || !dumpPackage.equals(rec.key.packageName))) { 11869 continue; 11870 } 11871 printed = true; 11872 if (rec != null) { 11873 pw.print(" * "); pw.println(rec); 11874 if (dumpAll) { 11875 rec.dump(pw, " "); 11876 } 11877 } else { 11878 pw.print(" * "); pw.println(ref); 11879 } 11880 } 11881 } 11882 11883 if (!printed) { 11884 pw.println(" (nothing)"); 11885 } 11886 } 11887 11888 private static final int dumpProcessList(PrintWriter pw, 11889 ActivityManagerService service, List list, 11890 String prefix, String normalLabel, String persistentLabel, 11891 String dumpPackage) { 11892 int numPers = 0; 11893 final int N = list.size()-1; 11894 for (int i=N; i>=0; i--) { 11895 ProcessRecord r = (ProcessRecord)list.get(i); 11896 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 11897 continue; 11898 } 11899 pw.println(String.format("%s%s #%2d: %s", 11900 prefix, (r.persistent ? persistentLabel : normalLabel), 11901 i, r.toString())); 11902 if (r.persistent) { 11903 numPers++; 11904 } 11905 } 11906 return numPers; 11907 } 11908 11909 private static final boolean dumpProcessOomList(PrintWriter pw, 11910 ActivityManagerService service, List<ProcessRecord> origList, 11911 String prefix, String normalLabel, String persistentLabel, 11912 boolean inclDetails, String dumpPackage) { 11913 11914 ArrayList<Pair<ProcessRecord, Integer>> list 11915 = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size()); 11916 for (int i=0; i<origList.size(); i++) { 11917 ProcessRecord r = origList.get(i); 11918 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 11919 continue; 11920 } 11921 list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i)); 11922 } 11923 11924 if (list.size() <= 0) { 11925 return false; 11926 } 11927 11928 Comparator<Pair<ProcessRecord, Integer>> comparator 11929 = new Comparator<Pair<ProcessRecord, Integer>>() { 11930 @Override 11931 public int compare(Pair<ProcessRecord, Integer> object1, 11932 Pair<ProcessRecord, Integer> object2) { 11933 if (object1.first.setAdj != object2.first.setAdj) { 11934 return object1.first.setAdj > object2.first.setAdj ? -1 : 1; 11935 } 11936 if (object1.second.intValue() != object2.second.intValue()) { 11937 return object1.second.intValue() > object2.second.intValue() ? -1 : 1; 11938 } 11939 return 0; 11940 } 11941 }; 11942 11943 Collections.sort(list, comparator); 11944 11945 final long curRealtime = SystemClock.elapsedRealtime(); 11946 final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime; 11947 final long curUptime = SystemClock.uptimeMillis(); 11948 final long uptimeSince = curUptime - service.mLastPowerCheckUptime; 11949 11950 for (int i=list.size()-1; i>=0; i--) { 11951 ProcessRecord r = list.get(i).first; 11952 String oomAdj = ProcessList.makeOomAdjString(r.setAdj); 11953 char schedGroup; 11954 switch (r.setSchedGroup) { 11955 case Process.THREAD_GROUP_BG_NONINTERACTIVE: 11956 schedGroup = 'B'; 11957 break; 11958 case Process.THREAD_GROUP_DEFAULT: 11959 schedGroup = 'F'; 11960 break; 11961 default: 11962 schedGroup = '?'; 11963 break; 11964 } 11965 char foreground; 11966 if (r.foregroundActivities) { 11967 foreground = 'A'; 11968 } else if (r.foregroundServices) { 11969 foreground = 'S'; 11970 } else { 11971 foreground = ' '; 11972 } 11973 String procState = ProcessList.makeProcStateString(r.curProcState); 11974 pw.print(prefix); 11975 pw.print(r.persistent ? persistentLabel : normalLabel); 11976 pw.print(" #"); 11977 int num = (origList.size()-1)-list.get(i).second; 11978 if (num < 10) pw.print(' '); 11979 pw.print(num); 11980 pw.print(": "); 11981 pw.print(oomAdj); 11982 pw.print(' '); 11983 pw.print(schedGroup); 11984 pw.print('/'); 11985 pw.print(foreground); 11986 pw.print('/'); 11987 pw.print(procState); 11988 pw.print(" trm:"); 11989 if (r.trimMemoryLevel < 10) pw.print(' '); 11990 pw.print(r.trimMemoryLevel); 11991 pw.print(' '); 11992 pw.print(r.toShortString()); 11993 pw.print(" ("); 11994 pw.print(r.adjType); 11995 pw.println(')'); 11996 if (r.adjSource != null || r.adjTarget != null) { 11997 pw.print(prefix); 11998 pw.print(" "); 11999 if (r.adjTarget instanceof ComponentName) { 12000 pw.print(((ComponentName)r.adjTarget).flattenToShortString()); 12001 } else if (r.adjTarget != null) { 12002 pw.print(r.adjTarget.toString()); 12003 } else { 12004 pw.print("{null}"); 12005 } 12006 pw.print("<="); 12007 if (r.adjSource instanceof ProcessRecord) { 12008 pw.print("Proc{"); 12009 pw.print(((ProcessRecord)r.adjSource).toShortString()); 12010 pw.println("}"); 12011 } else if (r.adjSource != null) { 12012 pw.println(r.adjSource.toString()); 12013 } else { 12014 pw.println("{null}"); 12015 } 12016 } 12017 if (inclDetails) { 12018 pw.print(prefix); 12019 pw.print(" "); 12020 pw.print("oom: max="); pw.print(r.maxAdj); 12021 pw.print(" curRaw="); pw.print(r.curRawAdj); 12022 pw.print(" setRaw="); pw.print(r.setRawAdj); 12023 pw.print(" cur="); pw.print(r.curAdj); 12024 pw.print(" set="); pw.println(r.setAdj); 12025 pw.print(prefix); 12026 pw.print(" "); 12027 pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState)); 12028 pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState)); 12029 pw.print(" lastPss="); pw.print(r.lastPss); 12030 pw.print(" lastCachedPss="); pw.println(r.lastCachedPss); 12031 pw.print(prefix); 12032 pw.print(" "); 12033 pw.print("keeping="); pw.print(r.keeping); 12034 pw.print(" cached="); pw.print(r.cached); 12035 pw.print(" empty="); pw.print(r.empty); 12036 pw.print(" hasAboveClient="); pw.println(r.hasAboveClient); 12037 12038 if (!r.keeping) { 12039 if (r.lastWakeTime != 0) { 12040 long wtime; 12041 BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics(); 12042 synchronized (stats) { 12043 wtime = stats.getProcessWakeTime(r.info.uid, 12044 r.pid, curRealtime); 12045 } 12046 long timeUsed = wtime - r.lastWakeTime; 12047 pw.print(prefix); 12048 pw.print(" "); 12049 pw.print("keep awake over "); 12050 TimeUtils.formatDuration(realtimeSince, pw); 12051 pw.print(" used "); 12052 TimeUtils.formatDuration(timeUsed, pw); 12053 pw.print(" ("); 12054 pw.print((timeUsed*100)/realtimeSince); 12055 pw.println("%)"); 12056 } 12057 if (r.lastCpuTime != 0) { 12058 long timeUsed = r.curCpuTime - r.lastCpuTime; 12059 pw.print(prefix); 12060 pw.print(" "); 12061 pw.print("run cpu over "); 12062 TimeUtils.formatDuration(uptimeSince, pw); 12063 pw.print(" used "); 12064 TimeUtils.formatDuration(timeUsed, pw); 12065 pw.print(" ("); 12066 pw.print((timeUsed*100)/uptimeSince); 12067 pw.println("%)"); 12068 } 12069 } 12070 } 12071 } 12072 return true; 12073 } 12074 12075 ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) { 12076 ArrayList<ProcessRecord> procs; 12077 synchronized (this) { 12078 if (args != null && args.length > start 12079 && args[start].charAt(0) != '-') { 12080 procs = new ArrayList<ProcessRecord>(); 12081 int pid = -1; 12082 try { 12083 pid = Integer.parseInt(args[start]); 12084 } catch (NumberFormatException e) { 12085 } 12086 for (int i=mLruProcesses.size()-1; i>=0; i--) { 12087 ProcessRecord proc = mLruProcesses.get(i); 12088 if (proc.pid == pid) { 12089 procs.add(proc); 12090 } else if (proc.processName.equals(args[start])) { 12091 procs.add(proc); 12092 } 12093 } 12094 if (procs.size() <= 0) { 12095 return null; 12096 } 12097 } else { 12098 procs = new ArrayList<ProcessRecord>(mLruProcesses); 12099 } 12100 } 12101 return procs; 12102 } 12103 12104 final void dumpGraphicsHardwareUsage(FileDescriptor fd, 12105 PrintWriter pw, String[] args) { 12106 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args); 12107 if (procs == null) { 12108 pw.println("No process found for: " + args[0]); 12109 return; 12110 } 12111 12112 long uptime = SystemClock.uptimeMillis(); 12113 long realtime = SystemClock.elapsedRealtime(); 12114 pw.println("Applications Graphics Acceleration Info:"); 12115 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 12116 12117 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 12118 ProcessRecord r = procs.get(i); 12119 if (r.thread != null) { 12120 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **"); 12121 pw.flush(); 12122 try { 12123 TransferPipe tp = new TransferPipe(); 12124 try { 12125 r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args); 12126 tp.go(fd); 12127 } finally { 12128 tp.kill(); 12129 } 12130 } catch (IOException e) { 12131 pw.println("Failure while dumping the app: " + r); 12132 pw.flush(); 12133 } catch (RemoteException e) { 12134 pw.println("Got a RemoteException while dumping the app " + r); 12135 pw.flush(); 12136 } 12137 } 12138 } 12139 } 12140 12141 final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) { 12142 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args); 12143 if (procs == null) { 12144 pw.println("No process found for: " + args[0]); 12145 return; 12146 } 12147 12148 pw.println("Applications Database Info:"); 12149 12150 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 12151 ProcessRecord r = procs.get(i); 12152 if (r.thread != null) { 12153 pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **"); 12154 pw.flush(); 12155 try { 12156 TransferPipe tp = new TransferPipe(); 12157 try { 12158 r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args); 12159 tp.go(fd); 12160 } finally { 12161 tp.kill(); 12162 } 12163 } catch (IOException e) { 12164 pw.println("Failure while dumping the app: " + r); 12165 pw.flush(); 12166 } catch (RemoteException e) { 12167 pw.println("Got a RemoteException while dumping the app " + r); 12168 pw.flush(); 12169 } 12170 } 12171 } 12172 } 12173 12174 final static class MemItem { 12175 final boolean isProc; 12176 final String label; 12177 final String shortLabel; 12178 final long pss; 12179 final int id; 12180 final boolean hasActivities; 12181 ArrayList<MemItem> subitems; 12182 12183 public MemItem(String _label, String _shortLabel, long _pss, int _id, 12184 boolean _hasActivities) { 12185 isProc = true; 12186 label = _label; 12187 shortLabel = _shortLabel; 12188 pss = _pss; 12189 id = _id; 12190 hasActivities = _hasActivities; 12191 } 12192 12193 public MemItem(String _label, String _shortLabel, long _pss, int _id) { 12194 isProc = false; 12195 label = _label; 12196 shortLabel = _shortLabel; 12197 pss = _pss; 12198 id = _id; 12199 hasActivities = false; 12200 } 12201 } 12202 12203 static final void dumpMemItems(PrintWriter pw, String prefix, String tag, 12204 ArrayList<MemItem> items, boolean sort, boolean isCompact) { 12205 if (sort && !isCompact) { 12206 Collections.sort(items, new Comparator<MemItem>() { 12207 @Override 12208 public int compare(MemItem lhs, MemItem rhs) { 12209 if (lhs.pss < rhs.pss) { 12210 return 1; 12211 } else if (lhs.pss > rhs.pss) { 12212 return -1; 12213 } 12214 return 0; 12215 } 12216 }); 12217 } 12218 12219 for (int i=0; i<items.size(); i++) { 12220 MemItem mi = items.get(i); 12221 if (!isCompact) { 12222 pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label); 12223 } else if (mi.isProc) { 12224 pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel); 12225 pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss); 12226 pw.println(mi.hasActivities ? ",a" : ",e"); 12227 } else { 12228 pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(","); 12229 pw.println(mi.pss); 12230 } 12231 if (mi.subitems != null) { 12232 dumpMemItems(pw, prefix + " ", mi.shortLabel, mi.subitems, 12233 true, isCompact); 12234 } 12235 } 12236 } 12237 12238 // These are in KB. 12239 static final long[] DUMP_MEM_BUCKETS = new long[] { 12240 5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024, 12241 120*1024, 160*1024, 200*1024, 12242 250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024, 12243 1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024 12244 }; 12245 12246 static final void appendMemBucket(StringBuilder out, long memKB, String label, 12247 boolean stackLike) { 12248 int start = label.lastIndexOf('.'); 12249 if (start >= 0) start++; 12250 else start = 0; 12251 int end = label.length(); 12252 for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) { 12253 if (DUMP_MEM_BUCKETS[i] >= memKB) { 12254 long bucket = DUMP_MEM_BUCKETS[i]/1024; 12255 out.append(bucket); 12256 out.append(stackLike ? "MB." : "MB "); 12257 out.append(label, start, end); 12258 return; 12259 } 12260 } 12261 out.append(memKB/1024); 12262 out.append(stackLike ? "MB." : "MB "); 12263 out.append(label, start, end); 12264 } 12265 12266 static final int[] DUMP_MEM_OOM_ADJ = new int[] { 12267 ProcessList.NATIVE_ADJ, 12268 ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ, 12269 ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ, 12270 ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ, 12271 ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ, 12272 ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ 12273 }; 12274 static final String[] DUMP_MEM_OOM_LABEL = new String[] { 12275 "Native", 12276 "System", "Persistent", "Foreground", 12277 "Visible", "Perceptible", 12278 "Heavy Weight", "Backup", 12279 "A Services", "Home", 12280 "Previous", "B Services", "Cached" 12281 }; 12282 static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] { 12283 "native", 12284 "sys", "pers", "fore", 12285 "vis", "percept", 12286 "heavy", "backup", 12287 "servicea", "home", 12288 "prev", "serviceb", "cached" 12289 }; 12290 12291 private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime, 12292 long realtime, boolean isCheckinRequest, boolean isCompact) { 12293 if (isCheckinRequest || isCompact) { 12294 // short checkin version 12295 pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime); 12296 } else { 12297 pw.println("Applications Memory Usage (kB):"); 12298 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 12299 } 12300 } 12301 12302 final void dumpApplicationMemoryUsage(FileDescriptor fd, 12303 PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) { 12304 boolean dumpDetails = false; 12305 boolean dumpFullDetails = false; 12306 boolean dumpDalvik = false; 12307 boolean oomOnly = false; 12308 boolean isCompact = false; 12309 boolean localOnly = false; 12310 12311 int opti = 0; 12312 while (opti < args.length) { 12313 String opt = args[opti]; 12314 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 12315 break; 12316 } 12317 opti++; 12318 if ("-a".equals(opt)) { 12319 dumpDetails = true; 12320 dumpFullDetails = true; 12321 dumpDalvik = true; 12322 } else if ("-d".equals(opt)) { 12323 dumpDalvik = true; 12324 } else if ("-c".equals(opt)) { 12325 isCompact = true; 12326 } else if ("--oom".equals(opt)) { 12327 oomOnly = true; 12328 } else if ("--local".equals(opt)) { 12329 localOnly = true; 12330 } else if ("-h".equals(opt)) { 12331 pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]"); 12332 pw.println(" -a: include all available information for each process."); 12333 pw.println(" -d: include dalvik details when dumping process details."); 12334 pw.println(" -c: dump in a compact machine-parseable representation."); 12335 pw.println(" --oom: only show processes organized by oom adj."); 12336 pw.println(" --local: only collect details locally, don't call process."); 12337 pw.println("If [process] is specified it can be the name or "); 12338 pw.println("pid of a specific process to dump."); 12339 return; 12340 } else { 12341 pw.println("Unknown argument: " + opt + "; use -h for help"); 12342 } 12343 } 12344 12345 final boolean isCheckinRequest = scanArgs(args, "--checkin"); 12346 long uptime = SystemClock.uptimeMillis(); 12347 long realtime = SystemClock.elapsedRealtime(); 12348 final long[] tmpLong = new long[1]; 12349 12350 ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args); 12351 if (procs == null) { 12352 // No Java processes. Maybe they want to print a native process. 12353 if (args != null && args.length > opti 12354 && args[opti].charAt(0) != '-') { 12355 ArrayList<ProcessCpuTracker.Stats> nativeProcs 12356 = new ArrayList<ProcessCpuTracker.Stats>(); 12357 updateCpuStatsNow(); 12358 int findPid = -1; 12359 try { 12360 findPid = Integer.parseInt(args[opti]); 12361 } catch (NumberFormatException e) { 12362 } 12363 synchronized (mProcessCpuThread) { 12364 final int N = mProcessCpuTracker.countStats(); 12365 for (int i=0; i<N; i++) { 12366 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 12367 if (st.pid == findPid || (st.baseName != null 12368 && st.baseName.equals(args[opti]))) { 12369 nativeProcs.add(st); 12370 } 12371 } 12372 } 12373 if (nativeProcs.size() > 0) { 12374 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, 12375 isCompact); 12376 Debug.MemoryInfo mi = null; 12377 for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) { 12378 final ProcessCpuTracker.Stats r = nativeProcs.get(i); 12379 final int pid = r.pid; 12380 if (!isCheckinRequest && dumpDetails) { 12381 pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **"); 12382 } 12383 if (mi == null) { 12384 mi = new Debug.MemoryInfo(); 12385 } 12386 if (dumpDetails || (!brief && !oomOnly)) { 12387 Debug.getMemoryInfo(pid, mi); 12388 } else { 12389 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong); 12390 mi.dalvikPrivateDirty = (int)tmpLong[0]; 12391 } 12392 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails, 12393 dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0); 12394 if (isCheckinRequest) { 12395 pw.println(); 12396 } 12397 } 12398 return; 12399 } 12400 } 12401 pw.println("No process found for: " + args[opti]); 12402 return; 12403 } 12404 12405 if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest)) { 12406 dumpDetails = true; 12407 } 12408 12409 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact); 12410 12411 String[] innerArgs = new String[args.length-opti]; 12412 System.arraycopy(args, opti, innerArgs, 0, args.length-opti); 12413 12414 ArrayList<MemItem> procMems = new ArrayList<MemItem>(); 12415 final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>(); 12416 long nativePss=0, dalvikPss=0, otherPss=0; 12417 long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS]; 12418 12419 long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length]; 12420 ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[]) 12421 new ArrayList[DUMP_MEM_OOM_LABEL.length]; 12422 12423 long totalPss = 0; 12424 long cachedPss = 0; 12425 12426 Debug.MemoryInfo mi = null; 12427 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 12428 final ProcessRecord r = procs.get(i); 12429 final IApplicationThread thread; 12430 final int pid; 12431 final int oomAdj; 12432 final boolean hasActivities; 12433 synchronized (this) { 12434 thread = r.thread; 12435 pid = r.pid; 12436 oomAdj = r.getSetAdjWithServices(); 12437 hasActivities = r.activities.size() > 0; 12438 } 12439 if (thread != null) { 12440 if (!isCheckinRequest && dumpDetails) { 12441 pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **"); 12442 } 12443 if (mi == null) { 12444 mi = new Debug.MemoryInfo(); 12445 } 12446 if (dumpDetails || (!brief && !oomOnly)) { 12447 Debug.getMemoryInfo(pid, mi); 12448 } else { 12449 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong); 12450 mi.dalvikPrivateDirty = (int)tmpLong[0]; 12451 } 12452 if (dumpDetails) { 12453 if (localOnly) { 12454 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails, 12455 dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0); 12456 if (isCheckinRequest) { 12457 pw.println(); 12458 } 12459 } else { 12460 try { 12461 pw.flush(); 12462 thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails, 12463 dumpDalvik, innerArgs); 12464 } catch (RemoteException e) { 12465 if (!isCheckinRequest) { 12466 pw.println("Got RemoteException!"); 12467 pw.flush(); 12468 } 12469 } 12470 } 12471 } 12472 12473 final long myTotalPss = mi.getTotalPss(); 12474 final long myTotalUss = mi.getTotalUss(); 12475 12476 synchronized (this) { 12477 if (r.thread != null && oomAdj == r.getSetAdjWithServices()) { 12478 // Record this for posterity if the process has been stable. 12479 r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList); 12480 } 12481 } 12482 12483 if (!isCheckinRequest && mi != null) { 12484 totalPss += myTotalPss; 12485 MemItem pssItem = new MemItem(r.processName + " (pid " + pid + 12486 (hasActivities ? " / activities)" : ")"), 12487 r.processName, myTotalPss, pid, hasActivities); 12488 procMems.add(pssItem); 12489 procMemsMap.put(pid, pssItem); 12490 12491 nativePss += mi.nativePss; 12492 dalvikPss += mi.dalvikPss; 12493 otherPss += mi.otherPss; 12494 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 12495 long mem = mi.getOtherPss(j); 12496 miscPss[j] += mem; 12497 otherPss -= mem; 12498 } 12499 12500 if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 12501 cachedPss += myTotalPss; 12502 } 12503 12504 for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) { 12505 if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex] 12506 || oomIndex == (oomPss.length-1)) { 12507 oomPss[oomIndex] += myTotalPss; 12508 if (oomProcs[oomIndex] == null) { 12509 oomProcs[oomIndex] = new ArrayList<MemItem>(); 12510 } 12511 oomProcs[oomIndex].add(pssItem); 12512 break; 12513 } 12514 } 12515 } 12516 } 12517 } 12518 12519 if (!isCheckinRequest && procs.size() > 1) { 12520 // If we are showing aggregations, also look for native processes to 12521 // include so that our aggregations are more accurate. 12522 updateCpuStatsNow(); 12523 synchronized (mProcessCpuThread) { 12524 final int N = mProcessCpuTracker.countStats(); 12525 for (int i=0; i<N; i++) { 12526 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 12527 if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) { 12528 if (mi == null) { 12529 mi = new Debug.MemoryInfo(); 12530 } 12531 if (!brief && !oomOnly) { 12532 Debug.getMemoryInfo(st.pid, mi); 12533 } else { 12534 mi.nativePss = (int)Debug.getPss(st.pid, tmpLong); 12535 mi.nativePrivateDirty = (int)tmpLong[0]; 12536 } 12537 12538 final long myTotalPss = mi.getTotalPss(); 12539 totalPss += myTotalPss; 12540 12541 MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")", 12542 st.name, myTotalPss, st.pid, false); 12543 procMems.add(pssItem); 12544 12545 nativePss += mi.nativePss; 12546 dalvikPss += mi.dalvikPss; 12547 otherPss += mi.otherPss; 12548 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 12549 long mem = mi.getOtherPss(j); 12550 miscPss[j] += mem; 12551 otherPss -= mem; 12552 } 12553 oomPss[0] += myTotalPss; 12554 if (oomProcs[0] == null) { 12555 oomProcs[0] = new ArrayList<MemItem>(); 12556 } 12557 oomProcs[0].add(pssItem); 12558 } 12559 } 12560 } 12561 12562 ArrayList<MemItem> catMems = new ArrayList<MemItem>(); 12563 12564 catMems.add(new MemItem("Native", "Native", nativePss, -1)); 12565 catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2)); 12566 catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3)); 12567 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 12568 String label = Debug.MemoryInfo.getOtherLabel(j); 12569 catMems.add(new MemItem(label, label, miscPss[j], j)); 12570 } 12571 12572 ArrayList<MemItem> oomMems = new ArrayList<MemItem>(); 12573 for (int j=0; j<oomPss.length; j++) { 12574 if (oomPss[j] != 0) { 12575 String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j] 12576 : DUMP_MEM_OOM_LABEL[j]; 12577 MemItem item = new MemItem(label, label, oomPss[j], 12578 DUMP_MEM_OOM_ADJ[j]); 12579 item.subitems = oomProcs[j]; 12580 oomMems.add(item); 12581 } 12582 } 12583 12584 if (!brief && !oomOnly && !isCompact) { 12585 pw.println(); 12586 pw.println("Total PSS by process:"); 12587 dumpMemItems(pw, " ", "proc", procMems, true, isCompact); 12588 pw.println(); 12589 } 12590 if (!isCompact) { 12591 pw.println("Total PSS by OOM adjustment:"); 12592 } 12593 dumpMemItems(pw, " ", "oom", oomMems, false, isCompact); 12594 if (!brief && !oomOnly) { 12595 PrintWriter out = categoryPw != null ? categoryPw : pw; 12596 if (!isCompact) { 12597 out.println(); 12598 out.println("Total PSS by category:"); 12599 } 12600 dumpMemItems(out, " ", "cat", catMems, true, isCompact); 12601 } 12602 if (!isCompact) { 12603 pw.println(); 12604 } 12605 MemInfoReader memInfo = new MemInfoReader(); 12606 memInfo.readMemInfo(); 12607 if (!brief) { 12608 if (!isCompact) { 12609 pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb()); 12610 pw.print(" kB (status "); 12611 switch (mLastMemoryLevel) { 12612 case ProcessStats.ADJ_MEM_FACTOR_NORMAL: 12613 pw.println("normal)"); 12614 break; 12615 case ProcessStats.ADJ_MEM_FACTOR_MODERATE: 12616 pw.println("moderate)"); 12617 break; 12618 case ProcessStats.ADJ_MEM_FACTOR_LOW: 12619 pw.println("low)"); 12620 break; 12621 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL: 12622 pw.println("critical)"); 12623 break; 12624 default: 12625 pw.print(mLastMemoryLevel); 12626 pw.println(")"); 12627 break; 12628 } 12629 pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb() 12630 + memInfo.getFreeSizeKb()); pw.print(" kB ("); 12631 pw.print(cachedPss); pw.print(" cached pss + "); 12632 pw.print(memInfo.getCachedSizeKb()); pw.print(" cached + "); 12633 pw.print(memInfo.getFreeSizeKb()); pw.println(" free)"); 12634 } else { 12635 pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(","); 12636 pw.print(cachedPss + memInfo.getCachedSizeKb() 12637 + memInfo.getFreeSizeKb()); pw.print(","); 12638 pw.println(totalPss - cachedPss); 12639 } 12640 } 12641 if (!isCompact) { 12642 pw.print(" Used RAM: "); pw.print(totalPss - cachedPss 12643 + memInfo.getBuffersSizeKb() + memInfo.getShmemSizeKb() 12644 + memInfo.getSlabSizeKb()); pw.print(" kB ("); 12645 pw.print(totalPss - cachedPss); pw.print(" used pss + "); 12646 pw.print(memInfo.getBuffersSizeKb()); pw.print(" buffers + "); 12647 pw.print(memInfo.getShmemSizeKb()); pw.print(" shmem + "); 12648 pw.print(memInfo.getSlabSizeKb()); pw.println(" slab)"); 12649 pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb() 12650 - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb() 12651 - memInfo.getBuffersSizeKb() - memInfo.getShmemSizeKb() 12652 - memInfo.getSlabSizeKb()); pw.println(" kB"); 12653 } 12654 if (!brief) { 12655 if (memInfo.getZramTotalSizeKb() != 0) { 12656 if (!isCompact) { 12657 pw.print(" ZRAM: "); pw.print(memInfo.getZramTotalSizeKb()); 12658 pw.print(" kB physical used for "); 12659 pw.print(memInfo.getSwapTotalSizeKb() 12660 - memInfo.getSwapFreeSizeKb()); 12661 pw.print(" kB in swap ("); 12662 pw.print(memInfo.getSwapTotalSizeKb()); 12663 pw.println(" kB total swap)"); 12664 } else { 12665 pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(","); 12666 pw.print(memInfo.getSwapTotalSizeKb()); pw.print(","); 12667 pw.println(memInfo.getSwapFreeSizeKb()); 12668 } 12669 } 12670 final int[] SINGLE_LONG_FORMAT = new int[] { 12671 Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG 12672 }; 12673 long[] longOut = new long[1]; 12674 Process.readProcFile("/sys/kernel/mm/ksm/pages_shared", 12675 SINGLE_LONG_FORMAT, null, longOut, null); 12676 long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024; 12677 longOut[0] = 0; 12678 Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing", 12679 SINGLE_LONG_FORMAT, null, longOut, null); 12680 long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024; 12681 longOut[0] = 0; 12682 Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared", 12683 SINGLE_LONG_FORMAT, null, longOut, null); 12684 long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024; 12685 longOut[0] = 0; 12686 Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile", 12687 SINGLE_LONG_FORMAT, null, longOut, null); 12688 long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024; 12689 if (!isCompact) { 12690 if (sharing != 0 || shared != 0 || unshared != 0 || voltile != 0) { 12691 pw.print(" KSM: "); pw.print(sharing); 12692 pw.print(" kB saved from shared "); 12693 pw.print(shared); pw.println(" kB"); 12694 pw.print(" "); pw.print(unshared); pw.print(" kB unshared; "); 12695 pw.print(voltile); pw.println(" kB volatile"); 12696 } 12697 pw.print(" Tuning: "); 12698 pw.print(ActivityManager.staticGetMemoryClass()); 12699 pw.print(" (large "); 12700 pw.print(ActivityManager.staticGetLargeMemoryClass()); 12701 pw.print("), oom "); 12702 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024); 12703 pw.print(" kB"); 12704 pw.print(", restore limit "); 12705 pw.print(mProcessList.getCachedRestoreThresholdKb()); 12706 pw.print(" kB"); 12707 if (ActivityManager.isLowRamDeviceStatic()) { 12708 pw.print(" (low-ram)"); 12709 } 12710 if (ActivityManager.isHighEndGfx()) { 12711 pw.print(" (high-end-gfx)"); 12712 } 12713 pw.println(); 12714 } else { 12715 pw.print("ksm,"); pw.print(sharing); pw.print(","); 12716 pw.print(shared); pw.print(","); pw.print(unshared); pw.print(","); 12717 pw.println(voltile); 12718 pw.print("tuning,"); 12719 pw.print(ActivityManager.staticGetMemoryClass()); 12720 pw.print(','); 12721 pw.print(ActivityManager.staticGetLargeMemoryClass()); 12722 pw.print(','); 12723 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024); 12724 if (ActivityManager.isLowRamDeviceStatic()) { 12725 pw.print(",low-ram"); 12726 } 12727 if (ActivityManager.isHighEndGfx()) { 12728 pw.print(",high-end-gfx"); 12729 } 12730 pw.println(); 12731 } 12732 } 12733 } 12734 } 12735 12736 /** 12737 * Searches array of arguments for the specified string 12738 * @param args array of argument strings 12739 * @param value value to search for 12740 * @return true if the value is contained in the array 12741 */ 12742 private static boolean scanArgs(String[] args, String value) { 12743 if (args != null) { 12744 for (String arg : args) { 12745 if (value.equals(arg)) { 12746 return true; 12747 } 12748 } 12749 } 12750 return false; 12751 } 12752 12753 private final boolean removeDyingProviderLocked(ProcessRecord proc, 12754 ContentProviderRecord cpr, boolean always) { 12755 final boolean inLaunching = mLaunchingProviders.contains(cpr); 12756 12757 if (!inLaunching || always) { 12758 synchronized (cpr) { 12759 cpr.launchingApp = null; 12760 cpr.notifyAll(); 12761 } 12762 mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid)); 12763 String names[] = cpr.info.authority.split(";"); 12764 for (int j = 0; j < names.length; j++) { 12765 mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid)); 12766 } 12767 } 12768 12769 for (int i=0; i<cpr.connections.size(); i++) { 12770 ContentProviderConnection conn = cpr.connections.get(i); 12771 if (conn.waiting) { 12772 // If this connection is waiting for the provider, then we don't 12773 // need to mess with its process unless we are always removing 12774 // or for some reason the provider is not currently launching. 12775 if (inLaunching && !always) { 12776 continue; 12777 } 12778 } 12779 ProcessRecord capp = conn.client; 12780 conn.dead = true; 12781 if (conn.stableCount > 0) { 12782 if (!capp.persistent && capp.thread != null 12783 && capp.pid != 0 12784 && capp.pid != MY_PID) { 12785 killUnneededProcessLocked(capp, "depends on provider " 12786 + cpr.name.flattenToShortString() 12787 + " in dying proc " + (proc != null ? proc.processName : "??")); 12788 } 12789 } else if (capp.thread != null && conn.provider.provider != null) { 12790 try { 12791 capp.thread.unstableProviderDied(conn.provider.provider.asBinder()); 12792 } catch (RemoteException e) { 12793 } 12794 // In the protocol here, we don't expect the client to correctly 12795 // clean up this connection, we'll just remove it. 12796 cpr.connections.remove(i); 12797 conn.client.conProviders.remove(conn); 12798 } 12799 } 12800 12801 if (inLaunching && always) { 12802 mLaunchingProviders.remove(cpr); 12803 } 12804 return inLaunching; 12805 } 12806 12807 /** 12808 * Main code for cleaning up a process when it has gone away. This is 12809 * called both as a result of the process dying, or directly when stopping 12810 * a process when running in single process mode. 12811 */ 12812 private final void cleanUpApplicationRecordLocked(ProcessRecord app, 12813 boolean restarting, boolean allowRestart, int index) { 12814 if (index >= 0) { 12815 removeLruProcessLocked(app); 12816 ProcessList.remove(app.pid); 12817 } 12818 12819 mProcessesToGc.remove(app); 12820 mPendingPssProcesses.remove(app); 12821 12822 // Dismiss any open dialogs. 12823 if (app.crashDialog != null && !app.forceCrashReport) { 12824 app.crashDialog.dismiss(); 12825 app.crashDialog = null; 12826 } 12827 if (app.anrDialog != null) { 12828 app.anrDialog.dismiss(); 12829 app.anrDialog = null; 12830 } 12831 if (app.waitDialog != null) { 12832 app.waitDialog.dismiss(); 12833 app.waitDialog = null; 12834 } 12835 12836 app.crashing = false; 12837 app.notResponding = false; 12838 12839 app.resetPackageList(mProcessStats); 12840 app.unlinkDeathRecipient(); 12841 app.makeInactive(mProcessStats); 12842 app.forcingToForeground = null; 12843 updateProcessForegroundLocked(app, false, false); 12844 app.foregroundActivities = false; 12845 app.hasShownUi = false; 12846 app.treatLikeActivity = false; 12847 app.hasAboveClient = false; 12848 app.hasClientActivities = false; 12849 12850 mServices.killServicesLocked(app, allowRestart); 12851 12852 boolean restart = false; 12853 12854 // Remove published content providers. 12855 for (int i=app.pubProviders.size()-1; i>=0; i--) { 12856 ContentProviderRecord cpr = app.pubProviders.valueAt(i); 12857 final boolean always = app.bad || !allowRestart; 12858 if (removeDyingProviderLocked(app, cpr, always) || always) { 12859 // We left the provider in the launching list, need to 12860 // restart it. 12861 restart = true; 12862 } 12863 12864 cpr.provider = null; 12865 cpr.proc = null; 12866 } 12867 app.pubProviders.clear(); 12868 12869 // Take care of any launching providers waiting for this process. 12870 if (checkAppInLaunchingProvidersLocked(app, false)) { 12871 restart = true; 12872 } 12873 12874 // Unregister from connected content providers. 12875 if (!app.conProviders.isEmpty()) { 12876 for (int i=0; i<app.conProviders.size(); i++) { 12877 ContentProviderConnection conn = app.conProviders.get(i); 12878 conn.provider.connections.remove(conn); 12879 } 12880 app.conProviders.clear(); 12881 } 12882 12883 // At this point there may be remaining entries in mLaunchingProviders 12884 // where we were the only one waiting, so they are no longer of use. 12885 // Look for these and clean up if found. 12886 // XXX Commented out for now. Trying to figure out a way to reproduce 12887 // the actual situation to identify what is actually going on. 12888 if (false) { 12889 for (int i=0; i<mLaunchingProviders.size(); i++) { 12890 ContentProviderRecord cpr = (ContentProviderRecord) 12891 mLaunchingProviders.get(i); 12892 if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) { 12893 synchronized (cpr) { 12894 cpr.launchingApp = null; 12895 cpr.notifyAll(); 12896 } 12897 } 12898 } 12899 } 12900 12901 skipCurrentReceiverLocked(app); 12902 12903 // Unregister any receivers. 12904 for (int i=app.receivers.size()-1; i>=0; i--) { 12905 removeReceiverLocked(app.receivers.valueAt(i)); 12906 } 12907 app.receivers.clear(); 12908 12909 // If the app is undergoing backup, tell the backup manager about it 12910 if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) { 12911 if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App " 12912 + mBackupTarget.appInfo + " died during backup"); 12913 try { 12914 IBackupManager bm = IBackupManager.Stub.asInterface( 12915 ServiceManager.getService(Context.BACKUP_SERVICE)); 12916 bm.agentDisconnected(app.info.packageName); 12917 } catch (RemoteException e) { 12918 // can't happen; backup manager is local 12919 } 12920 } 12921 12922 for (int i = mPendingProcessChanges.size()-1; i>=0; i--) { 12923 ProcessChangeItem item = mPendingProcessChanges.get(i); 12924 if (item.pid == app.pid) { 12925 mPendingProcessChanges.remove(i); 12926 mAvailProcessChanges.add(item); 12927 } 12928 } 12929 mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget(); 12930 12931 // If the caller is restarting this app, then leave it in its 12932 // current lists and let the caller take care of it. 12933 if (restarting) { 12934 return; 12935 } 12936 12937 if (!app.persistent || app.isolated) { 12938 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, 12939 "Removing non-persistent process during cleanup: " + app); 12940 mProcessNames.remove(app.processName, app.uid); 12941 mIsolatedProcesses.remove(app.uid); 12942 if (mHeavyWeightProcess == app) { 12943 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 12944 mHeavyWeightProcess.userId, 0)); 12945 mHeavyWeightProcess = null; 12946 } 12947 } else if (!app.removed) { 12948 // This app is persistent, so we need to keep its record around. 12949 // If it is not already on the pending app list, add it there 12950 // and start a new process for it. 12951 if (mPersistentStartingProcesses.indexOf(app) < 0) { 12952 mPersistentStartingProcesses.add(app); 12953 restart = true; 12954 } 12955 } 12956 if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG, 12957 "Clean-up removing on hold: " + app); 12958 mProcessesOnHold.remove(app); 12959 12960 if (app == mHomeProcess) { 12961 mHomeProcess = null; 12962 } 12963 if (app == mPreviousProcess) { 12964 mPreviousProcess = null; 12965 } 12966 12967 if (restart && !app.isolated) { 12968 // We have components that still need to be running in the 12969 // process, so re-launch it. 12970 mProcessNames.put(app.processName, app.uid, app); 12971 startProcessLocked(app, "restart", app.processName); 12972 } else if (app.pid > 0 && app.pid != MY_PID) { 12973 // Goodbye! 12974 boolean removed; 12975 synchronized (mPidsSelfLocked) { 12976 mPidsSelfLocked.remove(app.pid); 12977 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 12978 } 12979 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH, 12980 app.processName, app.info.uid); 12981 if (app.isolated) { 12982 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 12983 } 12984 app.setPid(0); 12985 } 12986 } 12987 12988 boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) { 12989 // Look through the content providers we are waiting to have launched, 12990 // and if any run in this process then either schedule a restart of 12991 // the process or kill the client waiting for it if this process has 12992 // gone bad. 12993 int NL = mLaunchingProviders.size(); 12994 boolean restart = false; 12995 for (int i=0; i<NL; i++) { 12996 ContentProviderRecord cpr = mLaunchingProviders.get(i); 12997 if (cpr.launchingApp == app) { 12998 if (!alwaysBad && !app.bad) { 12999 restart = true; 13000 } else { 13001 removeDyingProviderLocked(app, cpr, true); 13002 // cpr should have been removed from mLaunchingProviders 13003 NL = mLaunchingProviders.size(); 13004 i--; 13005 } 13006 } 13007 } 13008 return restart; 13009 } 13010 13011 // ========================================================= 13012 // SERVICES 13013 // ========================================================= 13014 13015 public List<ActivityManager.RunningServiceInfo> getServices(int maxNum, 13016 int flags) { 13017 enforceNotIsolatedCaller("getServices"); 13018 synchronized (this) { 13019 return mServices.getRunningServiceInfoLocked(maxNum, flags); 13020 } 13021 } 13022 13023 public PendingIntent getRunningServiceControlPanel(ComponentName name) { 13024 enforceNotIsolatedCaller("getRunningServiceControlPanel"); 13025 synchronized (this) { 13026 return mServices.getRunningServiceControlPanelLocked(name); 13027 } 13028 } 13029 13030 public ComponentName startService(IApplicationThread caller, Intent service, 13031 String resolvedType, int userId) { 13032 enforceNotIsolatedCaller("startService"); 13033 // Refuse possible leaked file descriptors 13034 if (service != null && service.hasFileDescriptors() == true) { 13035 throw new IllegalArgumentException("File descriptors passed in Intent"); 13036 } 13037 13038 if (DEBUG_SERVICE) 13039 Slog.v(TAG, "startService: " + service + " type=" + resolvedType); 13040 synchronized(this) { 13041 final int callingPid = Binder.getCallingPid(); 13042 final int callingUid = Binder.getCallingUid(); 13043 final long origId = Binder.clearCallingIdentity(); 13044 ComponentName res = mServices.startServiceLocked(caller, service, 13045 resolvedType, callingPid, callingUid, userId); 13046 Binder.restoreCallingIdentity(origId); 13047 return res; 13048 } 13049 } 13050 13051 ComponentName startServiceInPackage(int uid, 13052 Intent service, String resolvedType, int userId) { 13053 synchronized(this) { 13054 if (DEBUG_SERVICE) 13055 Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType); 13056 final long origId = Binder.clearCallingIdentity(); 13057 ComponentName res = mServices.startServiceLocked(null, service, 13058 resolvedType, -1, uid, userId); 13059 Binder.restoreCallingIdentity(origId); 13060 return res; 13061 } 13062 } 13063 13064 public int stopService(IApplicationThread caller, Intent service, 13065 String resolvedType, int userId) { 13066 enforceNotIsolatedCaller("stopService"); 13067 // Refuse possible leaked file descriptors 13068 if (service != null && service.hasFileDescriptors() == true) { 13069 throw new IllegalArgumentException("File descriptors passed in Intent"); 13070 } 13071 13072 synchronized(this) { 13073 return mServices.stopServiceLocked(caller, service, resolvedType, userId); 13074 } 13075 } 13076 13077 public IBinder peekService(Intent service, String resolvedType) { 13078 enforceNotIsolatedCaller("peekService"); 13079 // Refuse possible leaked file descriptors 13080 if (service != null && service.hasFileDescriptors() == true) { 13081 throw new IllegalArgumentException("File descriptors passed in Intent"); 13082 } 13083 synchronized(this) { 13084 return mServices.peekServiceLocked(service, resolvedType); 13085 } 13086 } 13087 13088 public boolean stopServiceToken(ComponentName className, IBinder token, 13089 int startId) { 13090 synchronized(this) { 13091 return mServices.stopServiceTokenLocked(className, token, startId); 13092 } 13093 } 13094 13095 public void setServiceForeground(ComponentName className, IBinder token, 13096 int id, Notification notification, boolean removeNotification) { 13097 synchronized(this) { 13098 mServices.setServiceForegroundLocked(className, token, id, notification, 13099 removeNotification); 13100 } 13101 } 13102 13103 public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll, 13104 boolean requireFull, String name, String callerPackage) { 13105 final int callingUserId = UserHandle.getUserId(callingUid); 13106 if (callingUserId != userId) { 13107 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 13108 if ((requireFull || checkComponentPermission( 13109 android.Manifest.permission.INTERACT_ACROSS_USERS, 13110 callingPid, callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) 13111 && checkComponentPermission( 13112 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 13113 callingPid, callingUid, -1, true) 13114 != PackageManager.PERMISSION_GRANTED) { 13115 if (userId == UserHandle.USER_CURRENT_OR_SELF) { 13116 // In this case, they would like to just execute as their 13117 // owner user instead of failing. 13118 userId = callingUserId; 13119 } else { 13120 StringBuilder builder = new StringBuilder(128); 13121 builder.append("Permission Denial: "); 13122 builder.append(name); 13123 if (callerPackage != null) { 13124 builder.append(" from "); 13125 builder.append(callerPackage); 13126 } 13127 builder.append(" asks to run as user "); 13128 builder.append(userId); 13129 builder.append(" but is calling from user "); 13130 builder.append(UserHandle.getUserId(callingUid)); 13131 builder.append("; this requires "); 13132 builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL); 13133 if (!requireFull) { 13134 builder.append(" or "); 13135 builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS); 13136 } 13137 String msg = builder.toString(); 13138 Slog.w(TAG, msg); 13139 throw new SecurityException(msg); 13140 } 13141 } 13142 } 13143 if (userId == UserHandle.USER_CURRENT 13144 || userId == UserHandle.USER_CURRENT_OR_SELF) { 13145 // Note that we may be accessing this outside of a lock... 13146 // shouldn't be a big deal, if this is being called outside 13147 // of a locked context there is intrinsically a race with 13148 // the value the caller will receive and someone else changing it. 13149 userId = mCurrentUserId; 13150 } 13151 if (!allowAll && userId < 0) { 13152 throw new IllegalArgumentException( 13153 "Call does not support special user #" + userId); 13154 } 13155 } 13156 return userId; 13157 } 13158 13159 boolean isSingleton(String componentProcessName, ApplicationInfo aInfo, 13160 String className, int flags) { 13161 boolean result = false; 13162 if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) { 13163 if ((flags&ServiceInfo.FLAG_SINGLE_USER) != 0) { 13164 if (ActivityManager.checkUidPermission( 13165 android.Manifest.permission.INTERACT_ACROSS_USERS, 13166 aInfo.uid) != PackageManager.PERMISSION_GRANTED) { 13167 ComponentName comp = new ComponentName(aInfo.packageName, className); 13168 String msg = "Permission Denial: Component " + comp.flattenToShortString() 13169 + " requests FLAG_SINGLE_USER, but app does not hold " 13170 + android.Manifest.permission.INTERACT_ACROSS_USERS; 13171 Slog.w(TAG, msg); 13172 throw new SecurityException(msg); 13173 } 13174 result = true; 13175 } 13176 } else if (componentProcessName == aInfo.packageName) { 13177 result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0; 13178 } else if ("system".equals(componentProcessName)) { 13179 result = true; 13180 } 13181 if (DEBUG_MU) { 13182 Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo 13183 + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result); 13184 } 13185 return result; 13186 } 13187 13188 public int bindService(IApplicationThread caller, IBinder token, 13189 Intent service, String resolvedType, 13190 IServiceConnection connection, int flags, int userId) { 13191 enforceNotIsolatedCaller("bindService"); 13192 // Refuse possible leaked file descriptors 13193 if (service != null && service.hasFileDescriptors() == true) { 13194 throw new IllegalArgumentException("File descriptors passed in Intent"); 13195 } 13196 13197 synchronized(this) { 13198 return mServices.bindServiceLocked(caller, token, service, resolvedType, 13199 connection, flags, userId); 13200 } 13201 } 13202 13203 public boolean unbindService(IServiceConnection connection) { 13204 synchronized (this) { 13205 return mServices.unbindServiceLocked(connection); 13206 } 13207 } 13208 13209 public void publishService(IBinder token, Intent intent, IBinder service) { 13210 // Refuse possible leaked file descriptors 13211 if (intent != null && intent.hasFileDescriptors() == true) { 13212 throw new IllegalArgumentException("File descriptors passed in Intent"); 13213 } 13214 13215 synchronized(this) { 13216 if (!(token instanceof ServiceRecord)) { 13217 throw new IllegalArgumentException("Invalid service token"); 13218 } 13219 mServices.publishServiceLocked((ServiceRecord)token, intent, service); 13220 } 13221 } 13222 13223 public void unbindFinished(IBinder token, Intent intent, boolean doRebind) { 13224 // Refuse possible leaked file descriptors 13225 if (intent != null && intent.hasFileDescriptors() == true) { 13226 throw new IllegalArgumentException("File descriptors passed in Intent"); 13227 } 13228 13229 synchronized(this) { 13230 mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind); 13231 } 13232 } 13233 13234 public void serviceDoneExecuting(IBinder token, int type, int startId, int res) { 13235 synchronized(this) { 13236 if (!(token instanceof ServiceRecord)) { 13237 throw new IllegalArgumentException("Invalid service token"); 13238 } 13239 mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res); 13240 } 13241 } 13242 13243 // ========================================================= 13244 // BACKUP AND RESTORE 13245 // ========================================================= 13246 13247 // Cause the target app to be launched if necessary and its backup agent 13248 // instantiated. The backup agent will invoke backupAgentCreated() on the 13249 // activity manager to announce its creation. 13250 public boolean bindBackupAgent(ApplicationInfo app, int backupMode) { 13251 if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode); 13252 enforceCallingPermission("android.permission.BACKUP", "bindBackupAgent"); 13253 13254 synchronized(this) { 13255 // !!! TODO: currently no check here that we're already bound 13256 BatteryStatsImpl.Uid.Pkg.Serv ss = null; 13257 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 13258 synchronized (stats) { 13259 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name); 13260 } 13261 13262 // Backup agent is now in use, its package can't be stopped. 13263 try { 13264 AppGlobals.getPackageManager().setPackageStoppedState( 13265 app.packageName, false, UserHandle.getUserId(app.uid)); 13266 } catch (RemoteException e) { 13267 } catch (IllegalArgumentException e) { 13268 Slog.w(TAG, "Failed trying to unstop package " 13269 + app.packageName + ": " + e); 13270 } 13271 13272 BackupRecord r = new BackupRecord(ss, app, backupMode); 13273 ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL) 13274 ? new ComponentName(app.packageName, app.backupAgentName) 13275 : new ComponentName("android", "FullBackupAgent"); 13276 // startProcessLocked() returns existing proc's record if it's already running 13277 ProcessRecord proc = startProcessLocked(app.processName, app, 13278 false, 0, "backup", hostingName, false, false, false); 13279 if (proc == null) { 13280 Slog.e(TAG, "Unable to start backup agent process " + r); 13281 return false; 13282 } 13283 13284 r.app = proc; 13285 mBackupTarget = r; 13286 mBackupAppName = app.packageName; 13287 13288 // Try not to kill the process during backup 13289 updateOomAdjLocked(proc); 13290 13291 // If the process is already attached, schedule the creation of the backup agent now. 13292 // If it is not yet live, this will be done when it attaches to the framework. 13293 if (proc.thread != null) { 13294 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc); 13295 try { 13296 proc.thread.scheduleCreateBackupAgent(app, 13297 compatibilityInfoForPackageLocked(app), backupMode); 13298 } catch (RemoteException e) { 13299 // Will time out on the backup manager side 13300 } 13301 } else { 13302 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach"); 13303 } 13304 // Invariants: at this point, the target app process exists and the application 13305 // is either already running or in the process of coming up. mBackupTarget and 13306 // mBackupAppName describe the app, so that when it binds back to the AM we 13307 // know that it's scheduled for a backup-agent operation. 13308 } 13309 13310 return true; 13311 } 13312 13313 @Override 13314 public void clearPendingBackup() { 13315 if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup"); 13316 enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup"); 13317 13318 synchronized (this) { 13319 mBackupTarget = null; 13320 mBackupAppName = null; 13321 } 13322 } 13323 13324 // A backup agent has just come up 13325 public void backupAgentCreated(String agentPackageName, IBinder agent) { 13326 if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName 13327 + " = " + agent); 13328 13329 synchronized(this) { 13330 if (!agentPackageName.equals(mBackupAppName)) { 13331 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!"); 13332 return; 13333 } 13334 } 13335 13336 long oldIdent = Binder.clearCallingIdentity(); 13337 try { 13338 IBackupManager bm = IBackupManager.Stub.asInterface( 13339 ServiceManager.getService(Context.BACKUP_SERVICE)); 13340 bm.agentConnected(agentPackageName, agent); 13341 } catch (RemoteException e) { 13342 // can't happen; the backup manager service is local 13343 } catch (Exception e) { 13344 Slog.w(TAG, "Exception trying to deliver BackupAgent binding: "); 13345 e.printStackTrace(); 13346 } finally { 13347 Binder.restoreCallingIdentity(oldIdent); 13348 } 13349 } 13350 13351 // done with this agent 13352 public void unbindBackupAgent(ApplicationInfo appInfo) { 13353 if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo); 13354 if (appInfo == null) { 13355 Slog.w(TAG, "unbind backup agent for null app"); 13356 return; 13357 } 13358 13359 synchronized(this) { 13360 try { 13361 if (mBackupAppName == null) { 13362 Slog.w(TAG, "Unbinding backup agent with no active backup"); 13363 return; 13364 } 13365 13366 if (!mBackupAppName.equals(appInfo.packageName)) { 13367 Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target"); 13368 return; 13369 } 13370 13371 // Not backing this app up any more; reset its OOM adjustment 13372 final ProcessRecord proc = mBackupTarget.app; 13373 updateOomAdjLocked(proc); 13374 13375 // If the app crashed during backup, 'thread' will be null here 13376 if (proc.thread != null) { 13377 try { 13378 proc.thread.scheduleDestroyBackupAgent(appInfo, 13379 compatibilityInfoForPackageLocked(appInfo)); 13380 } catch (Exception e) { 13381 Slog.e(TAG, "Exception when unbinding backup agent:"); 13382 e.printStackTrace(); 13383 } 13384 } 13385 } finally { 13386 mBackupTarget = null; 13387 mBackupAppName = null; 13388 } 13389 } 13390 } 13391 // ========================================================= 13392 // BROADCASTS 13393 // ========================================================= 13394 13395 private final List getStickiesLocked(String action, IntentFilter filter, 13396 List cur, int userId) { 13397 final ContentResolver resolver = mContext.getContentResolver(); 13398 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 13399 if (stickies == null) { 13400 return cur; 13401 } 13402 final ArrayList<Intent> list = stickies.get(action); 13403 if (list == null) { 13404 return cur; 13405 } 13406 int N = list.size(); 13407 for (int i=0; i<N; i++) { 13408 Intent intent = list.get(i); 13409 if (filter.match(resolver, intent, true, TAG) >= 0) { 13410 if (cur == null) { 13411 cur = new ArrayList<Intent>(); 13412 } 13413 cur.add(intent); 13414 } 13415 } 13416 return cur; 13417 } 13418 13419 boolean isPendingBroadcastProcessLocked(int pid) { 13420 return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid) 13421 || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid); 13422 } 13423 13424 void skipPendingBroadcastLocked(int pid) { 13425 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 13426 for (BroadcastQueue queue : mBroadcastQueues) { 13427 queue.skipPendingBroadcastLocked(pid); 13428 } 13429 } 13430 13431 // The app just attached; send any pending broadcasts that it should receive 13432 boolean sendPendingBroadcastsLocked(ProcessRecord app) { 13433 boolean didSomething = false; 13434 for (BroadcastQueue queue : mBroadcastQueues) { 13435 didSomething |= queue.sendPendingBroadcastsLocked(app); 13436 } 13437 return didSomething; 13438 } 13439 13440 public Intent registerReceiver(IApplicationThread caller, String callerPackage, 13441 IIntentReceiver receiver, IntentFilter filter, String permission, int userId) { 13442 enforceNotIsolatedCaller("registerReceiver"); 13443 int callingUid; 13444 int callingPid; 13445 synchronized(this) { 13446 ProcessRecord callerApp = null; 13447 if (caller != null) { 13448 callerApp = getRecordForAppLocked(caller); 13449 if (callerApp == null) { 13450 throw new SecurityException( 13451 "Unable to find app for caller " + caller 13452 + " (pid=" + Binder.getCallingPid() 13453 + ") when registering receiver " + receiver); 13454 } 13455 if (callerApp.info.uid != Process.SYSTEM_UID && 13456 !callerApp.pkgList.containsKey(callerPackage) && 13457 !"android".equals(callerPackage)) { 13458 throw new SecurityException("Given caller package " + callerPackage 13459 + " is not running in process " + callerApp); 13460 } 13461 callingUid = callerApp.info.uid; 13462 callingPid = callerApp.pid; 13463 } else { 13464 callerPackage = null; 13465 callingUid = Binder.getCallingUid(); 13466 callingPid = Binder.getCallingPid(); 13467 } 13468 13469 userId = this.handleIncomingUser(callingPid, callingUid, userId, 13470 true, true, "registerReceiver", callerPackage); 13471 13472 List allSticky = null; 13473 13474 // Look for any matching sticky broadcasts... 13475 Iterator actions = filter.actionsIterator(); 13476 if (actions != null) { 13477 while (actions.hasNext()) { 13478 String action = (String)actions.next(); 13479 allSticky = getStickiesLocked(action, filter, allSticky, 13480 UserHandle.USER_ALL); 13481 allSticky = getStickiesLocked(action, filter, allSticky, 13482 UserHandle.getUserId(callingUid)); 13483 } 13484 } else { 13485 allSticky = getStickiesLocked(null, filter, allSticky, 13486 UserHandle.USER_ALL); 13487 allSticky = getStickiesLocked(null, filter, allSticky, 13488 UserHandle.getUserId(callingUid)); 13489 } 13490 13491 // The first sticky in the list is returned directly back to 13492 // the client. 13493 Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null; 13494 13495 if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter 13496 + ": " + sticky); 13497 13498 if (receiver == null) { 13499 return sticky; 13500 } 13501 13502 ReceiverList rl 13503 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder()); 13504 if (rl == null) { 13505 rl = new ReceiverList(this, callerApp, callingPid, callingUid, 13506 userId, receiver); 13507 if (rl.app != null) { 13508 rl.app.receivers.add(rl); 13509 } else { 13510 try { 13511 receiver.asBinder().linkToDeath(rl, 0); 13512 } catch (RemoteException e) { 13513 return sticky; 13514 } 13515 rl.linkedToDeath = true; 13516 } 13517 mRegisteredReceivers.put(receiver.asBinder(), rl); 13518 } else if (rl.uid != callingUid) { 13519 throw new IllegalArgumentException( 13520 "Receiver requested to register for uid " + callingUid 13521 + " was previously registered for uid " + rl.uid); 13522 } else if (rl.pid != callingPid) { 13523 throw new IllegalArgumentException( 13524 "Receiver requested to register for pid " + callingPid 13525 + " was previously registered for pid " + rl.pid); 13526 } else if (rl.userId != userId) { 13527 throw new IllegalArgumentException( 13528 "Receiver requested to register for user " + userId 13529 + " was previously registered for user " + rl.userId); 13530 } 13531 BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage, 13532 permission, callingUid, userId); 13533 rl.add(bf); 13534 if (!bf.debugCheck()) { 13535 Slog.w(TAG, "==> For Dynamic broadast"); 13536 } 13537 mReceiverResolver.addFilter(bf); 13538 13539 // Enqueue broadcasts for all existing stickies that match 13540 // this filter. 13541 if (allSticky != null) { 13542 ArrayList receivers = new ArrayList(); 13543 receivers.add(bf); 13544 13545 int N = allSticky.size(); 13546 for (int i=0; i<N; i++) { 13547 Intent intent = (Intent)allSticky.get(i); 13548 BroadcastQueue queue = broadcastQueueForIntent(intent); 13549 BroadcastRecord r = new BroadcastRecord(queue, intent, null, 13550 null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0, 13551 null, null, false, true, true, -1); 13552 queue.enqueueParallelBroadcastLocked(r); 13553 queue.scheduleBroadcastsLocked(); 13554 } 13555 } 13556 13557 return sticky; 13558 } 13559 } 13560 13561 public void unregisterReceiver(IIntentReceiver receiver) { 13562 if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver); 13563 13564 final long origId = Binder.clearCallingIdentity(); 13565 try { 13566 boolean doTrim = false; 13567 13568 synchronized(this) { 13569 ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder()); 13570 if (rl != null) { 13571 if (rl.curBroadcast != null) { 13572 BroadcastRecord r = rl.curBroadcast; 13573 final boolean doNext = finishReceiverLocked( 13574 receiver.asBinder(), r.resultCode, r.resultData, 13575 r.resultExtras, r.resultAbort); 13576 if (doNext) { 13577 doTrim = true; 13578 r.queue.processNextBroadcast(false); 13579 } 13580 } 13581 13582 if (rl.app != null) { 13583 rl.app.receivers.remove(rl); 13584 } 13585 removeReceiverLocked(rl); 13586 if (rl.linkedToDeath) { 13587 rl.linkedToDeath = false; 13588 rl.receiver.asBinder().unlinkToDeath(rl, 0); 13589 } 13590 } 13591 } 13592 13593 // If we actually concluded any broadcasts, we might now be able 13594 // to trim the recipients' apps from our working set 13595 if (doTrim) { 13596 trimApplications(); 13597 return; 13598 } 13599 13600 } finally { 13601 Binder.restoreCallingIdentity(origId); 13602 } 13603 } 13604 13605 void removeReceiverLocked(ReceiverList rl) { 13606 mRegisteredReceivers.remove(rl.receiver.asBinder()); 13607 int N = rl.size(); 13608 for (int i=0; i<N; i++) { 13609 mReceiverResolver.removeFilter(rl.get(i)); 13610 } 13611 } 13612 13613 private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) { 13614 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 13615 ProcessRecord r = mLruProcesses.get(i); 13616 if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) { 13617 try { 13618 r.thread.dispatchPackageBroadcast(cmd, packages); 13619 } catch (RemoteException ex) { 13620 } 13621 } 13622 } 13623 } 13624 13625 private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType, 13626 int[] users) { 13627 List<ResolveInfo> receivers = null; 13628 try { 13629 HashSet<ComponentName> singleUserReceivers = null; 13630 boolean scannedFirstReceivers = false; 13631 for (int user : users) { 13632 List<ResolveInfo> newReceivers = AppGlobals.getPackageManager() 13633 .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user); 13634 if (user != 0 && newReceivers != null) { 13635 // If this is not the primary user, we need to check for 13636 // any receivers that should be filtered out. 13637 for (int i=0; i<newReceivers.size(); i++) { 13638 ResolveInfo ri = newReceivers.get(i); 13639 if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) { 13640 newReceivers.remove(i); 13641 i--; 13642 } 13643 } 13644 } 13645 if (newReceivers != null && newReceivers.size() == 0) { 13646 newReceivers = null; 13647 } 13648 if (receivers == null) { 13649 receivers = newReceivers; 13650 } else if (newReceivers != null) { 13651 // We need to concatenate the additional receivers 13652 // found with what we have do far. This would be easy, 13653 // but we also need to de-dup any receivers that are 13654 // singleUser. 13655 if (!scannedFirstReceivers) { 13656 // Collect any single user receivers we had already retrieved. 13657 scannedFirstReceivers = true; 13658 for (int i=0; i<receivers.size(); i++) { 13659 ResolveInfo ri = receivers.get(i); 13660 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 13661 ComponentName cn = new ComponentName( 13662 ri.activityInfo.packageName, ri.activityInfo.name); 13663 if (singleUserReceivers == null) { 13664 singleUserReceivers = new HashSet<ComponentName>(); 13665 } 13666 singleUserReceivers.add(cn); 13667 } 13668 } 13669 } 13670 // Add the new results to the existing results, tracking 13671 // and de-dupping single user receivers. 13672 for (int i=0; i<newReceivers.size(); i++) { 13673 ResolveInfo ri = newReceivers.get(i); 13674 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 13675 ComponentName cn = new ComponentName( 13676 ri.activityInfo.packageName, ri.activityInfo.name); 13677 if (singleUserReceivers == null) { 13678 singleUserReceivers = new HashSet<ComponentName>(); 13679 } 13680 if (!singleUserReceivers.contains(cn)) { 13681 singleUserReceivers.add(cn); 13682 receivers.add(ri); 13683 } 13684 } else { 13685 receivers.add(ri); 13686 } 13687 } 13688 } 13689 } 13690 } catch (RemoteException ex) { 13691 // pm is in same process, this will never happen. 13692 } 13693 return receivers; 13694 } 13695 13696 private final int broadcastIntentLocked(ProcessRecord callerApp, 13697 String callerPackage, Intent intent, String resolvedType, 13698 IIntentReceiver resultTo, int resultCode, String resultData, 13699 Bundle map, String requiredPermission, int appOp, 13700 boolean ordered, boolean sticky, int callingPid, int callingUid, 13701 int userId) { 13702 intent = new Intent(intent); 13703 13704 // By default broadcasts do not go to stopped apps. 13705 intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES); 13706 13707 if (DEBUG_BROADCAST_LIGHT) Slog.v( 13708 TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent 13709 + " ordered=" + ordered + " userid=" + userId); 13710 if ((resultTo != null) && !ordered) { 13711 Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!"); 13712 } 13713 13714 userId = handleIncomingUser(callingPid, callingUid, userId, 13715 true, false, "broadcast", callerPackage); 13716 13717 // Make sure that the user who is receiving this broadcast is started. 13718 // If not, we will just skip it. 13719 if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) { 13720 if (callingUid != Process.SYSTEM_UID || (intent.getFlags() 13721 & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) { 13722 Slog.w(TAG, "Skipping broadcast of " + intent 13723 + ": user " + userId + " is stopped"); 13724 return ActivityManager.BROADCAST_SUCCESS; 13725 } 13726 } 13727 13728 /* 13729 * Prevent non-system code (defined here to be non-persistent 13730 * processes) from sending protected broadcasts. 13731 */ 13732 int callingAppId = UserHandle.getAppId(callingUid); 13733 if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID 13734 || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID || 13735 callingUid == 0) { 13736 // Always okay. 13737 } else if (callerApp == null || !callerApp.persistent) { 13738 try { 13739 if (AppGlobals.getPackageManager().isProtectedBroadcast( 13740 intent.getAction())) { 13741 String msg = "Permission Denial: not allowed to send broadcast " 13742 + intent.getAction() + " from pid=" 13743 + callingPid + ", uid=" + callingUid; 13744 Slog.w(TAG, msg); 13745 throw new SecurityException(msg); 13746 } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) { 13747 // Special case for compatibility: we don't want apps to send this, 13748 // but historically it has not been protected and apps may be using it 13749 // to poke their own app widget. So, instead of making it protected, 13750 // just limit it to the caller. 13751 if (callerApp == null) { 13752 String msg = "Permission Denial: not allowed to send broadcast " 13753 + intent.getAction() + " from unknown caller."; 13754 Slog.w(TAG, msg); 13755 throw new SecurityException(msg); 13756 } else if (intent.getComponent() != null) { 13757 // They are good enough to send to an explicit component... verify 13758 // it is being sent to the calling app. 13759 if (!intent.getComponent().getPackageName().equals( 13760 callerApp.info.packageName)) { 13761 String msg = "Permission Denial: not allowed to send broadcast " 13762 + intent.getAction() + " to " 13763 + intent.getComponent().getPackageName() + " from " 13764 + callerApp.info.packageName; 13765 Slog.w(TAG, msg); 13766 throw new SecurityException(msg); 13767 } 13768 } else { 13769 // Limit broadcast to their own package. 13770 intent.setPackage(callerApp.info.packageName); 13771 } 13772 } 13773 } catch (RemoteException e) { 13774 Slog.w(TAG, "Remote exception", e); 13775 return ActivityManager.BROADCAST_SUCCESS; 13776 } 13777 } 13778 13779 // Handle special intents: if this broadcast is from the package 13780 // manager about a package being removed, we need to remove all of 13781 // its activities from the history stack. 13782 final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals( 13783 intent.getAction()); 13784 if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction()) 13785 || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction()) 13786 || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction()) 13787 || uidRemoved) { 13788 if (checkComponentPermission( 13789 android.Manifest.permission.BROADCAST_PACKAGE_REMOVED, 13790 callingPid, callingUid, -1, true) 13791 == PackageManager.PERMISSION_GRANTED) { 13792 if (uidRemoved) { 13793 final Bundle intentExtras = intent.getExtras(); 13794 final int uid = intentExtras != null 13795 ? intentExtras.getInt(Intent.EXTRA_UID) : -1; 13796 if (uid >= 0) { 13797 BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics(); 13798 synchronized (bs) { 13799 bs.removeUidStatsLocked(uid); 13800 } 13801 mAppOpsService.uidRemoved(uid); 13802 } 13803 } else { 13804 // If resources are unavailable just force stop all 13805 // those packages and flush the attribute cache as well. 13806 if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) { 13807 String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 13808 if (list != null && (list.length > 0)) { 13809 for (String pkg : list) { 13810 forceStopPackageLocked(pkg, -1, false, true, true, false, false, userId, 13811 "storage unmount"); 13812 } 13813 sendPackageBroadcastLocked( 13814 IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId); 13815 } 13816 } else { 13817 Uri data = intent.getData(); 13818 String ssp; 13819 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 13820 boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals( 13821 intent.getAction()); 13822 boolean fullUninstall = removed && 13823 !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false); 13824 if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) { 13825 forceStopPackageLocked(ssp, UserHandle.getAppId( 13826 intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true, 13827 false, fullUninstall, userId, 13828 removed ? "pkg removed" : "pkg changed"); 13829 } 13830 if (removed) { 13831 sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED, 13832 new String[] {ssp}, userId); 13833 if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) { 13834 mAppOpsService.packageRemoved( 13835 intent.getIntExtra(Intent.EXTRA_UID, -1), ssp); 13836 13837 // Remove all permissions granted from/to this package 13838 removeUriPermissionsForPackageLocked(ssp, userId, true); 13839 } 13840 } 13841 } 13842 } 13843 } 13844 } else { 13845 String msg = "Permission Denial: " + intent.getAction() 13846 + " broadcast from " + callerPackage + " (pid=" + callingPid 13847 + ", uid=" + callingUid + ")" 13848 + " requires " 13849 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED; 13850 Slog.w(TAG, msg); 13851 throw new SecurityException(msg); 13852 } 13853 13854 // Special case for adding a package: by default turn on compatibility 13855 // mode. 13856 } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) { 13857 Uri data = intent.getData(); 13858 String ssp; 13859 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 13860 mCompatModePackages.handlePackageAddedLocked(ssp, 13861 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)); 13862 } 13863 } 13864 13865 /* 13866 * If this is the time zone changed action, queue up a message that will reset the timezone 13867 * of all currently running processes. This message will get queued up before the broadcast 13868 * happens. 13869 */ 13870 if (Intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) { 13871 mHandler.sendEmptyMessage(UPDATE_TIME_ZONE); 13872 } 13873 13874 /* 13875 * If the user set the time, let all running processes know. 13876 */ 13877 if (Intent.ACTION_TIME_CHANGED.equals(intent.getAction())) { 13878 final int is24Hour = intent.getBooleanExtra( 13879 Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1 : 0; 13880 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0)); 13881 } 13882 13883 if (Intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) { 13884 mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG); 13885 } 13886 13887 if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) { 13888 ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO); 13889 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy)); 13890 } 13891 13892 // Add to the sticky list if requested. 13893 if (sticky) { 13894 if (checkPermission(android.Manifest.permission.BROADCAST_STICKY, 13895 callingPid, callingUid) 13896 != PackageManager.PERMISSION_GRANTED) { 13897 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid=" 13898 + callingPid + ", uid=" + callingUid 13899 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 13900 Slog.w(TAG, msg); 13901 throw new SecurityException(msg); 13902 } 13903 if (requiredPermission != null) { 13904 Slog.w(TAG, "Can't broadcast sticky intent " + intent 13905 + " and enforce permission " + requiredPermission); 13906 return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION; 13907 } 13908 if (intent.getComponent() != null) { 13909 throw new SecurityException( 13910 "Sticky broadcasts can't target a specific component"); 13911 } 13912 // We use userId directly here, since the "all" target is maintained 13913 // as a separate set of sticky broadcasts. 13914 if (userId != UserHandle.USER_ALL) { 13915 // But first, if this is not a broadcast to all users, then 13916 // make sure it doesn't conflict with an existing broadcast to 13917 // all users. 13918 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get( 13919 UserHandle.USER_ALL); 13920 if (stickies != null) { 13921 ArrayList<Intent> list = stickies.get(intent.getAction()); 13922 if (list != null) { 13923 int N = list.size(); 13924 int i; 13925 for (i=0; i<N; i++) { 13926 if (intent.filterEquals(list.get(i))) { 13927 throw new IllegalArgumentException( 13928 "Sticky broadcast " + intent + " for user " 13929 + userId + " conflicts with existing global broadcast"); 13930 } 13931 } 13932 } 13933 } 13934 } 13935 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 13936 if (stickies == null) { 13937 stickies = new ArrayMap<String, ArrayList<Intent>>(); 13938 mStickyBroadcasts.put(userId, stickies); 13939 } 13940 ArrayList<Intent> list = stickies.get(intent.getAction()); 13941 if (list == null) { 13942 list = new ArrayList<Intent>(); 13943 stickies.put(intent.getAction(), list); 13944 } 13945 int N = list.size(); 13946 int i; 13947 for (i=0; i<N; i++) { 13948 if (intent.filterEquals(list.get(i))) { 13949 // This sticky already exists, replace it. 13950 list.set(i, new Intent(intent)); 13951 break; 13952 } 13953 } 13954 if (i >= N) { 13955 list.add(new Intent(intent)); 13956 } 13957 } 13958 13959 int[] users; 13960 if (userId == UserHandle.USER_ALL) { 13961 // Caller wants broadcast to go to all started users. 13962 users = mStartedUserArray; 13963 } else { 13964 // Caller wants broadcast to go to one specific user. 13965 users = new int[] {userId}; 13966 } 13967 13968 // Figure out who all will receive this broadcast. 13969 List receivers = null; 13970 List<BroadcastFilter> registeredReceivers = null; 13971 // Need to resolve the intent to interested receivers... 13972 if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) 13973 == 0) { 13974 receivers = collectReceiverComponents(intent, resolvedType, users); 13975 } 13976 if (intent.getComponent() == null) { 13977 registeredReceivers = mReceiverResolver.queryIntent(intent, 13978 resolvedType, false, userId); 13979 } 13980 13981 final boolean replacePending = 13982 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0; 13983 13984 if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction() 13985 + " replacePending=" + replacePending); 13986 13987 int NR = registeredReceivers != null ? registeredReceivers.size() : 0; 13988 if (!ordered && NR > 0) { 13989 // If we are not serializing this broadcast, then send the 13990 // registered receivers separately so they don't wait for the 13991 // components to be launched. 13992 final BroadcastQueue queue = broadcastQueueForIntent(intent); 13993 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 13994 callerPackage, callingPid, callingUid, resolvedType, requiredPermission, 13995 appOp, registeredReceivers, resultTo, resultCode, resultData, map, 13996 ordered, sticky, false, userId); 13997 if (DEBUG_BROADCAST) Slog.v( 13998 TAG, "Enqueueing parallel broadcast " + r); 13999 final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r); 14000 if (!replaced) { 14001 queue.enqueueParallelBroadcastLocked(r); 14002 queue.scheduleBroadcastsLocked(); 14003 } 14004 registeredReceivers = null; 14005 NR = 0; 14006 } 14007 14008 // Merge into one list. 14009 int ir = 0; 14010 if (receivers != null) { 14011 // A special case for PACKAGE_ADDED: do not allow the package 14012 // being added to see this broadcast. This prevents them from 14013 // using this as a back door to get run as soon as they are 14014 // installed. Maybe in the future we want to have a special install 14015 // broadcast or such for apps, but we'd like to deliberately make 14016 // this decision. 14017 String skipPackages[] = null; 14018 if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction()) 14019 || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction()) 14020 || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) { 14021 Uri data = intent.getData(); 14022 if (data != null) { 14023 String pkgName = data.getSchemeSpecificPart(); 14024 if (pkgName != null) { 14025 skipPackages = new String[] { pkgName }; 14026 } 14027 } 14028 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) { 14029 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 14030 } 14031 if (skipPackages != null && (skipPackages.length > 0)) { 14032 for (String skipPackage : skipPackages) { 14033 if (skipPackage != null) { 14034 int NT = receivers.size(); 14035 for (int it=0; it<NT; it++) { 14036 ResolveInfo curt = (ResolveInfo)receivers.get(it); 14037 if (curt.activityInfo.packageName.equals(skipPackage)) { 14038 receivers.remove(it); 14039 it--; 14040 NT--; 14041 } 14042 } 14043 } 14044 } 14045 } 14046 14047 int NT = receivers != null ? receivers.size() : 0; 14048 int it = 0; 14049 ResolveInfo curt = null; 14050 BroadcastFilter curr = null; 14051 while (it < NT && ir < NR) { 14052 if (curt == null) { 14053 curt = (ResolveInfo)receivers.get(it); 14054 } 14055 if (curr == null) { 14056 curr = registeredReceivers.get(ir); 14057 } 14058 if (curr.getPriority() >= curt.priority) { 14059 // Insert this broadcast record into the final list. 14060 receivers.add(it, curr); 14061 ir++; 14062 curr = null; 14063 it++; 14064 NT++; 14065 } else { 14066 // Skip to the next ResolveInfo in the final list. 14067 it++; 14068 curt = null; 14069 } 14070 } 14071 } 14072 while (ir < NR) { 14073 if (receivers == null) { 14074 receivers = new ArrayList(); 14075 } 14076 receivers.add(registeredReceivers.get(ir)); 14077 ir++; 14078 } 14079 14080 if ((receivers != null && receivers.size() > 0) 14081 || resultTo != null) { 14082 BroadcastQueue queue = broadcastQueueForIntent(intent); 14083 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 14084 callerPackage, callingPid, callingUid, resolvedType, 14085 requiredPermission, appOp, receivers, resultTo, resultCode, 14086 resultData, map, ordered, sticky, false, userId); 14087 if (DEBUG_BROADCAST) Slog.v( 14088 TAG, "Enqueueing ordered broadcast " + r 14089 + ": prev had " + queue.mOrderedBroadcasts.size()); 14090 if (DEBUG_BROADCAST) { 14091 int seq = r.intent.getIntExtra("seq", -1); 14092 Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq); 14093 } 14094 boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r); 14095 if (!replaced) { 14096 queue.enqueueOrderedBroadcastLocked(r); 14097 queue.scheduleBroadcastsLocked(); 14098 } 14099 } 14100 14101 return ActivityManager.BROADCAST_SUCCESS; 14102 } 14103 14104 final Intent verifyBroadcastLocked(Intent intent) { 14105 // Refuse possible leaked file descriptors 14106 if (intent != null && intent.hasFileDescriptors() == true) { 14107 throw new IllegalArgumentException("File descriptors passed in Intent"); 14108 } 14109 14110 int flags = intent.getFlags(); 14111 14112 if (!mProcessesReady) { 14113 // if the caller really truly claims to know what they're doing, go 14114 // ahead and allow the broadcast without launching any receivers 14115 if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) { 14116 intent = new Intent(intent); 14117 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 14118 } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) { 14119 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent 14120 + " before boot completion"); 14121 throw new IllegalStateException("Cannot broadcast before boot completed"); 14122 } 14123 } 14124 14125 if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 14126 throw new IllegalArgumentException( 14127 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 14128 } 14129 14130 return intent; 14131 } 14132 14133 public final int broadcastIntent(IApplicationThread caller, 14134 Intent intent, String resolvedType, IIntentReceiver resultTo, 14135 int resultCode, String resultData, Bundle map, 14136 String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) { 14137 enforceNotIsolatedCaller("broadcastIntent"); 14138 synchronized(this) { 14139 intent = verifyBroadcastLocked(intent); 14140 14141 final ProcessRecord callerApp = getRecordForAppLocked(caller); 14142 final int callingPid = Binder.getCallingPid(); 14143 final int callingUid = Binder.getCallingUid(); 14144 final long origId = Binder.clearCallingIdentity(); 14145 int res = broadcastIntentLocked(callerApp, 14146 callerApp != null ? callerApp.info.packageName : null, 14147 intent, resolvedType, resultTo, 14148 resultCode, resultData, map, requiredPermission, appOp, serialized, sticky, 14149 callingPid, callingUid, userId); 14150 Binder.restoreCallingIdentity(origId); 14151 return res; 14152 } 14153 } 14154 14155 int broadcastIntentInPackage(String packageName, int uid, 14156 Intent intent, String resolvedType, IIntentReceiver resultTo, 14157 int resultCode, String resultData, Bundle map, 14158 String requiredPermission, boolean serialized, boolean sticky, int userId) { 14159 synchronized(this) { 14160 intent = verifyBroadcastLocked(intent); 14161 14162 final long origId = Binder.clearCallingIdentity(); 14163 int res = broadcastIntentLocked(null, packageName, intent, resolvedType, 14164 resultTo, resultCode, resultData, map, requiredPermission, 14165 AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId); 14166 Binder.restoreCallingIdentity(origId); 14167 return res; 14168 } 14169 } 14170 14171 public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) { 14172 // Refuse possible leaked file descriptors 14173 if (intent != null && intent.hasFileDescriptors() == true) { 14174 throw new IllegalArgumentException("File descriptors passed in Intent"); 14175 } 14176 14177 userId = handleIncomingUser(Binder.getCallingPid(), 14178 Binder.getCallingUid(), userId, true, false, "removeStickyBroadcast", null); 14179 14180 synchronized(this) { 14181 if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY) 14182 != PackageManager.PERMISSION_GRANTED) { 14183 String msg = "Permission Denial: unbroadcastIntent() from pid=" 14184 + Binder.getCallingPid() 14185 + ", uid=" + Binder.getCallingUid() 14186 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 14187 Slog.w(TAG, msg); 14188 throw new SecurityException(msg); 14189 } 14190 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 14191 if (stickies != null) { 14192 ArrayList<Intent> list = stickies.get(intent.getAction()); 14193 if (list != null) { 14194 int N = list.size(); 14195 int i; 14196 for (i=0; i<N; i++) { 14197 if (intent.filterEquals(list.get(i))) { 14198 list.remove(i); 14199 break; 14200 } 14201 } 14202 if (list.size() <= 0) { 14203 stickies.remove(intent.getAction()); 14204 } 14205 } 14206 if (stickies.size() <= 0) { 14207 mStickyBroadcasts.remove(userId); 14208 } 14209 } 14210 } 14211 } 14212 14213 private final boolean finishReceiverLocked(IBinder receiver, int resultCode, 14214 String resultData, Bundle resultExtras, boolean resultAbort) { 14215 final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver); 14216 if (r == null) { 14217 Slog.w(TAG, "finishReceiver called but not found on queue"); 14218 return false; 14219 } 14220 14221 return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false); 14222 } 14223 14224 void backgroundServicesFinishedLocked(int userId) { 14225 for (BroadcastQueue queue : mBroadcastQueues) { 14226 queue.backgroundServicesFinishedLocked(userId); 14227 } 14228 } 14229 14230 public void finishReceiver(IBinder who, int resultCode, String resultData, 14231 Bundle resultExtras, boolean resultAbort) { 14232 if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who); 14233 14234 // Refuse possible leaked file descriptors 14235 if (resultExtras != null && resultExtras.hasFileDescriptors()) { 14236 throw new IllegalArgumentException("File descriptors passed in Bundle"); 14237 } 14238 14239 final long origId = Binder.clearCallingIdentity(); 14240 try { 14241 boolean doNext = false; 14242 BroadcastRecord r; 14243 14244 synchronized(this) { 14245 r = broadcastRecordForReceiverLocked(who); 14246 if (r != null) { 14247 doNext = r.queue.finishReceiverLocked(r, resultCode, 14248 resultData, resultExtras, resultAbort, true); 14249 } 14250 } 14251 14252 if (doNext) { 14253 r.queue.processNextBroadcast(false); 14254 } 14255 trimApplications(); 14256 } finally { 14257 Binder.restoreCallingIdentity(origId); 14258 } 14259 } 14260 14261 // ========================================================= 14262 // INSTRUMENTATION 14263 // ========================================================= 14264 14265 public boolean startInstrumentation(ComponentName className, 14266 String profileFile, int flags, Bundle arguments, 14267 IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection, 14268 int userId) { 14269 enforceNotIsolatedCaller("startInstrumentation"); 14270 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 14271 userId, false, true, "startInstrumentation", null); 14272 // Refuse possible leaked file descriptors 14273 if (arguments != null && arguments.hasFileDescriptors()) { 14274 throw new IllegalArgumentException("File descriptors passed in Bundle"); 14275 } 14276 14277 synchronized(this) { 14278 InstrumentationInfo ii = null; 14279 ApplicationInfo ai = null; 14280 try { 14281 ii = mContext.getPackageManager().getInstrumentationInfo( 14282 className, STOCK_PM_FLAGS); 14283 ai = AppGlobals.getPackageManager().getApplicationInfo( 14284 ii.targetPackage, STOCK_PM_FLAGS, userId); 14285 } catch (PackageManager.NameNotFoundException e) { 14286 } catch (RemoteException e) { 14287 } 14288 if (ii == null) { 14289 reportStartInstrumentationFailure(watcher, className, 14290 "Unable to find instrumentation info for: " + className); 14291 return false; 14292 } 14293 if (ai == null) { 14294 reportStartInstrumentationFailure(watcher, className, 14295 "Unable to find instrumentation target package: " + ii.targetPackage); 14296 return false; 14297 } 14298 14299 int match = mContext.getPackageManager().checkSignatures( 14300 ii.targetPackage, ii.packageName); 14301 if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) { 14302 String msg = "Permission Denial: starting instrumentation " 14303 + className + " from pid=" 14304 + Binder.getCallingPid() 14305 + ", uid=" + Binder.getCallingPid() 14306 + " not allowed because package " + ii.packageName 14307 + " does not have a signature matching the target " 14308 + ii.targetPackage; 14309 reportStartInstrumentationFailure(watcher, className, msg); 14310 throw new SecurityException(msg); 14311 } 14312 14313 final long origId = Binder.clearCallingIdentity(); 14314 // Instrumentation can kill and relaunch even persistent processes 14315 forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId, 14316 "start instr"); 14317 ProcessRecord app = addAppLocked(ai, false); 14318 app.instrumentationClass = className; 14319 app.instrumentationInfo = ai; 14320 app.instrumentationProfileFile = profileFile; 14321 app.instrumentationArguments = arguments; 14322 app.instrumentationWatcher = watcher; 14323 app.instrumentationUiAutomationConnection = uiAutomationConnection; 14324 app.instrumentationResultClass = className; 14325 Binder.restoreCallingIdentity(origId); 14326 } 14327 14328 return true; 14329 } 14330 14331 /** 14332 * Report errors that occur while attempting to start Instrumentation. Always writes the 14333 * error to the logs, but if somebody is watching, send the report there too. This enables 14334 * the "am" command to report errors with more information. 14335 * 14336 * @param watcher The IInstrumentationWatcher. Null if there isn't one. 14337 * @param cn The component name of the instrumentation. 14338 * @param report The error report. 14339 */ 14340 private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher, 14341 ComponentName cn, String report) { 14342 Slog.w(TAG, report); 14343 try { 14344 if (watcher != null) { 14345 Bundle results = new Bundle(); 14346 results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService"); 14347 results.putString("Error", report); 14348 watcher.instrumentationStatus(cn, -1, results); 14349 } 14350 } catch (RemoteException e) { 14351 Slog.w(TAG, e); 14352 } 14353 } 14354 14355 void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) { 14356 if (app.instrumentationWatcher != null) { 14357 try { 14358 // NOTE: IInstrumentationWatcher *must* be oneway here 14359 app.instrumentationWatcher.instrumentationFinished( 14360 app.instrumentationClass, 14361 resultCode, 14362 results); 14363 } catch (RemoteException e) { 14364 } 14365 } 14366 if (app.instrumentationUiAutomationConnection != null) { 14367 try { 14368 app.instrumentationUiAutomationConnection.shutdown(); 14369 } catch (RemoteException re) { 14370 /* ignore */ 14371 } 14372 // Only a UiAutomation can set this flag and now that 14373 // it is finished we make sure it is reset to its default. 14374 mUserIsMonkey = false; 14375 } 14376 app.instrumentationWatcher = null; 14377 app.instrumentationUiAutomationConnection = null; 14378 app.instrumentationClass = null; 14379 app.instrumentationInfo = null; 14380 app.instrumentationProfileFile = null; 14381 app.instrumentationArguments = null; 14382 14383 forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId, 14384 "finished inst"); 14385 } 14386 14387 public void finishInstrumentation(IApplicationThread target, 14388 int resultCode, Bundle results) { 14389 int userId = UserHandle.getCallingUserId(); 14390 // Refuse possible leaked file descriptors 14391 if (results != null && results.hasFileDescriptors()) { 14392 throw new IllegalArgumentException("File descriptors passed in Intent"); 14393 } 14394 14395 synchronized(this) { 14396 ProcessRecord app = getRecordForAppLocked(target); 14397 if (app == null) { 14398 Slog.w(TAG, "finishInstrumentation: no app for " + target); 14399 return; 14400 } 14401 final long origId = Binder.clearCallingIdentity(); 14402 finishInstrumentationLocked(app, resultCode, results); 14403 Binder.restoreCallingIdentity(origId); 14404 } 14405 } 14406 14407 // ========================================================= 14408 // CONFIGURATION 14409 // ========================================================= 14410 14411 public ConfigurationInfo getDeviceConfigurationInfo() { 14412 ConfigurationInfo config = new ConfigurationInfo(); 14413 synchronized (this) { 14414 config.reqTouchScreen = mConfiguration.touchscreen; 14415 config.reqKeyboardType = mConfiguration.keyboard; 14416 config.reqNavigation = mConfiguration.navigation; 14417 if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD 14418 || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) { 14419 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV; 14420 } 14421 if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED 14422 && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) { 14423 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD; 14424 } 14425 config.reqGlEsVersion = GL_ES_VERSION; 14426 } 14427 return config; 14428 } 14429 14430 ActivityStack getFocusedStack() { 14431 return mStackSupervisor.getFocusedStack(); 14432 } 14433 14434 public Configuration getConfiguration() { 14435 Configuration ci; 14436 synchronized(this) { 14437 ci = new Configuration(mConfiguration); 14438 } 14439 return ci; 14440 } 14441 14442 public void updatePersistentConfiguration(Configuration values) { 14443 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 14444 "updateConfiguration()"); 14445 enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS, 14446 "updateConfiguration()"); 14447 if (values == null) { 14448 throw new NullPointerException("Configuration must not be null"); 14449 } 14450 14451 synchronized(this) { 14452 final long origId = Binder.clearCallingIdentity(); 14453 updateConfigurationLocked(values, null, true, false); 14454 Binder.restoreCallingIdentity(origId); 14455 } 14456 } 14457 14458 public void updateConfiguration(Configuration values) { 14459 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 14460 "updateConfiguration()"); 14461 14462 synchronized(this) { 14463 if (values == null && mWindowManager != null) { 14464 // sentinel: fetch the current configuration from the window manager 14465 values = mWindowManager.computeNewConfiguration(); 14466 } 14467 14468 if (mWindowManager != null) { 14469 mProcessList.applyDisplaySize(mWindowManager); 14470 } 14471 14472 final long origId = Binder.clearCallingIdentity(); 14473 if (values != null) { 14474 Settings.System.clearConfiguration(values); 14475 } 14476 updateConfigurationLocked(values, null, false, false); 14477 Binder.restoreCallingIdentity(origId); 14478 } 14479 } 14480 14481 /** 14482 * Do either or both things: (1) change the current configuration, and (2) 14483 * make sure the given activity is running with the (now) current 14484 * configuration. Returns true if the activity has been left running, or 14485 * false if <var>starting</var> is being destroyed to match the new 14486 * configuration. 14487 * @param persistent TODO 14488 */ 14489 boolean updateConfigurationLocked(Configuration values, 14490 ActivityRecord starting, boolean persistent, boolean initLocale) { 14491 int changes = 0; 14492 14493 if (values != null) { 14494 Configuration newConfig = new Configuration(mConfiguration); 14495 changes = newConfig.updateFrom(values); 14496 if (changes != 0) { 14497 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) { 14498 Slog.i(TAG, "Updating configuration to: " + values); 14499 } 14500 14501 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes); 14502 14503 if (values.locale != null && !initLocale) { 14504 saveLocaleLocked(values.locale, 14505 !values.locale.equals(mConfiguration.locale), 14506 values.userSetLocale); 14507 } 14508 14509 mConfigurationSeq++; 14510 if (mConfigurationSeq <= 0) { 14511 mConfigurationSeq = 1; 14512 } 14513 newConfig.seq = mConfigurationSeq; 14514 mConfiguration = newConfig; 14515 Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig); 14516 mUsageStatsService.noteStartConfig(newConfig); 14517 14518 final Configuration configCopy = new Configuration(mConfiguration); 14519 14520 // TODO: If our config changes, should we auto dismiss any currently 14521 // showing dialogs? 14522 mShowDialogs = shouldShowDialogs(newConfig); 14523 14524 AttributeCache ac = AttributeCache.instance(); 14525 if (ac != null) { 14526 ac.updateConfiguration(configCopy); 14527 } 14528 14529 // Make sure all resources in our process are updated 14530 // right now, so that anyone who is going to retrieve 14531 // resource values after we return will be sure to get 14532 // the new ones. This is especially important during 14533 // boot, where the first config change needs to guarantee 14534 // all resources have that config before following boot 14535 // code is executed. 14536 mSystemThread.applyConfigurationToResources(configCopy); 14537 14538 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) { 14539 Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG); 14540 msg.obj = new Configuration(configCopy); 14541 mHandler.sendMessage(msg); 14542 } 14543 14544 for (int i=mLruProcesses.size()-1; i>=0; i--) { 14545 ProcessRecord app = mLruProcesses.get(i); 14546 try { 14547 if (app.thread != null) { 14548 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc " 14549 + app.processName + " new config " + mConfiguration); 14550 app.thread.scheduleConfigurationChanged(configCopy); 14551 } 14552 } catch (Exception e) { 14553 } 14554 } 14555 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED); 14556 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 14557 | Intent.FLAG_RECEIVER_REPLACE_PENDING 14558 | Intent.FLAG_RECEIVER_FOREGROUND); 14559 broadcastIntentLocked(null, null, intent, null, null, 0, null, null, 14560 null, AppOpsManager.OP_NONE, false, false, MY_PID, 14561 Process.SYSTEM_UID, UserHandle.USER_ALL); 14562 if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) { 14563 intent = new Intent(Intent.ACTION_LOCALE_CHANGED); 14564 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 14565 broadcastIntentLocked(null, null, intent, 14566 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 14567 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 14568 } 14569 } 14570 } 14571 14572 boolean kept = true; 14573 final ActivityStack mainStack = mStackSupervisor.getFocusedStack(); 14574 // mainStack is null during startup. 14575 if (mainStack != null) { 14576 if (changes != 0 && starting == null) { 14577 // If the configuration changed, and the caller is not already 14578 // in the process of starting an activity, then find the top 14579 // activity to check if its configuration needs to change. 14580 starting = mainStack.topRunningActivityLocked(null); 14581 } 14582 14583 if (starting != null) { 14584 kept = mainStack.ensureActivityConfigurationLocked(starting, changes); 14585 // And we need to make sure at this point that all other activities 14586 // are made visible with the correct configuration. 14587 mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes); 14588 } 14589 } 14590 14591 if (values != null && mWindowManager != null) { 14592 mWindowManager.setNewConfiguration(mConfiguration); 14593 } 14594 14595 return kept; 14596 } 14597 14598 /** 14599 * Decide based on the configuration whether we should shouw the ANR, 14600 * crash, etc dialogs. The idea is that if there is no affordnace to 14601 * press the on-screen buttons, we shouldn't show the dialog. 14602 * 14603 * A thought: SystemUI might also want to get told about this, the Power 14604 * dialog / global actions also might want different behaviors. 14605 */ 14606 private static final boolean shouldShowDialogs(Configuration config) { 14607 return !(config.keyboard == Configuration.KEYBOARD_NOKEYS 14608 && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH); 14609 } 14610 14611 /** 14612 * Save the locale. You must be inside a synchronized (this) block. 14613 */ 14614 private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) { 14615 if(isDiff) { 14616 SystemProperties.set("user.language", l.getLanguage()); 14617 SystemProperties.set("user.region", l.getCountry()); 14618 } 14619 14620 if(isPersist) { 14621 SystemProperties.set("persist.sys.language", l.getLanguage()); 14622 SystemProperties.set("persist.sys.country", l.getCountry()); 14623 SystemProperties.set("persist.sys.localevar", l.getVariant()); 14624 } 14625 } 14626 14627 @Override 14628 public boolean targetTaskAffinityMatchesActivity(IBinder token, String destAffinity) { 14629 ActivityRecord srec = ActivityRecord.forToken(token); 14630 return srec != null && srec.task.affinity != null && 14631 srec.task.affinity.equals(destAffinity); 14632 } 14633 14634 public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode, 14635 Intent resultData) { 14636 14637 synchronized (this) { 14638 final ActivityStack stack = ActivityRecord.getStackLocked(token); 14639 if (stack != null) { 14640 return stack.navigateUpToLocked(token, destIntent, resultCode, resultData); 14641 } 14642 return false; 14643 } 14644 } 14645 14646 public int getLaunchedFromUid(IBinder activityToken) { 14647 ActivityRecord srec = ActivityRecord.forToken(activityToken); 14648 if (srec == null) { 14649 return -1; 14650 } 14651 return srec.launchedFromUid; 14652 } 14653 14654 public String getLaunchedFromPackage(IBinder activityToken) { 14655 ActivityRecord srec = ActivityRecord.forToken(activityToken); 14656 if (srec == null) { 14657 return null; 14658 } 14659 return srec.launchedFromPackage; 14660 } 14661 14662 // ========================================================= 14663 // LIFETIME MANAGEMENT 14664 // ========================================================= 14665 14666 // Returns which broadcast queue the app is the current [or imminent] receiver 14667 // on, or 'null' if the app is not an active broadcast recipient. 14668 private BroadcastQueue isReceivingBroadcast(ProcessRecord app) { 14669 BroadcastRecord r = app.curReceiver; 14670 if (r != null) { 14671 return r.queue; 14672 } 14673 14674 // It's not the current receiver, but it might be starting up to become one 14675 synchronized (this) { 14676 for (BroadcastQueue queue : mBroadcastQueues) { 14677 r = queue.mPendingBroadcast; 14678 if (r != null && r.curApp == app) { 14679 // found it; report which queue it's in 14680 return queue; 14681 } 14682 } 14683 } 14684 14685 return null; 14686 } 14687 14688 private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP, 14689 boolean doingAll, long now) { 14690 if (mAdjSeq == app.adjSeq) { 14691 // This adjustment has already been computed. 14692 return app.curRawAdj; 14693 } 14694 14695 if (app.thread == null) { 14696 app.adjSeq = mAdjSeq; 14697 app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 14698 app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 14699 return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ); 14700 } 14701 14702 app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN; 14703 app.adjSource = null; 14704 app.adjTarget = null; 14705 app.empty = false; 14706 app.cached = false; 14707 14708 final int activitiesSize = app.activities.size(); 14709 14710 if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) { 14711 // The max adjustment doesn't allow this app to be anything 14712 // below foreground, so it is not worth doing work for it. 14713 app.adjType = "fixed"; 14714 app.adjSeq = mAdjSeq; 14715 app.curRawAdj = app.maxAdj; 14716 app.foregroundActivities = false; 14717 app.keeping = true; 14718 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT; 14719 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT; 14720 // System processes can do UI, and when they do we want to have 14721 // them trim their memory after the user leaves the UI. To 14722 // facilitate this, here we need to determine whether or not it 14723 // is currently showing UI. 14724 app.systemNoUi = true; 14725 if (app == TOP_APP) { 14726 app.systemNoUi = false; 14727 } else if (activitiesSize > 0) { 14728 for (int j = 0; j < activitiesSize; j++) { 14729 final ActivityRecord r = app.activities.get(j); 14730 if (r.visible) { 14731 app.systemNoUi = false; 14732 } 14733 } 14734 } 14735 if (!app.systemNoUi) { 14736 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI; 14737 } 14738 return (app.curAdj=app.maxAdj); 14739 } 14740 14741 app.keeping = false; 14742 app.systemNoUi = false; 14743 14744 // Determine the importance of the process, starting with most 14745 // important to least, and assign an appropriate OOM adjustment. 14746 int adj; 14747 int schedGroup; 14748 int procState; 14749 boolean foregroundActivities = false; 14750 boolean interesting = false; 14751 BroadcastQueue queue; 14752 if (app == TOP_APP) { 14753 // The last app on the list is the foreground app. 14754 adj = ProcessList.FOREGROUND_APP_ADJ; 14755 schedGroup = Process.THREAD_GROUP_DEFAULT; 14756 app.adjType = "top-activity"; 14757 foregroundActivities = true; 14758 interesting = true; 14759 procState = ActivityManager.PROCESS_STATE_TOP; 14760 } else if (app.instrumentationClass != null) { 14761 // Don't want to kill running instrumentation. 14762 adj = ProcessList.FOREGROUND_APP_ADJ; 14763 schedGroup = Process.THREAD_GROUP_DEFAULT; 14764 app.adjType = "instrumentation"; 14765 interesting = true; 14766 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14767 } else if ((queue = isReceivingBroadcast(app)) != null) { 14768 // An app that is currently receiving a broadcast also 14769 // counts as being in the foreground for OOM killer purposes. 14770 // It's placed in a sched group based on the nature of the 14771 // broadcast as reflected by which queue it's active in. 14772 adj = ProcessList.FOREGROUND_APP_ADJ; 14773 schedGroup = (queue == mFgBroadcastQueue) 14774 ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 14775 app.adjType = "broadcast"; 14776 procState = ActivityManager.PROCESS_STATE_RECEIVER; 14777 } else if (app.executingServices.size() > 0) { 14778 // An app that is currently executing a service callback also 14779 // counts as being in the foreground. 14780 adj = ProcessList.FOREGROUND_APP_ADJ; 14781 schedGroup = app.execServicesFg ? 14782 Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 14783 app.adjType = "exec-service"; 14784 procState = ActivityManager.PROCESS_STATE_SERVICE; 14785 //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app); 14786 } else { 14787 // As far as we know the process is empty. We may change our mind later. 14788 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 14789 // At this point we don't actually know the adjustment. Use the cached adj 14790 // value that the caller wants us to. 14791 adj = cachedAdj; 14792 procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 14793 app.cached = true; 14794 app.empty = true; 14795 app.adjType = "cch-empty"; 14796 } 14797 14798 // Examine all activities if not already foreground. 14799 if (!foregroundActivities && activitiesSize > 0) { 14800 for (int j = 0; j < activitiesSize; j++) { 14801 final ActivityRecord r = app.activities.get(j); 14802 if (r.app != app) { 14803 Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc " 14804 + app + "?!?"); 14805 continue; 14806 } 14807 if (r.visible) { 14808 // App has a visible activity; only upgrade adjustment. 14809 if (adj > ProcessList.VISIBLE_APP_ADJ) { 14810 adj = ProcessList.VISIBLE_APP_ADJ; 14811 app.adjType = "visible"; 14812 } 14813 if (procState > ActivityManager.PROCESS_STATE_TOP) { 14814 procState = ActivityManager.PROCESS_STATE_TOP; 14815 } 14816 schedGroup = Process.THREAD_GROUP_DEFAULT; 14817 app.cached = false; 14818 app.empty = false; 14819 foregroundActivities = true; 14820 break; 14821 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) { 14822 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14823 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 14824 app.adjType = "pausing"; 14825 } 14826 if (procState > ActivityManager.PROCESS_STATE_TOP) { 14827 procState = ActivityManager.PROCESS_STATE_TOP; 14828 } 14829 schedGroup = Process.THREAD_GROUP_DEFAULT; 14830 app.cached = false; 14831 app.empty = false; 14832 foregroundActivities = true; 14833 } else if (r.state == ActivityState.STOPPING) { 14834 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14835 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 14836 app.adjType = "stopping"; 14837 } 14838 // For the process state, we will at this point consider the 14839 // process to be cached. It will be cached either as an activity 14840 // or empty depending on whether the activity is finishing. We do 14841 // this so that we can treat the process as cached for purposes of 14842 // memory trimming (determing current memory level, trim command to 14843 // send to process) since there can be an arbitrary number of stopping 14844 // processes and they should soon all go into the cached state. 14845 if (!r.finishing) { 14846 if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 14847 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 14848 } 14849 } 14850 app.cached = false; 14851 app.empty = false; 14852 foregroundActivities = true; 14853 } else { 14854 if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 14855 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 14856 app.adjType = "cch-act"; 14857 } 14858 } 14859 } 14860 } 14861 14862 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14863 if (app.foregroundServices) { 14864 // The user is aware of this app, so make it visible. 14865 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 14866 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14867 app.cached = false; 14868 app.adjType = "fg-service"; 14869 schedGroup = Process.THREAD_GROUP_DEFAULT; 14870 } else if (app.forcingToForeground != null) { 14871 // The user is aware of this app, so make it visible. 14872 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 14873 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14874 app.cached = false; 14875 app.adjType = "force-fg"; 14876 app.adjSource = app.forcingToForeground; 14877 schedGroup = Process.THREAD_GROUP_DEFAULT; 14878 } 14879 } 14880 14881 if (app.foregroundServices) { 14882 interesting = true; 14883 } 14884 14885 if (app == mHeavyWeightProcess) { 14886 if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) { 14887 // We don't want to kill the current heavy-weight process. 14888 adj = ProcessList.HEAVY_WEIGHT_APP_ADJ; 14889 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 14890 app.cached = false; 14891 app.adjType = "heavy"; 14892 } 14893 if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) { 14894 procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT; 14895 } 14896 } 14897 14898 if (app == mHomeProcess) { 14899 if (adj > ProcessList.HOME_APP_ADJ) { 14900 // This process is hosting what we currently consider to be the 14901 // home app, so we don't want to let it go into the background. 14902 adj = ProcessList.HOME_APP_ADJ; 14903 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 14904 app.cached = false; 14905 app.adjType = "home"; 14906 } 14907 if (procState > ActivityManager.PROCESS_STATE_HOME) { 14908 procState = ActivityManager.PROCESS_STATE_HOME; 14909 } 14910 } 14911 14912 if (app == mPreviousProcess && app.activities.size() > 0) { 14913 if (adj > ProcessList.PREVIOUS_APP_ADJ) { 14914 // This was the previous process that showed UI to the user. 14915 // We want to try to keep it around more aggressively, to give 14916 // a good experience around switching between two apps. 14917 adj = ProcessList.PREVIOUS_APP_ADJ; 14918 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 14919 app.cached = false; 14920 app.adjType = "previous"; 14921 } 14922 if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) { 14923 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY; 14924 } 14925 } 14926 14927 if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj 14928 + " reason=" + app.adjType); 14929 14930 // By default, we use the computed adjustment. It may be changed if 14931 // there are applications dependent on our services or providers, but 14932 // this gives us a baseline and makes sure we don't get into an 14933 // infinite recursion. 14934 app.adjSeq = mAdjSeq; 14935 app.curRawAdj = adj; 14936 app.hasStartedServices = false; 14937 14938 if (mBackupTarget != null && app == mBackupTarget.app) { 14939 // If possible we want to avoid killing apps while they're being backed up 14940 if (adj > ProcessList.BACKUP_APP_ADJ) { 14941 if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app); 14942 adj = ProcessList.BACKUP_APP_ADJ; 14943 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) { 14944 procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND; 14945 } 14946 app.adjType = "backup"; 14947 app.cached = false; 14948 } 14949 if (procState > ActivityManager.PROCESS_STATE_BACKUP) { 14950 procState = ActivityManager.PROCESS_STATE_BACKUP; 14951 } 14952 } 14953 14954 boolean mayBeTop = false; 14955 14956 for (int is = app.services.size()-1; 14957 is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 14958 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 14959 || procState > ActivityManager.PROCESS_STATE_TOP); 14960 is--) { 14961 ServiceRecord s = app.services.valueAt(is); 14962 if (s.startRequested) { 14963 app.hasStartedServices = true; 14964 if (procState > ActivityManager.PROCESS_STATE_SERVICE) { 14965 procState = ActivityManager.PROCESS_STATE_SERVICE; 14966 } 14967 if (app.hasShownUi && app != mHomeProcess) { 14968 // If this process has shown some UI, let it immediately 14969 // go to the LRU list because it may be pretty heavy with 14970 // UI stuff. We'll tag it with a label just to help 14971 // debug and understand what is going on. 14972 if (adj > ProcessList.SERVICE_ADJ) { 14973 app.adjType = "cch-started-ui-services"; 14974 } 14975 } else { 14976 if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) { 14977 // This service has seen some activity within 14978 // recent memory, so we will keep its process ahead 14979 // of the background processes. 14980 if (adj > ProcessList.SERVICE_ADJ) { 14981 adj = ProcessList.SERVICE_ADJ; 14982 app.adjType = "started-services"; 14983 app.cached = false; 14984 } 14985 } 14986 // If we have let the service slide into the background 14987 // state, still have some text describing what it is doing 14988 // even though the service no longer has an impact. 14989 if (adj > ProcessList.SERVICE_ADJ) { 14990 app.adjType = "cch-started-services"; 14991 } 14992 } 14993 // Don't kill this process because it is doing work; it 14994 // has said it is doing work. 14995 app.keeping = true; 14996 } 14997 for (int conni = s.connections.size()-1; 14998 conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 14999 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 15000 || procState > ActivityManager.PROCESS_STATE_TOP); 15001 conni--) { 15002 ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni); 15003 for (int i = 0; 15004 i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ 15005 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 15006 || procState > ActivityManager.PROCESS_STATE_TOP); 15007 i++) { 15008 // XXX should compute this based on the max of 15009 // all connected clients. 15010 ConnectionRecord cr = clist.get(i); 15011 if (cr.binding.client == app) { 15012 // Binding to ourself is not interesting. 15013 continue; 15014 } 15015 if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) { 15016 ProcessRecord client = cr.binding.client; 15017 int clientAdj = computeOomAdjLocked(client, cachedAdj, 15018 TOP_APP, doingAll, now); 15019 int clientProcState = client.curProcState; 15020 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 15021 // If the other app is cached for any reason, for purposes here 15022 // we are going to consider it empty. The specific cached state 15023 // doesn't propagate except under certain conditions. 15024 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 15025 } 15026 String adjType = null; 15027 if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) { 15028 // Not doing bind OOM management, so treat 15029 // this guy more like a started service. 15030 if (app.hasShownUi && app != mHomeProcess) { 15031 // If this process has shown some UI, let it immediately 15032 // go to the LRU list because it may be pretty heavy with 15033 // UI stuff. We'll tag it with a label just to help 15034 // debug and understand what is going on. 15035 if (adj > clientAdj) { 15036 adjType = "cch-bound-ui-services"; 15037 } 15038 app.cached = false; 15039 clientAdj = adj; 15040 clientProcState = procState; 15041 } else { 15042 if (now >= (s.lastActivity 15043 + ActiveServices.MAX_SERVICE_INACTIVITY)) { 15044 // This service has not seen activity within 15045 // recent memory, so allow it to drop to the 15046 // LRU list if there is no other reason to keep 15047 // it around. We'll also tag it with a label just 15048 // to help debug and undertand what is going on. 15049 if (adj > clientAdj) { 15050 adjType = "cch-bound-services"; 15051 } 15052 clientAdj = adj; 15053 } 15054 } 15055 } 15056 if (adj > clientAdj) { 15057 // If this process has recently shown UI, and 15058 // the process that is binding to it is less 15059 // important than being visible, then we don't 15060 // care about the binding as much as we care 15061 // about letting this process get into the LRU 15062 // list to be killed and restarted if needed for 15063 // memory. 15064 if (app.hasShownUi && app != mHomeProcess 15065 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 15066 adjType = "cch-bound-ui-services"; 15067 } else { 15068 if ((cr.flags&(Context.BIND_ABOVE_CLIENT 15069 |Context.BIND_IMPORTANT)) != 0) { 15070 adj = clientAdj; 15071 } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0 15072 && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ 15073 && adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 15074 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 15075 } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) { 15076 adj = clientAdj; 15077 } else { 15078 if (adj > ProcessList.VISIBLE_APP_ADJ) { 15079 adj = ProcessList.VISIBLE_APP_ADJ; 15080 } 15081 } 15082 if (!client.cached) { 15083 app.cached = false; 15084 } 15085 if (client.keeping) { 15086 app.keeping = true; 15087 } 15088 adjType = "service"; 15089 } 15090 } 15091 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 15092 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 15093 schedGroup = Process.THREAD_GROUP_DEFAULT; 15094 } 15095 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) { 15096 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) { 15097 // Special handling of clients who are in the top state. 15098 // We *may* want to consider this process to be in the 15099 // top state as well, but only if there is not another 15100 // reason for it to be running. Being on the top is a 15101 // special state, meaning you are specifically running 15102 // for the current top app. If the process is already 15103 // running in the background for some other reason, it 15104 // is more important to continue considering it to be 15105 // in the background state. 15106 mayBeTop = true; 15107 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 15108 } else { 15109 // Special handling for above-top states (persistent 15110 // processes). These should not bring the current process 15111 // into the top state, since they are not on top. Instead 15112 // give them the best state after that. 15113 clientProcState = 15114 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 15115 } 15116 } 15117 } else { 15118 if (clientProcState < 15119 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) { 15120 clientProcState = 15121 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND; 15122 } 15123 } 15124 if (procState > clientProcState) { 15125 procState = clientProcState; 15126 } 15127 if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 15128 && (cr.flags&Context.BIND_SHOWING_UI) != 0) { 15129 app.pendingUiClean = true; 15130 } 15131 if (adjType != null) { 15132 app.adjType = adjType; 15133 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 15134 .REASON_SERVICE_IN_USE; 15135 app.adjSource = cr.binding.client; 15136 app.adjSourceOom = clientAdj; 15137 app.adjTarget = s.name; 15138 } 15139 } 15140 if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) { 15141 app.treatLikeActivity = true; 15142 } 15143 final ActivityRecord a = cr.activity; 15144 if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) { 15145 if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ && 15146 (a.visible || a.state == ActivityState.RESUMED 15147 || a.state == ActivityState.PAUSING)) { 15148 adj = ProcessList.FOREGROUND_APP_ADJ; 15149 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 15150 schedGroup = Process.THREAD_GROUP_DEFAULT; 15151 } 15152 app.cached = false; 15153 app.adjType = "service"; 15154 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 15155 .REASON_SERVICE_IN_USE; 15156 app.adjSource = a; 15157 app.adjSourceOom = adj; 15158 app.adjTarget = s.name; 15159 } 15160 } 15161 } 15162 } 15163 } 15164 15165 for (int provi = app.pubProviders.size()-1; 15166 provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 15167 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 15168 || procState > ActivityManager.PROCESS_STATE_TOP); 15169 provi--) { 15170 ContentProviderRecord cpr = app.pubProviders.valueAt(provi); 15171 for (int i = cpr.connections.size()-1; 15172 i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 15173 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 15174 || procState > ActivityManager.PROCESS_STATE_TOP); 15175 i--) { 15176 ContentProviderConnection conn = cpr.connections.get(i); 15177 ProcessRecord client = conn.client; 15178 if (client == app) { 15179 // Being our own client is not interesting. 15180 continue; 15181 } 15182 int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now); 15183 int clientProcState = client.curProcState; 15184 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 15185 // If the other app is cached for any reason, for purposes here 15186 // we are going to consider it empty. 15187 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 15188 } 15189 if (adj > clientAdj) { 15190 if (app.hasShownUi && app != mHomeProcess 15191 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 15192 app.adjType = "cch-ui-provider"; 15193 } else { 15194 adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ 15195 ? clientAdj : ProcessList.FOREGROUND_APP_ADJ; 15196 app.adjType = "provider"; 15197 } 15198 app.cached &= client.cached; 15199 app.keeping |= client.keeping; 15200 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 15201 .REASON_PROVIDER_IN_USE; 15202 app.adjSource = client; 15203 app.adjSourceOom = clientAdj; 15204 app.adjTarget = cpr.name; 15205 } 15206 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) { 15207 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) { 15208 // Special handling of clients who are in the top state. 15209 // We *may* want to consider this process to be in the 15210 // top state as well, but only if there is not another 15211 // reason for it to be running. Being on the top is a 15212 // special state, meaning you are specifically running 15213 // for the current top app. If the process is already 15214 // running in the background for some other reason, it 15215 // is more important to continue considering it to be 15216 // in the background state. 15217 mayBeTop = true; 15218 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 15219 } else { 15220 // Special handling for above-top states (persistent 15221 // processes). These should not bring the current process 15222 // into the top state, since they are not on top. Instead 15223 // give them the best state after that. 15224 clientProcState = 15225 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 15226 } 15227 } 15228 if (procState > clientProcState) { 15229 procState = clientProcState; 15230 } 15231 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 15232 schedGroup = Process.THREAD_GROUP_DEFAULT; 15233 } 15234 } 15235 // If the provider has external (non-framework) process 15236 // dependencies, ensure that its adjustment is at least 15237 // FOREGROUND_APP_ADJ. 15238 if (cpr.hasExternalProcessHandles()) { 15239 if (adj > ProcessList.FOREGROUND_APP_ADJ) { 15240 adj = ProcessList.FOREGROUND_APP_ADJ; 15241 schedGroup = Process.THREAD_GROUP_DEFAULT; 15242 app.cached = false; 15243 app.keeping = true; 15244 app.adjType = "provider"; 15245 app.adjTarget = cpr.name; 15246 } 15247 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) { 15248 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 15249 } 15250 } 15251 } 15252 15253 if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) { 15254 // A client of one of our services or providers is in the top state. We 15255 // *may* want to be in the top state, but not if we are already running in 15256 // the background for some other reason. For the decision here, we are going 15257 // to pick out a few specific states that we want to remain in when a client 15258 // is top (states that tend to be longer-term) and otherwise allow it to go 15259 // to the top state. 15260 switch (procState) { 15261 case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND: 15262 case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND: 15263 case ActivityManager.PROCESS_STATE_SERVICE: 15264 // These all are longer-term states, so pull them up to the top 15265 // of the background states, but not all the way to the top state. 15266 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 15267 break; 15268 default: 15269 // Otherwise, top is a better choice, so take it. 15270 procState = ActivityManager.PROCESS_STATE_TOP; 15271 break; 15272 } 15273 } 15274 15275 if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) { 15276 if (app.hasClientActivities) { 15277 // This is a cached process, but with client activities. Mark it so. 15278 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT; 15279 app.adjType = "cch-client-act"; 15280 } else if (app.treatLikeActivity) { 15281 // This is a cached process, but somebody wants us to treat it like it has 15282 // an activity, okay! 15283 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 15284 app.adjType = "cch-as-act"; 15285 } 15286 } 15287 15288 if (adj == ProcessList.SERVICE_ADJ) { 15289 if (doingAll) { 15290 app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3); 15291 mNewNumServiceProcs++; 15292 //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb); 15293 if (!app.serviceb) { 15294 // This service isn't far enough down on the LRU list to 15295 // normally be a B service, but if we are low on RAM and it 15296 // is large we want to force it down since we would prefer to 15297 // keep launcher over it. 15298 if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL 15299 && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) { 15300 app.serviceHighRam = true; 15301 app.serviceb = true; 15302 //Slog.i(TAG, "ADJ " + app + " high ram!"); 15303 } else { 15304 mNewNumAServiceProcs++; 15305 //Slog.i(TAG, "ADJ " + app + " not high ram!"); 15306 } 15307 } else { 15308 app.serviceHighRam = false; 15309 } 15310 } 15311 if (app.serviceb) { 15312 adj = ProcessList.SERVICE_B_ADJ; 15313 } 15314 } 15315 15316 app.curRawAdj = adj; 15317 15318 //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid + 15319 // " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj); 15320 if (adj > app.maxAdj) { 15321 adj = app.maxAdj; 15322 if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 15323 schedGroup = Process.THREAD_GROUP_DEFAULT; 15324 } 15325 } 15326 if (adj < ProcessList.CACHED_APP_MIN_ADJ) { 15327 app.keeping = true; 15328 } 15329 15330 // Do final modification to adj. Everything we do between here and applying 15331 // the final setAdj must be done in this function, because we will also use 15332 // it when computing the final cached adj later. Note that we don't need to 15333 // worry about this for max adj above, since max adj will always be used to 15334 // keep it out of the cached vaues. 15335 app.curAdj = app.modifyRawOomAdj(adj); 15336 app.curSchedGroup = schedGroup; 15337 app.curProcState = procState; 15338 app.foregroundActivities = foregroundActivities; 15339 15340 return app.curRawAdj; 15341 } 15342 15343 /** 15344 * Schedule PSS collection of a process. 15345 */ 15346 void requestPssLocked(ProcessRecord proc, int procState) { 15347 if (mPendingPssProcesses.contains(proc)) { 15348 return; 15349 } 15350 if (mPendingPssProcesses.size() == 0) { 15351 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG); 15352 } 15353 if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc); 15354 proc.pssProcState = procState; 15355 mPendingPssProcesses.add(proc); 15356 } 15357 15358 /** 15359 * Schedule PSS collection of all processes. 15360 */ 15361 void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) { 15362 if (!always) { 15363 if (now < (mLastFullPssTime + 15364 (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) { 15365 return; 15366 } 15367 } 15368 if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs! memLowered=" + memLowered); 15369 mLastFullPssTime = now; 15370 mPendingPssProcesses.ensureCapacity(mLruProcesses.size()); 15371 mPendingPssProcesses.clear(); 15372 for (int i=mLruProcesses.size()-1; i>=0; i--) { 15373 ProcessRecord app = mLruProcesses.get(i); 15374 if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) { 15375 app.pssProcState = app.setProcState; 15376 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true, 15377 isSleeping(), now); 15378 mPendingPssProcesses.add(app); 15379 } 15380 } 15381 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG); 15382 } 15383 15384 /** 15385 * Ask a given process to GC right now. 15386 */ 15387 final void performAppGcLocked(ProcessRecord app) { 15388 try { 15389 app.lastRequestedGc = SystemClock.uptimeMillis(); 15390 if (app.thread != null) { 15391 if (app.reportLowMemory) { 15392 app.reportLowMemory = false; 15393 app.thread.scheduleLowMemory(); 15394 } else { 15395 app.thread.processInBackground(); 15396 } 15397 } 15398 } catch (Exception e) { 15399 // whatever. 15400 } 15401 } 15402 15403 /** 15404 * Returns true if things are idle enough to perform GCs. 15405 */ 15406 private final boolean canGcNowLocked() { 15407 boolean processingBroadcasts = false; 15408 for (BroadcastQueue q : mBroadcastQueues) { 15409 if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) { 15410 processingBroadcasts = true; 15411 } 15412 } 15413 return !processingBroadcasts 15414 && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle()); 15415 } 15416 15417 /** 15418 * Perform GCs on all processes that are waiting for it, but only 15419 * if things are idle. 15420 */ 15421 final void performAppGcsLocked() { 15422 final int N = mProcessesToGc.size(); 15423 if (N <= 0) { 15424 return; 15425 } 15426 if (canGcNowLocked()) { 15427 while (mProcessesToGc.size() > 0) { 15428 ProcessRecord proc = mProcessesToGc.remove(0); 15429 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) { 15430 if ((proc.lastRequestedGc+GC_MIN_INTERVAL) 15431 <= SystemClock.uptimeMillis()) { 15432 // To avoid spamming the system, we will GC processes one 15433 // at a time, waiting a few seconds between each. 15434 performAppGcLocked(proc); 15435 scheduleAppGcsLocked(); 15436 return; 15437 } else { 15438 // It hasn't been long enough since we last GCed this 15439 // process... put it in the list to wait for its time. 15440 addProcessToGcListLocked(proc); 15441 break; 15442 } 15443 } 15444 } 15445 15446 scheduleAppGcsLocked(); 15447 } 15448 } 15449 15450 /** 15451 * If all looks good, perform GCs on all processes waiting for them. 15452 */ 15453 final void performAppGcsIfAppropriateLocked() { 15454 if (canGcNowLocked()) { 15455 performAppGcsLocked(); 15456 return; 15457 } 15458 // Still not idle, wait some more. 15459 scheduleAppGcsLocked(); 15460 } 15461 15462 /** 15463 * Schedule the execution of all pending app GCs. 15464 */ 15465 final void scheduleAppGcsLocked() { 15466 mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG); 15467 15468 if (mProcessesToGc.size() > 0) { 15469 // Schedule a GC for the time to the next process. 15470 ProcessRecord proc = mProcessesToGc.get(0); 15471 Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG); 15472 15473 long when = proc.lastRequestedGc + GC_MIN_INTERVAL; 15474 long now = SystemClock.uptimeMillis(); 15475 if (when < (now+GC_TIMEOUT)) { 15476 when = now + GC_TIMEOUT; 15477 } 15478 mHandler.sendMessageAtTime(msg, when); 15479 } 15480 } 15481 15482 /** 15483 * Add a process to the array of processes waiting to be GCed. Keeps the 15484 * list in sorted order by the last GC time. The process can't already be 15485 * on the list. 15486 */ 15487 final void addProcessToGcListLocked(ProcessRecord proc) { 15488 boolean added = false; 15489 for (int i=mProcessesToGc.size()-1; i>=0; i--) { 15490 if (mProcessesToGc.get(i).lastRequestedGc < 15491 proc.lastRequestedGc) { 15492 added = true; 15493 mProcessesToGc.add(i+1, proc); 15494 break; 15495 } 15496 } 15497 if (!added) { 15498 mProcessesToGc.add(0, proc); 15499 } 15500 } 15501 15502 /** 15503 * Set up to ask a process to GC itself. This will either do it 15504 * immediately, or put it on the list of processes to gc the next 15505 * time things are idle. 15506 */ 15507 final void scheduleAppGcLocked(ProcessRecord app) { 15508 long now = SystemClock.uptimeMillis(); 15509 if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) { 15510 return; 15511 } 15512 if (!mProcessesToGc.contains(app)) { 15513 addProcessToGcListLocked(app); 15514 scheduleAppGcsLocked(); 15515 } 15516 } 15517 15518 final void checkExcessivePowerUsageLocked(boolean doKills) { 15519 updateCpuStatsNow(); 15520 15521 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 15522 boolean doWakeKills = doKills; 15523 boolean doCpuKills = doKills; 15524 if (mLastPowerCheckRealtime == 0) { 15525 doWakeKills = false; 15526 } 15527 if (mLastPowerCheckUptime == 0) { 15528 doCpuKills = false; 15529 } 15530 if (stats.isScreenOn()) { 15531 doWakeKills = false; 15532 } 15533 final long curRealtime = SystemClock.elapsedRealtime(); 15534 final long realtimeSince = curRealtime - mLastPowerCheckRealtime; 15535 final long curUptime = SystemClock.uptimeMillis(); 15536 final long uptimeSince = curUptime - mLastPowerCheckUptime; 15537 mLastPowerCheckRealtime = curRealtime; 15538 mLastPowerCheckUptime = curUptime; 15539 if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) { 15540 doWakeKills = false; 15541 } 15542 if (uptimeSince < CPU_MIN_CHECK_DURATION) { 15543 doCpuKills = false; 15544 } 15545 int i = mLruProcesses.size(); 15546 while (i > 0) { 15547 i--; 15548 ProcessRecord app = mLruProcesses.get(i); 15549 if (!app.keeping) { 15550 long wtime; 15551 synchronized (stats) { 15552 wtime = stats.getProcessWakeTime(app.info.uid, 15553 app.pid, curRealtime); 15554 } 15555 long wtimeUsed = wtime - app.lastWakeTime; 15556 long cputimeUsed = app.curCpuTime - app.lastCpuTime; 15557 if (DEBUG_POWER) { 15558 StringBuilder sb = new StringBuilder(128); 15559 sb.append("Wake for "); 15560 app.toShortString(sb); 15561 sb.append(": over "); 15562 TimeUtils.formatDuration(realtimeSince, sb); 15563 sb.append(" used "); 15564 TimeUtils.formatDuration(wtimeUsed, sb); 15565 sb.append(" ("); 15566 sb.append((wtimeUsed*100)/realtimeSince); 15567 sb.append("%)"); 15568 Slog.i(TAG, sb.toString()); 15569 sb.setLength(0); 15570 sb.append("CPU for "); 15571 app.toShortString(sb); 15572 sb.append(": over "); 15573 TimeUtils.formatDuration(uptimeSince, sb); 15574 sb.append(" used "); 15575 TimeUtils.formatDuration(cputimeUsed, sb); 15576 sb.append(" ("); 15577 sb.append((cputimeUsed*100)/uptimeSince); 15578 sb.append("%)"); 15579 Slog.i(TAG, sb.toString()); 15580 } 15581 // If a process has held a wake lock for more 15582 // than 50% of the time during this period, 15583 // that sounds bad. Kill! 15584 if (doWakeKills && realtimeSince > 0 15585 && ((wtimeUsed*100)/realtimeSince) >= 50) { 15586 synchronized (stats) { 15587 stats.reportExcessiveWakeLocked(app.info.uid, app.processName, 15588 realtimeSince, wtimeUsed); 15589 } 15590 killUnneededProcessLocked(app, "excessive wake held " + wtimeUsed 15591 + " during " + realtimeSince); 15592 app.baseProcessTracker.reportExcessiveWake(app.pkgList); 15593 } else if (doCpuKills && uptimeSince > 0 15594 && ((cputimeUsed*100)/uptimeSince) >= 50) { 15595 synchronized (stats) { 15596 stats.reportExcessiveCpuLocked(app.info.uid, app.processName, 15597 uptimeSince, cputimeUsed); 15598 } 15599 killUnneededProcessLocked(app, "excessive cpu " + cputimeUsed 15600 + " during " + uptimeSince); 15601 app.baseProcessTracker.reportExcessiveCpu(app.pkgList); 15602 } else { 15603 app.lastWakeTime = wtime; 15604 app.lastCpuTime = app.curCpuTime; 15605 } 15606 } 15607 } 15608 } 15609 15610 private final boolean applyOomAdjLocked(ProcessRecord app, boolean wasKeeping, 15611 ProcessRecord TOP_APP, boolean doingAll, long now) { 15612 boolean success = true; 15613 15614 if (app.curRawAdj != app.setRawAdj) { 15615 if (wasKeeping && !app.keeping) { 15616 // This app is no longer something we want to keep. Note 15617 // its current wake lock time to later know to kill it if 15618 // it is not behaving well. 15619 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 15620 synchronized (stats) { 15621 app.lastWakeTime = stats.getProcessWakeTime(app.info.uid, 15622 app.pid, SystemClock.elapsedRealtime()); 15623 } 15624 app.lastCpuTime = app.curCpuTime; 15625 } 15626 15627 app.setRawAdj = app.curRawAdj; 15628 } 15629 15630 int changes = 0; 15631 15632 if (app.curAdj != app.setAdj) { 15633 ProcessList.setOomAdj(app.pid, app.curAdj); 15634 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v( 15635 TAG, "Set " + app.pid + " " + app.processName + 15636 " adj " + app.curAdj + ": " + app.adjType); 15637 app.setAdj = app.curAdj; 15638 } 15639 15640 if (app.setSchedGroup != app.curSchedGroup) { 15641 app.setSchedGroup = app.curSchedGroup; 15642 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 15643 "Setting process group of " + app.processName 15644 + " to " + app.curSchedGroup); 15645 if (app.waitingToKill != null && 15646 app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 15647 killUnneededProcessLocked(app, app.waitingToKill); 15648 success = false; 15649 } else { 15650 if (true) { 15651 long oldId = Binder.clearCallingIdentity(); 15652 try { 15653 Process.setProcessGroup(app.pid, app.curSchedGroup); 15654 } catch (Exception e) { 15655 Slog.w(TAG, "Failed setting process group of " + app.pid 15656 + " to " + app.curSchedGroup); 15657 e.printStackTrace(); 15658 } finally { 15659 Binder.restoreCallingIdentity(oldId); 15660 } 15661 } else { 15662 if (app.thread != null) { 15663 try { 15664 app.thread.setSchedulingGroup(app.curSchedGroup); 15665 } catch (RemoteException e) { 15666 } 15667 } 15668 } 15669 Process.setSwappiness(app.pid, 15670 app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE); 15671 } 15672 } 15673 if (app.repForegroundActivities != app.foregroundActivities) { 15674 app.repForegroundActivities = app.foregroundActivities; 15675 changes |= ProcessChangeItem.CHANGE_ACTIVITIES; 15676 } 15677 if (app.repProcState != app.curProcState) { 15678 app.repProcState = app.curProcState; 15679 changes |= ProcessChangeItem.CHANGE_PROCESS_STATE; 15680 if (app.thread != null) { 15681 try { 15682 if (false) { 15683 //RuntimeException h = new RuntimeException("here"); 15684 Slog.i(TAG, "Sending new process state " + app.repProcState 15685 + " to " + app /*, h*/); 15686 } 15687 app.thread.setProcessState(app.repProcState); 15688 } catch (RemoteException e) { 15689 } 15690 } 15691 } 15692 if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState, 15693 app.setProcState)) { 15694 app.lastStateTime = now; 15695 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true, 15696 isSleeping(), now); 15697 if (DEBUG_PSS) Slog.d(TAG, "Process state change from " 15698 + ProcessList.makeProcStateString(app.setProcState) + " to " 15699 + ProcessList.makeProcStateString(app.curProcState) + " next pss in " 15700 + (app.nextPssTime-now) + ": " + app); 15701 } else { 15702 if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL) 15703 && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) { 15704 requestPssLocked(app, app.setProcState); 15705 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false, 15706 isSleeping(), now); 15707 } else if (false && DEBUG_PSS) { 15708 Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now)); 15709 } 15710 } 15711 if (app.setProcState != app.curProcState) { 15712 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 15713 "Proc state change of " + app.processName 15714 + " to " + app.curProcState); 15715 app.setProcState = app.curProcState; 15716 if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) { 15717 app.notCachedSinceIdle = false; 15718 } 15719 if (!doingAll) { 15720 setProcessTrackerState(app, mProcessStats.getMemFactorLocked(), now); 15721 } else { 15722 app.procStateChanged = true; 15723 } 15724 } 15725 15726 if (changes != 0) { 15727 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes); 15728 int i = mPendingProcessChanges.size()-1; 15729 ProcessChangeItem item = null; 15730 while (i >= 0) { 15731 item = mPendingProcessChanges.get(i); 15732 if (item.pid == app.pid) { 15733 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item); 15734 break; 15735 } 15736 i--; 15737 } 15738 if (i < 0) { 15739 // No existing item in pending changes; need a new one. 15740 final int NA = mAvailProcessChanges.size(); 15741 if (NA > 0) { 15742 item = mAvailProcessChanges.remove(NA-1); 15743 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item); 15744 } else { 15745 item = new ProcessChangeItem(); 15746 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item); 15747 } 15748 item.changes = 0; 15749 item.pid = app.pid; 15750 item.uid = app.info.uid; 15751 if (mPendingProcessChanges.size() == 0) { 15752 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, 15753 "*** Enqueueing dispatch processes changed!"); 15754 mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget(); 15755 } 15756 mPendingProcessChanges.add(item); 15757 } 15758 item.changes |= changes; 15759 item.processState = app.repProcState; 15760 item.foregroundActivities = app.repForegroundActivities; 15761 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item " 15762 + Integer.toHexString(System.identityHashCode(item)) 15763 + " " + app.toShortString() + ": changes=" + item.changes 15764 + " procState=" + item.processState 15765 + " foreground=" + item.foregroundActivities 15766 + " type=" + app.adjType + " source=" + app.adjSource 15767 + " target=" + app.adjTarget); 15768 } 15769 15770 return success; 15771 } 15772 15773 private final void setProcessTrackerState(ProcessRecord proc, int memFactor, long now) { 15774 if (proc.thread != null && proc.baseProcessTracker != null) { 15775 proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList); 15776 } 15777 } 15778 15779 private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj, 15780 ProcessRecord TOP_APP, boolean doingAll, long now) { 15781 if (app.thread == null) { 15782 return false; 15783 } 15784 15785 final boolean wasKeeping = app.keeping; 15786 15787 computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now); 15788 15789 return applyOomAdjLocked(app, wasKeeping, TOP_APP, doingAll, now); 15790 } 15791 15792 final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground, 15793 boolean oomAdj) { 15794 if (isForeground != proc.foregroundServices) { 15795 proc.foregroundServices = isForeground; 15796 ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName, 15797 proc.info.uid); 15798 if (isForeground) { 15799 if (curProcs == null) { 15800 curProcs = new ArrayList<ProcessRecord>(); 15801 mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs); 15802 } 15803 if (!curProcs.contains(proc)) { 15804 curProcs.add(proc); 15805 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START, 15806 proc.info.packageName, proc.info.uid); 15807 } 15808 } else { 15809 if (curProcs != null) { 15810 if (curProcs.remove(proc)) { 15811 mBatteryStatsService.noteEvent( 15812 BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH, 15813 proc.info.packageName, proc.info.uid); 15814 if (curProcs.size() <= 0) { 15815 mForegroundPackages.remove(proc.info.packageName, proc.info.uid); 15816 } 15817 } 15818 } 15819 } 15820 if (oomAdj) { 15821 updateOomAdjLocked(); 15822 } 15823 } 15824 } 15825 15826 private final ActivityRecord resumedAppLocked() { 15827 ActivityRecord act = mStackSupervisor.resumedAppLocked(); 15828 String pkg; 15829 int uid; 15830 if (act != null && !act.sleeping) { 15831 pkg = act.packageName; 15832 uid = act.info.applicationInfo.uid; 15833 } else { 15834 pkg = null; 15835 uid = -1; 15836 } 15837 // Has the UID or resumed package name changed? 15838 if (uid != mCurResumedUid || (pkg != mCurResumedPackage 15839 && (pkg == null || !pkg.equals(mCurResumedPackage)))) { 15840 if (mCurResumedPackage != null) { 15841 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH, 15842 mCurResumedPackage, mCurResumedUid); 15843 } 15844 mCurResumedPackage = pkg; 15845 mCurResumedUid = uid; 15846 if (mCurResumedPackage != null) { 15847 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START, 15848 mCurResumedPackage, mCurResumedUid); 15849 } 15850 } 15851 return act; 15852 } 15853 15854 final boolean updateOomAdjLocked(ProcessRecord app) { 15855 final ActivityRecord TOP_ACT = resumedAppLocked(); 15856 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 15857 final boolean wasCached = app.cached; 15858 15859 mAdjSeq++; 15860 15861 // This is the desired cached adjusment we want to tell it to use. 15862 // If our app is currently cached, we know it, and that is it. Otherwise, 15863 // we don't know it yet, and it needs to now be cached we will then 15864 // need to do a complete oom adj. 15865 final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ 15866 ? app.curRawAdj : ProcessList.UNKNOWN_ADJ; 15867 boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false, 15868 SystemClock.uptimeMillis()); 15869 if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) { 15870 // Changed to/from cached state, so apps after it in the LRU 15871 // list may also be changed. 15872 updateOomAdjLocked(); 15873 } 15874 return success; 15875 } 15876 15877 final void updateOomAdjLocked() { 15878 final ActivityRecord TOP_ACT = resumedAppLocked(); 15879 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 15880 final long now = SystemClock.uptimeMillis(); 15881 final long oldTime = now - ProcessList.MAX_EMPTY_TIME; 15882 final int N = mLruProcesses.size(); 15883 15884 if (false) { 15885 RuntimeException e = new RuntimeException(); 15886 e.fillInStackTrace(); 15887 Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e); 15888 } 15889 15890 mAdjSeq++; 15891 mNewNumServiceProcs = 0; 15892 mNewNumAServiceProcs = 0; 15893 15894 final int emptyProcessLimit; 15895 final int cachedProcessLimit; 15896 if (mProcessLimit <= 0) { 15897 emptyProcessLimit = cachedProcessLimit = 0; 15898 } else if (mProcessLimit == 1) { 15899 emptyProcessLimit = 1; 15900 cachedProcessLimit = 0; 15901 } else { 15902 emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit); 15903 cachedProcessLimit = mProcessLimit - emptyProcessLimit; 15904 } 15905 15906 // Let's determine how many processes we have running vs. 15907 // how many slots we have for background processes; we may want 15908 // to put multiple processes in a slot of there are enough of 15909 // them. 15910 int numSlots = (ProcessList.CACHED_APP_MAX_ADJ 15911 - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2; 15912 int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs; 15913 if (numEmptyProcs > cachedProcessLimit) { 15914 // If there are more empty processes than our limit on cached 15915 // processes, then use the cached process limit for the factor. 15916 // This ensures that the really old empty processes get pushed 15917 // down to the bottom, so if we are running low on memory we will 15918 // have a better chance at keeping around more cached processes 15919 // instead of a gazillion empty processes. 15920 numEmptyProcs = cachedProcessLimit; 15921 } 15922 int emptyFactor = numEmptyProcs/numSlots; 15923 if (emptyFactor < 1) emptyFactor = 1; 15924 int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots; 15925 if (cachedFactor < 1) cachedFactor = 1; 15926 int stepCached = 0; 15927 int stepEmpty = 0; 15928 int numCached = 0; 15929 int numEmpty = 0; 15930 int numTrimming = 0; 15931 15932 mNumNonCachedProcs = 0; 15933 mNumCachedHiddenProcs = 0; 15934 15935 // First update the OOM adjustment for each of the 15936 // application processes based on their current state. 15937 int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ; 15938 int nextCachedAdj = curCachedAdj+1; 15939 int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ; 15940 int nextEmptyAdj = curEmptyAdj+2; 15941 for (int i=N-1; i>=0; i--) { 15942 ProcessRecord app = mLruProcesses.get(i); 15943 if (!app.killedByAm && app.thread != null) { 15944 app.procStateChanged = false; 15945 final boolean wasKeeping = app.keeping; 15946 computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now); 15947 15948 // If we haven't yet assigned the final cached adj 15949 // to the process, do that now. 15950 if (app.curAdj >= ProcessList.UNKNOWN_ADJ) { 15951 switch (app.curProcState) { 15952 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY: 15953 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: 15954 // This process is a cached process holding activities... 15955 // assign it the next cached value for that type, and then 15956 // step that cached level. 15957 app.curRawAdj = curCachedAdj; 15958 app.curAdj = app.modifyRawOomAdj(curCachedAdj); 15959 if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i 15960 + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj 15961 + ")"); 15962 if (curCachedAdj != nextCachedAdj) { 15963 stepCached++; 15964 if (stepCached >= cachedFactor) { 15965 stepCached = 0; 15966 curCachedAdj = nextCachedAdj; 15967 nextCachedAdj += 2; 15968 if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) { 15969 nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ; 15970 } 15971 } 15972 } 15973 break; 15974 default: 15975 // For everything else, assign next empty cached process 15976 // level and bump that up. Note that this means that 15977 // long-running services that have dropped down to the 15978 // cached level will be treated as empty (since their process 15979 // state is still as a service), which is what we want. 15980 app.curRawAdj = curEmptyAdj; 15981 app.curAdj = app.modifyRawOomAdj(curEmptyAdj); 15982 if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i 15983 + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj 15984 + ")"); 15985 if (curEmptyAdj != nextEmptyAdj) { 15986 stepEmpty++; 15987 if (stepEmpty >= emptyFactor) { 15988 stepEmpty = 0; 15989 curEmptyAdj = nextEmptyAdj; 15990 nextEmptyAdj += 2; 15991 if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) { 15992 nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ; 15993 } 15994 } 15995 } 15996 break; 15997 } 15998 } 15999 16000 applyOomAdjLocked(app, wasKeeping, TOP_APP, true, now); 16001 16002 // Count the number of process types. 16003 switch (app.curProcState) { 16004 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY: 16005 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: 16006 mNumCachedHiddenProcs++; 16007 numCached++; 16008 if (numCached > cachedProcessLimit) { 16009 killUnneededProcessLocked(app, "cached #" + numCached); 16010 } 16011 break; 16012 case ActivityManager.PROCESS_STATE_CACHED_EMPTY: 16013 if (numEmpty > ProcessList.TRIM_EMPTY_APPS 16014 && app.lastActivityTime < oldTime) { 16015 killUnneededProcessLocked(app, "empty for " 16016 + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime) 16017 / 1000) + "s"); 16018 } else { 16019 numEmpty++; 16020 if (numEmpty > emptyProcessLimit) { 16021 killUnneededProcessLocked(app, "empty #" + numEmpty); 16022 } 16023 } 16024 break; 16025 default: 16026 mNumNonCachedProcs++; 16027 break; 16028 } 16029 16030 if (app.isolated && app.services.size() <= 0) { 16031 // If this is an isolated process, and there are no 16032 // services running in it, then the process is no longer 16033 // needed. We agressively kill these because we can by 16034 // definition not re-use the same process again, and it is 16035 // good to avoid having whatever code was running in them 16036 // left sitting around after no longer needed. 16037 killUnneededProcessLocked(app, "isolated not needed"); 16038 } 16039 16040 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME 16041 && !app.killedByAm) { 16042 numTrimming++; 16043 } 16044 } 16045 } 16046 16047 mNumServiceProcs = mNewNumServiceProcs; 16048 16049 // Now determine the memory trimming level of background processes. 16050 // Unfortunately we need to start at the back of the list to do this 16051 // properly. We only do this if the number of background apps we 16052 // are managing to keep around is less than half the maximum we desire; 16053 // if we are keeping a good number around, we'll let them use whatever 16054 // memory they want. 16055 final int numCachedAndEmpty = numCached + numEmpty; 16056 int memFactor; 16057 if (numCached <= ProcessList.TRIM_CACHED_APPS 16058 && numEmpty <= ProcessList.TRIM_EMPTY_APPS) { 16059 if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) { 16060 memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL; 16061 } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) { 16062 memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW; 16063 } else { 16064 memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE; 16065 } 16066 } else { 16067 memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL; 16068 } 16069 // We always allow the memory level to go up (better). We only allow it to go 16070 // down if we are in a state where that is allowed, *and* the total number of processes 16071 // has gone down since last time. 16072 if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel 16073 + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size() 16074 + " last=" + mLastNumProcesses); 16075 if (memFactor > mLastMemoryLevel) { 16076 if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) { 16077 memFactor = mLastMemoryLevel; 16078 if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!"); 16079 } 16080 } 16081 mLastMemoryLevel = memFactor; 16082 mLastNumProcesses = mLruProcesses.size(); 16083 boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now); 16084 final int trackerMemFactor = mProcessStats.getMemFactorLocked(); 16085 if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) { 16086 if (mLowRamStartTime == 0) { 16087 mLowRamStartTime = now; 16088 } 16089 int step = 0; 16090 int fgTrimLevel; 16091 switch (memFactor) { 16092 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL: 16093 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL; 16094 break; 16095 case ProcessStats.ADJ_MEM_FACTOR_LOW: 16096 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW; 16097 break; 16098 default: 16099 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE; 16100 break; 16101 } 16102 int factor = numTrimming/3; 16103 int minFactor = 2; 16104 if (mHomeProcess != null) minFactor++; 16105 if (mPreviousProcess != null) minFactor++; 16106 if (factor < minFactor) factor = minFactor; 16107 int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE; 16108 for (int i=N-1; i>=0; i--) { 16109 ProcessRecord app = mLruProcesses.get(i); 16110 if (allChanged || app.procStateChanged) { 16111 setProcessTrackerState(app, trackerMemFactor, now); 16112 app.procStateChanged = false; 16113 } 16114 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME 16115 && !app.killedByAm) { 16116 if (app.trimMemoryLevel < curLevel && app.thread != null) { 16117 try { 16118 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 16119 "Trimming memory of " + app.processName 16120 + " to " + curLevel); 16121 app.thread.scheduleTrimMemory(curLevel); 16122 } catch (RemoteException e) { 16123 } 16124 if (false) { 16125 // For now we won't do this; our memory trimming seems 16126 // to be good enough at this point that destroying 16127 // activities causes more harm than good. 16128 if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE 16129 && app != mHomeProcess && app != mPreviousProcess) { 16130 // Need to do this on its own message because the stack may not 16131 // be in a consistent state at this point. 16132 // For these apps we will also finish their activities 16133 // to help them free memory. 16134 mStackSupervisor.scheduleDestroyAllActivities(app, "trim"); 16135 } 16136 } 16137 } 16138 app.trimMemoryLevel = curLevel; 16139 step++; 16140 if (step >= factor) { 16141 step = 0; 16142 switch (curLevel) { 16143 case ComponentCallbacks2.TRIM_MEMORY_COMPLETE: 16144 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE; 16145 break; 16146 case ComponentCallbacks2.TRIM_MEMORY_MODERATE: 16147 curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 16148 break; 16149 } 16150 } 16151 } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) { 16152 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND 16153 && app.thread != null) { 16154 try { 16155 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 16156 "Trimming memory of heavy-weight " + app.processName 16157 + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 16158 app.thread.scheduleTrimMemory( 16159 ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 16160 } catch (RemoteException e) { 16161 } 16162 } 16163 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 16164 } else { 16165 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 16166 || app.systemNoUi) && app.pendingUiClean) { 16167 // If this application is now in the background and it 16168 // had done UI, then give it the special trim level to 16169 // have it free UI resources. 16170 final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN; 16171 if (app.trimMemoryLevel < level && app.thread != null) { 16172 try { 16173 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 16174 "Trimming memory of bg-ui " + app.processName 16175 + " to " + level); 16176 app.thread.scheduleTrimMemory(level); 16177 } catch (RemoteException e) { 16178 } 16179 } 16180 app.pendingUiClean = false; 16181 } 16182 if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) { 16183 try { 16184 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 16185 "Trimming memory of fg " + app.processName 16186 + " to " + fgTrimLevel); 16187 app.thread.scheduleTrimMemory(fgTrimLevel); 16188 } catch (RemoteException e) { 16189 } 16190 } 16191 app.trimMemoryLevel = fgTrimLevel; 16192 } 16193 } 16194 } else { 16195 if (mLowRamStartTime != 0) { 16196 mLowRamTimeSinceLastIdle += now - mLowRamStartTime; 16197 mLowRamStartTime = 0; 16198 } 16199 for (int i=N-1; i>=0; i--) { 16200 ProcessRecord app = mLruProcesses.get(i); 16201 if (allChanged || app.procStateChanged) { 16202 setProcessTrackerState(app, trackerMemFactor, now); 16203 app.procStateChanged = false; 16204 } 16205 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 16206 || app.systemNoUi) && app.pendingUiClean) { 16207 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN 16208 && app.thread != null) { 16209 try { 16210 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 16211 "Trimming memory of ui hidden " + app.processName 16212 + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 16213 app.thread.scheduleTrimMemory( 16214 ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 16215 } catch (RemoteException e) { 16216 } 16217 } 16218 app.pendingUiClean = false; 16219 } 16220 app.trimMemoryLevel = 0; 16221 } 16222 } 16223 16224 if (mAlwaysFinishActivities) { 16225 // Need to do this on its own message because the stack may not 16226 // be in a consistent state at this point. 16227 mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish"); 16228 } 16229 16230 if (allChanged) { 16231 requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered()); 16232 } 16233 16234 if (mProcessStats.shouldWriteNowLocked(now)) { 16235 mHandler.post(new Runnable() { 16236 @Override public void run() { 16237 synchronized (ActivityManagerService.this) { 16238 mProcessStats.writeStateAsyncLocked(); 16239 } 16240 } 16241 }); 16242 } 16243 16244 if (DEBUG_OOM_ADJ) { 16245 Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms"); 16246 } 16247 } 16248 16249 final void trimApplications() { 16250 synchronized (this) { 16251 int i; 16252 16253 // First remove any unused application processes whose package 16254 // has been removed. 16255 for (i=mRemovedProcesses.size()-1; i>=0; i--) { 16256 final ProcessRecord app = mRemovedProcesses.get(i); 16257 if (app.activities.size() == 0 16258 && app.curReceiver == null && app.services.size() == 0) { 16259 Slog.i( 16260 TAG, "Exiting empty application process " 16261 + app.processName + " (" 16262 + (app.thread != null ? app.thread.asBinder() : null) 16263 + ")\n"); 16264 if (app.pid > 0 && app.pid != MY_PID) { 16265 EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid, 16266 app.processName, app.setAdj, "empty"); 16267 app.killedByAm = true; 16268 Process.killProcessQuiet(app.pid); 16269 } else { 16270 try { 16271 app.thread.scheduleExit(); 16272 } catch (Exception e) { 16273 // Ignore exceptions. 16274 } 16275 } 16276 cleanUpApplicationRecordLocked(app, false, true, -1); 16277 mRemovedProcesses.remove(i); 16278 16279 if (app.persistent) { 16280 if (app.persistent) { 16281 addAppLocked(app.info, false); 16282 } 16283 } 16284 } 16285 } 16286 16287 // Now update the oom adj for all processes. 16288 updateOomAdjLocked(); 16289 } 16290 } 16291 16292 /** This method sends the specified signal to each of the persistent apps */ 16293 public void signalPersistentProcesses(int sig) throws RemoteException { 16294 if (sig != Process.SIGNAL_USR1) { 16295 throw new SecurityException("Only SIGNAL_USR1 is allowed"); 16296 } 16297 16298 synchronized (this) { 16299 if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES) 16300 != PackageManager.PERMISSION_GRANTED) { 16301 throw new SecurityException("Requires permission " 16302 + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES); 16303 } 16304 16305 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 16306 ProcessRecord r = mLruProcesses.get(i); 16307 if (r.thread != null && r.persistent) { 16308 Process.sendSignal(r.pid, sig); 16309 } 16310 } 16311 } 16312 } 16313 16314 private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) { 16315 if (proc == null || proc == mProfileProc) { 16316 proc = mProfileProc; 16317 path = mProfileFile; 16318 profileType = mProfileType; 16319 clearProfilerLocked(); 16320 } 16321 if (proc == null) { 16322 return; 16323 } 16324 try { 16325 proc.thread.profilerControl(false, path, null, profileType); 16326 } catch (RemoteException e) { 16327 throw new IllegalStateException("Process disappeared"); 16328 } 16329 } 16330 16331 private void clearProfilerLocked() { 16332 if (mProfileFd != null) { 16333 try { 16334 mProfileFd.close(); 16335 } catch (IOException e) { 16336 } 16337 } 16338 mProfileApp = null; 16339 mProfileProc = null; 16340 mProfileFile = null; 16341 mProfileType = 0; 16342 mAutoStopProfiler = false; 16343 } 16344 16345 public boolean profileControl(String process, int userId, boolean start, 16346 String path, ParcelFileDescriptor fd, int profileType) throws RemoteException { 16347 16348 try { 16349 synchronized (this) { 16350 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 16351 // its own permission. 16352 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 16353 != PackageManager.PERMISSION_GRANTED) { 16354 throw new SecurityException("Requires permission " 16355 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 16356 } 16357 16358 if (start && fd == null) { 16359 throw new IllegalArgumentException("null fd"); 16360 } 16361 16362 ProcessRecord proc = null; 16363 if (process != null) { 16364 proc = findProcessLocked(process, userId, "profileControl"); 16365 } 16366 16367 if (start && (proc == null || proc.thread == null)) { 16368 throw new IllegalArgumentException("Unknown process: " + process); 16369 } 16370 16371 if (start) { 16372 stopProfilerLocked(null, null, 0); 16373 setProfileApp(proc.info, proc.processName, path, fd, false); 16374 mProfileProc = proc; 16375 mProfileType = profileType; 16376 try { 16377 fd = fd.dup(); 16378 } catch (IOException e) { 16379 fd = null; 16380 } 16381 proc.thread.profilerControl(start, path, fd, profileType); 16382 fd = null; 16383 mProfileFd = null; 16384 } else { 16385 stopProfilerLocked(proc, path, profileType); 16386 if (fd != null) { 16387 try { 16388 fd.close(); 16389 } catch (IOException e) { 16390 } 16391 } 16392 } 16393 16394 return true; 16395 } 16396 } catch (RemoteException e) { 16397 throw new IllegalStateException("Process disappeared"); 16398 } finally { 16399 if (fd != null) { 16400 try { 16401 fd.close(); 16402 } catch (IOException e) { 16403 } 16404 } 16405 } 16406 } 16407 16408 private ProcessRecord findProcessLocked(String process, int userId, String callName) { 16409 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 16410 userId, true, true, callName, null); 16411 ProcessRecord proc = null; 16412 try { 16413 int pid = Integer.parseInt(process); 16414 synchronized (mPidsSelfLocked) { 16415 proc = mPidsSelfLocked.get(pid); 16416 } 16417 } catch (NumberFormatException e) { 16418 } 16419 16420 if (proc == null) { 16421 ArrayMap<String, SparseArray<ProcessRecord>> all 16422 = mProcessNames.getMap(); 16423 SparseArray<ProcessRecord> procs = all.get(process); 16424 if (procs != null && procs.size() > 0) { 16425 proc = procs.valueAt(0); 16426 if (userId != UserHandle.USER_ALL && proc.userId != userId) { 16427 for (int i=1; i<procs.size(); i++) { 16428 ProcessRecord thisProc = procs.valueAt(i); 16429 if (thisProc.userId == userId) { 16430 proc = thisProc; 16431 break; 16432 } 16433 } 16434 } 16435 } 16436 } 16437 16438 return proc; 16439 } 16440 16441 public boolean dumpHeap(String process, int userId, boolean managed, 16442 String path, ParcelFileDescriptor fd) throws RemoteException { 16443 16444 try { 16445 synchronized (this) { 16446 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 16447 // its own permission (same as profileControl). 16448 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 16449 != PackageManager.PERMISSION_GRANTED) { 16450 throw new SecurityException("Requires permission " 16451 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 16452 } 16453 16454 if (fd == null) { 16455 throw new IllegalArgumentException("null fd"); 16456 } 16457 16458 ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap"); 16459 if (proc == null || proc.thread == null) { 16460 throw new IllegalArgumentException("Unknown process: " + process); 16461 } 16462 16463 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 16464 if (!isDebuggable) { 16465 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 16466 throw new SecurityException("Process not debuggable: " + proc); 16467 } 16468 } 16469 16470 proc.thread.dumpHeap(managed, path, fd); 16471 fd = null; 16472 return true; 16473 } 16474 } catch (RemoteException e) { 16475 throw new IllegalStateException("Process disappeared"); 16476 } finally { 16477 if (fd != null) { 16478 try { 16479 fd.close(); 16480 } catch (IOException e) { 16481 } 16482 } 16483 } 16484 } 16485 16486 /** In this method we try to acquire our lock to make sure that we have not deadlocked */ 16487 public void monitor() { 16488 synchronized (this) { } 16489 } 16490 16491 void onCoreSettingsChange(Bundle settings) { 16492 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 16493 ProcessRecord processRecord = mLruProcesses.get(i); 16494 try { 16495 if (processRecord.thread != null) { 16496 processRecord.thread.setCoreSettings(settings); 16497 } 16498 } catch (RemoteException re) { 16499 /* ignore */ 16500 } 16501 } 16502 } 16503 16504 // Multi-user methods 16505 16506 /** 16507 * Start user, if its not already running, but don't bring it to foreground. 16508 */ 16509 @Override 16510 public boolean startUserInBackground(final int userId) { 16511 return startUser(userId, /* foreground */ false); 16512 } 16513 16514 /** 16515 * Refreshes the list of users related to the current user when either a 16516 * user switch happens or when a new related user is started in the 16517 * background. 16518 */ 16519 private void updateCurrentProfileIdsLocked() { 16520 final List<UserInfo> profiles = getUserManagerLocked().getProfiles( 16521 mCurrentUserId, false /* enabledOnly */); 16522 int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null 16523 for (int i = 0; i < currentProfileIds.length; i++) { 16524 currentProfileIds[i] = profiles.get(i).id; 16525 } 16526 mCurrentProfileIds = currentProfileIds; 16527 } 16528 16529 private Set getProfileIdsLocked(int userId) { 16530 Set userIds = new HashSet<Integer>(); 16531 final List<UserInfo> profiles = getUserManagerLocked().getProfiles( 16532 userId, false /* enabledOnly */); 16533 for (UserInfo user : profiles) { 16534 userIds.add(Integer.valueOf(user.id)); 16535 } 16536 return userIds; 16537 } 16538 16539 @Override 16540 public boolean switchUser(final int userId) { 16541 return startUser(userId, /* foregound */ true); 16542 } 16543 16544 private boolean startUser(final int userId, boolean foreground) { 16545 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 16546 != PackageManager.PERMISSION_GRANTED) { 16547 String msg = "Permission Denial: switchUser() from pid=" 16548 + Binder.getCallingPid() 16549 + ", uid=" + Binder.getCallingUid() 16550 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 16551 Slog.w(TAG, msg); 16552 throw new SecurityException(msg); 16553 } 16554 16555 if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground); 16556 16557 final long ident = Binder.clearCallingIdentity(); 16558 try { 16559 synchronized (this) { 16560 final int oldUserId = mCurrentUserId; 16561 if (oldUserId == userId) { 16562 return true; 16563 } 16564 16565 mStackSupervisor.setLockTaskModeLocked(null); 16566 16567 final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId); 16568 if (userInfo == null) { 16569 Slog.w(TAG, "No user info for user #" + userId); 16570 return false; 16571 } 16572 16573 if (foreground) { 16574 mWindowManager.startFreezingScreen(R.anim.screen_user_exit, 16575 R.anim.screen_user_enter); 16576 } 16577 16578 boolean needStart = false; 16579 16580 // If the user we are switching to is not currently started, then 16581 // we need to start it now. 16582 if (mStartedUsers.get(userId) == null) { 16583 mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false)); 16584 updateStartedUserArrayLocked(); 16585 needStart = true; 16586 } 16587 16588 final Integer userIdInt = Integer.valueOf(userId); 16589 mUserLru.remove(userIdInt); 16590 mUserLru.add(userIdInt); 16591 16592 if (foreground) { 16593 mCurrentUserId = userId; 16594 updateCurrentProfileIdsLocked(); 16595 mWindowManager.setCurrentUser(userId, mCurrentProfileIds); 16596 // Once the internal notion of the active user has switched, we lock the device 16597 // with the option to show the user switcher on the keyguard. 16598 mWindowManager.lockNow(null); 16599 } else { 16600 final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId); 16601 updateCurrentProfileIdsLocked(); 16602 mWindowManager.setCurrentProfileIds(mCurrentProfileIds); 16603 mUserLru.remove(currentUserIdInt); 16604 mUserLru.add(currentUserIdInt); 16605 } 16606 16607 final UserStartedState uss = mStartedUsers.get(userId); 16608 16609 // Make sure user is in the started state. If it is currently 16610 // stopping, we need to knock that off. 16611 if (uss.mState == UserStartedState.STATE_STOPPING) { 16612 // If we are stopping, we haven't sent ACTION_SHUTDOWN, 16613 // so we can just fairly silently bring the user back from 16614 // the almost-dead. 16615 uss.mState = UserStartedState.STATE_RUNNING; 16616 updateStartedUserArrayLocked(); 16617 needStart = true; 16618 } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) { 16619 // This means ACTION_SHUTDOWN has been sent, so we will 16620 // need to treat this as a new boot of the user. 16621 uss.mState = UserStartedState.STATE_BOOTING; 16622 updateStartedUserArrayLocked(); 16623 needStart = true; 16624 } 16625 16626 if (uss.mState == UserStartedState.STATE_BOOTING) { 16627 // Booting up a new user, need to tell system services about it. 16628 // Note that this is on the same handler as scheduling of broadcasts, 16629 // which is important because it needs to go first. 16630 mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId)); 16631 } 16632 16633 if (foreground) { 16634 mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId)); 16635 mHandler.removeMessages(REPORT_USER_SWITCH_MSG); 16636 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 16637 mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG, 16638 oldUserId, userId, uss)); 16639 mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG, 16640 oldUserId, userId, uss), USER_SWITCH_TIMEOUT); 16641 } 16642 16643 if (needStart) { 16644 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 16645 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16646 | Intent.FLAG_RECEIVER_FOREGROUND); 16647 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 16648 broadcastIntentLocked(null, null, intent, 16649 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 16650 false, false, MY_PID, Process.SYSTEM_UID, userId); 16651 } 16652 16653 if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) { 16654 if (userId != UserHandle.USER_OWNER) { 16655 Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE); 16656 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 16657 broadcastIntentLocked(null, null, intent, null, 16658 new IIntentReceiver.Stub() { 16659 public void performReceive(Intent intent, int resultCode, 16660 String data, Bundle extras, boolean ordered, 16661 boolean sticky, int sendingUser) { 16662 userInitialized(uss, userId); 16663 } 16664 }, 0, null, null, null, AppOpsManager.OP_NONE, 16665 true, false, MY_PID, Process.SYSTEM_UID, 16666 userId); 16667 uss.initializing = true; 16668 } else { 16669 getUserManagerLocked().makeInitialized(userInfo.id); 16670 } 16671 } 16672 16673 if (foreground) { 16674 boolean homeInFront = mStackSupervisor.switchUserLocked(userId, uss); 16675 if (homeInFront) { 16676 startHomeActivityLocked(userId); 16677 } else { 16678 mStackSupervisor.resumeTopActivitiesLocked(); 16679 } 16680 EventLogTags.writeAmSwitchUser(userId); 16681 getUserManagerLocked().userForeground(userId); 16682 sendUserSwitchBroadcastsLocked(oldUserId, userId); 16683 } else { 16684 mStackSupervisor.startBackgroundUserLocked(userId, uss); 16685 } 16686 16687 if (needStart) { 16688 Intent intent = new Intent(Intent.ACTION_USER_STARTING); 16689 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 16690 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 16691 broadcastIntentLocked(null, null, intent, 16692 null, new IIntentReceiver.Stub() { 16693 @Override 16694 public void performReceive(Intent intent, int resultCode, String data, 16695 Bundle extras, boolean ordered, boolean sticky, int sendingUser) 16696 throws RemoteException { 16697 } 16698 }, 0, null, null, 16699 android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 16700 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 16701 } 16702 } 16703 } finally { 16704 Binder.restoreCallingIdentity(ident); 16705 } 16706 16707 return true; 16708 } 16709 16710 void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) { 16711 long ident = Binder.clearCallingIdentity(); 16712 try { 16713 Intent intent; 16714 if (oldUserId >= 0) { 16715 intent = new Intent(Intent.ACTION_USER_BACKGROUND); 16716 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16717 | Intent.FLAG_RECEIVER_FOREGROUND); 16718 intent.putExtra(Intent.EXTRA_USER_HANDLE, oldUserId); 16719 broadcastIntentLocked(null, null, intent, 16720 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 16721 false, false, MY_PID, Process.SYSTEM_UID, oldUserId); 16722 } 16723 if (newUserId >= 0) { 16724 intent = new Intent(Intent.ACTION_USER_FOREGROUND); 16725 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16726 | Intent.FLAG_RECEIVER_FOREGROUND); 16727 intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId); 16728 broadcastIntentLocked(null, null, intent, 16729 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 16730 false, false, MY_PID, Process.SYSTEM_UID, newUserId); 16731 intent = new Intent(Intent.ACTION_USER_SWITCHED); 16732 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16733 | Intent.FLAG_RECEIVER_FOREGROUND); 16734 intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId); 16735 broadcastIntentLocked(null, null, intent, 16736 null, null, 0, null, null, 16737 android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE, 16738 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 16739 } 16740 } finally { 16741 Binder.restoreCallingIdentity(ident); 16742 } 16743 } 16744 16745 void dispatchUserSwitch(final UserStartedState uss, final int oldUserId, 16746 final int newUserId) { 16747 final int N = mUserSwitchObservers.beginBroadcast(); 16748 if (N > 0) { 16749 final IRemoteCallback callback = new IRemoteCallback.Stub() { 16750 int mCount = 0; 16751 @Override 16752 public void sendResult(Bundle data) throws RemoteException { 16753 synchronized (ActivityManagerService.this) { 16754 if (mCurUserSwitchCallback == this) { 16755 mCount++; 16756 if (mCount == N) { 16757 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 16758 } 16759 } 16760 } 16761 } 16762 }; 16763 synchronized (this) { 16764 uss.switching = true; 16765 mCurUserSwitchCallback = callback; 16766 } 16767 for (int i=0; i<N; i++) { 16768 try { 16769 mUserSwitchObservers.getBroadcastItem(i).onUserSwitching( 16770 newUserId, callback); 16771 } catch (RemoteException e) { 16772 } 16773 } 16774 } else { 16775 synchronized (this) { 16776 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 16777 } 16778 } 16779 mUserSwitchObservers.finishBroadcast(); 16780 } 16781 16782 void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 16783 synchronized (this) { 16784 Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId); 16785 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 16786 } 16787 } 16788 16789 void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) { 16790 mCurUserSwitchCallback = null; 16791 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 16792 mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG, 16793 oldUserId, newUserId, uss)); 16794 } 16795 16796 void userInitialized(UserStartedState uss, int newUserId) { 16797 completeSwitchAndInitalize(uss, newUserId, true, false); 16798 } 16799 16800 void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 16801 completeSwitchAndInitalize(uss, newUserId, false, true); 16802 } 16803 16804 void completeSwitchAndInitalize(UserStartedState uss, int newUserId, 16805 boolean clearInitializing, boolean clearSwitching) { 16806 boolean unfrozen = false; 16807 synchronized (this) { 16808 if (clearInitializing) { 16809 uss.initializing = false; 16810 getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier()); 16811 } 16812 if (clearSwitching) { 16813 uss.switching = false; 16814 } 16815 if (!uss.switching && !uss.initializing) { 16816 mWindowManager.stopFreezingScreen(); 16817 unfrozen = true; 16818 } 16819 } 16820 if (unfrozen) { 16821 final int N = mUserSwitchObservers.beginBroadcast(); 16822 for (int i=0; i<N; i++) { 16823 try { 16824 mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId); 16825 } catch (RemoteException e) { 16826 } 16827 } 16828 mUserSwitchObservers.finishBroadcast(); 16829 } 16830 } 16831 16832 void scheduleStartProfilesLocked() { 16833 if (!mHandler.hasMessages(START_PROFILES_MSG)) { 16834 mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG), 16835 DateUtils.SECOND_IN_MILLIS); 16836 } 16837 } 16838 16839 void startProfilesLocked() { 16840 if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked"); 16841 List<UserInfo> profiles = getUserManagerLocked().getProfiles( 16842 mCurrentUserId, false /* enabledOnly */); 16843 List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size()); 16844 for (UserInfo user : profiles) { 16845 if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED 16846 && user.id != mCurrentUserId) { 16847 toStart.add(user); 16848 } 16849 } 16850 final int n = toStart.size(); 16851 int i = 0; 16852 for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) { 16853 startUserInBackground(toStart.get(i).id); 16854 } 16855 if (i < n) { 16856 Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS"); 16857 } 16858 } 16859 16860 void finishUserBoot(UserStartedState uss) { 16861 synchronized (this) { 16862 if (uss.mState == UserStartedState.STATE_BOOTING 16863 && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) { 16864 uss.mState = UserStartedState.STATE_RUNNING; 16865 final int userId = uss.mHandle.getIdentifier(); 16866 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 16867 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 16868 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT); 16869 broadcastIntentLocked(null, null, intent, 16870 null, null, 0, null, null, 16871 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE, 16872 true, false, MY_PID, Process.SYSTEM_UID, userId); 16873 } 16874 } 16875 } 16876 16877 void finishUserSwitch(UserStartedState uss) { 16878 synchronized (this) { 16879 finishUserBoot(uss); 16880 16881 startProfilesLocked(); 16882 16883 int num = mUserLru.size(); 16884 int i = 0; 16885 while (num > MAX_RUNNING_USERS && i < mUserLru.size()) { 16886 Integer oldUserId = mUserLru.get(i); 16887 UserStartedState oldUss = mStartedUsers.get(oldUserId); 16888 if (oldUss == null) { 16889 // Shouldn't happen, but be sane if it does. 16890 mUserLru.remove(i); 16891 num--; 16892 continue; 16893 } 16894 if (oldUss.mState == UserStartedState.STATE_STOPPING 16895 || oldUss.mState == UserStartedState.STATE_SHUTDOWN) { 16896 // This user is already stopping, doesn't count. 16897 num--; 16898 i++; 16899 continue; 16900 } 16901 if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) { 16902 // Owner and current can't be stopped, but count as running. 16903 i++; 16904 continue; 16905 } 16906 // This is a user to be stopped. 16907 stopUserLocked(oldUserId, null); 16908 num--; 16909 i++; 16910 } 16911 } 16912 } 16913 16914 @Override 16915 public int stopUser(final int userId, final IStopUserCallback callback) { 16916 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 16917 != PackageManager.PERMISSION_GRANTED) { 16918 String msg = "Permission Denial: switchUser() from pid=" 16919 + Binder.getCallingPid() 16920 + ", uid=" + Binder.getCallingUid() 16921 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 16922 Slog.w(TAG, msg); 16923 throw new SecurityException(msg); 16924 } 16925 if (userId <= 0) { 16926 throw new IllegalArgumentException("Can't stop primary user " + userId); 16927 } 16928 synchronized (this) { 16929 return stopUserLocked(userId, callback); 16930 } 16931 } 16932 16933 private int stopUserLocked(final int userId, final IStopUserCallback callback) { 16934 if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId); 16935 if (mCurrentUserId == userId) { 16936 return ActivityManager.USER_OP_IS_CURRENT; 16937 } 16938 16939 final UserStartedState uss = mStartedUsers.get(userId); 16940 if (uss == null) { 16941 // User is not started, nothing to do... but we do need to 16942 // callback if requested. 16943 if (callback != null) { 16944 mHandler.post(new Runnable() { 16945 @Override 16946 public void run() { 16947 try { 16948 callback.userStopped(userId); 16949 } catch (RemoteException e) { 16950 } 16951 } 16952 }); 16953 } 16954 return ActivityManager.USER_OP_SUCCESS; 16955 } 16956 16957 if (callback != null) { 16958 uss.mStopCallbacks.add(callback); 16959 } 16960 16961 if (uss.mState != UserStartedState.STATE_STOPPING 16962 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 16963 uss.mState = UserStartedState.STATE_STOPPING; 16964 updateStartedUserArrayLocked(); 16965 16966 long ident = Binder.clearCallingIdentity(); 16967 try { 16968 // We are going to broadcast ACTION_USER_STOPPING and then 16969 // once that is done send a final ACTION_SHUTDOWN and then 16970 // stop the user. 16971 final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING); 16972 stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 16973 stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 16974 stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true); 16975 final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN); 16976 // This is the result receiver for the final shutdown broadcast. 16977 final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() { 16978 @Override 16979 public void performReceive(Intent intent, int resultCode, String data, 16980 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 16981 finishUserStop(uss); 16982 } 16983 }; 16984 // This is the result receiver for the initial stopping broadcast. 16985 final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() { 16986 @Override 16987 public void performReceive(Intent intent, int resultCode, String data, 16988 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 16989 // On to the next. 16990 synchronized (ActivityManagerService.this) { 16991 if (uss.mState != UserStartedState.STATE_STOPPING) { 16992 // Whoops, we are being started back up. Abort, abort! 16993 return; 16994 } 16995 uss.mState = UserStartedState.STATE_SHUTDOWN; 16996 } 16997 mSystemServiceManager.stopUser(userId); 16998 broadcastIntentLocked(null, null, shutdownIntent, 16999 null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE, 17000 true, false, MY_PID, Process.SYSTEM_UID, userId); 17001 } 17002 }; 17003 // Kick things off. 17004 broadcastIntentLocked(null, null, stoppingIntent, 17005 null, stoppingReceiver, 0, null, null, 17006 android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 17007 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 17008 } finally { 17009 Binder.restoreCallingIdentity(ident); 17010 } 17011 } 17012 17013 return ActivityManager.USER_OP_SUCCESS; 17014 } 17015 17016 void finishUserStop(UserStartedState uss) { 17017 final int userId = uss.mHandle.getIdentifier(); 17018 boolean stopped; 17019 ArrayList<IStopUserCallback> callbacks; 17020 synchronized (this) { 17021 callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks); 17022 if (mStartedUsers.get(userId) != uss) { 17023 stopped = false; 17024 } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) { 17025 stopped = false; 17026 } else { 17027 stopped = true; 17028 // User can no longer run. 17029 mStartedUsers.remove(userId); 17030 mUserLru.remove(Integer.valueOf(userId)); 17031 updateStartedUserArrayLocked(); 17032 17033 // Clean up all state and processes associated with the user. 17034 // Kill all the processes for the user. 17035 forceStopUserLocked(userId, "finish user"); 17036 } 17037 } 17038 17039 for (int i=0; i<callbacks.size(); i++) { 17040 try { 17041 if (stopped) callbacks.get(i).userStopped(userId); 17042 else callbacks.get(i).userStopAborted(userId); 17043 } catch (RemoteException e) { 17044 } 17045 } 17046 17047 if (stopped) { 17048 mSystemServiceManager.cleanupUser(userId); 17049 synchronized (this) { 17050 mStackSupervisor.removeUserLocked(userId); 17051 } 17052 } 17053 } 17054 17055 @Override 17056 public UserInfo getCurrentUser() { 17057 if ((checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) 17058 != PackageManager.PERMISSION_GRANTED) && ( 17059 checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 17060 != PackageManager.PERMISSION_GRANTED)) { 17061 String msg = "Permission Denial: getCurrentUser() from pid=" 17062 + Binder.getCallingPid() 17063 + ", uid=" + Binder.getCallingUid() 17064 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS; 17065 Slog.w(TAG, msg); 17066 throw new SecurityException(msg); 17067 } 17068 synchronized (this) { 17069 return getUserManagerLocked().getUserInfo(mCurrentUserId); 17070 } 17071 } 17072 17073 int getCurrentUserIdLocked() { 17074 return mCurrentUserId; 17075 } 17076 17077 @Override 17078 public boolean isUserRunning(int userId, boolean orStopped) { 17079 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) 17080 != PackageManager.PERMISSION_GRANTED) { 17081 String msg = "Permission Denial: isUserRunning() from pid=" 17082 + Binder.getCallingPid() 17083 + ", uid=" + Binder.getCallingUid() 17084 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS; 17085 Slog.w(TAG, msg); 17086 throw new SecurityException(msg); 17087 } 17088 synchronized (this) { 17089 return isUserRunningLocked(userId, orStopped); 17090 } 17091 } 17092 17093 boolean isUserRunningLocked(int userId, boolean orStopped) { 17094 UserStartedState state = mStartedUsers.get(userId); 17095 if (state == null) { 17096 return false; 17097 } 17098 if (orStopped) { 17099 return true; 17100 } 17101 return state.mState != UserStartedState.STATE_STOPPING 17102 && state.mState != UserStartedState.STATE_SHUTDOWN; 17103 } 17104 17105 @Override 17106 public int[] getRunningUserIds() { 17107 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) 17108 != PackageManager.PERMISSION_GRANTED) { 17109 String msg = "Permission Denial: isUserRunning() from pid=" 17110 + Binder.getCallingPid() 17111 + ", uid=" + Binder.getCallingUid() 17112 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS; 17113 Slog.w(TAG, msg); 17114 throw new SecurityException(msg); 17115 } 17116 synchronized (this) { 17117 return mStartedUserArray; 17118 } 17119 } 17120 17121 private void updateStartedUserArrayLocked() { 17122 int num = 0; 17123 for (int i=0; i<mStartedUsers.size(); i++) { 17124 UserStartedState uss = mStartedUsers.valueAt(i); 17125 // This list does not include stopping users. 17126 if (uss.mState != UserStartedState.STATE_STOPPING 17127 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 17128 num++; 17129 } 17130 } 17131 mStartedUserArray = new int[num]; 17132 num = 0; 17133 for (int i=0; i<mStartedUsers.size(); i++) { 17134 UserStartedState uss = mStartedUsers.valueAt(i); 17135 if (uss.mState != UserStartedState.STATE_STOPPING 17136 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 17137 mStartedUserArray[num] = mStartedUsers.keyAt(i); 17138 num++; 17139 } 17140 } 17141 } 17142 17143 @Override 17144 public void registerUserSwitchObserver(IUserSwitchObserver observer) { 17145 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 17146 != PackageManager.PERMISSION_GRANTED) { 17147 String msg = "Permission Denial: registerUserSwitchObserver() from pid=" 17148 + Binder.getCallingPid() 17149 + ", uid=" + Binder.getCallingUid() 17150 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 17151 Slog.w(TAG, msg); 17152 throw new SecurityException(msg); 17153 } 17154 17155 mUserSwitchObservers.register(observer); 17156 } 17157 17158 @Override 17159 public void unregisterUserSwitchObserver(IUserSwitchObserver observer) { 17160 mUserSwitchObservers.unregister(observer); 17161 } 17162 17163 private boolean userExists(int userId) { 17164 if (userId == 0) { 17165 return true; 17166 } 17167 UserManagerService ums = getUserManagerLocked(); 17168 return ums != null ? (ums.getUserInfo(userId) != null) : false; 17169 } 17170 17171 int[] getUsersLocked() { 17172 UserManagerService ums = getUserManagerLocked(); 17173 return ums != null ? ums.getUserIds() : new int[] { 0 }; 17174 } 17175 17176 UserManagerService getUserManagerLocked() { 17177 if (mUserManager == null) { 17178 IBinder b = ServiceManager.getService(Context.USER_SERVICE); 17179 mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b); 17180 } 17181 return mUserManager; 17182 } 17183 17184 private int applyUserId(int uid, int userId) { 17185 return UserHandle.getUid(userId, uid); 17186 } 17187 17188 ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) { 17189 if (info == null) return null; 17190 ApplicationInfo newInfo = new ApplicationInfo(info); 17191 newInfo.uid = applyUserId(info.uid, userId); 17192 newInfo.dataDir = USER_DATA_DIR + userId + "/" 17193 + info.packageName; 17194 return newInfo; 17195 } 17196 17197 ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) { 17198 if (aInfo == null 17199 || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) { 17200 return aInfo; 17201 } 17202 17203 ActivityInfo info = new ActivityInfo(aInfo); 17204 info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId); 17205 return info; 17206 } 17207 17208 private final class LocalService extends ActivityManagerInternal { 17209 @Override 17210 public void goingToSleep() { 17211 ActivityManagerService.this.goingToSleep(); 17212 } 17213 17214 @Override 17215 public void wakingUp() { 17216 ActivityManagerService.this.wakingUp(); 17217 } 17218 } 17219 17220 /** 17221 * An implementation of IAppTask, that allows an app to manage its own tasks via 17222 * {@link android.app.ActivityManager.AppTask}. We keep track of the callingUid to ensure that 17223 * only the process that calls getAppTasks() can call the AppTask methods. 17224 */ 17225 class AppTaskImpl extends IAppTask.Stub { 17226 private int mTaskId; 17227 private int mCallingUid; 17228 17229 public AppTaskImpl(int taskId, int callingUid) { 17230 mTaskId = taskId; 17231 mCallingUid = callingUid; 17232 } 17233 17234 @Override 17235 public void finishAndRemoveTask() { 17236 // Ensure that we are called from the same process that created this AppTask 17237 if (mCallingUid != Binder.getCallingUid()) { 17238 Slog.w(TAG, "finishAndRemoveTask: caller " + mCallingUid 17239 + " does not match caller of getAppTasks(): " + Binder.getCallingUid()); 17240 return; 17241 } 17242 17243 synchronized (ActivityManagerService.this) { 17244 long origId = Binder.clearCallingIdentity(); 17245 try { 17246 TaskRecord tr = recentTaskForIdLocked(mTaskId); 17247 if (tr != null) { 17248 // Only kill the process if we are not a new document 17249 int flags = tr.getBaseIntent().getFlags(); 17250 boolean isDocument = (flags & Intent.FLAG_ACTIVITY_NEW_DOCUMENT) == 17251 Intent.FLAG_ACTIVITY_NEW_DOCUMENT; 17252 removeTaskByIdLocked(mTaskId, 17253 !isDocument ? ActivityManager.REMOVE_TASK_KILL_PROCESS : 0); 17254 } 17255 } finally { 17256 Binder.restoreCallingIdentity(origId); 17257 } 17258 } 17259 } 17260 17261 @Override 17262 public ActivityManager.RecentTaskInfo getTaskInfo() { 17263 // Ensure that we are called from the same process that created this AppTask 17264 if (mCallingUid != Binder.getCallingUid()) { 17265 Slog.w(TAG, "finishAndRemoveTask: caller " + mCallingUid 17266 + " does not match caller of getAppTasks(): " + Binder.getCallingUid()); 17267 return null; 17268 } 17269 17270 synchronized (ActivityManagerService.this) { 17271 long origId = Binder.clearCallingIdentity(); 17272 try { 17273 TaskRecord tr = recentTaskForIdLocked(mTaskId); 17274 if (tr != null) { 17275 return createRecentTaskInfoFromTaskRecord(tr); 17276 } 17277 } finally { 17278 Binder.restoreCallingIdentity(origId); 17279 } 17280 return null; 17281 } 17282 } 17283 } 17284} 17285