ActivityManagerService.java revision 87f851d0bad0183eccbb59b1fb378db9155e4a66
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 : 20; 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 for (int i=0; i<N; i++) { 3536 TaskRecord tr = mRecentTasks.get(i); 3537 if (task != tr) { 3538 if (task.userId != tr.userId) { 3539 continue; 3540 } 3541 final Intent trIntent = tr.intent; 3542 if ((task.affinity == null || !task.affinity.equals(tr.affinity)) && 3543 (intent == null || !intent.filterEquals(trIntent))) { 3544 continue; 3545 } 3546 if (document || trIntent != null && trIntent.isDocument()) { 3547 // Document tasks do not match other tasks. 3548 continue; 3549 } 3550 } 3551 3552 // Either task and tr are the same or, their affinities match or their intents match 3553 // and neither of them is a document. 3554 tr.disposeThumbnail(); 3555 mRecentTasks.remove(i); 3556 i--; 3557 N--; 3558 if (task.intent == null) { 3559 // If the new recent task we are adding is not fully 3560 // specified, then replace it with the existing recent task. 3561 task = tr; 3562 } 3563 } 3564 if (N >= MAX_RECENT_TASKS) { 3565 mRecentTasks.remove(N-1).disposeThumbnail(); 3566 } 3567 mRecentTasks.add(0, task); 3568 } 3569 3570 @Override 3571 public void reportActivityFullyDrawn(IBinder token) { 3572 synchronized (this) { 3573 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3574 if (r == null) { 3575 return; 3576 } 3577 r.reportFullyDrawnLocked(); 3578 } 3579 } 3580 3581 @Override 3582 public void setRequestedOrientation(IBinder token, int requestedOrientation) { 3583 synchronized (this) { 3584 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3585 if (r == null) { 3586 return; 3587 } 3588 final long origId = Binder.clearCallingIdentity(); 3589 mWindowManager.setAppOrientation(r.appToken, requestedOrientation); 3590 Configuration config = mWindowManager.updateOrientationFromAppTokens( 3591 mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null); 3592 if (config != null) { 3593 r.frozenBeforeDestroy = true; 3594 if (!updateConfigurationLocked(config, r, false, false)) { 3595 mStackSupervisor.resumeTopActivitiesLocked(); 3596 } 3597 } 3598 Binder.restoreCallingIdentity(origId); 3599 } 3600 } 3601 3602 @Override 3603 public int getRequestedOrientation(IBinder token) { 3604 synchronized (this) { 3605 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3606 if (r == null) { 3607 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; 3608 } 3609 return mWindowManager.getAppOrientation(r.appToken); 3610 } 3611 } 3612 3613 /** 3614 * This is the internal entry point for handling Activity.finish(). 3615 * 3616 * @param token The Binder token referencing the Activity we want to finish. 3617 * @param resultCode Result code, if any, from this Activity. 3618 * @param resultData Result data (Intent), if any, from this Activity. 3619 * @param finishTask Whether to finish the task associated with this Activity. Only applies to 3620 * the root Activity in the task. 3621 * 3622 * @return Returns true if the activity successfully finished, or false if it is still running. 3623 */ 3624 @Override 3625 public final boolean finishActivity(IBinder token, int resultCode, Intent resultData, 3626 boolean finishTask) { 3627 // Refuse possible leaked file descriptors 3628 if (resultData != null && resultData.hasFileDescriptors() == true) { 3629 throw new IllegalArgumentException("File descriptors passed in Intent"); 3630 } 3631 3632 synchronized(this) { 3633 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3634 if (r == null) { 3635 return true; 3636 } 3637 // Keep track of the root activity of the task before we finish it 3638 TaskRecord tr = r.task; 3639 ActivityRecord rootR = tr.getRootActivity(); 3640 if (mController != null) { 3641 // Find the first activity that is not finishing. 3642 ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0); 3643 if (next != null) { 3644 // ask watcher if this is allowed 3645 boolean resumeOK = true; 3646 try { 3647 resumeOK = mController.activityResuming(next.packageName); 3648 } catch (RemoteException e) { 3649 mController = null; 3650 Watchdog.getInstance().setActivityController(null); 3651 } 3652 3653 if (!resumeOK) { 3654 return false; 3655 } 3656 } 3657 } 3658 final long origId = Binder.clearCallingIdentity(); 3659 try { 3660 boolean res; 3661 if (finishTask && r == rootR) { 3662 // If requested, remove the task that is associated to this activity only if it 3663 // was the root activity in the task. The result code and data is ignored because 3664 // we don't support returning them across task boundaries. 3665 res = removeTaskByIdLocked(tr.taskId, 0); 3666 } else { 3667 res = tr.stack.requestFinishActivityLocked(token, resultCode, 3668 resultData, "app-request", true); 3669 } 3670 return res; 3671 } finally { 3672 Binder.restoreCallingIdentity(origId); 3673 } 3674 } 3675 } 3676 3677 @Override 3678 public final void finishHeavyWeightApp() { 3679 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 3680 != PackageManager.PERMISSION_GRANTED) { 3681 String msg = "Permission Denial: finishHeavyWeightApp() from pid=" 3682 + Binder.getCallingPid() 3683 + ", uid=" + Binder.getCallingUid() 3684 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 3685 Slog.w(TAG, msg); 3686 throw new SecurityException(msg); 3687 } 3688 3689 synchronized(this) { 3690 if (mHeavyWeightProcess == null) { 3691 return; 3692 } 3693 3694 ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>( 3695 mHeavyWeightProcess.activities); 3696 for (int i=0; i<activities.size(); i++) { 3697 ActivityRecord r = activities.get(i); 3698 if (!r.finishing) { 3699 r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED, 3700 null, "finish-heavy", true); 3701 } 3702 } 3703 3704 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 3705 mHeavyWeightProcess.userId, 0)); 3706 mHeavyWeightProcess = null; 3707 } 3708 } 3709 3710 @Override 3711 public void crashApplication(int uid, int initialPid, String packageName, 3712 String message) { 3713 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 3714 != PackageManager.PERMISSION_GRANTED) { 3715 String msg = "Permission Denial: crashApplication() from pid=" 3716 + Binder.getCallingPid() 3717 + ", uid=" + Binder.getCallingUid() 3718 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 3719 Slog.w(TAG, msg); 3720 throw new SecurityException(msg); 3721 } 3722 3723 synchronized(this) { 3724 ProcessRecord proc = null; 3725 3726 // Figure out which process to kill. We don't trust that initialPid 3727 // still has any relation to current pids, so must scan through the 3728 // list. 3729 synchronized (mPidsSelfLocked) { 3730 for (int i=0; i<mPidsSelfLocked.size(); i++) { 3731 ProcessRecord p = mPidsSelfLocked.valueAt(i); 3732 if (p.uid != uid) { 3733 continue; 3734 } 3735 if (p.pid == initialPid) { 3736 proc = p; 3737 break; 3738 } 3739 if (p.pkgList.containsKey(packageName)) { 3740 proc = p; 3741 } 3742 } 3743 } 3744 3745 if (proc == null) { 3746 Slog.w(TAG, "crashApplication: nothing for uid=" + uid 3747 + " initialPid=" + initialPid 3748 + " packageName=" + packageName); 3749 return; 3750 } 3751 3752 if (proc.thread != null) { 3753 if (proc.pid == Process.myPid()) { 3754 Log.w(TAG, "crashApplication: trying to crash self!"); 3755 return; 3756 } 3757 long ident = Binder.clearCallingIdentity(); 3758 try { 3759 proc.thread.scheduleCrash(message); 3760 } catch (RemoteException e) { 3761 } 3762 Binder.restoreCallingIdentity(ident); 3763 } 3764 } 3765 } 3766 3767 @Override 3768 public final void finishSubActivity(IBinder token, String resultWho, 3769 int requestCode) { 3770 synchronized(this) { 3771 final long origId = Binder.clearCallingIdentity(); 3772 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3773 if (r != null) { 3774 r.task.stack.finishSubActivityLocked(r, resultWho, requestCode); 3775 } 3776 Binder.restoreCallingIdentity(origId); 3777 } 3778 } 3779 3780 @Override 3781 public boolean finishActivityAffinity(IBinder token) { 3782 synchronized(this) { 3783 final long origId = Binder.clearCallingIdentity(); 3784 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3785 boolean res = false; 3786 if (r != null) { 3787 res = r.task.stack.finishActivityAffinityLocked(r); 3788 } 3789 Binder.restoreCallingIdentity(origId); 3790 return res; 3791 } 3792 } 3793 3794 @Override 3795 public boolean willActivityBeVisible(IBinder token) { 3796 synchronized(this) { 3797 ActivityStack stack = ActivityRecord.getStackLocked(token); 3798 if (stack != null) { 3799 return stack.willActivityBeVisibleLocked(token); 3800 } 3801 return false; 3802 } 3803 } 3804 3805 @Override 3806 public void overridePendingTransition(IBinder token, String packageName, 3807 int enterAnim, int exitAnim) { 3808 synchronized(this) { 3809 ActivityRecord self = ActivityRecord.isInStackLocked(token); 3810 if (self == null) { 3811 return; 3812 } 3813 3814 final long origId = Binder.clearCallingIdentity(); 3815 3816 if (self.state == ActivityState.RESUMED 3817 || self.state == ActivityState.PAUSING) { 3818 mWindowManager.overridePendingAppTransition(packageName, 3819 enterAnim, exitAnim, null); 3820 } 3821 3822 Binder.restoreCallingIdentity(origId); 3823 } 3824 } 3825 3826 /** 3827 * Main function for removing an existing process from the activity manager 3828 * as a result of that process going away. Clears out all connections 3829 * to the process. 3830 */ 3831 private final void handleAppDiedLocked(ProcessRecord app, 3832 boolean restarting, boolean allowRestart) { 3833 int pid = app.pid; 3834 cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1); 3835 if (!restarting) { 3836 removeLruProcessLocked(app); 3837 if (pid > 0) { 3838 ProcessList.remove(pid); 3839 } 3840 } 3841 3842 if (mProfileProc == app) { 3843 clearProfilerLocked(); 3844 } 3845 3846 // Remove this application's activities from active lists. 3847 boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app); 3848 3849 app.activities.clear(); 3850 3851 if (app.instrumentationClass != null) { 3852 Slog.w(TAG, "Crash of app " + app.processName 3853 + " running instrumentation " + app.instrumentationClass); 3854 Bundle info = new Bundle(); 3855 info.putString("shortMsg", "Process crashed."); 3856 finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info); 3857 } 3858 3859 if (!restarting) { 3860 if (!mStackSupervisor.resumeTopActivitiesLocked()) { 3861 // If there was nothing to resume, and we are not already 3862 // restarting this process, but there is a visible activity that 3863 // is hosted by the process... then make sure all visible 3864 // activities are running, taking care of restarting this 3865 // process. 3866 if (hasVisibleActivities) { 3867 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 3868 } 3869 } 3870 } 3871 } 3872 3873 private final int getLRURecordIndexForAppLocked(IApplicationThread thread) { 3874 IBinder threadBinder = thread.asBinder(); 3875 // Find the application record. 3876 for (int i=mLruProcesses.size()-1; i>=0; i--) { 3877 ProcessRecord rec = mLruProcesses.get(i); 3878 if (rec.thread != null && rec.thread.asBinder() == threadBinder) { 3879 return i; 3880 } 3881 } 3882 return -1; 3883 } 3884 3885 final ProcessRecord getRecordForAppLocked( 3886 IApplicationThread thread) { 3887 if (thread == null) { 3888 return null; 3889 } 3890 3891 int appIndex = getLRURecordIndexForAppLocked(thread); 3892 return appIndex >= 0 ? mLruProcesses.get(appIndex) : null; 3893 } 3894 3895 final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) { 3896 // If there are no longer any background processes running, 3897 // and the app that died was not running instrumentation, 3898 // then tell everyone we are now low on memory. 3899 boolean haveBg = false; 3900 for (int i=mLruProcesses.size()-1; i>=0; i--) { 3901 ProcessRecord rec = mLruProcesses.get(i); 3902 if (rec.thread != null 3903 && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 3904 haveBg = true; 3905 break; 3906 } 3907 } 3908 3909 if (!haveBg) { 3910 boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 3911 if (doReport) { 3912 long now = SystemClock.uptimeMillis(); 3913 if (now < (mLastMemUsageReportTime+5*60*1000)) { 3914 doReport = false; 3915 } else { 3916 mLastMemUsageReportTime = now; 3917 } 3918 } 3919 final ArrayList<ProcessMemInfo> memInfos 3920 = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null; 3921 EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size()); 3922 long now = SystemClock.uptimeMillis(); 3923 for (int i=mLruProcesses.size()-1; i>=0; i--) { 3924 ProcessRecord rec = mLruProcesses.get(i); 3925 if (rec == dyingProc || rec.thread == null) { 3926 continue; 3927 } 3928 if (doReport) { 3929 memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj, 3930 rec.setProcState, rec.adjType, rec.makeAdjReason())); 3931 } 3932 if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) { 3933 // The low memory report is overriding any current 3934 // state for a GC request. Make sure to do 3935 // heavy/important/visible/foreground processes first. 3936 if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 3937 rec.lastRequestedGc = 0; 3938 } else { 3939 rec.lastRequestedGc = rec.lastLowMemory; 3940 } 3941 rec.reportLowMemory = true; 3942 rec.lastLowMemory = now; 3943 mProcessesToGc.remove(rec); 3944 addProcessToGcListLocked(rec); 3945 } 3946 } 3947 if (doReport) { 3948 Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos); 3949 mHandler.sendMessage(msg); 3950 } 3951 scheduleAppGcsLocked(); 3952 } 3953 } 3954 3955 final void appDiedLocked(ProcessRecord app, int pid, 3956 IApplicationThread thread) { 3957 3958 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 3959 synchronized (stats) { 3960 stats.noteProcessDiedLocked(app.info.uid, pid); 3961 } 3962 3963 // Clean up already done if the process has been re-started. 3964 if (app.pid == pid && app.thread != null && 3965 app.thread.asBinder() == thread.asBinder()) { 3966 boolean doLowMem = app.instrumentationClass == null; 3967 boolean doOomAdj = doLowMem; 3968 if (!app.killedByAm) { 3969 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 3970 + ") has died."); 3971 mAllowLowerMemLevel = true; 3972 } else { 3973 // Note that we always want to do oom adj to update our state with the 3974 // new number of procs. 3975 mAllowLowerMemLevel = false; 3976 doLowMem = false; 3977 } 3978 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName); 3979 if (DEBUG_CLEANUP) Slog.v( 3980 TAG, "Dying app: " + app + ", pid: " + pid 3981 + ", thread: " + thread.asBinder()); 3982 handleAppDiedLocked(app, false, true); 3983 3984 if (doOomAdj) { 3985 updateOomAdjLocked(); 3986 } 3987 if (doLowMem) { 3988 doLowMemReportIfNeededLocked(app); 3989 } 3990 } else if (app.pid != pid) { 3991 // A new process has already been started. 3992 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 3993 + ") has died and restarted (pid " + app.pid + ")."); 3994 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName); 3995 } else if (DEBUG_PROCESSES) { 3996 Slog.d(TAG, "Received spurious death notification for thread " 3997 + thread.asBinder()); 3998 } 3999 } 4000 4001 /** 4002 * If a stack trace dump file is configured, dump process stack traces. 4003 * @param clearTraces causes the dump file to be erased prior to the new 4004 * traces being written, if true; when false, the new traces will be 4005 * appended to any existing file content. 4006 * @param firstPids of dalvik VM processes to dump stack traces for first 4007 * @param lastPids of dalvik VM processes to dump stack traces for last 4008 * @param nativeProcs optional list of native process names to dump stack crawls 4009 * @return file containing stack traces, or null if no dump file is configured 4010 */ 4011 public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids, 4012 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) { 4013 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 4014 if (tracesPath == null || tracesPath.length() == 0) { 4015 return null; 4016 } 4017 4018 File tracesFile = new File(tracesPath); 4019 try { 4020 File tracesDir = tracesFile.getParentFile(); 4021 if (!tracesDir.exists()) { 4022 tracesFile.mkdirs(); 4023 if (!SELinux.restorecon(tracesDir)) { 4024 return null; 4025 } 4026 } 4027 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 4028 4029 if (clearTraces && tracesFile.exists()) tracesFile.delete(); 4030 tracesFile.createNewFile(); 4031 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 4032 } catch (IOException e) { 4033 Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e); 4034 return null; 4035 } 4036 4037 dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs); 4038 return tracesFile; 4039 } 4040 4041 private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids, 4042 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) { 4043 // Use a FileObserver to detect when traces finish writing. 4044 // The order of traces is considered important to maintain for legibility. 4045 FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) { 4046 @Override 4047 public synchronized void onEvent(int event, String path) { notify(); } 4048 }; 4049 4050 try { 4051 observer.startWatching(); 4052 4053 // First collect all of the stacks of the most important pids. 4054 if (firstPids != null) { 4055 try { 4056 int num = firstPids.size(); 4057 for (int i = 0; i < num; i++) { 4058 synchronized (observer) { 4059 Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT); 4060 observer.wait(200); // Wait for write-close, give up after 200msec 4061 } 4062 } 4063 } catch (InterruptedException e) { 4064 Log.wtf(TAG, e); 4065 } 4066 } 4067 4068 // Next collect the stacks of the native pids 4069 if (nativeProcs != null) { 4070 int[] pids = Process.getPidsForCommands(nativeProcs); 4071 if (pids != null) { 4072 for (int pid : pids) { 4073 Debug.dumpNativeBacktraceToFile(pid, tracesPath); 4074 } 4075 } 4076 } 4077 4078 // Lastly, measure CPU usage. 4079 if (processCpuTracker != null) { 4080 processCpuTracker.init(); 4081 System.gc(); 4082 processCpuTracker.update(); 4083 try { 4084 synchronized (processCpuTracker) { 4085 processCpuTracker.wait(500); // measure over 1/2 second. 4086 } 4087 } catch (InterruptedException e) { 4088 } 4089 processCpuTracker.update(); 4090 4091 // We'll take the stack crawls of just the top apps using CPU. 4092 final int N = processCpuTracker.countWorkingStats(); 4093 int numProcs = 0; 4094 for (int i=0; i<N && numProcs<5; i++) { 4095 ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i); 4096 if (lastPids.indexOfKey(stats.pid) >= 0) { 4097 numProcs++; 4098 try { 4099 synchronized (observer) { 4100 Process.sendSignal(stats.pid, Process.SIGNAL_QUIT); 4101 observer.wait(200); // Wait for write-close, give up after 200msec 4102 } 4103 } catch (InterruptedException e) { 4104 Log.wtf(TAG, e); 4105 } 4106 4107 } 4108 } 4109 } 4110 } finally { 4111 observer.stopWatching(); 4112 } 4113 } 4114 4115 final void logAppTooSlow(ProcessRecord app, long startTime, String msg) { 4116 if (true || IS_USER_BUILD) { 4117 return; 4118 } 4119 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 4120 if (tracesPath == null || tracesPath.length() == 0) { 4121 return; 4122 } 4123 4124 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads(); 4125 StrictMode.allowThreadDiskWrites(); 4126 try { 4127 final File tracesFile = new File(tracesPath); 4128 final File tracesDir = tracesFile.getParentFile(); 4129 final File tracesTmp = new File(tracesDir, "__tmp__"); 4130 try { 4131 if (!tracesDir.exists()) { 4132 tracesFile.mkdirs(); 4133 if (!SELinux.restorecon(tracesDir.getPath())) { 4134 return; 4135 } 4136 } 4137 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 4138 4139 if (tracesFile.exists()) { 4140 tracesTmp.delete(); 4141 tracesFile.renameTo(tracesTmp); 4142 } 4143 StringBuilder sb = new StringBuilder(); 4144 Time tobj = new Time(); 4145 tobj.set(System.currentTimeMillis()); 4146 sb.append(tobj.format("%Y-%m-%d %H:%M:%S")); 4147 sb.append(": "); 4148 TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb); 4149 sb.append(" since "); 4150 sb.append(msg); 4151 FileOutputStream fos = new FileOutputStream(tracesFile); 4152 fos.write(sb.toString().getBytes()); 4153 if (app == null) { 4154 fos.write("\n*** No application process!".getBytes()); 4155 } 4156 fos.close(); 4157 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 4158 } catch (IOException e) { 4159 Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e); 4160 return; 4161 } 4162 4163 if (app != null) { 4164 ArrayList<Integer> firstPids = new ArrayList<Integer>(); 4165 firstPids.add(app.pid); 4166 dumpStackTraces(tracesPath, firstPids, null, null, null); 4167 } 4168 4169 File lastTracesFile = null; 4170 File curTracesFile = null; 4171 for (int i=9; i>=0; i--) { 4172 String name = String.format(Locale.US, "slow%02d.txt", i); 4173 curTracesFile = new File(tracesDir, name); 4174 if (curTracesFile.exists()) { 4175 if (lastTracesFile != null) { 4176 curTracesFile.renameTo(lastTracesFile); 4177 } else { 4178 curTracesFile.delete(); 4179 } 4180 } 4181 lastTracesFile = curTracesFile; 4182 } 4183 tracesFile.renameTo(curTracesFile); 4184 if (tracesTmp.exists()) { 4185 tracesTmp.renameTo(tracesFile); 4186 } 4187 } finally { 4188 StrictMode.setThreadPolicy(oldPolicy); 4189 } 4190 } 4191 4192 final void appNotResponding(ProcessRecord app, ActivityRecord activity, 4193 ActivityRecord parent, boolean aboveSystem, final String annotation) { 4194 ArrayList<Integer> firstPids = new ArrayList<Integer>(5); 4195 SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20); 4196 4197 if (mController != null) { 4198 try { 4199 // 0 == continue, -1 = kill process immediately 4200 int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation); 4201 if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid); 4202 } catch (RemoteException e) { 4203 mController = null; 4204 Watchdog.getInstance().setActivityController(null); 4205 } 4206 } 4207 4208 long anrTime = SystemClock.uptimeMillis(); 4209 if (MONITOR_CPU_USAGE) { 4210 updateCpuStatsNow(); 4211 } 4212 4213 synchronized (this) { 4214 // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down. 4215 if (mShuttingDown) { 4216 Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation); 4217 return; 4218 } else if (app.notResponding) { 4219 Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation); 4220 return; 4221 } else if (app.crashing) { 4222 Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation); 4223 return; 4224 } 4225 4226 // In case we come through here for the same app before completing 4227 // this one, mark as anring now so we will bail out. 4228 app.notResponding = true; 4229 4230 // Log the ANR to the event log. 4231 EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid, 4232 app.processName, app.info.flags, annotation); 4233 4234 // Dump thread traces as quickly as we can, starting with "interesting" processes. 4235 firstPids.add(app.pid); 4236 4237 int parentPid = app.pid; 4238 if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid; 4239 if (parentPid != app.pid) firstPids.add(parentPid); 4240 4241 if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID); 4242 4243 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 4244 ProcessRecord r = mLruProcesses.get(i); 4245 if (r != null && r.thread != null) { 4246 int pid = r.pid; 4247 if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) { 4248 if (r.persistent) { 4249 firstPids.add(pid); 4250 } else { 4251 lastPids.put(pid, Boolean.TRUE); 4252 } 4253 } 4254 } 4255 } 4256 } 4257 4258 // Log the ANR to the main log. 4259 StringBuilder info = new StringBuilder(); 4260 info.setLength(0); 4261 info.append("ANR in ").append(app.processName); 4262 if (activity != null && activity.shortComponentName != null) { 4263 info.append(" (").append(activity.shortComponentName).append(")"); 4264 } 4265 info.append("\n"); 4266 info.append("PID: ").append(app.pid).append("\n"); 4267 if (annotation != null) { 4268 info.append("Reason: ").append(annotation).append("\n"); 4269 } 4270 if (parent != null && parent != activity) { 4271 info.append("Parent: ").append(parent.shortComponentName).append("\n"); 4272 } 4273 4274 final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true); 4275 4276 File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids, 4277 NATIVE_STACKS_OF_INTEREST); 4278 4279 String cpuInfo = null; 4280 if (MONITOR_CPU_USAGE) { 4281 updateCpuStatsNow(); 4282 synchronized (mProcessCpuThread) { 4283 cpuInfo = mProcessCpuTracker.printCurrentState(anrTime); 4284 } 4285 info.append(processCpuTracker.printCurrentLoad()); 4286 info.append(cpuInfo); 4287 } 4288 4289 info.append(processCpuTracker.printCurrentState(anrTime)); 4290 4291 Slog.e(TAG, info.toString()); 4292 if (tracesFile == null) { 4293 // There is no trace file, so dump (only) the alleged culprit's threads to the log 4294 Process.sendSignal(app.pid, Process.SIGNAL_QUIT); 4295 } 4296 4297 addErrorToDropBox("anr", app, app.processName, activity, parent, annotation, 4298 cpuInfo, tracesFile, null); 4299 4300 if (mController != null) { 4301 try { 4302 // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately 4303 int res = mController.appNotResponding(app.processName, app.pid, info.toString()); 4304 if (res != 0) { 4305 if (res < 0 && app.pid != MY_PID) { 4306 Process.killProcess(app.pid); 4307 } else { 4308 synchronized (this) { 4309 mServices.scheduleServiceTimeoutLocked(app); 4310 } 4311 } 4312 return; 4313 } 4314 } catch (RemoteException e) { 4315 mController = null; 4316 Watchdog.getInstance().setActivityController(null); 4317 } 4318 } 4319 4320 // Unless configured otherwise, swallow ANRs in background processes & kill the process. 4321 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), 4322 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; 4323 4324 synchronized (this) { 4325 if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) { 4326 killUnneededProcessLocked(app, "background ANR"); 4327 return; 4328 } 4329 4330 // Set the app's notResponding state, and look up the errorReportReceiver 4331 makeAppNotRespondingLocked(app, 4332 activity != null ? activity.shortComponentName : null, 4333 annotation != null ? "ANR " + annotation : "ANR", 4334 info.toString()); 4335 4336 // Bring up the infamous App Not Responding dialog 4337 Message msg = Message.obtain(); 4338 HashMap<String, Object> map = new HashMap<String, Object>(); 4339 msg.what = SHOW_NOT_RESPONDING_MSG; 4340 msg.obj = map; 4341 msg.arg1 = aboveSystem ? 1 : 0; 4342 map.put("app", app); 4343 if (activity != null) { 4344 map.put("activity", activity); 4345 } 4346 4347 mHandler.sendMessage(msg); 4348 } 4349 } 4350 4351 final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) { 4352 if (!mLaunchWarningShown) { 4353 mLaunchWarningShown = true; 4354 mHandler.post(new Runnable() { 4355 @Override 4356 public void run() { 4357 synchronized (ActivityManagerService.this) { 4358 final Dialog d = new LaunchWarningWindow(mContext, cur, next); 4359 d.show(); 4360 mHandler.postDelayed(new Runnable() { 4361 @Override 4362 public void run() { 4363 synchronized (ActivityManagerService.this) { 4364 d.dismiss(); 4365 mLaunchWarningShown = false; 4366 } 4367 } 4368 }, 4000); 4369 } 4370 } 4371 }); 4372 } 4373 } 4374 4375 @Override 4376 public boolean clearApplicationUserData(final String packageName, 4377 final IPackageDataObserver observer, int userId) { 4378 enforceNotIsolatedCaller("clearApplicationUserData"); 4379 int uid = Binder.getCallingUid(); 4380 int pid = Binder.getCallingPid(); 4381 userId = handleIncomingUser(pid, uid, 4382 userId, false, true, "clearApplicationUserData", null); 4383 long callingId = Binder.clearCallingIdentity(); 4384 try { 4385 IPackageManager pm = AppGlobals.getPackageManager(); 4386 int pkgUid = -1; 4387 synchronized(this) { 4388 try { 4389 pkgUid = pm.getPackageUid(packageName, userId); 4390 } catch (RemoteException e) { 4391 } 4392 if (pkgUid == -1) { 4393 Slog.w(TAG, "Invalid packageName: " + packageName); 4394 if (observer != null) { 4395 try { 4396 observer.onRemoveCompleted(packageName, false); 4397 } catch (RemoteException e) { 4398 Slog.i(TAG, "Observer no longer exists."); 4399 } 4400 } 4401 return false; 4402 } 4403 if (uid == pkgUid || checkComponentPermission( 4404 android.Manifest.permission.CLEAR_APP_USER_DATA, 4405 pid, uid, -1, true) 4406 == PackageManager.PERMISSION_GRANTED) { 4407 forceStopPackageLocked(packageName, pkgUid, "clear data"); 4408 } else { 4409 throw new SecurityException("PID " + pid + " does not have permission " 4410 + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data" 4411 + " of package " + packageName); 4412 } 4413 } 4414 4415 try { 4416 // Clear application user data 4417 pm.clearApplicationUserData(packageName, observer, userId); 4418 4419 // Remove all permissions granted from/to this package 4420 removeUriPermissionsForPackageLocked(packageName, userId, true); 4421 4422 Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED, 4423 Uri.fromParts("package", packageName, null)); 4424 intent.putExtra(Intent.EXTRA_UID, pkgUid); 4425 broadcastIntentInPackage("android", Process.SYSTEM_UID, intent, 4426 null, null, 0, null, null, null, false, false, userId); 4427 } catch (RemoteException e) { 4428 } 4429 } finally { 4430 Binder.restoreCallingIdentity(callingId); 4431 } 4432 return true; 4433 } 4434 4435 @Override 4436 public void killBackgroundProcesses(final String packageName, int userId) { 4437 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 4438 != PackageManager.PERMISSION_GRANTED && 4439 checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES) 4440 != PackageManager.PERMISSION_GRANTED) { 4441 String msg = "Permission Denial: killBackgroundProcesses() from pid=" 4442 + Binder.getCallingPid() 4443 + ", uid=" + Binder.getCallingUid() 4444 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 4445 Slog.w(TAG, msg); 4446 throw new SecurityException(msg); 4447 } 4448 4449 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 4450 userId, true, true, "killBackgroundProcesses", null); 4451 long callingId = Binder.clearCallingIdentity(); 4452 try { 4453 IPackageManager pm = AppGlobals.getPackageManager(); 4454 synchronized(this) { 4455 int appId = -1; 4456 try { 4457 appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0)); 4458 } catch (RemoteException e) { 4459 } 4460 if (appId == -1) { 4461 Slog.w(TAG, "Invalid packageName: " + packageName); 4462 return; 4463 } 4464 killPackageProcessesLocked(packageName, appId, userId, 4465 ProcessList.SERVICE_ADJ, false, true, true, false, "kill background"); 4466 } 4467 } finally { 4468 Binder.restoreCallingIdentity(callingId); 4469 } 4470 } 4471 4472 @Override 4473 public void killAllBackgroundProcesses() { 4474 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 4475 != PackageManager.PERMISSION_GRANTED) { 4476 String msg = "Permission Denial: killAllBackgroundProcesses() from pid=" 4477 + Binder.getCallingPid() 4478 + ", uid=" + Binder.getCallingUid() 4479 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 4480 Slog.w(TAG, msg); 4481 throw new SecurityException(msg); 4482 } 4483 4484 long callingId = Binder.clearCallingIdentity(); 4485 try { 4486 synchronized(this) { 4487 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 4488 final int NP = mProcessNames.getMap().size(); 4489 for (int ip=0; ip<NP; ip++) { 4490 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 4491 final int NA = apps.size(); 4492 for (int ia=0; ia<NA; ia++) { 4493 ProcessRecord app = apps.valueAt(ia); 4494 if (app.persistent) { 4495 // we don't kill persistent processes 4496 continue; 4497 } 4498 if (app.removed) { 4499 procs.add(app); 4500 } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 4501 app.removed = true; 4502 procs.add(app); 4503 } 4504 } 4505 } 4506 4507 int N = procs.size(); 4508 for (int i=0; i<N; i++) { 4509 removeProcessLocked(procs.get(i), false, true, "kill all background"); 4510 } 4511 mAllowLowerMemLevel = true; 4512 updateOomAdjLocked(); 4513 doLowMemReportIfNeededLocked(null); 4514 } 4515 } finally { 4516 Binder.restoreCallingIdentity(callingId); 4517 } 4518 } 4519 4520 @Override 4521 public void forceStopPackage(final String packageName, int userId) { 4522 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 4523 != PackageManager.PERMISSION_GRANTED) { 4524 String msg = "Permission Denial: forceStopPackage() from pid=" 4525 + Binder.getCallingPid() 4526 + ", uid=" + Binder.getCallingUid() 4527 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 4528 Slog.w(TAG, msg); 4529 throw new SecurityException(msg); 4530 } 4531 final int callingPid = Binder.getCallingPid(); 4532 userId = handleIncomingUser(callingPid, Binder.getCallingUid(), 4533 userId, true, true, "forceStopPackage", null); 4534 long callingId = Binder.clearCallingIdentity(); 4535 try { 4536 IPackageManager pm = AppGlobals.getPackageManager(); 4537 synchronized(this) { 4538 int[] users = userId == UserHandle.USER_ALL 4539 ? getUsersLocked() : new int[] { userId }; 4540 for (int user : users) { 4541 int pkgUid = -1; 4542 try { 4543 pkgUid = pm.getPackageUid(packageName, user); 4544 } catch (RemoteException e) { 4545 } 4546 if (pkgUid == -1) { 4547 Slog.w(TAG, "Invalid packageName: " + packageName); 4548 continue; 4549 } 4550 try { 4551 pm.setPackageStoppedState(packageName, true, user); 4552 } catch (RemoteException e) { 4553 } catch (IllegalArgumentException e) { 4554 Slog.w(TAG, "Failed trying to unstop package " 4555 + packageName + ": " + e); 4556 } 4557 if (isUserRunningLocked(user, false)) { 4558 forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid); 4559 } 4560 } 4561 } 4562 } finally { 4563 Binder.restoreCallingIdentity(callingId); 4564 } 4565 } 4566 4567 /* 4568 * The pkg name and app id have to be specified. 4569 */ 4570 @Override 4571 public void killApplicationWithAppId(String pkg, int appid, String reason) { 4572 if (pkg == null) { 4573 return; 4574 } 4575 // Make sure the uid is valid. 4576 if (appid < 0) { 4577 Slog.w(TAG, "Invalid appid specified for pkg : " + pkg); 4578 return; 4579 } 4580 int callerUid = Binder.getCallingUid(); 4581 // Only the system server can kill an application 4582 if (callerUid == Process.SYSTEM_UID) { 4583 // Post an aysnc message to kill the application 4584 Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG); 4585 msg.arg1 = appid; 4586 msg.arg2 = 0; 4587 Bundle bundle = new Bundle(); 4588 bundle.putString("pkg", pkg); 4589 bundle.putString("reason", reason); 4590 msg.obj = bundle; 4591 mHandler.sendMessage(msg); 4592 } else { 4593 throw new SecurityException(callerUid + " cannot kill pkg: " + 4594 pkg); 4595 } 4596 } 4597 4598 @Override 4599 public void closeSystemDialogs(String reason) { 4600 enforceNotIsolatedCaller("closeSystemDialogs"); 4601 4602 final int pid = Binder.getCallingPid(); 4603 final int uid = Binder.getCallingUid(); 4604 final long origId = Binder.clearCallingIdentity(); 4605 try { 4606 synchronized (this) { 4607 // Only allow this from foreground processes, so that background 4608 // applications can't abuse it to prevent system UI from being shown. 4609 if (uid >= Process.FIRST_APPLICATION_UID) { 4610 ProcessRecord proc; 4611 synchronized (mPidsSelfLocked) { 4612 proc = mPidsSelfLocked.get(pid); 4613 } 4614 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 4615 Slog.w(TAG, "Ignoring closeSystemDialogs " + reason 4616 + " from background process " + proc); 4617 return; 4618 } 4619 } 4620 closeSystemDialogsLocked(reason); 4621 } 4622 } finally { 4623 Binder.restoreCallingIdentity(origId); 4624 } 4625 } 4626 4627 void closeSystemDialogsLocked(String reason) { 4628 Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS); 4629 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 4630 | Intent.FLAG_RECEIVER_FOREGROUND); 4631 if (reason != null) { 4632 intent.putExtra("reason", reason); 4633 } 4634 mWindowManager.closeSystemDialogs(reason); 4635 4636 mStackSupervisor.closeSystemDialogsLocked(); 4637 4638 broadcastIntentLocked(null, null, intent, null, 4639 null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1, 4640 Process.SYSTEM_UID, UserHandle.USER_ALL); 4641 } 4642 4643 @Override 4644 public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) { 4645 enforceNotIsolatedCaller("getProcessMemoryInfo"); 4646 Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length]; 4647 for (int i=pids.length-1; i>=0; i--) { 4648 ProcessRecord proc; 4649 int oomAdj; 4650 synchronized (this) { 4651 synchronized (mPidsSelfLocked) { 4652 proc = mPidsSelfLocked.get(pids[i]); 4653 oomAdj = proc != null ? proc.setAdj : 0; 4654 } 4655 } 4656 infos[i] = new Debug.MemoryInfo(); 4657 Debug.getMemoryInfo(pids[i], infos[i]); 4658 if (proc != null) { 4659 synchronized (this) { 4660 if (proc.thread != null && proc.setAdj == oomAdj) { 4661 // Record this for posterity if the process has been stable. 4662 proc.baseProcessTracker.addPss(infos[i].getTotalPss(), 4663 infos[i].getTotalUss(), false, proc.pkgList); 4664 } 4665 } 4666 } 4667 } 4668 return infos; 4669 } 4670 4671 @Override 4672 public long[] getProcessPss(int[] pids) { 4673 enforceNotIsolatedCaller("getProcessPss"); 4674 long[] pss = new long[pids.length]; 4675 for (int i=pids.length-1; i>=0; i--) { 4676 ProcessRecord proc; 4677 int oomAdj; 4678 synchronized (this) { 4679 synchronized (mPidsSelfLocked) { 4680 proc = mPidsSelfLocked.get(pids[i]); 4681 oomAdj = proc != null ? proc.setAdj : 0; 4682 } 4683 } 4684 long[] tmpUss = new long[1]; 4685 pss[i] = Debug.getPss(pids[i], tmpUss); 4686 if (proc != null) { 4687 synchronized (this) { 4688 if (proc.thread != null && proc.setAdj == oomAdj) { 4689 // Record this for posterity if the process has been stable. 4690 proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList); 4691 } 4692 } 4693 } 4694 } 4695 return pss; 4696 } 4697 4698 @Override 4699 public void killApplicationProcess(String processName, int uid) { 4700 if (processName == null) { 4701 return; 4702 } 4703 4704 int callerUid = Binder.getCallingUid(); 4705 // Only the system server can kill an application 4706 if (callerUid == Process.SYSTEM_UID) { 4707 synchronized (this) { 4708 ProcessRecord app = getProcessRecordLocked(processName, uid, true); 4709 if (app != null && app.thread != null) { 4710 try { 4711 app.thread.scheduleSuicide(); 4712 } catch (RemoteException e) { 4713 // If the other end already died, then our work here is done. 4714 } 4715 } else { 4716 Slog.w(TAG, "Process/uid not found attempting kill of " 4717 + processName + " / " + uid); 4718 } 4719 } 4720 } else { 4721 throw new SecurityException(callerUid + " cannot kill app process: " + 4722 processName); 4723 } 4724 } 4725 4726 private void forceStopPackageLocked(final String packageName, int uid, String reason) { 4727 forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false, 4728 false, true, false, false, UserHandle.getUserId(uid), reason); 4729 Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED, 4730 Uri.fromParts("package", packageName, null)); 4731 if (!mProcessesReady) { 4732 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 4733 | Intent.FLAG_RECEIVER_FOREGROUND); 4734 } 4735 intent.putExtra(Intent.EXTRA_UID, uid); 4736 intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid)); 4737 broadcastIntentLocked(null, null, intent, 4738 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 4739 false, false, 4740 MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid)); 4741 } 4742 4743 private void forceStopUserLocked(int userId, String reason) { 4744 forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason); 4745 Intent intent = new Intent(Intent.ACTION_USER_STOPPED); 4746 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 4747 | Intent.FLAG_RECEIVER_FOREGROUND); 4748 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 4749 broadcastIntentLocked(null, null, intent, 4750 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 4751 false, false, 4752 MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 4753 } 4754 4755 private final boolean killPackageProcessesLocked(String packageName, int appId, 4756 int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart, 4757 boolean doit, boolean evenPersistent, String reason) { 4758 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 4759 4760 // Remove all processes this package may have touched: all with the 4761 // same UID (except for the system or root user), and all whose name 4762 // matches the package name. 4763 final String procNamePrefix = packageName != null ? (packageName + ":") : null; 4764 final int NP = mProcessNames.getMap().size(); 4765 for (int ip=0; ip<NP; ip++) { 4766 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 4767 final int NA = apps.size(); 4768 for (int ia=0; ia<NA; ia++) { 4769 ProcessRecord app = apps.valueAt(ia); 4770 if (app.persistent && !evenPersistent) { 4771 // we don't kill persistent processes 4772 continue; 4773 } 4774 if (app.removed) { 4775 if (doit) { 4776 procs.add(app); 4777 } 4778 continue; 4779 } 4780 4781 // Skip process if it doesn't meet our oom adj requirement. 4782 if (app.setAdj < minOomAdj) { 4783 continue; 4784 } 4785 4786 // If no package is specified, we call all processes under the 4787 // give user id. 4788 if (packageName == null) { 4789 if (app.userId != userId) { 4790 continue; 4791 } 4792 if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) { 4793 continue; 4794 } 4795 // Package has been specified, we want to hit all processes 4796 // that match it. We need to qualify this by the processes 4797 // that are running under the specified app and user ID. 4798 } else { 4799 if (UserHandle.getAppId(app.uid) != appId) { 4800 continue; 4801 } 4802 if (userId != UserHandle.USER_ALL && app.userId != userId) { 4803 continue; 4804 } 4805 if (!app.pkgList.containsKey(packageName)) { 4806 continue; 4807 } 4808 } 4809 4810 // Process has passed all conditions, kill it! 4811 if (!doit) { 4812 return true; 4813 } 4814 app.removed = true; 4815 procs.add(app); 4816 } 4817 } 4818 4819 int N = procs.size(); 4820 for (int i=0; i<N; i++) { 4821 removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason); 4822 } 4823 updateOomAdjLocked(); 4824 return N > 0; 4825 } 4826 4827 private final boolean forceStopPackageLocked(String name, int appId, 4828 boolean callerWillRestart, boolean purgeCache, boolean doit, 4829 boolean evenPersistent, boolean uninstalling, int userId, String reason) { 4830 int i; 4831 int N; 4832 4833 if (userId == UserHandle.USER_ALL && name == null) { 4834 Slog.w(TAG, "Can't force stop all processes of all users, that is insane!"); 4835 } 4836 4837 if (appId < 0 && name != null) { 4838 try { 4839 appId = UserHandle.getAppId( 4840 AppGlobals.getPackageManager().getPackageUid(name, 0)); 4841 } catch (RemoteException e) { 4842 } 4843 } 4844 4845 if (doit) { 4846 if (name != null) { 4847 Slog.i(TAG, "Force stopping " + name + " appid=" + appId 4848 + " user=" + userId + ": " + reason); 4849 } else { 4850 Slog.i(TAG, "Force stopping u" + userId + ": " + reason); 4851 } 4852 4853 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap(); 4854 for (int ip=pmap.size()-1; ip>=0; ip--) { 4855 SparseArray<Long> ba = pmap.valueAt(ip); 4856 for (i=ba.size()-1; i>=0; i--) { 4857 boolean remove = false; 4858 final int entUid = ba.keyAt(i); 4859 if (name != null) { 4860 if (userId == UserHandle.USER_ALL) { 4861 if (UserHandle.getAppId(entUid) == appId) { 4862 remove = true; 4863 } 4864 } else { 4865 if (entUid == UserHandle.getUid(userId, appId)) { 4866 remove = true; 4867 } 4868 } 4869 } else if (UserHandle.getUserId(entUid) == userId) { 4870 remove = true; 4871 } 4872 if (remove) { 4873 ba.removeAt(i); 4874 } 4875 } 4876 if (ba.size() == 0) { 4877 pmap.removeAt(ip); 4878 } 4879 } 4880 } 4881 4882 boolean didSomething = killPackageProcessesLocked(name, appId, userId, 4883 -100, callerWillRestart, true, doit, evenPersistent, 4884 name == null ? ("stop user " + userId) : ("stop " + name)); 4885 4886 if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) { 4887 if (!doit) { 4888 return true; 4889 } 4890 didSomething = true; 4891 } 4892 4893 if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) { 4894 if (!doit) { 4895 return true; 4896 } 4897 didSomething = true; 4898 } 4899 4900 if (name == null) { 4901 // Remove all sticky broadcasts from this user. 4902 mStickyBroadcasts.remove(userId); 4903 } 4904 4905 ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>(); 4906 if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent, 4907 userId, providers)) { 4908 if (!doit) { 4909 return true; 4910 } 4911 didSomething = true; 4912 } 4913 N = providers.size(); 4914 for (i=0; i<N; i++) { 4915 removeDyingProviderLocked(null, providers.get(i), true); 4916 } 4917 4918 // Remove transient permissions granted from/to this package/user 4919 removeUriPermissionsForPackageLocked(name, userId, false); 4920 4921 if (name == null || uninstalling) { 4922 // Remove pending intents. For now we only do this when force 4923 // stopping users, because we have some problems when doing this 4924 // for packages -- app widgets are not currently cleaned up for 4925 // such packages, so they can be left with bad pending intents. 4926 if (mIntentSenderRecords.size() > 0) { 4927 Iterator<WeakReference<PendingIntentRecord>> it 4928 = mIntentSenderRecords.values().iterator(); 4929 while (it.hasNext()) { 4930 WeakReference<PendingIntentRecord> wpir = it.next(); 4931 if (wpir == null) { 4932 it.remove(); 4933 continue; 4934 } 4935 PendingIntentRecord pir = wpir.get(); 4936 if (pir == null) { 4937 it.remove(); 4938 continue; 4939 } 4940 if (name == null) { 4941 // Stopping user, remove all objects for the user. 4942 if (pir.key.userId != userId) { 4943 // Not the same user, skip it. 4944 continue; 4945 } 4946 } else { 4947 if (UserHandle.getAppId(pir.uid) != appId) { 4948 // Different app id, skip it. 4949 continue; 4950 } 4951 if (userId != UserHandle.USER_ALL && pir.key.userId != userId) { 4952 // Different user, skip it. 4953 continue; 4954 } 4955 if (!pir.key.packageName.equals(name)) { 4956 // Different package, skip it. 4957 continue; 4958 } 4959 } 4960 if (!doit) { 4961 return true; 4962 } 4963 didSomething = true; 4964 it.remove(); 4965 pir.canceled = true; 4966 if (pir.key.activity != null) { 4967 pir.key.activity.pendingResults.remove(pir.ref); 4968 } 4969 } 4970 } 4971 } 4972 4973 if (doit) { 4974 if (purgeCache && name != null) { 4975 AttributeCache ac = AttributeCache.instance(); 4976 if (ac != null) { 4977 ac.removePackage(name); 4978 } 4979 } 4980 if (mBooted) { 4981 mStackSupervisor.resumeTopActivitiesLocked(); 4982 mStackSupervisor.scheduleIdleLocked(); 4983 } 4984 } 4985 4986 return didSomething; 4987 } 4988 4989 private final boolean removeProcessLocked(ProcessRecord app, 4990 boolean callerWillRestart, boolean allowRestart, String reason) { 4991 final String name = app.processName; 4992 final int uid = app.uid; 4993 if (DEBUG_PROCESSES) Slog.d( 4994 TAG, "Force removing proc " + app.toShortString() + " (" + name 4995 + "/" + uid + ")"); 4996 4997 mProcessNames.remove(name, uid); 4998 mIsolatedProcesses.remove(app.uid); 4999 if (mHeavyWeightProcess == app) { 5000 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 5001 mHeavyWeightProcess.userId, 0)); 5002 mHeavyWeightProcess = null; 5003 } 5004 boolean needRestart = false; 5005 if (app.pid > 0 && app.pid != MY_PID) { 5006 int pid = app.pid; 5007 synchronized (mPidsSelfLocked) { 5008 mPidsSelfLocked.remove(pid); 5009 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 5010 } 5011 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH, 5012 app.processName, app.info.uid); 5013 if (app.isolated) { 5014 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 5015 } 5016 killUnneededProcessLocked(app, reason); 5017 handleAppDiedLocked(app, true, allowRestart); 5018 removeLruProcessLocked(app); 5019 5020 if (app.persistent && !app.isolated) { 5021 if (!callerWillRestart) { 5022 addAppLocked(app.info, false); 5023 } else { 5024 needRestart = true; 5025 } 5026 } 5027 } else { 5028 mRemovedProcesses.add(app); 5029 } 5030 5031 return needRestart; 5032 } 5033 5034 private final void processStartTimedOutLocked(ProcessRecord app) { 5035 final int pid = app.pid; 5036 boolean gone = false; 5037 synchronized (mPidsSelfLocked) { 5038 ProcessRecord knownApp = mPidsSelfLocked.get(pid); 5039 if (knownApp != null && knownApp.thread == null) { 5040 mPidsSelfLocked.remove(pid); 5041 gone = true; 5042 } 5043 } 5044 5045 if (gone) { 5046 Slog.w(TAG, "Process " + app + " failed to attach"); 5047 EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId, 5048 pid, app.uid, app.processName); 5049 mProcessNames.remove(app.processName, app.uid); 5050 mIsolatedProcesses.remove(app.uid); 5051 if (mHeavyWeightProcess == app) { 5052 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 5053 mHeavyWeightProcess.userId, 0)); 5054 mHeavyWeightProcess = null; 5055 } 5056 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH, 5057 app.processName, app.info.uid); 5058 if (app.isolated) { 5059 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 5060 } 5061 // Take care of any launching providers waiting for this process. 5062 checkAppInLaunchingProvidersLocked(app, true); 5063 // Take care of any services that are waiting for the process. 5064 mServices.processStartTimedOutLocked(app); 5065 killUnneededProcessLocked(app, "start timeout"); 5066 if (mBackupTarget != null && mBackupTarget.app.pid == pid) { 5067 Slog.w(TAG, "Unattached app died before backup, skipping"); 5068 try { 5069 IBackupManager bm = IBackupManager.Stub.asInterface( 5070 ServiceManager.getService(Context.BACKUP_SERVICE)); 5071 bm.agentDisconnected(app.info.packageName); 5072 } catch (RemoteException e) { 5073 // Can't happen; the backup manager is local 5074 } 5075 } 5076 if (isPendingBroadcastProcessLocked(pid)) { 5077 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 5078 skipPendingBroadcastLocked(pid); 5079 } 5080 } else { 5081 Slog.w(TAG, "Spurious process start timeout - pid not known for " + app); 5082 } 5083 } 5084 5085 private final boolean attachApplicationLocked(IApplicationThread thread, 5086 int pid) { 5087 5088 // Find the application record that is being attached... either via 5089 // the pid if we are running in multiple processes, or just pull the 5090 // next app record if we are emulating process with anonymous threads. 5091 ProcessRecord app; 5092 if (pid != MY_PID && pid >= 0) { 5093 synchronized (mPidsSelfLocked) { 5094 app = mPidsSelfLocked.get(pid); 5095 } 5096 } else { 5097 app = null; 5098 } 5099 5100 if (app == null) { 5101 Slog.w(TAG, "No pending application record for pid " + pid 5102 + " (IApplicationThread " + thread + "); dropping process"); 5103 EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid); 5104 if (pid > 0 && pid != MY_PID) { 5105 Process.killProcessQuiet(pid); 5106 } else { 5107 try { 5108 thread.scheduleExit(); 5109 } catch (Exception e) { 5110 // Ignore exceptions. 5111 } 5112 } 5113 return false; 5114 } 5115 5116 // If this application record is still attached to a previous 5117 // process, clean it up now. 5118 if (app.thread != null) { 5119 handleAppDiedLocked(app, true, true); 5120 } 5121 5122 // Tell the process all about itself. 5123 5124 if (localLOGV) Slog.v( 5125 TAG, "Binding process pid " + pid + " to record " + app); 5126 5127 final String processName = app.processName; 5128 try { 5129 AppDeathRecipient adr = new AppDeathRecipient( 5130 app, pid, thread); 5131 thread.asBinder().linkToDeath(adr, 0); 5132 app.deathRecipient = adr; 5133 } catch (RemoteException e) { 5134 app.resetPackageList(mProcessStats); 5135 startProcessLocked(app, "link fail", processName); 5136 return false; 5137 } 5138 5139 EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName); 5140 5141 app.makeActive(thread, mProcessStats); 5142 app.curAdj = app.setAdj = -100; 5143 app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT; 5144 app.forcingToForeground = null; 5145 updateProcessForegroundLocked(app, false, false); 5146 app.hasShownUi = false; 5147 app.debugging = false; 5148 app.cached = false; 5149 5150 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 5151 5152 boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info); 5153 List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null; 5154 5155 if (!normalMode) { 5156 Slog.i(TAG, "Launching preboot mode app: " + app); 5157 } 5158 5159 if (localLOGV) Slog.v( 5160 TAG, "New app record " + app 5161 + " thread=" + thread.asBinder() + " pid=" + pid); 5162 try { 5163 int testMode = IApplicationThread.DEBUG_OFF; 5164 if (mDebugApp != null && mDebugApp.equals(processName)) { 5165 testMode = mWaitForDebugger 5166 ? IApplicationThread.DEBUG_WAIT 5167 : IApplicationThread.DEBUG_ON; 5168 app.debugging = true; 5169 if (mDebugTransient) { 5170 mDebugApp = mOrigDebugApp; 5171 mWaitForDebugger = mOrigWaitForDebugger; 5172 } 5173 } 5174 String profileFile = app.instrumentationProfileFile; 5175 ParcelFileDescriptor profileFd = null; 5176 boolean profileAutoStop = false; 5177 if (mProfileApp != null && mProfileApp.equals(processName)) { 5178 mProfileProc = app; 5179 profileFile = mProfileFile; 5180 profileFd = mProfileFd; 5181 profileAutoStop = mAutoStopProfiler; 5182 } 5183 boolean enableOpenGlTrace = false; 5184 if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) { 5185 enableOpenGlTrace = true; 5186 mOpenGlTraceApp = null; 5187 } 5188 5189 // If the app is being launched for restore or full backup, set it up specially 5190 boolean isRestrictedBackupMode = false; 5191 if (mBackupTarget != null && mBackupAppName.equals(processName)) { 5192 isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE) 5193 || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL) 5194 || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL); 5195 } 5196 5197 ensurePackageDexOpt(app.instrumentationInfo != null 5198 ? app.instrumentationInfo.packageName 5199 : app.info.packageName); 5200 if (app.instrumentationClass != null) { 5201 ensurePackageDexOpt(app.instrumentationClass.getPackageName()); 5202 } 5203 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc " 5204 + processName + " with config " + mConfiguration); 5205 ApplicationInfo appInfo = app.instrumentationInfo != null 5206 ? app.instrumentationInfo : app.info; 5207 app.compat = compatibilityInfoForPackageLocked(appInfo); 5208 if (profileFd != null) { 5209 profileFd = profileFd.dup(); 5210 } 5211 thread.bindApplication(processName, appInfo, providers, 5212 app.instrumentationClass, profileFile, profileFd, profileAutoStop, 5213 app.instrumentationArguments, app.instrumentationWatcher, 5214 app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace, 5215 isRestrictedBackupMode || !normalMode, app.persistent, 5216 new Configuration(mConfiguration), app.compat, getCommonServicesLocked(), 5217 mCoreSettingsObserver.getCoreSettingsLocked()); 5218 updateLruProcessLocked(app, false, null); 5219 app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis(); 5220 } catch (Exception e) { 5221 // todo: Yikes! What should we do? For now we will try to 5222 // start another process, but that could easily get us in 5223 // an infinite loop of restarting processes... 5224 Slog.w(TAG, "Exception thrown during bind!", e); 5225 5226 app.resetPackageList(mProcessStats); 5227 app.unlinkDeathRecipient(); 5228 startProcessLocked(app, "bind fail", processName); 5229 return false; 5230 } 5231 5232 // Remove this record from the list of starting applications. 5233 mPersistentStartingProcesses.remove(app); 5234 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 5235 "Attach application locked removing on hold: " + app); 5236 mProcessesOnHold.remove(app); 5237 5238 boolean badApp = false; 5239 boolean didSomething = false; 5240 5241 // See if the top visible activity is waiting to run in this process... 5242 if (normalMode) { 5243 try { 5244 if (mStackSupervisor.attachApplicationLocked(app)) { 5245 didSomething = true; 5246 } 5247 } catch (Exception e) { 5248 badApp = true; 5249 } 5250 } 5251 5252 // Find any services that should be running in this process... 5253 if (!badApp) { 5254 try { 5255 didSomething |= mServices.attachApplicationLocked(app, processName); 5256 } catch (Exception e) { 5257 badApp = true; 5258 } 5259 } 5260 5261 // Check if a next-broadcast receiver is in this process... 5262 if (!badApp && isPendingBroadcastProcessLocked(pid)) { 5263 try { 5264 didSomething |= sendPendingBroadcastsLocked(app); 5265 } catch (Exception e) { 5266 // If the app died trying to launch the receiver we declare it 'bad' 5267 badApp = true; 5268 } 5269 } 5270 5271 // Check whether the next backup agent is in this process... 5272 if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) { 5273 if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app); 5274 ensurePackageDexOpt(mBackupTarget.appInfo.packageName); 5275 try { 5276 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo, 5277 compatibilityInfoForPackageLocked(mBackupTarget.appInfo), 5278 mBackupTarget.backupMode); 5279 } catch (Exception e) { 5280 Slog.w(TAG, "Exception scheduling backup agent creation: "); 5281 e.printStackTrace(); 5282 } 5283 } 5284 5285 if (badApp) { 5286 // todo: Also need to kill application to deal with all 5287 // kinds of exceptions. 5288 handleAppDiedLocked(app, false, true); 5289 return false; 5290 } 5291 5292 if (!didSomething) { 5293 updateOomAdjLocked(); 5294 } 5295 5296 return true; 5297 } 5298 5299 @Override 5300 public final void attachApplication(IApplicationThread thread) { 5301 synchronized (this) { 5302 int callingPid = Binder.getCallingPid(); 5303 final long origId = Binder.clearCallingIdentity(); 5304 attachApplicationLocked(thread, callingPid); 5305 Binder.restoreCallingIdentity(origId); 5306 } 5307 } 5308 5309 @Override 5310 public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) { 5311 final long origId = Binder.clearCallingIdentity(); 5312 synchronized (this) { 5313 ActivityStack stack = ActivityRecord.getStackLocked(token); 5314 if (stack != null) { 5315 ActivityRecord r = 5316 mStackSupervisor.activityIdleInternalLocked(token, false, config); 5317 if (stopProfiling) { 5318 if ((mProfileProc == r.app) && (mProfileFd != null)) { 5319 try { 5320 mProfileFd.close(); 5321 } catch (IOException e) { 5322 } 5323 clearProfilerLocked(); 5324 } 5325 } 5326 } 5327 } 5328 Binder.restoreCallingIdentity(origId); 5329 } 5330 5331 void enableScreenAfterBoot() { 5332 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN, 5333 SystemClock.uptimeMillis()); 5334 mWindowManager.enableScreenAfterBoot(); 5335 5336 synchronized (this) { 5337 updateEventDispatchingLocked(); 5338 } 5339 } 5340 5341 @Override 5342 public void showBootMessage(final CharSequence msg, final boolean always) { 5343 enforceNotIsolatedCaller("showBootMessage"); 5344 mWindowManager.showBootMessage(msg, always); 5345 } 5346 5347 @Override 5348 public void dismissKeyguardOnNextActivity() { 5349 enforceNotIsolatedCaller("dismissKeyguardOnNextActivity"); 5350 final long token = Binder.clearCallingIdentity(); 5351 try { 5352 synchronized (this) { 5353 if (DEBUG_LOCKSCREEN) logLockScreen(""); 5354 if (mLockScreenShown) { 5355 mLockScreenShown = false; 5356 comeOutOfSleepIfNeededLocked(); 5357 } 5358 mStackSupervisor.setDismissKeyguard(true); 5359 } 5360 } finally { 5361 Binder.restoreCallingIdentity(token); 5362 } 5363 } 5364 5365 final void finishBooting() { 5366 // Register receivers to handle package update events 5367 mPackageMonitor.register(mContext, Looper.getMainLooper(), false); 5368 5369 synchronized (this) { 5370 // Ensure that any processes we had put on hold are now started 5371 // up. 5372 final int NP = mProcessesOnHold.size(); 5373 if (NP > 0) { 5374 ArrayList<ProcessRecord> procs = 5375 new ArrayList<ProcessRecord>(mProcessesOnHold); 5376 for (int ip=0; ip<NP; ip++) { 5377 if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: " 5378 + procs.get(ip)); 5379 startProcessLocked(procs.get(ip), "on-hold", null); 5380 } 5381 } 5382 5383 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 5384 // Start looking for apps that are abusing wake locks. 5385 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 5386 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 5387 // Tell anyone interested that we are done booting! 5388 SystemProperties.set("sys.boot_completed", "1"); 5389 SystemProperties.set("dev.bootcomplete", "1"); 5390 for (int i=0; i<mStartedUsers.size(); i++) { 5391 UserStartedState uss = mStartedUsers.valueAt(i); 5392 if (uss.mState == UserStartedState.STATE_BOOTING) { 5393 uss.mState = UserStartedState.STATE_RUNNING; 5394 final int userId = mStartedUsers.keyAt(i); 5395 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 5396 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 5397 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT); 5398 broadcastIntentLocked(null, null, intent, null, 5399 new IIntentReceiver.Stub() { 5400 @Override 5401 public void performReceive(Intent intent, int resultCode, 5402 String data, Bundle extras, boolean ordered, 5403 boolean sticky, int sendingUser) { 5404 synchronized (ActivityManagerService.this) { 5405 requestPssAllProcsLocked(SystemClock.uptimeMillis(), 5406 true, false); 5407 } 5408 } 5409 }, 5410 0, null, null, 5411 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, 5412 AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID, 5413 userId); 5414 } 5415 } 5416 scheduleStartProfilesLocked(); 5417 } 5418 } 5419 } 5420 5421 final void ensureBootCompleted() { 5422 boolean booting; 5423 boolean enableScreen; 5424 synchronized (this) { 5425 booting = mBooting; 5426 mBooting = false; 5427 enableScreen = !mBooted; 5428 mBooted = true; 5429 } 5430 5431 if (booting) { 5432 finishBooting(); 5433 } 5434 5435 if (enableScreen) { 5436 enableScreenAfterBoot(); 5437 } 5438 } 5439 5440 @Override 5441 public final void activityResumed(IBinder token) { 5442 final long origId = Binder.clearCallingIdentity(); 5443 synchronized(this) { 5444 ActivityStack stack = ActivityRecord.getStackLocked(token); 5445 if (stack != null) { 5446 ActivityRecord.activityResumedLocked(token); 5447 } 5448 } 5449 Binder.restoreCallingIdentity(origId); 5450 } 5451 5452 @Override 5453 public final void activityPaused(IBinder token, PersistableBundle persistentState) { 5454 final long origId = Binder.clearCallingIdentity(); 5455 synchronized(this) { 5456 ActivityStack stack = ActivityRecord.getStackLocked(token); 5457 if (stack != null) { 5458 stack.activityPausedLocked(token, false, persistentState); 5459 } 5460 } 5461 Binder.restoreCallingIdentity(origId); 5462 } 5463 5464 @Override 5465 public final void activityStopped(IBinder token, Bundle icicle, 5466 PersistableBundle persistentState, CharSequence description) { 5467 if (localLOGV) Slog.v(TAG, "Activity stopped: token=" + token); 5468 5469 // Refuse possible leaked file descriptors 5470 if (icicle != null && icicle.hasFileDescriptors()) { 5471 throw new IllegalArgumentException("File descriptors passed in Bundle"); 5472 } 5473 5474 final long origId = Binder.clearCallingIdentity(); 5475 5476 synchronized (this) { 5477 ActivityRecord r = ActivityRecord.isInStackLocked(token); 5478 if (r != null) { 5479 r.task.stack.activityStoppedLocked(r, icicle, persistentState, description); 5480 } 5481 } 5482 5483 trimApplications(); 5484 5485 Binder.restoreCallingIdentity(origId); 5486 } 5487 5488 @Override 5489 public final void activityDestroyed(IBinder token) { 5490 if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token); 5491 synchronized (this) { 5492 ActivityStack stack = ActivityRecord.getStackLocked(token); 5493 if (stack != null) { 5494 stack.activityDestroyedLocked(token); 5495 } 5496 } 5497 } 5498 5499 @Override 5500 public String getCallingPackage(IBinder token) { 5501 synchronized (this) { 5502 ActivityRecord r = getCallingRecordLocked(token); 5503 return r != null ? r.info.packageName : null; 5504 } 5505 } 5506 5507 @Override 5508 public ComponentName getCallingActivity(IBinder token) { 5509 synchronized (this) { 5510 ActivityRecord r = getCallingRecordLocked(token); 5511 return r != null ? r.intent.getComponent() : null; 5512 } 5513 } 5514 5515 private ActivityRecord getCallingRecordLocked(IBinder token) { 5516 ActivityRecord r = ActivityRecord.isInStackLocked(token); 5517 if (r == null) { 5518 return null; 5519 } 5520 return r.resultTo; 5521 } 5522 5523 @Override 5524 public ComponentName getActivityClassForToken(IBinder token) { 5525 synchronized(this) { 5526 ActivityRecord r = ActivityRecord.isInStackLocked(token); 5527 if (r == null) { 5528 return null; 5529 } 5530 return r.intent.getComponent(); 5531 } 5532 } 5533 5534 @Override 5535 public String getPackageForToken(IBinder token) { 5536 synchronized(this) { 5537 ActivityRecord r = ActivityRecord.isInStackLocked(token); 5538 if (r == null) { 5539 return null; 5540 } 5541 return r.packageName; 5542 } 5543 } 5544 5545 @Override 5546 public IIntentSender getIntentSender(int type, 5547 String packageName, IBinder token, String resultWho, 5548 int requestCode, Intent[] intents, String[] resolvedTypes, 5549 int flags, Bundle options, int userId) { 5550 enforceNotIsolatedCaller("getIntentSender"); 5551 // Refuse possible leaked file descriptors 5552 if (intents != null) { 5553 if (intents.length < 1) { 5554 throw new IllegalArgumentException("Intents array length must be >= 1"); 5555 } 5556 for (int i=0; i<intents.length; i++) { 5557 Intent intent = intents[i]; 5558 if (intent != null) { 5559 if (intent.hasFileDescriptors()) { 5560 throw new IllegalArgumentException("File descriptors passed in Intent"); 5561 } 5562 if (type == ActivityManager.INTENT_SENDER_BROADCAST && 5563 (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 5564 throw new IllegalArgumentException( 5565 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 5566 } 5567 intents[i] = new Intent(intent); 5568 } 5569 } 5570 if (resolvedTypes != null && resolvedTypes.length != intents.length) { 5571 throw new IllegalArgumentException( 5572 "Intent array length does not match resolvedTypes length"); 5573 } 5574 } 5575 if (options != null) { 5576 if (options.hasFileDescriptors()) { 5577 throw new IllegalArgumentException("File descriptors passed in options"); 5578 } 5579 } 5580 5581 synchronized(this) { 5582 int callingUid = Binder.getCallingUid(); 5583 int origUserId = userId; 5584 userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId, 5585 type == ActivityManager.INTENT_SENDER_BROADCAST, false, 5586 "getIntentSender", null); 5587 if (origUserId == UserHandle.USER_CURRENT) { 5588 // We don't want to evaluate this until the pending intent is 5589 // actually executed. However, we do want to always do the 5590 // security checking for it above. 5591 userId = UserHandle.USER_CURRENT; 5592 } 5593 try { 5594 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 5595 int uid = AppGlobals.getPackageManager() 5596 .getPackageUid(packageName, UserHandle.getUserId(callingUid)); 5597 if (!UserHandle.isSameApp(callingUid, uid)) { 5598 String msg = "Permission Denial: getIntentSender() from pid=" 5599 + Binder.getCallingPid() 5600 + ", uid=" + Binder.getCallingUid() 5601 + ", (need uid=" + uid + ")" 5602 + " is not allowed to send as package " + packageName; 5603 Slog.w(TAG, msg); 5604 throw new SecurityException(msg); 5605 } 5606 } 5607 5608 return getIntentSenderLocked(type, packageName, callingUid, userId, 5609 token, resultWho, requestCode, intents, resolvedTypes, flags, options); 5610 5611 } catch (RemoteException e) { 5612 throw new SecurityException(e); 5613 } 5614 } 5615 } 5616 5617 IIntentSender getIntentSenderLocked(int type, String packageName, 5618 int callingUid, int userId, IBinder token, String resultWho, 5619 int requestCode, Intent[] intents, String[] resolvedTypes, int flags, 5620 Bundle options) { 5621 if (DEBUG_MU) 5622 Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid); 5623 ActivityRecord activity = null; 5624 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 5625 activity = ActivityRecord.isInStackLocked(token); 5626 if (activity == null) { 5627 return null; 5628 } 5629 if (activity.finishing) { 5630 return null; 5631 } 5632 } 5633 5634 final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0; 5635 final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0; 5636 final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0; 5637 flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT 5638 |PendingIntent.FLAG_UPDATE_CURRENT); 5639 5640 PendingIntentRecord.Key key = new PendingIntentRecord.Key( 5641 type, packageName, activity, resultWho, 5642 requestCode, intents, resolvedTypes, flags, options, userId); 5643 WeakReference<PendingIntentRecord> ref; 5644 ref = mIntentSenderRecords.get(key); 5645 PendingIntentRecord rec = ref != null ? ref.get() : null; 5646 if (rec != null) { 5647 if (!cancelCurrent) { 5648 if (updateCurrent) { 5649 if (rec.key.requestIntent != null) { 5650 rec.key.requestIntent.replaceExtras(intents != null ? 5651 intents[intents.length - 1] : null); 5652 } 5653 if (intents != null) { 5654 intents[intents.length-1] = rec.key.requestIntent; 5655 rec.key.allIntents = intents; 5656 rec.key.allResolvedTypes = resolvedTypes; 5657 } else { 5658 rec.key.allIntents = null; 5659 rec.key.allResolvedTypes = null; 5660 } 5661 } 5662 return rec; 5663 } 5664 rec.canceled = true; 5665 mIntentSenderRecords.remove(key); 5666 } 5667 if (noCreate) { 5668 return rec; 5669 } 5670 rec = new PendingIntentRecord(this, key, callingUid); 5671 mIntentSenderRecords.put(key, rec.ref); 5672 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 5673 if (activity.pendingResults == null) { 5674 activity.pendingResults 5675 = new HashSet<WeakReference<PendingIntentRecord>>(); 5676 } 5677 activity.pendingResults.add(rec.ref); 5678 } 5679 return rec; 5680 } 5681 5682 @Override 5683 public void cancelIntentSender(IIntentSender sender) { 5684 if (!(sender instanceof PendingIntentRecord)) { 5685 return; 5686 } 5687 synchronized(this) { 5688 PendingIntentRecord rec = (PendingIntentRecord)sender; 5689 try { 5690 int uid = AppGlobals.getPackageManager() 5691 .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId()); 5692 if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) { 5693 String msg = "Permission Denial: cancelIntentSender() from pid=" 5694 + Binder.getCallingPid() 5695 + ", uid=" + Binder.getCallingUid() 5696 + " is not allowed to cancel packges " 5697 + rec.key.packageName; 5698 Slog.w(TAG, msg); 5699 throw new SecurityException(msg); 5700 } 5701 } catch (RemoteException e) { 5702 throw new SecurityException(e); 5703 } 5704 cancelIntentSenderLocked(rec, true); 5705 } 5706 } 5707 5708 void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) { 5709 rec.canceled = true; 5710 mIntentSenderRecords.remove(rec.key); 5711 if (cleanActivity && rec.key.activity != null) { 5712 rec.key.activity.pendingResults.remove(rec.ref); 5713 } 5714 } 5715 5716 @Override 5717 public String getPackageForIntentSender(IIntentSender pendingResult) { 5718 if (!(pendingResult instanceof PendingIntentRecord)) { 5719 return null; 5720 } 5721 try { 5722 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5723 return res.key.packageName; 5724 } catch (ClassCastException e) { 5725 } 5726 return null; 5727 } 5728 5729 @Override 5730 public int getUidForIntentSender(IIntentSender sender) { 5731 if (sender instanceof PendingIntentRecord) { 5732 try { 5733 PendingIntentRecord res = (PendingIntentRecord)sender; 5734 return res.uid; 5735 } catch (ClassCastException e) { 5736 } 5737 } 5738 return -1; 5739 } 5740 5741 @Override 5742 public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) { 5743 if (!(pendingResult instanceof PendingIntentRecord)) { 5744 return false; 5745 } 5746 try { 5747 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5748 if (res.key.allIntents == null) { 5749 return false; 5750 } 5751 for (int i=0; i<res.key.allIntents.length; i++) { 5752 Intent intent = res.key.allIntents[i]; 5753 if (intent.getPackage() != null && intent.getComponent() != null) { 5754 return false; 5755 } 5756 } 5757 return true; 5758 } catch (ClassCastException e) { 5759 } 5760 return false; 5761 } 5762 5763 @Override 5764 public boolean isIntentSenderAnActivity(IIntentSender pendingResult) { 5765 if (!(pendingResult instanceof PendingIntentRecord)) { 5766 return false; 5767 } 5768 try { 5769 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5770 if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) { 5771 return true; 5772 } 5773 return false; 5774 } catch (ClassCastException e) { 5775 } 5776 return false; 5777 } 5778 5779 @Override 5780 public Intent getIntentForIntentSender(IIntentSender pendingResult) { 5781 if (!(pendingResult instanceof PendingIntentRecord)) { 5782 return null; 5783 } 5784 try { 5785 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5786 return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null; 5787 } catch (ClassCastException e) { 5788 } 5789 return null; 5790 } 5791 5792 @Override 5793 public String getTagForIntentSender(IIntentSender pendingResult, String prefix) { 5794 if (!(pendingResult instanceof PendingIntentRecord)) { 5795 return null; 5796 } 5797 try { 5798 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5799 Intent intent = res.key.requestIntent; 5800 if (intent != null) { 5801 if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null 5802 || res.lastTagPrefix.equals(prefix))) { 5803 return res.lastTag; 5804 } 5805 res.lastTagPrefix = prefix; 5806 StringBuilder sb = new StringBuilder(128); 5807 if (prefix != null) { 5808 sb.append(prefix); 5809 } 5810 if (intent.getAction() != null) { 5811 sb.append(intent.getAction()); 5812 } else if (intent.getComponent() != null) { 5813 intent.getComponent().appendShortString(sb); 5814 } else { 5815 sb.append("?"); 5816 } 5817 return res.lastTag = sb.toString(); 5818 } 5819 } catch (ClassCastException e) { 5820 } 5821 return null; 5822 } 5823 5824 @Override 5825 public void setProcessLimit(int max) { 5826 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 5827 "setProcessLimit()"); 5828 synchronized (this) { 5829 mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max; 5830 mProcessLimitOverride = max; 5831 } 5832 trimApplications(); 5833 } 5834 5835 @Override 5836 public int getProcessLimit() { 5837 synchronized (this) { 5838 return mProcessLimitOverride; 5839 } 5840 } 5841 5842 void foregroundTokenDied(ForegroundToken token) { 5843 synchronized (ActivityManagerService.this) { 5844 synchronized (mPidsSelfLocked) { 5845 ForegroundToken cur 5846 = mForegroundProcesses.get(token.pid); 5847 if (cur != token) { 5848 return; 5849 } 5850 mForegroundProcesses.remove(token.pid); 5851 ProcessRecord pr = mPidsSelfLocked.get(token.pid); 5852 if (pr == null) { 5853 return; 5854 } 5855 pr.forcingToForeground = null; 5856 updateProcessForegroundLocked(pr, false, false); 5857 } 5858 updateOomAdjLocked(); 5859 } 5860 } 5861 5862 @Override 5863 public void setProcessForeground(IBinder token, int pid, boolean isForeground) { 5864 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 5865 "setProcessForeground()"); 5866 synchronized(this) { 5867 boolean changed = false; 5868 5869 synchronized (mPidsSelfLocked) { 5870 ProcessRecord pr = mPidsSelfLocked.get(pid); 5871 if (pr == null && isForeground) { 5872 Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid); 5873 return; 5874 } 5875 ForegroundToken oldToken = mForegroundProcesses.get(pid); 5876 if (oldToken != null) { 5877 oldToken.token.unlinkToDeath(oldToken, 0); 5878 mForegroundProcesses.remove(pid); 5879 if (pr != null) { 5880 pr.forcingToForeground = null; 5881 } 5882 changed = true; 5883 } 5884 if (isForeground && token != null) { 5885 ForegroundToken newToken = new ForegroundToken() { 5886 @Override 5887 public void binderDied() { 5888 foregroundTokenDied(this); 5889 } 5890 }; 5891 newToken.pid = pid; 5892 newToken.token = token; 5893 try { 5894 token.linkToDeath(newToken, 0); 5895 mForegroundProcesses.put(pid, newToken); 5896 pr.forcingToForeground = token; 5897 changed = true; 5898 } catch (RemoteException e) { 5899 // If the process died while doing this, we will later 5900 // do the cleanup with the process death link. 5901 } 5902 } 5903 } 5904 5905 if (changed) { 5906 updateOomAdjLocked(); 5907 } 5908 } 5909 } 5910 5911 // ========================================================= 5912 // PERMISSIONS 5913 // ========================================================= 5914 5915 static class PermissionController extends IPermissionController.Stub { 5916 ActivityManagerService mActivityManagerService; 5917 PermissionController(ActivityManagerService activityManagerService) { 5918 mActivityManagerService = activityManagerService; 5919 } 5920 5921 @Override 5922 public boolean checkPermission(String permission, int pid, int uid) { 5923 return mActivityManagerService.checkPermission(permission, pid, 5924 uid) == PackageManager.PERMISSION_GRANTED; 5925 } 5926 } 5927 5928 class IntentFirewallInterface implements IntentFirewall.AMSInterface { 5929 @Override 5930 public int checkComponentPermission(String permission, int pid, int uid, 5931 int owningUid, boolean exported) { 5932 return ActivityManagerService.this.checkComponentPermission(permission, pid, uid, 5933 owningUid, exported); 5934 } 5935 5936 @Override 5937 public Object getAMSLock() { 5938 return ActivityManagerService.this; 5939 } 5940 } 5941 5942 /** 5943 * This can be called with or without the global lock held. 5944 */ 5945 int checkComponentPermission(String permission, int pid, int uid, 5946 int owningUid, boolean exported) { 5947 // We might be performing an operation on behalf of an indirect binder 5948 // invocation, e.g. via {@link #openContentUri}. Check and adjust the 5949 // client identity accordingly before proceeding. 5950 Identity tlsIdentity = sCallerIdentity.get(); 5951 if (tlsIdentity != null) { 5952 Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {" 5953 + tlsIdentity.pid + "," + tlsIdentity.uid + "}"); 5954 uid = tlsIdentity.uid; 5955 pid = tlsIdentity.pid; 5956 } 5957 5958 if (pid == MY_PID) { 5959 return PackageManager.PERMISSION_GRANTED; 5960 } 5961 5962 return ActivityManager.checkComponentPermission(permission, uid, 5963 owningUid, exported); 5964 } 5965 5966 /** 5967 * As the only public entry point for permissions checking, this method 5968 * can enforce the semantic that requesting a check on a null global 5969 * permission is automatically denied. (Internally a null permission 5970 * string is used when calling {@link #checkComponentPermission} in cases 5971 * when only uid-based security is needed.) 5972 * 5973 * This can be called with or without the global lock held. 5974 */ 5975 @Override 5976 public int checkPermission(String permission, int pid, int uid) { 5977 if (permission == null) { 5978 return PackageManager.PERMISSION_DENIED; 5979 } 5980 return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true); 5981 } 5982 5983 /** 5984 * Binder IPC calls go through the public entry point. 5985 * This can be called with or without the global lock held. 5986 */ 5987 int checkCallingPermission(String permission) { 5988 return checkPermission(permission, 5989 Binder.getCallingPid(), 5990 UserHandle.getAppId(Binder.getCallingUid())); 5991 } 5992 5993 /** 5994 * This can be called with or without the global lock held. 5995 */ 5996 void enforceCallingPermission(String permission, String func) { 5997 if (checkCallingPermission(permission) 5998 == PackageManager.PERMISSION_GRANTED) { 5999 return; 6000 } 6001 6002 String msg = "Permission Denial: " + func + " from pid=" 6003 + Binder.getCallingPid() 6004 + ", uid=" + Binder.getCallingUid() 6005 + " requires " + permission; 6006 Slog.w(TAG, msg); 6007 throw new SecurityException(msg); 6008 } 6009 6010 /** 6011 * Determine if UID is holding permissions required to access {@link Uri} in 6012 * the given {@link ProviderInfo}. Final permission checking is always done 6013 * in {@link ContentProvider}. 6014 */ 6015 private final boolean checkHoldingPermissionsLocked( 6016 IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) { 6017 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6018 "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid); 6019 6020 if (pi.applicationInfo.uid == uid) { 6021 return true; 6022 } else if (!pi.exported) { 6023 return false; 6024 } 6025 6026 boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0; 6027 boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0; 6028 try { 6029 // check if target holds top-level <provider> permissions 6030 if (!readMet && pi.readPermission != null 6031 && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) { 6032 readMet = true; 6033 } 6034 if (!writeMet && pi.writePermission != null 6035 && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) { 6036 writeMet = true; 6037 } 6038 6039 // track if unprotected read/write is allowed; any denied 6040 // <path-permission> below removes this ability 6041 boolean allowDefaultRead = pi.readPermission == null; 6042 boolean allowDefaultWrite = pi.writePermission == null; 6043 6044 // check if target holds any <path-permission> that match uri 6045 final PathPermission[] pps = pi.pathPermissions; 6046 if (pps != null) { 6047 final String path = grantUri.uri.getPath(); 6048 int i = pps.length; 6049 while (i > 0 && (!readMet || !writeMet)) { 6050 i--; 6051 PathPermission pp = pps[i]; 6052 if (pp.match(path)) { 6053 if (!readMet) { 6054 final String pprperm = pp.getReadPermission(); 6055 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for " 6056 + pprperm + " for " + pp.getPath() 6057 + ": match=" + pp.match(path) 6058 + " check=" + pm.checkUidPermission(pprperm, uid)); 6059 if (pprperm != null) { 6060 if (pm.checkUidPermission(pprperm, uid) == PERMISSION_GRANTED) { 6061 readMet = true; 6062 } else { 6063 allowDefaultRead = false; 6064 } 6065 } 6066 } 6067 if (!writeMet) { 6068 final String ppwperm = pp.getWritePermission(); 6069 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm " 6070 + ppwperm + " for " + pp.getPath() 6071 + ": match=" + pp.match(path) 6072 + " check=" + pm.checkUidPermission(ppwperm, uid)); 6073 if (ppwperm != null) { 6074 if (pm.checkUidPermission(ppwperm, uid) == PERMISSION_GRANTED) { 6075 writeMet = true; 6076 } else { 6077 allowDefaultWrite = false; 6078 } 6079 } 6080 } 6081 } 6082 } 6083 } 6084 6085 // grant unprotected <provider> read/write, if not blocked by 6086 // <path-permission> above 6087 if (allowDefaultRead) readMet = true; 6088 if (allowDefaultWrite) writeMet = true; 6089 6090 } catch (RemoteException e) { 6091 return false; 6092 } 6093 6094 return readMet && writeMet; 6095 } 6096 6097 private ProviderInfo getProviderInfoLocked(String authority, int userHandle) { 6098 ProviderInfo pi = null; 6099 ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle); 6100 if (cpr != null) { 6101 pi = cpr.info; 6102 } else { 6103 try { 6104 pi = AppGlobals.getPackageManager().resolveContentProvider( 6105 authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle); 6106 } catch (RemoteException ex) { 6107 } 6108 } 6109 return pi; 6110 } 6111 6112 private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) { 6113 final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid); 6114 if (targetUris != null) { 6115 return targetUris.get(grantUri); 6116 } 6117 return null; 6118 } 6119 6120 private UriPermission findOrCreateUriPermissionLocked(String sourcePkg, 6121 String targetPkg, int targetUid, GrantUri grantUri) { 6122 ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid); 6123 if (targetUris == null) { 6124 targetUris = Maps.newArrayMap(); 6125 mGrantedUriPermissions.put(targetUid, targetUris); 6126 } 6127 6128 UriPermission perm = targetUris.get(grantUri); 6129 if (perm == null) { 6130 perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri); 6131 targetUris.put(grantUri, perm); 6132 } 6133 6134 return perm; 6135 } 6136 6137 private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid, 6138 final int modeFlags) { 6139 final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0; 6140 final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE 6141 : UriPermission.STRENGTH_OWNED; 6142 6143 // Root gets to do everything. 6144 if (uid == 0) { 6145 return true; 6146 } 6147 6148 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid); 6149 if (perms == null) return false; 6150 6151 // First look for exact match 6152 final UriPermission exactPerm = perms.get(grantUri); 6153 if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) { 6154 return true; 6155 } 6156 6157 // No exact match, look for prefixes 6158 final int N = perms.size(); 6159 for (int i = 0; i < N; i++) { 6160 final UriPermission perm = perms.valueAt(i); 6161 if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri) 6162 && perm.getStrength(modeFlags) >= minStrength) { 6163 return true; 6164 } 6165 } 6166 6167 return false; 6168 } 6169 6170 @Override 6171 public int checkUriPermission(Uri uri, int pid, int uid, 6172 final int modeFlags, int userId) { 6173 enforceNotIsolatedCaller("checkUriPermission"); 6174 6175 // Another redirected-binder-call permissions check as in 6176 // {@link checkComponentPermission}. 6177 Identity tlsIdentity = sCallerIdentity.get(); 6178 if (tlsIdentity != null) { 6179 uid = tlsIdentity.uid; 6180 pid = tlsIdentity.pid; 6181 } 6182 6183 // Our own process gets to do everything. 6184 if (pid == MY_PID) { 6185 return PackageManager.PERMISSION_GRANTED; 6186 } 6187 synchronized (this) { 6188 return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags) 6189 ? PackageManager.PERMISSION_GRANTED 6190 : PackageManager.PERMISSION_DENIED; 6191 } 6192 } 6193 6194 /** 6195 * Check if the targetPkg can be granted permission to access uri by 6196 * the callingUid using the given modeFlags. Throws a security exception 6197 * if callingUid is not allowed to do this. Returns the uid of the target 6198 * if the URI permission grant should be performed; returns -1 if it is not 6199 * needed (for example targetPkg already has permission to access the URI). 6200 * If you already know the uid of the target, you can supply it in 6201 * lastTargetUid else set that to -1. 6202 */ 6203 int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri, 6204 final int modeFlags, int lastTargetUid) { 6205 if (!Intent.isAccessUriMode(modeFlags)) { 6206 return -1; 6207 } 6208 6209 if (targetPkg != null) { 6210 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6211 "Checking grant " + targetPkg + " permission to " + grantUri); 6212 } 6213 6214 final IPackageManager pm = AppGlobals.getPackageManager(); 6215 6216 // If this is not a content: uri, we can't do anything with it. 6217 if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) { 6218 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6219 "Can't grant URI permission for non-content URI: " + grantUri); 6220 return -1; 6221 } 6222 6223 final String authority = grantUri.uri.getAuthority(); 6224 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId); 6225 if (pi == null) { 6226 Slog.w(TAG, "No content provider found for permission check: " + 6227 grantUri.uri.toSafeString()); 6228 return -1; 6229 } 6230 6231 int targetUid = lastTargetUid; 6232 if (targetUid < 0 && targetPkg != null) { 6233 try { 6234 targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid)); 6235 if (targetUid < 0) { 6236 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6237 "Can't grant URI permission no uid for: " + targetPkg); 6238 return -1; 6239 } 6240 } catch (RemoteException ex) { 6241 return -1; 6242 } 6243 } 6244 6245 if (targetUid >= 0) { 6246 // First... does the target actually need this permission? 6247 if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) { 6248 // No need to grant the target this permission. 6249 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6250 "Target " + targetPkg + " already has full permission to " + grantUri); 6251 return -1; 6252 } 6253 } else { 6254 // First... there is no target package, so can anyone access it? 6255 boolean allowed = pi.exported; 6256 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) { 6257 if (pi.readPermission != null) { 6258 allowed = false; 6259 } 6260 } 6261 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) { 6262 if (pi.writePermission != null) { 6263 allowed = false; 6264 } 6265 } 6266 if (allowed) { 6267 return -1; 6268 } 6269 } 6270 6271 // Second... is the provider allowing granting of URI permissions? 6272 if (!pi.grantUriPermissions) { 6273 throw new SecurityException("Provider " + pi.packageName 6274 + "/" + pi.name 6275 + " does not allow granting of Uri permissions (uri " 6276 + grantUri + ")"); 6277 } 6278 if (pi.uriPermissionPatterns != null) { 6279 final int N = pi.uriPermissionPatterns.length; 6280 boolean allowed = false; 6281 for (int i=0; i<N; i++) { 6282 if (pi.uriPermissionPatterns[i] != null 6283 && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) { 6284 allowed = true; 6285 break; 6286 } 6287 } 6288 if (!allowed) { 6289 throw new SecurityException("Provider " + pi.packageName 6290 + "/" + pi.name 6291 + " does not allow granting of permission to path of Uri " 6292 + grantUri); 6293 } 6294 } 6295 6296 // Third... does the caller itself have permission to access 6297 // this uri? 6298 if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) { 6299 if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) { 6300 // Require they hold a strong enough Uri permission 6301 if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) { 6302 throw new SecurityException("Uid " + callingUid 6303 + " does not have permission to uri " + grantUri); 6304 } 6305 } 6306 } 6307 return targetUid; 6308 } 6309 6310 @Override 6311 public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri, 6312 final int modeFlags, int userId) { 6313 enforceNotIsolatedCaller("checkGrantUriPermission"); 6314 synchronized(this) { 6315 return checkGrantUriPermissionLocked(callingUid, targetPkg, 6316 new GrantUri(userId, uri, false), modeFlags, -1); 6317 } 6318 } 6319 6320 void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri, 6321 final int modeFlags, UriPermissionOwner owner) { 6322 if (!Intent.isAccessUriMode(modeFlags)) { 6323 return; 6324 } 6325 6326 // So here we are: the caller has the assumed permission 6327 // to the uri, and the target doesn't. Let's now give this to 6328 // the target. 6329 6330 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6331 "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri); 6332 6333 final String authority = grantUri.uri.getAuthority(); 6334 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId); 6335 if (pi == null) { 6336 Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString()); 6337 return; 6338 } 6339 6340 if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) { 6341 grantUri.prefix = true; 6342 } 6343 final UriPermission perm = findOrCreateUriPermissionLocked( 6344 pi.packageName, targetPkg, targetUid, grantUri); 6345 perm.grantModes(modeFlags, owner); 6346 } 6347 6348 void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri, 6349 final int modeFlags, UriPermissionOwner owner) { 6350 if (targetPkg == null) { 6351 throw new NullPointerException("targetPkg"); 6352 } 6353 6354 int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags, 6355 -1); 6356 if (targetUid < 0) { 6357 return; 6358 } 6359 6360 grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags, 6361 owner); 6362 } 6363 6364 static class NeededUriGrants extends ArrayList<GrantUri> { 6365 final String targetPkg; 6366 final int targetUid; 6367 final int flags; 6368 6369 NeededUriGrants(String targetPkg, int targetUid, int flags) { 6370 this.targetPkg = targetPkg; 6371 this.targetUid = targetUid; 6372 this.flags = flags; 6373 } 6374 } 6375 6376 /** 6377 * Like checkGrantUriPermissionLocked, but takes an Intent. 6378 */ 6379 NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid, 6380 String targetPkg, Intent intent, int mode, NeededUriGrants needed) { 6381 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6382 "Checking URI perm to data=" + (intent != null ? intent.getData() : null) 6383 + " clip=" + (intent != null ? intent.getClipData() : null) 6384 + " from " + intent + "; flags=0x" 6385 + Integer.toHexString(intent != null ? intent.getFlags() : 0)); 6386 6387 if (targetPkg == null) { 6388 throw new NullPointerException("targetPkg"); 6389 } 6390 6391 if (intent == null) { 6392 return null; 6393 } 6394 Uri data = intent.getData(); 6395 ClipData clip = intent.getClipData(); 6396 if (data == null && clip == null) { 6397 return null; 6398 } 6399 6400 if (data != null) { 6401 GrantUri grantUri = GrantUri.resolve(UserHandle.getUserId(callingUid), data); 6402 int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode, 6403 needed != null ? needed.targetUid : -1); 6404 if (targetUid > 0) { 6405 if (needed == null) { 6406 needed = new NeededUriGrants(targetPkg, targetUid, mode); 6407 } 6408 needed.add(grantUri); 6409 } 6410 } 6411 if (clip != null) { 6412 for (int i=0; i<clip.getItemCount(); i++) { 6413 Uri uri = clip.getItemAt(i).getUri(); 6414 if (uri != null) { 6415 int targetUid = -1; 6416 GrantUri grantUri = GrantUri.resolve(UserHandle.getUserId(callingUid), uri); 6417 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode, 6418 needed != null ? needed.targetUid : -1); 6419 if (targetUid > 0) { 6420 if (needed == null) { 6421 needed = new NeededUriGrants(targetPkg, targetUid, mode); 6422 } 6423 needed.add(grantUri); 6424 } 6425 } else { 6426 Intent clipIntent = clip.getItemAt(i).getIntent(); 6427 if (clipIntent != null) { 6428 NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked( 6429 callingUid, targetPkg, clipIntent, mode, needed); 6430 if (newNeeded != null) { 6431 needed = newNeeded; 6432 } 6433 } 6434 } 6435 } 6436 } 6437 6438 return needed; 6439 } 6440 6441 /** 6442 * Like grantUriPermissionUncheckedLocked, but takes an Intent. 6443 */ 6444 void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed, 6445 UriPermissionOwner owner) { 6446 if (needed != null) { 6447 for (int i=0; i<needed.size(); i++) { 6448 GrantUri grantUri = needed.get(i); 6449 grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg, 6450 grantUri, needed.flags, owner); 6451 } 6452 } 6453 } 6454 6455 void grantUriPermissionFromIntentLocked(int callingUid, 6456 String targetPkg, Intent intent, UriPermissionOwner owner) { 6457 NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg, 6458 intent, intent != null ? intent.getFlags() : 0, null); 6459 if (needed == null) { 6460 return; 6461 } 6462 6463 grantUriPermissionUncheckedFromIntentLocked(needed, owner); 6464 } 6465 6466 @Override 6467 public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri, 6468 final int modeFlags, int userId) { 6469 enforceNotIsolatedCaller("grantUriPermission"); 6470 GrantUri grantUri = new GrantUri(userId, uri, false); 6471 synchronized(this) { 6472 final ProcessRecord r = getRecordForAppLocked(caller); 6473 if (r == null) { 6474 throw new SecurityException("Unable to find app for caller " 6475 + caller 6476 + " when granting permission to uri " + grantUri); 6477 } 6478 if (targetPkg == null) { 6479 throw new IllegalArgumentException("null target"); 6480 } 6481 if (grantUri == null) { 6482 throw new IllegalArgumentException("null uri"); 6483 } 6484 6485 Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION 6486 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION 6487 | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION 6488 | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION); 6489 6490 grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null); 6491 } 6492 } 6493 6494 void removeUriPermissionIfNeededLocked(UriPermission perm) { 6495 if (perm.modeFlags == 0) { 6496 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get( 6497 perm.targetUid); 6498 if (perms != null) { 6499 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6500 "Removing " + perm.targetUid + " permission to " + perm.uri); 6501 6502 perms.remove(perm.uri); 6503 if (perms.isEmpty()) { 6504 mGrantedUriPermissions.remove(perm.targetUid); 6505 } 6506 } 6507 } 6508 } 6509 6510 private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) { 6511 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + grantUri); 6512 6513 final IPackageManager pm = AppGlobals.getPackageManager(); 6514 final String authority = grantUri.uri.getAuthority(); 6515 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId); 6516 if (pi == null) { 6517 Slog.w(TAG, "No content provider found for permission revoke: " 6518 + grantUri.toSafeString()); 6519 return; 6520 } 6521 6522 // Does the caller have this permission on the URI? 6523 if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) { 6524 // Right now, if you are not the original owner of the permission, 6525 // you are not allowed to revoke it. 6526 //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) { 6527 throw new SecurityException("Uid " + callingUid 6528 + " does not have permission to uri " + grantUri); 6529 //} 6530 } 6531 6532 boolean persistChanged = false; 6533 6534 // Go through all of the permissions and remove any that match. 6535 int N = mGrantedUriPermissions.size(); 6536 for (int i = 0; i < N; i++) { 6537 final int targetUid = mGrantedUriPermissions.keyAt(i); 6538 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 6539 6540 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) { 6541 final UriPermission perm = it.next(); 6542 if (perm.uri.sourceUserId == grantUri.sourceUserId 6543 && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) { 6544 if (DEBUG_URI_PERMISSION) 6545 Slog.v(TAG, 6546 "Revoking " + perm.targetUid + " permission to " + perm.uri); 6547 persistChanged |= perm.revokeModes( 6548 modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION); 6549 if (perm.modeFlags == 0) { 6550 it.remove(); 6551 } 6552 } 6553 } 6554 6555 if (perms.isEmpty()) { 6556 mGrantedUriPermissions.remove(targetUid); 6557 N--; 6558 i--; 6559 } 6560 } 6561 6562 if (persistChanged) { 6563 schedulePersistUriGrants(); 6564 } 6565 } 6566 6567 @Override 6568 public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags, 6569 int userId) { 6570 enforceNotIsolatedCaller("revokeUriPermission"); 6571 synchronized(this) { 6572 final ProcessRecord r = getRecordForAppLocked(caller); 6573 if (r == null) { 6574 throw new SecurityException("Unable to find app for caller " 6575 + caller 6576 + " when revoking permission to uri " + uri); 6577 } 6578 if (uri == null) { 6579 Slog.w(TAG, "revokeUriPermission: null uri"); 6580 return; 6581 } 6582 6583 if (!Intent.isAccessUriMode(modeFlags)) { 6584 return; 6585 } 6586 6587 final IPackageManager pm = AppGlobals.getPackageManager(); 6588 final String authority = uri.getAuthority(); 6589 final ProviderInfo pi = getProviderInfoLocked(authority, userId); 6590 if (pi == null) { 6591 Slog.w(TAG, "No content provider found for permission revoke: " 6592 + uri.toSafeString()); 6593 return; 6594 } 6595 6596 revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags); 6597 } 6598 } 6599 6600 /** 6601 * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the 6602 * given package. 6603 * 6604 * @param packageName Package name to match, or {@code null} to apply to all 6605 * packages. 6606 * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply 6607 * to all users. 6608 * @param persistable If persistable grants should be removed. 6609 */ 6610 private void removeUriPermissionsForPackageLocked( 6611 String packageName, int userHandle, boolean persistable) { 6612 if (userHandle == UserHandle.USER_ALL && packageName == null) { 6613 throw new IllegalArgumentException("Must narrow by either package or user"); 6614 } 6615 6616 boolean persistChanged = false; 6617 6618 int N = mGrantedUriPermissions.size(); 6619 for (int i = 0; i < N; i++) { 6620 final int targetUid = mGrantedUriPermissions.keyAt(i); 6621 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 6622 6623 // Only inspect grants matching user 6624 if (userHandle == UserHandle.USER_ALL 6625 || userHandle == UserHandle.getUserId(targetUid)) { 6626 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) { 6627 final UriPermission perm = it.next(); 6628 6629 // Only inspect grants matching package 6630 if (packageName == null || perm.sourcePkg.equals(packageName) 6631 || perm.targetPkg.equals(packageName)) { 6632 persistChanged |= perm.revokeModes( 6633 persistable ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION); 6634 6635 // Only remove when no modes remain; any persisted grants 6636 // will keep this alive. 6637 if (perm.modeFlags == 0) { 6638 it.remove(); 6639 } 6640 } 6641 } 6642 6643 if (perms.isEmpty()) { 6644 mGrantedUriPermissions.remove(targetUid); 6645 N--; 6646 i--; 6647 } 6648 } 6649 } 6650 6651 if (persistChanged) { 6652 schedulePersistUriGrants(); 6653 } 6654 } 6655 6656 @Override 6657 public IBinder newUriPermissionOwner(String name) { 6658 enforceNotIsolatedCaller("newUriPermissionOwner"); 6659 synchronized(this) { 6660 UriPermissionOwner owner = new UriPermissionOwner(this, name); 6661 return owner.getExternalTokenLocked(); 6662 } 6663 } 6664 6665 @Override 6666 public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri, 6667 final int modeFlags, int userId) { 6668 synchronized(this) { 6669 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 6670 if (owner == null) { 6671 throw new IllegalArgumentException("Unknown owner: " + token); 6672 } 6673 if (fromUid != Binder.getCallingUid()) { 6674 if (Binder.getCallingUid() != Process.myUid()) { 6675 // Only system code can grant URI permissions on behalf 6676 // of other users. 6677 throw new SecurityException("nice try"); 6678 } 6679 } 6680 if (targetPkg == null) { 6681 throw new IllegalArgumentException("null target"); 6682 } 6683 if (uri == null) { 6684 throw new IllegalArgumentException("null uri"); 6685 } 6686 6687 grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(userId, uri, false), 6688 modeFlags, owner); 6689 } 6690 } 6691 6692 @Override 6693 public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) { 6694 synchronized(this) { 6695 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 6696 if (owner == null) { 6697 throw new IllegalArgumentException("Unknown owner: " + token); 6698 } 6699 6700 if (uri == null) { 6701 owner.removeUriPermissionsLocked(mode); 6702 } else { 6703 owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode); 6704 } 6705 } 6706 } 6707 6708 private void schedulePersistUriGrants() { 6709 if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) { 6710 mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG), 6711 10 * DateUtils.SECOND_IN_MILLIS); 6712 } 6713 } 6714 6715 private void writeGrantedUriPermissions() { 6716 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()"); 6717 6718 // Snapshot permissions so we can persist without lock 6719 ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList(); 6720 synchronized (this) { 6721 final int size = mGrantedUriPermissions.size(); 6722 for (int i = 0; i < size; i++) { 6723 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 6724 for (UriPermission perm : perms.values()) { 6725 if (perm.persistedModeFlags != 0) { 6726 persist.add(perm.snapshot()); 6727 } 6728 } 6729 } 6730 } 6731 6732 FileOutputStream fos = null; 6733 try { 6734 fos = mGrantFile.startWrite(); 6735 6736 XmlSerializer out = new FastXmlSerializer(); 6737 out.setOutput(fos, "utf-8"); 6738 out.startDocument(null, true); 6739 out.startTag(null, TAG_URI_GRANTS); 6740 for (UriPermission.Snapshot perm : persist) { 6741 out.startTag(null, TAG_URI_GRANT); 6742 writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId); 6743 writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId); 6744 out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg); 6745 out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg); 6746 out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri)); 6747 writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix); 6748 writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags); 6749 writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime); 6750 out.endTag(null, TAG_URI_GRANT); 6751 } 6752 out.endTag(null, TAG_URI_GRANTS); 6753 out.endDocument(); 6754 6755 mGrantFile.finishWrite(fos); 6756 } catch (IOException e) { 6757 if (fos != null) { 6758 mGrantFile.failWrite(fos); 6759 } 6760 } 6761 } 6762 6763 private void readGrantedUriPermissionsLocked() { 6764 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()"); 6765 6766 final long now = System.currentTimeMillis(); 6767 6768 FileInputStream fis = null; 6769 try { 6770 fis = mGrantFile.openRead(); 6771 final XmlPullParser in = Xml.newPullParser(); 6772 in.setInput(fis, null); 6773 6774 int type; 6775 while ((type = in.next()) != END_DOCUMENT) { 6776 final String tag = in.getName(); 6777 if (type == START_TAG) { 6778 if (TAG_URI_GRANT.equals(tag)) { 6779 final int sourceUserId; 6780 final int targetUserId; 6781 final int userHandle = readIntAttribute(in, 6782 ATTR_USER_HANDLE, UserHandle.USER_NULL); 6783 if (userHandle != UserHandle.USER_NULL) { 6784 // For backwards compatibility. 6785 sourceUserId = userHandle; 6786 targetUserId = userHandle; 6787 } else { 6788 sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID); 6789 targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID); 6790 } 6791 final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG); 6792 final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG); 6793 final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI)); 6794 final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX); 6795 final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS); 6796 final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now); 6797 6798 // Sanity check that provider still belongs to source package 6799 final ProviderInfo pi = getProviderInfoLocked( 6800 uri.getAuthority(), sourceUserId); 6801 if (pi != null && sourcePkg.equals(pi.packageName)) { 6802 int targetUid = -1; 6803 try { 6804 targetUid = AppGlobals.getPackageManager() 6805 .getPackageUid(targetPkg, targetUserId); 6806 } catch (RemoteException e) { 6807 } 6808 if (targetUid != -1) { 6809 final UriPermission perm = findOrCreateUriPermissionLocked( 6810 sourcePkg, targetPkg, targetUid, 6811 new GrantUri(sourceUserId, uri, prefix)); 6812 perm.initPersistedModes(modeFlags, createdTime); 6813 } 6814 } else { 6815 Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg 6816 + " but instead found " + pi); 6817 } 6818 } 6819 } 6820 } 6821 } catch (FileNotFoundException e) { 6822 // Missing grants is okay 6823 } catch (IOException e) { 6824 Log.wtf(TAG, "Failed reading Uri grants", e); 6825 } catch (XmlPullParserException e) { 6826 Log.wtf(TAG, "Failed reading Uri grants", e); 6827 } finally { 6828 IoUtils.closeQuietly(fis); 6829 } 6830 } 6831 6832 @Override 6833 public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) { 6834 enforceNotIsolatedCaller("takePersistableUriPermission"); 6835 6836 Preconditions.checkFlagsArgument(modeFlags, 6837 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 6838 6839 synchronized (this) { 6840 final int callingUid = Binder.getCallingUid(); 6841 boolean persistChanged = false; 6842 GrantUri grantUri = new GrantUri(userId, uri, false); 6843 6844 UriPermission exactPerm = findUriPermissionLocked(callingUid, 6845 new GrantUri(userId, uri, false)); 6846 UriPermission prefixPerm = findUriPermissionLocked(callingUid, 6847 new GrantUri(userId, uri, true)); 6848 6849 final boolean exactValid = (exactPerm != null) 6850 && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags); 6851 final boolean prefixValid = (prefixPerm != null) 6852 && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags); 6853 6854 if (!(exactValid || prefixValid)) { 6855 throw new SecurityException("No persistable permission grants found for UID " 6856 + callingUid + " and Uri " + grantUri.toSafeString()); 6857 } 6858 6859 if (exactValid) { 6860 persistChanged |= exactPerm.takePersistableModes(modeFlags); 6861 } 6862 if (prefixValid) { 6863 persistChanged |= prefixPerm.takePersistableModes(modeFlags); 6864 } 6865 6866 persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid); 6867 6868 if (persistChanged) { 6869 schedulePersistUriGrants(); 6870 } 6871 } 6872 } 6873 6874 @Override 6875 public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) { 6876 enforceNotIsolatedCaller("releasePersistableUriPermission"); 6877 6878 Preconditions.checkFlagsArgument(modeFlags, 6879 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 6880 6881 synchronized (this) { 6882 final int callingUid = Binder.getCallingUid(); 6883 boolean persistChanged = false; 6884 6885 UriPermission exactPerm = findUriPermissionLocked(callingUid, 6886 new GrantUri(userId, uri, false)); 6887 UriPermission prefixPerm = findUriPermissionLocked(callingUid, 6888 new GrantUri(userId, uri, true)); 6889 if (exactPerm == null && prefixPerm == null) { 6890 throw new SecurityException("No permission grants found for UID " + callingUid 6891 + " and Uri " + uri.toSafeString()); 6892 } 6893 6894 if (exactPerm != null) { 6895 persistChanged |= exactPerm.releasePersistableModes(modeFlags); 6896 removeUriPermissionIfNeededLocked(exactPerm); 6897 } 6898 if (prefixPerm != null) { 6899 persistChanged |= prefixPerm.releasePersistableModes(modeFlags); 6900 removeUriPermissionIfNeededLocked(prefixPerm); 6901 } 6902 6903 if (persistChanged) { 6904 schedulePersistUriGrants(); 6905 } 6906 } 6907 } 6908 6909 /** 6910 * Prune any older {@link UriPermission} for the given UID until outstanding 6911 * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}. 6912 * 6913 * @return if any mutations occured that require persisting. 6914 */ 6915 private boolean maybePrunePersistedUriGrantsLocked(int uid) { 6916 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid); 6917 if (perms == null) return false; 6918 if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false; 6919 6920 final ArrayList<UriPermission> persisted = Lists.newArrayList(); 6921 for (UriPermission perm : perms.values()) { 6922 if (perm.persistedModeFlags != 0) { 6923 persisted.add(perm); 6924 } 6925 } 6926 6927 final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS; 6928 if (trimCount <= 0) return false; 6929 6930 Collections.sort(persisted, new UriPermission.PersistedTimeComparator()); 6931 for (int i = 0; i < trimCount; i++) { 6932 final UriPermission perm = persisted.get(i); 6933 6934 if (DEBUG_URI_PERMISSION) { 6935 Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime); 6936 } 6937 6938 perm.releasePersistableModes(~0); 6939 removeUriPermissionIfNeededLocked(perm); 6940 } 6941 6942 return true; 6943 } 6944 6945 @Override 6946 public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions( 6947 String packageName, boolean incoming) { 6948 enforceNotIsolatedCaller("getPersistedUriPermissions"); 6949 Preconditions.checkNotNull(packageName, "packageName"); 6950 6951 final int callingUid = Binder.getCallingUid(); 6952 final IPackageManager pm = AppGlobals.getPackageManager(); 6953 try { 6954 final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid)); 6955 if (packageUid != callingUid) { 6956 throw new SecurityException( 6957 "Package " + packageName + " does not belong to calling UID " + callingUid); 6958 } 6959 } catch (RemoteException e) { 6960 throw new SecurityException("Failed to verify package name ownership"); 6961 } 6962 6963 final ArrayList<android.content.UriPermission> result = Lists.newArrayList(); 6964 synchronized (this) { 6965 if (incoming) { 6966 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get( 6967 callingUid); 6968 if (perms == null) { 6969 Slog.w(TAG, "No permission grants found for " + packageName); 6970 } else { 6971 for (UriPermission perm : perms.values()) { 6972 if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) { 6973 result.add(perm.buildPersistedPublicApiObject()); 6974 } 6975 } 6976 } 6977 } else { 6978 final int size = mGrantedUriPermissions.size(); 6979 for (int i = 0; i < size; i++) { 6980 final ArrayMap<GrantUri, UriPermission> perms = 6981 mGrantedUriPermissions.valueAt(i); 6982 for (UriPermission perm : perms.values()) { 6983 if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) { 6984 result.add(perm.buildPersistedPublicApiObject()); 6985 } 6986 } 6987 } 6988 } 6989 } 6990 return new ParceledListSlice<android.content.UriPermission>(result); 6991 } 6992 6993 @Override 6994 public void showWaitingForDebugger(IApplicationThread who, boolean waiting) { 6995 synchronized (this) { 6996 ProcessRecord app = 6997 who != null ? getRecordForAppLocked(who) : null; 6998 if (app == null) return; 6999 7000 Message msg = Message.obtain(); 7001 msg.what = WAIT_FOR_DEBUGGER_MSG; 7002 msg.obj = app; 7003 msg.arg1 = waiting ? 1 : 0; 7004 mHandler.sendMessage(msg); 7005 } 7006 } 7007 7008 @Override 7009 public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) { 7010 final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ); 7011 final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ); 7012 outInfo.availMem = Process.getFreeMemory(); 7013 outInfo.totalMem = Process.getTotalMemory(); 7014 outInfo.threshold = homeAppMem; 7015 outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2)); 7016 outInfo.hiddenAppThreshold = cachedAppMem; 7017 outInfo.secondaryServerThreshold = mProcessList.getMemLevel( 7018 ProcessList.SERVICE_ADJ); 7019 outInfo.visibleAppThreshold = mProcessList.getMemLevel( 7020 ProcessList.VISIBLE_APP_ADJ); 7021 outInfo.foregroundAppThreshold = mProcessList.getMemLevel( 7022 ProcessList.FOREGROUND_APP_ADJ); 7023 } 7024 7025 // ========================================================= 7026 // TASK MANAGEMENT 7027 // ========================================================= 7028 7029 @Override 7030 public List<IAppTask> getAppTasks() { 7031 int callingUid = Binder.getCallingUid(); 7032 long ident = Binder.clearCallingIdentity(); 7033 synchronized(this) { 7034 ArrayList<IAppTask> list = new ArrayList<IAppTask>(); 7035 try { 7036 if (localLOGV) Slog.v(TAG, "getAppTasks"); 7037 7038 final int N = mRecentTasks.size(); 7039 for (int i = 0; i < N; i++) { 7040 TaskRecord tr = mRecentTasks.get(i); 7041 // Skip tasks that are not created by the caller 7042 if (tr.creatorUid == callingUid) { 7043 ActivityManager.RecentTaskInfo taskInfo = 7044 createRecentTaskInfoFromTaskRecord(tr); 7045 AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid); 7046 list.add(taskImpl); 7047 } 7048 } 7049 } finally { 7050 Binder.restoreCallingIdentity(ident); 7051 } 7052 return list; 7053 } 7054 } 7055 7056 @Override 7057 public List<RunningTaskInfo> getTasks(int maxNum, int flags) { 7058 final int callingUid = Binder.getCallingUid(); 7059 ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>(); 7060 7061 synchronized(this) { 7062 if (localLOGV) Slog.v( 7063 TAG, "getTasks: max=" + maxNum + ", flags=" + flags); 7064 7065 final boolean allowed = checkCallingPermission( 7066 android.Manifest.permission.GET_TASKS) 7067 == PackageManager.PERMISSION_GRANTED; 7068 if (!allowed) { 7069 Slog.w(TAG, "getTasks: caller " + callingUid 7070 + " does not hold GET_TASKS; limiting output"); 7071 } 7072 7073 // TODO: Improve with MRU list from all ActivityStacks. 7074 mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed); 7075 } 7076 7077 return list; 7078 } 7079 7080 TaskRecord getMostRecentTask() { 7081 return mRecentTasks.get(0); 7082 } 7083 7084 /** 7085 * Creates a new RecentTaskInfo from a TaskRecord. 7086 */ 7087 private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) { 7088 ActivityManager.RecentTaskInfo rti 7089 = new ActivityManager.RecentTaskInfo(); 7090 rti.id = tr.mActivities.isEmpty() ? -1 : tr.taskId; 7091 rti.persistentId = tr.taskId; 7092 rti.baseIntent = new Intent(tr.getBaseIntent()); 7093 rti.origActivity = tr.origActivity; 7094 rti.description = tr.lastDescription; 7095 rti.stackId = tr.stack != null ? tr.stack.mStackId : -1; 7096 rti.userId = tr.userId; 7097 rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription); 7098 return rti; 7099 } 7100 7101 @Override 7102 public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, 7103 int flags, int userId) { 7104 final int callingUid = Binder.getCallingUid(); 7105 userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId, 7106 false, true, "getRecentTasks", null); 7107 7108 synchronized (this) { 7109 final boolean allowed = checkCallingPermission( 7110 android.Manifest.permission.GET_TASKS) 7111 == PackageManager.PERMISSION_GRANTED; 7112 if (!allowed) { 7113 Slog.w(TAG, "getRecentTasks: caller " + callingUid 7114 + " does not hold GET_TASKS; limiting output"); 7115 } 7116 final boolean detailed = checkCallingPermission( 7117 android.Manifest.permission.GET_DETAILED_TASKS) 7118 == PackageManager.PERMISSION_GRANTED; 7119 7120 IPackageManager pm = AppGlobals.getPackageManager(); 7121 7122 final int N = mRecentTasks.size(); 7123 ArrayList<ActivityManager.RecentTaskInfo> res 7124 = new ArrayList<ActivityManager.RecentTaskInfo>( 7125 maxNum < N ? maxNum : N); 7126 7127 final Set<Integer> includedUsers; 7128 if ((flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0) { 7129 includedUsers = getProfileIdsLocked(userId); 7130 } else { 7131 includedUsers = new HashSet<Integer>(); 7132 } 7133 includedUsers.add(Integer.valueOf(userId)); 7134 for (int i=0; i<N && maxNum > 0; i++) { 7135 TaskRecord tr = mRecentTasks.get(i); 7136 // Only add calling user or related users recent tasks 7137 if (!includedUsers.contains(Integer.valueOf(tr.userId))) continue; 7138 7139 // Return the entry if desired by the caller. We always return 7140 // the first entry, because callers always expect this to be the 7141 // foreground app. We may filter others if the caller has 7142 // not supplied RECENT_WITH_EXCLUDED and there is some reason 7143 // we should exclude the entry. 7144 7145 if (i == 0 7146 || ((flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0) 7147 || (tr.intent == null) 7148 || ((tr.intent.getFlags() 7149 &Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0)) { 7150 if (!allowed) { 7151 // If the caller doesn't have the GET_TASKS permission, then only 7152 // allow them to see a small subset of tasks -- their own and home. 7153 if (!tr.isHomeTask() && tr.creatorUid != callingUid) { 7154 continue; 7155 } 7156 } 7157 7158 ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr); 7159 if (!detailed) { 7160 rti.baseIntent.replaceExtras((Bundle)null); 7161 } 7162 7163 if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) { 7164 // Check whether this activity is currently available. 7165 try { 7166 if (rti.origActivity != null) { 7167 if (pm.getActivityInfo(rti.origActivity, 0, userId) 7168 == null) { 7169 continue; 7170 } 7171 } else if (rti.baseIntent != null) { 7172 if (pm.queryIntentActivities(rti.baseIntent, 7173 null, 0, userId) == null) { 7174 continue; 7175 } 7176 } 7177 } catch (RemoteException e) { 7178 // Will never happen. 7179 } 7180 } 7181 7182 res.add(rti); 7183 maxNum--; 7184 } 7185 } 7186 return res; 7187 } 7188 } 7189 7190 private TaskRecord recentTaskForIdLocked(int id) { 7191 final int N = mRecentTasks.size(); 7192 for (int i=0; i<N; i++) { 7193 TaskRecord tr = mRecentTasks.get(i); 7194 if (tr.taskId == id) { 7195 return tr; 7196 } 7197 } 7198 return null; 7199 } 7200 7201 @Override 7202 public ActivityManager.TaskThumbnails getTaskThumbnails(int id) { 7203 synchronized (this) { 7204 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER, 7205 "getTaskThumbnails()"); 7206 TaskRecord tr = recentTaskForIdLocked(id); 7207 if (tr != null) { 7208 return tr.getTaskThumbnailsLocked(); 7209 } 7210 } 7211 return null; 7212 } 7213 7214 @Override 7215 public Bitmap getTaskTopThumbnail(int id) { 7216 synchronized (this) { 7217 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER, 7218 "getTaskTopThumbnail()"); 7219 TaskRecord tr = recentTaskForIdLocked(id); 7220 if (tr != null) { 7221 return tr.getTaskTopThumbnailLocked(); 7222 } 7223 } 7224 return null; 7225 } 7226 7227 @Override 7228 public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) { 7229 synchronized (this) { 7230 ActivityRecord r = ActivityRecord.isInStackLocked(token); 7231 if (r != null) { 7232 r.taskDescription = td; 7233 r.task.updateTaskDescription(); 7234 } 7235 } 7236 } 7237 7238 @Override 7239 public boolean removeSubTask(int taskId, int subTaskIndex) { 7240 synchronized (this) { 7241 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, 7242 "removeSubTask()"); 7243 long ident = Binder.clearCallingIdentity(); 7244 try { 7245 TaskRecord tr = recentTaskForIdLocked(taskId); 7246 if (tr != null) { 7247 return tr.removeTaskActivitiesLocked(subTaskIndex, true) != null; 7248 } 7249 return false; 7250 } finally { 7251 Binder.restoreCallingIdentity(ident); 7252 } 7253 } 7254 } 7255 7256 private void killUnneededProcessLocked(ProcessRecord pr, String reason) { 7257 if (!pr.killedByAm) { 7258 Slog.i(TAG, "Killing " + pr.toShortString() + " (adj " + pr.setAdj + "): " + reason); 7259 EventLog.writeEvent(EventLogTags.AM_KILL, pr.userId, pr.pid, 7260 pr.processName, pr.setAdj, reason); 7261 pr.killedByAm = true; 7262 Process.killProcessQuiet(pr.pid); 7263 } 7264 } 7265 7266 private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) { 7267 tr.disposeThumbnail(); 7268 mRecentTasks.remove(tr); 7269 final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0; 7270 Intent baseIntent = new Intent( 7271 tr.intent != null ? tr.intent : tr.affinityIntent); 7272 ComponentName component = baseIntent.getComponent(); 7273 if (component == null) { 7274 Slog.w(TAG, "Now component for base intent of task: " + tr); 7275 return; 7276 } 7277 7278 // Find any running services associated with this app. 7279 mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent); 7280 7281 if (killProcesses) { 7282 // Find any running processes associated with this app. 7283 final String pkg = component.getPackageName(); 7284 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 7285 ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap(); 7286 for (int i=0; i<pmap.size(); i++) { 7287 SparseArray<ProcessRecord> uids = pmap.valueAt(i); 7288 for (int j=0; j<uids.size(); j++) { 7289 ProcessRecord proc = uids.valueAt(j); 7290 if (proc.userId != tr.userId) { 7291 continue; 7292 } 7293 if (!proc.pkgList.containsKey(pkg)) { 7294 continue; 7295 } 7296 procs.add(proc); 7297 } 7298 } 7299 7300 // Kill the running processes. 7301 for (int i=0; i<procs.size(); i++) { 7302 ProcessRecord pr = procs.get(i); 7303 if (pr == mHomeProcess) { 7304 // Don't kill the home process along with tasks from the same package. 7305 continue; 7306 } 7307 if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 7308 killUnneededProcessLocked(pr, "remove task"); 7309 } else { 7310 pr.waitingToKill = "remove task"; 7311 } 7312 } 7313 } 7314 } 7315 7316 /** 7317 * Removes the task with the specified task id. 7318 * 7319 * @param taskId Identifier of the task to be removed. 7320 * @param flags Additional operational flags. May be 0 or 7321 * {@link ActivityManager#REMOVE_TASK_KILL_PROCESS}. 7322 * @return Returns true if the given task was found and removed. 7323 */ 7324 private boolean removeTaskByIdLocked(int taskId, int flags) { 7325 TaskRecord tr = recentTaskForIdLocked(taskId); 7326 if (tr != null) { 7327 tr.removeTaskActivitiesLocked(-1, false); 7328 cleanUpRemovedTaskLocked(tr, flags); 7329 if (tr.isPersistable) { 7330 notifyTaskPersisterLocked(tr, true); 7331 } 7332 return true; 7333 } 7334 return false; 7335 } 7336 7337 @Override 7338 public boolean removeTask(int taskId, int flags) { 7339 synchronized (this) { 7340 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, 7341 "removeTask()"); 7342 long ident = Binder.clearCallingIdentity(); 7343 try { 7344 return removeTaskByIdLocked(taskId, flags); 7345 } finally { 7346 Binder.restoreCallingIdentity(ident); 7347 } 7348 } 7349 } 7350 7351 /** 7352 * TODO: Add mController hook 7353 */ 7354 @Override 7355 public void moveTaskToFront(int taskId, int flags, Bundle options) { 7356 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 7357 "moveTaskToFront()"); 7358 7359 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId); 7360 synchronized(this) { 7361 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 7362 Binder.getCallingUid(), "Task to front")) { 7363 ActivityOptions.abort(options); 7364 return; 7365 } 7366 final long origId = Binder.clearCallingIdentity(); 7367 try { 7368 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId); 7369 if (task == null) { 7370 return; 7371 } 7372 if (mStackSupervisor.isLockTaskModeViolation(task)) { 7373 Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode"); 7374 return; 7375 } 7376 mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options); 7377 } finally { 7378 Binder.restoreCallingIdentity(origId); 7379 } 7380 ActivityOptions.abort(options); 7381 } 7382 } 7383 7384 @Override 7385 public void moveTaskToBack(int taskId) { 7386 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 7387 "moveTaskToBack()"); 7388 7389 synchronized(this) { 7390 TaskRecord tr = recentTaskForIdLocked(taskId); 7391 if (tr != null) { 7392 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr); 7393 ActivityStack stack = tr.stack; 7394 if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) { 7395 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 7396 Binder.getCallingUid(), "Task to back")) { 7397 return; 7398 } 7399 } 7400 final long origId = Binder.clearCallingIdentity(); 7401 try { 7402 stack.moveTaskToBackLocked(taskId, null); 7403 } finally { 7404 Binder.restoreCallingIdentity(origId); 7405 } 7406 } 7407 } 7408 } 7409 7410 /** 7411 * Moves an activity, and all of the other activities within the same task, to the bottom 7412 * of the history stack. The activity's order within the task is unchanged. 7413 * 7414 * @param token A reference to the activity we wish to move 7415 * @param nonRoot If false then this only works if the activity is the root 7416 * of a task; if true it will work for any activity in a task. 7417 * @return Returns true if the move completed, false if not. 7418 */ 7419 @Override 7420 public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) { 7421 enforceNotIsolatedCaller("moveActivityTaskToBack"); 7422 synchronized(this) { 7423 final long origId = Binder.clearCallingIdentity(); 7424 int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot); 7425 if (taskId >= 0) { 7426 return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null); 7427 } 7428 Binder.restoreCallingIdentity(origId); 7429 } 7430 return false; 7431 } 7432 7433 @Override 7434 public void moveTaskBackwards(int task) { 7435 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 7436 "moveTaskBackwards()"); 7437 7438 synchronized(this) { 7439 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 7440 Binder.getCallingUid(), "Task backwards")) { 7441 return; 7442 } 7443 final long origId = Binder.clearCallingIdentity(); 7444 moveTaskBackwardsLocked(task); 7445 Binder.restoreCallingIdentity(origId); 7446 } 7447 } 7448 7449 private final void moveTaskBackwardsLocked(int task) { 7450 Slog.e(TAG, "moveTaskBackwards not yet implemented!"); 7451 } 7452 7453 @Override 7454 public IBinder getHomeActivityToken() throws RemoteException { 7455 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7456 "getHomeActivityToken()"); 7457 synchronized (this) { 7458 return mStackSupervisor.getHomeActivityToken(); 7459 } 7460 } 7461 7462 @Override 7463 public IActivityContainer createActivityContainer(IBinder parentActivityToken, 7464 IActivityContainerCallback callback) throws RemoteException { 7465 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7466 "createActivityContainer()"); 7467 synchronized (this) { 7468 if (parentActivityToken == null) { 7469 throw new IllegalArgumentException("parent token must not be null"); 7470 } 7471 ActivityRecord r = ActivityRecord.forToken(parentActivityToken); 7472 if (r == null) { 7473 return null; 7474 } 7475 if (callback == null) { 7476 throw new IllegalArgumentException("callback must not be null"); 7477 } 7478 return mStackSupervisor.createActivityContainer(r, callback); 7479 } 7480 } 7481 7482 @Override 7483 public void deleteActivityContainer(IActivityContainer container) throws RemoteException { 7484 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7485 "deleteActivityContainer()"); 7486 synchronized (this) { 7487 mStackSupervisor.deleteActivityContainer(container); 7488 } 7489 } 7490 7491 @Override 7492 public IActivityContainer getEnclosingActivityContainer(IBinder activityToken) 7493 throws RemoteException { 7494 synchronized (this) { 7495 ActivityStack stack = ActivityRecord.getStackLocked(activityToken); 7496 if (stack != null) { 7497 return stack.mActivityContainer; 7498 } 7499 return null; 7500 } 7501 } 7502 7503 @Override 7504 public void moveTaskToStack(int taskId, int stackId, boolean toTop) { 7505 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7506 "moveTaskToStack()"); 7507 if (stackId == HOME_STACK_ID) { 7508 Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack", 7509 new RuntimeException("here").fillInStackTrace()); 7510 } 7511 synchronized (this) { 7512 long ident = Binder.clearCallingIdentity(); 7513 try { 7514 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId=" 7515 + stackId + " toTop=" + toTop); 7516 mStackSupervisor.moveTaskToStack(taskId, stackId, toTop); 7517 } finally { 7518 Binder.restoreCallingIdentity(ident); 7519 } 7520 } 7521 } 7522 7523 @Override 7524 public void resizeStack(int stackBoxId, Rect bounds) { 7525 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7526 "resizeStackBox()"); 7527 long ident = Binder.clearCallingIdentity(); 7528 try { 7529 mWindowManager.resizeStack(stackBoxId, bounds); 7530 } finally { 7531 Binder.restoreCallingIdentity(ident); 7532 } 7533 } 7534 7535 @Override 7536 public List<StackInfo> getAllStackInfos() { 7537 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7538 "getAllStackInfos()"); 7539 long ident = Binder.clearCallingIdentity(); 7540 try { 7541 synchronized (this) { 7542 return mStackSupervisor.getAllStackInfosLocked(); 7543 } 7544 } finally { 7545 Binder.restoreCallingIdentity(ident); 7546 } 7547 } 7548 7549 @Override 7550 public StackInfo getStackInfo(int stackId) { 7551 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7552 "getStackInfo()"); 7553 long ident = Binder.clearCallingIdentity(); 7554 try { 7555 synchronized (this) { 7556 return mStackSupervisor.getStackInfoLocked(stackId); 7557 } 7558 } finally { 7559 Binder.restoreCallingIdentity(ident); 7560 } 7561 } 7562 7563 @Override 7564 public boolean isInHomeStack(int taskId) { 7565 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7566 "getStackInfo()"); 7567 long ident = Binder.clearCallingIdentity(); 7568 try { 7569 synchronized (this) { 7570 TaskRecord tr = recentTaskForIdLocked(taskId); 7571 return tr != null && tr.stack != null && tr.stack.isHomeStack(); 7572 } 7573 } finally { 7574 Binder.restoreCallingIdentity(ident); 7575 } 7576 } 7577 7578 @Override 7579 public int getTaskForActivity(IBinder token, boolean onlyRoot) { 7580 synchronized(this) { 7581 return ActivityRecord.getTaskForActivityLocked(token, onlyRoot); 7582 } 7583 } 7584 7585 private boolean isLockTaskAuthorized(ComponentName name) { 7586 final DevicePolicyManager dpm = (DevicePolicyManager) 7587 mContext.getSystemService(Context.DEVICE_POLICY_SERVICE); 7588 return dpm != null && dpm.isLockTaskPermitted(name); 7589 } 7590 7591 private void startLockTaskMode(TaskRecord task) { 7592 if (!isLockTaskAuthorized(task.intent.getComponent())) { 7593 return; 7594 } 7595 long ident = Binder.clearCallingIdentity(); 7596 try { 7597 synchronized (this) { 7598 // Since we lost lock on task, make sure it is still there. 7599 task = mStackSupervisor.anyTaskForIdLocked(task.taskId); 7600 if (task != null) { 7601 mStackSupervisor.setLockTaskModeLocked(task); 7602 } 7603 } 7604 } finally { 7605 Binder.restoreCallingIdentity(ident); 7606 } 7607 } 7608 7609 @Override 7610 public void startLockTaskMode(int taskId) { 7611 long ident = Binder.clearCallingIdentity(); 7612 try { 7613 final TaskRecord task; 7614 synchronized (this) { 7615 task = mStackSupervisor.anyTaskForIdLocked(taskId); 7616 } 7617 if (task != null) { 7618 startLockTaskMode(task); 7619 } 7620 } finally { 7621 Binder.restoreCallingIdentity(ident); 7622 } 7623 } 7624 7625 @Override 7626 public void startLockTaskMode(IBinder token) { 7627 long ident = Binder.clearCallingIdentity(); 7628 try { 7629 final TaskRecord task; 7630 synchronized (this) { 7631 final ActivityRecord r = ActivityRecord.forToken(token); 7632 if (r == null) { 7633 return; 7634 } 7635 task = r.task; 7636 } 7637 if (task != null) { 7638 startLockTaskMode(task); 7639 } 7640 } finally { 7641 Binder.restoreCallingIdentity(ident); 7642 } 7643 } 7644 7645 @Override 7646 public void stopLockTaskMode() { 7647 // Check if the calling task is eligible to use lock task 7648 final int uid = Binder.getCallingUid(); 7649 try { 7650 final String name = AppGlobals.getPackageManager().getNameForUid(uid); 7651 if (!isLockTaskAuthorized(new ComponentName(name, name))) { 7652 return; 7653 } 7654 } catch (RemoteException e) { 7655 Log.d(TAG, "stopLockTaskMode " + e); 7656 return; 7657 } 7658 // Stop lock task 7659 synchronized (this) { 7660 mStackSupervisor.setLockTaskModeLocked(null); 7661 } 7662 } 7663 7664 @Override 7665 public boolean isInLockTaskMode() { 7666 synchronized (this) { 7667 return mStackSupervisor.isInLockTaskMode(); 7668 } 7669 } 7670 7671 // ========================================================= 7672 // CONTENT PROVIDERS 7673 // ========================================================= 7674 7675 private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) { 7676 List<ProviderInfo> providers = null; 7677 try { 7678 providers = AppGlobals.getPackageManager(). 7679 queryContentProviders(app.processName, app.uid, 7680 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS); 7681 } catch (RemoteException ex) { 7682 } 7683 if (DEBUG_MU) 7684 Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid); 7685 int userId = app.userId; 7686 if (providers != null) { 7687 int N = providers.size(); 7688 app.pubProviders.ensureCapacity(N + app.pubProviders.size()); 7689 for (int i=0; i<N; i++) { 7690 ProviderInfo cpi = 7691 (ProviderInfo)providers.get(i); 7692 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo, 7693 cpi.name, cpi.flags); 7694 if (singleton && UserHandle.getUserId(app.uid) != 0) { 7695 // This is a singleton provider, but a user besides the 7696 // default user is asking to initialize a process it runs 7697 // in... well, no, it doesn't actually run in this process, 7698 // it runs in the process of the default user. Get rid of it. 7699 providers.remove(i); 7700 N--; 7701 i--; 7702 continue; 7703 } 7704 7705 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 7706 ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId); 7707 if (cpr == null) { 7708 cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton); 7709 mProviderMap.putProviderByClass(comp, cpr); 7710 } 7711 if (DEBUG_MU) 7712 Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid); 7713 app.pubProviders.put(cpi.name, cpr); 7714 if (!cpi.multiprocess || !"android".equals(cpi.packageName)) { 7715 // Don't add this if it is a platform component that is marked 7716 // to run in multiple processes, because this is actually 7717 // part of the framework so doesn't make sense to track as a 7718 // separate apk in the process. 7719 app.addPackage(cpi.applicationInfo.packageName, mProcessStats); 7720 } 7721 ensurePackageDexOpt(cpi.applicationInfo.packageName); 7722 } 7723 } 7724 return providers; 7725 } 7726 7727 /** 7728 * Check if {@link ProcessRecord} has a possible chance at accessing the 7729 * given {@link ProviderInfo}. Final permission checking is always done 7730 * in {@link ContentProvider}. 7731 */ 7732 private final String checkContentProviderPermissionLocked( 7733 ProviderInfo cpi, ProcessRecord r, int userId) { 7734 final int callingPid = (r != null) ? r.pid : Binder.getCallingPid(); 7735 final int callingUid = (r != null) ? r.uid : Binder.getCallingUid(); 7736 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid); 7737 // Looking for cross-user grants before to enforce the typical cross-users permissions 7738 if (userId != UserHandle.getUserId(callingUid)) { 7739 if (perms != null) { 7740 for (GrantUri grantUri : perms.keySet()) { 7741 if (grantUri.sourceUserId == userId) { 7742 String authority = grantUri.uri.getAuthority(); 7743 if (authority.equals(cpi.authority)) { 7744 return null; 7745 } 7746 } 7747 } 7748 } 7749 } 7750 userId = handleIncomingUser(callingPid, callingUid, userId, 7751 false, true, "checkContentProviderPermissionLocked", null); 7752 if (checkComponentPermission(cpi.readPermission, callingPid, callingUid, 7753 cpi.applicationInfo.uid, cpi.exported) 7754 == PackageManager.PERMISSION_GRANTED) { 7755 return null; 7756 } 7757 if (checkComponentPermission(cpi.writePermission, callingPid, callingUid, 7758 cpi.applicationInfo.uid, cpi.exported) 7759 == PackageManager.PERMISSION_GRANTED) { 7760 return null; 7761 } 7762 7763 PathPermission[] pps = cpi.pathPermissions; 7764 if (pps != null) { 7765 int i = pps.length; 7766 while (i > 0) { 7767 i--; 7768 PathPermission pp = pps[i]; 7769 if (checkComponentPermission(pp.getReadPermission(), callingPid, callingUid, 7770 cpi.applicationInfo.uid, cpi.exported) 7771 == PackageManager.PERMISSION_GRANTED) { 7772 return null; 7773 } 7774 if (checkComponentPermission(pp.getWritePermission(), callingPid, callingUid, 7775 cpi.applicationInfo.uid, cpi.exported) 7776 == PackageManager.PERMISSION_GRANTED) { 7777 return null; 7778 } 7779 } 7780 } 7781 7782 if (perms != null) { 7783 for (GrantUri grantUri : perms.keySet()) { 7784 if (grantUri.uri.getAuthority().equals(cpi.authority)) { 7785 return null; 7786 } 7787 } 7788 } 7789 7790 String msg; 7791 if (!cpi.exported) { 7792 msg = "Permission Denial: opening provider " + cpi.name 7793 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 7794 + ", uid=" + callingUid + ") that is not exported from uid " 7795 + cpi.applicationInfo.uid; 7796 } else { 7797 msg = "Permission Denial: opening provider " + cpi.name 7798 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 7799 + ", uid=" + callingUid + ") requires " 7800 + cpi.readPermission + " or " + cpi.writePermission; 7801 } 7802 Slog.w(TAG, msg); 7803 return msg; 7804 } 7805 7806 ContentProviderConnection incProviderCountLocked(ProcessRecord r, 7807 final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 7808 if (r != null) { 7809 for (int i=0; i<r.conProviders.size(); i++) { 7810 ContentProviderConnection conn = r.conProviders.get(i); 7811 if (conn.provider == cpr) { 7812 if (DEBUG_PROVIDER) Slog.v(TAG, 7813 "Adding provider requested by " 7814 + r.processName + " from process " 7815 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 7816 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 7817 if (stable) { 7818 conn.stableCount++; 7819 conn.numStableIncs++; 7820 } else { 7821 conn.unstableCount++; 7822 conn.numUnstableIncs++; 7823 } 7824 return conn; 7825 } 7826 } 7827 ContentProviderConnection conn = new ContentProviderConnection(cpr, r); 7828 if (stable) { 7829 conn.stableCount = 1; 7830 conn.numStableIncs = 1; 7831 } else { 7832 conn.unstableCount = 1; 7833 conn.numUnstableIncs = 1; 7834 } 7835 cpr.connections.add(conn); 7836 r.conProviders.add(conn); 7837 return conn; 7838 } 7839 cpr.addExternalProcessHandleLocked(externalProcessToken); 7840 return null; 7841 } 7842 7843 boolean decProviderCountLocked(ContentProviderConnection conn, 7844 ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 7845 if (conn != null) { 7846 cpr = conn.provider; 7847 if (DEBUG_PROVIDER) Slog.v(TAG, 7848 "Removing provider requested by " 7849 + conn.client.processName + " from process " 7850 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 7851 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 7852 if (stable) { 7853 conn.stableCount--; 7854 } else { 7855 conn.unstableCount--; 7856 } 7857 if (conn.stableCount == 0 && conn.unstableCount == 0) { 7858 cpr.connections.remove(conn); 7859 conn.client.conProviders.remove(conn); 7860 return true; 7861 } 7862 return false; 7863 } 7864 cpr.removeExternalProcessHandleLocked(externalProcessToken); 7865 return false; 7866 } 7867 7868 private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller, 7869 String name, IBinder token, boolean stable, int userId) { 7870 ContentProviderRecord cpr; 7871 ContentProviderConnection conn = null; 7872 ProviderInfo cpi = null; 7873 7874 synchronized(this) { 7875 ProcessRecord r = null; 7876 if (caller != null) { 7877 r = getRecordForAppLocked(caller); 7878 if (r == null) { 7879 throw new SecurityException( 7880 "Unable to find app for caller " + caller 7881 + " (pid=" + Binder.getCallingPid() 7882 + ") when getting content provider " + name); 7883 } 7884 } 7885 7886 // First check if this content provider has been published... 7887 cpr = mProviderMap.getProviderByName(name, userId); 7888 boolean providerRunning = cpr != null; 7889 if (providerRunning) { 7890 cpi = cpr.info; 7891 String msg; 7892 if ((msg=checkContentProviderPermissionLocked(cpi, r, userId)) != null) { 7893 throw new SecurityException(msg); 7894 } 7895 7896 if (r != null && cpr.canRunHere(r)) { 7897 // This provider has been published or is in the process 7898 // of being published... but it is also allowed to run 7899 // in the caller's process, so don't make a connection 7900 // and just let the caller instantiate its own instance. 7901 ContentProviderHolder holder = cpr.newHolder(null); 7902 // don't give caller the provider object, it needs 7903 // to make its own. 7904 holder.provider = null; 7905 return holder; 7906 } 7907 7908 final long origId = Binder.clearCallingIdentity(); 7909 7910 // In this case the provider instance already exists, so we can 7911 // return it right away. 7912 conn = incProviderCountLocked(r, cpr, token, stable); 7913 if (conn != null && (conn.stableCount+conn.unstableCount) == 1) { 7914 if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 7915 // If this is a perceptible app accessing the provider, 7916 // make sure to count it as being accessed and thus 7917 // back up on the LRU list. This is good because 7918 // content providers are often expensive to start. 7919 updateLruProcessLocked(cpr.proc, false, null); 7920 } 7921 } 7922 7923 if (cpr.proc != null) { 7924 if (false) { 7925 if (cpr.name.flattenToShortString().equals( 7926 "com.android.providers.calendar/.CalendarProvider2")) { 7927 Slog.v(TAG, "****************** KILLING " 7928 + cpr.name.flattenToShortString()); 7929 Process.killProcess(cpr.proc.pid); 7930 } 7931 } 7932 boolean success = updateOomAdjLocked(cpr.proc); 7933 if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success); 7934 // NOTE: there is still a race here where a signal could be 7935 // pending on the process even though we managed to update its 7936 // adj level. Not sure what to do about this, but at least 7937 // the race is now smaller. 7938 if (!success) { 7939 // Uh oh... it looks like the provider's process 7940 // has been killed on us. We need to wait for a new 7941 // process to be started, and make sure its death 7942 // doesn't kill our process. 7943 Slog.i(TAG, 7944 "Existing provider " + cpr.name.flattenToShortString() 7945 + " is crashing; detaching " + r); 7946 boolean lastRef = decProviderCountLocked(conn, cpr, token, stable); 7947 appDiedLocked(cpr.proc, cpr.proc.pid, cpr.proc.thread); 7948 if (!lastRef) { 7949 // This wasn't the last ref our process had on 7950 // the provider... we have now been killed, bail. 7951 return null; 7952 } 7953 providerRunning = false; 7954 conn = null; 7955 } 7956 } 7957 7958 Binder.restoreCallingIdentity(origId); 7959 } 7960 7961 boolean singleton; 7962 if (!providerRunning) { 7963 try { 7964 cpi = AppGlobals.getPackageManager(). 7965 resolveContentProvider(name, 7966 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId); 7967 } catch (RemoteException ex) { 7968 } 7969 if (cpi == null) { 7970 return null; 7971 } 7972 singleton = isSingleton(cpi.processName, cpi.applicationInfo, 7973 cpi.name, cpi.flags); 7974 if (singleton) { 7975 userId = 0; 7976 } 7977 cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId); 7978 7979 String msg; 7980 if ((msg=checkContentProviderPermissionLocked(cpi, r, userId)) != null) { 7981 throw new SecurityException(msg); 7982 } 7983 7984 if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate 7985 && !cpi.processName.equals("system")) { 7986 // If this content provider does not run in the system 7987 // process, and the system is not yet ready to run other 7988 // processes, then fail fast instead of hanging. 7989 throw new IllegalArgumentException( 7990 "Attempt to launch content provider before system ready"); 7991 } 7992 7993 // Make sure that the user who owns this provider is started. If not, 7994 // we don't want to allow it to run. 7995 if (mStartedUsers.get(userId) == null) { 7996 Slog.w(TAG, "Unable to launch app " 7997 + cpi.applicationInfo.packageName + "/" 7998 + cpi.applicationInfo.uid + " for provider " 7999 + name + ": user " + userId + " is stopped"); 8000 return null; 8001 } 8002 8003 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 8004 cpr = mProviderMap.getProviderByClass(comp, userId); 8005 final boolean firstClass = cpr == null; 8006 if (firstClass) { 8007 try { 8008 ApplicationInfo ai = 8009 AppGlobals.getPackageManager(). 8010 getApplicationInfo( 8011 cpi.applicationInfo.packageName, 8012 STOCK_PM_FLAGS, userId); 8013 if (ai == null) { 8014 Slog.w(TAG, "No package info for content provider " 8015 + cpi.name); 8016 return null; 8017 } 8018 ai = getAppInfoForUser(ai, userId); 8019 cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton); 8020 } catch (RemoteException ex) { 8021 // pm is in same process, this will never happen. 8022 } 8023 } 8024 8025 if (r != null && cpr.canRunHere(r)) { 8026 // If this is a multiprocess provider, then just return its 8027 // info and allow the caller to instantiate it. Only do 8028 // this if the provider is the same user as the caller's 8029 // process, or can run as root (so can be in any process). 8030 return cpr.newHolder(null); 8031 } 8032 8033 if (DEBUG_PROVIDER) { 8034 RuntimeException e = new RuntimeException("here"); 8035 Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null) 8036 + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e); 8037 } 8038 8039 // This is single process, and our app is now connecting to it. 8040 // See if we are already in the process of launching this 8041 // provider. 8042 final int N = mLaunchingProviders.size(); 8043 int i; 8044 for (i=0; i<N; i++) { 8045 if (mLaunchingProviders.get(i) == cpr) { 8046 break; 8047 } 8048 } 8049 8050 // If the provider is not already being launched, then get it 8051 // started. 8052 if (i >= N) { 8053 final long origId = Binder.clearCallingIdentity(); 8054 8055 try { 8056 // Content provider is now in use, its package can't be stopped. 8057 try { 8058 AppGlobals.getPackageManager().setPackageStoppedState( 8059 cpr.appInfo.packageName, false, userId); 8060 } catch (RemoteException e) { 8061 } catch (IllegalArgumentException e) { 8062 Slog.w(TAG, "Failed trying to unstop package " 8063 + cpr.appInfo.packageName + ": " + e); 8064 } 8065 8066 // Use existing process if already started 8067 ProcessRecord proc = getProcessRecordLocked( 8068 cpi.processName, cpr.appInfo.uid, false); 8069 if (proc != null && proc.thread != null) { 8070 if (DEBUG_PROVIDER) { 8071 Slog.d(TAG, "Installing in existing process " + proc); 8072 } 8073 proc.pubProviders.put(cpi.name, cpr); 8074 try { 8075 proc.thread.scheduleInstallProvider(cpi); 8076 } catch (RemoteException e) { 8077 } 8078 } else { 8079 proc = startProcessLocked(cpi.processName, 8080 cpr.appInfo, false, 0, "content provider", 8081 new ComponentName(cpi.applicationInfo.packageName, 8082 cpi.name), false, false, false); 8083 if (proc == null) { 8084 Slog.w(TAG, "Unable to launch app " 8085 + cpi.applicationInfo.packageName + "/" 8086 + cpi.applicationInfo.uid + " for provider " 8087 + name + ": process is bad"); 8088 return null; 8089 } 8090 } 8091 cpr.launchingApp = proc; 8092 mLaunchingProviders.add(cpr); 8093 } finally { 8094 Binder.restoreCallingIdentity(origId); 8095 } 8096 } 8097 8098 // Make sure the provider is published (the same provider class 8099 // may be published under multiple names). 8100 if (firstClass) { 8101 mProviderMap.putProviderByClass(comp, cpr); 8102 } 8103 8104 mProviderMap.putProviderByName(name, cpr); 8105 conn = incProviderCountLocked(r, cpr, token, stable); 8106 if (conn != null) { 8107 conn.waiting = true; 8108 } 8109 } 8110 } 8111 8112 // Wait for the provider to be published... 8113 synchronized (cpr) { 8114 while (cpr.provider == null) { 8115 if (cpr.launchingApp == null) { 8116 Slog.w(TAG, "Unable to launch app " 8117 + cpi.applicationInfo.packageName + "/" 8118 + cpi.applicationInfo.uid + " for provider " 8119 + name + ": launching app became null"); 8120 EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS, 8121 UserHandle.getUserId(cpi.applicationInfo.uid), 8122 cpi.applicationInfo.packageName, 8123 cpi.applicationInfo.uid, name); 8124 return null; 8125 } 8126 try { 8127 if (DEBUG_MU) { 8128 Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp=" 8129 + cpr.launchingApp); 8130 } 8131 if (conn != null) { 8132 conn.waiting = true; 8133 } 8134 cpr.wait(); 8135 } catch (InterruptedException ex) { 8136 } finally { 8137 if (conn != null) { 8138 conn.waiting = false; 8139 } 8140 } 8141 } 8142 } 8143 return cpr != null ? cpr.newHolder(conn) : null; 8144 } 8145 8146 @Override 8147 public final ContentProviderHolder getContentProvider( 8148 IApplicationThread caller, String name, int userId, boolean stable) { 8149 enforceNotIsolatedCaller("getContentProvider"); 8150 if (caller == null) { 8151 String msg = "null IApplicationThread when getting content provider " 8152 + name; 8153 Slog.w(TAG, msg); 8154 throw new SecurityException(msg); 8155 } 8156 // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal 8157 // with cross-user grant. 8158 return getContentProviderImpl(caller, name, null, stable, userId); 8159 } 8160 8161 public ContentProviderHolder getContentProviderExternal( 8162 String name, int userId, IBinder token) { 8163 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 8164 "Do not have permission in call getContentProviderExternal()"); 8165 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 8166 false, true, "getContentProvider", null); 8167 return getContentProviderExternalUnchecked(name, token, userId); 8168 } 8169 8170 private ContentProviderHolder getContentProviderExternalUnchecked(String name, 8171 IBinder token, int userId) { 8172 return getContentProviderImpl(null, name, token, true, userId); 8173 } 8174 8175 /** 8176 * Drop a content provider from a ProcessRecord's bookkeeping 8177 */ 8178 public void removeContentProvider(IBinder connection, boolean stable) { 8179 enforceNotIsolatedCaller("removeContentProvider"); 8180 long ident = Binder.clearCallingIdentity(); 8181 try { 8182 synchronized (this) { 8183 ContentProviderConnection conn; 8184 try { 8185 conn = (ContentProviderConnection)connection; 8186 } catch (ClassCastException e) { 8187 String msg ="removeContentProvider: " + connection 8188 + " not a ContentProviderConnection"; 8189 Slog.w(TAG, msg); 8190 throw new IllegalArgumentException(msg); 8191 } 8192 if (conn == null) { 8193 throw new NullPointerException("connection is null"); 8194 } 8195 if (decProviderCountLocked(conn, null, null, stable)) { 8196 updateOomAdjLocked(); 8197 } 8198 } 8199 } finally { 8200 Binder.restoreCallingIdentity(ident); 8201 } 8202 } 8203 8204 public void removeContentProviderExternal(String name, IBinder token) { 8205 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 8206 "Do not have permission in call removeContentProviderExternal()"); 8207 removeContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId()); 8208 } 8209 8210 private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) { 8211 synchronized (this) { 8212 ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId); 8213 if(cpr == null) { 8214 //remove from mProvidersByClass 8215 if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list"); 8216 return; 8217 } 8218 8219 //update content provider record entry info 8220 ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name); 8221 ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId); 8222 if (localCpr.hasExternalProcessHandles()) { 8223 if (localCpr.removeExternalProcessHandleLocked(token)) { 8224 updateOomAdjLocked(); 8225 } else { 8226 Slog.e(TAG, "Attmpt to remove content provider " + localCpr 8227 + " with no external reference for token: " 8228 + token + "."); 8229 } 8230 } else { 8231 Slog.e(TAG, "Attmpt to remove content provider: " + localCpr 8232 + " with no external references."); 8233 } 8234 } 8235 } 8236 8237 public final void publishContentProviders(IApplicationThread caller, 8238 List<ContentProviderHolder> providers) { 8239 if (providers == null) { 8240 return; 8241 } 8242 8243 enforceNotIsolatedCaller("publishContentProviders"); 8244 synchronized (this) { 8245 final ProcessRecord r = getRecordForAppLocked(caller); 8246 if (DEBUG_MU) 8247 Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid); 8248 if (r == null) { 8249 throw new SecurityException( 8250 "Unable to find app for caller " + caller 8251 + " (pid=" + Binder.getCallingPid() 8252 + ") when publishing content providers"); 8253 } 8254 8255 final long origId = Binder.clearCallingIdentity(); 8256 8257 final int N = providers.size(); 8258 for (int i=0; i<N; i++) { 8259 ContentProviderHolder src = providers.get(i); 8260 if (src == null || src.info == null || src.provider == null) { 8261 continue; 8262 } 8263 ContentProviderRecord dst = r.pubProviders.get(src.info.name); 8264 if (DEBUG_MU) 8265 Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid); 8266 if (dst != null) { 8267 ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name); 8268 mProviderMap.putProviderByClass(comp, dst); 8269 String names[] = dst.info.authority.split(";"); 8270 for (int j = 0; j < names.length; j++) { 8271 mProviderMap.putProviderByName(names[j], dst); 8272 } 8273 8274 int NL = mLaunchingProviders.size(); 8275 int j; 8276 for (j=0; j<NL; j++) { 8277 if (mLaunchingProviders.get(j) == dst) { 8278 mLaunchingProviders.remove(j); 8279 j--; 8280 NL--; 8281 } 8282 } 8283 synchronized (dst) { 8284 dst.provider = src.provider; 8285 dst.proc = r; 8286 dst.notifyAll(); 8287 } 8288 updateOomAdjLocked(r); 8289 } 8290 } 8291 8292 Binder.restoreCallingIdentity(origId); 8293 } 8294 } 8295 8296 public boolean refContentProvider(IBinder connection, int stable, int unstable) { 8297 ContentProviderConnection conn; 8298 try { 8299 conn = (ContentProviderConnection)connection; 8300 } catch (ClassCastException e) { 8301 String msg ="refContentProvider: " + connection 8302 + " not a ContentProviderConnection"; 8303 Slog.w(TAG, msg); 8304 throw new IllegalArgumentException(msg); 8305 } 8306 if (conn == null) { 8307 throw new NullPointerException("connection is null"); 8308 } 8309 8310 synchronized (this) { 8311 if (stable > 0) { 8312 conn.numStableIncs += stable; 8313 } 8314 stable = conn.stableCount + stable; 8315 if (stable < 0) { 8316 throw new IllegalStateException("stableCount < 0: " + stable); 8317 } 8318 8319 if (unstable > 0) { 8320 conn.numUnstableIncs += unstable; 8321 } 8322 unstable = conn.unstableCount + unstable; 8323 if (unstable < 0) { 8324 throw new IllegalStateException("unstableCount < 0: " + unstable); 8325 } 8326 8327 if ((stable+unstable) <= 0) { 8328 throw new IllegalStateException("ref counts can't go to zero here: stable=" 8329 + stable + " unstable=" + unstable); 8330 } 8331 conn.stableCount = stable; 8332 conn.unstableCount = unstable; 8333 return !conn.dead; 8334 } 8335 } 8336 8337 public void unstableProviderDied(IBinder connection) { 8338 ContentProviderConnection conn; 8339 try { 8340 conn = (ContentProviderConnection)connection; 8341 } catch (ClassCastException e) { 8342 String msg ="refContentProvider: " + connection 8343 + " not a ContentProviderConnection"; 8344 Slog.w(TAG, msg); 8345 throw new IllegalArgumentException(msg); 8346 } 8347 if (conn == null) { 8348 throw new NullPointerException("connection is null"); 8349 } 8350 8351 // Safely retrieve the content provider associated with the connection. 8352 IContentProvider provider; 8353 synchronized (this) { 8354 provider = conn.provider.provider; 8355 } 8356 8357 if (provider == null) { 8358 // Um, yeah, we're way ahead of you. 8359 return; 8360 } 8361 8362 // Make sure the caller is being honest with us. 8363 if (provider.asBinder().pingBinder()) { 8364 // Er, no, still looks good to us. 8365 synchronized (this) { 8366 Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid() 8367 + " says " + conn + " died, but we don't agree"); 8368 return; 8369 } 8370 } 8371 8372 // Well look at that! It's dead! 8373 synchronized (this) { 8374 if (conn.provider.provider != provider) { 8375 // But something changed... good enough. 8376 return; 8377 } 8378 8379 ProcessRecord proc = conn.provider.proc; 8380 if (proc == null || proc.thread == null) { 8381 // Seems like the process is already cleaned up. 8382 return; 8383 } 8384 8385 // As far as we're concerned, this is just like receiving a 8386 // death notification... just a bit prematurely. 8387 Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid 8388 + ") early provider death"); 8389 final long ident = Binder.clearCallingIdentity(); 8390 try { 8391 appDiedLocked(proc, proc.pid, proc.thread); 8392 } finally { 8393 Binder.restoreCallingIdentity(ident); 8394 } 8395 } 8396 } 8397 8398 @Override 8399 public void appNotRespondingViaProvider(IBinder connection) { 8400 enforceCallingPermission( 8401 android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()"); 8402 8403 final ContentProviderConnection conn = (ContentProviderConnection) connection; 8404 if (conn == null) { 8405 Slog.w(TAG, "ContentProviderConnection is null"); 8406 return; 8407 } 8408 8409 final ProcessRecord host = conn.provider.proc; 8410 if (host == null) { 8411 Slog.w(TAG, "Failed to find hosting ProcessRecord"); 8412 return; 8413 } 8414 8415 final long token = Binder.clearCallingIdentity(); 8416 try { 8417 appNotResponding(host, null, null, false, "ContentProvider not responding"); 8418 } finally { 8419 Binder.restoreCallingIdentity(token); 8420 } 8421 } 8422 8423 public final void installSystemProviders() { 8424 List<ProviderInfo> providers; 8425 synchronized (this) { 8426 ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID); 8427 providers = generateApplicationProvidersLocked(app); 8428 if (providers != null) { 8429 for (int i=providers.size()-1; i>=0; i--) { 8430 ProviderInfo pi = (ProviderInfo)providers.get(i); 8431 if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) { 8432 Slog.w(TAG, "Not installing system proc provider " + pi.name 8433 + ": not system .apk"); 8434 providers.remove(i); 8435 } 8436 } 8437 } 8438 } 8439 if (providers != null) { 8440 mSystemThread.installSystemProviders(providers); 8441 } 8442 8443 mCoreSettingsObserver = new CoreSettingsObserver(this); 8444 8445 mUsageStatsService.monitorPackages(); 8446 } 8447 8448 /** 8449 * Allows app to retrieve the MIME type of a URI without having permission 8450 * to access its content provider. 8451 * 8452 * CTS tests for this functionality can be run with "runtest cts-appsecurity". 8453 * 8454 * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/ 8455 * src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java 8456 */ 8457 public String getProviderMimeType(Uri uri, int userId) { 8458 enforceNotIsolatedCaller("getProviderMimeType"); 8459 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 8460 userId, false, true, "getProviderMimeType", null); 8461 final String name = uri.getAuthority(); 8462 final long ident = Binder.clearCallingIdentity(); 8463 ContentProviderHolder holder = null; 8464 8465 try { 8466 holder = getContentProviderExternalUnchecked(name, null, userId); 8467 if (holder != null) { 8468 return holder.provider.getType(uri); 8469 } 8470 } catch (RemoteException e) { 8471 Log.w(TAG, "Content provider dead retrieving " + uri, e); 8472 return null; 8473 } finally { 8474 if (holder != null) { 8475 removeContentProviderExternalUnchecked(name, null, userId); 8476 } 8477 Binder.restoreCallingIdentity(ident); 8478 } 8479 8480 return null; 8481 } 8482 8483 // ========================================================= 8484 // GLOBAL MANAGEMENT 8485 // ========================================================= 8486 8487 final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess, 8488 boolean isolated) { 8489 String proc = customProcess != null ? customProcess : info.processName; 8490 BatteryStatsImpl.Uid.Proc ps = null; 8491 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 8492 int uid = info.uid; 8493 if (isolated) { 8494 int userId = UserHandle.getUserId(uid); 8495 int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1; 8496 while (true) { 8497 if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID 8498 || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) { 8499 mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID; 8500 } 8501 uid = UserHandle.getUid(userId, mNextIsolatedProcessUid); 8502 mNextIsolatedProcessUid++; 8503 if (mIsolatedProcesses.indexOfKey(uid) < 0) { 8504 // No process for this uid, use it. 8505 break; 8506 } 8507 stepsLeft--; 8508 if (stepsLeft <= 0) { 8509 return null; 8510 } 8511 } 8512 } 8513 return new ProcessRecord(stats, info, proc, uid); 8514 } 8515 8516 final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated) { 8517 ProcessRecord app; 8518 if (!isolated) { 8519 app = getProcessRecordLocked(info.processName, info.uid, true); 8520 } else { 8521 app = null; 8522 } 8523 8524 if (app == null) { 8525 app = newProcessRecordLocked(info, null, isolated); 8526 mProcessNames.put(info.processName, app.uid, app); 8527 if (isolated) { 8528 mIsolatedProcesses.put(app.uid, app); 8529 } 8530 updateLruProcessLocked(app, false, null); 8531 updateOomAdjLocked(); 8532 } 8533 8534 // This package really, really can not be stopped. 8535 try { 8536 AppGlobals.getPackageManager().setPackageStoppedState( 8537 info.packageName, false, UserHandle.getUserId(app.uid)); 8538 } catch (RemoteException e) { 8539 } catch (IllegalArgumentException e) { 8540 Slog.w(TAG, "Failed trying to unstop package " 8541 + info.packageName + ": " + e); 8542 } 8543 8544 if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) 8545 == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) { 8546 app.persistent = true; 8547 app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ; 8548 } 8549 if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) { 8550 mPersistentStartingProcesses.add(app); 8551 startProcessLocked(app, "added application", app.processName); 8552 } 8553 8554 return app; 8555 } 8556 8557 public void unhandledBack() { 8558 enforceCallingPermission(android.Manifest.permission.FORCE_BACK, 8559 "unhandledBack()"); 8560 8561 synchronized(this) { 8562 final long origId = Binder.clearCallingIdentity(); 8563 try { 8564 getFocusedStack().unhandledBackLocked(); 8565 } finally { 8566 Binder.restoreCallingIdentity(origId); 8567 } 8568 } 8569 } 8570 8571 public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException { 8572 enforceNotIsolatedCaller("openContentUri"); 8573 final int userId = UserHandle.getCallingUserId(); 8574 String name = uri.getAuthority(); 8575 ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId); 8576 ParcelFileDescriptor pfd = null; 8577 if (cph != null) { 8578 // We record the binder invoker's uid in thread-local storage before 8579 // going to the content provider to open the file. Later, in the code 8580 // that handles all permissions checks, we look for this uid and use 8581 // that rather than the Activity Manager's own uid. The effect is that 8582 // we do the check against the caller's permissions even though it looks 8583 // to the content provider like the Activity Manager itself is making 8584 // the request. 8585 sCallerIdentity.set(new Identity( 8586 Binder.getCallingPid(), Binder.getCallingUid())); 8587 try { 8588 pfd = cph.provider.openFile(null, uri, "r", null); 8589 } catch (FileNotFoundException e) { 8590 // do nothing; pfd will be returned null 8591 } finally { 8592 // Ensure that whatever happens, we clean up the identity state 8593 sCallerIdentity.remove(); 8594 } 8595 8596 // We've got the fd now, so we're done with the provider. 8597 removeContentProviderExternalUnchecked(name, null, userId); 8598 } else { 8599 Slog.d(TAG, "Failed to get provider for authority '" + name + "'"); 8600 } 8601 return pfd; 8602 } 8603 8604 // Actually is sleeping or shutting down or whatever else in the future 8605 // is an inactive state. 8606 public boolean isSleepingOrShuttingDown() { 8607 return mSleeping || mShuttingDown; 8608 } 8609 8610 public boolean isSleeping() { 8611 return mSleeping; 8612 } 8613 8614 void goingToSleep() { 8615 synchronized(this) { 8616 mWentToSleep = true; 8617 updateEventDispatchingLocked(); 8618 goToSleepIfNeededLocked(); 8619 } 8620 } 8621 8622 void finishRunningVoiceLocked() { 8623 if (mRunningVoice) { 8624 mRunningVoice = false; 8625 goToSleepIfNeededLocked(); 8626 } 8627 } 8628 8629 void goToSleepIfNeededLocked() { 8630 if (mWentToSleep && !mRunningVoice) { 8631 if (!mSleeping) { 8632 mSleeping = true; 8633 mStackSupervisor.goingToSleepLocked(); 8634 8635 // Initialize the wake times of all processes. 8636 checkExcessivePowerUsageLocked(false); 8637 mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 8638 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 8639 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 8640 } 8641 } 8642 } 8643 8644 void notifyTaskPersisterLocked(TaskRecord task, boolean flush) { 8645 mTaskPersister.notify(task, flush); 8646 } 8647 8648 @Override 8649 public boolean shutdown(int timeout) { 8650 if (checkCallingPermission(android.Manifest.permission.SHUTDOWN) 8651 != PackageManager.PERMISSION_GRANTED) { 8652 throw new SecurityException("Requires permission " 8653 + android.Manifest.permission.SHUTDOWN); 8654 } 8655 8656 boolean timedout = false; 8657 8658 synchronized(this) { 8659 mShuttingDown = true; 8660 updateEventDispatchingLocked(); 8661 timedout = mStackSupervisor.shutdownLocked(timeout); 8662 } 8663 8664 mAppOpsService.shutdown(); 8665 mUsageStatsService.shutdown(); 8666 mBatteryStatsService.shutdown(); 8667 synchronized (this) { 8668 mProcessStats.shutdownLocked(); 8669 } 8670 notifyTaskPersisterLocked(null, true); 8671 8672 return timedout; 8673 } 8674 8675 public final void activitySlept(IBinder token) { 8676 if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token); 8677 8678 final long origId = Binder.clearCallingIdentity(); 8679 8680 synchronized (this) { 8681 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 8682 if (r != null) { 8683 mStackSupervisor.activitySleptLocked(r); 8684 } 8685 } 8686 8687 Binder.restoreCallingIdentity(origId); 8688 } 8689 8690 void logLockScreen(String msg) { 8691 if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg + 8692 " mLockScreenShown=" + mLockScreenShown + " mWentToSleep=" + 8693 mWentToSleep + " mSleeping=" + mSleeping + " mDismissKeyguardOnNextActivity=" + 8694 mStackSupervisor.mDismissKeyguardOnNextActivity); 8695 } 8696 8697 private void comeOutOfSleepIfNeededLocked() { 8698 if ((!mWentToSleep && !mLockScreenShown) || mRunningVoice) { 8699 if (mSleeping) { 8700 mSleeping = false; 8701 mStackSupervisor.comeOutOfSleepIfNeededLocked(); 8702 } 8703 } 8704 } 8705 8706 void wakingUp() { 8707 synchronized(this) { 8708 mWentToSleep = false; 8709 updateEventDispatchingLocked(); 8710 comeOutOfSleepIfNeededLocked(); 8711 } 8712 } 8713 8714 void startRunningVoiceLocked() { 8715 if (!mRunningVoice) { 8716 mRunningVoice = true; 8717 comeOutOfSleepIfNeededLocked(); 8718 } 8719 } 8720 8721 private void updateEventDispatchingLocked() { 8722 mWindowManager.setEventDispatching(mBooted && !mWentToSleep && !mShuttingDown); 8723 } 8724 8725 public void setLockScreenShown(boolean shown) { 8726 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER) 8727 != PackageManager.PERMISSION_GRANTED) { 8728 throw new SecurityException("Requires permission " 8729 + android.Manifest.permission.DEVICE_POWER); 8730 } 8731 8732 synchronized(this) { 8733 long ident = Binder.clearCallingIdentity(); 8734 try { 8735 if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown); 8736 mLockScreenShown = shown; 8737 comeOutOfSleepIfNeededLocked(); 8738 } finally { 8739 Binder.restoreCallingIdentity(ident); 8740 } 8741 } 8742 } 8743 8744 public void stopAppSwitches() { 8745 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 8746 != PackageManager.PERMISSION_GRANTED) { 8747 throw new SecurityException("Requires permission " 8748 + android.Manifest.permission.STOP_APP_SWITCHES); 8749 } 8750 8751 synchronized(this) { 8752 mAppSwitchesAllowedTime = SystemClock.uptimeMillis() 8753 + APP_SWITCH_DELAY_TIME; 8754 mDidAppSwitch = false; 8755 mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 8756 Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 8757 mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME); 8758 } 8759 } 8760 8761 public void resumeAppSwitches() { 8762 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 8763 != PackageManager.PERMISSION_GRANTED) { 8764 throw new SecurityException("Requires permission " 8765 + android.Manifest.permission.STOP_APP_SWITCHES); 8766 } 8767 8768 synchronized(this) { 8769 // Note that we don't execute any pending app switches... we will 8770 // let those wait until either the timeout, or the next start 8771 // activity request. 8772 mAppSwitchesAllowedTime = 0; 8773 } 8774 } 8775 8776 boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid, 8777 String name) { 8778 if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) { 8779 return true; 8780 } 8781 8782 final int perm = checkComponentPermission( 8783 android.Manifest.permission.STOP_APP_SWITCHES, callingPid, 8784 callingUid, -1, true); 8785 if (perm == PackageManager.PERMISSION_GRANTED) { 8786 return true; 8787 } 8788 8789 Slog.w(TAG, name + " request from " + callingUid + " stopped"); 8790 return false; 8791 } 8792 8793 public void setDebugApp(String packageName, boolean waitForDebugger, 8794 boolean persistent) { 8795 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP, 8796 "setDebugApp()"); 8797 8798 long ident = Binder.clearCallingIdentity(); 8799 try { 8800 // Note that this is not really thread safe if there are multiple 8801 // callers into it at the same time, but that's not a situation we 8802 // care about. 8803 if (persistent) { 8804 final ContentResolver resolver = mContext.getContentResolver(); 8805 Settings.Global.putString( 8806 resolver, Settings.Global.DEBUG_APP, 8807 packageName); 8808 Settings.Global.putInt( 8809 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 8810 waitForDebugger ? 1 : 0); 8811 } 8812 8813 synchronized (this) { 8814 if (!persistent) { 8815 mOrigDebugApp = mDebugApp; 8816 mOrigWaitForDebugger = mWaitForDebugger; 8817 } 8818 mDebugApp = packageName; 8819 mWaitForDebugger = waitForDebugger; 8820 mDebugTransient = !persistent; 8821 if (packageName != null) { 8822 forceStopPackageLocked(packageName, -1, false, false, true, true, 8823 false, UserHandle.USER_ALL, "set debug app"); 8824 } 8825 } 8826 } finally { 8827 Binder.restoreCallingIdentity(ident); 8828 } 8829 } 8830 8831 void setOpenGlTraceApp(ApplicationInfo app, String processName) { 8832 synchronized (this) { 8833 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 8834 if (!isDebuggable) { 8835 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 8836 throw new SecurityException("Process not debuggable: " + app.packageName); 8837 } 8838 } 8839 8840 mOpenGlTraceApp = processName; 8841 } 8842 } 8843 8844 void setProfileApp(ApplicationInfo app, String processName, String profileFile, 8845 ParcelFileDescriptor profileFd, boolean autoStopProfiler) { 8846 synchronized (this) { 8847 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 8848 if (!isDebuggable) { 8849 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 8850 throw new SecurityException("Process not debuggable: " + app.packageName); 8851 } 8852 } 8853 mProfileApp = processName; 8854 mProfileFile = profileFile; 8855 if (mProfileFd != null) { 8856 try { 8857 mProfileFd.close(); 8858 } catch (IOException e) { 8859 } 8860 mProfileFd = null; 8861 } 8862 mProfileFd = profileFd; 8863 mProfileType = 0; 8864 mAutoStopProfiler = autoStopProfiler; 8865 } 8866 } 8867 8868 @Override 8869 public void setAlwaysFinish(boolean enabled) { 8870 enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH, 8871 "setAlwaysFinish()"); 8872 8873 Settings.Global.putInt( 8874 mContext.getContentResolver(), 8875 Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0); 8876 8877 synchronized (this) { 8878 mAlwaysFinishActivities = enabled; 8879 } 8880 } 8881 8882 @Override 8883 public void setActivityController(IActivityController controller) { 8884 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 8885 "setActivityController()"); 8886 synchronized (this) { 8887 mController = controller; 8888 Watchdog.getInstance().setActivityController(controller); 8889 } 8890 } 8891 8892 @Override 8893 public void setUserIsMonkey(boolean userIsMonkey) { 8894 synchronized (this) { 8895 synchronized (mPidsSelfLocked) { 8896 final int callingPid = Binder.getCallingPid(); 8897 ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid); 8898 if (precessRecord == null) { 8899 throw new SecurityException("Unknown process: " + callingPid); 8900 } 8901 if (precessRecord.instrumentationUiAutomationConnection == null) { 8902 throw new SecurityException("Only an instrumentation process " 8903 + "with a UiAutomation can call setUserIsMonkey"); 8904 } 8905 } 8906 mUserIsMonkey = userIsMonkey; 8907 } 8908 } 8909 8910 @Override 8911 public boolean isUserAMonkey() { 8912 synchronized (this) { 8913 // If there is a controller also implies the user is a monkey. 8914 return (mUserIsMonkey || mController != null); 8915 } 8916 } 8917 8918 public void requestBugReport() { 8919 enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport"); 8920 SystemProperties.set("ctl.start", "bugreport"); 8921 } 8922 8923 public static long getInputDispatchingTimeoutLocked(ActivityRecord r) { 8924 return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT; 8925 } 8926 8927 public static long getInputDispatchingTimeoutLocked(ProcessRecord r) { 8928 if (r != null && (r.instrumentationClass != null || r.usingWrapper)) { 8929 return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT; 8930 } 8931 return KEY_DISPATCHING_TIMEOUT; 8932 } 8933 8934 @Override 8935 public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) { 8936 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS) 8937 != PackageManager.PERMISSION_GRANTED) { 8938 throw new SecurityException("Requires permission " 8939 + android.Manifest.permission.FILTER_EVENTS); 8940 } 8941 ProcessRecord proc; 8942 long timeout; 8943 synchronized (this) { 8944 synchronized (mPidsSelfLocked) { 8945 proc = mPidsSelfLocked.get(pid); 8946 } 8947 timeout = getInputDispatchingTimeoutLocked(proc); 8948 } 8949 8950 if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) { 8951 return -1; 8952 } 8953 8954 return timeout; 8955 } 8956 8957 /** 8958 * Handle input dispatching timeouts. 8959 * Returns whether input dispatching should be aborted or not. 8960 */ 8961 public boolean inputDispatchingTimedOut(final ProcessRecord proc, 8962 final ActivityRecord activity, final ActivityRecord parent, 8963 final boolean aboveSystem, String reason) { 8964 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS) 8965 != PackageManager.PERMISSION_GRANTED) { 8966 throw new SecurityException("Requires permission " 8967 + android.Manifest.permission.FILTER_EVENTS); 8968 } 8969 8970 final String annotation; 8971 if (reason == null) { 8972 annotation = "Input dispatching timed out"; 8973 } else { 8974 annotation = "Input dispatching timed out (" + reason + ")"; 8975 } 8976 8977 if (proc != null) { 8978 synchronized (this) { 8979 if (proc.debugging) { 8980 return false; 8981 } 8982 8983 if (mDidDexOpt) { 8984 // Give more time since we were dexopting. 8985 mDidDexOpt = false; 8986 return false; 8987 } 8988 8989 if (proc.instrumentationClass != null) { 8990 Bundle info = new Bundle(); 8991 info.putString("shortMsg", "keyDispatchingTimedOut"); 8992 info.putString("longMsg", annotation); 8993 finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info); 8994 return true; 8995 } 8996 } 8997 mHandler.post(new Runnable() { 8998 @Override 8999 public void run() { 9000 appNotResponding(proc, activity, parent, aboveSystem, annotation); 9001 } 9002 }); 9003 } 9004 9005 return true; 9006 } 9007 9008 public Bundle getAssistContextExtras(int requestType) { 9009 enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO, 9010 "getAssistContextExtras()"); 9011 PendingAssistExtras pae; 9012 Bundle extras = new Bundle(); 9013 synchronized (this) { 9014 ActivityRecord activity = getFocusedStack().mResumedActivity; 9015 if (activity == null) { 9016 Slog.w(TAG, "getAssistContextExtras failed: no resumed activity"); 9017 return null; 9018 } 9019 extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName); 9020 if (activity.app == null || activity.app.thread == null) { 9021 Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity); 9022 return extras; 9023 } 9024 if (activity.app.pid == Binder.getCallingPid()) { 9025 Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity); 9026 return extras; 9027 } 9028 pae = new PendingAssistExtras(activity); 9029 try { 9030 activity.app.thread.requestAssistContextExtras(activity.appToken, pae, 9031 requestType); 9032 mPendingAssistExtras.add(pae); 9033 mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT); 9034 } catch (RemoteException e) { 9035 Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity); 9036 return extras; 9037 } 9038 } 9039 synchronized (pae) { 9040 while (!pae.haveResult) { 9041 try { 9042 pae.wait(); 9043 } catch (InterruptedException e) { 9044 } 9045 } 9046 if (pae.result != null) { 9047 extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result); 9048 } 9049 } 9050 synchronized (this) { 9051 mPendingAssistExtras.remove(pae); 9052 mHandler.removeCallbacks(pae); 9053 } 9054 return extras; 9055 } 9056 9057 public void reportAssistContextExtras(IBinder token, Bundle extras) { 9058 PendingAssistExtras pae = (PendingAssistExtras)token; 9059 synchronized (pae) { 9060 pae.result = extras; 9061 pae.haveResult = true; 9062 pae.notifyAll(); 9063 } 9064 } 9065 9066 public void registerProcessObserver(IProcessObserver observer) { 9067 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 9068 "registerProcessObserver()"); 9069 synchronized (this) { 9070 mProcessObservers.register(observer); 9071 } 9072 } 9073 9074 @Override 9075 public void unregisterProcessObserver(IProcessObserver observer) { 9076 synchronized (this) { 9077 mProcessObservers.unregister(observer); 9078 } 9079 } 9080 9081 @Override 9082 public boolean convertFromTranslucent(IBinder token) { 9083 final long origId = Binder.clearCallingIdentity(); 9084 try { 9085 synchronized (this) { 9086 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 9087 if (r == null) { 9088 return false; 9089 } 9090 if (r.changeWindowTranslucency(true)) { 9091 mWindowManager.setAppFullscreen(token, true); 9092 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 9093 return true; 9094 } 9095 return false; 9096 } 9097 } finally { 9098 Binder.restoreCallingIdentity(origId); 9099 } 9100 } 9101 9102 @Override 9103 public boolean convertToTranslucent(IBinder token, ActivityOptions options) { 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(false)) { 9112 r.task.stack.convertToTranslucent(r, options); 9113 mWindowManager.setAppFullscreen(token, false); 9114 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 9115 return true; 9116 } 9117 return false; 9118 } 9119 } finally { 9120 Binder.restoreCallingIdentity(origId); 9121 } 9122 } 9123 9124 @Override 9125 public ActivityOptions getActivityOptions(IBinder token) { 9126 final long origId = Binder.clearCallingIdentity(); 9127 try { 9128 synchronized (this) { 9129 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 9130 if (r != null) { 9131 final ActivityOptions activityOptions = r.pendingOptions; 9132 r.pendingOptions = null; 9133 return activityOptions; 9134 } 9135 return null; 9136 } 9137 } finally { 9138 Binder.restoreCallingIdentity(origId); 9139 } 9140 } 9141 9142 @Override 9143 public void setImmersive(IBinder token, boolean immersive) { 9144 synchronized(this) { 9145 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 9146 if (r == null) { 9147 throw new IllegalArgumentException(); 9148 } 9149 r.immersive = immersive; 9150 9151 // update associated state if we're frontmost 9152 if (r == mFocusedActivity) { 9153 if (DEBUG_IMMERSIVE) { 9154 Slog.d(TAG, "Frontmost changed immersion: "+ r); 9155 } 9156 applyUpdateLockStateLocked(r); 9157 } 9158 } 9159 } 9160 9161 @Override 9162 public boolean isImmersive(IBinder token) { 9163 synchronized (this) { 9164 ActivityRecord r = ActivityRecord.isInStackLocked(token); 9165 if (r == null) { 9166 throw new IllegalArgumentException(); 9167 } 9168 return r.immersive; 9169 } 9170 } 9171 9172 public boolean isTopActivityImmersive() { 9173 enforceNotIsolatedCaller("startActivity"); 9174 synchronized (this) { 9175 ActivityRecord r = getFocusedStack().topRunningActivityLocked(null); 9176 return (r != null) ? r.immersive : false; 9177 } 9178 } 9179 9180 public final void enterSafeMode() { 9181 synchronized(this) { 9182 // It only makes sense to do this before the system is ready 9183 // and started launching other packages. 9184 if (!mSystemReady) { 9185 try { 9186 AppGlobals.getPackageManager().enterSafeMode(); 9187 } catch (RemoteException e) { 9188 } 9189 } 9190 9191 mSafeMode = true; 9192 } 9193 } 9194 9195 public final void showSafeModeOverlay() { 9196 View v = LayoutInflater.from(mContext).inflate( 9197 com.android.internal.R.layout.safe_mode, null); 9198 WindowManager.LayoutParams lp = new WindowManager.LayoutParams(); 9199 lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY; 9200 lp.width = WindowManager.LayoutParams.WRAP_CONTENT; 9201 lp.height = WindowManager.LayoutParams.WRAP_CONTENT; 9202 lp.gravity = Gravity.BOTTOM | Gravity.START; 9203 lp.format = v.getBackground().getOpacity(); 9204 lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE 9205 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE; 9206 lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS; 9207 ((WindowManager)mContext.getSystemService( 9208 Context.WINDOW_SERVICE)).addView(v, lp); 9209 } 9210 9211 public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) { 9212 if (!(sender instanceof PendingIntentRecord)) { 9213 return; 9214 } 9215 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 9216 synchronized (stats) { 9217 if (mBatteryStatsService.isOnBattery()) { 9218 mBatteryStatsService.enforceCallingPermission(); 9219 PendingIntentRecord rec = (PendingIntentRecord)sender; 9220 int MY_UID = Binder.getCallingUid(); 9221 int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid; 9222 BatteryStatsImpl.Uid.Pkg pkg = 9223 stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid, 9224 sourcePkg != null ? sourcePkg : rec.key.packageName); 9225 pkg.incWakeupsLocked(); 9226 } 9227 } 9228 } 9229 9230 public boolean killPids(int[] pids, String pReason, boolean secure) { 9231 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 9232 throw new SecurityException("killPids only available to the system"); 9233 } 9234 String reason = (pReason == null) ? "Unknown" : pReason; 9235 // XXX Note: don't acquire main activity lock here, because the window 9236 // manager calls in with its locks held. 9237 9238 boolean killed = false; 9239 synchronized (mPidsSelfLocked) { 9240 int[] types = new int[pids.length]; 9241 int worstType = 0; 9242 for (int i=0; i<pids.length; i++) { 9243 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 9244 if (proc != null) { 9245 int type = proc.setAdj; 9246 types[i] = type; 9247 if (type > worstType) { 9248 worstType = type; 9249 } 9250 } 9251 } 9252 9253 // If the worst oom_adj is somewhere in the cached proc LRU range, 9254 // then constrain it so we will kill all cached procs. 9255 if (worstType < ProcessList.CACHED_APP_MAX_ADJ 9256 && worstType > ProcessList.CACHED_APP_MIN_ADJ) { 9257 worstType = ProcessList.CACHED_APP_MIN_ADJ; 9258 } 9259 9260 // If this is not a secure call, don't let it kill processes that 9261 // are important. 9262 if (!secure && worstType < ProcessList.SERVICE_ADJ) { 9263 worstType = ProcessList.SERVICE_ADJ; 9264 } 9265 9266 Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType); 9267 for (int i=0; i<pids.length; i++) { 9268 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 9269 if (proc == null) { 9270 continue; 9271 } 9272 int adj = proc.setAdj; 9273 if (adj >= worstType && !proc.killedByAm) { 9274 killUnneededProcessLocked(proc, reason); 9275 killed = true; 9276 } 9277 } 9278 } 9279 return killed; 9280 } 9281 9282 @Override 9283 public void killUid(int uid, String reason) { 9284 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 9285 throw new SecurityException("killUid only available to the system"); 9286 } 9287 synchronized (this) { 9288 killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid), 9289 ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false, 9290 reason != null ? reason : "kill uid"); 9291 } 9292 } 9293 9294 @Override 9295 public boolean killProcessesBelowForeground(String reason) { 9296 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 9297 throw new SecurityException("killProcessesBelowForeground() only available to system"); 9298 } 9299 9300 return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason); 9301 } 9302 9303 private boolean killProcessesBelowAdj(int belowAdj, String reason) { 9304 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 9305 throw new SecurityException("killProcessesBelowAdj() only available to system"); 9306 } 9307 9308 boolean killed = false; 9309 synchronized (mPidsSelfLocked) { 9310 final int size = mPidsSelfLocked.size(); 9311 for (int i = 0; i < size; i++) { 9312 final int pid = mPidsSelfLocked.keyAt(i); 9313 final ProcessRecord proc = mPidsSelfLocked.valueAt(i); 9314 if (proc == null) continue; 9315 9316 final int adj = proc.setAdj; 9317 if (adj > belowAdj && !proc.killedByAm) { 9318 killUnneededProcessLocked(proc, reason); 9319 killed = true; 9320 } 9321 } 9322 } 9323 return killed; 9324 } 9325 9326 @Override 9327 public void hang(final IBinder who, boolean allowRestart) { 9328 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 9329 != PackageManager.PERMISSION_GRANTED) { 9330 throw new SecurityException("Requires permission " 9331 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 9332 } 9333 9334 final IBinder.DeathRecipient death = new DeathRecipient() { 9335 @Override 9336 public void binderDied() { 9337 synchronized (this) { 9338 notifyAll(); 9339 } 9340 } 9341 }; 9342 9343 try { 9344 who.linkToDeath(death, 0); 9345 } catch (RemoteException e) { 9346 Slog.w(TAG, "hang: given caller IBinder is already dead."); 9347 return; 9348 } 9349 9350 synchronized (this) { 9351 Watchdog.getInstance().setAllowRestart(allowRestart); 9352 Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid()); 9353 synchronized (death) { 9354 while (who.isBinderAlive()) { 9355 try { 9356 death.wait(); 9357 } catch (InterruptedException e) { 9358 } 9359 } 9360 } 9361 Watchdog.getInstance().setAllowRestart(true); 9362 } 9363 } 9364 9365 @Override 9366 public void restart() { 9367 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 9368 != PackageManager.PERMISSION_GRANTED) { 9369 throw new SecurityException("Requires permission " 9370 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 9371 } 9372 9373 Log.i(TAG, "Sending shutdown broadcast..."); 9374 9375 BroadcastReceiver br = new BroadcastReceiver() { 9376 @Override public void onReceive(Context context, Intent intent) { 9377 // Now the broadcast is done, finish up the low-level shutdown. 9378 Log.i(TAG, "Shutting down activity manager..."); 9379 shutdown(10000); 9380 Log.i(TAG, "Shutdown complete, restarting!"); 9381 Process.killProcess(Process.myPid()); 9382 System.exit(10); 9383 } 9384 }; 9385 9386 // First send the high-level shut down broadcast. 9387 Intent intent = new Intent(Intent.ACTION_SHUTDOWN); 9388 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 9389 intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true); 9390 /* For now we are not doing a clean shutdown, because things seem to get unhappy. 9391 mContext.sendOrderedBroadcastAsUser(intent, 9392 UserHandle.ALL, null, br, mHandler, 0, null, null); 9393 */ 9394 br.onReceive(mContext, intent); 9395 } 9396 9397 private long getLowRamTimeSinceIdle(long now) { 9398 return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0); 9399 } 9400 9401 @Override 9402 public void performIdleMaintenance() { 9403 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 9404 != PackageManager.PERMISSION_GRANTED) { 9405 throw new SecurityException("Requires permission " 9406 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 9407 } 9408 9409 synchronized (this) { 9410 final long now = SystemClock.uptimeMillis(); 9411 final long timeSinceLastIdle = now - mLastIdleTime; 9412 final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now); 9413 mLastIdleTime = now; 9414 mLowRamTimeSinceLastIdle = 0; 9415 if (mLowRamStartTime != 0) { 9416 mLowRamStartTime = now; 9417 } 9418 9419 StringBuilder sb = new StringBuilder(128); 9420 sb.append("Idle maintenance over "); 9421 TimeUtils.formatDuration(timeSinceLastIdle, sb); 9422 sb.append(" low RAM for "); 9423 TimeUtils.formatDuration(lowRamSinceLastIdle, sb); 9424 Slog.i(TAG, sb.toString()); 9425 9426 // If at least 1/3 of our time since the last idle period has been spent 9427 // with RAM low, then we want to kill processes. 9428 boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3); 9429 9430 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 9431 ProcessRecord proc = mLruProcesses.get(i); 9432 if (proc.notCachedSinceIdle) { 9433 if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP 9434 && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) { 9435 if (doKilling && proc.initialIdlePss != 0 9436 && proc.lastPss > ((proc.initialIdlePss*3)/2)) { 9437 killUnneededProcessLocked(proc, "idle maint (pss " + proc.lastPss 9438 + " from " + proc.initialIdlePss + ")"); 9439 } 9440 } 9441 } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) { 9442 proc.notCachedSinceIdle = true; 9443 proc.initialIdlePss = 0; 9444 proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true, 9445 isSleeping(), now); 9446 } 9447 } 9448 9449 mHandler.removeMessages(REQUEST_ALL_PSS_MSG); 9450 mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000); 9451 } 9452 } 9453 9454 private void retrieveSettings() { 9455 final ContentResolver resolver = mContext.getContentResolver(); 9456 String debugApp = Settings.Global.getString( 9457 resolver, Settings.Global.DEBUG_APP); 9458 boolean waitForDebugger = Settings.Global.getInt( 9459 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0; 9460 boolean alwaysFinishActivities = Settings.Global.getInt( 9461 resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0; 9462 boolean forceRtl = Settings.Global.getInt( 9463 resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0; 9464 // Transfer any global setting for forcing RTL layout, into a System Property 9465 SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0"); 9466 9467 Configuration configuration = new Configuration(); 9468 Settings.System.getConfiguration(resolver, configuration); 9469 if (forceRtl) { 9470 // This will take care of setting the correct layout direction flags 9471 configuration.setLayoutDirection(configuration.locale); 9472 } 9473 9474 synchronized (this) { 9475 mDebugApp = mOrigDebugApp = debugApp; 9476 mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger; 9477 mAlwaysFinishActivities = alwaysFinishActivities; 9478 // This happens before any activities are started, so we can 9479 // change mConfiguration in-place. 9480 updateConfigurationLocked(configuration, null, false, true); 9481 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration); 9482 } 9483 } 9484 9485 public boolean testIsSystemReady() { 9486 // no need to synchronize(this) just to read & return the value 9487 return mSystemReady; 9488 } 9489 9490 private static File getCalledPreBootReceiversFile() { 9491 File dataDir = Environment.getDataDirectory(); 9492 File systemDir = new File(dataDir, "system"); 9493 File fname = new File(systemDir, "called_pre_boots.dat"); 9494 return fname; 9495 } 9496 9497 static final int LAST_DONE_VERSION = 10000; 9498 9499 private static ArrayList<ComponentName> readLastDonePreBootReceivers() { 9500 ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>(); 9501 File file = getCalledPreBootReceiversFile(); 9502 FileInputStream fis = null; 9503 try { 9504 fis = new FileInputStream(file); 9505 DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048)); 9506 int fvers = dis.readInt(); 9507 if (fvers == LAST_DONE_VERSION) { 9508 String vers = dis.readUTF(); 9509 String codename = dis.readUTF(); 9510 String build = dis.readUTF(); 9511 if (android.os.Build.VERSION.RELEASE.equals(vers) 9512 && android.os.Build.VERSION.CODENAME.equals(codename) 9513 && android.os.Build.VERSION.INCREMENTAL.equals(build)) { 9514 int num = dis.readInt(); 9515 while (num > 0) { 9516 num--; 9517 String pkg = dis.readUTF(); 9518 String cls = dis.readUTF(); 9519 lastDoneReceivers.add(new ComponentName(pkg, cls)); 9520 } 9521 } 9522 } 9523 } catch (FileNotFoundException e) { 9524 } catch (IOException e) { 9525 Slog.w(TAG, "Failure reading last done pre-boot receivers", e); 9526 } finally { 9527 if (fis != null) { 9528 try { 9529 fis.close(); 9530 } catch (IOException e) { 9531 } 9532 } 9533 } 9534 return lastDoneReceivers; 9535 } 9536 9537 private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) { 9538 File file = getCalledPreBootReceiversFile(); 9539 FileOutputStream fos = null; 9540 DataOutputStream dos = null; 9541 try { 9542 Slog.i(TAG, "Writing new set of last done pre-boot receivers..."); 9543 fos = new FileOutputStream(file); 9544 dos = new DataOutputStream(new BufferedOutputStream(fos, 2048)); 9545 dos.writeInt(LAST_DONE_VERSION); 9546 dos.writeUTF(android.os.Build.VERSION.RELEASE); 9547 dos.writeUTF(android.os.Build.VERSION.CODENAME); 9548 dos.writeUTF(android.os.Build.VERSION.INCREMENTAL); 9549 dos.writeInt(list.size()); 9550 for (int i=0; i<list.size(); i++) { 9551 dos.writeUTF(list.get(i).getPackageName()); 9552 dos.writeUTF(list.get(i).getClassName()); 9553 } 9554 } catch (IOException e) { 9555 Slog.w(TAG, "Failure writing last done pre-boot receivers", e); 9556 file.delete(); 9557 } finally { 9558 FileUtils.sync(fos); 9559 if (dos != null) { 9560 try { 9561 dos.close(); 9562 } catch (IOException e) { 9563 // TODO Auto-generated catch block 9564 e.printStackTrace(); 9565 } 9566 } 9567 } 9568 } 9569 9570 public void systemReady(final Runnable goingCallback) { 9571 synchronized(this) { 9572 if (mSystemReady) { 9573 if (goingCallback != null) goingCallback.run(); 9574 return; 9575 } 9576 9577 if (mRecentTasks == null) { 9578 mRecentTasks = mTaskPersister.restoreTasksLocked(); 9579 if (!mRecentTasks.isEmpty()) { 9580 mStackSupervisor.createStackForRestoredTaskHistory(mRecentTasks); 9581 } 9582 mTaskPersister.startPersisting(); 9583 } 9584 9585 // Check to see if there are any update receivers to run. 9586 if (!mDidUpdate) { 9587 if (mWaitingUpdate) { 9588 return; 9589 } 9590 Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED); 9591 List<ResolveInfo> ris = null; 9592 try { 9593 ris = AppGlobals.getPackageManager().queryIntentReceivers( 9594 intent, null, 0, 0); 9595 } catch (RemoteException e) { 9596 } 9597 if (ris != null) { 9598 for (int i=ris.size()-1; i>=0; i--) { 9599 if ((ris.get(i).activityInfo.applicationInfo.flags 9600 &ApplicationInfo.FLAG_SYSTEM) == 0) { 9601 ris.remove(i); 9602 } 9603 } 9604 intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE); 9605 9606 ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers(); 9607 9608 final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>(); 9609 for (int i=0; i<ris.size(); i++) { 9610 ActivityInfo ai = ris.get(i).activityInfo; 9611 ComponentName comp = new ComponentName(ai.packageName, ai.name); 9612 if (lastDoneReceivers.contains(comp)) { 9613 // We already did the pre boot receiver for this app with the current 9614 // platform version, so don't do it again... 9615 ris.remove(i); 9616 i--; 9617 // ...however, do keep it as one that has been done, so we don't 9618 // forget about it when rewriting the file of last done receivers. 9619 doneReceivers.add(comp); 9620 } 9621 } 9622 9623 final int[] users = getUsersLocked(); 9624 for (int i=0; i<ris.size(); i++) { 9625 ActivityInfo ai = ris.get(i).activityInfo; 9626 ComponentName comp = new ComponentName(ai.packageName, ai.name); 9627 doneReceivers.add(comp); 9628 intent.setComponent(comp); 9629 for (int j=0; j<users.length; j++) { 9630 IIntentReceiver finisher = null; 9631 if (i == ris.size()-1 && j == users.length-1) { 9632 finisher = new IIntentReceiver.Stub() { 9633 public void performReceive(Intent intent, int resultCode, 9634 String data, Bundle extras, boolean ordered, 9635 boolean sticky, int sendingUser) { 9636 // The raw IIntentReceiver interface is called 9637 // with the AM lock held, so redispatch to 9638 // execute our code without the lock. 9639 mHandler.post(new Runnable() { 9640 public void run() { 9641 synchronized (ActivityManagerService.this) { 9642 mDidUpdate = true; 9643 } 9644 writeLastDonePreBootReceivers(doneReceivers); 9645 showBootMessage(mContext.getText( 9646 R.string.android_upgrading_complete), 9647 false); 9648 systemReady(goingCallback); 9649 } 9650 }); 9651 } 9652 }; 9653 } 9654 Slog.i(TAG, "Sending system update to " + intent.getComponent() 9655 + " for user " + users[j]); 9656 broadcastIntentLocked(null, null, intent, null, finisher, 9657 0, null, null, null, AppOpsManager.OP_NONE, 9658 true, false, MY_PID, Process.SYSTEM_UID, 9659 users[j]); 9660 if (finisher != null) { 9661 mWaitingUpdate = true; 9662 } 9663 } 9664 } 9665 } 9666 if (mWaitingUpdate) { 9667 return; 9668 } 9669 mDidUpdate = true; 9670 } 9671 9672 mAppOpsService.systemReady(); 9673 mUsageStatsService.systemReady(); 9674 mSystemReady = true; 9675 } 9676 9677 ArrayList<ProcessRecord> procsToKill = null; 9678 synchronized(mPidsSelfLocked) { 9679 for (int i=mPidsSelfLocked.size()-1; i>=0; i--) { 9680 ProcessRecord proc = mPidsSelfLocked.valueAt(i); 9681 if (!isAllowedWhileBooting(proc.info)){ 9682 if (procsToKill == null) { 9683 procsToKill = new ArrayList<ProcessRecord>(); 9684 } 9685 procsToKill.add(proc); 9686 } 9687 } 9688 } 9689 9690 synchronized(this) { 9691 if (procsToKill != null) { 9692 for (int i=procsToKill.size()-1; i>=0; i--) { 9693 ProcessRecord proc = procsToKill.get(i); 9694 Slog.i(TAG, "Removing system update proc: " + proc); 9695 removeProcessLocked(proc, true, false, "system update done"); 9696 } 9697 } 9698 9699 // Now that we have cleaned up any update processes, we 9700 // are ready to start launching real processes and know that 9701 // we won't trample on them any more. 9702 mProcessesReady = true; 9703 } 9704 9705 Slog.i(TAG, "System now ready"); 9706 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY, 9707 SystemClock.uptimeMillis()); 9708 9709 synchronized(this) { 9710 // Make sure we have no pre-ready processes sitting around. 9711 9712 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) { 9713 ResolveInfo ri = mContext.getPackageManager() 9714 .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST), 9715 STOCK_PM_FLAGS); 9716 CharSequence errorMsg = null; 9717 if (ri != null) { 9718 ActivityInfo ai = ri.activityInfo; 9719 ApplicationInfo app = ai.applicationInfo; 9720 if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) { 9721 mTopAction = Intent.ACTION_FACTORY_TEST; 9722 mTopData = null; 9723 mTopComponent = new ComponentName(app.packageName, 9724 ai.name); 9725 } else { 9726 errorMsg = mContext.getResources().getText( 9727 com.android.internal.R.string.factorytest_not_system); 9728 } 9729 } else { 9730 errorMsg = mContext.getResources().getText( 9731 com.android.internal.R.string.factorytest_no_action); 9732 } 9733 if (errorMsg != null) { 9734 mTopAction = null; 9735 mTopData = null; 9736 mTopComponent = null; 9737 Message msg = Message.obtain(); 9738 msg.what = SHOW_FACTORY_ERROR_MSG; 9739 msg.getData().putCharSequence("msg", errorMsg); 9740 mHandler.sendMessage(msg); 9741 } 9742 } 9743 } 9744 9745 retrieveSettings(); 9746 9747 synchronized (this) { 9748 readGrantedUriPermissionsLocked(); 9749 } 9750 9751 if (goingCallback != null) goingCallback.run(); 9752 9753 mSystemServiceManager.startUser(mCurrentUserId); 9754 9755 synchronized (this) { 9756 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 9757 try { 9758 List apps = AppGlobals.getPackageManager(). 9759 getPersistentApplications(STOCK_PM_FLAGS); 9760 if (apps != null) { 9761 int N = apps.size(); 9762 int i; 9763 for (i=0; i<N; i++) { 9764 ApplicationInfo info 9765 = (ApplicationInfo)apps.get(i); 9766 if (info != null && 9767 !info.packageName.equals("android")) { 9768 addAppLocked(info, false); 9769 } 9770 } 9771 } 9772 } catch (RemoteException ex) { 9773 // pm is in same process, this will never happen. 9774 } 9775 } 9776 9777 // Start up initial activity. 9778 mBooting = true; 9779 9780 try { 9781 if (AppGlobals.getPackageManager().hasSystemUidErrors()) { 9782 Message msg = Message.obtain(); 9783 msg.what = SHOW_UID_ERROR_MSG; 9784 mHandler.sendMessage(msg); 9785 } 9786 } catch (RemoteException e) { 9787 } 9788 9789 long ident = Binder.clearCallingIdentity(); 9790 try { 9791 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 9792 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 9793 | Intent.FLAG_RECEIVER_FOREGROUND); 9794 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); 9795 broadcastIntentLocked(null, null, intent, 9796 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 9797 false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId); 9798 intent = new Intent(Intent.ACTION_USER_STARTING); 9799 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 9800 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); 9801 broadcastIntentLocked(null, null, intent, 9802 null, new IIntentReceiver.Stub() { 9803 @Override 9804 public void performReceive(Intent intent, int resultCode, String data, 9805 Bundle extras, boolean ordered, boolean sticky, int sendingUser) 9806 throws RemoteException { 9807 } 9808 }, 0, null, null, 9809 android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 9810 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 9811 } catch (Throwable t) { 9812 Slog.wtf(TAG, "Failed sending first user broadcasts", t); 9813 } finally { 9814 Binder.restoreCallingIdentity(ident); 9815 } 9816 mStackSupervisor.resumeTopActivitiesLocked(); 9817 sendUserSwitchBroadcastsLocked(-1, mCurrentUserId); 9818 } 9819 } 9820 9821 private boolean makeAppCrashingLocked(ProcessRecord app, 9822 String shortMsg, String longMsg, String stackTrace) { 9823 app.crashing = true; 9824 app.crashingReport = generateProcessError(app, 9825 ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace); 9826 startAppProblemLocked(app); 9827 app.stopFreezingAllLocked(); 9828 return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace); 9829 } 9830 9831 private void makeAppNotRespondingLocked(ProcessRecord app, 9832 String activity, String shortMsg, String longMsg) { 9833 app.notResponding = true; 9834 app.notRespondingReport = generateProcessError(app, 9835 ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING, 9836 activity, shortMsg, longMsg, null); 9837 startAppProblemLocked(app); 9838 app.stopFreezingAllLocked(); 9839 } 9840 9841 /** 9842 * Generate a process error record, suitable for attachment to a ProcessRecord. 9843 * 9844 * @param app The ProcessRecord in which the error occurred. 9845 * @param condition Crashing, Application Not Responding, etc. Values are defined in 9846 * ActivityManager.AppErrorStateInfo 9847 * @param activity The activity associated with the crash, if known. 9848 * @param shortMsg Short message describing the crash. 9849 * @param longMsg Long message describing the crash. 9850 * @param stackTrace Full crash stack trace, may be null. 9851 * 9852 * @return Returns a fully-formed AppErrorStateInfo record. 9853 */ 9854 private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app, 9855 int condition, String activity, String shortMsg, String longMsg, String stackTrace) { 9856 ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo(); 9857 9858 report.condition = condition; 9859 report.processName = app.processName; 9860 report.pid = app.pid; 9861 report.uid = app.info.uid; 9862 report.tag = activity; 9863 report.shortMsg = shortMsg; 9864 report.longMsg = longMsg; 9865 report.stackTrace = stackTrace; 9866 9867 return report; 9868 } 9869 9870 void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) { 9871 synchronized (this) { 9872 app.crashing = false; 9873 app.crashingReport = null; 9874 app.notResponding = false; 9875 app.notRespondingReport = null; 9876 if (app.anrDialog == fromDialog) { 9877 app.anrDialog = null; 9878 } 9879 if (app.waitDialog == fromDialog) { 9880 app.waitDialog = null; 9881 } 9882 if (app.pid > 0 && app.pid != MY_PID) { 9883 handleAppCrashLocked(app, null, null, null); 9884 killUnneededProcessLocked(app, "user request after error"); 9885 } 9886 } 9887 } 9888 9889 private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg, 9890 String stackTrace) { 9891 long now = SystemClock.uptimeMillis(); 9892 9893 Long crashTime; 9894 if (!app.isolated) { 9895 crashTime = mProcessCrashTimes.get(app.info.processName, app.uid); 9896 } else { 9897 crashTime = null; 9898 } 9899 if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) { 9900 // This process loses! 9901 Slog.w(TAG, "Process " + app.info.processName 9902 + " has crashed too many times: killing!"); 9903 EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH, 9904 app.userId, app.info.processName, app.uid); 9905 mStackSupervisor.handleAppCrashLocked(app); 9906 if (!app.persistent) { 9907 // We don't want to start this process again until the user 9908 // explicitly does so... but for persistent process, we really 9909 // need to keep it running. If a persistent process is actually 9910 // repeatedly crashing, then badness for everyone. 9911 EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid, 9912 app.info.processName); 9913 if (!app.isolated) { 9914 // XXX We don't have a way to mark isolated processes 9915 // as bad, since they don't have a peristent identity. 9916 mBadProcesses.put(app.info.processName, app.uid, 9917 new BadProcessInfo(now, shortMsg, longMsg, stackTrace)); 9918 mProcessCrashTimes.remove(app.info.processName, app.uid); 9919 } 9920 app.bad = true; 9921 app.removed = true; 9922 // Don't let services in this process be restarted and potentially 9923 // annoy the user repeatedly. Unless it is persistent, since those 9924 // processes run critical code. 9925 removeProcessLocked(app, false, false, "crash"); 9926 mStackSupervisor.resumeTopActivitiesLocked(); 9927 return false; 9928 } 9929 mStackSupervisor.resumeTopActivitiesLocked(); 9930 } else { 9931 mStackSupervisor.finishTopRunningActivityLocked(app); 9932 } 9933 9934 // Bump up the crash count of any services currently running in the proc. 9935 for (int i=app.services.size()-1; i>=0; i--) { 9936 // Any services running in the application need to be placed 9937 // back in the pending list. 9938 ServiceRecord sr = app.services.valueAt(i); 9939 sr.crashCount++; 9940 } 9941 9942 // If the crashing process is what we consider to be the "home process" and it has been 9943 // replaced by a third-party app, clear the package preferred activities from packages 9944 // with a home activity running in the process to prevent a repeatedly crashing app 9945 // from blocking the user to manually clear the list. 9946 final ArrayList<ActivityRecord> activities = app.activities; 9947 if (app == mHomeProcess && activities.size() > 0 9948 && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) { 9949 for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) { 9950 final ActivityRecord r = activities.get(activityNdx); 9951 if (r.isHomeActivity()) { 9952 Log.i(TAG, "Clearing package preferred activities from " + r.packageName); 9953 try { 9954 ActivityThread.getPackageManager() 9955 .clearPackagePreferredActivities(r.packageName); 9956 } catch (RemoteException c) { 9957 // pm is in same process, this will never happen. 9958 } 9959 } 9960 } 9961 } 9962 9963 if (!app.isolated) { 9964 // XXX Can't keep track of crash times for isolated processes, 9965 // because they don't have a perisistent identity. 9966 mProcessCrashTimes.put(app.info.processName, app.uid, now); 9967 } 9968 9969 return true; 9970 } 9971 9972 void startAppProblemLocked(ProcessRecord app) { 9973 if (app.userId == mCurrentUserId) { 9974 app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver( 9975 mContext, app.info.packageName, app.info.flags); 9976 } else { 9977 // If this app is not running under the current user, then we 9978 // can't give it a report button because that would require 9979 // launching the report UI under a different user. 9980 app.errorReportReceiver = null; 9981 } 9982 skipCurrentReceiverLocked(app); 9983 } 9984 9985 void skipCurrentReceiverLocked(ProcessRecord app) { 9986 for (BroadcastQueue queue : mBroadcastQueues) { 9987 queue.skipCurrentReceiverLocked(app); 9988 } 9989 } 9990 9991 /** 9992 * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes. 9993 * The application process will exit immediately after this call returns. 9994 * @param app object of the crashing app, null for the system server 9995 * @param crashInfo describing the exception 9996 */ 9997 public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) { 9998 ProcessRecord r = findAppProcess(app, "Crash"); 9999 final String processName = app == null ? "system_server" 10000 : (r == null ? "unknown" : r.processName); 10001 10002 handleApplicationCrashInner("crash", r, processName, crashInfo); 10003 } 10004 10005 /* Native crash reporting uses this inner version because it needs to be somewhat 10006 * decoupled from the AM-managed cleanup lifecycle 10007 */ 10008 void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName, 10009 ApplicationErrorReport.CrashInfo crashInfo) { 10010 EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(), 10011 UserHandle.getUserId(Binder.getCallingUid()), processName, 10012 r == null ? -1 : r.info.flags, 10013 crashInfo.exceptionClassName, 10014 crashInfo.exceptionMessage, 10015 crashInfo.throwFileName, 10016 crashInfo.throwLineNumber); 10017 10018 addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo); 10019 10020 crashApplication(r, crashInfo); 10021 } 10022 10023 public void handleApplicationStrictModeViolation( 10024 IBinder app, 10025 int violationMask, 10026 StrictMode.ViolationInfo info) { 10027 ProcessRecord r = findAppProcess(app, "StrictMode"); 10028 if (r == null) { 10029 return; 10030 } 10031 10032 if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) { 10033 Integer stackFingerprint = info.hashCode(); 10034 boolean logIt = true; 10035 synchronized (mAlreadyLoggedViolatedStacks) { 10036 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) { 10037 logIt = false; 10038 // TODO: sub-sample into EventLog for these, with 10039 // the info.durationMillis? Then we'd get 10040 // the relative pain numbers, without logging all 10041 // the stack traces repeatedly. We'd want to do 10042 // likewise in the client code, which also does 10043 // dup suppression, before the Binder call. 10044 } else { 10045 if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) { 10046 mAlreadyLoggedViolatedStacks.clear(); 10047 } 10048 mAlreadyLoggedViolatedStacks.add(stackFingerprint); 10049 } 10050 } 10051 if (logIt) { 10052 logStrictModeViolationToDropBox(r, info); 10053 } 10054 } 10055 10056 if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) { 10057 AppErrorResult result = new AppErrorResult(); 10058 synchronized (this) { 10059 final long origId = Binder.clearCallingIdentity(); 10060 10061 Message msg = Message.obtain(); 10062 msg.what = SHOW_STRICT_MODE_VIOLATION_MSG; 10063 HashMap<String, Object> data = new HashMap<String, Object>(); 10064 data.put("result", result); 10065 data.put("app", r); 10066 data.put("violationMask", violationMask); 10067 data.put("info", info); 10068 msg.obj = data; 10069 mHandler.sendMessage(msg); 10070 10071 Binder.restoreCallingIdentity(origId); 10072 } 10073 int res = result.get(); 10074 Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res); 10075 } 10076 } 10077 10078 // Depending on the policy in effect, there could be a bunch of 10079 // these in quick succession so we try to batch these together to 10080 // minimize disk writes, number of dropbox entries, and maximize 10081 // compression, by having more fewer, larger records. 10082 private void logStrictModeViolationToDropBox( 10083 ProcessRecord process, 10084 StrictMode.ViolationInfo info) { 10085 if (info == null) { 10086 return; 10087 } 10088 final boolean isSystemApp = process == null || 10089 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM | 10090 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0; 10091 final String processName = process == null ? "unknown" : process.processName; 10092 final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode"; 10093 final DropBoxManager dbox = (DropBoxManager) 10094 mContext.getSystemService(Context.DROPBOX_SERVICE); 10095 10096 // Exit early if the dropbox isn't configured to accept this report type. 10097 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 10098 10099 boolean bufferWasEmpty; 10100 boolean needsFlush; 10101 final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024); 10102 synchronized (sb) { 10103 bufferWasEmpty = sb.length() == 0; 10104 appendDropBoxProcessHeaders(process, processName, sb); 10105 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 10106 sb.append("System-App: ").append(isSystemApp).append("\n"); 10107 sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n"); 10108 if (info.violationNumThisLoop != 0) { 10109 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n"); 10110 } 10111 if (info.numAnimationsRunning != 0) { 10112 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n"); 10113 } 10114 if (info.broadcastIntentAction != null) { 10115 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n"); 10116 } 10117 if (info.durationMillis != -1) { 10118 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n"); 10119 } 10120 if (info.numInstances != -1) { 10121 sb.append("Instance-Count: ").append(info.numInstances).append("\n"); 10122 } 10123 if (info.tags != null) { 10124 for (String tag : info.tags) { 10125 sb.append("Span-Tag: ").append(tag).append("\n"); 10126 } 10127 } 10128 sb.append("\n"); 10129 if (info.crashInfo != null && info.crashInfo.stackTrace != null) { 10130 sb.append(info.crashInfo.stackTrace); 10131 } 10132 sb.append("\n"); 10133 10134 // Only buffer up to ~64k. Various logging bits truncate 10135 // things at 128k. 10136 needsFlush = (sb.length() > 64 * 1024); 10137 } 10138 10139 // Flush immediately if the buffer's grown too large, or this 10140 // is a non-system app. Non-system apps are isolated with a 10141 // different tag & policy and not batched. 10142 // 10143 // Batching is useful during internal testing with 10144 // StrictMode settings turned up high. Without batching, 10145 // thousands of separate files could be created on boot. 10146 if (!isSystemApp || needsFlush) { 10147 new Thread("Error dump: " + dropboxTag) { 10148 @Override 10149 public void run() { 10150 String report; 10151 synchronized (sb) { 10152 report = sb.toString(); 10153 sb.delete(0, sb.length()); 10154 sb.trimToSize(); 10155 } 10156 if (report.length() != 0) { 10157 dbox.addText(dropboxTag, report); 10158 } 10159 } 10160 }.start(); 10161 return; 10162 } 10163 10164 // System app batching: 10165 if (!bufferWasEmpty) { 10166 // An existing dropbox-writing thread is outstanding, so 10167 // we don't need to start it up. The existing thread will 10168 // catch the buffer appends we just did. 10169 return; 10170 } 10171 10172 // Worker thread to both batch writes and to avoid blocking the caller on I/O. 10173 // (After this point, we shouldn't access AMS internal data structures.) 10174 new Thread("Error dump: " + dropboxTag) { 10175 @Override 10176 public void run() { 10177 // 5 second sleep to let stacks arrive and be batched together 10178 try { 10179 Thread.sleep(5000); // 5 seconds 10180 } catch (InterruptedException e) {} 10181 10182 String errorReport; 10183 synchronized (mStrictModeBuffer) { 10184 errorReport = mStrictModeBuffer.toString(); 10185 if (errorReport.length() == 0) { 10186 return; 10187 } 10188 mStrictModeBuffer.delete(0, mStrictModeBuffer.length()); 10189 mStrictModeBuffer.trimToSize(); 10190 } 10191 dbox.addText(dropboxTag, errorReport); 10192 } 10193 }.start(); 10194 } 10195 10196 /** 10197 * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors. 10198 * @param app object of the crashing app, null for the system server 10199 * @param tag reported by the caller 10200 * @param crashInfo describing the context of the error 10201 * @return true if the process should exit immediately (WTF is fatal) 10202 */ 10203 public boolean handleApplicationWtf(IBinder app, String tag, 10204 ApplicationErrorReport.CrashInfo crashInfo) { 10205 ProcessRecord r = findAppProcess(app, "WTF"); 10206 final String processName = app == null ? "system_server" 10207 : (r == null ? "unknown" : r.processName); 10208 10209 EventLog.writeEvent(EventLogTags.AM_WTF, 10210 UserHandle.getUserId(Binder.getCallingUid()), Binder.getCallingPid(), 10211 processName, 10212 r == null ? -1 : r.info.flags, 10213 tag, crashInfo.exceptionMessage); 10214 10215 addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo); 10216 10217 if (r != null && r.pid != Process.myPid() && 10218 Settings.Global.getInt(mContext.getContentResolver(), 10219 Settings.Global.WTF_IS_FATAL, 0) != 0) { 10220 crashApplication(r, crashInfo); 10221 return true; 10222 } else { 10223 return false; 10224 } 10225 } 10226 10227 /** 10228 * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit}) 10229 * @return the corresponding {@link ProcessRecord} object, or null if none could be found 10230 */ 10231 private ProcessRecord findAppProcess(IBinder app, String reason) { 10232 if (app == null) { 10233 return null; 10234 } 10235 10236 synchronized (this) { 10237 final int NP = mProcessNames.getMap().size(); 10238 for (int ip=0; ip<NP; ip++) { 10239 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 10240 final int NA = apps.size(); 10241 for (int ia=0; ia<NA; ia++) { 10242 ProcessRecord p = apps.valueAt(ia); 10243 if (p.thread != null && p.thread.asBinder() == app) { 10244 return p; 10245 } 10246 } 10247 } 10248 10249 Slog.w(TAG, "Can't find mystery application for " + reason 10250 + " from pid=" + Binder.getCallingPid() 10251 + " uid=" + Binder.getCallingUid() + ": " + app); 10252 return null; 10253 } 10254 } 10255 10256 /** 10257 * Utility function for addErrorToDropBox and handleStrictModeViolation's logging 10258 * to append various headers to the dropbox log text. 10259 */ 10260 private void appendDropBoxProcessHeaders(ProcessRecord process, String processName, 10261 StringBuilder sb) { 10262 // Watchdog thread ends up invoking this function (with 10263 // a null ProcessRecord) to add the stack file to dropbox. 10264 // Do not acquire a lock on this (am) in such cases, as it 10265 // could cause a potential deadlock, if and when watchdog 10266 // is invoked due to unavailability of lock on am and it 10267 // would prevent watchdog from killing system_server. 10268 if (process == null) { 10269 sb.append("Process: ").append(processName).append("\n"); 10270 return; 10271 } 10272 // Note: ProcessRecord 'process' is guarded by the service 10273 // instance. (notably process.pkgList, which could otherwise change 10274 // concurrently during execution of this method) 10275 synchronized (this) { 10276 sb.append("Process: ").append(processName).append("\n"); 10277 int flags = process.info.flags; 10278 IPackageManager pm = AppGlobals.getPackageManager(); 10279 sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n"); 10280 for (int ip=0; ip<process.pkgList.size(); ip++) { 10281 String pkg = process.pkgList.keyAt(ip); 10282 sb.append("Package: ").append(pkg); 10283 try { 10284 PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId()); 10285 if (pi != null) { 10286 sb.append(" v").append(pi.versionCode); 10287 if (pi.versionName != null) { 10288 sb.append(" (").append(pi.versionName).append(")"); 10289 } 10290 } 10291 } catch (RemoteException e) { 10292 Slog.e(TAG, "Error getting package info: " + pkg, e); 10293 } 10294 sb.append("\n"); 10295 } 10296 } 10297 } 10298 10299 private static String processClass(ProcessRecord process) { 10300 if (process == null || process.pid == MY_PID) { 10301 return "system_server"; 10302 } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) { 10303 return "system_app"; 10304 } else { 10305 return "data_app"; 10306 } 10307 } 10308 10309 /** 10310 * Write a description of an error (crash, WTF, ANR) to the drop box. 10311 * @param eventType to include in the drop box tag ("crash", "wtf", etc.) 10312 * @param process which caused the error, null means the system server 10313 * @param activity which triggered the error, null if unknown 10314 * @param parent activity related to the error, null if unknown 10315 * @param subject line related to the error, null if absent 10316 * @param report in long form describing the error, null if absent 10317 * @param logFile to include in the report, null if none 10318 * @param crashInfo giving an application stack trace, null if absent 10319 */ 10320 public void addErrorToDropBox(String eventType, 10321 ProcessRecord process, String processName, ActivityRecord activity, 10322 ActivityRecord parent, String subject, 10323 final String report, final File logFile, 10324 final ApplicationErrorReport.CrashInfo crashInfo) { 10325 // NOTE -- this must never acquire the ActivityManagerService lock, 10326 // otherwise the watchdog may be prevented from resetting the system. 10327 10328 final String dropboxTag = processClass(process) + "_" + eventType; 10329 final DropBoxManager dbox = (DropBoxManager) 10330 mContext.getSystemService(Context.DROPBOX_SERVICE); 10331 10332 // Exit early if the dropbox isn't configured to accept this report type. 10333 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 10334 10335 final StringBuilder sb = new StringBuilder(1024); 10336 appendDropBoxProcessHeaders(process, processName, sb); 10337 if (activity != null) { 10338 sb.append("Activity: ").append(activity.shortComponentName).append("\n"); 10339 } 10340 if (parent != null && parent.app != null && parent.app.pid != process.pid) { 10341 sb.append("Parent-Process: ").append(parent.app.processName).append("\n"); 10342 } 10343 if (parent != null && parent != activity) { 10344 sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n"); 10345 } 10346 if (subject != null) { 10347 sb.append("Subject: ").append(subject).append("\n"); 10348 } 10349 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 10350 if (Debug.isDebuggerConnected()) { 10351 sb.append("Debugger: Connected\n"); 10352 } 10353 sb.append("\n"); 10354 10355 // Do the rest in a worker thread to avoid blocking the caller on I/O 10356 // (After this point, we shouldn't access AMS internal data structures.) 10357 Thread worker = new Thread("Error dump: " + dropboxTag) { 10358 @Override 10359 public void run() { 10360 if (report != null) { 10361 sb.append(report); 10362 } 10363 if (logFile != null) { 10364 try { 10365 sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE, 10366 "\n\n[[TRUNCATED]]")); 10367 } catch (IOException e) { 10368 Slog.e(TAG, "Error reading " + logFile, e); 10369 } 10370 } 10371 if (crashInfo != null && crashInfo.stackTrace != null) { 10372 sb.append(crashInfo.stackTrace); 10373 } 10374 10375 String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag; 10376 int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0); 10377 if (lines > 0) { 10378 sb.append("\n"); 10379 10380 // Merge several logcat streams, and take the last N lines 10381 InputStreamReader input = null; 10382 try { 10383 java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat", 10384 "-v", "time", "-b", "events", "-b", "system", "-b", "main", 10385 "-t", String.valueOf(lines)).redirectErrorStream(true).start(); 10386 10387 try { logcat.getOutputStream().close(); } catch (IOException e) {} 10388 try { logcat.getErrorStream().close(); } catch (IOException e) {} 10389 input = new InputStreamReader(logcat.getInputStream()); 10390 10391 int num; 10392 char[] buf = new char[8192]; 10393 while ((num = input.read(buf)) > 0) sb.append(buf, 0, num); 10394 } catch (IOException e) { 10395 Slog.e(TAG, "Error running logcat", e); 10396 } finally { 10397 if (input != null) try { input.close(); } catch (IOException e) {} 10398 } 10399 } 10400 10401 dbox.addText(dropboxTag, sb.toString()); 10402 } 10403 }; 10404 10405 if (process == null) { 10406 // If process is null, we are being called from some internal code 10407 // and may be about to die -- run this synchronously. 10408 worker.run(); 10409 } else { 10410 worker.start(); 10411 } 10412 } 10413 10414 /** 10415 * Bring up the "unexpected error" dialog box for a crashing app. 10416 * Deal with edge cases (intercepts from instrumented applications, 10417 * ActivityController, error intent receivers, that sort of thing). 10418 * @param r the application crashing 10419 * @param crashInfo describing the failure 10420 */ 10421 private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) { 10422 long timeMillis = System.currentTimeMillis(); 10423 String shortMsg = crashInfo.exceptionClassName; 10424 String longMsg = crashInfo.exceptionMessage; 10425 String stackTrace = crashInfo.stackTrace; 10426 if (shortMsg != null && longMsg != null) { 10427 longMsg = shortMsg + ": " + longMsg; 10428 } else if (shortMsg != null) { 10429 longMsg = shortMsg; 10430 } 10431 10432 AppErrorResult result = new AppErrorResult(); 10433 synchronized (this) { 10434 if (mController != null) { 10435 try { 10436 String name = r != null ? r.processName : null; 10437 int pid = r != null ? r.pid : Binder.getCallingPid(); 10438 if (!mController.appCrashed(name, pid, 10439 shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) { 10440 Slog.w(TAG, "Force-killing crashed app " + name 10441 + " at watcher's request"); 10442 Process.killProcess(pid); 10443 return; 10444 } 10445 } catch (RemoteException e) { 10446 mController = null; 10447 Watchdog.getInstance().setActivityController(null); 10448 } 10449 } 10450 10451 final long origId = Binder.clearCallingIdentity(); 10452 10453 // If this process is running instrumentation, finish it. 10454 if (r != null && r.instrumentationClass != null) { 10455 Slog.w(TAG, "Error in app " + r.processName 10456 + " running instrumentation " + r.instrumentationClass + ":"); 10457 if (shortMsg != null) Slog.w(TAG, " " + shortMsg); 10458 if (longMsg != null) Slog.w(TAG, " " + longMsg); 10459 Bundle info = new Bundle(); 10460 info.putString("shortMsg", shortMsg); 10461 info.putString("longMsg", longMsg); 10462 finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info); 10463 Binder.restoreCallingIdentity(origId); 10464 return; 10465 } 10466 10467 // If we can't identify the process or it's already exceeded its crash quota, 10468 // quit right away without showing a crash dialog. 10469 if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) { 10470 Binder.restoreCallingIdentity(origId); 10471 return; 10472 } 10473 10474 Message msg = Message.obtain(); 10475 msg.what = SHOW_ERROR_MSG; 10476 HashMap data = new HashMap(); 10477 data.put("result", result); 10478 data.put("app", r); 10479 msg.obj = data; 10480 mHandler.sendMessage(msg); 10481 10482 Binder.restoreCallingIdentity(origId); 10483 } 10484 10485 int res = result.get(); 10486 10487 Intent appErrorIntent = null; 10488 synchronized (this) { 10489 if (r != null && !r.isolated) { 10490 // XXX Can't keep track of crash time for isolated processes, 10491 // since they don't have a persistent identity. 10492 mProcessCrashTimes.put(r.info.processName, r.uid, 10493 SystemClock.uptimeMillis()); 10494 } 10495 if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) { 10496 appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo); 10497 } 10498 } 10499 10500 if (appErrorIntent != null) { 10501 try { 10502 mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId)); 10503 } catch (ActivityNotFoundException e) { 10504 Slog.w(TAG, "bug report receiver dissappeared", e); 10505 } 10506 } 10507 } 10508 10509 Intent createAppErrorIntentLocked(ProcessRecord r, 10510 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 10511 ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo); 10512 if (report == null) { 10513 return null; 10514 } 10515 Intent result = new Intent(Intent.ACTION_APP_ERROR); 10516 result.setComponent(r.errorReportReceiver); 10517 result.putExtra(Intent.EXTRA_BUG_REPORT, report); 10518 result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 10519 return result; 10520 } 10521 10522 private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r, 10523 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 10524 if (r.errorReportReceiver == null) { 10525 return null; 10526 } 10527 10528 if (!r.crashing && !r.notResponding && !r.forceCrashReport) { 10529 return null; 10530 } 10531 10532 ApplicationErrorReport report = new ApplicationErrorReport(); 10533 report.packageName = r.info.packageName; 10534 report.installerPackageName = r.errorReportReceiver.getPackageName(); 10535 report.processName = r.processName; 10536 report.time = timeMillis; 10537 report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0; 10538 10539 if (r.crashing || r.forceCrashReport) { 10540 report.type = ApplicationErrorReport.TYPE_CRASH; 10541 report.crashInfo = crashInfo; 10542 } else if (r.notResponding) { 10543 report.type = ApplicationErrorReport.TYPE_ANR; 10544 report.anrInfo = new ApplicationErrorReport.AnrInfo(); 10545 10546 report.anrInfo.activity = r.notRespondingReport.tag; 10547 report.anrInfo.cause = r.notRespondingReport.shortMsg; 10548 report.anrInfo.info = r.notRespondingReport.longMsg; 10549 } 10550 10551 return report; 10552 } 10553 10554 public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() { 10555 enforceNotIsolatedCaller("getProcessesInErrorState"); 10556 // assume our apps are happy - lazy create the list 10557 List<ActivityManager.ProcessErrorStateInfo> errList = null; 10558 10559 final boolean allUsers = ActivityManager.checkUidPermission( 10560 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 10561 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 10562 int userId = UserHandle.getUserId(Binder.getCallingUid()); 10563 10564 synchronized (this) { 10565 10566 // iterate across all processes 10567 for (int i=mLruProcesses.size()-1; i>=0; i--) { 10568 ProcessRecord app = mLruProcesses.get(i); 10569 if (!allUsers && app.userId != userId) { 10570 continue; 10571 } 10572 if ((app.thread != null) && (app.crashing || app.notResponding)) { 10573 // This one's in trouble, so we'll generate a report for it 10574 // crashes are higher priority (in case there's a crash *and* an anr) 10575 ActivityManager.ProcessErrorStateInfo report = null; 10576 if (app.crashing) { 10577 report = app.crashingReport; 10578 } else if (app.notResponding) { 10579 report = app.notRespondingReport; 10580 } 10581 10582 if (report != null) { 10583 if (errList == null) { 10584 errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1); 10585 } 10586 errList.add(report); 10587 } else { 10588 Slog.w(TAG, "Missing app error report, app = " + app.processName + 10589 " crashing = " + app.crashing + 10590 " notResponding = " + app.notResponding); 10591 } 10592 } 10593 } 10594 } 10595 10596 return errList; 10597 } 10598 10599 static int oomAdjToImportance(int adj, ActivityManager.RunningAppProcessInfo currApp) { 10600 if (adj >= ProcessList.CACHED_APP_MIN_ADJ) { 10601 if (currApp != null) { 10602 currApp.lru = adj - ProcessList.CACHED_APP_MIN_ADJ + 1; 10603 } 10604 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 10605 } else if (adj >= ProcessList.SERVICE_B_ADJ) { 10606 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 10607 } else if (adj >= ProcessList.HOME_APP_ADJ) { 10608 if (currApp != null) { 10609 currApp.lru = 0; 10610 } 10611 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 10612 } else if (adj >= ProcessList.SERVICE_ADJ) { 10613 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 10614 } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 10615 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE; 10616 } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) { 10617 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE; 10618 } else if (adj >= ProcessList.VISIBLE_APP_ADJ) { 10619 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE; 10620 } else { 10621 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND; 10622 } 10623 } 10624 10625 private void fillInProcMemInfo(ProcessRecord app, 10626 ActivityManager.RunningAppProcessInfo outInfo) { 10627 outInfo.pid = app.pid; 10628 outInfo.uid = app.info.uid; 10629 if (mHeavyWeightProcess == app) { 10630 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE; 10631 } 10632 if (app.persistent) { 10633 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT; 10634 } 10635 if (app.activities.size() > 0) { 10636 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES; 10637 } 10638 outInfo.lastTrimLevel = app.trimMemoryLevel; 10639 int adj = app.curAdj; 10640 outInfo.importance = oomAdjToImportance(adj, outInfo); 10641 outInfo.importanceReasonCode = app.adjTypeCode; 10642 outInfo.processState = app.curProcState; 10643 } 10644 10645 public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() { 10646 enforceNotIsolatedCaller("getRunningAppProcesses"); 10647 // Lazy instantiation of list 10648 List<ActivityManager.RunningAppProcessInfo> runList = null; 10649 final boolean allUsers = ActivityManager.checkUidPermission( 10650 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 10651 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 10652 int userId = UserHandle.getUserId(Binder.getCallingUid()); 10653 synchronized (this) { 10654 // Iterate across all processes 10655 for (int i=mLruProcesses.size()-1; i>=0; i--) { 10656 ProcessRecord app = mLruProcesses.get(i); 10657 if (!allUsers && app.userId != userId) { 10658 continue; 10659 } 10660 if ((app.thread != null) && (!app.crashing && !app.notResponding)) { 10661 // Generate process state info for running application 10662 ActivityManager.RunningAppProcessInfo currApp = 10663 new ActivityManager.RunningAppProcessInfo(app.processName, 10664 app.pid, app.getPackageList()); 10665 fillInProcMemInfo(app, currApp); 10666 if (app.adjSource instanceof ProcessRecord) { 10667 currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid; 10668 currApp.importanceReasonImportance = oomAdjToImportance( 10669 app.adjSourceOom, null); 10670 } else if (app.adjSource instanceof ActivityRecord) { 10671 ActivityRecord r = (ActivityRecord)app.adjSource; 10672 if (r.app != null) currApp.importanceReasonPid = r.app.pid; 10673 } 10674 if (app.adjTarget instanceof ComponentName) { 10675 currApp.importanceReasonComponent = (ComponentName)app.adjTarget; 10676 } 10677 //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance 10678 // + " lru=" + currApp.lru); 10679 if (runList == null) { 10680 runList = new ArrayList<ActivityManager.RunningAppProcessInfo>(); 10681 } 10682 runList.add(currApp); 10683 } 10684 } 10685 } 10686 return runList; 10687 } 10688 10689 public List<ApplicationInfo> getRunningExternalApplications() { 10690 enforceNotIsolatedCaller("getRunningExternalApplications"); 10691 List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses(); 10692 List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>(); 10693 if (runningApps != null && runningApps.size() > 0) { 10694 Set<String> extList = new HashSet<String>(); 10695 for (ActivityManager.RunningAppProcessInfo app : runningApps) { 10696 if (app.pkgList != null) { 10697 for (String pkg : app.pkgList) { 10698 extList.add(pkg); 10699 } 10700 } 10701 } 10702 IPackageManager pm = AppGlobals.getPackageManager(); 10703 for (String pkg : extList) { 10704 try { 10705 ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId()); 10706 if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) { 10707 retList.add(info); 10708 } 10709 } catch (RemoteException e) { 10710 } 10711 } 10712 } 10713 return retList; 10714 } 10715 10716 @Override 10717 public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) { 10718 enforceNotIsolatedCaller("getMyMemoryState"); 10719 synchronized (this) { 10720 ProcessRecord proc; 10721 synchronized (mPidsSelfLocked) { 10722 proc = mPidsSelfLocked.get(Binder.getCallingPid()); 10723 } 10724 fillInProcMemInfo(proc, outInfo); 10725 } 10726 } 10727 10728 @Override 10729 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 10730 if (checkCallingPermission(android.Manifest.permission.DUMP) 10731 != PackageManager.PERMISSION_GRANTED) { 10732 pw.println("Permission Denial: can't dump ActivityManager from from pid=" 10733 + Binder.getCallingPid() 10734 + ", uid=" + Binder.getCallingUid() 10735 + " without permission " 10736 + android.Manifest.permission.DUMP); 10737 return; 10738 } 10739 10740 boolean dumpAll = false; 10741 boolean dumpClient = false; 10742 String dumpPackage = null; 10743 10744 int opti = 0; 10745 while (opti < args.length) { 10746 String opt = args[opti]; 10747 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 10748 break; 10749 } 10750 opti++; 10751 if ("-a".equals(opt)) { 10752 dumpAll = true; 10753 } else if ("-c".equals(opt)) { 10754 dumpClient = true; 10755 } else if ("-h".equals(opt)) { 10756 pw.println("Activity manager dump options:"); 10757 pw.println(" [-a] [-c] [-h] [cmd] ..."); 10758 pw.println(" cmd may be one of:"); 10759 pw.println(" a[ctivities]: activity stack state"); 10760 pw.println(" b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state"); 10761 pw.println(" i[ntents] [PACKAGE_NAME]: pending intent state"); 10762 pw.println(" p[rocesses] [PACKAGE_NAME]: process state"); 10763 pw.println(" o[om]: out of memory management"); 10764 pw.println(" prov[iders] [COMP_SPEC ...]: content provider state"); 10765 pw.println(" provider [COMP_SPEC]: provider client-side state"); 10766 pw.println(" s[ervices] [COMP_SPEC ...]: service state"); 10767 pw.println(" service [COMP_SPEC]: service client-side state"); 10768 pw.println(" package [PACKAGE_NAME]: all state related to given package"); 10769 pw.println(" all: dump all activities"); 10770 pw.println(" top: dump the top activity"); 10771 pw.println(" cmd may also be a COMP_SPEC to dump activities."); 10772 pw.println(" COMP_SPEC may be a component name (com.foo/.myApp),"); 10773 pw.println(" a partial substring in a component name, a"); 10774 pw.println(" hex object identifier."); 10775 pw.println(" -a: include all available server state."); 10776 pw.println(" -c: include client state."); 10777 return; 10778 } else { 10779 pw.println("Unknown argument: " + opt + "; use -h for help"); 10780 } 10781 } 10782 10783 long origId = Binder.clearCallingIdentity(); 10784 boolean more = false; 10785 // Is the caller requesting to dump a particular piece of data? 10786 if (opti < args.length) { 10787 String cmd = args[opti]; 10788 opti++; 10789 if ("activities".equals(cmd) || "a".equals(cmd)) { 10790 synchronized (this) { 10791 dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null); 10792 } 10793 } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) { 10794 String[] newArgs; 10795 String name; 10796 if (opti >= args.length) { 10797 name = null; 10798 newArgs = EMPTY_STRING_ARRAY; 10799 } else { 10800 name = args[opti]; 10801 opti++; 10802 newArgs = new String[args.length - opti]; 10803 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 10804 args.length - opti); 10805 } 10806 synchronized (this) { 10807 dumpBroadcastsLocked(fd, pw, args, opti, true, name); 10808 } 10809 } else if ("intents".equals(cmd) || "i".equals(cmd)) { 10810 String[] newArgs; 10811 String name; 10812 if (opti >= args.length) { 10813 name = null; 10814 newArgs = EMPTY_STRING_ARRAY; 10815 } else { 10816 name = args[opti]; 10817 opti++; 10818 newArgs = new String[args.length - opti]; 10819 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 10820 args.length - opti); 10821 } 10822 synchronized (this) { 10823 dumpPendingIntentsLocked(fd, pw, args, opti, true, name); 10824 } 10825 } else if ("processes".equals(cmd) || "p".equals(cmd)) { 10826 String[] newArgs; 10827 String name; 10828 if (opti >= args.length) { 10829 name = null; 10830 newArgs = EMPTY_STRING_ARRAY; 10831 } else { 10832 name = args[opti]; 10833 opti++; 10834 newArgs = new String[args.length - opti]; 10835 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 10836 args.length - opti); 10837 } 10838 synchronized (this) { 10839 dumpProcessesLocked(fd, pw, args, opti, true, name); 10840 } 10841 } else if ("oom".equals(cmd) || "o".equals(cmd)) { 10842 synchronized (this) { 10843 dumpOomLocked(fd, pw, args, opti, true); 10844 } 10845 } else if ("provider".equals(cmd)) { 10846 String[] newArgs; 10847 String name; 10848 if (opti >= args.length) { 10849 name = null; 10850 newArgs = EMPTY_STRING_ARRAY; 10851 } else { 10852 name = args[opti]; 10853 opti++; 10854 newArgs = new String[args.length - opti]; 10855 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti); 10856 } 10857 if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) { 10858 pw.println("No providers match: " + name); 10859 pw.println("Use -h for help."); 10860 } 10861 } else if ("providers".equals(cmd) || "prov".equals(cmd)) { 10862 synchronized (this) { 10863 dumpProvidersLocked(fd, pw, args, opti, true, null); 10864 } 10865 } else if ("service".equals(cmd)) { 10866 String[] newArgs; 10867 String name; 10868 if (opti >= args.length) { 10869 name = null; 10870 newArgs = EMPTY_STRING_ARRAY; 10871 } else { 10872 name = args[opti]; 10873 opti++; 10874 newArgs = new String[args.length - opti]; 10875 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 10876 args.length - opti); 10877 } 10878 if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) { 10879 pw.println("No services match: " + name); 10880 pw.println("Use -h for help."); 10881 } 10882 } else if ("package".equals(cmd)) { 10883 String[] newArgs; 10884 if (opti >= args.length) { 10885 pw.println("package: no package name specified"); 10886 pw.println("Use -h for help."); 10887 } else { 10888 dumpPackage = args[opti]; 10889 opti++; 10890 newArgs = new String[args.length - opti]; 10891 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 10892 args.length - opti); 10893 args = newArgs; 10894 opti = 0; 10895 more = true; 10896 } 10897 } else if ("services".equals(cmd) || "s".equals(cmd)) { 10898 synchronized (this) { 10899 mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null); 10900 } 10901 } else { 10902 // Dumping a single activity? 10903 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) { 10904 pw.println("Bad activity command, or no activities match: " + cmd); 10905 pw.println("Use -h for help."); 10906 } 10907 } 10908 if (!more) { 10909 Binder.restoreCallingIdentity(origId); 10910 return; 10911 } 10912 } 10913 10914 // No piece of data specified, dump everything. 10915 synchronized (this) { 10916 dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 10917 pw.println(); 10918 if (dumpAll) { 10919 pw.println("-------------------------------------------------------------------------------"); 10920 } 10921 dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 10922 pw.println(); 10923 if (dumpAll) { 10924 pw.println("-------------------------------------------------------------------------------"); 10925 } 10926 dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage); 10927 pw.println(); 10928 if (dumpAll) { 10929 pw.println("-------------------------------------------------------------------------------"); 10930 } 10931 mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 10932 pw.println(); 10933 if (dumpAll) { 10934 pw.println("-------------------------------------------------------------------------------"); 10935 } 10936 dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 10937 pw.println(); 10938 if (dumpAll) { 10939 pw.println("-------------------------------------------------------------------------------"); 10940 } 10941 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage); 10942 } 10943 Binder.restoreCallingIdentity(origId); 10944 } 10945 10946 void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 10947 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) { 10948 pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)"); 10949 10950 boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient, 10951 dumpPackage); 10952 boolean needSep = printedAnything; 10953 10954 boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity, 10955 dumpPackage, needSep, " mFocusedActivity: "); 10956 if (printed) { 10957 printedAnything = true; 10958 needSep = false; 10959 } 10960 10961 if (dumpPackage == null) { 10962 if (needSep) { 10963 pw.println(); 10964 } 10965 needSep = true; 10966 printedAnything = true; 10967 mStackSupervisor.dump(pw, " "); 10968 } 10969 10970 if (mRecentTasks.size() > 0) { 10971 boolean printedHeader = false; 10972 10973 final int N = mRecentTasks.size(); 10974 for (int i=0; i<N; i++) { 10975 TaskRecord tr = mRecentTasks.get(i); 10976 if (dumpPackage != null) { 10977 if (tr.realActivity == null || 10978 !dumpPackage.equals(tr.realActivity)) { 10979 continue; 10980 } 10981 } 10982 if (!printedHeader) { 10983 if (needSep) { 10984 pw.println(); 10985 } 10986 pw.println(" Recent tasks:"); 10987 printedHeader = true; 10988 printedAnything = true; 10989 } 10990 pw.print(" * Recent #"); pw.print(i); pw.print(": "); 10991 pw.println(tr); 10992 if (dumpAll) { 10993 mRecentTasks.get(i).dump(pw, " "); 10994 } 10995 } 10996 } 10997 10998 if (!printedAnything) { 10999 pw.println(" (nothing)"); 11000 } 11001 } 11002 11003 void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 11004 int opti, boolean dumpAll, String dumpPackage) { 11005 boolean needSep = false; 11006 boolean printedAnything = false; 11007 int numPers = 0; 11008 11009 pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)"); 11010 11011 if (dumpAll) { 11012 final int NP = mProcessNames.getMap().size(); 11013 for (int ip=0; ip<NP; ip++) { 11014 SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip); 11015 final int NA = procs.size(); 11016 for (int ia=0; ia<NA; ia++) { 11017 ProcessRecord r = procs.valueAt(ia); 11018 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 11019 continue; 11020 } 11021 if (!needSep) { 11022 pw.println(" All known processes:"); 11023 needSep = true; 11024 printedAnything = true; 11025 } 11026 pw.print(r.persistent ? " *PERS*" : " *APP*"); 11027 pw.print(" UID "); pw.print(procs.keyAt(ia)); 11028 pw.print(" "); pw.println(r); 11029 r.dump(pw, " "); 11030 if (r.persistent) { 11031 numPers++; 11032 } 11033 } 11034 } 11035 } 11036 11037 if (mIsolatedProcesses.size() > 0) { 11038 boolean printed = false; 11039 for (int i=0; i<mIsolatedProcesses.size(); i++) { 11040 ProcessRecord r = mIsolatedProcesses.valueAt(i); 11041 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 11042 continue; 11043 } 11044 if (!printed) { 11045 if (needSep) { 11046 pw.println(); 11047 } 11048 pw.println(" Isolated process list (sorted by uid):"); 11049 printedAnything = true; 11050 printed = true; 11051 needSep = true; 11052 } 11053 pw.println(String.format("%sIsolated #%2d: %s", 11054 " ", i, r.toString())); 11055 } 11056 } 11057 11058 if (mLruProcesses.size() > 0) { 11059 if (needSep) { 11060 pw.println(); 11061 } 11062 pw.print(" Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size()); 11063 pw.print(" total, non-act at "); 11064 pw.print(mLruProcesses.size()-mLruProcessActivityStart); 11065 pw.print(", non-svc at "); 11066 pw.print(mLruProcesses.size()-mLruProcessServiceStart); 11067 pw.println("):"); 11068 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", false, dumpPackage); 11069 needSep = true; 11070 printedAnything = true; 11071 } 11072 11073 if (dumpAll || dumpPackage != null) { 11074 synchronized (mPidsSelfLocked) { 11075 boolean printed = false; 11076 for (int i=0; i<mPidsSelfLocked.size(); i++) { 11077 ProcessRecord r = mPidsSelfLocked.valueAt(i); 11078 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 11079 continue; 11080 } 11081 if (!printed) { 11082 if (needSep) pw.println(); 11083 needSep = true; 11084 pw.println(" PID mappings:"); 11085 printed = true; 11086 printedAnything = true; 11087 } 11088 pw.print(" PID #"); pw.print(mPidsSelfLocked.keyAt(i)); 11089 pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i)); 11090 } 11091 } 11092 } 11093 11094 if (mForegroundProcesses.size() > 0) { 11095 synchronized (mPidsSelfLocked) { 11096 boolean printed = false; 11097 for (int i=0; i<mForegroundProcesses.size(); i++) { 11098 ProcessRecord r = mPidsSelfLocked.get( 11099 mForegroundProcesses.valueAt(i).pid); 11100 if (dumpPackage != null && (r == null 11101 || !r.pkgList.containsKey(dumpPackage))) { 11102 continue; 11103 } 11104 if (!printed) { 11105 if (needSep) pw.println(); 11106 needSep = true; 11107 pw.println(" Foreground Processes:"); 11108 printed = true; 11109 printedAnything = true; 11110 } 11111 pw.print(" PID #"); pw.print(mForegroundProcesses.keyAt(i)); 11112 pw.print(": "); pw.println(mForegroundProcesses.valueAt(i)); 11113 } 11114 } 11115 } 11116 11117 if (mPersistentStartingProcesses.size() > 0) { 11118 if (needSep) pw.println(); 11119 needSep = true; 11120 printedAnything = true; 11121 pw.println(" Persisent processes that are starting:"); 11122 dumpProcessList(pw, this, mPersistentStartingProcesses, " ", 11123 "Starting Norm", "Restarting PERS", dumpPackage); 11124 } 11125 11126 if (mRemovedProcesses.size() > 0) { 11127 if (needSep) pw.println(); 11128 needSep = true; 11129 printedAnything = true; 11130 pw.println(" Processes that are being removed:"); 11131 dumpProcessList(pw, this, mRemovedProcesses, " ", 11132 "Removed Norm", "Removed PERS", dumpPackage); 11133 } 11134 11135 if (mProcessesOnHold.size() > 0) { 11136 if (needSep) pw.println(); 11137 needSep = true; 11138 printedAnything = true; 11139 pw.println(" Processes that are on old until the system is ready:"); 11140 dumpProcessList(pw, this, mProcessesOnHold, " ", 11141 "OnHold Norm", "OnHold PERS", dumpPackage); 11142 } 11143 11144 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage); 11145 11146 if (mProcessCrashTimes.getMap().size() > 0) { 11147 boolean printed = false; 11148 long now = SystemClock.uptimeMillis(); 11149 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap(); 11150 final int NP = pmap.size(); 11151 for (int ip=0; ip<NP; ip++) { 11152 String pname = pmap.keyAt(ip); 11153 SparseArray<Long> uids = pmap.valueAt(ip); 11154 final int N = uids.size(); 11155 for (int i=0; i<N; i++) { 11156 int puid = uids.keyAt(i); 11157 ProcessRecord r = mProcessNames.get(pname, puid); 11158 if (dumpPackage != null && (r == null 11159 || !r.pkgList.containsKey(dumpPackage))) { 11160 continue; 11161 } 11162 if (!printed) { 11163 if (needSep) pw.println(); 11164 needSep = true; 11165 pw.println(" Time since processes crashed:"); 11166 printed = true; 11167 printedAnything = true; 11168 } 11169 pw.print(" Process "); pw.print(pname); 11170 pw.print(" uid "); pw.print(puid); 11171 pw.print(": last crashed "); 11172 TimeUtils.formatDuration(now-uids.valueAt(i), pw); 11173 pw.println(" ago"); 11174 } 11175 } 11176 } 11177 11178 if (mBadProcesses.getMap().size() > 0) { 11179 boolean printed = false; 11180 final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap(); 11181 final int NP = pmap.size(); 11182 for (int ip=0; ip<NP; ip++) { 11183 String pname = pmap.keyAt(ip); 11184 SparseArray<BadProcessInfo> uids = pmap.valueAt(ip); 11185 final int N = uids.size(); 11186 for (int i=0; i<N; i++) { 11187 int puid = uids.keyAt(i); 11188 ProcessRecord r = mProcessNames.get(pname, puid); 11189 if (dumpPackage != null && (r == null 11190 || !r.pkgList.containsKey(dumpPackage))) { 11191 continue; 11192 } 11193 if (!printed) { 11194 if (needSep) pw.println(); 11195 needSep = true; 11196 pw.println(" Bad processes:"); 11197 printedAnything = true; 11198 } 11199 BadProcessInfo info = uids.valueAt(i); 11200 pw.print(" Bad process "); pw.print(pname); 11201 pw.print(" uid "); pw.print(puid); 11202 pw.print(": crashed at time "); pw.println(info.time); 11203 if (info.shortMsg != null) { 11204 pw.print(" Short msg: "); pw.println(info.shortMsg); 11205 } 11206 if (info.longMsg != null) { 11207 pw.print(" Long msg: "); pw.println(info.longMsg); 11208 } 11209 if (info.stack != null) { 11210 pw.println(" Stack:"); 11211 int lastPos = 0; 11212 for (int pos=0; pos<info.stack.length(); pos++) { 11213 if (info.stack.charAt(pos) == '\n') { 11214 pw.print(" "); 11215 pw.write(info.stack, lastPos, pos-lastPos); 11216 pw.println(); 11217 lastPos = pos+1; 11218 } 11219 } 11220 if (lastPos < info.stack.length()) { 11221 pw.print(" "); 11222 pw.write(info.stack, lastPos, info.stack.length()-lastPos); 11223 pw.println(); 11224 } 11225 } 11226 } 11227 } 11228 } 11229 11230 if (dumpPackage == null) { 11231 pw.println(); 11232 needSep = false; 11233 pw.println(" mStartedUsers:"); 11234 for (int i=0; i<mStartedUsers.size(); i++) { 11235 UserStartedState uss = mStartedUsers.valueAt(i); 11236 pw.print(" User #"); pw.print(uss.mHandle.getIdentifier()); 11237 pw.print(": "); uss.dump("", pw); 11238 } 11239 pw.print(" mStartedUserArray: ["); 11240 for (int i=0; i<mStartedUserArray.length; i++) { 11241 if (i > 0) pw.print(", "); 11242 pw.print(mStartedUserArray[i]); 11243 } 11244 pw.println("]"); 11245 pw.print(" mUserLru: ["); 11246 for (int i=0; i<mUserLru.size(); i++) { 11247 if (i > 0) pw.print(", "); 11248 pw.print(mUserLru.get(i)); 11249 } 11250 pw.println("]"); 11251 if (dumpAll) { 11252 pw.print(" mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray)); 11253 } 11254 } 11255 if (mHomeProcess != null && (dumpPackage == null 11256 || mHomeProcess.pkgList.containsKey(dumpPackage))) { 11257 if (needSep) { 11258 pw.println(); 11259 needSep = false; 11260 } 11261 pw.println(" mHomeProcess: " + mHomeProcess); 11262 } 11263 if (mPreviousProcess != null && (dumpPackage == null 11264 || mPreviousProcess.pkgList.containsKey(dumpPackage))) { 11265 if (needSep) { 11266 pw.println(); 11267 needSep = false; 11268 } 11269 pw.println(" mPreviousProcess: " + mPreviousProcess); 11270 } 11271 if (dumpAll) { 11272 StringBuilder sb = new StringBuilder(128); 11273 sb.append(" mPreviousProcessVisibleTime: "); 11274 TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb); 11275 pw.println(sb); 11276 } 11277 if (mHeavyWeightProcess != null && (dumpPackage == null 11278 || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) { 11279 if (needSep) { 11280 pw.println(); 11281 needSep = false; 11282 } 11283 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 11284 } 11285 if (dumpPackage == null) { 11286 pw.println(" mConfiguration: " + mConfiguration); 11287 } 11288 if (dumpAll) { 11289 pw.println(" mConfigWillChange: " + getFocusedStack().mConfigWillChange); 11290 if (mCompatModePackages.getPackages().size() > 0) { 11291 boolean printed = false; 11292 for (Map.Entry<String, Integer> entry 11293 : mCompatModePackages.getPackages().entrySet()) { 11294 String pkg = entry.getKey(); 11295 int mode = entry.getValue(); 11296 if (dumpPackage != null && !dumpPackage.equals(pkg)) { 11297 continue; 11298 } 11299 if (!printed) { 11300 pw.println(" mScreenCompatPackages:"); 11301 printed = true; 11302 } 11303 pw.print(" "); pw.print(pkg); pw.print(": "); 11304 pw.print(mode); pw.println(); 11305 } 11306 } 11307 } 11308 if (dumpPackage == null) { 11309 if (mSleeping || mWentToSleep || mLockScreenShown) { 11310 pw.println(" mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep 11311 + " mLockScreenShown " + mLockScreenShown); 11312 } 11313 if (mShuttingDown || mRunningVoice) { 11314 pw.print(" mShuttingDown=" + mShuttingDown + " mRunningVoice=" + mRunningVoice); 11315 } 11316 } 11317 if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient 11318 || mOrigWaitForDebugger) { 11319 if (dumpPackage == null || dumpPackage.equals(mDebugApp) 11320 || dumpPackage.equals(mOrigDebugApp)) { 11321 if (needSep) { 11322 pw.println(); 11323 needSep = false; 11324 } 11325 pw.println(" mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp 11326 + " mDebugTransient=" + mDebugTransient 11327 + " mOrigWaitForDebugger=" + mOrigWaitForDebugger); 11328 } 11329 } 11330 if (mOpenGlTraceApp != null) { 11331 if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) { 11332 if (needSep) { 11333 pw.println(); 11334 needSep = false; 11335 } 11336 pw.println(" mOpenGlTraceApp=" + mOpenGlTraceApp); 11337 } 11338 } 11339 if (mProfileApp != null || mProfileProc != null || mProfileFile != null 11340 || mProfileFd != null) { 11341 if (dumpPackage == null || dumpPackage.equals(mProfileApp)) { 11342 if (needSep) { 11343 pw.println(); 11344 needSep = false; 11345 } 11346 pw.println(" mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc); 11347 pw.println(" mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd); 11348 pw.println(" mProfileType=" + mProfileType + " mAutoStopProfiler=" 11349 + mAutoStopProfiler); 11350 } 11351 } 11352 if (dumpPackage == null) { 11353 if (mAlwaysFinishActivities || mController != null) { 11354 pw.println(" mAlwaysFinishActivities=" + mAlwaysFinishActivities 11355 + " mController=" + mController); 11356 } 11357 if (dumpAll) { 11358 pw.println(" Total persistent processes: " + numPers); 11359 pw.println(" mProcessesReady=" + mProcessesReady 11360 + " mSystemReady=" + mSystemReady); 11361 pw.println(" mBooting=" + mBooting 11362 + " mBooted=" + mBooted 11363 + " mFactoryTest=" + mFactoryTest); 11364 pw.print(" mLastPowerCheckRealtime="); 11365 TimeUtils.formatDuration(mLastPowerCheckRealtime, pw); 11366 pw.println(""); 11367 pw.print(" mLastPowerCheckUptime="); 11368 TimeUtils.formatDuration(mLastPowerCheckUptime, pw); 11369 pw.println(""); 11370 pw.println(" mGoingToSleep=" + mStackSupervisor.mGoingToSleep); 11371 pw.println(" mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity); 11372 pw.println(" mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq); 11373 pw.println(" mNumNonCachedProcs=" + mNumNonCachedProcs 11374 + " (" + mLruProcesses.size() + " total)" 11375 + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs 11376 + " mNumServiceProcs=" + mNumServiceProcs 11377 + " mNewNumServiceProcs=" + mNewNumServiceProcs); 11378 pw.println(" mAllowLowerMemLevel=" + mAllowLowerMemLevel 11379 + " mLastMemoryLevel" + mLastMemoryLevel 11380 + " mLastNumProcesses" + mLastNumProcesses); 11381 long now = SystemClock.uptimeMillis(); 11382 pw.print(" mLastIdleTime="); 11383 TimeUtils.formatDuration(now, mLastIdleTime, pw); 11384 pw.print(" mLowRamSinceLastIdle="); 11385 TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw); 11386 pw.println(); 11387 } 11388 } 11389 11390 if (!printedAnything) { 11391 pw.println(" (nothing)"); 11392 } 11393 } 11394 11395 boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args, 11396 int opti, boolean needSep, boolean dumpAll, String dumpPackage) { 11397 if (mProcessesToGc.size() > 0) { 11398 boolean printed = false; 11399 long now = SystemClock.uptimeMillis(); 11400 for (int i=0; i<mProcessesToGc.size(); i++) { 11401 ProcessRecord proc = mProcessesToGc.get(i); 11402 if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) { 11403 continue; 11404 } 11405 if (!printed) { 11406 if (needSep) pw.println(); 11407 needSep = true; 11408 pw.println(" Processes that are waiting to GC:"); 11409 printed = true; 11410 } 11411 pw.print(" Process "); pw.println(proc); 11412 pw.print(" lowMem="); pw.print(proc.reportLowMemory); 11413 pw.print(", last gced="); 11414 pw.print(now-proc.lastRequestedGc); 11415 pw.print(" ms ago, last lowMem="); 11416 pw.print(now-proc.lastLowMemory); 11417 pw.println(" ms ago"); 11418 11419 } 11420 } 11421 return needSep; 11422 } 11423 11424 void printOomLevel(PrintWriter pw, String name, int adj) { 11425 pw.print(" "); 11426 if (adj >= 0) { 11427 pw.print(' '); 11428 if (adj < 10) pw.print(' '); 11429 } else { 11430 if (adj > -10) pw.print(' '); 11431 } 11432 pw.print(adj); 11433 pw.print(": "); 11434 pw.print(name); 11435 pw.print(" ("); 11436 pw.print(mProcessList.getMemLevel(adj)/1024); 11437 pw.println(" kB)"); 11438 } 11439 11440 boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args, 11441 int opti, boolean dumpAll) { 11442 boolean needSep = false; 11443 11444 if (mLruProcesses.size() > 0) { 11445 if (needSep) pw.println(); 11446 needSep = true; 11447 pw.println(" OOM levels:"); 11448 printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ); 11449 printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ); 11450 printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ); 11451 printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ); 11452 printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ); 11453 printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ); 11454 printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ); 11455 printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ); 11456 printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ); 11457 printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ); 11458 printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ); 11459 printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ); 11460 printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ); 11461 11462 if (needSep) pw.println(); 11463 pw.print(" Process OOM control ("); pw.print(mLruProcesses.size()); 11464 pw.print(" total, non-act at "); 11465 pw.print(mLruProcesses.size()-mLruProcessActivityStart); 11466 pw.print(", non-svc at "); 11467 pw.print(mLruProcesses.size()-mLruProcessServiceStart); 11468 pw.println("):"); 11469 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", true, null); 11470 needSep = true; 11471 } 11472 11473 dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null); 11474 11475 pw.println(); 11476 pw.println(" mHomeProcess: " + mHomeProcess); 11477 pw.println(" mPreviousProcess: " + mPreviousProcess); 11478 if (mHeavyWeightProcess != null) { 11479 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 11480 } 11481 11482 return true; 11483 } 11484 11485 /** 11486 * There are three ways to call this: 11487 * - no provider specified: dump all the providers 11488 * - a flattened component name that matched an existing provider was specified as the 11489 * first arg: dump that one provider 11490 * - the first arg isn't the flattened component name of an existing provider: 11491 * dump all providers whose component contains the first arg as a substring 11492 */ 11493 protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args, 11494 int opti, boolean dumpAll) { 11495 return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll); 11496 } 11497 11498 static class ItemMatcher { 11499 ArrayList<ComponentName> components; 11500 ArrayList<String> strings; 11501 ArrayList<Integer> objects; 11502 boolean all; 11503 11504 ItemMatcher() { 11505 all = true; 11506 } 11507 11508 void build(String name) { 11509 ComponentName componentName = ComponentName.unflattenFromString(name); 11510 if (componentName != null) { 11511 if (components == null) { 11512 components = new ArrayList<ComponentName>(); 11513 } 11514 components.add(componentName); 11515 all = false; 11516 } else { 11517 int objectId = 0; 11518 // Not a '/' separated full component name; maybe an object ID? 11519 try { 11520 objectId = Integer.parseInt(name, 16); 11521 if (objects == null) { 11522 objects = new ArrayList<Integer>(); 11523 } 11524 objects.add(objectId); 11525 all = false; 11526 } catch (RuntimeException e) { 11527 // Not an integer; just do string match. 11528 if (strings == null) { 11529 strings = new ArrayList<String>(); 11530 } 11531 strings.add(name); 11532 all = false; 11533 } 11534 } 11535 } 11536 11537 int build(String[] args, int opti) { 11538 for (; opti<args.length; opti++) { 11539 String name = args[opti]; 11540 if ("--".equals(name)) { 11541 return opti+1; 11542 } 11543 build(name); 11544 } 11545 return opti; 11546 } 11547 11548 boolean match(Object object, ComponentName comp) { 11549 if (all) { 11550 return true; 11551 } 11552 if (components != null) { 11553 for (int i=0; i<components.size(); i++) { 11554 if (components.get(i).equals(comp)) { 11555 return true; 11556 } 11557 } 11558 } 11559 if (objects != null) { 11560 for (int i=0; i<objects.size(); i++) { 11561 if (System.identityHashCode(object) == objects.get(i)) { 11562 return true; 11563 } 11564 } 11565 } 11566 if (strings != null) { 11567 String flat = comp.flattenToString(); 11568 for (int i=0; i<strings.size(); i++) { 11569 if (flat.contains(strings.get(i))) { 11570 return true; 11571 } 11572 } 11573 } 11574 return false; 11575 } 11576 } 11577 11578 /** 11579 * There are three things that cmd can be: 11580 * - a flattened component name that matches an existing activity 11581 * - the cmd arg isn't the flattened component name of an existing activity: 11582 * dump all activity whose component contains the cmd as a substring 11583 * - A hex number of the ActivityRecord object instance. 11584 */ 11585 protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args, 11586 int opti, boolean dumpAll) { 11587 ArrayList<ActivityRecord> activities; 11588 11589 synchronized (this) { 11590 activities = mStackSupervisor.getDumpActivitiesLocked(name); 11591 } 11592 11593 if (activities.size() <= 0) { 11594 return false; 11595 } 11596 11597 String[] newArgs = new String[args.length - opti]; 11598 System.arraycopy(args, opti, newArgs, 0, args.length - opti); 11599 11600 TaskRecord lastTask = null; 11601 boolean needSep = false; 11602 for (int i=activities.size()-1; i>=0; i--) { 11603 ActivityRecord r = activities.get(i); 11604 if (needSep) { 11605 pw.println(); 11606 } 11607 needSep = true; 11608 synchronized (this) { 11609 if (lastTask != r.task) { 11610 lastTask = r.task; 11611 pw.print("TASK "); pw.print(lastTask.affinity); 11612 pw.print(" id="); pw.println(lastTask.taskId); 11613 if (dumpAll) { 11614 lastTask.dump(pw, " "); 11615 } 11616 } 11617 } 11618 dumpActivity(" ", fd, pw, activities.get(i), newArgs, dumpAll); 11619 } 11620 return true; 11621 } 11622 11623 /** 11624 * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if 11625 * there is a thread associated with the activity. 11626 */ 11627 private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw, 11628 final ActivityRecord r, String[] args, boolean dumpAll) { 11629 String innerPrefix = prefix + " "; 11630 synchronized (this) { 11631 pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName); 11632 pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r))); 11633 pw.print(" pid="); 11634 if (r.app != null) pw.println(r.app.pid); 11635 else pw.println("(not running)"); 11636 if (dumpAll) { 11637 r.dump(pw, innerPrefix); 11638 } 11639 } 11640 if (r.app != null && r.app.thread != null) { 11641 // flush anything that is already in the PrintWriter since the thread is going 11642 // to write to the file descriptor directly 11643 pw.flush(); 11644 try { 11645 TransferPipe tp = new TransferPipe(); 11646 try { 11647 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(), 11648 r.appToken, innerPrefix, args); 11649 tp.go(fd); 11650 } finally { 11651 tp.kill(); 11652 } 11653 } catch (IOException e) { 11654 pw.println(innerPrefix + "Failure while dumping the activity: " + e); 11655 } catch (RemoteException e) { 11656 pw.println(innerPrefix + "Got a RemoteException while dumping the activity"); 11657 } 11658 } 11659 } 11660 11661 void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 11662 int opti, boolean dumpAll, String dumpPackage) { 11663 boolean needSep = false; 11664 boolean onlyHistory = false; 11665 boolean printedAnything = false; 11666 11667 if ("history".equals(dumpPackage)) { 11668 if (opti < args.length && "-s".equals(args[opti])) { 11669 dumpAll = false; 11670 } 11671 onlyHistory = true; 11672 dumpPackage = null; 11673 } 11674 11675 pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)"); 11676 if (!onlyHistory && dumpAll) { 11677 if (mRegisteredReceivers.size() > 0) { 11678 boolean printed = false; 11679 Iterator it = mRegisteredReceivers.values().iterator(); 11680 while (it.hasNext()) { 11681 ReceiverList r = (ReceiverList)it.next(); 11682 if (dumpPackage != null && (r.app == null || 11683 !dumpPackage.equals(r.app.info.packageName))) { 11684 continue; 11685 } 11686 if (!printed) { 11687 pw.println(" Registered Receivers:"); 11688 needSep = true; 11689 printed = true; 11690 printedAnything = true; 11691 } 11692 pw.print(" * "); pw.println(r); 11693 r.dump(pw, " "); 11694 } 11695 } 11696 11697 if (mReceiverResolver.dump(pw, needSep ? 11698 "\n Receiver Resolver Table:" : " Receiver Resolver Table:", 11699 " ", dumpPackage, false)) { 11700 needSep = true; 11701 printedAnything = true; 11702 } 11703 } 11704 11705 for (BroadcastQueue q : mBroadcastQueues) { 11706 needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep); 11707 printedAnything |= needSep; 11708 } 11709 11710 needSep = true; 11711 11712 if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) { 11713 for (int user=0; user<mStickyBroadcasts.size(); user++) { 11714 if (needSep) { 11715 pw.println(); 11716 } 11717 needSep = true; 11718 printedAnything = true; 11719 pw.print(" Sticky broadcasts for user "); 11720 pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":"); 11721 StringBuilder sb = new StringBuilder(128); 11722 for (Map.Entry<String, ArrayList<Intent>> ent 11723 : mStickyBroadcasts.valueAt(user).entrySet()) { 11724 pw.print(" * Sticky action "); pw.print(ent.getKey()); 11725 if (dumpAll) { 11726 pw.println(":"); 11727 ArrayList<Intent> intents = ent.getValue(); 11728 final int N = intents.size(); 11729 for (int i=0; i<N; i++) { 11730 sb.setLength(0); 11731 sb.append(" Intent: "); 11732 intents.get(i).toShortString(sb, false, true, false, false); 11733 pw.println(sb.toString()); 11734 Bundle bundle = intents.get(i).getExtras(); 11735 if (bundle != null) { 11736 pw.print(" "); 11737 pw.println(bundle.toString()); 11738 } 11739 } 11740 } else { 11741 pw.println(""); 11742 } 11743 } 11744 } 11745 } 11746 11747 if (!onlyHistory && dumpAll) { 11748 pw.println(); 11749 for (BroadcastQueue queue : mBroadcastQueues) { 11750 pw.println(" mBroadcastsScheduled [" + queue.mQueueName + "]=" 11751 + queue.mBroadcastsScheduled); 11752 } 11753 pw.println(" mHandler:"); 11754 mHandler.dump(new PrintWriterPrinter(pw), " "); 11755 needSep = true; 11756 printedAnything = true; 11757 } 11758 11759 if (!printedAnything) { 11760 pw.println(" (nothing)"); 11761 } 11762 } 11763 11764 void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args, 11765 int opti, boolean dumpAll, String dumpPackage) { 11766 boolean needSep; 11767 boolean printedAnything = false; 11768 11769 ItemMatcher matcher = new ItemMatcher(); 11770 matcher.build(args, opti); 11771 11772 pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)"); 11773 11774 needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage); 11775 printedAnything |= needSep; 11776 11777 if (mLaunchingProviders.size() > 0) { 11778 boolean printed = false; 11779 for (int i=mLaunchingProviders.size()-1; i>=0; i--) { 11780 ContentProviderRecord r = mLaunchingProviders.get(i); 11781 if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) { 11782 continue; 11783 } 11784 if (!printed) { 11785 if (needSep) pw.println(); 11786 needSep = true; 11787 pw.println(" Launching content providers:"); 11788 printed = true; 11789 printedAnything = true; 11790 } 11791 pw.print(" Launching #"); pw.print(i); pw.print(": "); 11792 pw.println(r); 11793 } 11794 } 11795 11796 if (mGrantedUriPermissions.size() > 0) { 11797 boolean printed = false; 11798 int dumpUid = -2; 11799 if (dumpPackage != null) { 11800 try { 11801 dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0); 11802 } catch (NameNotFoundException e) { 11803 dumpUid = -1; 11804 } 11805 } 11806 for (int i=0; i<mGrantedUriPermissions.size(); i++) { 11807 int uid = mGrantedUriPermissions.keyAt(i); 11808 if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) { 11809 continue; 11810 } 11811 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 11812 if (!printed) { 11813 if (needSep) pw.println(); 11814 needSep = true; 11815 pw.println(" Granted Uri Permissions:"); 11816 printed = true; 11817 printedAnything = true; 11818 } 11819 pw.print(" * UID "); pw.print(uid); pw.println(" holds:"); 11820 for (UriPermission perm : perms.values()) { 11821 pw.print(" "); pw.println(perm); 11822 if (dumpAll) { 11823 perm.dump(pw, " "); 11824 } 11825 } 11826 } 11827 } 11828 11829 if (!printedAnything) { 11830 pw.println(" (nothing)"); 11831 } 11832 } 11833 11834 void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 11835 int opti, boolean dumpAll, String dumpPackage) { 11836 boolean printed = false; 11837 11838 pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)"); 11839 11840 if (mIntentSenderRecords.size() > 0) { 11841 Iterator<WeakReference<PendingIntentRecord>> it 11842 = mIntentSenderRecords.values().iterator(); 11843 while (it.hasNext()) { 11844 WeakReference<PendingIntentRecord> ref = it.next(); 11845 PendingIntentRecord rec = ref != null ? ref.get(): null; 11846 if (dumpPackage != null && (rec == null 11847 || !dumpPackage.equals(rec.key.packageName))) { 11848 continue; 11849 } 11850 printed = true; 11851 if (rec != null) { 11852 pw.print(" * "); pw.println(rec); 11853 if (dumpAll) { 11854 rec.dump(pw, " "); 11855 } 11856 } else { 11857 pw.print(" * "); pw.println(ref); 11858 } 11859 } 11860 } 11861 11862 if (!printed) { 11863 pw.println(" (nothing)"); 11864 } 11865 } 11866 11867 private static final int dumpProcessList(PrintWriter pw, 11868 ActivityManagerService service, List list, 11869 String prefix, String normalLabel, String persistentLabel, 11870 String dumpPackage) { 11871 int numPers = 0; 11872 final int N = list.size()-1; 11873 for (int i=N; i>=0; i--) { 11874 ProcessRecord r = (ProcessRecord)list.get(i); 11875 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 11876 continue; 11877 } 11878 pw.println(String.format("%s%s #%2d: %s", 11879 prefix, (r.persistent ? persistentLabel : normalLabel), 11880 i, r.toString())); 11881 if (r.persistent) { 11882 numPers++; 11883 } 11884 } 11885 return numPers; 11886 } 11887 11888 private static final boolean dumpProcessOomList(PrintWriter pw, 11889 ActivityManagerService service, List<ProcessRecord> origList, 11890 String prefix, String normalLabel, String persistentLabel, 11891 boolean inclDetails, String dumpPackage) { 11892 11893 ArrayList<Pair<ProcessRecord, Integer>> list 11894 = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size()); 11895 for (int i=0; i<origList.size(); i++) { 11896 ProcessRecord r = origList.get(i); 11897 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 11898 continue; 11899 } 11900 list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i)); 11901 } 11902 11903 if (list.size() <= 0) { 11904 return false; 11905 } 11906 11907 Comparator<Pair<ProcessRecord, Integer>> comparator 11908 = new Comparator<Pair<ProcessRecord, Integer>>() { 11909 @Override 11910 public int compare(Pair<ProcessRecord, Integer> object1, 11911 Pair<ProcessRecord, Integer> object2) { 11912 if (object1.first.setAdj != object2.first.setAdj) { 11913 return object1.first.setAdj > object2.first.setAdj ? -1 : 1; 11914 } 11915 if (object1.second.intValue() != object2.second.intValue()) { 11916 return object1.second.intValue() > object2.second.intValue() ? -1 : 1; 11917 } 11918 return 0; 11919 } 11920 }; 11921 11922 Collections.sort(list, comparator); 11923 11924 final long curRealtime = SystemClock.elapsedRealtime(); 11925 final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime; 11926 final long curUptime = SystemClock.uptimeMillis(); 11927 final long uptimeSince = curUptime - service.mLastPowerCheckUptime; 11928 11929 for (int i=list.size()-1; i>=0; i--) { 11930 ProcessRecord r = list.get(i).first; 11931 String oomAdj = ProcessList.makeOomAdjString(r.setAdj); 11932 char schedGroup; 11933 switch (r.setSchedGroup) { 11934 case Process.THREAD_GROUP_BG_NONINTERACTIVE: 11935 schedGroup = 'B'; 11936 break; 11937 case Process.THREAD_GROUP_DEFAULT: 11938 schedGroup = 'F'; 11939 break; 11940 default: 11941 schedGroup = '?'; 11942 break; 11943 } 11944 char foreground; 11945 if (r.foregroundActivities) { 11946 foreground = 'A'; 11947 } else if (r.foregroundServices) { 11948 foreground = 'S'; 11949 } else { 11950 foreground = ' '; 11951 } 11952 String procState = ProcessList.makeProcStateString(r.curProcState); 11953 pw.print(prefix); 11954 pw.print(r.persistent ? persistentLabel : normalLabel); 11955 pw.print(" #"); 11956 int num = (origList.size()-1)-list.get(i).second; 11957 if (num < 10) pw.print(' '); 11958 pw.print(num); 11959 pw.print(": "); 11960 pw.print(oomAdj); 11961 pw.print(' '); 11962 pw.print(schedGroup); 11963 pw.print('/'); 11964 pw.print(foreground); 11965 pw.print('/'); 11966 pw.print(procState); 11967 pw.print(" trm:"); 11968 if (r.trimMemoryLevel < 10) pw.print(' '); 11969 pw.print(r.trimMemoryLevel); 11970 pw.print(' '); 11971 pw.print(r.toShortString()); 11972 pw.print(" ("); 11973 pw.print(r.adjType); 11974 pw.println(')'); 11975 if (r.adjSource != null || r.adjTarget != null) { 11976 pw.print(prefix); 11977 pw.print(" "); 11978 if (r.adjTarget instanceof ComponentName) { 11979 pw.print(((ComponentName)r.adjTarget).flattenToShortString()); 11980 } else if (r.adjTarget != null) { 11981 pw.print(r.adjTarget.toString()); 11982 } else { 11983 pw.print("{null}"); 11984 } 11985 pw.print("<="); 11986 if (r.adjSource instanceof ProcessRecord) { 11987 pw.print("Proc{"); 11988 pw.print(((ProcessRecord)r.adjSource).toShortString()); 11989 pw.println("}"); 11990 } else if (r.adjSource != null) { 11991 pw.println(r.adjSource.toString()); 11992 } else { 11993 pw.println("{null}"); 11994 } 11995 } 11996 if (inclDetails) { 11997 pw.print(prefix); 11998 pw.print(" "); 11999 pw.print("oom: max="); pw.print(r.maxAdj); 12000 pw.print(" curRaw="); pw.print(r.curRawAdj); 12001 pw.print(" setRaw="); pw.print(r.setRawAdj); 12002 pw.print(" cur="); pw.print(r.curAdj); 12003 pw.print(" set="); pw.println(r.setAdj); 12004 pw.print(prefix); 12005 pw.print(" "); 12006 pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState)); 12007 pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState)); 12008 pw.print(" lastPss="); pw.print(r.lastPss); 12009 pw.print(" lastCachedPss="); pw.println(r.lastCachedPss); 12010 pw.print(prefix); 12011 pw.print(" "); 12012 pw.print("keeping="); pw.print(r.keeping); 12013 pw.print(" cached="); pw.print(r.cached); 12014 pw.print(" empty="); pw.print(r.empty); 12015 pw.print(" hasAboveClient="); pw.println(r.hasAboveClient); 12016 12017 if (!r.keeping) { 12018 if (r.lastWakeTime != 0) { 12019 long wtime; 12020 BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics(); 12021 synchronized (stats) { 12022 wtime = stats.getProcessWakeTime(r.info.uid, 12023 r.pid, curRealtime); 12024 } 12025 long timeUsed = wtime - r.lastWakeTime; 12026 pw.print(prefix); 12027 pw.print(" "); 12028 pw.print("keep awake over "); 12029 TimeUtils.formatDuration(realtimeSince, pw); 12030 pw.print(" used "); 12031 TimeUtils.formatDuration(timeUsed, pw); 12032 pw.print(" ("); 12033 pw.print((timeUsed*100)/realtimeSince); 12034 pw.println("%)"); 12035 } 12036 if (r.lastCpuTime != 0) { 12037 long timeUsed = r.curCpuTime - r.lastCpuTime; 12038 pw.print(prefix); 12039 pw.print(" "); 12040 pw.print("run cpu over "); 12041 TimeUtils.formatDuration(uptimeSince, pw); 12042 pw.print(" used "); 12043 TimeUtils.formatDuration(timeUsed, pw); 12044 pw.print(" ("); 12045 pw.print((timeUsed*100)/uptimeSince); 12046 pw.println("%)"); 12047 } 12048 } 12049 } 12050 } 12051 return true; 12052 } 12053 12054 ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) { 12055 ArrayList<ProcessRecord> procs; 12056 synchronized (this) { 12057 if (args != null && args.length > start 12058 && args[start].charAt(0) != '-') { 12059 procs = new ArrayList<ProcessRecord>(); 12060 int pid = -1; 12061 try { 12062 pid = Integer.parseInt(args[start]); 12063 } catch (NumberFormatException e) { 12064 } 12065 for (int i=mLruProcesses.size()-1; i>=0; i--) { 12066 ProcessRecord proc = mLruProcesses.get(i); 12067 if (proc.pid == pid) { 12068 procs.add(proc); 12069 } else if (proc.processName.equals(args[start])) { 12070 procs.add(proc); 12071 } 12072 } 12073 if (procs.size() <= 0) { 12074 return null; 12075 } 12076 } else { 12077 procs = new ArrayList<ProcessRecord>(mLruProcesses); 12078 } 12079 } 12080 return procs; 12081 } 12082 12083 final void dumpGraphicsHardwareUsage(FileDescriptor fd, 12084 PrintWriter pw, String[] args) { 12085 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args); 12086 if (procs == null) { 12087 pw.println("No process found for: " + args[0]); 12088 return; 12089 } 12090 12091 long uptime = SystemClock.uptimeMillis(); 12092 long realtime = SystemClock.elapsedRealtime(); 12093 pw.println("Applications Graphics Acceleration Info:"); 12094 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 12095 12096 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 12097 ProcessRecord r = procs.get(i); 12098 if (r.thread != null) { 12099 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **"); 12100 pw.flush(); 12101 try { 12102 TransferPipe tp = new TransferPipe(); 12103 try { 12104 r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args); 12105 tp.go(fd); 12106 } finally { 12107 tp.kill(); 12108 } 12109 } catch (IOException e) { 12110 pw.println("Failure while dumping the app: " + r); 12111 pw.flush(); 12112 } catch (RemoteException e) { 12113 pw.println("Got a RemoteException while dumping the app " + r); 12114 pw.flush(); 12115 } 12116 } 12117 } 12118 } 12119 12120 final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) { 12121 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args); 12122 if (procs == null) { 12123 pw.println("No process found for: " + args[0]); 12124 return; 12125 } 12126 12127 pw.println("Applications Database Info:"); 12128 12129 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 12130 ProcessRecord r = procs.get(i); 12131 if (r.thread != null) { 12132 pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **"); 12133 pw.flush(); 12134 try { 12135 TransferPipe tp = new TransferPipe(); 12136 try { 12137 r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args); 12138 tp.go(fd); 12139 } finally { 12140 tp.kill(); 12141 } 12142 } catch (IOException e) { 12143 pw.println("Failure while dumping the app: " + r); 12144 pw.flush(); 12145 } catch (RemoteException e) { 12146 pw.println("Got a RemoteException while dumping the app " + r); 12147 pw.flush(); 12148 } 12149 } 12150 } 12151 } 12152 12153 final static class MemItem { 12154 final boolean isProc; 12155 final String label; 12156 final String shortLabel; 12157 final long pss; 12158 final int id; 12159 final boolean hasActivities; 12160 ArrayList<MemItem> subitems; 12161 12162 public MemItem(String _label, String _shortLabel, long _pss, int _id, 12163 boolean _hasActivities) { 12164 isProc = true; 12165 label = _label; 12166 shortLabel = _shortLabel; 12167 pss = _pss; 12168 id = _id; 12169 hasActivities = _hasActivities; 12170 } 12171 12172 public MemItem(String _label, String _shortLabel, long _pss, int _id) { 12173 isProc = false; 12174 label = _label; 12175 shortLabel = _shortLabel; 12176 pss = _pss; 12177 id = _id; 12178 hasActivities = false; 12179 } 12180 } 12181 12182 static final void dumpMemItems(PrintWriter pw, String prefix, String tag, 12183 ArrayList<MemItem> items, boolean sort, boolean isCompact) { 12184 if (sort && !isCompact) { 12185 Collections.sort(items, new Comparator<MemItem>() { 12186 @Override 12187 public int compare(MemItem lhs, MemItem rhs) { 12188 if (lhs.pss < rhs.pss) { 12189 return 1; 12190 } else if (lhs.pss > rhs.pss) { 12191 return -1; 12192 } 12193 return 0; 12194 } 12195 }); 12196 } 12197 12198 for (int i=0; i<items.size(); i++) { 12199 MemItem mi = items.get(i); 12200 if (!isCompact) { 12201 pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label); 12202 } else if (mi.isProc) { 12203 pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel); 12204 pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss); 12205 pw.println(mi.hasActivities ? ",a" : ",e"); 12206 } else { 12207 pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(","); 12208 pw.println(mi.pss); 12209 } 12210 if (mi.subitems != null) { 12211 dumpMemItems(pw, prefix + " ", mi.shortLabel, mi.subitems, 12212 true, isCompact); 12213 } 12214 } 12215 } 12216 12217 // These are in KB. 12218 static final long[] DUMP_MEM_BUCKETS = new long[] { 12219 5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024, 12220 120*1024, 160*1024, 200*1024, 12221 250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024, 12222 1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024 12223 }; 12224 12225 static final void appendMemBucket(StringBuilder out, long memKB, String label, 12226 boolean stackLike) { 12227 int start = label.lastIndexOf('.'); 12228 if (start >= 0) start++; 12229 else start = 0; 12230 int end = label.length(); 12231 for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) { 12232 if (DUMP_MEM_BUCKETS[i] >= memKB) { 12233 long bucket = DUMP_MEM_BUCKETS[i]/1024; 12234 out.append(bucket); 12235 out.append(stackLike ? "MB." : "MB "); 12236 out.append(label, start, end); 12237 return; 12238 } 12239 } 12240 out.append(memKB/1024); 12241 out.append(stackLike ? "MB." : "MB "); 12242 out.append(label, start, end); 12243 } 12244 12245 static final int[] DUMP_MEM_OOM_ADJ = new int[] { 12246 ProcessList.NATIVE_ADJ, 12247 ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ, 12248 ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ, 12249 ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ, 12250 ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ, 12251 ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ 12252 }; 12253 static final String[] DUMP_MEM_OOM_LABEL = new String[] { 12254 "Native", 12255 "System", "Persistent", "Foreground", 12256 "Visible", "Perceptible", 12257 "Heavy Weight", "Backup", 12258 "A Services", "Home", 12259 "Previous", "B Services", "Cached" 12260 }; 12261 static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] { 12262 "native", 12263 "sys", "pers", "fore", 12264 "vis", "percept", 12265 "heavy", "backup", 12266 "servicea", "home", 12267 "prev", "serviceb", "cached" 12268 }; 12269 12270 private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime, 12271 long realtime, boolean isCheckinRequest, boolean isCompact) { 12272 if (isCheckinRequest || isCompact) { 12273 // short checkin version 12274 pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime); 12275 } else { 12276 pw.println("Applications Memory Usage (kB):"); 12277 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 12278 } 12279 } 12280 12281 final void dumpApplicationMemoryUsage(FileDescriptor fd, 12282 PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) { 12283 boolean dumpDetails = false; 12284 boolean dumpFullDetails = false; 12285 boolean dumpDalvik = false; 12286 boolean oomOnly = false; 12287 boolean isCompact = false; 12288 boolean localOnly = false; 12289 12290 int opti = 0; 12291 while (opti < args.length) { 12292 String opt = args[opti]; 12293 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 12294 break; 12295 } 12296 opti++; 12297 if ("-a".equals(opt)) { 12298 dumpDetails = true; 12299 dumpFullDetails = true; 12300 dumpDalvik = true; 12301 } else if ("-d".equals(opt)) { 12302 dumpDalvik = true; 12303 } else if ("-c".equals(opt)) { 12304 isCompact = true; 12305 } else if ("--oom".equals(opt)) { 12306 oomOnly = true; 12307 } else if ("--local".equals(opt)) { 12308 localOnly = true; 12309 } else if ("-h".equals(opt)) { 12310 pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]"); 12311 pw.println(" -a: include all available information for each process."); 12312 pw.println(" -d: include dalvik details when dumping process details."); 12313 pw.println(" -c: dump in a compact machine-parseable representation."); 12314 pw.println(" --oom: only show processes organized by oom adj."); 12315 pw.println(" --local: only collect details locally, don't call process."); 12316 pw.println("If [process] is specified it can be the name or "); 12317 pw.println("pid of a specific process to dump."); 12318 return; 12319 } else { 12320 pw.println("Unknown argument: " + opt + "; use -h for help"); 12321 } 12322 } 12323 12324 final boolean isCheckinRequest = scanArgs(args, "--checkin"); 12325 long uptime = SystemClock.uptimeMillis(); 12326 long realtime = SystemClock.elapsedRealtime(); 12327 final long[] tmpLong = new long[1]; 12328 12329 ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args); 12330 if (procs == null) { 12331 // No Java processes. Maybe they want to print a native process. 12332 if (args != null && args.length > opti 12333 && args[opti].charAt(0) != '-') { 12334 ArrayList<ProcessCpuTracker.Stats> nativeProcs 12335 = new ArrayList<ProcessCpuTracker.Stats>(); 12336 updateCpuStatsNow(); 12337 int findPid = -1; 12338 try { 12339 findPid = Integer.parseInt(args[opti]); 12340 } catch (NumberFormatException e) { 12341 } 12342 synchronized (mProcessCpuThread) { 12343 final int N = mProcessCpuTracker.countStats(); 12344 for (int i=0; i<N; i++) { 12345 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 12346 if (st.pid == findPid || (st.baseName != null 12347 && st.baseName.equals(args[opti]))) { 12348 nativeProcs.add(st); 12349 } 12350 } 12351 } 12352 if (nativeProcs.size() > 0) { 12353 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, 12354 isCompact); 12355 Debug.MemoryInfo mi = null; 12356 for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) { 12357 final ProcessCpuTracker.Stats r = nativeProcs.get(i); 12358 final int pid = r.pid; 12359 if (!isCheckinRequest && dumpDetails) { 12360 pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **"); 12361 } 12362 if (mi == null) { 12363 mi = new Debug.MemoryInfo(); 12364 } 12365 if (dumpDetails || (!brief && !oomOnly)) { 12366 Debug.getMemoryInfo(pid, mi); 12367 } else { 12368 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong); 12369 mi.dalvikPrivateDirty = (int)tmpLong[0]; 12370 } 12371 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails, 12372 dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0); 12373 if (isCheckinRequest) { 12374 pw.println(); 12375 } 12376 } 12377 return; 12378 } 12379 } 12380 pw.println("No process found for: " + args[opti]); 12381 return; 12382 } 12383 12384 if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest)) { 12385 dumpDetails = true; 12386 } 12387 12388 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact); 12389 12390 String[] innerArgs = new String[args.length-opti]; 12391 System.arraycopy(args, opti, innerArgs, 0, args.length-opti); 12392 12393 ArrayList<MemItem> procMems = new ArrayList<MemItem>(); 12394 final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>(); 12395 long nativePss=0, dalvikPss=0, otherPss=0; 12396 long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS]; 12397 12398 long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length]; 12399 ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[]) 12400 new ArrayList[DUMP_MEM_OOM_LABEL.length]; 12401 12402 long totalPss = 0; 12403 long cachedPss = 0; 12404 12405 Debug.MemoryInfo mi = null; 12406 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 12407 final ProcessRecord r = procs.get(i); 12408 final IApplicationThread thread; 12409 final int pid; 12410 final int oomAdj; 12411 final boolean hasActivities; 12412 synchronized (this) { 12413 thread = r.thread; 12414 pid = r.pid; 12415 oomAdj = r.getSetAdjWithServices(); 12416 hasActivities = r.activities.size() > 0; 12417 } 12418 if (thread != null) { 12419 if (!isCheckinRequest && dumpDetails) { 12420 pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **"); 12421 } 12422 if (mi == null) { 12423 mi = new Debug.MemoryInfo(); 12424 } 12425 if (dumpDetails || (!brief && !oomOnly)) { 12426 Debug.getMemoryInfo(pid, mi); 12427 } else { 12428 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong); 12429 mi.dalvikPrivateDirty = (int)tmpLong[0]; 12430 } 12431 if (dumpDetails) { 12432 if (localOnly) { 12433 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails, 12434 dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0); 12435 if (isCheckinRequest) { 12436 pw.println(); 12437 } 12438 } else { 12439 try { 12440 pw.flush(); 12441 thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails, 12442 dumpDalvik, innerArgs); 12443 } catch (RemoteException e) { 12444 if (!isCheckinRequest) { 12445 pw.println("Got RemoteException!"); 12446 pw.flush(); 12447 } 12448 } 12449 } 12450 } 12451 12452 final long myTotalPss = mi.getTotalPss(); 12453 final long myTotalUss = mi.getTotalUss(); 12454 12455 synchronized (this) { 12456 if (r.thread != null && oomAdj == r.getSetAdjWithServices()) { 12457 // Record this for posterity if the process has been stable. 12458 r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList); 12459 } 12460 } 12461 12462 if (!isCheckinRequest && mi != null) { 12463 totalPss += myTotalPss; 12464 MemItem pssItem = new MemItem(r.processName + " (pid " + pid + 12465 (hasActivities ? " / activities)" : ")"), 12466 r.processName, myTotalPss, pid, hasActivities); 12467 procMems.add(pssItem); 12468 procMemsMap.put(pid, pssItem); 12469 12470 nativePss += mi.nativePss; 12471 dalvikPss += mi.dalvikPss; 12472 otherPss += mi.otherPss; 12473 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 12474 long mem = mi.getOtherPss(j); 12475 miscPss[j] += mem; 12476 otherPss -= mem; 12477 } 12478 12479 if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 12480 cachedPss += myTotalPss; 12481 } 12482 12483 for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) { 12484 if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex] 12485 || oomIndex == (oomPss.length-1)) { 12486 oomPss[oomIndex] += myTotalPss; 12487 if (oomProcs[oomIndex] == null) { 12488 oomProcs[oomIndex] = new ArrayList<MemItem>(); 12489 } 12490 oomProcs[oomIndex].add(pssItem); 12491 break; 12492 } 12493 } 12494 } 12495 } 12496 } 12497 12498 if (!isCheckinRequest && procs.size() > 1) { 12499 // If we are showing aggregations, also look for native processes to 12500 // include so that our aggregations are more accurate. 12501 updateCpuStatsNow(); 12502 synchronized (mProcessCpuThread) { 12503 final int N = mProcessCpuTracker.countStats(); 12504 for (int i=0; i<N; i++) { 12505 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 12506 if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) { 12507 if (mi == null) { 12508 mi = new Debug.MemoryInfo(); 12509 } 12510 if (!brief && !oomOnly) { 12511 Debug.getMemoryInfo(st.pid, mi); 12512 } else { 12513 mi.nativePss = (int)Debug.getPss(st.pid, tmpLong); 12514 mi.nativePrivateDirty = (int)tmpLong[0]; 12515 } 12516 12517 final long myTotalPss = mi.getTotalPss(); 12518 totalPss += myTotalPss; 12519 12520 MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")", 12521 st.name, myTotalPss, st.pid, false); 12522 procMems.add(pssItem); 12523 12524 nativePss += mi.nativePss; 12525 dalvikPss += mi.dalvikPss; 12526 otherPss += mi.otherPss; 12527 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 12528 long mem = mi.getOtherPss(j); 12529 miscPss[j] += mem; 12530 otherPss -= mem; 12531 } 12532 oomPss[0] += myTotalPss; 12533 if (oomProcs[0] == null) { 12534 oomProcs[0] = new ArrayList<MemItem>(); 12535 } 12536 oomProcs[0].add(pssItem); 12537 } 12538 } 12539 } 12540 12541 ArrayList<MemItem> catMems = new ArrayList<MemItem>(); 12542 12543 catMems.add(new MemItem("Native", "Native", nativePss, -1)); 12544 catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2)); 12545 catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3)); 12546 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 12547 String label = Debug.MemoryInfo.getOtherLabel(j); 12548 catMems.add(new MemItem(label, label, miscPss[j], j)); 12549 } 12550 12551 ArrayList<MemItem> oomMems = new ArrayList<MemItem>(); 12552 for (int j=0; j<oomPss.length; j++) { 12553 if (oomPss[j] != 0) { 12554 String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j] 12555 : DUMP_MEM_OOM_LABEL[j]; 12556 MemItem item = new MemItem(label, label, oomPss[j], 12557 DUMP_MEM_OOM_ADJ[j]); 12558 item.subitems = oomProcs[j]; 12559 oomMems.add(item); 12560 } 12561 } 12562 12563 if (!brief && !oomOnly && !isCompact) { 12564 pw.println(); 12565 pw.println("Total PSS by process:"); 12566 dumpMemItems(pw, " ", "proc", procMems, true, isCompact); 12567 pw.println(); 12568 } 12569 if (!isCompact) { 12570 pw.println("Total PSS by OOM adjustment:"); 12571 } 12572 dumpMemItems(pw, " ", "oom", oomMems, false, isCompact); 12573 if (!brief && !oomOnly) { 12574 PrintWriter out = categoryPw != null ? categoryPw : pw; 12575 if (!isCompact) { 12576 out.println(); 12577 out.println("Total PSS by category:"); 12578 } 12579 dumpMemItems(out, " ", "cat", catMems, true, isCompact); 12580 } 12581 if (!isCompact) { 12582 pw.println(); 12583 } 12584 MemInfoReader memInfo = new MemInfoReader(); 12585 memInfo.readMemInfo(); 12586 if (!brief) { 12587 if (!isCompact) { 12588 pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb()); 12589 pw.print(" kB (status "); 12590 switch (mLastMemoryLevel) { 12591 case ProcessStats.ADJ_MEM_FACTOR_NORMAL: 12592 pw.println("normal)"); 12593 break; 12594 case ProcessStats.ADJ_MEM_FACTOR_MODERATE: 12595 pw.println("moderate)"); 12596 break; 12597 case ProcessStats.ADJ_MEM_FACTOR_LOW: 12598 pw.println("low)"); 12599 break; 12600 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL: 12601 pw.println("critical)"); 12602 break; 12603 default: 12604 pw.print(mLastMemoryLevel); 12605 pw.println(")"); 12606 break; 12607 } 12608 pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb() 12609 + memInfo.getFreeSizeKb()); pw.print(" kB ("); 12610 pw.print(cachedPss); pw.print(" cached pss + "); 12611 pw.print(memInfo.getCachedSizeKb()); pw.print(" cached + "); 12612 pw.print(memInfo.getFreeSizeKb()); pw.println(" free)"); 12613 } else { 12614 pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(","); 12615 pw.print(cachedPss + memInfo.getCachedSizeKb() 12616 + memInfo.getFreeSizeKb()); pw.print(","); 12617 pw.println(totalPss - cachedPss); 12618 } 12619 } 12620 if (!isCompact) { 12621 pw.print(" Used RAM: "); pw.print(totalPss - cachedPss 12622 + memInfo.getBuffersSizeKb() + memInfo.getShmemSizeKb() 12623 + memInfo.getSlabSizeKb()); pw.print(" kB ("); 12624 pw.print(totalPss - cachedPss); pw.print(" used pss + "); 12625 pw.print(memInfo.getBuffersSizeKb()); pw.print(" buffers + "); 12626 pw.print(memInfo.getShmemSizeKb()); pw.print(" shmem + "); 12627 pw.print(memInfo.getSlabSizeKb()); pw.println(" slab)"); 12628 pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb() 12629 - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb() 12630 - memInfo.getBuffersSizeKb() - memInfo.getShmemSizeKb() 12631 - memInfo.getSlabSizeKb()); pw.println(" kB"); 12632 } 12633 if (!brief) { 12634 if (memInfo.getZramTotalSizeKb() != 0) { 12635 if (!isCompact) { 12636 pw.print(" ZRAM: "); pw.print(memInfo.getZramTotalSizeKb()); 12637 pw.print(" kB physical used for "); 12638 pw.print(memInfo.getSwapTotalSizeKb() 12639 - memInfo.getSwapFreeSizeKb()); 12640 pw.print(" kB in swap ("); 12641 pw.print(memInfo.getSwapTotalSizeKb()); 12642 pw.println(" kB total swap)"); 12643 } else { 12644 pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(","); 12645 pw.print(memInfo.getSwapTotalSizeKb()); pw.print(","); 12646 pw.println(memInfo.getSwapFreeSizeKb()); 12647 } 12648 } 12649 final int[] SINGLE_LONG_FORMAT = new int[] { 12650 Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG 12651 }; 12652 long[] longOut = new long[1]; 12653 Process.readProcFile("/sys/kernel/mm/ksm/pages_shared", 12654 SINGLE_LONG_FORMAT, null, longOut, null); 12655 long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024; 12656 longOut[0] = 0; 12657 Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing", 12658 SINGLE_LONG_FORMAT, null, longOut, null); 12659 long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024; 12660 longOut[0] = 0; 12661 Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared", 12662 SINGLE_LONG_FORMAT, null, longOut, null); 12663 long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024; 12664 longOut[0] = 0; 12665 Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile", 12666 SINGLE_LONG_FORMAT, null, longOut, null); 12667 long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024; 12668 if (!isCompact) { 12669 if (sharing != 0 || shared != 0 || unshared != 0 || voltile != 0) { 12670 pw.print(" KSM: "); pw.print(sharing); 12671 pw.print(" kB saved from shared "); 12672 pw.print(shared); pw.println(" kB"); 12673 pw.print(" "); pw.print(unshared); pw.print(" kB unshared; "); 12674 pw.print(voltile); pw.println(" kB volatile"); 12675 } 12676 pw.print(" Tuning: "); 12677 pw.print(ActivityManager.staticGetMemoryClass()); 12678 pw.print(" (large "); 12679 pw.print(ActivityManager.staticGetLargeMemoryClass()); 12680 pw.print("), oom "); 12681 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024); 12682 pw.print(" kB"); 12683 pw.print(", restore limit "); 12684 pw.print(mProcessList.getCachedRestoreThresholdKb()); 12685 pw.print(" kB"); 12686 if (ActivityManager.isLowRamDeviceStatic()) { 12687 pw.print(" (low-ram)"); 12688 } 12689 if (ActivityManager.isHighEndGfx()) { 12690 pw.print(" (high-end-gfx)"); 12691 } 12692 pw.println(); 12693 } else { 12694 pw.print("ksm,"); pw.print(sharing); pw.print(","); 12695 pw.print(shared); pw.print(","); pw.print(unshared); pw.print(","); 12696 pw.println(voltile); 12697 pw.print("tuning,"); 12698 pw.print(ActivityManager.staticGetMemoryClass()); 12699 pw.print(','); 12700 pw.print(ActivityManager.staticGetLargeMemoryClass()); 12701 pw.print(','); 12702 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024); 12703 if (ActivityManager.isLowRamDeviceStatic()) { 12704 pw.print(",low-ram"); 12705 } 12706 if (ActivityManager.isHighEndGfx()) { 12707 pw.print(",high-end-gfx"); 12708 } 12709 pw.println(); 12710 } 12711 } 12712 } 12713 } 12714 12715 /** 12716 * Searches array of arguments for the specified string 12717 * @param args array of argument strings 12718 * @param value value to search for 12719 * @return true if the value is contained in the array 12720 */ 12721 private static boolean scanArgs(String[] args, String value) { 12722 if (args != null) { 12723 for (String arg : args) { 12724 if (value.equals(arg)) { 12725 return true; 12726 } 12727 } 12728 } 12729 return false; 12730 } 12731 12732 private final boolean removeDyingProviderLocked(ProcessRecord proc, 12733 ContentProviderRecord cpr, boolean always) { 12734 final boolean inLaunching = mLaunchingProviders.contains(cpr); 12735 12736 if (!inLaunching || always) { 12737 synchronized (cpr) { 12738 cpr.launchingApp = null; 12739 cpr.notifyAll(); 12740 } 12741 mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid)); 12742 String names[] = cpr.info.authority.split(";"); 12743 for (int j = 0; j < names.length; j++) { 12744 mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid)); 12745 } 12746 } 12747 12748 for (int i=0; i<cpr.connections.size(); i++) { 12749 ContentProviderConnection conn = cpr.connections.get(i); 12750 if (conn.waiting) { 12751 // If this connection is waiting for the provider, then we don't 12752 // need to mess with its process unless we are always removing 12753 // or for some reason the provider is not currently launching. 12754 if (inLaunching && !always) { 12755 continue; 12756 } 12757 } 12758 ProcessRecord capp = conn.client; 12759 conn.dead = true; 12760 if (conn.stableCount > 0) { 12761 if (!capp.persistent && capp.thread != null 12762 && capp.pid != 0 12763 && capp.pid != MY_PID) { 12764 killUnneededProcessLocked(capp, "depends on provider " 12765 + cpr.name.flattenToShortString() 12766 + " in dying proc " + (proc != null ? proc.processName : "??")); 12767 } 12768 } else if (capp.thread != null && conn.provider.provider != null) { 12769 try { 12770 capp.thread.unstableProviderDied(conn.provider.provider.asBinder()); 12771 } catch (RemoteException e) { 12772 } 12773 // In the protocol here, we don't expect the client to correctly 12774 // clean up this connection, we'll just remove it. 12775 cpr.connections.remove(i); 12776 conn.client.conProviders.remove(conn); 12777 } 12778 } 12779 12780 if (inLaunching && always) { 12781 mLaunchingProviders.remove(cpr); 12782 } 12783 return inLaunching; 12784 } 12785 12786 /** 12787 * Main code for cleaning up a process when it has gone away. This is 12788 * called both as a result of the process dying, or directly when stopping 12789 * a process when running in single process mode. 12790 */ 12791 private final void cleanUpApplicationRecordLocked(ProcessRecord app, 12792 boolean restarting, boolean allowRestart, int index) { 12793 if (index >= 0) { 12794 removeLruProcessLocked(app); 12795 ProcessList.remove(app.pid); 12796 } 12797 12798 mProcessesToGc.remove(app); 12799 mPendingPssProcesses.remove(app); 12800 12801 // Dismiss any open dialogs. 12802 if (app.crashDialog != null && !app.forceCrashReport) { 12803 app.crashDialog.dismiss(); 12804 app.crashDialog = null; 12805 } 12806 if (app.anrDialog != null) { 12807 app.anrDialog.dismiss(); 12808 app.anrDialog = null; 12809 } 12810 if (app.waitDialog != null) { 12811 app.waitDialog.dismiss(); 12812 app.waitDialog = null; 12813 } 12814 12815 app.crashing = false; 12816 app.notResponding = false; 12817 12818 app.resetPackageList(mProcessStats); 12819 app.unlinkDeathRecipient(); 12820 app.makeInactive(mProcessStats); 12821 app.forcingToForeground = null; 12822 updateProcessForegroundLocked(app, false, false); 12823 app.foregroundActivities = false; 12824 app.hasShownUi = false; 12825 app.treatLikeActivity = false; 12826 app.hasAboveClient = false; 12827 app.hasClientActivities = false; 12828 12829 mServices.killServicesLocked(app, allowRestart); 12830 12831 boolean restart = false; 12832 12833 // Remove published content providers. 12834 for (int i=app.pubProviders.size()-1; i>=0; i--) { 12835 ContentProviderRecord cpr = app.pubProviders.valueAt(i); 12836 final boolean always = app.bad || !allowRestart; 12837 if (removeDyingProviderLocked(app, cpr, always) || always) { 12838 // We left the provider in the launching list, need to 12839 // restart it. 12840 restart = true; 12841 } 12842 12843 cpr.provider = null; 12844 cpr.proc = null; 12845 } 12846 app.pubProviders.clear(); 12847 12848 // Take care of any launching providers waiting for this process. 12849 if (checkAppInLaunchingProvidersLocked(app, false)) { 12850 restart = true; 12851 } 12852 12853 // Unregister from connected content providers. 12854 if (!app.conProviders.isEmpty()) { 12855 for (int i=0; i<app.conProviders.size(); i++) { 12856 ContentProviderConnection conn = app.conProviders.get(i); 12857 conn.provider.connections.remove(conn); 12858 } 12859 app.conProviders.clear(); 12860 } 12861 12862 // At this point there may be remaining entries in mLaunchingProviders 12863 // where we were the only one waiting, so they are no longer of use. 12864 // Look for these and clean up if found. 12865 // XXX Commented out for now. Trying to figure out a way to reproduce 12866 // the actual situation to identify what is actually going on. 12867 if (false) { 12868 for (int i=0; i<mLaunchingProviders.size(); i++) { 12869 ContentProviderRecord cpr = (ContentProviderRecord) 12870 mLaunchingProviders.get(i); 12871 if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) { 12872 synchronized (cpr) { 12873 cpr.launchingApp = null; 12874 cpr.notifyAll(); 12875 } 12876 } 12877 } 12878 } 12879 12880 skipCurrentReceiverLocked(app); 12881 12882 // Unregister any receivers. 12883 for (int i=app.receivers.size()-1; i>=0; i--) { 12884 removeReceiverLocked(app.receivers.valueAt(i)); 12885 } 12886 app.receivers.clear(); 12887 12888 // If the app is undergoing backup, tell the backup manager about it 12889 if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) { 12890 if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App " 12891 + mBackupTarget.appInfo + " died during backup"); 12892 try { 12893 IBackupManager bm = IBackupManager.Stub.asInterface( 12894 ServiceManager.getService(Context.BACKUP_SERVICE)); 12895 bm.agentDisconnected(app.info.packageName); 12896 } catch (RemoteException e) { 12897 // can't happen; backup manager is local 12898 } 12899 } 12900 12901 for (int i = mPendingProcessChanges.size()-1; i>=0; i--) { 12902 ProcessChangeItem item = mPendingProcessChanges.get(i); 12903 if (item.pid == app.pid) { 12904 mPendingProcessChanges.remove(i); 12905 mAvailProcessChanges.add(item); 12906 } 12907 } 12908 mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget(); 12909 12910 // If the caller is restarting this app, then leave it in its 12911 // current lists and let the caller take care of it. 12912 if (restarting) { 12913 return; 12914 } 12915 12916 if (!app.persistent || app.isolated) { 12917 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, 12918 "Removing non-persistent process during cleanup: " + app); 12919 mProcessNames.remove(app.processName, app.uid); 12920 mIsolatedProcesses.remove(app.uid); 12921 if (mHeavyWeightProcess == app) { 12922 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 12923 mHeavyWeightProcess.userId, 0)); 12924 mHeavyWeightProcess = null; 12925 } 12926 } else if (!app.removed) { 12927 // This app is persistent, so we need to keep its record around. 12928 // If it is not already on the pending app list, add it there 12929 // and start a new process for it. 12930 if (mPersistentStartingProcesses.indexOf(app) < 0) { 12931 mPersistentStartingProcesses.add(app); 12932 restart = true; 12933 } 12934 } 12935 if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG, 12936 "Clean-up removing on hold: " + app); 12937 mProcessesOnHold.remove(app); 12938 12939 if (app == mHomeProcess) { 12940 mHomeProcess = null; 12941 } 12942 if (app == mPreviousProcess) { 12943 mPreviousProcess = null; 12944 } 12945 12946 if (restart && !app.isolated) { 12947 // We have components that still need to be running in the 12948 // process, so re-launch it. 12949 mProcessNames.put(app.processName, app.uid, app); 12950 startProcessLocked(app, "restart", app.processName); 12951 } else if (app.pid > 0 && app.pid != MY_PID) { 12952 // Goodbye! 12953 boolean removed; 12954 synchronized (mPidsSelfLocked) { 12955 mPidsSelfLocked.remove(app.pid); 12956 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 12957 } 12958 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH, 12959 app.processName, app.info.uid); 12960 if (app.isolated) { 12961 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 12962 } 12963 app.setPid(0); 12964 } 12965 } 12966 12967 boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) { 12968 // Look through the content providers we are waiting to have launched, 12969 // and if any run in this process then either schedule a restart of 12970 // the process or kill the client waiting for it if this process has 12971 // gone bad. 12972 int NL = mLaunchingProviders.size(); 12973 boolean restart = false; 12974 for (int i=0; i<NL; i++) { 12975 ContentProviderRecord cpr = mLaunchingProviders.get(i); 12976 if (cpr.launchingApp == app) { 12977 if (!alwaysBad && !app.bad) { 12978 restart = true; 12979 } else { 12980 removeDyingProviderLocked(app, cpr, true); 12981 // cpr should have been removed from mLaunchingProviders 12982 NL = mLaunchingProviders.size(); 12983 i--; 12984 } 12985 } 12986 } 12987 return restart; 12988 } 12989 12990 // ========================================================= 12991 // SERVICES 12992 // ========================================================= 12993 12994 public List<ActivityManager.RunningServiceInfo> getServices(int maxNum, 12995 int flags) { 12996 enforceNotIsolatedCaller("getServices"); 12997 synchronized (this) { 12998 return mServices.getRunningServiceInfoLocked(maxNum, flags); 12999 } 13000 } 13001 13002 public PendingIntent getRunningServiceControlPanel(ComponentName name) { 13003 enforceNotIsolatedCaller("getRunningServiceControlPanel"); 13004 synchronized (this) { 13005 return mServices.getRunningServiceControlPanelLocked(name); 13006 } 13007 } 13008 13009 public ComponentName startService(IApplicationThread caller, Intent service, 13010 String resolvedType, int userId) { 13011 enforceNotIsolatedCaller("startService"); 13012 // Refuse possible leaked file descriptors 13013 if (service != null && service.hasFileDescriptors() == true) { 13014 throw new IllegalArgumentException("File descriptors passed in Intent"); 13015 } 13016 13017 if (DEBUG_SERVICE) 13018 Slog.v(TAG, "startService: " + service + " type=" + resolvedType); 13019 synchronized(this) { 13020 final int callingPid = Binder.getCallingPid(); 13021 final int callingUid = Binder.getCallingUid(); 13022 final long origId = Binder.clearCallingIdentity(); 13023 ComponentName res = mServices.startServiceLocked(caller, service, 13024 resolvedType, callingPid, callingUid, userId); 13025 Binder.restoreCallingIdentity(origId); 13026 return res; 13027 } 13028 } 13029 13030 ComponentName startServiceInPackage(int uid, 13031 Intent service, String resolvedType, int userId) { 13032 synchronized(this) { 13033 if (DEBUG_SERVICE) 13034 Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType); 13035 final long origId = Binder.clearCallingIdentity(); 13036 ComponentName res = mServices.startServiceLocked(null, service, 13037 resolvedType, -1, uid, userId); 13038 Binder.restoreCallingIdentity(origId); 13039 return res; 13040 } 13041 } 13042 13043 public int stopService(IApplicationThread caller, Intent service, 13044 String resolvedType, int userId) { 13045 enforceNotIsolatedCaller("stopService"); 13046 // Refuse possible leaked file descriptors 13047 if (service != null && service.hasFileDescriptors() == true) { 13048 throw new IllegalArgumentException("File descriptors passed in Intent"); 13049 } 13050 13051 synchronized(this) { 13052 return mServices.stopServiceLocked(caller, service, resolvedType, userId); 13053 } 13054 } 13055 13056 public IBinder peekService(Intent service, String resolvedType) { 13057 enforceNotIsolatedCaller("peekService"); 13058 // Refuse possible leaked file descriptors 13059 if (service != null && service.hasFileDescriptors() == true) { 13060 throw new IllegalArgumentException("File descriptors passed in Intent"); 13061 } 13062 synchronized(this) { 13063 return mServices.peekServiceLocked(service, resolvedType); 13064 } 13065 } 13066 13067 public boolean stopServiceToken(ComponentName className, IBinder token, 13068 int startId) { 13069 synchronized(this) { 13070 return mServices.stopServiceTokenLocked(className, token, startId); 13071 } 13072 } 13073 13074 public void setServiceForeground(ComponentName className, IBinder token, 13075 int id, Notification notification, boolean removeNotification) { 13076 synchronized(this) { 13077 mServices.setServiceForegroundLocked(className, token, id, notification, 13078 removeNotification); 13079 } 13080 } 13081 13082 public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll, 13083 boolean requireFull, String name, String callerPackage) { 13084 final int callingUserId = UserHandle.getUserId(callingUid); 13085 if (callingUserId != userId) { 13086 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 13087 if ((requireFull || checkComponentPermission( 13088 android.Manifest.permission.INTERACT_ACROSS_USERS, 13089 callingPid, callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) 13090 && checkComponentPermission( 13091 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 13092 callingPid, callingUid, -1, true) 13093 != PackageManager.PERMISSION_GRANTED) { 13094 if (userId == UserHandle.USER_CURRENT_OR_SELF) { 13095 // In this case, they would like to just execute as their 13096 // owner user instead of failing. 13097 userId = callingUserId; 13098 } else { 13099 StringBuilder builder = new StringBuilder(128); 13100 builder.append("Permission Denial: "); 13101 builder.append(name); 13102 if (callerPackage != null) { 13103 builder.append(" from "); 13104 builder.append(callerPackage); 13105 } 13106 builder.append(" asks to run as user "); 13107 builder.append(userId); 13108 builder.append(" but is calling from user "); 13109 builder.append(UserHandle.getUserId(callingUid)); 13110 builder.append("; this requires "); 13111 builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL); 13112 if (!requireFull) { 13113 builder.append(" or "); 13114 builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS); 13115 } 13116 String msg = builder.toString(); 13117 Slog.w(TAG, msg); 13118 throw new SecurityException(msg); 13119 } 13120 } 13121 } 13122 if (userId == UserHandle.USER_CURRENT 13123 || userId == UserHandle.USER_CURRENT_OR_SELF) { 13124 // Note that we may be accessing this outside of a lock... 13125 // shouldn't be a big deal, if this is being called outside 13126 // of a locked context there is intrinsically a race with 13127 // the value the caller will receive and someone else changing it. 13128 userId = mCurrentUserId; 13129 } 13130 if (!allowAll && userId < 0) { 13131 throw new IllegalArgumentException( 13132 "Call does not support special user #" + userId); 13133 } 13134 } 13135 return userId; 13136 } 13137 13138 boolean isSingleton(String componentProcessName, ApplicationInfo aInfo, 13139 String className, int flags) { 13140 boolean result = false; 13141 if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) { 13142 if ((flags&ServiceInfo.FLAG_SINGLE_USER) != 0) { 13143 if (ActivityManager.checkUidPermission( 13144 android.Manifest.permission.INTERACT_ACROSS_USERS, 13145 aInfo.uid) != PackageManager.PERMISSION_GRANTED) { 13146 ComponentName comp = new ComponentName(aInfo.packageName, className); 13147 String msg = "Permission Denial: Component " + comp.flattenToShortString() 13148 + " requests FLAG_SINGLE_USER, but app does not hold " 13149 + android.Manifest.permission.INTERACT_ACROSS_USERS; 13150 Slog.w(TAG, msg); 13151 throw new SecurityException(msg); 13152 } 13153 result = true; 13154 } 13155 } else if (componentProcessName == aInfo.packageName) { 13156 result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0; 13157 } else if ("system".equals(componentProcessName)) { 13158 result = true; 13159 } 13160 if (DEBUG_MU) { 13161 Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo 13162 + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result); 13163 } 13164 return result; 13165 } 13166 13167 public int bindService(IApplicationThread caller, IBinder token, 13168 Intent service, String resolvedType, 13169 IServiceConnection connection, int flags, int userId) { 13170 enforceNotIsolatedCaller("bindService"); 13171 // Refuse possible leaked file descriptors 13172 if (service != null && service.hasFileDescriptors() == true) { 13173 throw new IllegalArgumentException("File descriptors passed in Intent"); 13174 } 13175 13176 synchronized(this) { 13177 return mServices.bindServiceLocked(caller, token, service, resolvedType, 13178 connection, flags, userId); 13179 } 13180 } 13181 13182 public boolean unbindService(IServiceConnection connection) { 13183 synchronized (this) { 13184 return mServices.unbindServiceLocked(connection); 13185 } 13186 } 13187 13188 public void publishService(IBinder token, Intent intent, IBinder service) { 13189 // Refuse possible leaked file descriptors 13190 if (intent != null && intent.hasFileDescriptors() == true) { 13191 throw new IllegalArgumentException("File descriptors passed in Intent"); 13192 } 13193 13194 synchronized(this) { 13195 if (!(token instanceof ServiceRecord)) { 13196 throw new IllegalArgumentException("Invalid service token"); 13197 } 13198 mServices.publishServiceLocked((ServiceRecord)token, intent, service); 13199 } 13200 } 13201 13202 public void unbindFinished(IBinder token, Intent intent, boolean doRebind) { 13203 // Refuse possible leaked file descriptors 13204 if (intent != null && intent.hasFileDescriptors() == true) { 13205 throw new IllegalArgumentException("File descriptors passed in Intent"); 13206 } 13207 13208 synchronized(this) { 13209 mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind); 13210 } 13211 } 13212 13213 public void serviceDoneExecuting(IBinder token, int type, int startId, int res) { 13214 synchronized(this) { 13215 if (!(token instanceof ServiceRecord)) { 13216 throw new IllegalArgumentException("Invalid service token"); 13217 } 13218 mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res); 13219 } 13220 } 13221 13222 // ========================================================= 13223 // BACKUP AND RESTORE 13224 // ========================================================= 13225 13226 // Cause the target app to be launched if necessary and its backup agent 13227 // instantiated. The backup agent will invoke backupAgentCreated() on the 13228 // activity manager to announce its creation. 13229 public boolean bindBackupAgent(ApplicationInfo app, int backupMode) { 13230 if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode); 13231 enforceCallingPermission("android.permission.BACKUP", "bindBackupAgent"); 13232 13233 synchronized(this) { 13234 // !!! TODO: currently no check here that we're already bound 13235 BatteryStatsImpl.Uid.Pkg.Serv ss = null; 13236 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 13237 synchronized (stats) { 13238 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name); 13239 } 13240 13241 // Backup agent is now in use, its package can't be stopped. 13242 try { 13243 AppGlobals.getPackageManager().setPackageStoppedState( 13244 app.packageName, false, UserHandle.getUserId(app.uid)); 13245 } catch (RemoteException e) { 13246 } catch (IllegalArgumentException e) { 13247 Slog.w(TAG, "Failed trying to unstop package " 13248 + app.packageName + ": " + e); 13249 } 13250 13251 BackupRecord r = new BackupRecord(ss, app, backupMode); 13252 ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL) 13253 ? new ComponentName(app.packageName, app.backupAgentName) 13254 : new ComponentName("android", "FullBackupAgent"); 13255 // startProcessLocked() returns existing proc's record if it's already running 13256 ProcessRecord proc = startProcessLocked(app.processName, app, 13257 false, 0, "backup", hostingName, false, false, false); 13258 if (proc == null) { 13259 Slog.e(TAG, "Unable to start backup agent process " + r); 13260 return false; 13261 } 13262 13263 r.app = proc; 13264 mBackupTarget = r; 13265 mBackupAppName = app.packageName; 13266 13267 // Try not to kill the process during backup 13268 updateOomAdjLocked(proc); 13269 13270 // If the process is already attached, schedule the creation of the backup agent now. 13271 // If it is not yet live, this will be done when it attaches to the framework. 13272 if (proc.thread != null) { 13273 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc); 13274 try { 13275 proc.thread.scheduleCreateBackupAgent(app, 13276 compatibilityInfoForPackageLocked(app), backupMode); 13277 } catch (RemoteException e) { 13278 // Will time out on the backup manager side 13279 } 13280 } else { 13281 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach"); 13282 } 13283 // Invariants: at this point, the target app process exists and the application 13284 // is either already running or in the process of coming up. mBackupTarget and 13285 // mBackupAppName describe the app, so that when it binds back to the AM we 13286 // know that it's scheduled for a backup-agent operation. 13287 } 13288 13289 return true; 13290 } 13291 13292 @Override 13293 public void clearPendingBackup() { 13294 if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup"); 13295 enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup"); 13296 13297 synchronized (this) { 13298 mBackupTarget = null; 13299 mBackupAppName = null; 13300 } 13301 } 13302 13303 // A backup agent has just come up 13304 public void backupAgentCreated(String agentPackageName, IBinder agent) { 13305 if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName 13306 + " = " + agent); 13307 13308 synchronized(this) { 13309 if (!agentPackageName.equals(mBackupAppName)) { 13310 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!"); 13311 return; 13312 } 13313 } 13314 13315 long oldIdent = Binder.clearCallingIdentity(); 13316 try { 13317 IBackupManager bm = IBackupManager.Stub.asInterface( 13318 ServiceManager.getService(Context.BACKUP_SERVICE)); 13319 bm.agentConnected(agentPackageName, agent); 13320 } catch (RemoteException e) { 13321 // can't happen; the backup manager service is local 13322 } catch (Exception e) { 13323 Slog.w(TAG, "Exception trying to deliver BackupAgent binding: "); 13324 e.printStackTrace(); 13325 } finally { 13326 Binder.restoreCallingIdentity(oldIdent); 13327 } 13328 } 13329 13330 // done with this agent 13331 public void unbindBackupAgent(ApplicationInfo appInfo) { 13332 if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo); 13333 if (appInfo == null) { 13334 Slog.w(TAG, "unbind backup agent for null app"); 13335 return; 13336 } 13337 13338 synchronized(this) { 13339 try { 13340 if (mBackupAppName == null) { 13341 Slog.w(TAG, "Unbinding backup agent with no active backup"); 13342 return; 13343 } 13344 13345 if (!mBackupAppName.equals(appInfo.packageName)) { 13346 Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target"); 13347 return; 13348 } 13349 13350 // Not backing this app up any more; reset its OOM adjustment 13351 final ProcessRecord proc = mBackupTarget.app; 13352 updateOomAdjLocked(proc); 13353 13354 // If the app crashed during backup, 'thread' will be null here 13355 if (proc.thread != null) { 13356 try { 13357 proc.thread.scheduleDestroyBackupAgent(appInfo, 13358 compatibilityInfoForPackageLocked(appInfo)); 13359 } catch (Exception e) { 13360 Slog.e(TAG, "Exception when unbinding backup agent:"); 13361 e.printStackTrace(); 13362 } 13363 } 13364 } finally { 13365 mBackupTarget = null; 13366 mBackupAppName = null; 13367 } 13368 } 13369 } 13370 // ========================================================= 13371 // BROADCASTS 13372 // ========================================================= 13373 13374 private final List getStickiesLocked(String action, IntentFilter filter, 13375 List cur, int userId) { 13376 final ContentResolver resolver = mContext.getContentResolver(); 13377 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 13378 if (stickies == null) { 13379 return cur; 13380 } 13381 final ArrayList<Intent> list = stickies.get(action); 13382 if (list == null) { 13383 return cur; 13384 } 13385 int N = list.size(); 13386 for (int i=0; i<N; i++) { 13387 Intent intent = list.get(i); 13388 if (filter.match(resolver, intent, true, TAG) >= 0) { 13389 if (cur == null) { 13390 cur = new ArrayList<Intent>(); 13391 } 13392 cur.add(intent); 13393 } 13394 } 13395 return cur; 13396 } 13397 13398 boolean isPendingBroadcastProcessLocked(int pid) { 13399 return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid) 13400 || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid); 13401 } 13402 13403 void skipPendingBroadcastLocked(int pid) { 13404 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 13405 for (BroadcastQueue queue : mBroadcastQueues) { 13406 queue.skipPendingBroadcastLocked(pid); 13407 } 13408 } 13409 13410 // The app just attached; send any pending broadcasts that it should receive 13411 boolean sendPendingBroadcastsLocked(ProcessRecord app) { 13412 boolean didSomething = false; 13413 for (BroadcastQueue queue : mBroadcastQueues) { 13414 didSomething |= queue.sendPendingBroadcastsLocked(app); 13415 } 13416 return didSomething; 13417 } 13418 13419 public Intent registerReceiver(IApplicationThread caller, String callerPackage, 13420 IIntentReceiver receiver, IntentFilter filter, String permission, int userId) { 13421 enforceNotIsolatedCaller("registerReceiver"); 13422 int callingUid; 13423 int callingPid; 13424 synchronized(this) { 13425 ProcessRecord callerApp = null; 13426 if (caller != null) { 13427 callerApp = getRecordForAppLocked(caller); 13428 if (callerApp == null) { 13429 throw new SecurityException( 13430 "Unable to find app for caller " + caller 13431 + " (pid=" + Binder.getCallingPid() 13432 + ") when registering receiver " + receiver); 13433 } 13434 if (callerApp.info.uid != Process.SYSTEM_UID && 13435 !callerApp.pkgList.containsKey(callerPackage) && 13436 !"android".equals(callerPackage)) { 13437 throw new SecurityException("Given caller package " + callerPackage 13438 + " is not running in process " + callerApp); 13439 } 13440 callingUid = callerApp.info.uid; 13441 callingPid = callerApp.pid; 13442 } else { 13443 callerPackage = null; 13444 callingUid = Binder.getCallingUid(); 13445 callingPid = Binder.getCallingPid(); 13446 } 13447 13448 userId = this.handleIncomingUser(callingPid, callingUid, userId, 13449 true, true, "registerReceiver", callerPackage); 13450 13451 List allSticky = null; 13452 13453 // Look for any matching sticky broadcasts... 13454 Iterator actions = filter.actionsIterator(); 13455 if (actions != null) { 13456 while (actions.hasNext()) { 13457 String action = (String)actions.next(); 13458 allSticky = getStickiesLocked(action, filter, allSticky, 13459 UserHandle.USER_ALL); 13460 allSticky = getStickiesLocked(action, filter, allSticky, 13461 UserHandle.getUserId(callingUid)); 13462 } 13463 } else { 13464 allSticky = getStickiesLocked(null, filter, allSticky, 13465 UserHandle.USER_ALL); 13466 allSticky = getStickiesLocked(null, filter, allSticky, 13467 UserHandle.getUserId(callingUid)); 13468 } 13469 13470 // The first sticky in the list is returned directly back to 13471 // the client. 13472 Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null; 13473 13474 if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter 13475 + ": " + sticky); 13476 13477 if (receiver == null) { 13478 return sticky; 13479 } 13480 13481 ReceiverList rl 13482 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder()); 13483 if (rl == null) { 13484 rl = new ReceiverList(this, callerApp, callingPid, callingUid, 13485 userId, receiver); 13486 if (rl.app != null) { 13487 rl.app.receivers.add(rl); 13488 } else { 13489 try { 13490 receiver.asBinder().linkToDeath(rl, 0); 13491 } catch (RemoteException e) { 13492 return sticky; 13493 } 13494 rl.linkedToDeath = true; 13495 } 13496 mRegisteredReceivers.put(receiver.asBinder(), rl); 13497 } else if (rl.uid != callingUid) { 13498 throw new IllegalArgumentException( 13499 "Receiver requested to register for uid " + callingUid 13500 + " was previously registered for uid " + rl.uid); 13501 } else if (rl.pid != callingPid) { 13502 throw new IllegalArgumentException( 13503 "Receiver requested to register for pid " + callingPid 13504 + " was previously registered for pid " + rl.pid); 13505 } else if (rl.userId != userId) { 13506 throw new IllegalArgumentException( 13507 "Receiver requested to register for user " + userId 13508 + " was previously registered for user " + rl.userId); 13509 } 13510 BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage, 13511 permission, callingUid, userId); 13512 rl.add(bf); 13513 if (!bf.debugCheck()) { 13514 Slog.w(TAG, "==> For Dynamic broadast"); 13515 } 13516 mReceiverResolver.addFilter(bf); 13517 13518 // Enqueue broadcasts for all existing stickies that match 13519 // this filter. 13520 if (allSticky != null) { 13521 ArrayList receivers = new ArrayList(); 13522 receivers.add(bf); 13523 13524 int N = allSticky.size(); 13525 for (int i=0; i<N; i++) { 13526 Intent intent = (Intent)allSticky.get(i); 13527 BroadcastQueue queue = broadcastQueueForIntent(intent); 13528 BroadcastRecord r = new BroadcastRecord(queue, intent, null, 13529 null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0, 13530 null, null, false, true, true, -1); 13531 queue.enqueueParallelBroadcastLocked(r); 13532 queue.scheduleBroadcastsLocked(); 13533 } 13534 } 13535 13536 return sticky; 13537 } 13538 } 13539 13540 public void unregisterReceiver(IIntentReceiver receiver) { 13541 if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver); 13542 13543 final long origId = Binder.clearCallingIdentity(); 13544 try { 13545 boolean doTrim = false; 13546 13547 synchronized(this) { 13548 ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder()); 13549 if (rl != null) { 13550 if (rl.curBroadcast != null) { 13551 BroadcastRecord r = rl.curBroadcast; 13552 final boolean doNext = finishReceiverLocked( 13553 receiver.asBinder(), r.resultCode, r.resultData, 13554 r.resultExtras, r.resultAbort); 13555 if (doNext) { 13556 doTrim = true; 13557 r.queue.processNextBroadcast(false); 13558 } 13559 } 13560 13561 if (rl.app != null) { 13562 rl.app.receivers.remove(rl); 13563 } 13564 removeReceiverLocked(rl); 13565 if (rl.linkedToDeath) { 13566 rl.linkedToDeath = false; 13567 rl.receiver.asBinder().unlinkToDeath(rl, 0); 13568 } 13569 } 13570 } 13571 13572 // If we actually concluded any broadcasts, we might now be able 13573 // to trim the recipients' apps from our working set 13574 if (doTrim) { 13575 trimApplications(); 13576 return; 13577 } 13578 13579 } finally { 13580 Binder.restoreCallingIdentity(origId); 13581 } 13582 } 13583 13584 void removeReceiverLocked(ReceiverList rl) { 13585 mRegisteredReceivers.remove(rl.receiver.asBinder()); 13586 int N = rl.size(); 13587 for (int i=0; i<N; i++) { 13588 mReceiverResolver.removeFilter(rl.get(i)); 13589 } 13590 } 13591 13592 private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) { 13593 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 13594 ProcessRecord r = mLruProcesses.get(i); 13595 if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) { 13596 try { 13597 r.thread.dispatchPackageBroadcast(cmd, packages); 13598 } catch (RemoteException ex) { 13599 } 13600 } 13601 } 13602 } 13603 13604 private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType, 13605 int[] users) { 13606 List<ResolveInfo> receivers = null; 13607 try { 13608 HashSet<ComponentName> singleUserReceivers = null; 13609 boolean scannedFirstReceivers = false; 13610 for (int user : users) { 13611 List<ResolveInfo> newReceivers = AppGlobals.getPackageManager() 13612 .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user); 13613 if (user != 0 && newReceivers != null) { 13614 // If this is not the primary user, we need to check for 13615 // any receivers that should be filtered out. 13616 for (int i=0; i<newReceivers.size(); i++) { 13617 ResolveInfo ri = newReceivers.get(i); 13618 if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) { 13619 newReceivers.remove(i); 13620 i--; 13621 } 13622 } 13623 } 13624 if (newReceivers != null && newReceivers.size() == 0) { 13625 newReceivers = null; 13626 } 13627 if (receivers == null) { 13628 receivers = newReceivers; 13629 } else if (newReceivers != null) { 13630 // We need to concatenate the additional receivers 13631 // found with what we have do far. This would be easy, 13632 // but we also need to de-dup any receivers that are 13633 // singleUser. 13634 if (!scannedFirstReceivers) { 13635 // Collect any single user receivers we had already retrieved. 13636 scannedFirstReceivers = true; 13637 for (int i=0; i<receivers.size(); i++) { 13638 ResolveInfo ri = receivers.get(i); 13639 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 13640 ComponentName cn = new ComponentName( 13641 ri.activityInfo.packageName, ri.activityInfo.name); 13642 if (singleUserReceivers == null) { 13643 singleUserReceivers = new HashSet<ComponentName>(); 13644 } 13645 singleUserReceivers.add(cn); 13646 } 13647 } 13648 } 13649 // Add the new results to the existing results, tracking 13650 // and de-dupping single user receivers. 13651 for (int i=0; i<newReceivers.size(); i++) { 13652 ResolveInfo ri = newReceivers.get(i); 13653 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 13654 ComponentName cn = new ComponentName( 13655 ri.activityInfo.packageName, ri.activityInfo.name); 13656 if (singleUserReceivers == null) { 13657 singleUserReceivers = new HashSet<ComponentName>(); 13658 } 13659 if (!singleUserReceivers.contains(cn)) { 13660 singleUserReceivers.add(cn); 13661 receivers.add(ri); 13662 } 13663 } else { 13664 receivers.add(ri); 13665 } 13666 } 13667 } 13668 } 13669 } catch (RemoteException ex) { 13670 // pm is in same process, this will never happen. 13671 } 13672 return receivers; 13673 } 13674 13675 private final int broadcastIntentLocked(ProcessRecord callerApp, 13676 String callerPackage, Intent intent, String resolvedType, 13677 IIntentReceiver resultTo, int resultCode, String resultData, 13678 Bundle map, String requiredPermission, int appOp, 13679 boolean ordered, boolean sticky, int callingPid, int callingUid, 13680 int userId) { 13681 intent = new Intent(intent); 13682 13683 // By default broadcasts do not go to stopped apps. 13684 intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES); 13685 13686 if (DEBUG_BROADCAST_LIGHT) Slog.v( 13687 TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent 13688 + " ordered=" + ordered + " userid=" + userId); 13689 if ((resultTo != null) && !ordered) { 13690 Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!"); 13691 } 13692 13693 userId = handleIncomingUser(callingPid, callingUid, userId, 13694 true, false, "broadcast", callerPackage); 13695 13696 // Make sure that the user who is receiving this broadcast is started. 13697 // If not, we will just skip it. 13698 if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) { 13699 if (callingUid != Process.SYSTEM_UID || (intent.getFlags() 13700 & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) { 13701 Slog.w(TAG, "Skipping broadcast of " + intent 13702 + ": user " + userId + " is stopped"); 13703 return ActivityManager.BROADCAST_SUCCESS; 13704 } 13705 } 13706 13707 /* 13708 * Prevent non-system code (defined here to be non-persistent 13709 * processes) from sending protected broadcasts. 13710 */ 13711 int callingAppId = UserHandle.getAppId(callingUid); 13712 if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID 13713 || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID || 13714 callingUid == 0) { 13715 // Always okay. 13716 } else if (callerApp == null || !callerApp.persistent) { 13717 try { 13718 if (AppGlobals.getPackageManager().isProtectedBroadcast( 13719 intent.getAction())) { 13720 String msg = "Permission Denial: not allowed to send broadcast " 13721 + intent.getAction() + " from pid=" 13722 + callingPid + ", uid=" + callingUid; 13723 Slog.w(TAG, msg); 13724 throw new SecurityException(msg); 13725 } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) { 13726 // Special case for compatibility: we don't want apps to send this, 13727 // but historically it has not been protected and apps may be using it 13728 // to poke their own app widget. So, instead of making it protected, 13729 // just limit it to the caller. 13730 if (callerApp == null) { 13731 String msg = "Permission Denial: not allowed to send broadcast " 13732 + intent.getAction() + " from unknown caller."; 13733 Slog.w(TAG, msg); 13734 throw new SecurityException(msg); 13735 } else if (intent.getComponent() != null) { 13736 // They are good enough to send to an explicit component... verify 13737 // it is being sent to the calling app. 13738 if (!intent.getComponent().getPackageName().equals( 13739 callerApp.info.packageName)) { 13740 String msg = "Permission Denial: not allowed to send broadcast " 13741 + intent.getAction() + " to " 13742 + intent.getComponent().getPackageName() + " from " 13743 + callerApp.info.packageName; 13744 Slog.w(TAG, msg); 13745 throw new SecurityException(msg); 13746 } 13747 } else { 13748 // Limit broadcast to their own package. 13749 intent.setPackage(callerApp.info.packageName); 13750 } 13751 } 13752 } catch (RemoteException e) { 13753 Slog.w(TAG, "Remote exception", e); 13754 return ActivityManager.BROADCAST_SUCCESS; 13755 } 13756 } 13757 13758 // Handle special intents: if this broadcast is from the package 13759 // manager about a package being removed, we need to remove all of 13760 // its activities from the history stack. 13761 final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals( 13762 intent.getAction()); 13763 if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction()) 13764 || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction()) 13765 || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction()) 13766 || uidRemoved) { 13767 if (checkComponentPermission( 13768 android.Manifest.permission.BROADCAST_PACKAGE_REMOVED, 13769 callingPid, callingUid, -1, true) 13770 == PackageManager.PERMISSION_GRANTED) { 13771 if (uidRemoved) { 13772 final Bundle intentExtras = intent.getExtras(); 13773 final int uid = intentExtras != null 13774 ? intentExtras.getInt(Intent.EXTRA_UID) : -1; 13775 if (uid >= 0) { 13776 BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics(); 13777 synchronized (bs) { 13778 bs.removeUidStatsLocked(uid); 13779 } 13780 mAppOpsService.uidRemoved(uid); 13781 } 13782 } else { 13783 // If resources are unavailable just force stop all 13784 // those packages and flush the attribute cache as well. 13785 if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) { 13786 String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 13787 if (list != null && (list.length > 0)) { 13788 for (String pkg : list) { 13789 forceStopPackageLocked(pkg, -1, false, true, true, false, false, userId, 13790 "storage unmount"); 13791 } 13792 sendPackageBroadcastLocked( 13793 IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId); 13794 } 13795 } else { 13796 Uri data = intent.getData(); 13797 String ssp; 13798 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 13799 boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals( 13800 intent.getAction()); 13801 boolean fullUninstall = removed && 13802 !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false); 13803 if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) { 13804 forceStopPackageLocked(ssp, UserHandle.getAppId( 13805 intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true, 13806 false, fullUninstall, userId, 13807 removed ? "pkg removed" : "pkg changed"); 13808 } 13809 if (removed) { 13810 sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED, 13811 new String[] {ssp}, userId); 13812 if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) { 13813 mAppOpsService.packageRemoved( 13814 intent.getIntExtra(Intent.EXTRA_UID, -1), ssp); 13815 13816 // Remove all permissions granted from/to this package 13817 removeUriPermissionsForPackageLocked(ssp, userId, true); 13818 } 13819 } 13820 } 13821 } 13822 } 13823 } else { 13824 String msg = "Permission Denial: " + intent.getAction() 13825 + " broadcast from " + callerPackage + " (pid=" + callingPid 13826 + ", uid=" + callingUid + ")" 13827 + " requires " 13828 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED; 13829 Slog.w(TAG, msg); 13830 throw new SecurityException(msg); 13831 } 13832 13833 // Special case for adding a package: by default turn on compatibility 13834 // mode. 13835 } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) { 13836 Uri data = intent.getData(); 13837 String ssp; 13838 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 13839 mCompatModePackages.handlePackageAddedLocked(ssp, 13840 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)); 13841 } 13842 } 13843 13844 /* 13845 * If this is the time zone changed action, queue up a message that will reset the timezone 13846 * of all currently running processes. This message will get queued up before the broadcast 13847 * happens. 13848 */ 13849 if (Intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) { 13850 mHandler.sendEmptyMessage(UPDATE_TIME_ZONE); 13851 } 13852 13853 /* 13854 * If the user set the time, let all running processes know. 13855 */ 13856 if (Intent.ACTION_TIME_CHANGED.equals(intent.getAction())) { 13857 final int is24Hour = intent.getBooleanExtra( 13858 Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1 : 0; 13859 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0)); 13860 } 13861 13862 if (Intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) { 13863 mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG); 13864 } 13865 13866 if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) { 13867 ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO); 13868 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy)); 13869 } 13870 13871 // Add to the sticky list if requested. 13872 if (sticky) { 13873 if (checkPermission(android.Manifest.permission.BROADCAST_STICKY, 13874 callingPid, callingUid) 13875 != PackageManager.PERMISSION_GRANTED) { 13876 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid=" 13877 + callingPid + ", uid=" + callingUid 13878 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 13879 Slog.w(TAG, msg); 13880 throw new SecurityException(msg); 13881 } 13882 if (requiredPermission != null) { 13883 Slog.w(TAG, "Can't broadcast sticky intent " + intent 13884 + " and enforce permission " + requiredPermission); 13885 return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION; 13886 } 13887 if (intent.getComponent() != null) { 13888 throw new SecurityException( 13889 "Sticky broadcasts can't target a specific component"); 13890 } 13891 // We use userId directly here, since the "all" target is maintained 13892 // as a separate set of sticky broadcasts. 13893 if (userId != UserHandle.USER_ALL) { 13894 // But first, if this is not a broadcast to all users, then 13895 // make sure it doesn't conflict with an existing broadcast to 13896 // all users. 13897 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get( 13898 UserHandle.USER_ALL); 13899 if (stickies != null) { 13900 ArrayList<Intent> list = stickies.get(intent.getAction()); 13901 if (list != null) { 13902 int N = list.size(); 13903 int i; 13904 for (i=0; i<N; i++) { 13905 if (intent.filterEquals(list.get(i))) { 13906 throw new IllegalArgumentException( 13907 "Sticky broadcast " + intent + " for user " 13908 + userId + " conflicts with existing global broadcast"); 13909 } 13910 } 13911 } 13912 } 13913 } 13914 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 13915 if (stickies == null) { 13916 stickies = new ArrayMap<String, ArrayList<Intent>>(); 13917 mStickyBroadcasts.put(userId, stickies); 13918 } 13919 ArrayList<Intent> list = stickies.get(intent.getAction()); 13920 if (list == null) { 13921 list = new ArrayList<Intent>(); 13922 stickies.put(intent.getAction(), list); 13923 } 13924 int N = list.size(); 13925 int i; 13926 for (i=0; i<N; i++) { 13927 if (intent.filterEquals(list.get(i))) { 13928 // This sticky already exists, replace it. 13929 list.set(i, new Intent(intent)); 13930 break; 13931 } 13932 } 13933 if (i >= N) { 13934 list.add(new Intent(intent)); 13935 } 13936 } 13937 13938 int[] users; 13939 if (userId == UserHandle.USER_ALL) { 13940 // Caller wants broadcast to go to all started users. 13941 users = mStartedUserArray; 13942 } else { 13943 // Caller wants broadcast to go to one specific user. 13944 users = new int[] {userId}; 13945 } 13946 13947 // Figure out who all will receive this broadcast. 13948 List receivers = null; 13949 List<BroadcastFilter> registeredReceivers = null; 13950 // Need to resolve the intent to interested receivers... 13951 if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) 13952 == 0) { 13953 receivers = collectReceiverComponents(intent, resolvedType, users); 13954 } 13955 if (intent.getComponent() == null) { 13956 registeredReceivers = mReceiverResolver.queryIntent(intent, 13957 resolvedType, false, userId); 13958 } 13959 13960 final boolean replacePending = 13961 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0; 13962 13963 if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction() 13964 + " replacePending=" + replacePending); 13965 13966 int NR = registeredReceivers != null ? registeredReceivers.size() : 0; 13967 if (!ordered && NR > 0) { 13968 // If we are not serializing this broadcast, then send the 13969 // registered receivers separately so they don't wait for the 13970 // components to be launched. 13971 final BroadcastQueue queue = broadcastQueueForIntent(intent); 13972 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 13973 callerPackage, callingPid, callingUid, resolvedType, requiredPermission, 13974 appOp, registeredReceivers, resultTo, resultCode, resultData, map, 13975 ordered, sticky, false, userId); 13976 if (DEBUG_BROADCAST) Slog.v( 13977 TAG, "Enqueueing parallel broadcast " + r); 13978 final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r); 13979 if (!replaced) { 13980 queue.enqueueParallelBroadcastLocked(r); 13981 queue.scheduleBroadcastsLocked(); 13982 } 13983 registeredReceivers = null; 13984 NR = 0; 13985 } 13986 13987 // Merge into one list. 13988 int ir = 0; 13989 if (receivers != null) { 13990 // A special case for PACKAGE_ADDED: do not allow the package 13991 // being added to see this broadcast. This prevents them from 13992 // using this as a back door to get run as soon as they are 13993 // installed. Maybe in the future we want to have a special install 13994 // broadcast or such for apps, but we'd like to deliberately make 13995 // this decision. 13996 String skipPackages[] = null; 13997 if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction()) 13998 || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction()) 13999 || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) { 14000 Uri data = intent.getData(); 14001 if (data != null) { 14002 String pkgName = data.getSchemeSpecificPart(); 14003 if (pkgName != null) { 14004 skipPackages = new String[] { pkgName }; 14005 } 14006 } 14007 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) { 14008 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 14009 } 14010 if (skipPackages != null && (skipPackages.length > 0)) { 14011 for (String skipPackage : skipPackages) { 14012 if (skipPackage != null) { 14013 int NT = receivers.size(); 14014 for (int it=0; it<NT; it++) { 14015 ResolveInfo curt = (ResolveInfo)receivers.get(it); 14016 if (curt.activityInfo.packageName.equals(skipPackage)) { 14017 receivers.remove(it); 14018 it--; 14019 NT--; 14020 } 14021 } 14022 } 14023 } 14024 } 14025 14026 int NT = receivers != null ? receivers.size() : 0; 14027 int it = 0; 14028 ResolveInfo curt = null; 14029 BroadcastFilter curr = null; 14030 while (it < NT && ir < NR) { 14031 if (curt == null) { 14032 curt = (ResolveInfo)receivers.get(it); 14033 } 14034 if (curr == null) { 14035 curr = registeredReceivers.get(ir); 14036 } 14037 if (curr.getPriority() >= curt.priority) { 14038 // Insert this broadcast record into the final list. 14039 receivers.add(it, curr); 14040 ir++; 14041 curr = null; 14042 it++; 14043 NT++; 14044 } else { 14045 // Skip to the next ResolveInfo in the final list. 14046 it++; 14047 curt = null; 14048 } 14049 } 14050 } 14051 while (ir < NR) { 14052 if (receivers == null) { 14053 receivers = new ArrayList(); 14054 } 14055 receivers.add(registeredReceivers.get(ir)); 14056 ir++; 14057 } 14058 14059 if ((receivers != null && receivers.size() > 0) 14060 || resultTo != null) { 14061 BroadcastQueue queue = broadcastQueueForIntent(intent); 14062 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 14063 callerPackage, callingPid, callingUid, resolvedType, 14064 requiredPermission, appOp, receivers, resultTo, resultCode, 14065 resultData, map, ordered, sticky, false, userId); 14066 if (DEBUG_BROADCAST) Slog.v( 14067 TAG, "Enqueueing ordered broadcast " + r 14068 + ": prev had " + queue.mOrderedBroadcasts.size()); 14069 if (DEBUG_BROADCAST) { 14070 int seq = r.intent.getIntExtra("seq", -1); 14071 Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq); 14072 } 14073 boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r); 14074 if (!replaced) { 14075 queue.enqueueOrderedBroadcastLocked(r); 14076 queue.scheduleBroadcastsLocked(); 14077 } 14078 } 14079 14080 return ActivityManager.BROADCAST_SUCCESS; 14081 } 14082 14083 final Intent verifyBroadcastLocked(Intent intent) { 14084 // Refuse possible leaked file descriptors 14085 if (intent != null && intent.hasFileDescriptors() == true) { 14086 throw new IllegalArgumentException("File descriptors passed in Intent"); 14087 } 14088 14089 int flags = intent.getFlags(); 14090 14091 if (!mProcessesReady) { 14092 // if the caller really truly claims to know what they're doing, go 14093 // ahead and allow the broadcast without launching any receivers 14094 if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) { 14095 intent = new Intent(intent); 14096 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 14097 } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) { 14098 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent 14099 + " before boot completion"); 14100 throw new IllegalStateException("Cannot broadcast before boot completed"); 14101 } 14102 } 14103 14104 if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 14105 throw new IllegalArgumentException( 14106 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 14107 } 14108 14109 return intent; 14110 } 14111 14112 public final int broadcastIntent(IApplicationThread caller, 14113 Intent intent, String resolvedType, IIntentReceiver resultTo, 14114 int resultCode, String resultData, Bundle map, 14115 String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) { 14116 enforceNotIsolatedCaller("broadcastIntent"); 14117 synchronized(this) { 14118 intent = verifyBroadcastLocked(intent); 14119 14120 final ProcessRecord callerApp = getRecordForAppLocked(caller); 14121 final int callingPid = Binder.getCallingPid(); 14122 final int callingUid = Binder.getCallingUid(); 14123 final long origId = Binder.clearCallingIdentity(); 14124 int res = broadcastIntentLocked(callerApp, 14125 callerApp != null ? callerApp.info.packageName : null, 14126 intent, resolvedType, resultTo, 14127 resultCode, resultData, map, requiredPermission, appOp, serialized, sticky, 14128 callingPid, callingUid, userId); 14129 Binder.restoreCallingIdentity(origId); 14130 return res; 14131 } 14132 } 14133 14134 int broadcastIntentInPackage(String packageName, int uid, 14135 Intent intent, String resolvedType, IIntentReceiver resultTo, 14136 int resultCode, String resultData, Bundle map, 14137 String requiredPermission, boolean serialized, boolean sticky, int userId) { 14138 synchronized(this) { 14139 intent = verifyBroadcastLocked(intent); 14140 14141 final long origId = Binder.clearCallingIdentity(); 14142 int res = broadcastIntentLocked(null, packageName, intent, resolvedType, 14143 resultTo, resultCode, resultData, map, requiredPermission, 14144 AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId); 14145 Binder.restoreCallingIdentity(origId); 14146 return res; 14147 } 14148 } 14149 14150 public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) { 14151 // Refuse possible leaked file descriptors 14152 if (intent != null && intent.hasFileDescriptors() == true) { 14153 throw new IllegalArgumentException("File descriptors passed in Intent"); 14154 } 14155 14156 userId = handleIncomingUser(Binder.getCallingPid(), 14157 Binder.getCallingUid(), userId, true, false, "removeStickyBroadcast", null); 14158 14159 synchronized(this) { 14160 if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY) 14161 != PackageManager.PERMISSION_GRANTED) { 14162 String msg = "Permission Denial: unbroadcastIntent() from pid=" 14163 + Binder.getCallingPid() 14164 + ", uid=" + Binder.getCallingUid() 14165 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 14166 Slog.w(TAG, msg); 14167 throw new SecurityException(msg); 14168 } 14169 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 14170 if (stickies != null) { 14171 ArrayList<Intent> list = stickies.get(intent.getAction()); 14172 if (list != null) { 14173 int N = list.size(); 14174 int i; 14175 for (i=0; i<N; i++) { 14176 if (intent.filterEquals(list.get(i))) { 14177 list.remove(i); 14178 break; 14179 } 14180 } 14181 if (list.size() <= 0) { 14182 stickies.remove(intent.getAction()); 14183 } 14184 } 14185 if (stickies.size() <= 0) { 14186 mStickyBroadcasts.remove(userId); 14187 } 14188 } 14189 } 14190 } 14191 14192 private final boolean finishReceiverLocked(IBinder receiver, int resultCode, 14193 String resultData, Bundle resultExtras, boolean resultAbort) { 14194 final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver); 14195 if (r == null) { 14196 Slog.w(TAG, "finishReceiver called but not found on queue"); 14197 return false; 14198 } 14199 14200 return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false); 14201 } 14202 14203 void backgroundServicesFinishedLocked(int userId) { 14204 for (BroadcastQueue queue : mBroadcastQueues) { 14205 queue.backgroundServicesFinishedLocked(userId); 14206 } 14207 } 14208 14209 public void finishReceiver(IBinder who, int resultCode, String resultData, 14210 Bundle resultExtras, boolean resultAbort) { 14211 if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who); 14212 14213 // Refuse possible leaked file descriptors 14214 if (resultExtras != null && resultExtras.hasFileDescriptors()) { 14215 throw new IllegalArgumentException("File descriptors passed in Bundle"); 14216 } 14217 14218 final long origId = Binder.clearCallingIdentity(); 14219 try { 14220 boolean doNext = false; 14221 BroadcastRecord r; 14222 14223 synchronized(this) { 14224 r = broadcastRecordForReceiverLocked(who); 14225 if (r != null) { 14226 doNext = r.queue.finishReceiverLocked(r, resultCode, 14227 resultData, resultExtras, resultAbort, true); 14228 } 14229 } 14230 14231 if (doNext) { 14232 r.queue.processNextBroadcast(false); 14233 } 14234 trimApplications(); 14235 } finally { 14236 Binder.restoreCallingIdentity(origId); 14237 } 14238 } 14239 14240 // ========================================================= 14241 // INSTRUMENTATION 14242 // ========================================================= 14243 14244 public boolean startInstrumentation(ComponentName className, 14245 String profileFile, int flags, Bundle arguments, 14246 IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection, 14247 int userId) { 14248 enforceNotIsolatedCaller("startInstrumentation"); 14249 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 14250 userId, false, true, "startInstrumentation", null); 14251 // Refuse possible leaked file descriptors 14252 if (arguments != null && arguments.hasFileDescriptors()) { 14253 throw new IllegalArgumentException("File descriptors passed in Bundle"); 14254 } 14255 14256 synchronized(this) { 14257 InstrumentationInfo ii = null; 14258 ApplicationInfo ai = null; 14259 try { 14260 ii = mContext.getPackageManager().getInstrumentationInfo( 14261 className, STOCK_PM_FLAGS); 14262 ai = AppGlobals.getPackageManager().getApplicationInfo( 14263 ii.targetPackage, STOCK_PM_FLAGS, userId); 14264 } catch (PackageManager.NameNotFoundException e) { 14265 } catch (RemoteException e) { 14266 } 14267 if (ii == null) { 14268 reportStartInstrumentationFailure(watcher, className, 14269 "Unable to find instrumentation info for: " + className); 14270 return false; 14271 } 14272 if (ai == null) { 14273 reportStartInstrumentationFailure(watcher, className, 14274 "Unable to find instrumentation target package: " + ii.targetPackage); 14275 return false; 14276 } 14277 14278 int match = mContext.getPackageManager().checkSignatures( 14279 ii.targetPackage, ii.packageName); 14280 if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) { 14281 String msg = "Permission Denial: starting instrumentation " 14282 + className + " from pid=" 14283 + Binder.getCallingPid() 14284 + ", uid=" + Binder.getCallingPid() 14285 + " not allowed because package " + ii.packageName 14286 + " does not have a signature matching the target " 14287 + ii.targetPackage; 14288 reportStartInstrumentationFailure(watcher, className, msg); 14289 throw new SecurityException(msg); 14290 } 14291 14292 final long origId = Binder.clearCallingIdentity(); 14293 // Instrumentation can kill and relaunch even persistent processes 14294 forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId, 14295 "start instr"); 14296 ProcessRecord app = addAppLocked(ai, false); 14297 app.instrumentationClass = className; 14298 app.instrumentationInfo = ai; 14299 app.instrumentationProfileFile = profileFile; 14300 app.instrumentationArguments = arguments; 14301 app.instrumentationWatcher = watcher; 14302 app.instrumentationUiAutomationConnection = uiAutomationConnection; 14303 app.instrumentationResultClass = className; 14304 Binder.restoreCallingIdentity(origId); 14305 } 14306 14307 return true; 14308 } 14309 14310 /** 14311 * Report errors that occur while attempting to start Instrumentation. Always writes the 14312 * error to the logs, but if somebody is watching, send the report there too. This enables 14313 * the "am" command to report errors with more information. 14314 * 14315 * @param watcher The IInstrumentationWatcher. Null if there isn't one. 14316 * @param cn The component name of the instrumentation. 14317 * @param report The error report. 14318 */ 14319 private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher, 14320 ComponentName cn, String report) { 14321 Slog.w(TAG, report); 14322 try { 14323 if (watcher != null) { 14324 Bundle results = new Bundle(); 14325 results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService"); 14326 results.putString("Error", report); 14327 watcher.instrumentationStatus(cn, -1, results); 14328 } 14329 } catch (RemoteException e) { 14330 Slog.w(TAG, e); 14331 } 14332 } 14333 14334 void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) { 14335 if (app.instrumentationWatcher != null) { 14336 try { 14337 // NOTE: IInstrumentationWatcher *must* be oneway here 14338 app.instrumentationWatcher.instrumentationFinished( 14339 app.instrumentationClass, 14340 resultCode, 14341 results); 14342 } catch (RemoteException e) { 14343 } 14344 } 14345 if (app.instrumentationUiAutomationConnection != null) { 14346 try { 14347 app.instrumentationUiAutomationConnection.shutdown(); 14348 } catch (RemoteException re) { 14349 /* ignore */ 14350 } 14351 // Only a UiAutomation can set this flag and now that 14352 // it is finished we make sure it is reset to its default. 14353 mUserIsMonkey = false; 14354 } 14355 app.instrumentationWatcher = null; 14356 app.instrumentationUiAutomationConnection = null; 14357 app.instrumentationClass = null; 14358 app.instrumentationInfo = null; 14359 app.instrumentationProfileFile = null; 14360 app.instrumentationArguments = null; 14361 14362 forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId, 14363 "finished inst"); 14364 } 14365 14366 public void finishInstrumentation(IApplicationThread target, 14367 int resultCode, Bundle results) { 14368 int userId = UserHandle.getCallingUserId(); 14369 // Refuse possible leaked file descriptors 14370 if (results != null && results.hasFileDescriptors()) { 14371 throw new IllegalArgumentException("File descriptors passed in Intent"); 14372 } 14373 14374 synchronized(this) { 14375 ProcessRecord app = getRecordForAppLocked(target); 14376 if (app == null) { 14377 Slog.w(TAG, "finishInstrumentation: no app for " + target); 14378 return; 14379 } 14380 final long origId = Binder.clearCallingIdentity(); 14381 finishInstrumentationLocked(app, resultCode, results); 14382 Binder.restoreCallingIdentity(origId); 14383 } 14384 } 14385 14386 // ========================================================= 14387 // CONFIGURATION 14388 // ========================================================= 14389 14390 public ConfigurationInfo getDeviceConfigurationInfo() { 14391 ConfigurationInfo config = new ConfigurationInfo(); 14392 synchronized (this) { 14393 config.reqTouchScreen = mConfiguration.touchscreen; 14394 config.reqKeyboardType = mConfiguration.keyboard; 14395 config.reqNavigation = mConfiguration.navigation; 14396 if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD 14397 || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) { 14398 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV; 14399 } 14400 if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED 14401 && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) { 14402 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD; 14403 } 14404 config.reqGlEsVersion = GL_ES_VERSION; 14405 } 14406 return config; 14407 } 14408 14409 ActivityStack getFocusedStack() { 14410 return mStackSupervisor.getFocusedStack(); 14411 } 14412 14413 public Configuration getConfiguration() { 14414 Configuration ci; 14415 synchronized(this) { 14416 ci = new Configuration(mConfiguration); 14417 } 14418 return ci; 14419 } 14420 14421 public void updatePersistentConfiguration(Configuration values) { 14422 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 14423 "updateConfiguration()"); 14424 enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS, 14425 "updateConfiguration()"); 14426 if (values == null) { 14427 throw new NullPointerException("Configuration must not be null"); 14428 } 14429 14430 synchronized(this) { 14431 final long origId = Binder.clearCallingIdentity(); 14432 updateConfigurationLocked(values, null, true, false); 14433 Binder.restoreCallingIdentity(origId); 14434 } 14435 } 14436 14437 public void updateConfiguration(Configuration values) { 14438 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 14439 "updateConfiguration()"); 14440 14441 synchronized(this) { 14442 if (values == null && mWindowManager != null) { 14443 // sentinel: fetch the current configuration from the window manager 14444 values = mWindowManager.computeNewConfiguration(); 14445 } 14446 14447 if (mWindowManager != null) { 14448 mProcessList.applyDisplaySize(mWindowManager); 14449 } 14450 14451 final long origId = Binder.clearCallingIdentity(); 14452 if (values != null) { 14453 Settings.System.clearConfiguration(values); 14454 } 14455 updateConfigurationLocked(values, null, false, false); 14456 Binder.restoreCallingIdentity(origId); 14457 } 14458 } 14459 14460 /** 14461 * Do either or both things: (1) change the current configuration, and (2) 14462 * make sure the given activity is running with the (now) current 14463 * configuration. Returns true if the activity has been left running, or 14464 * false if <var>starting</var> is being destroyed to match the new 14465 * configuration. 14466 * @param persistent TODO 14467 */ 14468 boolean updateConfigurationLocked(Configuration values, 14469 ActivityRecord starting, boolean persistent, boolean initLocale) { 14470 int changes = 0; 14471 14472 if (values != null) { 14473 Configuration newConfig = new Configuration(mConfiguration); 14474 changes = newConfig.updateFrom(values); 14475 if (changes != 0) { 14476 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) { 14477 Slog.i(TAG, "Updating configuration to: " + values); 14478 } 14479 14480 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes); 14481 14482 if (values.locale != null && !initLocale) { 14483 saveLocaleLocked(values.locale, 14484 !values.locale.equals(mConfiguration.locale), 14485 values.userSetLocale); 14486 } 14487 14488 mConfigurationSeq++; 14489 if (mConfigurationSeq <= 0) { 14490 mConfigurationSeq = 1; 14491 } 14492 newConfig.seq = mConfigurationSeq; 14493 mConfiguration = newConfig; 14494 Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig); 14495 mUsageStatsService.noteStartConfig(newConfig); 14496 14497 final Configuration configCopy = new Configuration(mConfiguration); 14498 14499 // TODO: If our config changes, should we auto dismiss any currently 14500 // showing dialogs? 14501 mShowDialogs = shouldShowDialogs(newConfig); 14502 14503 AttributeCache ac = AttributeCache.instance(); 14504 if (ac != null) { 14505 ac.updateConfiguration(configCopy); 14506 } 14507 14508 // Make sure all resources in our process are updated 14509 // right now, so that anyone who is going to retrieve 14510 // resource values after we return will be sure to get 14511 // the new ones. This is especially important during 14512 // boot, where the first config change needs to guarantee 14513 // all resources have that config before following boot 14514 // code is executed. 14515 mSystemThread.applyConfigurationToResources(configCopy); 14516 14517 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) { 14518 Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG); 14519 msg.obj = new Configuration(configCopy); 14520 mHandler.sendMessage(msg); 14521 } 14522 14523 for (int i=mLruProcesses.size()-1; i>=0; i--) { 14524 ProcessRecord app = mLruProcesses.get(i); 14525 try { 14526 if (app.thread != null) { 14527 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc " 14528 + app.processName + " new config " + mConfiguration); 14529 app.thread.scheduleConfigurationChanged(configCopy); 14530 } 14531 } catch (Exception e) { 14532 } 14533 } 14534 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED); 14535 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 14536 | Intent.FLAG_RECEIVER_REPLACE_PENDING 14537 | Intent.FLAG_RECEIVER_FOREGROUND); 14538 broadcastIntentLocked(null, null, intent, null, null, 0, null, null, 14539 null, AppOpsManager.OP_NONE, false, false, MY_PID, 14540 Process.SYSTEM_UID, UserHandle.USER_ALL); 14541 if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) { 14542 intent = new Intent(Intent.ACTION_LOCALE_CHANGED); 14543 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 14544 broadcastIntentLocked(null, null, intent, 14545 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 14546 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 14547 } 14548 } 14549 } 14550 14551 boolean kept = true; 14552 final ActivityStack mainStack = mStackSupervisor.getFocusedStack(); 14553 // mainStack is null during startup. 14554 if (mainStack != null) { 14555 if (changes != 0 && starting == null) { 14556 // If the configuration changed, and the caller is not already 14557 // in the process of starting an activity, then find the top 14558 // activity to check if its configuration needs to change. 14559 starting = mainStack.topRunningActivityLocked(null); 14560 } 14561 14562 if (starting != null) { 14563 kept = mainStack.ensureActivityConfigurationLocked(starting, changes); 14564 // And we need to make sure at this point that all other activities 14565 // are made visible with the correct configuration. 14566 mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes); 14567 } 14568 } 14569 14570 if (values != null && mWindowManager != null) { 14571 mWindowManager.setNewConfiguration(mConfiguration); 14572 } 14573 14574 return kept; 14575 } 14576 14577 /** 14578 * Decide based on the configuration whether we should shouw the ANR, 14579 * crash, etc dialogs. The idea is that if there is no affordnace to 14580 * press the on-screen buttons, we shouldn't show the dialog. 14581 * 14582 * A thought: SystemUI might also want to get told about this, the Power 14583 * dialog / global actions also might want different behaviors. 14584 */ 14585 private static final boolean shouldShowDialogs(Configuration config) { 14586 return !(config.keyboard == Configuration.KEYBOARD_NOKEYS 14587 && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH); 14588 } 14589 14590 /** 14591 * Save the locale. You must be inside a synchronized (this) block. 14592 */ 14593 private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) { 14594 if(isDiff) { 14595 SystemProperties.set("user.language", l.getLanguage()); 14596 SystemProperties.set("user.region", l.getCountry()); 14597 } 14598 14599 if(isPersist) { 14600 SystemProperties.set("persist.sys.language", l.getLanguage()); 14601 SystemProperties.set("persist.sys.country", l.getCountry()); 14602 SystemProperties.set("persist.sys.localevar", l.getVariant()); 14603 } 14604 } 14605 14606 @Override 14607 public boolean targetTaskAffinityMatchesActivity(IBinder token, String destAffinity) { 14608 ActivityRecord srec = ActivityRecord.forToken(token); 14609 return srec != null && srec.task.affinity != null && 14610 srec.task.affinity.equals(destAffinity); 14611 } 14612 14613 public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode, 14614 Intent resultData) { 14615 14616 synchronized (this) { 14617 final ActivityStack stack = ActivityRecord.getStackLocked(token); 14618 if (stack != null) { 14619 return stack.navigateUpToLocked(token, destIntent, resultCode, resultData); 14620 } 14621 return false; 14622 } 14623 } 14624 14625 public int getLaunchedFromUid(IBinder activityToken) { 14626 ActivityRecord srec = ActivityRecord.forToken(activityToken); 14627 if (srec == null) { 14628 return -1; 14629 } 14630 return srec.launchedFromUid; 14631 } 14632 14633 public String getLaunchedFromPackage(IBinder activityToken) { 14634 ActivityRecord srec = ActivityRecord.forToken(activityToken); 14635 if (srec == null) { 14636 return null; 14637 } 14638 return srec.launchedFromPackage; 14639 } 14640 14641 // ========================================================= 14642 // LIFETIME MANAGEMENT 14643 // ========================================================= 14644 14645 // Returns which broadcast queue the app is the current [or imminent] receiver 14646 // on, or 'null' if the app is not an active broadcast recipient. 14647 private BroadcastQueue isReceivingBroadcast(ProcessRecord app) { 14648 BroadcastRecord r = app.curReceiver; 14649 if (r != null) { 14650 return r.queue; 14651 } 14652 14653 // It's not the current receiver, but it might be starting up to become one 14654 synchronized (this) { 14655 for (BroadcastQueue queue : mBroadcastQueues) { 14656 r = queue.mPendingBroadcast; 14657 if (r != null && r.curApp == app) { 14658 // found it; report which queue it's in 14659 return queue; 14660 } 14661 } 14662 } 14663 14664 return null; 14665 } 14666 14667 private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP, 14668 boolean doingAll, long now) { 14669 if (mAdjSeq == app.adjSeq) { 14670 // This adjustment has already been computed. 14671 return app.curRawAdj; 14672 } 14673 14674 if (app.thread == null) { 14675 app.adjSeq = mAdjSeq; 14676 app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 14677 app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 14678 return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ); 14679 } 14680 14681 app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN; 14682 app.adjSource = null; 14683 app.adjTarget = null; 14684 app.empty = false; 14685 app.cached = false; 14686 14687 final int activitiesSize = app.activities.size(); 14688 14689 if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) { 14690 // The max adjustment doesn't allow this app to be anything 14691 // below foreground, so it is not worth doing work for it. 14692 app.adjType = "fixed"; 14693 app.adjSeq = mAdjSeq; 14694 app.curRawAdj = app.maxAdj; 14695 app.foregroundActivities = false; 14696 app.keeping = true; 14697 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT; 14698 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT; 14699 // System processes can do UI, and when they do we want to have 14700 // them trim their memory after the user leaves the UI. To 14701 // facilitate this, here we need to determine whether or not it 14702 // is currently showing UI. 14703 app.systemNoUi = true; 14704 if (app == TOP_APP) { 14705 app.systemNoUi = false; 14706 } else if (activitiesSize > 0) { 14707 for (int j = 0; j < activitiesSize; j++) { 14708 final ActivityRecord r = app.activities.get(j); 14709 if (r.visible) { 14710 app.systemNoUi = false; 14711 } 14712 } 14713 } 14714 if (!app.systemNoUi) { 14715 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI; 14716 } 14717 return (app.curAdj=app.maxAdj); 14718 } 14719 14720 app.keeping = false; 14721 app.systemNoUi = false; 14722 14723 // Determine the importance of the process, starting with most 14724 // important to least, and assign an appropriate OOM adjustment. 14725 int adj; 14726 int schedGroup; 14727 int procState; 14728 boolean foregroundActivities = false; 14729 boolean interesting = false; 14730 BroadcastQueue queue; 14731 if (app == TOP_APP) { 14732 // The last app on the list is the foreground app. 14733 adj = ProcessList.FOREGROUND_APP_ADJ; 14734 schedGroup = Process.THREAD_GROUP_DEFAULT; 14735 app.adjType = "top-activity"; 14736 foregroundActivities = true; 14737 interesting = true; 14738 procState = ActivityManager.PROCESS_STATE_TOP; 14739 } else if (app.instrumentationClass != null) { 14740 // Don't want to kill running instrumentation. 14741 adj = ProcessList.FOREGROUND_APP_ADJ; 14742 schedGroup = Process.THREAD_GROUP_DEFAULT; 14743 app.adjType = "instrumentation"; 14744 interesting = true; 14745 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14746 } else if ((queue = isReceivingBroadcast(app)) != null) { 14747 // An app that is currently receiving a broadcast also 14748 // counts as being in the foreground for OOM killer purposes. 14749 // It's placed in a sched group based on the nature of the 14750 // broadcast as reflected by which queue it's active in. 14751 adj = ProcessList.FOREGROUND_APP_ADJ; 14752 schedGroup = (queue == mFgBroadcastQueue) 14753 ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 14754 app.adjType = "broadcast"; 14755 procState = ActivityManager.PROCESS_STATE_RECEIVER; 14756 } else if (app.executingServices.size() > 0) { 14757 // An app that is currently executing a service callback also 14758 // counts as being in the foreground. 14759 adj = ProcessList.FOREGROUND_APP_ADJ; 14760 schedGroup = app.execServicesFg ? 14761 Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 14762 app.adjType = "exec-service"; 14763 procState = ActivityManager.PROCESS_STATE_SERVICE; 14764 //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app); 14765 } else { 14766 // As far as we know the process is empty. We may change our mind later. 14767 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 14768 // At this point we don't actually know the adjustment. Use the cached adj 14769 // value that the caller wants us to. 14770 adj = cachedAdj; 14771 procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 14772 app.cached = true; 14773 app.empty = true; 14774 app.adjType = "cch-empty"; 14775 } 14776 14777 // Examine all activities if not already foreground. 14778 if (!foregroundActivities && activitiesSize > 0) { 14779 for (int j = 0; j < activitiesSize; j++) { 14780 final ActivityRecord r = app.activities.get(j); 14781 if (r.app != app) { 14782 Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc " 14783 + app + "?!?"); 14784 continue; 14785 } 14786 if (r.visible) { 14787 // App has a visible activity; only upgrade adjustment. 14788 if (adj > ProcessList.VISIBLE_APP_ADJ) { 14789 adj = ProcessList.VISIBLE_APP_ADJ; 14790 app.adjType = "visible"; 14791 } 14792 if (procState > ActivityManager.PROCESS_STATE_TOP) { 14793 procState = ActivityManager.PROCESS_STATE_TOP; 14794 } 14795 schedGroup = Process.THREAD_GROUP_DEFAULT; 14796 app.cached = false; 14797 app.empty = false; 14798 foregroundActivities = true; 14799 break; 14800 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) { 14801 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14802 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 14803 app.adjType = "pausing"; 14804 } 14805 if (procState > ActivityManager.PROCESS_STATE_TOP) { 14806 procState = ActivityManager.PROCESS_STATE_TOP; 14807 } 14808 schedGroup = Process.THREAD_GROUP_DEFAULT; 14809 app.cached = false; 14810 app.empty = false; 14811 foregroundActivities = true; 14812 } else if (r.state == ActivityState.STOPPING) { 14813 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14814 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 14815 app.adjType = "stopping"; 14816 } 14817 // For the process state, we will at this point consider the 14818 // process to be cached. It will be cached either as an activity 14819 // or empty depending on whether the activity is finishing. We do 14820 // this so that we can treat the process as cached for purposes of 14821 // memory trimming (determing current memory level, trim command to 14822 // send to process) since there can be an arbitrary number of stopping 14823 // processes and they should soon all go into the cached state. 14824 if (!r.finishing) { 14825 if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 14826 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 14827 } 14828 } 14829 app.cached = false; 14830 app.empty = false; 14831 foregroundActivities = true; 14832 } else { 14833 if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 14834 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 14835 app.adjType = "cch-act"; 14836 } 14837 } 14838 } 14839 } 14840 14841 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14842 if (app.foregroundServices) { 14843 // The user is aware of this app, so make it visible. 14844 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 14845 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14846 app.cached = false; 14847 app.adjType = "fg-service"; 14848 schedGroup = Process.THREAD_GROUP_DEFAULT; 14849 } else if (app.forcingToForeground != null) { 14850 // The user is aware of this app, so make it visible. 14851 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 14852 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14853 app.cached = false; 14854 app.adjType = "force-fg"; 14855 app.adjSource = app.forcingToForeground; 14856 schedGroup = Process.THREAD_GROUP_DEFAULT; 14857 } 14858 } 14859 14860 if (app.foregroundServices) { 14861 interesting = true; 14862 } 14863 14864 if (app == mHeavyWeightProcess) { 14865 if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) { 14866 // We don't want to kill the current heavy-weight process. 14867 adj = ProcessList.HEAVY_WEIGHT_APP_ADJ; 14868 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 14869 app.cached = false; 14870 app.adjType = "heavy"; 14871 } 14872 if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) { 14873 procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT; 14874 } 14875 } 14876 14877 if (app == mHomeProcess) { 14878 if (adj > ProcessList.HOME_APP_ADJ) { 14879 // This process is hosting what we currently consider to be the 14880 // home app, so we don't want to let it go into the background. 14881 adj = ProcessList.HOME_APP_ADJ; 14882 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 14883 app.cached = false; 14884 app.adjType = "home"; 14885 } 14886 if (procState > ActivityManager.PROCESS_STATE_HOME) { 14887 procState = ActivityManager.PROCESS_STATE_HOME; 14888 } 14889 } 14890 14891 if (app == mPreviousProcess && app.activities.size() > 0) { 14892 if (adj > ProcessList.PREVIOUS_APP_ADJ) { 14893 // This was the previous process that showed UI to the user. 14894 // We want to try to keep it around more aggressively, to give 14895 // a good experience around switching between two apps. 14896 adj = ProcessList.PREVIOUS_APP_ADJ; 14897 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 14898 app.cached = false; 14899 app.adjType = "previous"; 14900 } 14901 if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) { 14902 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY; 14903 } 14904 } 14905 14906 if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj 14907 + " reason=" + app.adjType); 14908 14909 // By default, we use the computed adjustment. It may be changed if 14910 // there are applications dependent on our services or providers, but 14911 // this gives us a baseline and makes sure we don't get into an 14912 // infinite recursion. 14913 app.adjSeq = mAdjSeq; 14914 app.curRawAdj = adj; 14915 app.hasStartedServices = false; 14916 14917 if (mBackupTarget != null && app == mBackupTarget.app) { 14918 // If possible we want to avoid killing apps while they're being backed up 14919 if (adj > ProcessList.BACKUP_APP_ADJ) { 14920 if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app); 14921 adj = ProcessList.BACKUP_APP_ADJ; 14922 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) { 14923 procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND; 14924 } 14925 app.adjType = "backup"; 14926 app.cached = false; 14927 } 14928 if (procState > ActivityManager.PROCESS_STATE_BACKUP) { 14929 procState = ActivityManager.PROCESS_STATE_BACKUP; 14930 } 14931 } 14932 14933 boolean mayBeTop = false; 14934 14935 for (int is = app.services.size()-1; 14936 is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 14937 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 14938 || procState > ActivityManager.PROCESS_STATE_TOP); 14939 is--) { 14940 ServiceRecord s = app.services.valueAt(is); 14941 if (s.startRequested) { 14942 app.hasStartedServices = true; 14943 if (procState > ActivityManager.PROCESS_STATE_SERVICE) { 14944 procState = ActivityManager.PROCESS_STATE_SERVICE; 14945 } 14946 if (app.hasShownUi && app != mHomeProcess) { 14947 // If this process has shown some UI, let it immediately 14948 // go to the LRU list because it may be pretty heavy with 14949 // UI stuff. We'll tag it with a label just to help 14950 // debug and understand what is going on. 14951 if (adj > ProcessList.SERVICE_ADJ) { 14952 app.adjType = "cch-started-ui-services"; 14953 } 14954 } else { 14955 if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) { 14956 // This service has seen some activity within 14957 // recent memory, so we will keep its process ahead 14958 // of the background processes. 14959 if (adj > ProcessList.SERVICE_ADJ) { 14960 adj = ProcessList.SERVICE_ADJ; 14961 app.adjType = "started-services"; 14962 app.cached = false; 14963 } 14964 } 14965 // If we have let the service slide into the background 14966 // state, still have some text describing what it is doing 14967 // even though the service no longer has an impact. 14968 if (adj > ProcessList.SERVICE_ADJ) { 14969 app.adjType = "cch-started-services"; 14970 } 14971 } 14972 // Don't kill this process because it is doing work; it 14973 // has said it is doing work. 14974 app.keeping = true; 14975 } 14976 for (int conni = s.connections.size()-1; 14977 conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 14978 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 14979 || procState > ActivityManager.PROCESS_STATE_TOP); 14980 conni--) { 14981 ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni); 14982 for (int i = 0; 14983 i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ 14984 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 14985 || procState > ActivityManager.PROCESS_STATE_TOP); 14986 i++) { 14987 // XXX should compute this based on the max of 14988 // all connected clients. 14989 ConnectionRecord cr = clist.get(i); 14990 if (cr.binding.client == app) { 14991 // Binding to ourself is not interesting. 14992 continue; 14993 } 14994 if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) { 14995 ProcessRecord client = cr.binding.client; 14996 int clientAdj = computeOomAdjLocked(client, cachedAdj, 14997 TOP_APP, doingAll, now); 14998 int clientProcState = client.curProcState; 14999 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 15000 // If the other app is cached for any reason, for purposes here 15001 // we are going to consider it empty. The specific cached state 15002 // doesn't propagate except under certain conditions. 15003 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 15004 } 15005 String adjType = null; 15006 if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) { 15007 // Not doing bind OOM management, so treat 15008 // this guy more like a started service. 15009 if (app.hasShownUi && app != mHomeProcess) { 15010 // If this process has shown some UI, let it immediately 15011 // go to the LRU list because it may be pretty heavy with 15012 // UI stuff. We'll tag it with a label just to help 15013 // debug and understand what is going on. 15014 if (adj > clientAdj) { 15015 adjType = "cch-bound-ui-services"; 15016 } 15017 app.cached = false; 15018 clientAdj = adj; 15019 clientProcState = procState; 15020 } else { 15021 if (now >= (s.lastActivity 15022 + ActiveServices.MAX_SERVICE_INACTIVITY)) { 15023 // This service has not seen activity within 15024 // recent memory, so allow it to drop to the 15025 // LRU list if there is no other reason to keep 15026 // it around. We'll also tag it with a label just 15027 // to help debug and undertand what is going on. 15028 if (adj > clientAdj) { 15029 adjType = "cch-bound-services"; 15030 } 15031 clientAdj = adj; 15032 } 15033 } 15034 } 15035 if (adj > clientAdj) { 15036 // If this process has recently shown UI, and 15037 // the process that is binding to it is less 15038 // important than being visible, then we don't 15039 // care about the binding as much as we care 15040 // about letting this process get into the LRU 15041 // list to be killed and restarted if needed for 15042 // memory. 15043 if (app.hasShownUi && app != mHomeProcess 15044 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 15045 adjType = "cch-bound-ui-services"; 15046 } else { 15047 if ((cr.flags&(Context.BIND_ABOVE_CLIENT 15048 |Context.BIND_IMPORTANT)) != 0) { 15049 adj = clientAdj; 15050 } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0 15051 && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ 15052 && adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 15053 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 15054 } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) { 15055 adj = clientAdj; 15056 } else { 15057 if (adj > ProcessList.VISIBLE_APP_ADJ) { 15058 adj = ProcessList.VISIBLE_APP_ADJ; 15059 } 15060 } 15061 if (!client.cached) { 15062 app.cached = false; 15063 } 15064 if (client.keeping) { 15065 app.keeping = true; 15066 } 15067 adjType = "service"; 15068 } 15069 } 15070 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 15071 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 15072 schedGroup = Process.THREAD_GROUP_DEFAULT; 15073 } 15074 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) { 15075 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) { 15076 // Special handling of clients who are in the top state. 15077 // We *may* want to consider this process to be in the 15078 // top state as well, but only if there is not another 15079 // reason for it to be running. Being on the top is a 15080 // special state, meaning you are specifically running 15081 // for the current top app. If the process is already 15082 // running in the background for some other reason, it 15083 // is more important to continue considering it to be 15084 // in the background state. 15085 mayBeTop = true; 15086 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 15087 } else { 15088 // Special handling for above-top states (persistent 15089 // processes). These should not bring the current process 15090 // into the top state, since they are not on top. Instead 15091 // give them the best state after that. 15092 clientProcState = 15093 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 15094 } 15095 } 15096 } else { 15097 if (clientProcState < 15098 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) { 15099 clientProcState = 15100 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND; 15101 } 15102 } 15103 if (procState > clientProcState) { 15104 procState = clientProcState; 15105 } 15106 if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 15107 && (cr.flags&Context.BIND_SHOWING_UI) != 0) { 15108 app.pendingUiClean = true; 15109 } 15110 if (adjType != null) { 15111 app.adjType = adjType; 15112 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 15113 .REASON_SERVICE_IN_USE; 15114 app.adjSource = cr.binding.client; 15115 app.adjSourceOom = clientAdj; 15116 app.adjTarget = s.name; 15117 } 15118 } 15119 if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) { 15120 app.treatLikeActivity = true; 15121 } 15122 final ActivityRecord a = cr.activity; 15123 if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) { 15124 if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ && 15125 (a.visible || a.state == ActivityState.RESUMED 15126 || a.state == ActivityState.PAUSING)) { 15127 adj = ProcessList.FOREGROUND_APP_ADJ; 15128 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 15129 schedGroup = Process.THREAD_GROUP_DEFAULT; 15130 } 15131 app.cached = false; 15132 app.adjType = "service"; 15133 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 15134 .REASON_SERVICE_IN_USE; 15135 app.adjSource = a; 15136 app.adjSourceOom = adj; 15137 app.adjTarget = s.name; 15138 } 15139 } 15140 } 15141 } 15142 } 15143 15144 for (int provi = app.pubProviders.size()-1; 15145 provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 15146 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 15147 || procState > ActivityManager.PROCESS_STATE_TOP); 15148 provi--) { 15149 ContentProviderRecord cpr = app.pubProviders.valueAt(provi); 15150 for (int i = cpr.connections.size()-1; 15151 i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 15152 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 15153 || procState > ActivityManager.PROCESS_STATE_TOP); 15154 i--) { 15155 ContentProviderConnection conn = cpr.connections.get(i); 15156 ProcessRecord client = conn.client; 15157 if (client == app) { 15158 // Being our own client is not interesting. 15159 continue; 15160 } 15161 int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now); 15162 int clientProcState = client.curProcState; 15163 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 15164 // If the other app is cached for any reason, for purposes here 15165 // we are going to consider it empty. 15166 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 15167 } 15168 if (adj > clientAdj) { 15169 if (app.hasShownUi && app != mHomeProcess 15170 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 15171 app.adjType = "cch-ui-provider"; 15172 } else { 15173 adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ 15174 ? clientAdj : ProcessList.FOREGROUND_APP_ADJ; 15175 app.adjType = "provider"; 15176 } 15177 app.cached &= client.cached; 15178 app.keeping |= client.keeping; 15179 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 15180 .REASON_PROVIDER_IN_USE; 15181 app.adjSource = client; 15182 app.adjSourceOom = clientAdj; 15183 app.adjTarget = cpr.name; 15184 } 15185 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) { 15186 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) { 15187 // Special handling of clients who are in the top state. 15188 // We *may* want to consider this process to be in the 15189 // top state as well, but only if there is not another 15190 // reason for it to be running. Being on the top is a 15191 // special state, meaning you are specifically running 15192 // for the current top app. If the process is already 15193 // running in the background for some other reason, it 15194 // is more important to continue considering it to be 15195 // in the background state. 15196 mayBeTop = true; 15197 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 15198 } else { 15199 // Special handling for above-top states (persistent 15200 // processes). These should not bring the current process 15201 // into the top state, since they are not on top. Instead 15202 // give them the best state after that. 15203 clientProcState = 15204 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 15205 } 15206 } 15207 if (procState > clientProcState) { 15208 procState = clientProcState; 15209 } 15210 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 15211 schedGroup = Process.THREAD_GROUP_DEFAULT; 15212 } 15213 } 15214 // If the provider has external (non-framework) process 15215 // dependencies, ensure that its adjustment is at least 15216 // FOREGROUND_APP_ADJ. 15217 if (cpr.hasExternalProcessHandles()) { 15218 if (adj > ProcessList.FOREGROUND_APP_ADJ) { 15219 adj = ProcessList.FOREGROUND_APP_ADJ; 15220 schedGroup = Process.THREAD_GROUP_DEFAULT; 15221 app.cached = false; 15222 app.keeping = true; 15223 app.adjType = "provider"; 15224 app.adjTarget = cpr.name; 15225 } 15226 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) { 15227 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 15228 } 15229 } 15230 } 15231 15232 if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) { 15233 // A client of one of our services or providers is in the top state. We 15234 // *may* want to be in the top state, but not if we are already running in 15235 // the background for some other reason. For the decision here, we are going 15236 // to pick out a few specific states that we want to remain in when a client 15237 // is top (states that tend to be longer-term) and otherwise allow it to go 15238 // to the top state. 15239 switch (procState) { 15240 case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND: 15241 case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND: 15242 case ActivityManager.PROCESS_STATE_SERVICE: 15243 // These all are longer-term states, so pull them up to the top 15244 // of the background states, but not all the way to the top state. 15245 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 15246 break; 15247 default: 15248 // Otherwise, top is a better choice, so take it. 15249 procState = ActivityManager.PROCESS_STATE_TOP; 15250 break; 15251 } 15252 } 15253 15254 if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) { 15255 if (app.hasClientActivities) { 15256 // This is a cached process, but with client activities. Mark it so. 15257 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT; 15258 app.adjType = "cch-client-act"; 15259 } else if (app.treatLikeActivity) { 15260 // This is a cached process, but somebody wants us to treat it like it has 15261 // an activity, okay! 15262 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 15263 app.adjType = "cch-as-act"; 15264 } 15265 } 15266 15267 if (adj == ProcessList.SERVICE_ADJ) { 15268 if (doingAll) { 15269 app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3); 15270 mNewNumServiceProcs++; 15271 //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb); 15272 if (!app.serviceb) { 15273 // This service isn't far enough down on the LRU list to 15274 // normally be a B service, but if we are low on RAM and it 15275 // is large we want to force it down since we would prefer to 15276 // keep launcher over it. 15277 if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL 15278 && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) { 15279 app.serviceHighRam = true; 15280 app.serviceb = true; 15281 //Slog.i(TAG, "ADJ " + app + " high ram!"); 15282 } else { 15283 mNewNumAServiceProcs++; 15284 //Slog.i(TAG, "ADJ " + app + " not high ram!"); 15285 } 15286 } else { 15287 app.serviceHighRam = false; 15288 } 15289 } 15290 if (app.serviceb) { 15291 adj = ProcessList.SERVICE_B_ADJ; 15292 } 15293 } 15294 15295 app.curRawAdj = adj; 15296 15297 //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid + 15298 // " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj); 15299 if (adj > app.maxAdj) { 15300 adj = app.maxAdj; 15301 if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 15302 schedGroup = Process.THREAD_GROUP_DEFAULT; 15303 } 15304 } 15305 if (adj < ProcessList.CACHED_APP_MIN_ADJ) { 15306 app.keeping = true; 15307 } 15308 15309 // Do final modification to adj. Everything we do between here and applying 15310 // the final setAdj must be done in this function, because we will also use 15311 // it when computing the final cached adj later. Note that we don't need to 15312 // worry about this for max adj above, since max adj will always be used to 15313 // keep it out of the cached vaues. 15314 app.curAdj = app.modifyRawOomAdj(adj); 15315 app.curSchedGroup = schedGroup; 15316 app.curProcState = procState; 15317 app.foregroundActivities = foregroundActivities; 15318 15319 return app.curRawAdj; 15320 } 15321 15322 /** 15323 * Schedule PSS collection of a process. 15324 */ 15325 void requestPssLocked(ProcessRecord proc, int procState) { 15326 if (mPendingPssProcesses.contains(proc)) { 15327 return; 15328 } 15329 if (mPendingPssProcesses.size() == 0) { 15330 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG); 15331 } 15332 if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc); 15333 proc.pssProcState = procState; 15334 mPendingPssProcesses.add(proc); 15335 } 15336 15337 /** 15338 * Schedule PSS collection of all processes. 15339 */ 15340 void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) { 15341 if (!always) { 15342 if (now < (mLastFullPssTime + 15343 (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) { 15344 return; 15345 } 15346 } 15347 if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs! memLowered=" + memLowered); 15348 mLastFullPssTime = now; 15349 mPendingPssProcesses.ensureCapacity(mLruProcesses.size()); 15350 mPendingPssProcesses.clear(); 15351 for (int i=mLruProcesses.size()-1; i>=0; i--) { 15352 ProcessRecord app = mLruProcesses.get(i); 15353 if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) { 15354 app.pssProcState = app.setProcState; 15355 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true, 15356 isSleeping(), now); 15357 mPendingPssProcesses.add(app); 15358 } 15359 } 15360 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG); 15361 } 15362 15363 /** 15364 * Ask a given process to GC right now. 15365 */ 15366 final void performAppGcLocked(ProcessRecord app) { 15367 try { 15368 app.lastRequestedGc = SystemClock.uptimeMillis(); 15369 if (app.thread != null) { 15370 if (app.reportLowMemory) { 15371 app.reportLowMemory = false; 15372 app.thread.scheduleLowMemory(); 15373 } else { 15374 app.thread.processInBackground(); 15375 } 15376 } 15377 } catch (Exception e) { 15378 // whatever. 15379 } 15380 } 15381 15382 /** 15383 * Returns true if things are idle enough to perform GCs. 15384 */ 15385 private final boolean canGcNowLocked() { 15386 boolean processingBroadcasts = false; 15387 for (BroadcastQueue q : mBroadcastQueues) { 15388 if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) { 15389 processingBroadcasts = true; 15390 } 15391 } 15392 return !processingBroadcasts 15393 && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle()); 15394 } 15395 15396 /** 15397 * Perform GCs on all processes that are waiting for it, but only 15398 * if things are idle. 15399 */ 15400 final void performAppGcsLocked() { 15401 final int N = mProcessesToGc.size(); 15402 if (N <= 0) { 15403 return; 15404 } 15405 if (canGcNowLocked()) { 15406 while (mProcessesToGc.size() > 0) { 15407 ProcessRecord proc = mProcessesToGc.remove(0); 15408 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) { 15409 if ((proc.lastRequestedGc+GC_MIN_INTERVAL) 15410 <= SystemClock.uptimeMillis()) { 15411 // To avoid spamming the system, we will GC processes one 15412 // at a time, waiting a few seconds between each. 15413 performAppGcLocked(proc); 15414 scheduleAppGcsLocked(); 15415 return; 15416 } else { 15417 // It hasn't been long enough since we last GCed this 15418 // process... put it in the list to wait for its time. 15419 addProcessToGcListLocked(proc); 15420 break; 15421 } 15422 } 15423 } 15424 15425 scheduleAppGcsLocked(); 15426 } 15427 } 15428 15429 /** 15430 * If all looks good, perform GCs on all processes waiting for them. 15431 */ 15432 final void performAppGcsIfAppropriateLocked() { 15433 if (canGcNowLocked()) { 15434 performAppGcsLocked(); 15435 return; 15436 } 15437 // Still not idle, wait some more. 15438 scheduleAppGcsLocked(); 15439 } 15440 15441 /** 15442 * Schedule the execution of all pending app GCs. 15443 */ 15444 final void scheduleAppGcsLocked() { 15445 mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG); 15446 15447 if (mProcessesToGc.size() > 0) { 15448 // Schedule a GC for the time to the next process. 15449 ProcessRecord proc = mProcessesToGc.get(0); 15450 Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG); 15451 15452 long when = proc.lastRequestedGc + GC_MIN_INTERVAL; 15453 long now = SystemClock.uptimeMillis(); 15454 if (when < (now+GC_TIMEOUT)) { 15455 when = now + GC_TIMEOUT; 15456 } 15457 mHandler.sendMessageAtTime(msg, when); 15458 } 15459 } 15460 15461 /** 15462 * Add a process to the array of processes waiting to be GCed. Keeps the 15463 * list in sorted order by the last GC time. The process can't already be 15464 * on the list. 15465 */ 15466 final void addProcessToGcListLocked(ProcessRecord proc) { 15467 boolean added = false; 15468 for (int i=mProcessesToGc.size()-1; i>=0; i--) { 15469 if (mProcessesToGc.get(i).lastRequestedGc < 15470 proc.lastRequestedGc) { 15471 added = true; 15472 mProcessesToGc.add(i+1, proc); 15473 break; 15474 } 15475 } 15476 if (!added) { 15477 mProcessesToGc.add(0, proc); 15478 } 15479 } 15480 15481 /** 15482 * Set up to ask a process to GC itself. This will either do it 15483 * immediately, or put it on the list of processes to gc the next 15484 * time things are idle. 15485 */ 15486 final void scheduleAppGcLocked(ProcessRecord app) { 15487 long now = SystemClock.uptimeMillis(); 15488 if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) { 15489 return; 15490 } 15491 if (!mProcessesToGc.contains(app)) { 15492 addProcessToGcListLocked(app); 15493 scheduleAppGcsLocked(); 15494 } 15495 } 15496 15497 final void checkExcessivePowerUsageLocked(boolean doKills) { 15498 updateCpuStatsNow(); 15499 15500 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 15501 boolean doWakeKills = doKills; 15502 boolean doCpuKills = doKills; 15503 if (mLastPowerCheckRealtime == 0) { 15504 doWakeKills = false; 15505 } 15506 if (mLastPowerCheckUptime == 0) { 15507 doCpuKills = false; 15508 } 15509 if (stats.isScreenOn()) { 15510 doWakeKills = false; 15511 } 15512 final long curRealtime = SystemClock.elapsedRealtime(); 15513 final long realtimeSince = curRealtime - mLastPowerCheckRealtime; 15514 final long curUptime = SystemClock.uptimeMillis(); 15515 final long uptimeSince = curUptime - mLastPowerCheckUptime; 15516 mLastPowerCheckRealtime = curRealtime; 15517 mLastPowerCheckUptime = curUptime; 15518 if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) { 15519 doWakeKills = false; 15520 } 15521 if (uptimeSince < CPU_MIN_CHECK_DURATION) { 15522 doCpuKills = false; 15523 } 15524 int i = mLruProcesses.size(); 15525 while (i > 0) { 15526 i--; 15527 ProcessRecord app = mLruProcesses.get(i); 15528 if (!app.keeping) { 15529 long wtime; 15530 synchronized (stats) { 15531 wtime = stats.getProcessWakeTime(app.info.uid, 15532 app.pid, curRealtime); 15533 } 15534 long wtimeUsed = wtime - app.lastWakeTime; 15535 long cputimeUsed = app.curCpuTime - app.lastCpuTime; 15536 if (DEBUG_POWER) { 15537 StringBuilder sb = new StringBuilder(128); 15538 sb.append("Wake for "); 15539 app.toShortString(sb); 15540 sb.append(": over "); 15541 TimeUtils.formatDuration(realtimeSince, sb); 15542 sb.append(" used "); 15543 TimeUtils.formatDuration(wtimeUsed, sb); 15544 sb.append(" ("); 15545 sb.append((wtimeUsed*100)/realtimeSince); 15546 sb.append("%)"); 15547 Slog.i(TAG, sb.toString()); 15548 sb.setLength(0); 15549 sb.append("CPU for "); 15550 app.toShortString(sb); 15551 sb.append(": over "); 15552 TimeUtils.formatDuration(uptimeSince, sb); 15553 sb.append(" used "); 15554 TimeUtils.formatDuration(cputimeUsed, sb); 15555 sb.append(" ("); 15556 sb.append((cputimeUsed*100)/uptimeSince); 15557 sb.append("%)"); 15558 Slog.i(TAG, sb.toString()); 15559 } 15560 // If a process has held a wake lock for more 15561 // than 50% of the time during this period, 15562 // that sounds bad. Kill! 15563 if (doWakeKills && realtimeSince > 0 15564 && ((wtimeUsed*100)/realtimeSince) >= 50) { 15565 synchronized (stats) { 15566 stats.reportExcessiveWakeLocked(app.info.uid, app.processName, 15567 realtimeSince, wtimeUsed); 15568 } 15569 killUnneededProcessLocked(app, "excessive wake held " + wtimeUsed 15570 + " during " + realtimeSince); 15571 app.baseProcessTracker.reportExcessiveWake(app.pkgList); 15572 } else if (doCpuKills && uptimeSince > 0 15573 && ((cputimeUsed*100)/uptimeSince) >= 50) { 15574 synchronized (stats) { 15575 stats.reportExcessiveCpuLocked(app.info.uid, app.processName, 15576 uptimeSince, cputimeUsed); 15577 } 15578 killUnneededProcessLocked(app, "excessive cpu " + cputimeUsed 15579 + " during " + uptimeSince); 15580 app.baseProcessTracker.reportExcessiveCpu(app.pkgList); 15581 } else { 15582 app.lastWakeTime = wtime; 15583 app.lastCpuTime = app.curCpuTime; 15584 } 15585 } 15586 } 15587 } 15588 15589 private final boolean applyOomAdjLocked(ProcessRecord app, boolean wasKeeping, 15590 ProcessRecord TOP_APP, boolean doingAll, long now) { 15591 boolean success = true; 15592 15593 if (app.curRawAdj != app.setRawAdj) { 15594 if (wasKeeping && !app.keeping) { 15595 // This app is no longer something we want to keep. Note 15596 // its current wake lock time to later know to kill it if 15597 // it is not behaving well. 15598 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 15599 synchronized (stats) { 15600 app.lastWakeTime = stats.getProcessWakeTime(app.info.uid, 15601 app.pid, SystemClock.elapsedRealtime()); 15602 } 15603 app.lastCpuTime = app.curCpuTime; 15604 } 15605 15606 app.setRawAdj = app.curRawAdj; 15607 } 15608 15609 int changes = 0; 15610 15611 if (app.curAdj != app.setAdj) { 15612 ProcessList.setOomAdj(app.pid, app.curAdj); 15613 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v( 15614 TAG, "Set " + app.pid + " " + app.processName + 15615 " adj " + app.curAdj + ": " + app.adjType); 15616 app.setAdj = app.curAdj; 15617 } 15618 15619 if (app.setSchedGroup != app.curSchedGroup) { 15620 app.setSchedGroup = app.curSchedGroup; 15621 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 15622 "Setting process group of " + app.processName 15623 + " to " + app.curSchedGroup); 15624 if (app.waitingToKill != null && 15625 app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 15626 killUnneededProcessLocked(app, app.waitingToKill); 15627 success = false; 15628 } else { 15629 if (true) { 15630 long oldId = Binder.clearCallingIdentity(); 15631 try { 15632 Process.setProcessGroup(app.pid, app.curSchedGroup); 15633 } catch (Exception e) { 15634 Slog.w(TAG, "Failed setting process group of " + app.pid 15635 + " to " + app.curSchedGroup); 15636 e.printStackTrace(); 15637 } finally { 15638 Binder.restoreCallingIdentity(oldId); 15639 } 15640 } else { 15641 if (app.thread != null) { 15642 try { 15643 app.thread.setSchedulingGroup(app.curSchedGroup); 15644 } catch (RemoteException e) { 15645 } 15646 } 15647 } 15648 Process.setSwappiness(app.pid, 15649 app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE); 15650 } 15651 } 15652 if (app.repForegroundActivities != app.foregroundActivities) { 15653 app.repForegroundActivities = app.foregroundActivities; 15654 changes |= ProcessChangeItem.CHANGE_ACTIVITIES; 15655 } 15656 if (app.repProcState != app.curProcState) { 15657 app.repProcState = app.curProcState; 15658 changes |= ProcessChangeItem.CHANGE_PROCESS_STATE; 15659 if (app.thread != null) { 15660 try { 15661 if (false) { 15662 //RuntimeException h = new RuntimeException("here"); 15663 Slog.i(TAG, "Sending new process state " + app.repProcState 15664 + " to " + app /*, h*/); 15665 } 15666 app.thread.setProcessState(app.repProcState); 15667 } catch (RemoteException e) { 15668 } 15669 } 15670 } 15671 if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState, 15672 app.setProcState)) { 15673 app.lastStateTime = now; 15674 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true, 15675 isSleeping(), now); 15676 if (DEBUG_PSS) Slog.d(TAG, "Process state change from " 15677 + ProcessList.makeProcStateString(app.setProcState) + " to " 15678 + ProcessList.makeProcStateString(app.curProcState) + " next pss in " 15679 + (app.nextPssTime-now) + ": " + app); 15680 } else { 15681 if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL) 15682 && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) { 15683 requestPssLocked(app, app.setProcState); 15684 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false, 15685 isSleeping(), now); 15686 } else if (false && DEBUG_PSS) { 15687 Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now)); 15688 } 15689 } 15690 if (app.setProcState != app.curProcState) { 15691 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 15692 "Proc state change of " + app.processName 15693 + " to " + app.curProcState); 15694 app.setProcState = app.curProcState; 15695 if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) { 15696 app.notCachedSinceIdle = false; 15697 } 15698 if (!doingAll) { 15699 setProcessTrackerState(app, mProcessStats.getMemFactorLocked(), now); 15700 } else { 15701 app.procStateChanged = true; 15702 } 15703 } 15704 15705 if (changes != 0) { 15706 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes); 15707 int i = mPendingProcessChanges.size()-1; 15708 ProcessChangeItem item = null; 15709 while (i >= 0) { 15710 item = mPendingProcessChanges.get(i); 15711 if (item.pid == app.pid) { 15712 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item); 15713 break; 15714 } 15715 i--; 15716 } 15717 if (i < 0) { 15718 // No existing item in pending changes; need a new one. 15719 final int NA = mAvailProcessChanges.size(); 15720 if (NA > 0) { 15721 item = mAvailProcessChanges.remove(NA-1); 15722 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item); 15723 } else { 15724 item = new ProcessChangeItem(); 15725 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item); 15726 } 15727 item.changes = 0; 15728 item.pid = app.pid; 15729 item.uid = app.info.uid; 15730 if (mPendingProcessChanges.size() == 0) { 15731 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, 15732 "*** Enqueueing dispatch processes changed!"); 15733 mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget(); 15734 } 15735 mPendingProcessChanges.add(item); 15736 } 15737 item.changes |= changes; 15738 item.processState = app.repProcState; 15739 item.foregroundActivities = app.repForegroundActivities; 15740 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item " 15741 + Integer.toHexString(System.identityHashCode(item)) 15742 + " " + app.toShortString() + ": changes=" + item.changes 15743 + " procState=" + item.processState 15744 + " foreground=" + item.foregroundActivities 15745 + " type=" + app.adjType + " source=" + app.adjSource 15746 + " target=" + app.adjTarget); 15747 } 15748 15749 return success; 15750 } 15751 15752 private final void setProcessTrackerState(ProcessRecord proc, int memFactor, long now) { 15753 if (proc.thread != null && proc.baseProcessTracker != null) { 15754 proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList); 15755 } 15756 } 15757 15758 private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj, 15759 ProcessRecord TOP_APP, boolean doingAll, long now) { 15760 if (app.thread == null) { 15761 return false; 15762 } 15763 15764 final boolean wasKeeping = app.keeping; 15765 15766 computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now); 15767 15768 return applyOomAdjLocked(app, wasKeeping, TOP_APP, doingAll, now); 15769 } 15770 15771 final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground, 15772 boolean oomAdj) { 15773 if (isForeground != proc.foregroundServices) { 15774 proc.foregroundServices = isForeground; 15775 ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName, 15776 proc.info.uid); 15777 if (isForeground) { 15778 if (curProcs == null) { 15779 curProcs = new ArrayList<ProcessRecord>(); 15780 mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs); 15781 } 15782 if (!curProcs.contains(proc)) { 15783 curProcs.add(proc); 15784 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START, 15785 proc.info.packageName, proc.info.uid); 15786 } 15787 } else { 15788 if (curProcs != null) { 15789 if (curProcs.remove(proc)) { 15790 mBatteryStatsService.noteEvent( 15791 BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH, 15792 proc.info.packageName, proc.info.uid); 15793 if (curProcs.size() <= 0) { 15794 mForegroundPackages.remove(proc.info.packageName, proc.info.uid); 15795 } 15796 } 15797 } 15798 } 15799 if (oomAdj) { 15800 updateOomAdjLocked(); 15801 } 15802 } 15803 } 15804 15805 private final ActivityRecord resumedAppLocked() { 15806 ActivityRecord act = mStackSupervisor.resumedAppLocked(); 15807 String pkg; 15808 int uid; 15809 if (act != null && !act.sleeping) { 15810 pkg = act.packageName; 15811 uid = act.info.applicationInfo.uid; 15812 } else { 15813 pkg = null; 15814 uid = -1; 15815 } 15816 // Has the UID or resumed package name changed? 15817 if (uid != mCurResumedUid || (pkg != mCurResumedPackage 15818 && (pkg == null || !pkg.equals(mCurResumedPackage)))) { 15819 if (mCurResumedPackage != null) { 15820 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH, 15821 mCurResumedPackage, mCurResumedUid); 15822 } 15823 mCurResumedPackage = pkg; 15824 mCurResumedUid = uid; 15825 if (mCurResumedPackage != null) { 15826 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START, 15827 mCurResumedPackage, mCurResumedUid); 15828 } 15829 } 15830 return act; 15831 } 15832 15833 final boolean updateOomAdjLocked(ProcessRecord app) { 15834 final ActivityRecord TOP_ACT = resumedAppLocked(); 15835 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 15836 final boolean wasCached = app.cached; 15837 15838 mAdjSeq++; 15839 15840 // This is the desired cached adjusment we want to tell it to use. 15841 // If our app is currently cached, we know it, and that is it. Otherwise, 15842 // we don't know it yet, and it needs to now be cached we will then 15843 // need to do a complete oom adj. 15844 final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ 15845 ? app.curRawAdj : ProcessList.UNKNOWN_ADJ; 15846 boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false, 15847 SystemClock.uptimeMillis()); 15848 if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) { 15849 // Changed to/from cached state, so apps after it in the LRU 15850 // list may also be changed. 15851 updateOomAdjLocked(); 15852 } 15853 return success; 15854 } 15855 15856 final void updateOomAdjLocked() { 15857 final ActivityRecord TOP_ACT = resumedAppLocked(); 15858 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 15859 final long now = SystemClock.uptimeMillis(); 15860 final long oldTime = now - ProcessList.MAX_EMPTY_TIME; 15861 final int N = mLruProcesses.size(); 15862 15863 if (false) { 15864 RuntimeException e = new RuntimeException(); 15865 e.fillInStackTrace(); 15866 Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e); 15867 } 15868 15869 mAdjSeq++; 15870 mNewNumServiceProcs = 0; 15871 mNewNumAServiceProcs = 0; 15872 15873 final int emptyProcessLimit; 15874 final int cachedProcessLimit; 15875 if (mProcessLimit <= 0) { 15876 emptyProcessLimit = cachedProcessLimit = 0; 15877 } else if (mProcessLimit == 1) { 15878 emptyProcessLimit = 1; 15879 cachedProcessLimit = 0; 15880 } else { 15881 emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit); 15882 cachedProcessLimit = mProcessLimit - emptyProcessLimit; 15883 } 15884 15885 // Let's determine how many processes we have running vs. 15886 // how many slots we have for background processes; we may want 15887 // to put multiple processes in a slot of there are enough of 15888 // them. 15889 int numSlots = (ProcessList.CACHED_APP_MAX_ADJ 15890 - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2; 15891 int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs; 15892 if (numEmptyProcs > cachedProcessLimit) { 15893 // If there are more empty processes than our limit on cached 15894 // processes, then use the cached process limit for the factor. 15895 // This ensures that the really old empty processes get pushed 15896 // down to the bottom, so if we are running low on memory we will 15897 // have a better chance at keeping around more cached processes 15898 // instead of a gazillion empty processes. 15899 numEmptyProcs = cachedProcessLimit; 15900 } 15901 int emptyFactor = numEmptyProcs/numSlots; 15902 if (emptyFactor < 1) emptyFactor = 1; 15903 int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots; 15904 if (cachedFactor < 1) cachedFactor = 1; 15905 int stepCached = 0; 15906 int stepEmpty = 0; 15907 int numCached = 0; 15908 int numEmpty = 0; 15909 int numTrimming = 0; 15910 15911 mNumNonCachedProcs = 0; 15912 mNumCachedHiddenProcs = 0; 15913 15914 // First update the OOM adjustment for each of the 15915 // application processes based on their current state. 15916 int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ; 15917 int nextCachedAdj = curCachedAdj+1; 15918 int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ; 15919 int nextEmptyAdj = curEmptyAdj+2; 15920 for (int i=N-1; i>=0; i--) { 15921 ProcessRecord app = mLruProcesses.get(i); 15922 if (!app.killedByAm && app.thread != null) { 15923 app.procStateChanged = false; 15924 final boolean wasKeeping = app.keeping; 15925 computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now); 15926 15927 // If we haven't yet assigned the final cached adj 15928 // to the process, do that now. 15929 if (app.curAdj >= ProcessList.UNKNOWN_ADJ) { 15930 switch (app.curProcState) { 15931 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY: 15932 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: 15933 // This process is a cached process holding activities... 15934 // assign it the next cached value for that type, and then 15935 // step that cached level. 15936 app.curRawAdj = curCachedAdj; 15937 app.curAdj = app.modifyRawOomAdj(curCachedAdj); 15938 if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i 15939 + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj 15940 + ")"); 15941 if (curCachedAdj != nextCachedAdj) { 15942 stepCached++; 15943 if (stepCached >= cachedFactor) { 15944 stepCached = 0; 15945 curCachedAdj = nextCachedAdj; 15946 nextCachedAdj += 2; 15947 if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) { 15948 nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ; 15949 } 15950 } 15951 } 15952 break; 15953 default: 15954 // For everything else, assign next empty cached process 15955 // level and bump that up. Note that this means that 15956 // long-running services that have dropped down to the 15957 // cached level will be treated as empty (since their process 15958 // state is still as a service), which is what we want. 15959 app.curRawAdj = curEmptyAdj; 15960 app.curAdj = app.modifyRawOomAdj(curEmptyAdj); 15961 if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i 15962 + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj 15963 + ")"); 15964 if (curEmptyAdj != nextEmptyAdj) { 15965 stepEmpty++; 15966 if (stepEmpty >= emptyFactor) { 15967 stepEmpty = 0; 15968 curEmptyAdj = nextEmptyAdj; 15969 nextEmptyAdj += 2; 15970 if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) { 15971 nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ; 15972 } 15973 } 15974 } 15975 break; 15976 } 15977 } 15978 15979 applyOomAdjLocked(app, wasKeeping, TOP_APP, true, now); 15980 15981 // Count the number of process types. 15982 switch (app.curProcState) { 15983 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY: 15984 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: 15985 mNumCachedHiddenProcs++; 15986 numCached++; 15987 if (numCached > cachedProcessLimit) { 15988 killUnneededProcessLocked(app, "cached #" + numCached); 15989 } 15990 break; 15991 case ActivityManager.PROCESS_STATE_CACHED_EMPTY: 15992 if (numEmpty > ProcessList.TRIM_EMPTY_APPS 15993 && app.lastActivityTime < oldTime) { 15994 killUnneededProcessLocked(app, "empty for " 15995 + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime) 15996 / 1000) + "s"); 15997 } else { 15998 numEmpty++; 15999 if (numEmpty > emptyProcessLimit) { 16000 killUnneededProcessLocked(app, "empty #" + numEmpty); 16001 } 16002 } 16003 break; 16004 default: 16005 mNumNonCachedProcs++; 16006 break; 16007 } 16008 16009 if (app.isolated && app.services.size() <= 0) { 16010 // If this is an isolated process, and there are no 16011 // services running in it, then the process is no longer 16012 // needed. We agressively kill these because we can by 16013 // definition not re-use the same process again, and it is 16014 // good to avoid having whatever code was running in them 16015 // left sitting around after no longer needed. 16016 killUnneededProcessLocked(app, "isolated not needed"); 16017 } 16018 16019 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME 16020 && !app.killedByAm) { 16021 numTrimming++; 16022 } 16023 } 16024 } 16025 16026 mNumServiceProcs = mNewNumServiceProcs; 16027 16028 // Now determine the memory trimming level of background processes. 16029 // Unfortunately we need to start at the back of the list to do this 16030 // properly. We only do this if the number of background apps we 16031 // are managing to keep around is less than half the maximum we desire; 16032 // if we are keeping a good number around, we'll let them use whatever 16033 // memory they want. 16034 final int numCachedAndEmpty = numCached + numEmpty; 16035 int memFactor; 16036 if (numCached <= ProcessList.TRIM_CACHED_APPS 16037 && numEmpty <= ProcessList.TRIM_EMPTY_APPS) { 16038 if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) { 16039 memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL; 16040 } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) { 16041 memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW; 16042 } else { 16043 memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE; 16044 } 16045 } else { 16046 memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL; 16047 } 16048 // We always allow the memory level to go up (better). We only allow it to go 16049 // down if we are in a state where that is allowed, *and* the total number of processes 16050 // has gone down since last time. 16051 if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel 16052 + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size() 16053 + " last=" + mLastNumProcesses); 16054 if (memFactor > mLastMemoryLevel) { 16055 if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) { 16056 memFactor = mLastMemoryLevel; 16057 if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!"); 16058 } 16059 } 16060 mLastMemoryLevel = memFactor; 16061 mLastNumProcesses = mLruProcesses.size(); 16062 boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now); 16063 final int trackerMemFactor = mProcessStats.getMemFactorLocked(); 16064 if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) { 16065 if (mLowRamStartTime == 0) { 16066 mLowRamStartTime = now; 16067 } 16068 int step = 0; 16069 int fgTrimLevel; 16070 switch (memFactor) { 16071 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL: 16072 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL; 16073 break; 16074 case ProcessStats.ADJ_MEM_FACTOR_LOW: 16075 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW; 16076 break; 16077 default: 16078 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE; 16079 break; 16080 } 16081 int factor = numTrimming/3; 16082 int minFactor = 2; 16083 if (mHomeProcess != null) minFactor++; 16084 if (mPreviousProcess != null) minFactor++; 16085 if (factor < minFactor) factor = minFactor; 16086 int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE; 16087 for (int i=N-1; i>=0; i--) { 16088 ProcessRecord app = mLruProcesses.get(i); 16089 if (allChanged || app.procStateChanged) { 16090 setProcessTrackerState(app, trackerMemFactor, now); 16091 app.procStateChanged = false; 16092 } 16093 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME 16094 && !app.killedByAm) { 16095 if (app.trimMemoryLevel < curLevel && app.thread != null) { 16096 try { 16097 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 16098 "Trimming memory of " + app.processName 16099 + " to " + curLevel); 16100 app.thread.scheduleTrimMemory(curLevel); 16101 } catch (RemoteException e) { 16102 } 16103 if (false) { 16104 // For now we won't do this; our memory trimming seems 16105 // to be good enough at this point that destroying 16106 // activities causes more harm than good. 16107 if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE 16108 && app != mHomeProcess && app != mPreviousProcess) { 16109 // Need to do this on its own message because the stack may not 16110 // be in a consistent state at this point. 16111 // For these apps we will also finish their activities 16112 // to help them free memory. 16113 mStackSupervisor.scheduleDestroyAllActivities(app, "trim"); 16114 } 16115 } 16116 } 16117 app.trimMemoryLevel = curLevel; 16118 step++; 16119 if (step >= factor) { 16120 step = 0; 16121 switch (curLevel) { 16122 case ComponentCallbacks2.TRIM_MEMORY_COMPLETE: 16123 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE; 16124 break; 16125 case ComponentCallbacks2.TRIM_MEMORY_MODERATE: 16126 curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 16127 break; 16128 } 16129 } 16130 } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) { 16131 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND 16132 && app.thread != null) { 16133 try { 16134 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 16135 "Trimming memory of heavy-weight " + app.processName 16136 + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 16137 app.thread.scheduleTrimMemory( 16138 ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 16139 } catch (RemoteException e) { 16140 } 16141 } 16142 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 16143 } else { 16144 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 16145 || app.systemNoUi) && app.pendingUiClean) { 16146 // If this application is now in the background and it 16147 // had done UI, then give it the special trim level to 16148 // have it free UI resources. 16149 final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN; 16150 if (app.trimMemoryLevel < level && app.thread != null) { 16151 try { 16152 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 16153 "Trimming memory of bg-ui " + app.processName 16154 + " to " + level); 16155 app.thread.scheduleTrimMemory(level); 16156 } catch (RemoteException e) { 16157 } 16158 } 16159 app.pendingUiClean = false; 16160 } 16161 if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) { 16162 try { 16163 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 16164 "Trimming memory of fg " + app.processName 16165 + " to " + fgTrimLevel); 16166 app.thread.scheduleTrimMemory(fgTrimLevel); 16167 } catch (RemoteException e) { 16168 } 16169 } 16170 app.trimMemoryLevel = fgTrimLevel; 16171 } 16172 } 16173 } else { 16174 if (mLowRamStartTime != 0) { 16175 mLowRamTimeSinceLastIdle += now - mLowRamStartTime; 16176 mLowRamStartTime = 0; 16177 } 16178 for (int i=N-1; i>=0; i--) { 16179 ProcessRecord app = mLruProcesses.get(i); 16180 if (allChanged || app.procStateChanged) { 16181 setProcessTrackerState(app, trackerMemFactor, now); 16182 app.procStateChanged = false; 16183 } 16184 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 16185 || app.systemNoUi) && app.pendingUiClean) { 16186 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN 16187 && app.thread != null) { 16188 try { 16189 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 16190 "Trimming memory of ui hidden " + app.processName 16191 + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 16192 app.thread.scheduleTrimMemory( 16193 ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 16194 } catch (RemoteException e) { 16195 } 16196 } 16197 app.pendingUiClean = false; 16198 } 16199 app.trimMemoryLevel = 0; 16200 } 16201 } 16202 16203 if (mAlwaysFinishActivities) { 16204 // Need to do this on its own message because the stack may not 16205 // be in a consistent state at this point. 16206 mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish"); 16207 } 16208 16209 if (allChanged) { 16210 requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered()); 16211 } 16212 16213 if (mProcessStats.shouldWriteNowLocked(now)) { 16214 mHandler.post(new Runnable() { 16215 @Override public void run() { 16216 synchronized (ActivityManagerService.this) { 16217 mProcessStats.writeStateAsyncLocked(); 16218 } 16219 } 16220 }); 16221 } 16222 16223 if (DEBUG_OOM_ADJ) { 16224 Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms"); 16225 } 16226 } 16227 16228 final void trimApplications() { 16229 synchronized (this) { 16230 int i; 16231 16232 // First remove any unused application processes whose package 16233 // has been removed. 16234 for (i=mRemovedProcesses.size()-1; i>=0; i--) { 16235 final ProcessRecord app = mRemovedProcesses.get(i); 16236 if (app.activities.size() == 0 16237 && app.curReceiver == null && app.services.size() == 0) { 16238 Slog.i( 16239 TAG, "Exiting empty application process " 16240 + app.processName + " (" 16241 + (app.thread != null ? app.thread.asBinder() : null) 16242 + ")\n"); 16243 if (app.pid > 0 && app.pid != MY_PID) { 16244 EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid, 16245 app.processName, app.setAdj, "empty"); 16246 app.killedByAm = true; 16247 Process.killProcessQuiet(app.pid); 16248 } else { 16249 try { 16250 app.thread.scheduleExit(); 16251 } catch (Exception e) { 16252 // Ignore exceptions. 16253 } 16254 } 16255 cleanUpApplicationRecordLocked(app, false, true, -1); 16256 mRemovedProcesses.remove(i); 16257 16258 if (app.persistent) { 16259 if (app.persistent) { 16260 addAppLocked(app.info, false); 16261 } 16262 } 16263 } 16264 } 16265 16266 // Now update the oom adj for all processes. 16267 updateOomAdjLocked(); 16268 } 16269 } 16270 16271 /** This method sends the specified signal to each of the persistent apps */ 16272 public void signalPersistentProcesses(int sig) throws RemoteException { 16273 if (sig != Process.SIGNAL_USR1) { 16274 throw new SecurityException("Only SIGNAL_USR1 is allowed"); 16275 } 16276 16277 synchronized (this) { 16278 if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES) 16279 != PackageManager.PERMISSION_GRANTED) { 16280 throw new SecurityException("Requires permission " 16281 + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES); 16282 } 16283 16284 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 16285 ProcessRecord r = mLruProcesses.get(i); 16286 if (r.thread != null && r.persistent) { 16287 Process.sendSignal(r.pid, sig); 16288 } 16289 } 16290 } 16291 } 16292 16293 private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) { 16294 if (proc == null || proc == mProfileProc) { 16295 proc = mProfileProc; 16296 path = mProfileFile; 16297 profileType = mProfileType; 16298 clearProfilerLocked(); 16299 } 16300 if (proc == null) { 16301 return; 16302 } 16303 try { 16304 proc.thread.profilerControl(false, path, null, profileType); 16305 } catch (RemoteException e) { 16306 throw new IllegalStateException("Process disappeared"); 16307 } 16308 } 16309 16310 private void clearProfilerLocked() { 16311 if (mProfileFd != null) { 16312 try { 16313 mProfileFd.close(); 16314 } catch (IOException e) { 16315 } 16316 } 16317 mProfileApp = null; 16318 mProfileProc = null; 16319 mProfileFile = null; 16320 mProfileType = 0; 16321 mAutoStopProfiler = false; 16322 } 16323 16324 public boolean profileControl(String process, int userId, boolean start, 16325 String path, ParcelFileDescriptor fd, int profileType) throws RemoteException { 16326 16327 try { 16328 synchronized (this) { 16329 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 16330 // its own permission. 16331 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 16332 != PackageManager.PERMISSION_GRANTED) { 16333 throw new SecurityException("Requires permission " 16334 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 16335 } 16336 16337 if (start && fd == null) { 16338 throw new IllegalArgumentException("null fd"); 16339 } 16340 16341 ProcessRecord proc = null; 16342 if (process != null) { 16343 proc = findProcessLocked(process, userId, "profileControl"); 16344 } 16345 16346 if (start && (proc == null || proc.thread == null)) { 16347 throw new IllegalArgumentException("Unknown process: " + process); 16348 } 16349 16350 if (start) { 16351 stopProfilerLocked(null, null, 0); 16352 setProfileApp(proc.info, proc.processName, path, fd, false); 16353 mProfileProc = proc; 16354 mProfileType = profileType; 16355 try { 16356 fd = fd.dup(); 16357 } catch (IOException e) { 16358 fd = null; 16359 } 16360 proc.thread.profilerControl(start, path, fd, profileType); 16361 fd = null; 16362 mProfileFd = null; 16363 } else { 16364 stopProfilerLocked(proc, path, profileType); 16365 if (fd != null) { 16366 try { 16367 fd.close(); 16368 } catch (IOException e) { 16369 } 16370 } 16371 } 16372 16373 return true; 16374 } 16375 } catch (RemoteException e) { 16376 throw new IllegalStateException("Process disappeared"); 16377 } finally { 16378 if (fd != null) { 16379 try { 16380 fd.close(); 16381 } catch (IOException e) { 16382 } 16383 } 16384 } 16385 } 16386 16387 private ProcessRecord findProcessLocked(String process, int userId, String callName) { 16388 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 16389 userId, true, true, callName, null); 16390 ProcessRecord proc = null; 16391 try { 16392 int pid = Integer.parseInt(process); 16393 synchronized (mPidsSelfLocked) { 16394 proc = mPidsSelfLocked.get(pid); 16395 } 16396 } catch (NumberFormatException e) { 16397 } 16398 16399 if (proc == null) { 16400 ArrayMap<String, SparseArray<ProcessRecord>> all 16401 = mProcessNames.getMap(); 16402 SparseArray<ProcessRecord> procs = all.get(process); 16403 if (procs != null && procs.size() > 0) { 16404 proc = procs.valueAt(0); 16405 if (userId != UserHandle.USER_ALL && proc.userId != userId) { 16406 for (int i=1; i<procs.size(); i++) { 16407 ProcessRecord thisProc = procs.valueAt(i); 16408 if (thisProc.userId == userId) { 16409 proc = thisProc; 16410 break; 16411 } 16412 } 16413 } 16414 } 16415 } 16416 16417 return proc; 16418 } 16419 16420 public boolean dumpHeap(String process, int userId, boolean managed, 16421 String path, ParcelFileDescriptor fd) throws RemoteException { 16422 16423 try { 16424 synchronized (this) { 16425 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 16426 // its own permission (same as profileControl). 16427 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 16428 != PackageManager.PERMISSION_GRANTED) { 16429 throw new SecurityException("Requires permission " 16430 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 16431 } 16432 16433 if (fd == null) { 16434 throw new IllegalArgumentException("null fd"); 16435 } 16436 16437 ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap"); 16438 if (proc == null || proc.thread == null) { 16439 throw new IllegalArgumentException("Unknown process: " + process); 16440 } 16441 16442 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 16443 if (!isDebuggable) { 16444 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 16445 throw new SecurityException("Process not debuggable: " + proc); 16446 } 16447 } 16448 16449 proc.thread.dumpHeap(managed, path, fd); 16450 fd = null; 16451 return true; 16452 } 16453 } catch (RemoteException e) { 16454 throw new IllegalStateException("Process disappeared"); 16455 } finally { 16456 if (fd != null) { 16457 try { 16458 fd.close(); 16459 } catch (IOException e) { 16460 } 16461 } 16462 } 16463 } 16464 16465 /** In this method we try to acquire our lock to make sure that we have not deadlocked */ 16466 public void monitor() { 16467 synchronized (this) { } 16468 } 16469 16470 void onCoreSettingsChange(Bundle settings) { 16471 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 16472 ProcessRecord processRecord = mLruProcesses.get(i); 16473 try { 16474 if (processRecord.thread != null) { 16475 processRecord.thread.setCoreSettings(settings); 16476 } 16477 } catch (RemoteException re) { 16478 /* ignore */ 16479 } 16480 } 16481 } 16482 16483 // Multi-user methods 16484 16485 /** 16486 * Start user, if its not already running, but don't bring it to foreground. 16487 */ 16488 @Override 16489 public boolean startUserInBackground(final int userId) { 16490 return startUser(userId, /* foreground */ false); 16491 } 16492 16493 /** 16494 * Refreshes the list of users related to the current user when either a 16495 * user switch happens or when a new related user is started in the 16496 * background. 16497 */ 16498 private void updateCurrentProfileIdsLocked() { 16499 final List<UserInfo> profiles = getUserManagerLocked().getProfiles( 16500 mCurrentUserId, false /* enabledOnly */); 16501 int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null 16502 for (int i = 0; i < currentProfileIds.length; i++) { 16503 currentProfileIds[i] = profiles.get(i).id; 16504 } 16505 mCurrentProfileIds = currentProfileIds; 16506 } 16507 16508 private Set getProfileIdsLocked(int userId) { 16509 Set userIds = new HashSet<Integer>(); 16510 final List<UserInfo> profiles = getUserManagerLocked().getProfiles( 16511 userId, false /* enabledOnly */); 16512 for (UserInfo user : profiles) { 16513 userIds.add(Integer.valueOf(user.id)); 16514 } 16515 return userIds; 16516 } 16517 16518 @Override 16519 public boolean switchUser(final int userId) { 16520 return startUser(userId, /* foregound */ true); 16521 } 16522 16523 private boolean startUser(final int userId, boolean foreground) { 16524 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 16525 != PackageManager.PERMISSION_GRANTED) { 16526 String msg = "Permission Denial: switchUser() from pid=" 16527 + Binder.getCallingPid() 16528 + ", uid=" + Binder.getCallingUid() 16529 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 16530 Slog.w(TAG, msg); 16531 throw new SecurityException(msg); 16532 } 16533 16534 if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground); 16535 16536 final long ident = Binder.clearCallingIdentity(); 16537 try { 16538 synchronized (this) { 16539 final int oldUserId = mCurrentUserId; 16540 if (oldUserId == userId) { 16541 return true; 16542 } 16543 16544 mStackSupervisor.setLockTaskModeLocked(null); 16545 16546 final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId); 16547 if (userInfo == null) { 16548 Slog.w(TAG, "No user info for user #" + userId); 16549 return false; 16550 } 16551 16552 if (foreground) { 16553 mWindowManager.startFreezingScreen(R.anim.screen_user_exit, 16554 R.anim.screen_user_enter); 16555 } 16556 16557 boolean needStart = false; 16558 16559 // If the user we are switching to is not currently started, then 16560 // we need to start it now. 16561 if (mStartedUsers.get(userId) == null) { 16562 mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false)); 16563 updateStartedUserArrayLocked(); 16564 needStart = true; 16565 } 16566 16567 final Integer userIdInt = Integer.valueOf(userId); 16568 mUserLru.remove(userIdInt); 16569 mUserLru.add(userIdInt); 16570 16571 if (foreground) { 16572 mCurrentUserId = userId; 16573 updateCurrentProfileIdsLocked(); 16574 mWindowManager.setCurrentUser(userId, mCurrentProfileIds); 16575 // Once the internal notion of the active user has switched, we lock the device 16576 // with the option to show the user switcher on the keyguard. 16577 mWindowManager.lockNow(null); 16578 } else { 16579 final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId); 16580 updateCurrentProfileIdsLocked(); 16581 mWindowManager.setCurrentProfileIds(mCurrentProfileIds); 16582 mUserLru.remove(currentUserIdInt); 16583 mUserLru.add(currentUserIdInt); 16584 } 16585 16586 final UserStartedState uss = mStartedUsers.get(userId); 16587 16588 // Make sure user is in the started state. If it is currently 16589 // stopping, we need to knock that off. 16590 if (uss.mState == UserStartedState.STATE_STOPPING) { 16591 // If we are stopping, we haven't sent ACTION_SHUTDOWN, 16592 // so we can just fairly silently bring the user back from 16593 // the almost-dead. 16594 uss.mState = UserStartedState.STATE_RUNNING; 16595 updateStartedUserArrayLocked(); 16596 needStart = true; 16597 } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) { 16598 // This means ACTION_SHUTDOWN has been sent, so we will 16599 // need to treat this as a new boot of the user. 16600 uss.mState = UserStartedState.STATE_BOOTING; 16601 updateStartedUserArrayLocked(); 16602 needStart = true; 16603 } 16604 16605 if (uss.mState == UserStartedState.STATE_BOOTING) { 16606 // Booting up a new user, need to tell system services about it. 16607 // Note that this is on the same handler as scheduling of broadcasts, 16608 // which is important because it needs to go first. 16609 mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId)); 16610 } 16611 16612 if (foreground) { 16613 mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId)); 16614 mHandler.removeMessages(REPORT_USER_SWITCH_MSG); 16615 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 16616 mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG, 16617 oldUserId, userId, uss)); 16618 mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG, 16619 oldUserId, userId, uss), USER_SWITCH_TIMEOUT); 16620 } 16621 16622 if (needStart) { 16623 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 16624 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16625 | Intent.FLAG_RECEIVER_FOREGROUND); 16626 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 16627 broadcastIntentLocked(null, null, intent, 16628 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 16629 false, false, MY_PID, Process.SYSTEM_UID, userId); 16630 } 16631 16632 if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) { 16633 if (userId != UserHandle.USER_OWNER) { 16634 Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE); 16635 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 16636 broadcastIntentLocked(null, null, intent, null, 16637 new IIntentReceiver.Stub() { 16638 public void performReceive(Intent intent, int resultCode, 16639 String data, Bundle extras, boolean ordered, 16640 boolean sticky, int sendingUser) { 16641 userInitialized(uss, userId); 16642 } 16643 }, 0, null, null, null, AppOpsManager.OP_NONE, 16644 true, false, MY_PID, Process.SYSTEM_UID, 16645 userId); 16646 uss.initializing = true; 16647 } else { 16648 getUserManagerLocked().makeInitialized(userInfo.id); 16649 } 16650 } 16651 16652 if (foreground) { 16653 boolean homeInFront = mStackSupervisor.switchUserLocked(userId, uss); 16654 if (homeInFront) { 16655 startHomeActivityLocked(userId); 16656 } else { 16657 mStackSupervisor.resumeTopActivitiesLocked(); 16658 } 16659 EventLogTags.writeAmSwitchUser(userId); 16660 getUserManagerLocked().userForeground(userId); 16661 sendUserSwitchBroadcastsLocked(oldUserId, userId); 16662 } else { 16663 mStackSupervisor.startBackgroundUserLocked(userId, uss); 16664 } 16665 16666 if (needStart) { 16667 Intent intent = new Intent(Intent.ACTION_USER_STARTING); 16668 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 16669 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 16670 broadcastIntentLocked(null, null, intent, 16671 null, new IIntentReceiver.Stub() { 16672 @Override 16673 public void performReceive(Intent intent, int resultCode, String data, 16674 Bundle extras, boolean ordered, boolean sticky, int sendingUser) 16675 throws RemoteException { 16676 } 16677 }, 0, null, null, 16678 android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 16679 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 16680 } 16681 } 16682 } finally { 16683 Binder.restoreCallingIdentity(ident); 16684 } 16685 16686 return true; 16687 } 16688 16689 void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) { 16690 long ident = Binder.clearCallingIdentity(); 16691 try { 16692 Intent intent; 16693 if (oldUserId >= 0) { 16694 intent = new Intent(Intent.ACTION_USER_BACKGROUND); 16695 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16696 | Intent.FLAG_RECEIVER_FOREGROUND); 16697 intent.putExtra(Intent.EXTRA_USER_HANDLE, oldUserId); 16698 broadcastIntentLocked(null, null, intent, 16699 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 16700 false, false, MY_PID, Process.SYSTEM_UID, oldUserId); 16701 } 16702 if (newUserId >= 0) { 16703 intent = new Intent(Intent.ACTION_USER_FOREGROUND); 16704 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16705 | Intent.FLAG_RECEIVER_FOREGROUND); 16706 intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId); 16707 broadcastIntentLocked(null, null, intent, 16708 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 16709 false, false, MY_PID, Process.SYSTEM_UID, newUserId); 16710 intent = new Intent(Intent.ACTION_USER_SWITCHED); 16711 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16712 | Intent.FLAG_RECEIVER_FOREGROUND); 16713 intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId); 16714 broadcastIntentLocked(null, null, intent, 16715 null, null, 0, null, null, 16716 android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE, 16717 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 16718 } 16719 } finally { 16720 Binder.restoreCallingIdentity(ident); 16721 } 16722 } 16723 16724 void dispatchUserSwitch(final UserStartedState uss, final int oldUserId, 16725 final int newUserId) { 16726 final int N = mUserSwitchObservers.beginBroadcast(); 16727 if (N > 0) { 16728 final IRemoteCallback callback = new IRemoteCallback.Stub() { 16729 int mCount = 0; 16730 @Override 16731 public void sendResult(Bundle data) throws RemoteException { 16732 synchronized (ActivityManagerService.this) { 16733 if (mCurUserSwitchCallback == this) { 16734 mCount++; 16735 if (mCount == N) { 16736 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 16737 } 16738 } 16739 } 16740 } 16741 }; 16742 synchronized (this) { 16743 uss.switching = true; 16744 mCurUserSwitchCallback = callback; 16745 } 16746 for (int i=0; i<N; i++) { 16747 try { 16748 mUserSwitchObservers.getBroadcastItem(i).onUserSwitching( 16749 newUserId, callback); 16750 } catch (RemoteException e) { 16751 } 16752 } 16753 } else { 16754 synchronized (this) { 16755 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 16756 } 16757 } 16758 mUserSwitchObservers.finishBroadcast(); 16759 } 16760 16761 void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 16762 synchronized (this) { 16763 Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId); 16764 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 16765 } 16766 } 16767 16768 void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) { 16769 mCurUserSwitchCallback = null; 16770 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 16771 mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG, 16772 oldUserId, newUserId, uss)); 16773 } 16774 16775 void userInitialized(UserStartedState uss, int newUserId) { 16776 completeSwitchAndInitalize(uss, newUserId, true, false); 16777 } 16778 16779 void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 16780 completeSwitchAndInitalize(uss, newUserId, false, true); 16781 } 16782 16783 void completeSwitchAndInitalize(UserStartedState uss, int newUserId, 16784 boolean clearInitializing, boolean clearSwitching) { 16785 boolean unfrozen = false; 16786 synchronized (this) { 16787 if (clearInitializing) { 16788 uss.initializing = false; 16789 getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier()); 16790 } 16791 if (clearSwitching) { 16792 uss.switching = false; 16793 } 16794 if (!uss.switching && !uss.initializing) { 16795 mWindowManager.stopFreezingScreen(); 16796 unfrozen = true; 16797 } 16798 } 16799 if (unfrozen) { 16800 final int N = mUserSwitchObservers.beginBroadcast(); 16801 for (int i=0; i<N; i++) { 16802 try { 16803 mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId); 16804 } catch (RemoteException e) { 16805 } 16806 } 16807 mUserSwitchObservers.finishBroadcast(); 16808 } 16809 } 16810 16811 void scheduleStartProfilesLocked() { 16812 if (!mHandler.hasMessages(START_PROFILES_MSG)) { 16813 mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG), 16814 DateUtils.SECOND_IN_MILLIS); 16815 } 16816 } 16817 16818 void startProfilesLocked() { 16819 if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked"); 16820 List<UserInfo> profiles = getUserManagerLocked().getProfiles( 16821 mCurrentUserId, false /* enabledOnly */); 16822 List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size()); 16823 for (UserInfo user : profiles) { 16824 if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED 16825 && user.id != mCurrentUserId) { 16826 toStart.add(user); 16827 } 16828 } 16829 final int n = toStart.size(); 16830 int i = 0; 16831 for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) { 16832 startUserInBackground(toStart.get(i).id); 16833 } 16834 if (i < n) { 16835 Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS"); 16836 } 16837 } 16838 16839 void finishUserBoot(UserStartedState uss) { 16840 synchronized (this) { 16841 if (uss.mState == UserStartedState.STATE_BOOTING 16842 && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) { 16843 uss.mState = UserStartedState.STATE_RUNNING; 16844 final int userId = uss.mHandle.getIdentifier(); 16845 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 16846 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 16847 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT); 16848 broadcastIntentLocked(null, null, intent, 16849 null, null, 0, null, null, 16850 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE, 16851 true, false, MY_PID, Process.SYSTEM_UID, userId); 16852 } 16853 } 16854 } 16855 16856 void finishUserSwitch(UserStartedState uss) { 16857 synchronized (this) { 16858 finishUserBoot(uss); 16859 16860 startProfilesLocked(); 16861 16862 int num = mUserLru.size(); 16863 int i = 0; 16864 while (num > MAX_RUNNING_USERS && i < mUserLru.size()) { 16865 Integer oldUserId = mUserLru.get(i); 16866 UserStartedState oldUss = mStartedUsers.get(oldUserId); 16867 if (oldUss == null) { 16868 // Shouldn't happen, but be sane if it does. 16869 mUserLru.remove(i); 16870 num--; 16871 continue; 16872 } 16873 if (oldUss.mState == UserStartedState.STATE_STOPPING 16874 || oldUss.mState == UserStartedState.STATE_SHUTDOWN) { 16875 // This user is already stopping, doesn't count. 16876 num--; 16877 i++; 16878 continue; 16879 } 16880 if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) { 16881 // Owner and current can't be stopped, but count as running. 16882 i++; 16883 continue; 16884 } 16885 // This is a user to be stopped. 16886 stopUserLocked(oldUserId, null); 16887 num--; 16888 i++; 16889 } 16890 } 16891 } 16892 16893 @Override 16894 public int stopUser(final int userId, final IStopUserCallback callback) { 16895 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 16896 != PackageManager.PERMISSION_GRANTED) { 16897 String msg = "Permission Denial: switchUser() from pid=" 16898 + Binder.getCallingPid() 16899 + ", uid=" + Binder.getCallingUid() 16900 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 16901 Slog.w(TAG, msg); 16902 throw new SecurityException(msg); 16903 } 16904 if (userId <= 0) { 16905 throw new IllegalArgumentException("Can't stop primary user " + userId); 16906 } 16907 synchronized (this) { 16908 return stopUserLocked(userId, callback); 16909 } 16910 } 16911 16912 private int stopUserLocked(final int userId, final IStopUserCallback callback) { 16913 if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId); 16914 if (mCurrentUserId == userId) { 16915 return ActivityManager.USER_OP_IS_CURRENT; 16916 } 16917 16918 final UserStartedState uss = mStartedUsers.get(userId); 16919 if (uss == null) { 16920 // User is not started, nothing to do... but we do need to 16921 // callback if requested. 16922 if (callback != null) { 16923 mHandler.post(new Runnable() { 16924 @Override 16925 public void run() { 16926 try { 16927 callback.userStopped(userId); 16928 } catch (RemoteException e) { 16929 } 16930 } 16931 }); 16932 } 16933 return ActivityManager.USER_OP_SUCCESS; 16934 } 16935 16936 if (callback != null) { 16937 uss.mStopCallbacks.add(callback); 16938 } 16939 16940 if (uss.mState != UserStartedState.STATE_STOPPING 16941 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 16942 uss.mState = UserStartedState.STATE_STOPPING; 16943 updateStartedUserArrayLocked(); 16944 16945 long ident = Binder.clearCallingIdentity(); 16946 try { 16947 // We are going to broadcast ACTION_USER_STOPPING and then 16948 // once that is done send a final ACTION_SHUTDOWN and then 16949 // stop the user. 16950 final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING); 16951 stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 16952 stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 16953 stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true); 16954 final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN); 16955 // This is the result receiver for the final shutdown broadcast. 16956 final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() { 16957 @Override 16958 public void performReceive(Intent intent, int resultCode, String data, 16959 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 16960 finishUserStop(uss); 16961 } 16962 }; 16963 // This is the result receiver for the initial stopping broadcast. 16964 final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() { 16965 @Override 16966 public void performReceive(Intent intent, int resultCode, String data, 16967 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 16968 // On to the next. 16969 synchronized (ActivityManagerService.this) { 16970 if (uss.mState != UserStartedState.STATE_STOPPING) { 16971 // Whoops, we are being started back up. Abort, abort! 16972 return; 16973 } 16974 uss.mState = UserStartedState.STATE_SHUTDOWN; 16975 } 16976 mSystemServiceManager.stopUser(userId); 16977 broadcastIntentLocked(null, null, shutdownIntent, 16978 null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE, 16979 true, false, MY_PID, Process.SYSTEM_UID, userId); 16980 } 16981 }; 16982 // Kick things off. 16983 broadcastIntentLocked(null, null, stoppingIntent, 16984 null, stoppingReceiver, 0, null, null, 16985 android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 16986 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 16987 } finally { 16988 Binder.restoreCallingIdentity(ident); 16989 } 16990 } 16991 16992 return ActivityManager.USER_OP_SUCCESS; 16993 } 16994 16995 void finishUserStop(UserStartedState uss) { 16996 final int userId = uss.mHandle.getIdentifier(); 16997 boolean stopped; 16998 ArrayList<IStopUserCallback> callbacks; 16999 synchronized (this) { 17000 callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks); 17001 if (mStartedUsers.get(userId) != uss) { 17002 stopped = false; 17003 } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) { 17004 stopped = false; 17005 } else { 17006 stopped = true; 17007 // User can no longer run. 17008 mStartedUsers.remove(userId); 17009 mUserLru.remove(Integer.valueOf(userId)); 17010 updateStartedUserArrayLocked(); 17011 17012 // Clean up all state and processes associated with the user. 17013 // Kill all the processes for the user. 17014 forceStopUserLocked(userId, "finish user"); 17015 } 17016 } 17017 17018 for (int i=0; i<callbacks.size(); i++) { 17019 try { 17020 if (stopped) callbacks.get(i).userStopped(userId); 17021 else callbacks.get(i).userStopAborted(userId); 17022 } catch (RemoteException e) { 17023 } 17024 } 17025 17026 if (stopped) { 17027 mSystemServiceManager.cleanupUser(userId); 17028 synchronized (this) { 17029 mStackSupervisor.removeUserLocked(userId); 17030 } 17031 } 17032 } 17033 17034 @Override 17035 public UserInfo getCurrentUser() { 17036 if ((checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) 17037 != PackageManager.PERMISSION_GRANTED) && ( 17038 checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 17039 != PackageManager.PERMISSION_GRANTED)) { 17040 String msg = "Permission Denial: getCurrentUser() from pid=" 17041 + Binder.getCallingPid() 17042 + ", uid=" + Binder.getCallingUid() 17043 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS; 17044 Slog.w(TAG, msg); 17045 throw new SecurityException(msg); 17046 } 17047 synchronized (this) { 17048 return getUserManagerLocked().getUserInfo(mCurrentUserId); 17049 } 17050 } 17051 17052 int getCurrentUserIdLocked() { 17053 return mCurrentUserId; 17054 } 17055 17056 @Override 17057 public boolean isUserRunning(int userId, boolean orStopped) { 17058 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) 17059 != PackageManager.PERMISSION_GRANTED) { 17060 String msg = "Permission Denial: isUserRunning() from pid=" 17061 + Binder.getCallingPid() 17062 + ", uid=" + Binder.getCallingUid() 17063 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS; 17064 Slog.w(TAG, msg); 17065 throw new SecurityException(msg); 17066 } 17067 synchronized (this) { 17068 return isUserRunningLocked(userId, orStopped); 17069 } 17070 } 17071 17072 boolean isUserRunningLocked(int userId, boolean orStopped) { 17073 UserStartedState state = mStartedUsers.get(userId); 17074 if (state == null) { 17075 return false; 17076 } 17077 if (orStopped) { 17078 return true; 17079 } 17080 return state.mState != UserStartedState.STATE_STOPPING 17081 && state.mState != UserStartedState.STATE_SHUTDOWN; 17082 } 17083 17084 @Override 17085 public int[] getRunningUserIds() { 17086 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) 17087 != PackageManager.PERMISSION_GRANTED) { 17088 String msg = "Permission Denial: isUserRunning() from pid=" 17089 + Binder.getCallingPid() 17090 + ", uid=" + Binder.getCallingUid() 17091 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS; 17092 Slog.w(TAG, msg); 17093 throw new SecurityException(msg); 17094 } 17095 synchronized (this) { 17096 return mStartedUserArray; 17097 } 17098 } 17099 17100 private void updateStartedUserArrayLocked() { 17101 int num = 0; 17102 for (int i=0; i<mStartedUsers.size(); i++) { 17103 UserStartedState uss = mStartedUsers.valueAt(i); 17104 // This list does not include stopping users. 17105 if (uss.mState != UserStartedState.STATE_STOPPING 17106 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 17107 num++; 17108 } 17109 } 17110 mStartedUserArray = new int[num]; 17111 num = 0; 17112 for (int i=0; i<mStartedUsers.size(); i++) { 17113 UserStartedState uss = mStartedUsers.valueAt(i); 17114 if (uss.mState != UserStartedState.STATE_STOPPING 17115 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 17116 mStartedUserArray[num] = mStartedUsers.keyAt(i); 17117 num++; 17118 } 17119 } 17120 } 17121 17122 @Override 17123 public void registerUserSwitchObserver(IUserSwitchObserver observer) { 17124 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 17125 != PackageManager.PERMISSION_GRANTED) { 17126 String msg = "Permission Denial: registerUserSwitchObserver() from pid=" 17127 + Binder.getCallingPid() 17128 + ", uid=" + Binder.getCallingUid() 17129 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 17130 Slog.w(TAG, msg); 17131 throw new SecurityException(msg); 17132 } 17133 17134 mUserSwitchObservers.register(observer); 17135 } 17136 17137 @Override 17138 public void unregisterUserSwitchObserver(IUserSwitchObserver observer) { 17139 mUserSwitchObservers.unregister(observer); 17140 } 17141 17142 private boolean userExists(int userId) { 17143 if (userId == 0) { 17144 return true; 17145 } 17146 UserManagerService ums = getUserManagerLocked(); 17147 return ums != null ? (ums.getUserInfo(userId) != null) : false; 17148 } 17149 17150 int[] getUsersLocked() { 17151 UserManagerService ums = getUserManagerLocked(); 17152 return ums != null ? ums.getUserIds() : new int[] { 0 }; 17153 } 17154 17155 UserManagerService getUserManagerLocked() { 17156 if (mUserManager == null) { 17157 IBinder b = ServiceManager.getService(Context.USER_SERVICE); 17158 mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b); 17159 } 17160 return mUserManager; 17161 } 17162 17163 private int applyUserId(int uid, int userId) { 17164 return UserHandle.getUid(userId, uid); 17165 } 17166 17167 ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) { 17168 if (info == null) return null; 17169 ApplicationInfo newInfo = new ApplicationInfo(info); 17170 newInfo.uid = applyUserId(info.uid, userId); 17171 newInfo.dataDir = USER_DATA_DIR + userId + "/" 17172 + info.packageName; 17173 return newInfo; 17174 } 17175 17176 ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) { 17177 if (aInfo == null 17178 || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) { 17179 return aInfo; 17180 } 17181 17182 ActivityInfo info = new ActivityInfo(aInfo); 17183 info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId); 17184 return info; 17185 } 17186 17187 private final class LocalService extends ActivityManagerInternal { 17188 @Override 17189 public void goingToSleep() { 17190 ActivityManagerService.this.goingToSleep(); 17191 } 17192 17193 @Override 17194 public void wakingUp() { 17195 ActivityManagerService.this.wakingUp(); 17196 } 17197 } 17198 17199 /** 17200 * An implementation of IAppTask, that allows an app to manage its own tasks via 17201 * {@link android.app.ActivityManager.AppTask}. We keep track of the callingUid to ensure that 17202 * only the process that calls getAppTasks() can call the AppTask methods. 17203 */ 17204 class AppTaskImpl extends IAppTask.Stub { 17205 private int mTaskId; 17206 private int mCallingUid; 17207 17208 public AppTaskImpl(int taskId, int callingUid) { 17209 mTaskId = taskId; 17210 mCallingUid = callingUid; 17211 } 17212 17213 @Override 17214 public void finishAndRemoveTask() { 17215 // Ensure that we are called from the same process that created this AppTask 17216 if (mCallingUid != Binder.getCallingUid()) { 17217 Slog.w(TAG, "finishAndRemoveTask: caller " + mCallingUid 17218 + " does not match caller of getAppTasks(): " + Binder.getCallingUid()); 17219 return; 17220 } 17221 17222 synchronized (ActivityManagerService.this) { 17223 long origId = Binder.clearCallingIdentity(); 17224 try { 17225 TaskRecord tr = recentTaskForIdLocked(mTaskId); 17226 if (tr != null) { 17227 // Only kill the process if we are not a new document 17228 int flags = tr.getBaseIntent().getFlags(); 17229 boolean isDocument = (flags & Intent.FLAG_ACTIVITY_NEW_DOCUMENT) == 17230 Intent.FLAG_ACTIVITY_NEW_DOCUMENT; 17231 removeTaskByIdLocked(mTaskId, 17232 !isDocument ? ActivityManager.REMOVE_TASK_KILL_PROCESS : 0); 17233 } 17234 } finally { 17235 Binder.restoreCallingIdentity(origId); 17236 } 17237 } 17238 } 17239 17240 @Override 17241 public ActivityManager.RecentTaskInfo getTaskInfo() { 17242 // Ensure that we are called from the same process that created this AppTask 17243 if (mCallingUid != Binder.getCallingUid()) { 17244 Slog.w(TAG, "finishAndRemoveTask: caller " + mCallingUid 17245 + " does not match caller of getAppTasks(): " + Binder.getCallingUid()); 17246 return null; 17247 } 17248 17249 synchronized (ActivityManagerService.this) { 17250 long origId = Binder.clearCallingIdentity(); 17251 try { 17252 TaskRecord tr = recentTaskForIdLocked(mTaskId); 17253 if (tr != null) { 17254 return createRecentTaskInfoFromTaskRecord(tr); 17255 } 17256 } finally { 17257 Binder.restoreCallingIdentity(origId); 17258 } 17259 return null; 17260 } 17261 } 17262 } 17263} 17264