ActivityManagerService.java revision a002604af0c9b1204556610537b85685d7055996
1/* 2 * Copyright (C) 2006-2008 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17package com.android.server.am; 18 19import static android.content.pm.PackageManager.PERMISSION_GRANTED; 20import static com.android.internal.util.XmlUtils.readBooleanAttribute; 21import static com.android.internal.util.XmlUtils.readIntAttribute; 22import static com.android.internal.util.XmlUtils.readLongAttribute; 23import static com.android.internal.util.XmlUtils.writeBooleanAttribute; 24import static com.android.internal.util.XmlUtils.writeIntAttribute; 25import static com.android.internal.util.XmlUtils.writeLongAttribute; 26import static com.android.server.Watchdog.NATIVE_STACKS_OF_INTEREST; 27import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT; 28import static org.xmlpull.v1.XmlPullParser.START_TAG; 29import static com.android.server.am.ActivityStackSupervisor.HOME_STACK_ID; 30 31import android.Manifest; 32import android.app.AppOpsManager; 33import android.app.IActivityContainer; 34import android.app.IActivityContainerCallback; 35import android.appwidget.AppWidgetManager; 36import android.graphics.Rect; 37import android.os.BatteryStats; 38import android.os.PersistableBundle; 39import android.service.voice.IVoiceInteractionSession; 40import android.util.ArrayMap; 41 42import com.android.internal.R; 43import com.android.internal.annotations.GuardedBy; 44import com.android.internal.app.IAppOpsService; 45import com.android.internal.app.IVoiceInteractor; 46import com.android.internal.app.ProcessMap; 47import com.android.internal.app.ProcessStats; 48import com.android.internal.content.PackageMonitor; 49import com.android.internal.os.BackgroundThread; 50import com.android.internal.os.BatteryStatsImpl; 51import com.android.internal.os.ProcessCpuTracker; 52import com.android.internal.os.TransferPipe; 53import com.android.internal.os.Zygote; 54import com.android.internal.util.FastPrintWriter; 55import com.android.internal.util.FastXmlSerializer; 56import com.android.internal.util.MemInfoReader; 57import com.android.internal.util.Preconditions; 58import com.android.server.AppOpsService; 59import com.android.server.AttributeCache; 60import com.android.server.IntentResolver; 61import com.android.server.LocalServices; 62import com.android.server.ServiceThread; 63import com.android.server.SystemService; 64import com.android.server.SystemServiceManager; 65import com.android.server.Watchdog; 66import com.android.server.am.ActivityStack.ActivityState; 67import com.android.server.firewall.IntentFirewall; 68import com.android.server.pm.UserManagerService; 69import com.android.server.wm.AppTransition; 70import com.android.server.wm.WindowManagerService; 71import com.google.android.collect.Lists; 72import com.google.android.collect.Maps; 73 74import libcore.io.IoUtils; 75 76import org.xmlpull.v1.XmlPullParser; 77import org.xmlpull.v1.XmlPullParserException; 78import org.xmlpull.v1.XmlSerializer; 79 80import android.app.Activity; 81import android.app.ActivityManager; 82import android.app.ActivityManager.RunningTaskInfo; 83import android.app.ActivityManager.StackInfo; 84import android.app.ActivityManagerInternal; 85import android.app.ActivityManagerNative; 86import android.app.ActivityOptions; 87import android.app.ActivityThread; 88import android.app.AlertDialog; 89import android.app.AppGlobals; 90import android.app.ApplicationErrorReport; 91import android.app.Dialog; 92import android.app.IActivityController; 93import android.app.IApplicationThread; 94import android.app.IInstrumentationWatcher; 95import android.app.INotificationManager; 96import android.app.IProcessObserver; 97import android.app.IServiceConnection; 98import android.app.IStopUserCallback; 99import android.app.IUiAutomationConnection; 100import android.app.IUserSwitchObserver; 101import android.app.Instrumentation; 102import android.app.Notification; 103import android.app.NotificationManager; 104import android.app.PendingIntent; 105import android.app.backup.IBackupManager; 106import android.content.ActivityNotFoundException; 107import android.content.BroadcastReceiver; 108import android.content.ClipData; 109import android.content.ComponentCallbacks2; 110import android.content.ComponentName; 111import android.content.ContentProvider; 112import android.content.ContentResolver; 113import android.content.Context; 114import android.content.DialogInterface; 115import android.content.IContentProvider; 116import android.content.IIntentReceiver; 117import android.content.IIntentSender; 118import android.content.Intent; 119import android.content.IntentFilter; 120import android.content.IntentSender; 121import android.content.pm.ActivityInfo; 122import android.content.pm.ApplicationInfo; 123import android.content.pm.ConfigurationInfo; 124import android.content.pm.IPackageDataObserver; 125import android.content.pm.IPackageManager; 126import android.content.pm.InstrumentationInfo; 127import android.content.pm.PackageInfo; 128import android.content.pm.PackageManager; 129import android.content.pm.ParceledListSlice; 130import android.content.pm.UserInfo; 131import android.content.pm.PackageManager.NameNotFoundException; 132import android.content.pm.PathPermission; 133import android.content.pm.ProviderInfo; 134import android.content.pm.ResolveInfo; 135import android.content.pm.ServiceInfo; 136import android.content.res.CompatibilityInfo; 137import android.content.res.Configuration; 138import android.graphics.Bitmap; 139import android.net.Proxy; 140import android.net.ProxyProperties; 141import android.net.Uri; 142import android.os.Binder; 143import android.os.Build; 144import android.os.Bundle; 145import android.os.Debug; 146import android.os.DropBoxManager; 147import android.os.Environment; 148import android.os.FactoryTest; 149import android.os.FileObserver; 150import android.os.FileUtils; 151import android.os.Handler; 152import android.os.IBinder; 153import android.os.IPermissionController; 154import android.os.IRemoteCallback; 155import android.os.IUserManager; 156import android.os.Looper; 157import android.os.Message; 158import android.os.Parcel; 159import android.os.ParcelFileDescriptor; 160import android.os.Process; 161import android.os.RemoteCallbackList; 162import android.os.RemoteException; 163import android.os.SELinux; 164import android.os.ServiceManager; 165import android.os.StrictMode; 166import android.os.SystemClock; 167import android.os.SystemProperties; 168import android.os.UpdateLock; 169import android.os.UserHandle; 170import android.provider.Settings; 171import android.text.format.DateUtils; 172import android.text.format.Time; 173import android.util.AtomicFile; 174import android.util.EventLog; 175import android.util.Log; 176import android.util.Pair; 177import android.util.PrintWriterPrinter; 178import android.util.Slog; 179import android.util.SparseArray; 180import android.util.TimeUtils; 181import android.util.Xml; 182import android.view.Gravity; 183import android.view.LayoutInflater; 184import android.view.View; 185import android.view.WindowManager; 186 187import java.io.BufferedInputStream; 188import java.io.BufferedOutputStream; 189import java.io.DataInputStream; 190import java.io.DataOutputStream; 191import java.io.File; 192import java.io.FileDescriptor; 193import java.io.FileInputStream; 194import java.io.FileNotFoundException; 195import java.io.FileOutputStream; 196import java.io.IOException; 197import java.io.InputStreamReader; 198import java.io.PrintWriter; 199import java.io.StringWriter; 200import java.lang.ref.WeakReference; 201import java.util.ArrayList; 202import java.util.Arrays; 203import java.util.Collections; 204import java.util.Comparator; 205import java.util.HashMap; 206import java.util.HashSet; 207import java.util.Iterator; 208import java.util.List; 209import java.util.Locale; 210import java.util.Map; 211import java.util.Set; 212import java.util.concurrent.atomic.AtomicBoolean; 213import java.util.concurrent.atomic.AtomicLong; 214 215public final class ActivityManagerService extends ActivityManagerNative 216 implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback { 217 private static final String USER_DATA_DIR = "/data/user/"; 218 static final String TAG = "ActivityManager"; 219 static final String TAG_MU = "ActivityManagerServiceMU"; 220 static final boolean DEBUG = false; 221 static final boolean localLOGV = DEBUG; 222 static final boolean DEBUG_BACKUP = localLOGV || false; 223 static final boolean DEBUG_BROADCAST = localLOGV || false; 224 static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false; 225 static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false; 226 static final boolean DEBUG_CLEANUP = localLOGV || false; 227 static final boolean DEBUG_CONFIGURATION = localLOGV || false; 228 static final boolean DEBUG_FOCUS = false; 229 static final boolean DEBUG_IMMERSIVE = localLOGV || false; 230 static final boolean DEBUG_MU = localLOGV || false; 231 static final boolean DEBUG_OOM_ADJ = localLOGV || false; 232 static final boolean DEBUG_LRU = localLOGV || false; 233 static final boolean DEBUG_PAUSE = localLOGV || false; 234 static final boolean DEBUG_POWER = localLOGV || false; 235 static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false; 236 static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false; 237 static final boolean DEBUG_PROCESSES = localLOGV || false; 238 static final boolean DEBUG_PROVIDER = localLOGV || false; 239 static final boolean DEBUG_RESULTS = localLOGV || false; 240 static final boolean DEBUG_SERVICE = localLOGV || false; 241 static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false; 242 static final boolean DEBUG_STACK = localLOGV || false; 243 static final boolean DEBUG_SWITCH = localLOGV || false; 244 static final boolean DEBUG_TASKS = localLOGV || false; 245 static final boolean DEBUG_THUMBNAILS = localLOGV || false; 246 static final boolean DEBUG_TRANSITION = localLOGV || false; 247 static final boolean DEBUG_URI_PERMISSION = localLOGV || false; 248 static final boolean DEBUG_USER_LEAVING = localLOGV || false; 249 static final boolean DEBUG_VISBILITY = localLOGV || false; 250 static final boolean DEBUG_PSS = localLOGV || false; 251 static final boolean DEBUG_LOCKSCREEN = localLOGV || false; 252 static final boolean VALIDATE_TOKENS = false; 253 static final boolean SHOW_ACTIVITY_START_TIME = true; 254 255 // Control over CPU and battery monitoring. 256 static final long BATTERY_STATS_TIME = 30*60*1000; // write battery stats every 30 minutes. 257 static final boolean MONITOR_CPU_USAGE = true; 258 static final long MONITOR_CPU_MIN_TIME = 5*1000; // don't sample cpu less than every 5 seconds. 259 static final long MONITOR_CPU_MAX_TIME = 0x0fffffff; // wait possibly forever for next cpu sample. 260 static final boolean MONITOR_THREAD_CPU_USAGE = false; 261 262 // The flags that are set for all calls we make to the package manager. 263 static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES; 264 265 private static final String SYSTEM_DEBUGGABLE = "ro.debuggable"; 266 267 static final boolean IS_USER_BUILD = "user".equals(Build.TYPE); 268 269 // Maximum number of recent tasks that we can remember. 270 static final int MAX_RECENT_TASKS = ActivityManager.isLowRamDeviceStatic() ? 10 : 20; 271 272 // Amount of time after a call to stopAppSwitches() during which we will 273 // prevent further untrusted switches from happening. 274 static final long APP_SWITCH_DELAY_TIME = 5*1000; 275 276 // How long we wait for a launched process to attach to the activity manager 277 // before we decide it's never going to come up for real. 278 static final int PROC_START_TIMEOUT = 10*1000; 279 280 // How long we wait for a launched process to attach to the activity manager 281 // before we decide it's never going to come up for real, when the process was 282 // started with a wrapper for instrumentation (such as Valgrind) because it 283 // could take much longer than usual. 284 static final int PROC_START_TIMEOUT_WITH_WRAPPER = 300*1000; 285 286 // How long to wait after going idle before forcing apps to GC. 287 static final int GC_TIMEOUT = 5*1000; 288 289 // The minimum amount of time between successive GC requests for a process. 290 static final int GC_MIN_INTERVAL = 60*1000; 291 292 // The minimum amount of time between successive PSS requests for a process. 293 static final int FULL_PSS_MIN_INTERVAL = 10*60*1000; 294 295 // The minimum amount of time between successive PSS requests for a process 296 // when the request is due to the memory state being lowered. 297 static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000; 298 299 // The rate at which we check for apps using excessive power -- 15 mins. 300 static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000; 301 302 // The minimum sample duration we will allow before deciding we have 303 // enough data on wake locks to start killing things. 304 static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000; 305 306 // The minimum sample duration we will allow before deciding we have 307 // enough data on CPU usage to start killing things. 308 static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000; 309 310 // How long we allow a receiver to run before giving up on it. 311 static final int BROADCAST_FG_TIMEOUT = 10*1000; 312 static final int BROADCAST_BG_TIMEOUT = 60*1000; 313 314 // How long we wait until we timeout on key dispatching. 315 static final int KEY_DISPATCHING_TIMEOUT = 5*1000; 316 317 // How long we wait until we timeout on key dispatching during instrumentation. 318 static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000; 319 320 // Amount of time we wait for observers to handle a user switch before 321 // giving up on them and unfreezing the screen. 322 static final int USER_SWITCH_TIMEOUT = 2*1000; 323 324 // Maximum number of users we allow to be running at a time. 325 static final int MAX_RUNNING_USERS = 3; 326 327 // How long to wait in getAssistContextExtras for the activity and foreground services 328 // to respond with the result. 329 static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500; 330 331 // Maximum number of persisted Uri grants a package is allowed 332 static final int MAX_PERSISTED_URI_GRANTS = 128; 333 334 static final int MY_PID = Process.myPid(); 335 336 static final String[] EMPTY_STRING_ARRAY = new String[0]; 337 338 // How many bytes to write into the dropbox log before truncating 339 static final int DROPBOX_MAX_SIZE = 256 * 1024; 340 341 /** All system services */ 342 SystemServiceManager mSystemServiceManager; 343 344 /** Run all ActivityStacks through this */ 345 ActivityStackSupervisor mStackSupervisor; 346 347 public IntentFirewall mIntentFirewall; 348 349 // Whether we should show our dialogs (ANR, crash, etc) or just perform their 350 // default actuion automatically. Important for devices without direct input 351 // devices. 352 private boolean mShowDialogs = true; 353 354 /** 355 * Description of a request to start a new activity, which has been held 356 * due to app switches being disabled. 357 */ 358 static class PendingActivityLaunch { 359 final ActivityRecord r; 360 final ActivityRecord sourceRecord; 361 final int startFlags; 362 final ActivityStack stack; 363 364 PendingActivityLaunch(ActivityRecord _r, ActivityRecord _sourceRecord, 365 int _startFlags, ActivityStack _stack) { 366 r = _r; 367 sourceRecord = _sourceRecord; 368 startFlags = _startFlags; 369 stack = _stack; 370 } 371 } 372 373 final ArrayList<PendingActivityLaunch> mPendingActivityLaunches 374 = new ArrayList<PendingActivityLaunch>(); 375 376 BroadcastQueue mFgBroadcastQueue; 377 BroadcastQueue mBgBroadcastQueue; 378 // Convenient for easy iteration over the queues. Foreground is first 379 // so that dispatch of foreground broadcasts gets precedence. 380 final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2]; 381 382 BroadcastQueue broadcastQueueForIntent(Intent intent) { 383 final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0; 384 if (DEBUG_BACKGROUND_BROADCAST) { 385 Slog.i(TAG, "Broadcast intent " + intent + " on " 386 + (isFg ? "foreground" : "background") 387 + " queue"); 388 } 389 return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue; 390 } 391 392 BroadcastRecord broadcastRecordForReceiverLocked(IBinder receiver) { 393 for (BroadcastQueue queue : mBroadcastQueues) { 394 BroadcastRecord r = queue.getMatchingOrderedReceiver(receiver); 395 if (r != null) { 396 return r; 397 } 398 } 399 return null; 400 } 401 402 /** 403 * Activity we have told the window manager to have key focus. 404 */ 405 ActivityRecord mFocusedActivity = null; 406 407 /** 408 * List of intents that were used to start the most recent tasks. 409 */ 410 final ArrayList<TaskRecord> mRecentTasks = new ArrayList<TaskRecord>(); 411 412 public class PendingAssistExtras extends Binder implements Runnable { 413 public final ActivityRecord activity; 414 public boolean haveResult = false; 415 public Bundle result = null; 416 public PendingAssistExtras(ActivityRecord _activity) { 417 activity = _activity; 418 } 419 @Override 420 public void run() { 421 Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity); 422 synchronized (this) { 423 haveResult = true; 424 notifyAll(); 425 } 426 } 427 } 428 429 final ArrayList<PendingAssistExtras> mPendingAssistExtras 430 = new ArrayList<PendingAssistExtras>(); 431 432 /** 433 * Process management. 434 */ 435 final ProcessList mProcessList = new ProcessList(); 436 437 /** 438 * All of the applications we currently have running organized by name. 439 * The keys are strings of the application package name (as 440 * returned by the package manager), and the keys are ApplicationRecord 441 * objects. 442 */ 443 final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>(); 444 445 /** 446 * Tracking long-term execution of processes to look for abuse and other 447 * bad app behavior. 448 */ 449 final ProcessStatsService mProcessStats; 450 451 /** 452 * The currently running isolated processes. 453 */ 454 final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>(); 455 456 /** 457 * Counter for assigning isolated process uids, to avoid frequently reusing the 458 * same ones. 459 */ 460 int mNextIsolatedProcessUid = 0; 461 462 /** 463 * The currently running heavy-weight process, if any. 464 */ 465 ProcessRecord mHeavyWeightProcess = null; 466 467 /** 468 * The last time that various processes have crashed. 469 */ 470 final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>(); 471 472 /** 473 * Information about a process that is currently marked as bad. 474 */ 475 static final class BadProcessInfo { 476 BadProcessInfo(long time, String shortMsg, String longMsg, String stack) { 477 this.time = time; 478 this.shortMsg = shortMsg; 479 this.longMsg = longMsg; 480 this.stack = stack; 481 } 482 483 final long time; 484 final String shortMsg; 485 final String longMsg; 486 final String stack; 487 } 488 489 /** 490 * Set of applications that we consider to be bad, and will reject 491 * incoming broadcasts from (which the user has no control over). 492 * Processes are added to this set when they have crashed twice within 493 * a minimum amount of time; they are removed from it when they are 494 * later restarted (hopefully due to some user action). The value is the 495 * time it was added to the list. 496 */ 497 final ProcessMap<BadProcessInfo> mBadProcesses = new ProcessMap<BadProcessInfo>(); 498 499 /** 500 * All of the processes we currently have running organized by pid. 501 * The keys are the pid running the application. 502 * 503 * <p>NOTE: This object is protected by its own lock, NOT the global 504 * activity manager lock! 505 */ 506 final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>(); 507 508 /** 509 * All of the processes that have been forced to be foreground. The key 510 * is the pid of the caller who requested it (we hold a death 511 * link on it). 512 */ 513 abstract class ForegroundToken implements IBinder.DeathRecipient { 514 int pid; 515 IBinder token; 516 } 517 final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>(); 518 519 /** 520 * List of records for processes that someone had tried to start before the 521 * system was ready. We don't start them at that point, but ensure they 522 * are started by the time booting is complete. 523 */ 524 final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>(); 525 526 /** 527 * List of persistent applications that are in the process 528 * of being started. 529 */ 530 final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>(); 531 532 /** 533 * Processes that are being forcibly torn down. 534 */ 535 final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>(); 536 537 /** 538 * List of running applications, sorted by recent usage. 539 * The first entry in the list is the least recently used. 540 */ 541 final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>(); 542 543 /** 544 * Where in mLruProcesses that the processes hosting activities start. 545 */ 546 int mLruProcessActivityStart = 0; 547 548 /** 549 * Where in mLruProcesses that the processes hosting services start. 550 * This is after (lower index) than mLruProcessesActivityStart. 551 */ 552 int mLruProcessServiceStart = 0; 553 554 /** 555 * List of processes that should gc as soon as things are idle. 556 */ 557 final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>(); 558 559 /** 560 * Processes we want to collect PSS data from. 561 */ 562 final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>(); 563 564 /** 565 * Last time we requested PSS data of all processes. 566 */ 567 long mLastFullPssTime = SystemClock.uptimeMillis(); 568 569 /** 570 * This is the process holding what we currently consider to be 571 * the "home" activity. 572 */ 573 ProcessRecord mHomeProcess; 574 575 /** 576 * This is the process holding the activity the user last visited that 577 * is in a different process from the one they are currently in. 578 */ 579 ProcessRecord mPreviousProcess; 580 581 /** 582 * The time at which the previous process was last visible. 583 */ 584 long mPreviousProcessVisibleTime; 585 586 /** 587 * Which uses have been started, so are allowed to run code. 588 */ 589 final SparseArray<UserStartedState> mStartedUsers = new SparseArray<UserStartedState>(); 590 591 /** 592 * LRU list of history of current users. Most recently current is at the end. 593 */ 594 final ArrayList<Integer> mUserLru = new ArrayList<Integer>(); 595 596 /** 597 * Constant array of the users that are currently started. 598 */ 599 int[] mStartedUserArray = new int[] { 0 }; 600 601 /** 602 * Registered observers of the user switching mechanics. 603 */ 604 final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers 605 = new RemoteCallbackList<IUserSwitchObserver>(); 606 607 /** 608 * Currently active user switch. 609 */ 610 Object mCurUserSwitchCallback; 611 612 /** 613 * Packages that the user has asked to have run in screen size 614 * compatibility mode instead of filling the screen. 615 */ 616 final CompatModePackages mCompatModePackages; 617 618 /** 619 * Set of IntentSenderRecord objects that are currently active. 620 */ 621 final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords 622 = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>(); 623 624 /** 625 * Fingerprints (hashCode()) of stack traces that we've 626 * already logged DropBox entries for. Guarded by itself. If 627 * something (rogue user app) forces this over 628 * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared. 629 */ 630 private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>(); 631 private static final int MAX_DUP_SUPPRESSED_STACKS = 5000; 632 633 /** 634 * Strict Mode background batched logging state. 635 * 636 * The string buffer is guarded by itself, and its lock is also 637 * used to determine if another batched write is already 638 * in-flight. 639 */ 640 private final StringBuilder mStrictModeBuffer = new StringBuilder(); 641 642 /** 643 * Keeps track of all IIntentReceivers that have been registered for 644 * broadcasts. Hash keys are the receiver IBinder, hash value is 645 * a ReceiverList. 646 */ 647 final HashMap<IBinder, ReceiverList> mRegisteredReceivers = 648 new HashMap<IBinder, ReceiverList>(); 649 650 /** 651 * Resolver for broadcast intents to registered receivers. 652 * Holds BroadcastFilter (subclass of IntentFilter). 653 */ 654 final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver 655 = new IntentResolver<BroadcastFilter, BroadcastFilter>() { 656 @Override 657 protected boolean allowFilterResult( 658 BroadcastFilter filter, List<BroadcastFilter> dest) { 659 IBinder target = filter.receiverList.receiver.asBinder(); 660 for (int i=dest.size()-1; i>=0; i--) { 661 if (dest.get(i).receiverList.receiver.asBinder() == target) { 662 return false; 663 } 664 } 665 return true; 666 } 667 668 @Override 669 protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) { 670 if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL 671 || userId == filter.owningUserId) { 672 return super.newResult(filter, match, userId); 673 } 674 return null; 675 } 676 677 @Override 678 protected BroadcastFilter[] newArray(int size) { 679 return new BroadcastFilter[size]; 680 } 681 682 @Override 683 protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) { 684 return packageName.equals(filter.packageName); 685 } 686 }; 687 688 /** 689 * State of all active sticky broadcasts per user. Keys are the action of the 690 * sticky Intent, values are an ArrayList of all broadcasted intents with 691 * that action (which should usually be one). The SparseArray is keyed 692 * by the user ID the sticky is for, and can include UserHandle.USER_ALL 693 * for stickies that are sent to all users. 694 */ 695 final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts = 696 new SparseArray<ArrayMap<String, ArrayList<Intent>>>(); 697 698 final ActiveServices mServices; 699 700 /** 701 * Backup/restore process management 702 */ 703 String mBackupAppName = null; 704 BackupRecord mBackupTarget = null; 705 706 final ProviderMap mProviderMap; 707 708 /** 709 * List of content providers who have clients waiting for them. The 710 * application is currently being launched and the provider will be 711 * removed from this list once it is published. 712 */ 713 final ArrayList<ContentProviderRecord> mLaunchingProviders 714 = new ArrayList<ContentProviderRecord>(); 715 716 /** 717 * File storing persisted {@link #mGrantedUriPermissions}. 718 */ 719 private final AtomicFile mGrantFile; 720 721 /** XML constants used in {@link #mGrantFile} */ 722 private static final String TAG_URI_GRANTS = "uri-grants"; 723 private static final String TAG_URI_GRANT = "uri-grant"; 724 private static final String ATTR_USER_HANDLE = "userHandle"; 725 private static final String ATTR_SOURCE_PKG = "sourcePkg"; 726 private static final String ATTR_TARGET_PKG = "targetPkg"; 727 private static final String ATTR_URI = "uri"; 728 private static final String ATTR_MODE_FLAGS = "modeFlags"; 729 private static final String ATTR_CREATED_TIME = "createdTime"; 730 private static final String ATTR_PREFIX = "prefix"; 731 732 /** 733 * Global set of specific {@link Uri} permissions that have been granted. 734 * This optimized lookup structure maps from {@link UriPermission#targetUid} 735 * to {@link UriPermission#uri} to {@link UriPermission}. 736 */ 737 @GuardedBy("this") 738 private final SparseArray<ArrayMap<GrantUri, UriPermission>> 739 mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>(); 740 741 public static class GrantUri { 742 public final Uri uri; 743 public final boolean prefix; 744 745 public GrantUri(Uri uri, boolean prefix) { 746 this.uri = uri; 747 this.prefix = prefix; 748 } 749 750 @Override 751 public int hashCode() { 752 return toString().hashCode(); 753 } 754 755 @Override 756 public boolean equals(Object o) { 757 if (o instanceof GrantUri) { 758 GrantUri other = (GrantUri) o; 759 return uri.equals(other.uri) && prefix == other.prefix; 760 } 761 return false; 762 } 763 764 @Override 765 public String toString() { 766 if (prefix) { 767 return uri.toString() + " [prefix]"; 768 } else { 769 return uri.toString(); 770 } 771 } 772 } 773 774 CoreSettingsObserver mCoreSettingsObserver; 775 776 /** 777 * Thread-local storage used to carry caller permissions over through 778 * indirect content-provider access. 779 */ 780 private class Identity { 781 public int pid; 782 public int uid; 783 784 Identity(int _pid, int _uid) { 785 pid = _pid; 786 uid = _uid; 787 } 788 } 789 790 private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>(); 791 792 /** 793 * All information we have collected about the runtime performance of 794 * any user id that can impact battery performance. 795 */ 796 final BatteryStatsService mBatteryStatsService; 797 798 /** 799 * Information about component usage 800 */ 801 final UsageStatsService mUsageStatsService; 802 803 /** 804 * Information about and control over application operations 805 */ 806 final AppOpsService mAppOpsService; 807 808 /** 809 * Current configuration information. HistoryRecord objects are given 810 * a reference to this object to indicate which configuration they are 811 * currently running in, so this object must be kept immutable. 812 */ 813 Configuration mConfiguration = new Configuration(); 814 815 /** 816 * Current sequencing integer of the configuration, for skipping old 817 * configurations. 818 */ 819 int mConfigurationSeq = 0; 820 821 /** 822 * Hardware-reported OpenGLES version. 823 */ 824 final int GL_ES_VERSION; 825 826 /** 827 * List of initialization arguments to pass to all processes when binding applications to them. 828 * For example, references to the commonly used services. 829 */ 830 HashMap<String, IBinder> mAppBindArgs; 831 832 /** 833 * Temporary to avoid allocations. Protected by main lock. 834 */ 835 final StringBuilder mStringBuilder = new StringBuilder(256); 836 837 /** 838 * Used to control how we initialize the service. 839 */ 840 ComponentName mTopComponent; 841 String mTopAction = Intent.ACTION_MAIN; 842 String mTopData; 843 boolean mProcessesReady = false; 844 boolean mSystemReady = false; 845 boolean mBooting = false; 846 boolean mWaitingUpdate = false; 847 boolean mDidUpdate = false; 848 boolean mOnBattery = false; 849 boolean mLaunchWarningShown = false; 850 851 Context mContext; 852 853 int mFactoryTest; 854 855 boolean mCheckedForSetup; 856 857 /** 858 * The time at which we will allow normal application switches again, 859 * after a call to {@link #stopAppSwitches()}. 860 */ 861 long mAppSwitchesAllowedTime; 862 863 /** 864 * This is set to true after the first switch after mAppSwitchesAllowedTime 865 * is set; any switches after that will clear the time. 866 */ 867 boolean mDidAppSwitch; 868 869 /** 870 * Last time (in realtime) at which we checked for power usage. 871 */ 872 long mLastPowerCheckRealtime; 873 874 /** 875 * Last time (in uptime) at which we checked for power usage. 876 */ 877 long mLastPowerCheckUptime; 878 879 /** 880 * Set while we are wanting to sleep, to prevent any 881 * activities from being started/resumed. 882 */ 883 private boolean mSleeping = false; 884 885 /** 886 * Set while we are running a voice interaction. This overrides 887 * sleeping while it is active. 888 */ 889 private boolean mRunningVoice = false; 890 891 /** 892 * State of external calls telling us if the device is asleep. 893 */ 894 private boolean mWentToSleep = false; 895 896 /** 897 * State of external call telling us if the lock screen is shown. 898 */ 899 private boolean mLockScreenShown = false; 900 901 /** 902 * Set if we are shutting down the system, similar to sleeping. 903 */ 904 boolean mShuttingDown = false; 905 906 /** 907 * Current sequence id for oom_adj computation traversal. 908 */ 909 int mAdjSeq = 0; 910 911 /** 912 * Current sequence id for process LRU updating. 913 */ 914 int mLruSeq = 0; 915 916 /** 917 * Keep track of the non-cached/empty process we last found, to help 918 * determine how to distribute cached/empty processes next time. 919 */ 920 int mNumNonCachedProcs = 0; 921 922 /** 923 * Keep track of the number of cached hidden procs, to balance oom adj 924 * distribution between those and empty procs. 925 */ 926 int mNumCachedHiddenProcs = 0; 927 928 /** 929 * Keep track of the number of service processes we last found, to 930 * determine on the next iteration which should be B services. 931 */ 932 int mNumServiceProcs = 0; 933 int mNewNumAServiceProcs = 0; 934 int mNewNumServiceProcs = 0; 935 936 /** 937 * Allow the current computed overall memory level of the system to go down? 938 * This is set to false when we are killing processes for reasons other than 939 * memory management, so that the now smaller process list will not be taken as 940 * an indication that memory is tighter. 941 */ 942 boolean mAllowLowerMemLevel = false; 943 944 /** 945 * The last computed memory level, for holding when we are in a state that 946 * processes are going away for other reasons. 947 */ 948 int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL; 949 950 /** 951 * The last total number of process we have, to determine if changes actually look 952 * like a shrinking number of process due to lower RAM. 953 */ 954 int mLastNumProcesses; 955 956 /** 957 * The uptime of the last time we performed idle maintenance. 958 */ 959 long mLastIdleTime = SystemClock.uptimeMillis(); 960 961 /** 962 * Total time spent with RAM that has been added in the past since the last idle time. 963 */ 964 long mLowRamTimeSinceLastIdle = 0; 965 966 /** 967 * If RAM is currently low, when that horrible situation started. 968 */ 969 long mLowRamStartTime = 0; 970 971 /** 972 * For reporting to battery stats the current top application. 973 */ 974 private String mCurResumedPackage = null; 975 private int mCurResumedUid = -1; 976 977 /** 978 * For reporting to battery stats the apps currently running foreground 979 * service. The ProcessMap is package/uid tuples; each of these contain 980 * an array of the currently foreground processes. 981 */ 982 final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages 983 = new ProcessMap<ArrayList<ProcessRecord>>(); 984 985 /** 986 * This is set if we had to do a delayed dexopt of an app before launching 987 * it, to increasing the ANR timeouts in that case. 988 */ 989 boolean mDidDexOpt; 990 991 /** 992 * Set if the systemServer made a call to enterSafeMode. 993 */ 994 boolean mSafeMode; 995 996 String mDebugApp = null; 997 boolean mWaitForDebugger = false; 998 boolean mDebugTransient = false; 999 String mOrigDebugApp = null; 1000 boolean mOrigWaitForDebugger = false; 1001 boolean mAlwaysFinishActivities = false; 1002 IActivityController mController = null; 1003 String mProfileApp = null; 1004 ProcessRecord mProfileProc = null; 1005 String mProfileFile; 1006 ParcelFileDescriptor mProfileFd; 1007 int mProfileType = 0; 1008 boolean mAutoStopProfiler = false; 1009 String mOpenGlTraceApp = null; 1010 1011 static class ProcessChangeItem { 1012 static final int CHANGE_ACTIVITIES = 1<<0; 1013 static final int CHANGE_PROCESS_STATE = 1<<1; 1014 int changes; 1015 int uid; 1016 int pid; 1017 int processState; 1018 boolean foregroundActivities; 1019 } 1020 1021 final RemoteCallbackList<IProcessObserver> mProcessObservers 1022 = new RemoteCallbackList<IProcessObserver>(); 1023 ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5]; 1024 1025 final ArrayList<ProcessChangeItem> mPendingProcessChanges 1026 = new ArrayList<ProcessChangeItem>(); 1027 final ArrayList<ProcessChangeItem> mAvailProcessChanges 1028 = new ArrayList<ProcessChangeItem>(); 1029 1030 /** 1031 * Runtime CPU use collection thread. This object's lock is used to 1032 * protect all related state. 1033 */ 1034 final Thread mProcessCpuThread; 1035 1036 /** 1037 * Used to collect process stats when showing not responding dialog. 1038 * Protected by mProcessCpuThread. 1039 */ 1040 final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker( 1041 MONITOR_THREAD_CPU_USAGE); 1042 final AtomicLong mLastCpuTime = new AtomicLong(0); 1043 final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true); 1044 1045 long mLastWriteTime = 0; 1046 1047 /** 1048 * Used to retain an update lock when the foreground activity is in 1049 * immersive mode. 1050 */ 1051 final UpdateLock mUpdateLock = new UpdateLock("immersive"); 1052 1053 /** 1054 * Set to true after the system has finished booting. 1055 */ 1056 boolean mBooted = false; 1057 1058 int mProcessLimit = ProcessList.MAX_CACHED_APPS; 1059 int mProcessLimitOverride = -1; 1060 1061 WindowManagerService mWindowManager; 1062 1063 final ActivityThread mSystemThread; 1064 1065 int mCurrentUserId = 0; 1066 int[] mCurrentProfileIds = new int[] {UserHandle.USER_OWNER}; // Accessed by ActivityStack 1067 private UserManagerService mUserManager; 1068 1069 private final class AppDeathRecipient implements IBinder.DeathRecipient { 1070 final ProcessRecord mApp; 1071 final int mPid; 1072 final IApplicationThread mAppThread; 1073 1074 AppDeathRecipient(ProcessRecord app, int pid, 1075 IApplicationThread thread) { 1076 if (localLOGV) Slog.v( 1077 TAG, "New death recipient " + this 1078 + " for thread " + thread.asBinder()); 1079 mApp = app; 1080 mPid = pid; 1081 mAppThread = thread; 1082 } 1083 1084 @Override 1085 public void binderDied() { 1086 if (localLOGV) Slog.v( 1087 TAG, "Death received in " + this 1088 + " for thread " + mAppThread.asBinder()); 1089 synchronized(ActivityManagerService.this) { 1090 appDiedLocked(mApp, mPid, mAppThread); 1091 } 1092 } 1093 } 1094 1095 static final int SHOW_ERROR_MSG = 1; 1096 static final int SHOW_NOT_RESPONDING_MSG = 2; 1097 static final int SHOW_FACTORY_ERROR_MSG = 3; 1098 static final int UPDATE_CONFIGURATION_MSG = 4; 1099 static final int GC_BACKGROUND_PROCESSES_MSG = 5; 1100 static final int WAIT_FOR_DEBUGGER_MSG = 6; 1101 static final int SERVICE_TIMEOUT_MSG = 12; 1102 static final int UPDATE_TIME_ZONE = 13; 1103 static final int SHOW_UID_ERROR_MSG = 14; 1104 static final int IM_FEELING_LUCKY_MSG = 15; 1105 static final int PROC_START_TIMEOUT_MSG = 20; 1106 static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21; 1107 static final int KILL_APPLICATION_MSG = 22; 1108 static final int FINALIZE_PENDING_INTENT_MSG = 23; 1109 static final int POST_HEAVY_NOTIFICATION_MSG = 24; 1110 static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25; 1111 static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26; 1112 static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27; 1113 static final int CLEAR_DNS_CACHE_MSG = 28; 1114 static final int UPDATE_HTTP_PROXY_MSG = 29; 1115 static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30; 1116 static final int DISPATCH_PROCESSES_CHANGED = 31; 1117 static final int DISPATCH_PROCESS_DIED = 32; 1118 static final int REPORT_MEM_USAGE_MSG = 33; 1119 static final int REPORT_USER_SWITCH_MSG = 34; 1120 static final int CONTINUE_USER_SWITCH_MSG = 35; 1121 static final int USER_SWITCH_TIMEOUT_MSG = 36; 1122 static final int IMMERSIVE_MODE_LOCK_MSG = 37; 1123 static final int PERSIST_URI_GRANTS_MSG = 38; 1124 static final int REQUEST_ALL_PSS_MSG = 39; 1125 static final int START_PROFILES_MSG = 40; 1126 static final int UPDATE_TIME = 41; 1127 static final int SYSTEM_USER_START_MSG = 42; 1128 static final int SYSTEM_USER_CURRENT_MSG = 43; 1129 1130 static final int FIRST_ACTIVITY_STACK_MSG = 100; 1131 static final int FIRST_BROADCAST_QUEUE_MSG = 200; 1132 static final int FIRST_COMPAT_MODE_MSG = 300; 1133 static final int FIRST_SUPERVISOR_STACK_MSG = 100; 1134 1135 AlertDialog mUidAlert; 1136 CompatModeDialog mCompatModeDialog; 1137 long mLastMemUsageReportTime = 0; 1138 1139 /** 1140 * Flag whether the current user is a "monkey", i.e. whether 1141 * the UI is driven by a UI automation tool. 1142 */ 1143 private boolean mUserIsMonkey; 1144 1145 final ServiceThread mHandlerThread; 1146 final MainHandler mHandler; 1147 1148 final class MainHandler extends Handler { 1149 public MainHandler(Looper looper) { 1150 super(looper, null, true); 1151 } 1152 1153 @Override 1154 public void handleMessage(Message msg) { 1155 switch (msg.what) { 1156 case SHOW_ERROR_MSG: { 1157 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1158 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), 1159 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; 1160 synchronized (ActivityManagerService.this) { 1161 ProcessRecord proc = (ProcessRecord)data.get("app"); 1162 AppErrorResult res = (AppErrorResult) data.get("result"); 1163 if (proc != null && proc.crashDialog != null) { 1164 Slog.e(TAG, "App already has crash dialog: " + proc); 1165 if (res != null) { 1166 res.set(0); 1167 } 1168 return; 1169 } 1170 if (!showBackground && UserHandle.getAppId(proc.uid) 1171 >= Process.FIRST_APPLICATION_UID && proc.userId != mCurrentUserId 1172 && proc.pid != MY_PID) { 1173 Slog.w(TAG, "Skipping crash dialog of " + proc + ": background"); 1174 if (res != null) { 1175 res.set(0); 1176 } 1177 return; 1178 } 1179 if (mShowDialogs && !mSleeping && !mShuttingDown) { 1180 Dialog d = new AppErrorDialog(mContext, 1181 ActivityManagerService.this, res, proc); 1182 d.show(); 1183 proc.crashDialog = d; 1184 } else { 1185 // The device is asleep, so just pretend that the user 1186 // saw a crash dialog and hit "force quit". 1187 if (res != null) { 1188 res.set(0); 1189 } 1190 } 1191 } 1192 1193 ensureBootCompleted(); 1194 } break; 1195 case SHOW_NOT_RESPONDING_MSG: { 1196 synchronized (ActivityManagerService.this) { 1197 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1198 ProcessRecord proc = (ProcessRecord)data.get("app"); 1199 if (proc != null && proc.anrDialog != null) { 1200 Slog.e(TAG, "App already has anr dialog: " + proc); 1201 return; 1202 } 1203 1204 Intent intent = new Intent("android.intent.action.ANR"); 1205 if (!mProcessesReady) { 1206 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 1207 | Intent.FLAG_RECEIVER_FOREGROUND); 1208 } 1209 broadcastIntentLocked(null, null, intent, 1210 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 1211 false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */); 1212 1213 if (mShowDialogs) { 1214 Dialog d = new AppNotRespondingDialog(ActivityManagerService.this, 1215 mContext, proc, (ActivityRecord)data.get("activity"), 1216 msg.arg1 != 0); 1217 d.show(); 1218 proc.anrDialog = d; 1219 } else { 1220 // Just kill the app if there is no dialog to be shown. 1221 killAppAtUsersRequest(proc, null); 1222 } 1223 } 1224 1225 ensureBootCompleted(); 1226 } break; 1227 case SHOW_STRICT_MODE_VIOLATION_MSG: { 1228 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1229 synchronized (ActivityManagerService.this) { 1230 ProcessRecord proc = (ProcessRecord) data.get("app"); 1231 if (proc == null) { 1232 Slog.e(TAG, "App not found when showing strict mode dialog."); 1233 break; 1234 } 1235 if (proc.crashDialog != null) { 1236 Slog.e(TAG, "App already has strict mode dialog: " + proc); 1237 return; 1238 } 1239 AppErrorResult res = (AppErrorResult) data.get("result"); 1240 if (mShowDialogs && !mSleeping && !mShuttingDown) { 1241 Dialog d = new StrictModeViolationDialog(mContext, 1242 ActivityManagerService.this, res, proc); 1243 d.show(); 1244 proc.crashDialog = d; 1245 } else { 1246 // The device is asleep, so just pretend that the user 1247 // saw a crash dialog and hit "force quit". 1248 res.set(0); 1249 } 1250 } 1251 ensureBootCompleted(); 1252 } break; 1253 case SHOW_FACTORY_ERROR_MSG: { 1254 Dialog d = new FactoryErrorDialog( 1255 mContext, msg.getData().getCharSequence("msg")); 1256 d.show(); 1257 ensureBootCompleted(); 1258 } break; 1259 case UPDATE_CONFIGURATION_MSG: { 1260 final ContentResolver resolver = mContext.getContentResolver(); 1261 Settings.System.putConfiguration(resolver, (Configuration)msg.obj); 1262 } break; 1263 case GC_BACKGROUND_PROCESSES_MSG: { 1264 synchronized (ActivityManagerService.this) { 1265 performAppGcsIfAppropriateLocked(); 1266 } 1267 } break; 1268 case WAIT_FOR_DEBUGGER_MSG: { 1269 synchronized (ActivityManagerService.this) { 1270 ProcessRecord app = (ProcessRecord)msg.obj; 1271 if (msg.arg1 != 0) { 1272 if (!app.waitedForDebugger) { 1273 Dialog d = new AppWaitingForDebuggerDialog( 1274 ActivityManagerService.this, 1275 mContext, app); 1276 app.waitDialog = d; 1277 app.waitedForDebugger = true; 1278 d.show(); 1279 } 1280 } else { 1281 if (app.waitDialog != null) { 1282 app.waitDialog.dismiss(); 1283 app.waitDialog = null; 1284 } 1285 } 1286 } 1287 } break; 1288 case SERVICE_TIMEOUT_MSG: { 1289 if (mDidDexOpt) { 1290 mDidDexOpt = false; 1291 Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG); 1292 nmsg.obj = msg.obj; 1293 mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT); 1294 return; 1295 } 1296 mServices.serviceTimeout((ProcessRecord)msg.obj); 1297 } break; 1298 case UPDATE_TIME_ZONE: { 1299 synchronized (ActivityManagerService.this) { 1300 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1301 ProcessRecord r = mLruProcesses.get(i); 1302 if (r.thread != null) { 1303 try { 1304 r.thread.updateTimeZone(); 1305 } catch (RemoteException ex) { 1306 Slog.w(TAG, "Failed to update time zone for: " + r.info.processName); 1307 } 1308 } 1309 } 1310 } 1311 } break; 1312 case CLEAR_DNS_CACHE_MSG: { 1313 synchronized (ActivityManagerService.this) { 1314 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1315 ProcessRecord r = mLruProcesses.get(i); 1316 if (r.thread != null) { 1317 try { 1318 r.thread.clearDnsCache(); 1319 } catch (RemoteException ex) { 1320 Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName); 1321 } 1322 } 1323 } 1324 } 1325 } break; 1326 case UPDATE_HTTP_PROXY_MSG: { 1327 ProxyProperties proxy = (ProxyProperties)msg.obj; 1328 String host = ""; 1329 String port = ""; 1330 String exclList = ""; 1331 String pacFileUrl = null; 1332 if (proxy != null) { 1333 host = proxy.getHost(); 1334 port = Integer.toString(proxy.getPort()); 1335 exclList = proxy.getExclusionList(); 1336 pacFileUrl = proxy.getPacFileUrl(); 1337 } 1338 synchronized (ActivityManagerService.this) { 1339 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1340 ProcessRecord r = mLruProcesses.get(i); 1341 if (r.thread != null) { 1342 try { 1343 r.thread.setHttpProxy(host, port, exclList, pacFileUrl); 1344 } catch (RemoteException ex) { 1345 Slog.w(TAG, "Failed to update http proxy for: " + 1346 r.info.processName); 1347 } 1348 } 1349 } 1350 } 1351 } break; 1352 case SHOW_UID_ERROR_MSG: { 1353 String title = "System UIDs Inconsistent"; 1354 String text = "UIDs on the system are inconsistent, you need to wipe your" 1355 + " data partition or your device will be unstable."; 1356 Log.e(TAG, title + ": " + text); 1357 if (mShowDialogs) { 1358 // XXX This is a temporary dialog, no need to localize. 1359 AlertDialog d = new BaseErrorDialog(mContext); 1360 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR); 1361 d.setCancelable(false); 1362 d.setTitle(title); 1363 d.setMessage(text); 1364 d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky", 1365 mHandler.obtainMessage(IM_FEELING_LUCKY_MSG)); 1366 mUidAlert = d; 1367 d.show(); 1368 } 1369 } break; 1370 case IM_FEELING_LUCKY_MSG: { 1371 if (mUidAlert != null) { 1372 mUidAlert.dismiss(); 1373 mUidAlert = null; 1374 } 1375 } break; 1376 case PROC_START_TIMEOUT_MSG: { 1377 if (mDidDexOpt) { 1378 mDidDexOpt = false; 1379 Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 1380 nmsg.obj = msg.obj; 1381 mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT); 1382 return; 1383 } 1384 ProcessRecord app = (ProcessRecord)msg.obj; 1385 synchronized (ActivityManagerService.this) { 1386 processStartTimedOutLocked(app); 1387 } 1388 } break; 1389 case DO_PENDING_ACTIVITY_LAUNCHES_MSG: { 1390 synchronized (ActivityManagerService.this) { 1391 doPendingActivityLaunchesLocked(true); 1392 } 1393 } break; 1394 case KILL_APPLICATION_MSG: { 1395 synchronized (ActivityManagerService.this) { 1396 int appid = msg.arg1; 1397 boolean restart = (msg.arg2 == 1); 1398 Bundle bundle = (Bundle)msg.obj; 1399 String pkg = bundle.getString("pkg"); 1400 String reason = bundle.getString("reason"); 1401 forceStopPackageLocked(pkg, appid, restart, false, true, false, 1402 false, UserHandle.USER_ALL, reason); 1403 } 1404 } break; 1405 case FINALIZE_PENDING_INTENT_MSG: { 1406 ((PendingIntentRecord)msg.obj).completeFinalize(); 1407 } break; 1408 case POST_HEAVY_NOTIFICATION_MSG: { 1409 INotificationManager inm = NotificationManager.getService(); 1410 if (inm == null) { 1411 return; 1412 } 1413 1414 ActivityRecord root = (ActivityRecord)msg.obj; 1415 ProcessRecord process = root.app; 1416 if (process == null) { 1417 return; 1418 } 1419 1420 try { 1421 Context context = mContext.createPackageContext(process.info.packageName, 0); 1422 String text = mContext.getString(R.string.heavy_weight_notification, 1423 context.getApplicationInfo().loadLabel(context.getPackageManager())); 1424 Notification notification = new Notification(); 1425 notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon; 1426 notification.when = 0; 1427 notification.flags = Notification.FLAG_ONGOING_EVENT; 1428 notification.tickerText = text; 1429 notification.defaults = 0; // please be quiet 1430 notification.sound = null; 1431 notification.vibrate = null; 1432 notification.setLatestEventInfo(context, text, 1433 mContext.getText(R.string.heavy_weight_notification_detail), 1434 PendingIntent.getActivityAsUser(mContext, 0, root.intent, 1435 PendingIntent.FLAG_CANCEL_CURRENT, null, 1436 new UserHandle(root.userId))); 1437 1438 try { 1439 int[] outId = new int[1]; 1440 inm.enqueueNotificationWithTag("android", "android", null, 1441 R.string.heavy_weight_notification, 1442 notification, outId, root.userId); 1443 } catch (RuntimeException e) { 1444 Slog.w(ActivityManagerService.TAG, 1445 "Error showing notification for heavy-weight app", e); 1446 } catch (RemoteException e) { 1447 } 1448 } catch (NameNotFoundException e) { 1449 Slog.w(TAG, "Unable to create context for heavy notification", e); 1450 } 1451 } break; 1452 case CANCEL_HEAVY_NOTIFICATION_MSG: { 1453 INotificationManager inm = NotificationManager.getService(); 1454 if (inm == null) { 1455 return; 1456 } 1457 try { 1458 inm.cancelNotificationWithTag("android", null, 1459 R.string.heavy_weight_notification, msg.arg1); 1460 } catch (RuntimeException e) { 1461 Slog.w(ActivityManagerService.TAG, 1462 "Error canceling notification for service", e); 1463 } catch (RemoteException e) { 1464 } 1465 } break; 1466 case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: { 1467 synchronized (ActivityManagerService.this) { 1468 checkExcessivePowerUsageLocked(true); 1469 removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1470 Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1471 sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 1472 } 1473 } break; 1474 case SHOW_COMPAT_MODE_DIALOG_MSG: { 1475 synchronized (ActivityManagerService.this) { 1476 ActivityRecord ar = (ActivityRecord)msg.obj; 1477 if (mCompatModeDialog != null) { 1478 if (mCompatModeDialog.mAppInfo.packageName.equals( 1479 ar.info.applicationInfo.packageName)) { 1480 return; 1481 } 1482 mCompatModeDialog.dismiss(); 1483 mCompatModeDialog = null; 1484 } 1485 if (ar != null && false) { 1486 if (mCompatModePackages.getPackageAskCompatModeLocked( 1487 ar.packageName)) { 1488 int mode = mCompatModePackages.computeCompatModeLocked( 1489 ar.info.applicationInfo); 1490 if (mode == ActivityManager.COMPAT_MODE_DISABLED 1491 || mode == ActivityManager.COMPAT_MODE_ENABLED) { 1492 mCompatModeDialog = new CompatModeDialog( 1493 ActivityManagerService.this, mContext, 1494 ar.info.applicationInfo); 1495 mCompatModeDialog.show(); 1496 } 1497 } 1498 } 1499 } 1500 break; 1501 } 1502 case DISPATCH_PROCESSES_CHANGED: { 1503 dispatchProcessesChanged(); 1504 break; 1505 } 1506 case DISPATCH_PROCESS_DIED: { 1507 final int pid = msg.arg1; 1508 final int uid = msg.arg2; 1509 dispatchProcessDied(pid, uid); 1510 break; 1511 } 1512 case REPORT_MEM_USAGE_MSG: { 1513 final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj; 1514 Thread thread = new Thread() { 1515 @Override public void run() { 1516 final SparseArray<ProcessMemInfo> infoMap 1517 = new SparseArray<ProcessMemInfo>(memInfos.size()); 1518 for (int i=0, N=memInfos.size(); i<N; i++) { 1519 ProcessMemInfo mi = memInfos.get(i); 1520 infoMap.put(mi.pid, mi); 1521 } 1522 updateCpuStatsNow(); 1523 synchronized (mProcessCpuThread) { 1524 final int N = mProcessCpuTracker.countStats(); 1525 for (int i=0; i<N; i++) { 1526 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 1527 if (st.vsize > 0) { 1528 long pss = Debug.getPss(st.pid, null); 1529 if (pss > 0) { 1530 if (infoMap.indexOfKey(st.pid) < 0) { 1531 ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid, 1532 ProcessList.NATIVE_ADJ, -1, "native", null); 1533 mi.pss = pss; 1534 memInfos.add(mi); 1535 } 1536 } 1537 } 1538 } 1539 } 1540 1541 long totalPss = 0; 1542 for (int i=0, N=memInfos.size(); i<N; i++) { 1543 ProcessMemInfo mi = memInfos.get(i); 1544 if (mi.pss == 0) { 1545 mi.pss = Debug.getPss(mi.pid, null); 1546 } 1547 totalPss += mi.pss; 1548 } 1549 Collections.sort(memInfos, new Comparator<ProcessMemInfo>() { 1550 @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) { 1551 if (lhs.oomAdj != rhs.oomAdj) { 1552 return lhs.oomAdj < rhs.oomAdj ? -1 : 1; 1553 } 1554 if (lhs.pss != rhs.pss) { 1555 return lhs.pss < rhs.pss ? 1 : -1; 1556 } 1557 return 0; 1558 } 1559 }); 1560 1561 StringBuilder tag = new StringBuilder(128); 1562 StringBuilder stack = new StringBuilder(128); 1563 tag.append("Low on memory -- "); 1564 appendMemBucket(tag, totalPss, "total", false); 1565 appendMemBucket(stack, totalPss, "total", true); 1566 1567 StringBuilder logBuilder = new StringBuilder(1024); 1568 logBuilder.append("Low on memory:\n"); 1569 1570 boolean firstLine = true; 1571 int lastOomAdj = Integer.MIN_VALUE; 1572 for (int i=0, N=memInfos.size(); i<N; i++) { 1573 ProcessMemInfo mi = memInfos.get(i); 1574 1575 if (mi.oomAdj != ProcessList.NATIVE_ADJ 1576 && (mi.oomAdj < ProcessList.SERVICE_ADJ 1577 || mi.oomAdj == ProcessList.HOME_APP_ADJ 1578 || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) { 1579 if (lastOomAdj != mi.oomAdj) { 1580 lastOomAdj = mi.oomAdj; 1581 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) { 1582 tag.append(" / "); 1583 } 1584 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) { 1585 if (firstLine) { 1586 stack.append(":"); 1587 firstLine = false; 1588 } 1589 stack.append("\n\t at "); 1590 } else { 1591 stack.append("$"); 1592 } 1593 } else { 1594 tag.append(" "); 1595 stack.append("$"); 1596 } 1597 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) { 1598 appendMemBucket(tag, mi.pss, mi.name, false); 1599 } 1600 appendMemBucket(stack, mi.pss, mi.name, true); 1601 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ 1602 && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) { 1603 stack.append("("); 1604 for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) { 1605 if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) { 1606 stack.append(DUMP_MEM_OOM_LABEL[k]); 1607 stack.append(":"); 1608 stack.append(DUMP_MEM_OOM_ADJ[k]); 1609 } 1610 } 1611 stack.append(")"); 1612 } 1613 } 1614 1615 logBuilder.append(" "); 1616 logBuilder.append(ProcessList.makeOomAdjString(mi.oomAdj)); 1617 logBuilder.append(' '); 1618 logBuilder.append(ProcessList.makeProcStateString(mi.procState)); 1619 logBuilder.append(' '); 1620 ProcessList.appendRamKb(logBuilder, mi.pss); 1621 logBuilder.append(" kB: "); 1622 logBuilder.append(mi.name); 1623 logBuilder.append(" ("); 1624 logBuilder.append(mi.pid); 1625 logBuilder.append(") "); 1626 logBuilder.append(mi.adjType); 1627 logBuilder.append('\n'); 1628 if (mi.adjReason != null) { 1629 logBuilder.append(" "); 1630 logBuilder.append(mi.adjReason); 1631 logBuilder.append('\n'); 1632 } 1633 } 1634 1635 logBuilder.append(" "); 1636 ProcessList.appendRamKb(logBuilder, totalPss); 1637 logBuilder.append(" kB: TOTAL\n"); 1638 1639 long[] infos = new long[Debug.MEMINFO_COUNT]; 1640 Debug.getMemInfo(infos); 1641 logBuilder.append(" MemInfo: "); 1642 logBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, "); 1643 logBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, "); 1644 logBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, "); 1645 logBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, "); 1646 logBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n"); 1647 if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) { 1648 logBuilder.append(" ZRAM: "); 1649 logBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]); 1650 logBuilder.append(" kB RAM, "); 1651 logBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]); 1652 logBuilder.append(" kB swap total, "); 1653 logBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]); 1654 logBuilder.append(" kB swap free\n"); 1655 } 1656 Slog.i(TAG, logBuilder.toString()); 1657 1658 StringBuilder dropBuilder = new StringBuilder(1024); 1659 /* 1660 StringWriter oomSw = new StringWriter(); 1661 PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256); 1662 StringWriter catSw = new StringWriter(); 1663 PrintWriter catPw = new FastPrintWriter(catSw, false, 256); 1664 String[] emptyArgs = new String[] { }; 1665 dumpApplicationMemoryUsage(null, oomPw, " ", emptyArgs, true, catPw); 1666 oomPw.flush(); 1667 String oomString = oomSw.toString(); 1668 */ 1669 dropBuilder.append(stack); 1670 dropBuilder.append('\n'); 1671 dropBuilder.append('\n'); 1672 dropBuilder.append(logBuilder); 1673 dropBuilder.append('\n'); 1674 /* 1675 dropBuilder.append(oomString); 1676 dropBuilder.append('\n'); 1677 */ 1678 StringWriter catSw = new StringWriter(); 1679 synchronized (ActivityManagerService.this) { 1680 PrintWriter catPw = new FastPrintWriter(catSw, false, 256); 1681 String[] emptyArgs = new String[] { }; 1682 catPw.println(); 1683 dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null); 1684 catPw.println(); 1685 mServices.dumpServicesLocked(null, catPw, emptyArgs, 0, 1686 false, false, null); 1687 catPw.println(); 1688 dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null); 1689 catPw.flush(); 1690 } 1691 dropBuilder.append(catSw.toString()); 1692 addErrorToDropBox("lowmem", null, "system_server", null, 1693 null, tag.toString(), dropBuilder.toString(), null, null); 1694 //Slog.i(TAG, "Sent to dropbox:"); 1695 //Slog.i(TAG, dropBuilder.toString()); 1696 synchronized (ActivityManagerService.this) { 1697 long now = SystemClock.uptimeMillis(); 1698 if (mLastMemUsageReportTime < now) { 1699 mLastMemUsageReportTime = now; 1700 } 1701 } 1702 } 1703 }; 1704 thread.start(); 1705 break; 1706 } 1707 case REPORT_USER_SWITCH_MSG: { 1708 dispatchUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2); 1709 break; 1710 } 1711 case CONTINUE_USER_SWITCH_MSG: { 1712 continueUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2); 1713 break; 1714 } 1715 case USER_SWITCH_TIMEOUT_MSG: { 1716 timeoutUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2); 1717 break; 1718 } 1719 case IMMERSIVE_MODE_LOCK_MSG: { 1720 final boolean nextState = (msg.arg1 != 0); 1721 if (mUpdateLock.isHeld() != nextState) { 1722 if (DEBUG_IMMERSIVE) { 1723 final ActivityRecord r = (ActivityRecord) msg.obj; 1724 Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r); 1725 } 1726 if (nextState) { 1727 mUpdateLock.acquire(); 1728 } else { 1729 mUpdateLock.release(); 1730 } 1731 } 1732 break; 1733 } 1734 case PERSIST_URI_GRANTS_MSG: { 1735 writeGrantedUriPermissions(); 1736 break; 1737 } 1738 case REQUEST_ALL_PSS_MSG: { 1739 requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false); 1740 break; 1741 } 1742 case START_PROFILES_MSG: { 1743 synchronized (ActivityManagerService.this) { 1744 startProfilesLocked(); 1745 } 1746 break; 1747 } 1748 case UPDATE_TIME: { 1749 synchronized (ActivityManagerService.this) { 1750 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1751 ProcessRecord r = mLruProcesses.get(i); 1752 if (r.thread != null) { 1753 try { 1754 r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true); 1755 } catch (RemoteException ex) { 1756 Slog.w(TAG, "Failed to update preferences for: " + r.info.processName); 1757 } 1758 } 1759 } 1760 } 1761 break; 1762 } 1763 case SYSTEM_USER_START_MSG: { 1764 mSystemServiceManager.startUser(msg.arg1); 1765 break; 1766 } 1767 case SYSTEM_USER_CURRENT_MSG: { 1768 mSystemServiceManager.switchUser(msg.arg1); 1769 break; 1770 } 1771 } 1772 } 1773 }; 1774 1775 static final int COLLECT_PSS_BG_MSG = 1; 1776 1777 final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) { 1778 @Override 1779 public void handleMessage(Message msg) { 1780 switch (msg.what) { 1781 case COLLECT_PSS_BG_MSG: { 1782 int i=0, num=0; 1783 long start = SystemClock.uptimeMillis(); 1784 long[] tmp = new long[1]; 1785 do { 1786 ProcessRecord proc; 1787 int procState; 1788 int pid; 1789 synchronized (ActivityManagerService.this) { 1790 if (i >= mPendingPssProcesses.size()) { 1791 if (DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num + " of " + i 1792 + " processes in " + (SystemClock.uptimeMillis()-start) + "ms"); 1793 mPendingPssProcesses.clear(); 1794 return; 1795 } 1796 proc = mPendingPssProcesses.get(i); 1797 procState = proc.pssProcState; 1798 if (proc.thread != null && procState == proc.setProcState) { 1799 pid = proc.pid; 1800 } else { 1801 proc = null; 1802 pid = 0; 1803 } 1804 i++; 1805 } 1806 if (proc != null) { 1807 long pss = Debug.getPss(pid, tmp); 1808 synchronized (ActivityManagerService.this) { 1809 if (proc.thread != null && proc.setProcState == procState 1810 && proc.pid == pid) { 1811 num++; 1812 proc.lastPssTime = SystemClock.uptimeMillis(); 1813 proc.baseProcessTracker.addPss(pss, tmp[0], true, proc.pkgList); 1814 if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString() 1815 + ": " + pss + " lastPss=" + proc.lastPss 1816 + " state=" + ProcessList.makeProcStateString(procState)); 1817 if (proc.initialIdlePss == 0) { 1818 proc.initialIdlePss = pss; 1819 } 1820 proc.lastPss = pss; 1821 if (procState >= ActivityManager.PROCESS_STATE_HOME) { 1822 proc.lastCachedPss = pss; 1823 } 1824 } 1825 } 1826 } 1827 } while (true); 1828 } 1829 } 1830 } 1831 }; 1832 1833 /** 1834 * Monitor for package changes and update our internal state. 1835 */ 1836 private final PackageMonitor mPackageMonitor = new PackageMonitor() { 1837 @Override 1838 public void onPackageRemoved(String packageName, int uid) { 1839 // Remove all tasks with activities in the specified package from the list of recent tasks 1840 synchronized (ActivityManagerService.this) { 1841 for (int i = mRecentTasks.size() - 1; i >= 0; i--) { 1842 TaskRecord tr = mRecentTasks.get(i); 1843 ComponentName cn = tr.intent.getComponent(); 1844 if (cn != null && cn.getPackageName().equals(packageName)) { 1845 // If the package name matches, remove the task and kill the process 1846 removeTaskByIdLocked(tr.taskId, ActivityManager.REMOVE_TASK_KILL_PROCESS); 1847 } 1848 } 1849 } 1850 } 1851 1852 @Override 1853 public boolean onPackageChanged(String packageName, int uid, String[] components) { 1854 final PackageManager pm = mContext.getPackageManager(); 1855 final ArrayList<Pair<Intent, Integer>> recentTaskIntents = 1856 new ArrayList<Pair<Intent, Integer>>(); 1857 final ArrayList<Integer> tasksToRemove = new ArrayList<Integer>(); 1858 // Copy the list of recent tasks so that we don't hold onto the lock on 1859 // ActivityManagerService for long periods while checking if components exist. 1860 synchronized (ActivityManagerService.this) { 1861 for (int i = mRecentTasks.size() - 1; i >= 0; i--) { 1862 TaskRecord tr = mRecentTasks.get(i); 1863 recentTaskIntents.add(new Pair<Intent, Integer>(tr.intent, tr.taskId)); 1864 } 1865 } 1866 // Check the recent tasks and filter out all tasks with components that no longer exist. 1867 Intent tmpI = new Intent(); 1868 for (int i = recentTaskIntents.size() - 1; i >= 0; i--) { 1869 Pair<Intent, Integer> p = recentTaskIntents.get(i); 1870 ComponentName cn = p.first.getComponent(); 1871 if (cn != null && cn.getPackageName().equals(packageName)) { 1872 try { 1873 // Add the task to the list to remove if the component no longer exists 1874 tmpI.setComponent(cn); 1875 if (pm.queryIntentActivities(tmpI, PackageManager.MATCH_DEFAULT_ONLY).isEmpty()) { 1876 tasksToRemove.add(p.second); 1877 } 1878 } catch (Exception e) {} 1879 } 1880 } 1881 // Prune all the tasks with removed components from the list of recent tasks 1882 synchronized (ActivityManagerService.this) { 1883 for (int i = tasksToRemove.size() - 1; i >= 0; i--) { 1884 // Remove the task but don't kill the process (since other components in that 1885 // package may still be running and in the background) 1886 removeTaskByIdLocked(tasksToRemove.get(i), 0); 1887 } 1888 } 1889 return true; 1890 } 1891 1892 @Override 1893 public boolean onHandleForceStop(Intent intent, String[] packages, int uid, boolean doit) { 1894 // Force stop the specified packages 1895 if (packages != null) { 1896 for (String pkg : packages) { 1897 synchronized (ActivityManagerService.this) { 1898 if (forceStopPackageLocked(pkg, -1, false, false, false, false, false, 0, 1899 "finished booting")) { 1900 return true; 1901 } 1902 } 1903 } 1904 } 1905 return false; 1906 } 1907 }; 1908 1909 public void setSystemProcess() { 1910 try { 1911 ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true); 1912 ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats); 1913 ServiceManager.addService("meminfo", new MemBinder(this)); 1914 ServiceManager.addService("gfxinfo", new GraphicsBinder(this)); 1915 ServiceManager.addService("dbinfo", new DbBinder(this)); 1916 if (MONITOR_CPU_USAGE) { 1917 ServiceManager.addService("cpuinfo", new CpuBinder(this)); 1918 } 1919 ServiceManager.addService("permission", new PermissionController(this)); 1920 1921 ApplicationInfo info = mContext.getPackageManager().getApplicationInfo( 1922 "android", STOCK_PM_FLAGS); 1923 mSystemThread.installSystemApplicationInfo(info); 1924 1925 synchronized (this) { 1926 ProcessRecord app = newProcessRecordLocked(info, info.processName, false); 1927 app.persistent = true; 1928 app.pid = MY_PID; 1929 app.maxAdj = ProcessList.SYSTEM_ADJ; 1930 app.makeActive(mSystemThread.getApplicationThread(), mProcessStats); 1931 mProcessNames.put(app.processName, app.uid, app); 1932 synchronized (mPidsSelfLocked) { 1933 mPidsSelfLocked.put(app.pid, app); 1934 } 1935 updateLruProcessLocked(app, false, null); 1936 updateOomAdjLocked(); 1937 } 1938 } catch (PackageManager.NameNotFoundException e) { 1939 throw new RuntimeException( 1940 "Unable to find android system package", e); 1941 } 1942 } 1943 1944 public void setWindowManager(WindowManagerService wm) { 1945 mWindowManager = wm; 1946 mStackSupervisor.setWindowManager(wm); 1947 } 1948 1949 public void startObservingNativeCrashes() { 1950 final NativeCrashListener ncl = new NativeCrashListener(this); 1951 ncl.start(); 1952 } 1953 1954 public IAppOpsService getAppOpsService() { 1955 return mAppOpsService; 1956 } 1957 1958 static class MemBinder extends Binder { 1959 ActivityManagerService mActivityManagerService; 1960 MemBinder(ActivityManagerService activityManagerService) { 1961 mActivityManagerService = activityManagerService; 1962 } 1963 1964 @Override 1965 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1966 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1967 != PackageManager.PERMISSION_GRANTED) { 1968 pw.println("Permission Denial: can't dump meminfo from from pid=" 1969 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1970 + " without permission " + android.Manifest.permission.DUMP); 1971 return; 1972 } 1973 1974 mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, " ", args, false, null); 1975 } 1976 } 1977 1978 static class GraphicsBinder extends Binder { 1979 ActivityManagerService mActivityManagerService; 1980 GraphicsBinder(ActivityManagerService activityManagerService) { 1981 mActivityManagerService = activityManagerService; 1982 } 1983 1984 @Override 1985 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1986 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1987 != PackageManager.PERMISSION_GRANTED) { 1988 pw.println("Permission Denial: can't dump gfxinfo from from pid=" 1989 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1990 + " without permission " + android.Manifest.permission.DUMP); 1991 return; 1992 } 1993 1994 mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args); 1995 } 1996 } 1997 1998 static class DbBinder extends Binder { 1999 ActivityManagerService mActivityManagerService; 2000 DbBinder(ActivityManagerService activityManagerService) { 2001 mActivityManagerService = activityManagerService; 2002 } 2003 2004 @Override 2005 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 2006 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 2007 != PackageManager.PERMISSION_GRANTED) { 2008 pw.println("Permission Denial: can't dump dbinfo from from pid=" 2009 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 2010 + " without permission " + android.Manifest.permission.DUMP); 2011 return; 2012 } 2013 2014 mActivityManagerService.dumpDbInfo(fd, pw, args); 2015 } 2016 } 2017 2018 static class CpuBinder extends Binder { 2019 ActivityManagerService mActivityManagerService; 2020 CpuBinder(ActivityManagerService activityManagerService) { 2021 mActivityManagerService = activityManagerService; 2022 } 2023 2024 @Override 2025 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 2026 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 2027 != PackageManager.PERMISSION_GRANTED) { 2028 pw.println("Permission Denial: can't dump cpuinfo from from pid=" 2029 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 2030 + " without permission " + android.Manifest.permission.DUMP); 2031 return; 2032 } 2033 2034 synchronized (mActivityManagerService.mProcessCpuThread) { 2035 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad()); 2036 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState( 2037 SystemClock.uptimeMillis())); 2038 } 2039 } 2040 } 2041 2042 public static final class Lifecycle extends SystemService { 2043 private final ActivityManagerService mService; 2044 2045 public Lifecycle(Context context) { 2046 super(context); 2047 mService = new ActivityManagerService(context); 2048 } 2049 2050 @Override 2051 public void onStart() { 2052 mService.start(); 2053 } 2054 2055 public ActivityManagerService getService() { 2056 return mService; 2057 } 2058 } 2059 2060 // Note: This method is invoked on the main thread but may need to attach various 2061 // handlers to other threads. So take care to be explicit about the looper. 2062 public ActivityManagerService(Context systemContext) { 2063 mContext = systemContext; 2064 mFactoryTest = FactoryTest.getMode(); 2065 mSystemThread = ActivityThread.currentActivityThread(); 2066 2067 Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass()); 2068 2069 mHandlerThread = new ServiceThread(TAG, 2070 android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/); 2071 mHandlerThread.start(); 2072 mHandler = new MainHandler(mHandlerThread.getLooper()); 2073 2074 mFgBroadcastQueue = new BroadcastQueue(this, mHandler, 2075 "foreground", BROADCAST_FG_TIMEOUT, false); 2076 mBgBroadcastQueue = new BroadcastQueue(this, mHandler, 2077 "background", BROADCAST_BG_TIMEOUT, true); 2078 mBroadcastQueues[0] = mFgBroadcastQueue; 2079 mBroadcastQueues[1] = mBgBroadcastQueue; 2080 2081 mServices = new ActiveServices(this); 2082 mProviderMap = new ProviderMap(this); 2083 2084 // TODO: Move creation of battery stats service outside of activity manager service. 2085 File dataDir = Environment.getDataDirectory(); 2086 File systemDir = new File(dataDir, "system"); 2087 systemDir.mkdirs(); 2088 mBatteryStatsService = new BatteryStatsService(new File( 2089 systemDir, "batterystats.bin").toString(), mHandler); 2090 mBatteryStatsService.getActiveStatistics().readLocked(); 2091 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 2092 mOnBattery = DEBUG_POWER ? true 2093 : mBatteryStatsService.getActiveStatistics().getIsOnBattery(); 2094 mBatteryStatsService.getActiveStatistics().setCallback(this); 2095 2096 mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats")); 2097 2098 mUsageStatsService = new UsageStatsService(new File(systemDir, "usagestats").toString()); 2099 mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler); 2100 2101 mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml")); 2102 2103 // User 0 is the first and only user that runs at boot. 2104 mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true)); 2105 mUserLru.add(Integer.valueOf(0)); 2106 updateStartedUserArrayLocked(); 2107 2108 GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version", 2109 ConfigurationInfo.GL_ES_VERSION_UNDEFINED); 2110 2111 mConfiguration.setToDefaults(); 2112 mConfiguration.setLocale(Locale.getDefault()); 2113 2114 mConfigurationSeq = mConfiguration.seq = 1; 2115 mProcessCpuTracker.init(); 2116 2117 mCompatModePackages = new CompatModePackages(this, systemDir, mHandler); 2118 mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler); 2119 mStackSupervisor = new ActivityStackSupervisor(this); 2120 2121 mProcessCpuThread = new Thread("CpuTracker") { 2122 @Override 2123 public void run() { 2124 while (true) { 2125 try { 2126 try { 2127 synchronized(this) { 2128 final long now = SystemClock.uptimeMillis(); 2129 long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now; 2130 long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now; 2131 //Slog.i(TAG, "Cpu delay=" + nextCpuDelay 2132 // + ", write delay=" + nextWriteDelay); 2133 if (nextWriteDelay < nextCpuDelay) { 2134 nextCpuDelay = nextWriteDelay; 2135 } 2136 if (nextCpuDelay > 0) { 2137 mProcessCpuMutexFree.set(true); 2138 this.wait(nextCpuDelay); 2139 } 2140 } 2141 } catch (InterruptedException e) { 2142 } 2143 updateCpuStatsNow(); 2144 } catch (Exception e) { 2145 Slog.e(TAG, "Unexpected exception collecting process stats", e); 2146 } 2147 } 2148 } 2149 }; 2150 2151 Watchdog.getInstance().addMonitor(this); 2152 Watchdog.getInstance().addThread(mHandler); 2153 } 2154 2155 public void setSystemServiceManager(SystemServiceManager mgr) { 2156 mSystemServiceManager = mgr; 2157 } 2158 2159 private void start() { 2160 mProcessCpuThread.start(); 2161 2162 mBatteryStatsService.publish(mContext); 2163 mUsageStatsService.publish(mContext); 2164 mAppOpsService.publish(mContext); 2165 2166 LocalServices.addService(ActivityManagerInternal.class, new LocalService()); 2167 } 2168 2169 @Override 2170 public boolean onTransact(int code, Parcel data, Parcel reply, int flags) 2171 throws RemoteException { 2172 if (code == SYSPROPS_TRANSACTION) { 2173 // We need to tell all apps about the system property change. 2174 ArrayList<IBinder> procs = new ArrayList<IBinder>(); 2175 synchronized(this) { 2176 final int NP = mProcessNames.getMap().size(); 2177 for (int ip=0; ip<NP; ip++) { 2178 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 2179 final int NA = apps.size(); 2180 for (int ia=0; ia<NA; ia++) { 2181 ProcessRecord app = apps.valueAt(ia); 2182 if (app.thread != null) { 2183 procs.add(app.thread.asBinder()); 2184 } 2185 } 2186 } 2187 } 2188 2189 int N = procs.size(); 2190 for (int i=0; i<N; i++) { 2191 Parcel data2 = Parcel.obtain(); 2192 try { 2193 procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0); 2194 } catch (RemoteException e) { 2195 } 2196 data2.recycle(); 2197 } 2198 } 2199 try { 2200 return super.onTransact(code, data, reply, flags); 2201 } catch (RuntimeException e) { 2202 // The activity manager only throws security exceptions, so let's 2203 // log all others. 2204 if (!(e instanceof SecurityException)) { 2205 Slog.wtf(TAG, "Activity Manager Crash", e); 2206 } 2207 throw e; 2208 } 2209 } 2210 2211 void updateCpuStats() { 2212 final long now = SystemClock.uptimeMillis(); 2213 if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) { 2214 return; 2215 } 2216 if (mProcessCpuMutexFree.compareAndSet(true, false)) { 2217 synchronized (mProcessCpuThread) { 2218 mProcessCpuThread.notify(); 2219 } 2220 } 2221 } 2222 2223 void updateCpuStatsNow() { 2224 synchronized (mProcessCpuThread) { 2225 mProcessCpuMutexFree.set(false); 2226 final long now = SystemClock.uptimeMillis(); 2227 boolean haveNewCpuStats = false; 2228 2229 if (MONITOR_CPU_USAGE && 2230 mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) { 2231 mLastCpuTime.set(now); 2232 haveNewCpuStats = true; 2233 mProcessCpuTracker.update(); 2234 //Slog.i(TAG, mProcessCpu.printCurrentState()); 2235 //Slog.i(TAG, "Total CPU usage: " 2236 // + mProcessCpu.getTotalCpuPercent() + "%"); 2237 2238 // Slog the cpu usage if the property is set. 2239 if ("true".equals(SystemProperties.get("events.cpu"))) { 2240 int user = mProcessCpuTracker.getLastUserTime(); 2241 int system = mProcessCpuTracker.getLastSystemTime(); 2242 int iowait = mProcessCpuTracker.getLastIoWaitTime(); 2243 int irq = mProcessCpuTracker.getLastIrqTime(); 2244 int softIrq = mProcessCpuTracker.getLastSoftIrqTime(); 2245 int idle = mProcessCpuTracker.getLastIdleTime(); 2246 2247 int total = user + system + iowait + irq + softIrq + idle; 2248 if (total == 0) total = 1; 2249 2250 EventLog.writeEvent(EventLogTags.CPU, 2251 ((user+system+iowait+irq+softIrq) * 100) / total, 2252 (user * 100) / total, 2253 (system * 100) / total, 2254 (iowait * 100) / total, 2255 (irq * 100) / total, 2256 (softIrq * 100) / total); 2257 } 2258 } 2259 2260 long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes(); 2261 final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics(); 2262 synchronized(bstats) { 2263 synchronized(mPidsSelfLocked) { 2264 if (haveNewCpuStats) { 2265 if (mOnBattery) { 2266 int perc = bstats.startAddingCpuLocked(); 2267 int totalUTime = 0; 2268 int totalSTime = 0; 2269 final int N = mProcessCpuTracker.countStats(); 2270 for (int i=0; i<N; i++) { 2271 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 2272 if (!st.working) { 2273 continue; 2274 } 2275 ProcessRecord pr = mPidsSelfLocked.get(st.pid); 2276 int otherUTime = (st.rel_utime*perc)/100; 2277 int otherSTime = (st.rel_stime*perc)/100; 2278 totalUTime += otherUTime; 2279 totalSTime += otherSTime; 2280 if (pr != null) { 2281 BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats; 2282 if (ps == null || !ps.isActive()) { 2283 pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked( 2284 pr.info.uid, pr.processName); 2285 } 2286 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 2287 st.rel_stime-otherSTime); 2288 ps.addSpeedStepTimes(cpuSpeedTimes); 2289 pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10; 2290 } else { 2291 BatteryStatsImpl.Uid.Proc ps = st.batteryStats; 2292 if (ps == null || !ps.isActive()) { 2293 st.batteryStats = ps = bstats.getProcessStatsLocked( 2294 bstats.mapUid(st.uid), st.name); 2295 } 2296 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 2297 st.rel_stime-otherSTime); 2298 ps.addSpeedStepTimes(cpuSpeedTimes); 2299 } 2300 } 2301 bstats.finishAddingCpuLocked(perc, totalUTime, 2302 totalSTime, cpuSpeedTimes); 2303 } 2304 } 2305 } 2306 2307 if (mLastWriteTime < (now-BATTERY_STATS_TIME)) { 2308 mLastWriteTime = now; 2309 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 2310 } 2311 } 2312 } 2313 } 2314 2315 @Override 2316 public void batteryNeedsCpuUpdate() { 2317 updateCpuStatsNow(); 2318 } 2319 2320 @Override 2321 public void batteryPowerChanged(boolean onBattery) { 2322 // When plugging in, update the CPU stats first before changing 2323 // the plug state. 2324 updateCpuStatsNow(); 2325 synchronized (this) { 2326 synchronized(mPidsSelfLocked) { 2327 mOnBattery = DEBUG_POWER ? true : onBattery; 2328 } 2329 } 2330 } 2331 2332 /** 2333 * Initialize the application bind args. These are passed to each 2334 * process when the bindApplication() IPC is sent to the process. They're 2335 * lazily setup to make sure the services are running when they're asked for. 2336 */ 2337 private HashMap<String, IBinder> getCommonServicesLocked() { 2338 if (mAppBindArgs == null) { 2339 mAppBindArgs = new HashMap<String, IBinder>(); 2340 2341 // Setup the application init args 2342 mAppBindArgs.put("package", ServiceManager.getService("package")); 2343 mAppBindArgs.put("window", ServiceManager.getService("window")); 2344 mAppBindArgs.put(Context.ALARM_SERVICE, 2345 ServiceManager.getService(Context.ALARM_SERVICE)); 2346 } 2347 return mAppBindArgs; 2348 } 2349 2350 final void setFocusedActivityLocked(ActivityRecord r) { 2351 if (mFocusedActivity != r) { 2352 if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r); 2353 mFocusedActivity = r; 2354 if (r.task != null && r.task.voiceInteractor != null) { 2355 startRunningVoiceLocked(); 2356 } else { 2357 finishRunningVoiceLocked(); 2358 } 2359 mStackSupervisor.setFocusedStack(r); 2360 if (r != null) { 2361 mWindowManager.setFocusedApp(r.appToken, true); 2362 } 2363 applyUpdateLockStateLocked(r); 2364 } 2365 } 2366 2367 final void clearFocusedActivity(ActivityRecord r) { 2368 if (mFocusedActivity == r) { 2369 mFocusedActivity = null; 2370 } 2371 } 2372 2373 @Override 2374 public void setFocusedStack(int stackId) { 2375 if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId); 2376 synchronized (ActivityManagerService.this) { 2377 ActivityStack stack = mStackSupervisor.getStack(stackId); 2378 if (stack != null) { 2379 ActivityRecord r = stack.topRunningActivityLocked(null); 2380 if (r != null) { 2381 setFocusedActivityLocked(r); 2382 } 2383 } 2384 } 2385 } 2386 2387 @Override 2388 public void notifyActivityDrawn(IBinder token) { 2389 if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token); 2390 synchronized (this) { 2391 ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token); 2392 if (r != null) { 2393 r.task.stack.notifyActivityDrawnLocked(r); 2394 } 2395 } 2396 } 2397 2398 final void applyUpdateLockStateLocked(ActivityRecord r) { 2399 // Modifications to the UpdateLock state are done on our handler, outside 2400 // the activity manager's locks. The new state is determined based on the 2401 // state *now* of the relevant activity record. The object is passed to 2402 // the handler solely for logging detail, not to be consulted/modified. 2403 final boolean nextState = r != null && r.immersive; 2404 mHandler.sendMessage( 2405 mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r)); 2406 } 2407 2408 final void showAskCompatModeDialogLocked(ActivityRecord r) { 2409 Message msg = Message.obtain(); 2410 msg.what = SHOW_COMPAT_MODE_DIALOG_MSG; 2411 msg.obj = r.task.askedCompatMode ? null : r; 2412 mHandler.sendMessage(msg); 2413 } 2414 2415 private final int updateLruProcessInternalLocked(ProcessRecord app, long now, int index, 2416 String what, Object obj, ProcessRecord srcApp) { 2417 app.lastActivityTime = now; 2418 2419 if (app.activities.size() > 0) { 2420 // Don't want to touch dependent processes that are hosting activities. 2421 return index; 2422 } 2423 2424 int lrui = mLruProcesses.lastIndexOf(app); 2425 if (lrui < 0) { 2426 Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: " 2427 + what + " " + obj + " from " + srcApp); 2428 return index; 2429 } 2430 2431 if (lrui >= index) { 2432 // Don't want to cause this to move dependent processes *back* in the 2433 // list as if they were less frequently used. 2434 return index; 2435 } 2436 2437 if (lrui >= mLruProcessActivityStart) { 2438 // Don't want to touch dependent processes that are hosting activities. 2439 return index; 2440 } 2441 2442 mLruProcesses.remove(lrui); 2443 if (index > 0) { 2444 index--; 2445 } 2446 if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index 2447 + " in LRU list: " + app); 2448 mLruProcesses.add(index, app); 2449 return index; 2450 } 2451 2452 final void removeLruProcessLocked(ProcessRecord app) { 2453 int lrui = mLruProcesses.lastIndexOf(app); 2454 if (lrui >= 0) { 2455 if (lrui <= mLruProcessActivityStart) { 2456 mLruProcessActivityStart--; 2457 } 2458 if (lrui <= mLruProcessServiceStart) { 2459 mLruProcessServiceStart--; 2460 } 2461 mLruProcesses.remove(lrui); 2462 } 2463 } 2464 2465 final void updateLruProcessLocked(ProcessRecord app, boolean activityChange, 2466 ProcessRecord client) { 2467 final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities 2468 || app.treatLikeActivity; 2469 final boolean hasService = false; // not impl yet. app.services.size() > 0; 2470 if (!activityChange && hasActivity) { 2471 // The process has activities, so we are only allowing activity-based adjustments 2472 // to move it. It should be kept in the front of the list with other 2473 // processes that have activities, and we don't want those to change their 2474 // order except due to activity operations. 2475 return; 2476 } 2477 2478 mLruSeq++; 2479 final long now = SystemClock.uptimeMillis(); 2480 app.lastActivityTime = now; 2481 2482 // First a quick reject: if the app is already at the position we will 2483 // put it, then there is nothing to do. 2484 if (hasActivity) { 2485 final int N = mLruProcesses.size(); 2486 if (N > 0 && mLruProcesses.get(N-1) == app) { 2487 if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app); 2488 return; 2489 } 2490 } else { 2491 if (mLruProcessServiceStart > 0 2492 && mLruProcesses.get(mLruProcessServiceStart-1) == app) { 2493 if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app); 2494 return; 2495 } 2496 } 2497 2498 int lrui = mLruProcesses.lastIndexOf(app); 2499 2500 if (app.persistent && lrui >= 0) { 2501 // We don't care about the position of persistent processes, as long as 2502 // they are in the list. 2503 if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app); 2504 return; 2505 } 2506 2507 /* In progress: compute new position first, so we can avoid doing work 2508 if the process is not actually going to move. Not yet working. 2509 int addIndex; 2510 int nextIndex; 2511 boolean inActivity = false, inService = false; 2512 if (hasActivity) { 2513 // Process has activities, put it at the very tipsy-top. 2514 addIndex = mLruProcesses.size(); 2515 nextIndex = mLruProcessServiceStart; 2516 inActivity = true; 2517 } else if (hasService) { 2518 // Process has services, put it at the top of the service list. 2519 addIndex = mLruProcessActivityStart; 2520 nextIndex = mLruProcessServiceStart; 2521 inActivity = true; 2522 inService = true; 2523 } else { 2524 // Process not otherwise of interest, it goes to the top of the non-service area. 2525 addIndex = mLruProcessServiceStart; 2526 if (client != null) { 2527 int clientIndex = mLruProcesses.lastIndexOf(client); 2528 if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating " 2529 + app); 2530 if (clientIndex >= 0 && addIndex > clientIndex) { 2531 addIndex = clientIndex; 2532 } 2533 } 2534 nextIndex = addIndex > 0 ? addIndex-1 : addIndex; 2535 } 2536 2537 Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act=" 2538 + mLruProcessActivityStart + "): " + app); 2539 */ 2540 2541 if (lrui >= 0) { 2542 if (lrui < mLruProcessActivityStart) { 2543 mLruProcessActivityStart--; 2544 } 2545 if (lrui < mLruProcessServiceStart) { 2546 mLruProcessServiceStart--; 2547 } 2548 /* 2549 if (addIndex > lrui) { 2550 addIndex--; 2551 } 2552 if (nextIndex > lrui) { 2553 nextIndex--; 2554 } 2555 */ 2556 mLruProcesses.remove(lrui); 2557 } 2558 2559 /* 2560 mLruProcesses.add(addIndex, app); 2561 if (inActivity) { 2562 mLruProcessActivityStart++; 2563 } 2564 if (inService) { 2565 mLruProcessActivityStart++; 2566 } 2567 */ 2568 2569 int nextIndex; 2570 if (hasActivity) { 2571 final int N = mLruProcesses.size(); 2572 if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) { 2573 // Process doesn't have activities, but has clients with 2574 // activities... move it up, but one below the top (the top 2575 // should always have a real activity). 2576 if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app); 2577 mLruProcesses.add(N-1, app); 2578 // To keep it from spamming the LRU list (by making a bunch of clients), 2579 // we will push down any other entries owned by the app. 2580 final int uid = app.info.uid; 2581 for (int i=N-2; i>mLruProcessActivityStart; i--) { 2582 ProcessRecord subProc = mLruProcesses.get(i); 2583 if (subProc.info.uid == uid) { 2584 // We want to push this one down the list. If the process after 2585 // it is for the same uid, however, don't do so, because we don't 2586 // want them internally to be re-ordered. 2587 if (mLruProcesses.get(i-1).info.uid != uid) { 2588 if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i 2589 + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1)); 2590 ProcessRecord tmp = mLruProcesses.get(i); 2591 mLruProcesses.set(i, mLruProcesses.get(i-1)); 2592 mLruProcesses.set(i-1, tmp); 2593 i--; 2594 } 2595 } else { 2596 // A gap, we can stop here. 2597 break; 2598 } 2599 } 2600 } else { 2601 // Process has activities, put it at the very tipsy-top. 2602 if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app); 2603 mLruProcesses.add(app); 2604 } 2605 nextIndex = mLruProcessServiceStart; 2606 } else if (hasService) { 2607 // Process has services, put it at the top of the service list. 2608 if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app); 2609 mLruProcesses.add(mLruProcessActivityStart, app); 2610 nextIndex = mLruProcessServiceStart; 2611 mLruProcessActivityStart++; 2612 } else { 2613 // Process not otherwise of interest, it goes to the top of the non-service area. 2614 int index = mLruProcessServiceStart; 2615 if (client != null) { 2616 // If there is a client, don't allow the process to be moved up higher 2617 // in the list than that client. 2618 int clientIndex = mLruProcesses.lastIndexOf(client); 2619 if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client 2620 + " when updating " + app); 2621 if (clientIndex <= lrui) { 2622 // Don't allow the client index restriction to push it down farther in the 2623 // list than it already is. 2624 clientIndex = lrui; 2625 } 2626 if (clientIndex >= 0 && index > clientIndex) { 2627 index = clientIndex; 2628 } 2629 } 2630 if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app); 2631 mLruProcesses.add(index, app); 2632 nextIndex = index-1; 2633 mLruProcessActivityStart++; 2634 mLruProcessServiceStart++; 2635 } 2636 2637 // If the app is currently using a content provider or service, 2638 // bump those processes as well. 2639 for (int j=app.connections.size()-1; j>=0; j--) { 2640 ConnectionRecord cr = app.connections.valueAt(j); 2641 if (cr.binding != null && !cr.serviceDead && cr.binding.service != null 2642 && cr.binding.service.app != null 2643 && cr.binding.service.app.lruSeq != mLruSeq 2644 && !cr.binding.service.app.persistent) { 2645 nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex, 2646 "service connection", cr, app); 2647 } 2648 } 2649 for (int j=app.conProviders.size()-1; j>=0; j--) { 2650 ContentProviderRecord cpr = app.conProviders.get(j).provider; 2651 if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) { 2652 nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex, 2653 "provider reference", cpr, app); 2654 } 2655 } 2656 } 2657 2658 final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) { 2659 if (uid == Process.SYSTEM_UID) { 2660 // The system gets to run in any process. If there are multiple 2661 // processes with the same uid, just pick the first (this 2662 // should never happen). 2663 SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName); 2664 if (procs == null) return null; 2665 final int N = procs.size(); 2666 for (int i = 0; i < N; i++) { 2667 if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i); 2668 } 2669 } 2670 ProcessRecord proc = mProcessNames.get(processName, uid); 2671 if (false && proc != null && !keepIfLarge 2672 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY 2673 && proc.lastCachedPss >= 4000) { 2674 // Turn this condition on to cause killing to happen regularly, for testing. 2675 if (proc.baseProcessTracker != null) { 2676 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss); 2677 } 2678 killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss) 2679 + "k from cached"); 2680 } else if (proc != null && !keepIfLarge 2681 && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL 2682 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) { 2683 if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss); 2684 if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) { 2685 if (proc.baseProcessTracker != null) { 2686 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss); 2687 } 2688 killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss) 2689 + "k from cached"); 2690 } 2691 } 2692 return proc; 2693 } 2694 2695 void ensurePackageDexOpt(String packageName) { 2696 IPackageManager pm = AppGlobals.getPackageManager(); 2697 try { 2698 if (pm.performDexOpt(packageName)) { 2699 mDidDexOpt = true; 2700 } 2701 } catch (RemoteException e) { 2702 } 2703 } 2704 2705 boolean isNextTransitionForward() { 2706 int transit = mWindowManager.getPendingAppTransition(); 2707 return transit == AppTransition.TRANSIT_ACTIVITY_OPEN 2708 || transit == AppTransition.TRANSIT_TASK_OPEN 2709 || transit == AppTransition.TRANSIT_TASK_TO_FRONT; 2710 } 2711 2712 final ProcessRecord startProcessLocked(String processName, 2713 ApplicationInfo info, boolean knownToBeDead, int intentFlags, 2714 String hostingType, ComponentName hostingName, boolean allowWhileBooting, 2715 boolean isolated, boolean keepIfLarge) { 2716 ProcessRecord app; 2717 if (!isolated) { 2718 app = getProcessRecordLocked(processName, info.uid, keepIfLarge); 2719 } else { 2720 // If this is an isolated process, it can't re-use an existing process. 2721 app = null; 2722 } 2723 // We don't have to do anything more if: 2724 // (1) There is an existing application record; and 2725 // (2) The caller doesn't think it is dead, OR there is no thread 2726 // object attached to it so we know it couldn't have crashed; and 2727 // (3) There is a pid assigned to it, so it is either starting or 2728 // already running. 2729 if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName 2730 + " app=" + app + " knownToBeDead=" + knownToBeDead 2731 + " thread=" + (app != null ? app.thread : null) 2732 + " pid=" + (app != null ? app.pid : -1)); 2733 if (app != null && app.pid > 0) { 2734 if (!knownToBeDead || app.thread == null) { 2735 // We already have the app running, or are waiting for it to 2736 // come up (we have a pid but not yet its thread), so keep it. 2737 if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app); 2738 // If this is a new package in the process, add the package to the list 2739 app.addPackage(info.packageName, mProcessStats); 2740 return app; 2741 } 2742 2743 // An application record is attached to a previous process, 2744 // clean it up now. 2745 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app); 2746 handleAppDiedLocked(app, true, true); 2747 } 2748 2749 String hostingNameStr = hostingName != null 2750 ? hostingName.flattenToShortString() : null; 2751 2752 if (!isolated) { 2753 if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) { 2754 // If we are in the background, then check to see if this process 2755 // is bad. If so, we will just silently fail. 2756 if (mBadProcesses.get(info.processName, info.uid) != null) { 2757 if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid 2758 + "/" + info.processName); 2759 return null; 2760 } 2761 } else { 2762 // When the user is explicitly starting a process, then clear its 2763 // crash count so that we won't make it bad until they see at 2764 // least one crash dialog again, and make the process good again 2765 // if it had been bad. 2766 if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid 2767 + "/" + info.processName); 2768 mProcessCrashTimes.remove(info.processName, info.uid); 2769 if (mBadProcesses.get(info.processName, info.uid) != null) { 2770 EventLog.writeEvent(EventLogTags.AM_PROC_GOOD, 2771 UserHandle.getUserId(info.uid), info.uid, 2772 info.processName); 2773 mBadProcesses.remove(info.processName, info.uid); 2774 if (app != null) { 2775 app.bad = false; 2776 } 2777 } 2778 } 2779 } 2780 2781 if (app == null) { 2782 app = newProcessRecordLocked(info, processName, isolated); 2783 if (app == null) { 2784 Slog.w(TAG, "Failed making new process record for " 2785 + processName + "/" + info.uid + " isolated=" + isolated); 2786 return null; 2787 } 2788 mProcessNames.put(processName, app.uid, app); 2789 if (isolated) { 2790 mIsolatedProcesses.put(app.uid, app); 2791 } 2792 } else { 2793 // If this is a new package in the process, add the package to the list 2794 app.addPackage(info.packageName, mProcessStats); 2795 } 2796 2797 // If the system is not ready yet, then hold off on starting this 2798 // process until it is. 2799 if (!mProcessesReady 2800 && !isAllowedWhileBooting(info) 2801 && !allowWhileBooting) { 2802 if (!mProcessesOnHold.contains(app)) { 2803 mProcessesOnHold.add(app); 2804 } 2805 if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app); 2806 return app; 2807 } 2808 2809 startProcessLocked(app, hostingType, hostingNameStr); 2810 return (app.pid != 0) ? app : null; 2811 } 2812 2813 boolean isAllowedWhileBooting(ApplicationInfo ai) { 2814 return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0; 2815 } 2816 2817 private final void startProcessLocked(ProcessRecord app, 2818 String hostingType, String hostingNameStr) { 2819 if (app.pid > 0 && app.pid != MY_PID) { 2820 synchronized (mPidsSelfLocked) { 2821 mPidsSelfLocked.remove(app.pid); 2822 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 2823 } 2824 app.setPid(0); 2825 } 2826 2827 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 2828 "startProcessLocked removing on hold: " + app); 2829 mProcessesOnHold.remove(app); 2830 2831 updateCpuStats(); 2832 2833 try { 2834 int uid = app.uid; 2835 2836 int[] gids = null; 2837 int mountExternal = Zygote.MOUNT_EXTERNAL_NONE; 2838 if (!app.isolated) { 2839 int[] permGids = null; 2840 try { 2841 final PackageManager pm = mContext.getPackageManager(); 2842 permGids = pm.getPackageGids(app.info.packageName); 2843 2844 if (Environment.isExternalStorageEmulated()) { 2845 if (pm.checkPermission( 2846 android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE, 2847 app.info.packageName) == PERMISSION_GRANTED) { 2848 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL; 2849 } else { 2850 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER; 2851 } 2852 } 2853 } catch (PackageManager.NameNotFoundException e) { 2854 Slog.w(TAG, "Unable to retrieve gids", e); 2855 } 2856 2857 /* 2858 * Add shared application GID so applications can share some 2859 * resources like shared libraries 2860 */ 2861 if (permGids == null) { 2862 gids = new int[1]; 2863 } else { 2864 gids = new int[permGids.length + 1]; 2865 System.arraycopy(permGids, 0, gids, 1, permGids.length); 2866 } 2867 gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid)); 2868 } 2869 if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) { 2870 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL 2871 && mTopComponent != null 2872 && app.processName.equals(mTopComponent.getPackageName())) { 2873 uid = 0; 2874 } 2875 if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL 2876 && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) { 2877 uid = 0; 2878 } 2879 } 2880 int debugFlags = 0; 2881 if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) { 2882 debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER; 2883 // Also turn on CheckJNI for debuggable apps. It's quite 2884 // awkward to turn on otherwise. 2885 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 2886 } 2887 // Run the app in safe mode if its manifest requests so or the 2888 // system is booted in safe mode. 2889 if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 || 2890 mSafeMode == true) { 2891 debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE; 2892 } 2893 if ("1".equals(SystemProperties.get("debug.checkjni"))) { 2894 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 2895 } 2896 if ("1".equals(SystemProperties.get("debug.jni.logging"))) { 2897 debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING; 2898 } 2899 if ("1".equals(SystemProperties.get("debug.assert"))) { 2900 debugFlags |= Zygote.DEBUG_ENABLE_ASSERT; 2901 } 2902 2903 String requiredAbi = app.info.requiredCpuAbi; 2904 if (requiredAbi == null) { 2905 requiredAbi = Build.SUPPORTED_ABIS[0]; 2906 } 2907 2908 // Start the process. It will either succeed and return a result containing 2909 // the PID of the new process, or else throw a RuntimeException. 2910 Process.ProcessStartResult startResult = Process.start("android.app.ActivityThread", 2911 app.processName, uid, uid, gids, debugFlags, mountExternal, 2912 app.info.targetSdkVersion, app.info.seinfo, requiredAbi, null); 2913 2914 BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics(); 2915 synchronized (bs) { 2916 if (bs.isOnBattery()) { 2917 bs.getProcessStatsLocked(app.uid, app.processName).incStartsLocked(); 2918 } 2919 } 2920 2921 EventLog.writeEvent(EventLogTags.AM_PROC_START, 2922 UserHandle.getUserId(uid), startResult.pid, uid, 2923 app.processName, hostingType, 2924 hostingNameStr != null ? hostingNameStr : ""); 2925 2926 if (app.persistent) { 2927 Watchdog.getInstance().processStarted(app.processName, startResult.pid); 2928 } 2929 2930 StringBuilder buf = mStringBuilder; 2931 buf.setLength(0); 2932 buf.append("Start proc "); 2933 buf.append(app.processName); 2934 buf.append(" for "); 2935 buf.append(hostingType); 2936 if (hostingNameStr != null) { 2937 buf.append(" "); 2938 buf.append(hostingNameStr); 2939 } 2940 buf.append(": pid="); 2941 buf.append(startResult.pid); 2942 buf.append(" uid="); 2943 buf.append(uid); 2944 buf.append(" gids={"); 2945 if (gids != null) { 2946 for (int gi=0; gi<gids.length; gi++) { 2947 if (gi != 0) buf.append(", "); 2948 buf.append(gids[gi]); 2949 2950 } 2951 } 2952 buf.append("}"); 2953 Slog.i(TAG, buf.toString()); 2954 app.setPid(startResult.pid); 2955 app.usingWrapper = startResult.usingWrapper; 2956 app.removed = false; 2957 synchronized (mPidsSelfLocked) { 2958 this.mPidsSelfLocked.put(startResult.pid, app); 2959 Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 2960 msg.obj = app; 2961 mHandler.sendMessageDelayed(msg, startResult.usingWrapper 2962 ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT); 2963 } 2964 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_START, 2965 app.processName, app.info.uid); 2966 if (app.isolated) { 2967 mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid); 2968 } 2969 } catch (RuntimeException e) { 2970 // XXX do better error recovery. 2971 app.setPid(0); 2972 Slog.e(TAG, "Failure starting process " + app.processName, e); 2973 } 2974 } 2975 2976 void updateUsageStats(ActivityRecord component, boolean resumed) { 2977 if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed); 2978 final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 2979 if (resumed) { 2980 mUsageStatsService.noteResumeComponent(component.realActivity); 2981 synchronized (stats) { 2982 stats.noteActivityResumedLocked(component.app.uid); 2983 } 2984 } else { 2985 mUsageStatsService.notePauseComponent(component.realActivity); 2986 synchronized (stats) { 2987 stats.noteActivityPausedLocked(component.app.uid); 2988 } 2989 } 2990 } 2991 2992 Intent getHomeIntent() { 2993 Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null); 2994 intent.setComponent(mTopComponent); 2995 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 2996 intent.addCategory(Intent.CATEGORY_HOME); 2997 } 2998 return intent; 2999 } 3000 3001 boolean startHomeActivityLocked(int userId) { 3002 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL 3003 && mTopAction == null) { 3004 // We are running in factory test mode, but unable to find 3005 // the factory test app, so just sit around displaying the 3006 // error message and don't try to start anything. 3007 return false; 3008 } 3009 Intent intent = getHomeIntent(); 3010 ActivityInfo aInfo = 3011 resolveActivityInfo(intent, STOCK_PM_FLAGS, userId); 3012 if (aInfo != null) { 3013 intent.setComponent(new ComponentName( 3014 aInfo.applicationInfo.packageName, aInfo.name)); 3015 // Don't do this if the home app is currently being 3016 // instrumented. 3017 aInfo = new ActivityInfo(aInfo); 3018 aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId); 3019 ProcessRecord app = getProcessRecordLocked(aInfo.processName, 3020 aInfo.applicationInfo.uid, true); 3021 if (app == null || app.instrumentationClass == null) { 3022 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK); 3023 mStackSupervisor.startHomeActivity(intent, aInfo); 3024 } 3025 } 3026 3027 return true; 3028 } 3029 3030 private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) { 3031 ActivityInfo ai = null; 3032 ComponentName comp = intent.getComponent(); 3033 try { 3034 if (comp != null) { 3035 ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId); 3036 } else { 3037 ResolveInfo info = AppGlobals.getPackageManager().resolveIntent( 3038 intent, 3039 intent.resolveTypeIfNeeded(mContext.getContentResolver()), 3040 flags, userId); 3041 3042 if (info != null) { 3043 ai = info.activityInfo; 3044 } 3045 } 3046 } catch (RemoteException e) { 3047 // ignore 3048 } 3049 3050 return ai; 3051 } 3052 3053 /** 3054 * Starts the "new version setup screen" if appropriate. 3055 */ 3056 void startSetupActivityLocked() { 3057 // Only do this once per boot. 3058 if (mCheckedForSetup) { 3059 return; 3060 } 3061 3062 // We will show this screen if the current one is a different 3063 // version than the last one shown, and we are not running in 3064 // low-level factory test mode. 3065 final ContentResolver resolver = mContext.getContentResolver(); 3066 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL && 3067 Settings.Global.getInt(resolver, 3068 Settings.Global.DEVICE_PROVISIONED, 0) != 0) { 3069 mCheckedForSetup = true; 3070 3071 // See if we should be showing the platform update setup UI. 3072 Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP); 3073 List<ResolveInfo> ris = mContext.getPackageManager() 3074 .queryIntentActivities(intent, PackageManager.GET_META_DATA); 3075 3076 // We don't allow third party apps to replace this. 3077 ResolveInfo ri = null; 3078 for (int i=0; ris != null && i<ris.size(); i++) { 3079 if ((ris.get(i).activityInfo.applicationInfo.flags 3080 & ApplicationInfo.FLAG_SYSTEM) != 0) { 3081 ri = ris.get(i); 3082 break; 3083 } 3084 } 3085 3086 if (ri != null) { 3087 String vers = ri.activityInfo.metaData != null 3088 ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION) 3089 : null; 3090 if (vers == null && ri.activityInfo.applicationInfo.metaData != null) { 3091 vers = ri.activityInfo.applicationInfo.metaData.getString( 3092 Intent.METADATA_SETUP_VERSION); 3093 } 3094 String lastVers = Settings.Secure.getString( 3095 resolver, Settings.Secure.LAST_SETUP_SHOWN); 3096 if (vers != null && !vers.equals(lastVers)) { 3097 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 3098 intent.setComponent(new ComponentName( 3099 ri.activityInfo.packageName, ri.activityInfo.name)); 3100 mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo, 3101 null, null, null, null, 0, 0, 0, null, 0, null, false, null, null); 3102 } 3103 } 3104 } 3105 } 3106 3107 CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) { 3108 return mCompatModePackages.compatibilityInfoForPackageLocked(ai); 3109 } 3110 3111 void enforceNotIsolatedCaller(String caller) { 3112 if (UserHandle.isIsolated(Binder.getCallingUid())) { 3113 throw new SecurityException("Isolated process not allowed to call " + caller); 3114 } 3115 } 3116 3117 @Override 3118 public int getFrontActivityScreenCompatMode() { 3119 enforceNotIsolatedCaller("getFrontActivityScreenCompatMode"); 3120 synchronized (this) { 3121 return mCompatModePackages.getFrontActivityScreenCompatModeLocked(); 3122 } 3123 } 3124 3125 @Override 3126 public void setFrontActivityScreenCompatMode(int mode) { 3127 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3128 "setFrontActivityScreenCompatMode"); 3129 synchronized (this) { 3130 mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode); 3131 } 3132 } 3133 3134 @Override 3135 public int getPackageScreenCompatMode(String packageName) { 3136 enforceNotIsolatedCaller("getPackageScreenCompatMode"); 3137 synchronized (this) { 3138 return mCompatModePackages.getPackageScreenCompatModeLocked(packageName); 3139 } 3140 } 3141 3142 @Override 3143 public void setPackageScreenCompatMode(String packageName, int mode) { 3144 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3145 "setPackageScreenCompatMode"); 3146 synchronized (this) { 3147 mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode); 3148 } 3149 } 3150 3151 @Override 3152 public boolean getPackageAskScreenCompat(String packageName) { 3153 enforceNotIsolatedCaller("getPackageAskScreenCompat"); 3154 synchronized (this) { 3155 return mCompatModePackages.getPackageAskCompatModeLocked(packageName); 3156 } 3157 } 3158 3159 @Override 3160 public void setPackageAskScreenCompat(String packageName, boolean ask) { 3161 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3162 "setPackageAskScreenCompat"); 3163 synchronized (this) { 3164 mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask); 3165 } 3166 } 3167 3168 private void dispatchProcessesChanged() { 3169 int N; 3170 synchronized (this) { 3171 N = mPendingProcessChanges.size(); 3172 if (mActiveProcessChanges.length < N) { 3173 mActiveProcessChanges = new ProcessChangeItem[N]; 3174 } 3175 mPendingProcessChanges.toArray(mActiveProcessChanges); 3176 mAvailProcessChanges.addAll(mPendingProcessChanges); 3177 mPendingProcessChanges.clear(); 3178 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes"); 3179 } 3180 3181 int i = mProcessObservers.beginBroadcast(); 3182 while (i > 0) { 3183 i--; 3184 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 3185 if (observer != null) { 3186 try { 3187 for (int j=0; j<N; j++) { 3188 ProcessChangeItem item = mActiveProcessChanges[j]; 3189 if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) { 3190 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid=" 3191 + item.pid + " uid=" + item.uid + ": " 3192 + item.foregroundActivities); 3193 observer.onForegroundActivitiesChanged(item.pid, item.uid, 3194 item.foregroundActivities); 3195 } 3196 if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) { 3197 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "PROCSTATE CHANGED pid=" 3198 + item.pid + " uid=" + item.uid + ": " + item.processState); 3199 observer.onProcessStateChanged(item.pid, item.uid, item.processState); 3200 } 3201 } 3202 } catch (RemoteException e) { 3203 } 3204 } 3205 } 3206 mProcessObservers.finishBroadcast(); 3207 } 3208 3209 private void dispatchProcessDied(int pid, int uid) { 3210 int i = mProcessObservers.beginBroadcast(); 3211 while (i > 0) { 3212 i--; 3213 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 3214 if (observer != null) { 3215 try { 3216 observer.onProcessDied(pid, uid); 3217 } catch (RemoteException e) { 3218 } 3219 } 3220 } 3221 mProcessObservers.finishBroadcast(); 3222 } 3223 3224 final void doPendingActivityLaunchesLocked(boolean doResume) { 3225 final int N = mPendingActivityLaunches.size(); 3226 if (N <= 0) { 3227 return; 3228 } 3229 for (int i=0; i<N; i++) { 3230 PendingActivityLaunch pal = mPendingActivityLaunches.get(i); 3231 mStackSupervisor.startActivityUncheckedLocked(pal.r, pal.sourceRecord, null, null, pal.startFlags, 3232 doResume && i == (N-1), null); 3233 } 3234 mPendingActivityLaunches.clear(); 3235 } 3236 3237 @Override 3238 public final int startActivity(IApplicationThread caller, String callingPackage, 3239 Intent intent, String resolvedType, IBinder resultTo, 3240 String resultWho, int requestCode, int startFlags, 3241 String profileFile, ParcelFileDescriptor profileFd, Bundle options) { 3242 return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo, 3243 resultWho, requestCode, 3244 startFlags, profileFile, profileFd, options, UserHandle.getCallingUserId()); 3245 } 3246 3247 @Override 3248 public final int startActivityAsUser(IApplicationThread caller, String callingPackage, 3249 Intent intent, String resolvedType, IBinder resultTo, 3250 String resultWho, int requestCode, int startFlags, 3251 String profileFile, ParcelFileDescriptor profileFd, Bundle options, int userId) { 3252 enforceNotIsolatedCaller("startActivity"); 3253 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3254 false, true, "startActivity", null); 3255 // TODO: Switch to user app stacks here. 3256 return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType, 3257 null, null, resultTo, resultWho, requestCode, startFlags, profileFile, profileFd, 3258 null, null, options, userId, null); 3259 } 3260 3261 @Override 3262 public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage, 3263 Intent intent, String resolvedType, IBinder resultTo, 3264 String resultWho, int requestCode, int startFlags, String profileFile, 3265 ParcelFileDescriptor profileFd, Bundle options, int userId) { 3266 enforceNotIsolatedCaller("startActivityAndWait"); 3267 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3268 false, true, "startActivityAndWait", null); 3269 WaitResult res = new WaitResult(); 3270 // TODO: Switch to user app stacks here. 3271 mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType, 3272 null, null, resultTo, resultWho, requestCode, startFlags, profileFile, profileFd, 3273 res, null, options, UserHandle.getCallingUserId(), null); 3274 return res; 3275 } 3276 3277 @Override 3278 public final int startActivityWithConfig(IApplicationThread caller, String callingPackage, 3279 Intent intent, String resolvedType, IBinder resultTo, 3280 String resultWho, int requestCode, int startFlags, Configuration config, 3281 Bundle options, int userId) { 3282 enforceNotIsolatedCaller("startActivityWithConfig"); 3283 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3284 false, true, "startActivityWithConfig", null); 3285 // TODO: Switch to user app stacks here. 3286 int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, 3287 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, 3288 null, null, null, config, options, userId, null); 3289 return ret; 3290 } 3291 3292 @Override 3293 public int startActivityIntentSender(IApplicationThread caller, 3294 IntentSender intent, Intent fillInIntent, String resolvedType, 3295 IBinder resultTo, String resultWho, int requestCode, 3296 int flagsMask, int flagsValues, Bundle options) { 3297 enforceNotIsolatedCaller("startActivityIntentSender"); 3298 // Refuse possible leaked file descriptors 3299 if (fillInIntent != null && fillInIntent.hasFileDescriptors()) { 3300 throw new IllegalArgumentException("File descriptors passed in Intent"); 3301 } 3302 3303 IIntentSender sender = intent.getTarget(); 3304 if (!(sender instanceof PendingIntentRecord)) { 3305 throw new IllegalArgumentException("Bad PendingIntent object"); 3306 } 3307 3308 PendingIntentRecord pir = (PendingIntentRecord)sender; 3309 3310 synchronized (this) { 3311 // If this is coming from the currently resumed activity, it is 3312 // effectively saying that app switches are allowed at this point. 3313 final ActivityStack stack = getFocusedStack(); 3314 if (stack.mResumedActivity != null && 3315 stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) { 3316 mAppSwitchesAllowedTime = 0; 3317 } 3318 } 3319 int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null, 3320 resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null); 3321 return ret; 3322 } 3323 3324 @Override 3325 public int startVoiceActivity(String callingPackage, int callingPid, int callingUid, 3326 Intent intent, String resolvedType, IVoiceInteractionSession session, 3327 IVoiceInteractor interactor, int startFlags, String profileFile, 3328 ParcelFileDescriptor profileFd, Bundle options, int userId) { 3329 if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION) 3330 != PackageManager.PERMISSION_GRANTED) { 3331 String msg = "Permission Denial: startVoiceActivity() from pid=" 3332 + Binder.getCallingPid() 3333 + ", uid=" + Binder.getCallingUid() 3334 + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION; 3335 Slog.w(TAG, msg); 3336 throw new SecurityException(msg); 3337 } 3338 if (session == null || interactor == null) { 3339 throw new NullPointerException("null session or interactor"); 3340 } 3341 userId = handleIncomingUser(callingPid, callingUid, userId, 3342 false, true, "startVoiceActivity", null); 3343 // TODO: Switch to user app stacks here. 3344 return mStackSupervisor.startActivityMayWait(null, callingUid, callingPackage, intent, 3345 resolvedType, session, interactor, null, null, 0, startFlags, 3346 profileFile, profileFd, null, null, options, userId, null); 3347 } 3348 3349 @Override 3350 public boolean startNextMatchingActivity(IBinder callingActivity, 3351 Intent intent, Bundle options) { 3352 // Refuse possible leaked file descriptors 3353 if (intent != null && intent.hasFileDescriptors() == true) { 3354 throw new IllegalArgumentException("File descriptors passed in Intent"); 3355 } 3356 3357 synchronized (this) { 3358 final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity); 3359 if (r == null) { 3360 ActivityOptions.abort(options); 3361 return false; 3362 } 3363 if (r.app == null || r.app.thread == null) { 3364 // The caller is not running... d'oh! 3365 ActivityOptions.abort(options); 3366 return false; 3367 } 3368 intent = new Intent(intent); 3369 // The caller is not allowed to change the data. 3370 intent.setDataAndType(r.intent.getData(), r.intent.getType()); 3371 // And we are resetting to find the next component... 3372 intent.setComponent(null); 3373 3374 final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0); 3375 3376 ActivityInfo aInfo = null; 3377 try { 3378 List<ResolveInfo> resolves = 3379 AppGlobals.getPackageManager().queryIntentActivities( 3380 intent, r.resolvedType, 3381 PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS, 3382 UserHandle.getCallingUserId()); 3383 3384 // Look for the original activity in the list... 3385 final int N = resolves != null ? resolves.size() : 0; 3386 for (int i=0; i<N; i++) { 3387 ResolveInfo rInfo = resolves.get(i); 3388 if (rInfo.activityInfo.packageName.equals(r.packageName) 3389 && rInfo.activityInfo.name.equals(r.info.name)) { 3390 // We found the current one... the next matching is 3391 // after it. 3392 i++; 3393 if (i<N) { 3394 aInfo = resolves.get(i).activityInfo; 3395 } 3396 if (debug) { 3397 Slog.v(TAG, "Next matching activity: found current " + r.packageName 3398 + "/" + r.info.name); 3399 Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName 3400 + "/" + aInfo.name); 3401 } 3402 break; 3403 } 3404 } 3405 } catch (RemoteException e) { 3406 } 3407 3408 if (aInfo == null) { 3409 // Nobody who is next! 3410 ActivityOptions.abort(options); 3411 if (debug) Slog.d(TAG, "Next matching activity: nothing found"); 3412 return false; 3413 } 3414 3415 intent.setComponent(new ComponentName( 3416 aInfo.applicationInfo.packageName, aInfo.name)); 3417 intent.setFlags(intent.getFlags()&~( 3418 Intent.FLAG_ACTIVITY_FORWARD_RESULT| 3419 Intent.FLAG_ACTIVITY_CLEAR_TOP| 3420 Intent.FLAG_ACTIVITY_MULTIPLE_TASK| 3421 Intent.FLAG_ACTIVITY_NEW_TASK)); 3422 3423 // Okay now we need to start the new activity, replacing the 3424 // currently running activity. This is a little tricky because 3425 // we want to start the new one as if the current one is finished, 3426 // but not finish the current one first so that there is no flicker. 3427 // And thus... 3428 final boolean wasFinishing = r.finishing; 3429 r.finishing = true; 3430 3431 // Propagate reply information over to the new activity. 3432 final ActivityRecord resultTo = r.resultTo; 3433 final String resultWho = r.resultWho; 3434 final int requestCode = r.requestCode; 3435 r.resultTo = null; 3436 if (resultTo != null) { 3437 resultTo.removeResultsLocked(r, resultWho, requestCode); 3438 } 3439 3440 final long origId = Binder.clearCallingIdentity(); 3441 int res = mStackSupervisor.startActivityLocked(r.app.thread, intent, 3442 r.resolvedType, aInfo, null, null, resultTo != null ? resultTo.appToken : null, 3443 resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage, 0, 3444 options, false, null, null); 3445 Binder.restoreCallingIdentity(origId); 3446 3447 r.finishing = wasFinishing; 3448 if (res != ActivityManager.START_SUCCESS) { 3449 return false; 3450 } 3451 return true; 3452 } 3453 } 3454 3455 final int startActivityInPackage(int uid, String callingPackage, 3456 Intent intent, String resolvedType, IBinder resultTo, 3457 String resultWho, int requestCode, int startFlags, Bundle options, int userId, 3458 IActivityContainer container) { 3459 3460 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3461 false, true, "startActivityInPackage", null); 3462 3463 // TODO: Switch to user app stacks here. 3464 int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent, resolvedType, 3465 null, null, resultTo, resultWho, requestCode, startFlags, 3466 null, null, null, null, options, userId, container); 3467 return ret; 3468 } 3469 3470 @Override 3471 public final int startActivities(IApplicationThread caller, String callingPackage, 3472 Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options, 3473 int userId) { 3474 enforceNotIsolatedCaller("startActivities"); 3475 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3476 false, true, "startActivity", null); 3477 // TODO: Switch to user app stacks here. 3478 int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents, 3479 resolvedTypes, resultTo, options, userId); 3480 return ret; 3481 } 3482 3483 final int startActivitiesInPackage(int uid, String callingPackage, 3484 Intent[] intents, String[] resolvedTypes, IBinder resultTo, 3485 Bundle options, int userId) { 3486 3487 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3488 false, true, "startActivityInPackage", null); 3489 // TODO: Switch to user app stacks here. 3490 int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes, 3491 resultTo, options, userId); 3492 return ret; 3493 } 3494 3495 final void addRecentTaskLocked(TaskRecord task) { 3496 int N = mRecentTasks.size(); 3497 // Quick case: check if the top-most recent task is the same. 3498 if (N > 0 && mRecentTasks.get(0) == task) { 3499 return; 3500 } 3501 // Another quick case: never add voice sessions. 3502 if (task.voiceSession != null) { 3503 return; 3504 } 3505 // Remove any existing entries that are the same kind of task. 3506 final Intent intent = task.intent; 3507 final boolean document = intent != null && intent.isDocument(); 3508 for (int i=0; i<N; i++) { 3509 TaskRecord tr = mRecentTasks.get(i); 3510 if (task != tr) { 3511 if (task.userId != tr.userId) { 3512 continue; 3513 } 3514 final Intent trIntent = tr.intent; 3515 if ((task.affinity == null || !task.affinity.equals(tr.affinity)) && 3516 (intent == null || !intent.filterEquals(trIntent))) { 3517 continue; 3518 } 3519 if (document || trIntent != null && trIntent.isDocument()) { 3520 // Document tasks do not match other tasks. 3521 continue; 3522 } 3523 } 3524 3525 // Either task and tr are the same or, their affinities match or their intents match 3526 // and neither of them is a document. 3527 tr.disposeThumbnail(); 3528 mRecentTasks.remove(i); 3529 i--; 3530 N--; 3531 if (task.intent == null) { 3532 // If the new recent task we are adding is not fully 3533 // specified, then replace it with the existing recent task. 3534 task = tr; 3535 } 3536 } 3537 if (N >= MAX_RECENT_TASKS) { 3538 mRecentTasks.remove(N-1).disposeThumbnail(); 3539 } 3540 mRecentTasks.add(0, task); 3541 } 3542 3543 @Override 3544 public void reportActivityFullyDrawn(IBinder token) { 3545 synchronized (this) { 3546 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3547 if (r == null) { 3548 return; 3549 } 3550 r.reportFullyDrawnLocked(); 3551 } 3552 } 3553 3554 @Override 3555 public void setRequestedOrientation(IBinder token, int requestedOrientation) { 3556 synchronized (this) { 3557 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3558 if (r == null) { 3559 return; 3560 } 3561 final long origId = Binder.clearCallingIdentity(); 3562 mWindowManager.setAppOrientation(r.appToken, requestedOrientation); 3563 Configuration config = mWindowManager.updateOrientationFromAppTokens( 3564 mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null); 3565 if (config != null) { 3566 r.frozenBeforeDestroy = true; 3567 if (!updateConfigurationLocked(config, r, false, false)) { 3568 mStackSupervisor.resumeTopActivitiesLocked(); 3569 } 3570 } 3571 Binder.restoreCallingIdentity(origId); 3572 } 3573 } 3574 3575 @Override 3576 public int getRequestedOrientation(IBinder token) { 3577 synchronized (this) { 3578 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3579 if (r == null) { 3580 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; 3581 } 3582 return mWindowManager.getAppOrientation(r.appToken); 3583 } 3584 } 3585 3586 /** 3587 * This is the internal entry point for handling Activity.finish(). 3588 * 3589 * @param token The Binder token referencing the Activity we want to finish. 3590 * @param resultCode Result code, if any, from this Activity. 3591 * @param resultData Result data (Intent), if any, from this Activity. 3592 * @param finishTask Whether to finish the task associated with this Activity. Only applies to 3593 * the root Activity in the task. 3594 * 3595 * @return Returns true if the activity successfully finished, or false if it is still running. 3596 */ 3597 @Override 3598 public final boolean finishActivity(IBinder token, int resultCode, Intent resultData, 3599 boolean finishTask) { 3600 // Refuse possible leaked file descriptors 3601 if (resultData != null && resultData.hasFileDescriptors() == true) { 3602 throw new IllegalArgumentException("File descriptors passed in Intent"); 3603 } 3604 3605 synchronized(this) { 3606 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3607 if (r == null) { 3608 return true; 3609 } 3610 // Keep track of the root activity of the task before we finish it 3611 TaskRecord tr = r.task; 3612 ActivityRecord rootR = tr.getRootActivity(); 3613 if (mController != null) { 3614 // Find the first activity that is not finishing. 3615 ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0); 3616 if (next != null) { 3617 // ask watcher if this is allowed 3618 boolean resumeOK = true; 3619 try { 3620 resumeOK = mController.activityResuming(next.packageName); 3621 } catch (RemoteException e) { 3622 mController = null; 3623 Watchdog.getInstance().setActivityController(null); 3624 } 3625 3626 if (!resumeOK) { 3627 return false; 3628 } 3629 } 3630 } 3631 final long origId = Binder.clearCallingIdentity(); 3632 try { 3633 boolean res; 3634 if (finishTask && r == rootR) { 3635 // If requested, remove the task that is associated to this activity only if it 3636 // was the root activity in the task. The result code and data is ignored because 3637 // we don't support returning them across task boundaries. 3638 res = removeTaskByIdLocked(tr.taskId, 0); 3639 } else { 3640 res = tr.stack.requestFinishActivityLocked(token, resultCode, 3641 resultData, "app-request", true); 3642 } 3643 return res; 3644 } finally { 3645 Binder.restoreCallingIdentity(origId); 3646 } 3647 } 3648 } 3649 3650 @Override 3651 public final void finishHeavyWeightApp() { 3652 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 3653 != PackageManager.PERMISSION_GRANTED) { 3654 String msg = "Permission Denial: finishHeavyWeightApp() from pid=" 3655 + Binder.getCallingPid() 3656 + ", uid=" + Binder.getCallingUid() 3657 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 3658 Slog.w(TAG, msg); 3659 throw new SecurityException(msg); 3660 } 3661 3662 synchronized(this) { 3663 if (mHeavyWeightProcess == null) { 3664 return; 3665 } 3666 3667 ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>( 3668 mHeavyWeightProcess.activities); 3669 for (int i=0; i<activities.size(); i++) { 3670 ActivityRecord r = activities.get(i); 3671 if (!r.finishing) { 3672 r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED, 3673 null, "finish-heavy", true); 3674 } 3675 } 3676 3677 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 3678 mHeavyWeightProcess.userId, 0)); 3679 mHeavyWeightProcess = null; 3680 } 3681 } 3682 3683 @Override 3684 public void crashApplication(int uid, int initialPid, String packageName, 3685 String message) { 3686 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 3687 != PackageManager.PERMISSION_GRANTED) { 3688 String msg = "Permission Denial: crashApplication() from pid=" 3689 + Binder.getCallingPid() 3690 + ", uid=" + Binder.getCallingUid() 3691 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 3692 Slog.w(TAG, msg); 3693 throw new SecurityException(msg); 3694 } 3695 3696 synchronized(this) { 3697 ProcessRecord proc = null; 3698 3699 // Figure out which process to kill. We don't trust that initialPid 3700 // still has any relation to current pids, so must scan through the 3701 // list. 3702 synchronized (mPidsSelfLocked) { 3703 for (int i=0; i<mPidsSelfLocked.size(); i++) { 3704 ProcessRecord p = mPidsSelfLocked.valueAt(i); 3705 if (p.uid != uid) { 3706 continue; 3707 } 3708 if (p.pid == initialPid) { 3709 proc = p; 3710 break; 3711 } 3712 if (p.pkgList.containsKey(packageName)) { 3713 proc = p; 3714 } 3715 } 3716 } 3717 3718 if (proc == null) { 3719 Slog.w(TAG, "crashApplication: nothing for uid=" + uid 3720 + " initialPid=" + initialPid 3721 + " packageName=" + packageName); 3722 return; 3723 } 3724 3725 if (proc.thread != null) { 3726 if (proc.pid == Process.myPid()) { 3727 Log.w(TAG, "crashApplication: trying to crash self!"); 3728 return; 3729 } 3730 long ident = Binder.clearCallingIdentity(); 3731 try { 3732 proc.thread.scheduleCrash(message); 3733 } catch (RemoteException e) { 3734 } 3735 Binder.restoreCallingIdentity(ident); 3736 } 3737 } 3738 } 3739 3740 @Override 3741 public final void finishSubActivity(IBinder token, String resultWho, 3742 int requestCode) { 3743 synchronized(this) { 3744 final long origId = Binder.clearCallingIdentity(); 3745 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3746 if (r != null) { 3747 r.task.stack.finishSubActivityLocked(r, resultWho, requestCode); 3748 } 3749 Binder.restoreCallingIdentity(origId); 3750 } 3751 } 3752 3753 @Override 3754 public boolean finishActivityAffinity(IBinder token) { 3755 synchronized(this) { 3756 final long origId = Binder.clearCallingIdentity(); 3757 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3758 boolean res = false; 3759 if (r != null) { 3760 res = r.task.stack.finishActivityAffinityLocked(r); 3761 } 3762 Binder.restoreCallingIdentity(origId); 3763 return res; 3764 } 3765 } 3766 3767 @Override 3768 public boolean willActivityBeVisible(IBinder token) { 3769 synchronized(this) { 3770 ActivityStack stack = ActivityRecord.getStackLocked(token); 3771 if (stack != null) { 3772 return stack.willActivityBeVisibleLocked(token); 3773 } 3774 return false; 3775 } 3776 } 3777 3778 @Override 3779 public void overridePendingTransition(IBinder token, String packageName, 3780 int enterAnim, int exitAnim) { 3781 synchronized(this) { 3782 ActivityRecord self = ActivityRecord.isInStackLocked(token); 3783 if (self == null) { 3784 return; 3785 } 3786 3787 final long origId = Binder.clearCallingIdentity(); 3788 3789 if (self.state == ActivityState.RESUMED 3790 || self.state == ActivityState.PAUSING) { 3791 mWindowManager.overridePendingAppTransition(packageName, 3792 enterAnim, exitAnim, null); 3793 } 3794 3795 Binder.restoreCallingIdentity(origId); 3796 } 3797 } 3798 3799 /** 3800 * Main function for removing an existing process from the activity manager 3801 * as a result of that process going away. Clears out all connections 3802 * to the process. 3803 */ 3804 private final void handleAppDiedLocked(ProcessRecord app, 3805 boolean restarting, boolean allowRestart) { 3806 int pid = app.pid; 3807 cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1); 3808 if (!restarting) { 3809 removeLruProcessLocked(app); 3810 if (pid > 0) { 3811 ProcessList.remove(pid); 3812 } 3813 } 3814 3815 if (mProfileProc == app) { 3816 clearProfilerLocked(); 3817 } 3818 3819 // Remove this application's activities from active lists. 3820 boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app); 3821 3822 app.activities.clear(); 3823 3824 if (app.instrumentationClass != null) { 3825 Slog.w(TAG, "Crash of app " + app.processName 3826 + " running instrumentation " + app.instrumentationClass); 3827 Bundle info = new Bundle(); 3828 info.putString("shortMsg", "Process crashed."); 3829 finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info); 3830 } 3831 3832 if (!restarting) { 3833 if (!mStackSupervisor.resumeTopActivitiesLocked()) { 3834 // If there was nothing to resume, and we are not already 3835 // restarting this process, but there is a visible activity that 3836 // is hosted by the process... then make sure all visible 3837 // activities are running, taking care of restarting this 3838 // process. 3839 if (hasVisibleActivities) { 3840 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 3841 } 3842 } 3843 } 3844 } 3845 3846 private final int getLRURecordIndexForAppLocked(IApplicationThread thread) { 3847 IBinder threadBinder = thread.asBinder(); 3848 // Find the application record. 3849 for (int i=mLruProcesses.size()-1; i>=0; i--) { 3850 ProcessRecord rec = mLruProcesses.get(i); 3851 if (rec.thread != null && rec.thread.asBinder() == threadBinder) { 3852 return i; 3853 } 3854 } 3855 return -1; 3856 } 3857 3858 final ProcessRecord getRecordForAppLocked( 3859 IApplicationThread thread) { 3860 if (thread == null) { 3861 return null; 3862 } 3863 3864 int appIndex = getLRURecordIndexForAppLocked(thread); 3865 return appIndex >= 0 ? mLruProcesses.get(appIndex) : null; 3866 } 3867 3868 final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) { 3869 // If there are no longer any background processes running, 3870 // and the app that died was not running instrumentation, 3871 // then tell everyone we are now low on memory. 3872 boolean haveBg = false; 3873 for (int i=mLruProcesses.size()-1; i>=0; i--) { 3874 ProcessRecord rec = mLruProcesses.get(i); 3875 if (rec.thread != null 3876 && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 3877 haveBg = true; 3878 break; 3879 } 3880 } 3881 3882 if (!haveBg) { 3883 boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 3884 if (doReport) { 3885 long now = SystemClock.uptimeMillis(); 3886 if (now < (mLastMemUsageReportTime+5*60*1000)) { 3887 doReport = false; 3888 } else { 3889 mLastMemUsageReportTime = now; 3890 } 3891 } 3892 final ArrayList<ProcessMemInfo> memInfos 3893 = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null; 3894 EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size()); 3895 long now = SystemClock.uptimeMillis(); 3896 for (int i=mLruProcesses.size()-1; i>=0; i--) { 3897 ProcessRecord rec = mLruProcesses.get(i); 3898 if (rec == dyingProc || rec.thread == null) { 3899 continue; 3900 } 3901 if (doReport) { 3902 memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj, 3903 rec.setProcState, rec.adjType, rec.makeAdjReason())); 3904 } 3905 if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) { 3906 // The low memory report is overriding any current 3907 // state for a GC request. Make sure to do 3908 // heavy/important/visible/foreground processes first. 3909 if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 3910 rec.lastRequestedGc = 0; 3911 } else { 3912 rec.lastRequestedGc = rec.lastLowMemory; 3913 } 3914 rec.reportLowMemory = true; 3915 rec.lastLowMemory = now; 3916 mProcessesToGc.remove(rec); 3917 addProcessToGcListLocked(rec); 3918 } 3919 } 3920 if (doReport) { 3921 Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos); 3922 mHandler.sendMessage(msg); 3923 } 3924 scheduleAppGcsLocked(); 3925 } 3926 } 3927 3928 final void appDiedLocked(ProcessRecord app, int pid, 3929 IApplicationThread thread) { 3930 3931 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 3932 synchronized (stats) { 3933 stats.noteProcessDiedLocked(app.info.uid, pid); 3934 } 3935 3936 // Clean up already done if the process has been re-started. 3937 if (app.pid == pid && app.thread != null && 3938 app.thread.asBinder() == thread.asBinder()) { 3939 boolean doLowMem = app.instrumentationClass == null; 3940 boolean doOomAdj = doLowMem; 3941 if (!app.killedByAm) { 3942 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 3943 + ") has died."); 3944 mAllowLowerMemLevel = true; 3945 } else { 3946 // Note that we always want to do oom adj to update our state with the 3947 // new number of procs. 3948 mAllowLowerMemLevel = false; 3949 doLowMem = false; 3950 } 3951 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName); 3952 if (DEBUG_CLEANUP) Slog.v( 3953 TAG, "Dying app: " + app + ", pid: " + pid 3954 + ", thread: " + thread.asBinder()); 3955 handleAppDiedLocked(app, false, true); 3956 3957 if (doOomAdj) { 3958 updateOomAdjLocked(); 3959 } 3960 if (doLowMem) { 3961 doLowMemReportIfNeededLocked(app); 3962 } 3963 } else if (app.pid != pid) { 3964 // A new process has already been started. 3965 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 3966 + ") has died and restarted (pid " + app.pid + ")."); 3967 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName); 3968 } else if (DEBUG_PROCESSES) { 3969 Slog.d(TAG, "Received spurious death notification for thread " 3970 + thread.asBinder()); 3971 } 3972 } 3973 3974 /** 3975 * If a stack trace dump file is configured, dump process stack traces. 3976 * @param clearTraces causes the dump file to be erased prior to the new 3977 * traces being written, if true; when false, the new traces will be 3978 * appended to any existing file content. 3979 * @param firstPids of dalvik VM processes to dump stack traces for first 3980 * @param lastPids of dalvik VM processes to dump stack traces for last 3981 * @param nativeProcs optional list of native process names to dump stack crawls 3982 * @return file containing stack traces, or null if no dump file is configured 3983 */ 3984 public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids, 3985 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) { 3986 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 3987 if (tracesPath == null || tracesPath.length() == 0) { 3988 return null; 3989 } 3990 3991 File tracesFile = new File(tracesPath); 3992 try { 3993 File tracesDir = tracesFile.getParentFile(); 3994 if (!tracesDir.exists()) { 3995 tracesFile.mkdirs(); 3996 if (!SELinux.restorecon(tracesDir)) { 3997 return null; 3998 } 3999 } 4000 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 4001 4002 if (clearTraces && tracesFile.exists()) tracesFile.delete(); 4003 tracesFile.createNewFile(); 4004 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 4005 } catch (IOException e) { 4006 Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e); 4007 return null; 4008 } 4009 4010 dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs); 4011 return tracesFile; 4012 } 4013 4014 private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids, 4015 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) { 4016 // Use a FileObserver to detect when traces finish writing. 4017 // The order of traces is considered important to maintain for legibility. 4018 FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) { 4019 @Override 4020 public synchronized void onEvent(int event, String path) { notify(); } 4021 }; 4022 4023 try { 4024 observer.startWatching(); 4025 4026 // First collect all of the stacks of the most important pids. 4027 if (firstPids != null) { 4028 try { 4029 int num = firstPids.size(); 4030 for (int i = 0; i < num; i++) { 4031 synchronized (observer) { 4032 Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT); 4033 observer.wait(200); // Wait for write-close, give up after 200msec 4034 } 4035 } 4036 } catch (InterruptedException e) { 4037 Log.wtf(TAG, e); 4038 } 4039 } 4040 4041 // Next collect the stacks of the native pids 4042 if (nativeProcs != null) { 4043 int[] pids = Process.getPidsForCommands(nativeProcs); 4044 if (pids != null) { 4045 for (int pid : pids) { 4046 Debug.dumpNativeBacktraceToFile(pid, tracesPath); 4047 } 4048 } 4049 } 4050 4051 // Lastly, measure CPU usage. 4052 if (processCpuTracker != null) { 4053 processCpuTracker.init(); 4054 System.gc(); 4055 processCpuTracker.update(); 4056 try { 4057 synchronized (processCpuTracker) { 4058 processCpuTracker.wait(500); // measure over 1/2 second. 4059 } 4060 } catch (InterruptedException e) { 4061 } 4062 processCpuTracker.update(); 4063 4064 // We'll take the stack crawls of just the top apps using CPU. 4065 final int N = processCpuTracker.countWorkingStats(); 4066 int numProcs = 0; 4067 for (int i=0; i<N && numProcs<5; i++) { 4068 ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i); 4069 if (lastPids.indexOfKey(stats.pid) >= 0) { 4070 numProcs++; 4071 try { 4072 synchronized (observer) { 4073 Process.sendSignal(stats.pid, Process.SIGNAL_QUIT); 4074 observer.wait(200); // Wait for write-close, give up after 200msec 4075 } 4076 } catch (InterruptedException e) { 4077 Log.wtf(TAG, e); 4078 } 4079 4080 } 4081 } 4082 } 4083 } finally { 4084 observer.stopWatching(); 4085 } 4086 } 4087 4088 final void logAppTooSlow(ProcessRecord app, long startTime, String msg) { 4089 if (true || IS_USER_BUILD) { 4090 return; 4091 } 4092 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 4093 if (tracesPath == null || tracesPath.length() == 0) { 4094 return; 4095 } 4096 4097 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads(); 4098 StrictMode.allowThreadDiskWrites(); 4099 try { 4100 final File tracesFile = new File(tracesPath); 4101 final File tracesDir = tracesFile.getParentFile(); 4102 final File tracesTmp = new File(tracesDir, "__tmp__"); 4103 try { 4104 if (!tracesDir.exists()) { 4105 tracesFile.mkdirs(); 4106 if (!SELinux.restorecon(tracesDir.getPath())) { 4107 return; 4108 } 4109 } 4110 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 4111 4112 if (tracesFile.exists()) { 4113 tracesTmp.delete(); 4114 tracesFile.renameTo(tracesTmp); 4115 } 4116 StringBuilder sb = new StringBuilder(); 4117 Time tobj = new Time(); 4118 tobj.set(System.currentTimeMillis()); 4119 sb.append(tobj.format("%Y-%m-%d %H:%M:%S")); 4120 sb.append(": "); 4121 TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb); 4122 sb.append(" since "); 4123 sb.append(msg); 4124 FileOutputStream fos = new FileOutputStream(tracesFile); 4125 fos.write(sb.toString().getBytes()); 4126 if (app == null) { 4127 fos.write("\n*** No application process!".getBytes()); 4128 } 4129 fos.close(); 4130 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 4131 } catch (IOException e) { 4132 Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e); 4133 return; 4134 } 4135 4136 if (app != null) { 4137 ArrayList<Integer> firstPids = new ArrayList<Integer>(); 4138 firstPids.add(app.pid); 4139 dumpStackTraces(tracesPath, firstPids, null, null, null); 4140 } 4141 4142 File lastTracesFile = null; 4143 File curTracesFile = null; 4144 for (int i=9; i>=0; i--) { 4145 String name = String.format(Locale.US, "slow%02d.txt", i); 4146 curTracesFile = new File(tracesDir, name); 4147 if (curTracesFile.exists()) { 4148 if (lastTracesFile != null) { 4149 curTracesFile.renameTo(lastTracesFile); 4150 } else { 4151 curTracesFile.delete(); 4152 } 4153 } 4154 lastTracesFile = curTracesFile; 4155 } 4156 tracesFile.renameTo(curTracesFile); 4157 if (tracesTmp.exists()) { 4158 tracesTmp.renameTo(tracesFile); 4159 } 4160 } finally { 4161 StrictMode.setThreadPolicy(oldPolicy); 4162 } 4163 } 4164 4165 final void appNotResponding(ProcessRecord app, ActivityRecord activity, 4166 ActivityRecord parent, boolean aboveSystem, final String annotation) { 4167 ArrayList<Integer> firstPids = new ArrayList<Integer>(5); 4168 SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20); 4169 4170 if (mController != null) { 4171 try { 4172 // 0 == continue, -1 = kill process immediately 4173 int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation); 4174 if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid); 4175 } catch (RemoteException e) { 4176 mController = null; 4177 Watchdog.getInstance().setActivityController(null); 4178 } 4179 } 4180 4181 long anrTime = SystemClock.uptimeMillis(); 4182 if (MONITOR_CPU_USAGE) { 4183 updateCpuStatsNow(); 4184 } 4185 4186 synchronized (this) { 4187 // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down. 4188 if (mShuttingDown) { 4189 Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation); 4190 return; 4191 } else if (app.notResponding) { 4192 Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation); 4193 return; 4194 } else if (app.crashing) { 4195 Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation); 4196 return; 4197 } 4198 4199 // In case we come through here for the same app before completing 4200 // this one, mark as anring now so we will bail out. 4201 app.notResponding = true; 4202 4203 // Log the ANR to the event log. 4204 EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid, 4205 app.processName, app.info.flags, annotation); 4206 4207 // Dump thread traces as quickly as we can, starting with "interesting" processes. 4208 firstPids.add(app.pid); 4209 4210 int parentPid = app.pid; 4211 if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid; 4212 if (parentPid != app.pid) firstPids.add(parentPid); 4213 4214 if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID); 4215 4216 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 4217 ProcessRecord r = mLruProcesses.get(i); 4218 if (r != null && r.thread != null) { 4219 int pid = r.pid; 4220 if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) { 4221 if (r.persistent) { 4222 firstPids.add(pid); 4223 } else { 4224 lastPids.put(pid, Boolean.TRUE); 4225 } 4226 } 4227 } 4228 } 4229 } 4230 4231 // Log the ANR to the main log. 4232 StringBuilder info = new StringBuilder(); 4233 info.setLength(0); 4234 info.append("ANR in ").append(app.processName); 4235 if (activity != null && activity.shortComponentName != null) { 4236 info.append(" (").append(activity.shortComponentName).append(")"); 4237 } 4238 info.append("\n"); 4239 info.append("PID: ").append(app.pid).append("\n"); 4240 if (annotation != null) { 4241 info.append("Reason: ").append(annotation).append("\n"); 4242 } 4243 if (parent != null && parent != activity) { 4244 info.append("Parent: ").append(parent.shortComponentName).append("\n"); 4245 } 4246 4247 final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true); 4248 4249 File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids, 4250 NATIVE_STACKS_OF_INTEREST); 4251 4252 String cpuInfo = null; 4253 if (MONITOR_CPU_USAGE) { 4254 updateCpuStatsNow(); 4255 synchronized (mProcessCpuThread) { 4256 cpuInfo = mProcessCpuTracker.printCurrentState(anrTime); 4257 } 4258 info.append(processCpuTracker.printCurrentLoad()); 4259 info.append(cpuInfo); 4260 } 4261 4262 info.append(processCpuTracker.printCurrentState(anrTime)); 4263 4264 Slog.e(TAG, info.toString()); 4265 if (tracesFile == null) { 4266 // There is no trace file, so dump (only) the alleged culprit's threads to the log 4267 Process.sendSignal(app.pid, Process.SIGNAL_QUIT); 4268 } 4269 4270 addErrorToDropBox("anr", app, app.processName, activity, parent, annotation, 4271 cpuInfo, tracesFile, null); 4272 4273 if (mController != null) { 4274 try { 4275 // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately 4276 int res = mController.appNotResponding(app.processName, app.pid, info.toString()); 4277 if (res != 0) { 4278 if (res < 0 && app.pid != MY_PID) { 4279 Process.killProcess(app.pid); 4280 } else { 4281 synchronized (this) { 4282 mServices.scheduleServiceTimeoutLocked(app); 4283 } 4284 } 4285 return; 4286 } 4287 } catch (RemoteException e) { 4288 mController = null; 4289 Watchdog.getInstance().setActivityController(null); 4290 } 4291 } 4292 4293 // Unless configured otherwise, swallow ANRs in background processes & kill the process. 4294 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), 4295 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; 4296 4297 synchronized (this) { 4298 if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) { 4299 killUnneededProcessLocked(app, "background ANR"); 4300 return; 4301 } 4302 4303 // Set the app's notResponding state, and look up the errorReportReceiver 4304 makeAppNotRespondingLocked(app, 4305 activity != null ? activity.shortComponentName : null, 4306 annotation != null ? "ANR " + annotation : "ANR", 4307 info.toString()); 4308 4309 // Bring up the infamous App Not Responding dialog 4310 Message msg = Message.obtain(); 4311 HashMap<String, Object> map = new HashMap<String, Object>(); 4312 msg.what = SHOW_NOT_RESPONDING_MSG; 4313 msg.obj = map; 4314 msg.arg1 = aboveSystem ? 1 : 0; 4315 map.put("app", app); 4316 if (activity != null) { 4317 map.put("activity", activity); 4318 } 4319 4320 mHandler.sendMessage(msg); 4321 } 4322 } 4323 4324 final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) { 4325 if (!mLaunchWarningShown) { 4326 mLaunchWarningShown = true; 4327 mHandler.post(new Runnable() { 4328 @Override 4329 public void run() { 4330 synchronized (ActivityManagerService.this) { 4331 final Dialog d = new LaunchWarningWindow(mContext, cur, next); 4332 d.show(); 4333 mHandler.postDelayed(new Runnable() { 4334 @Override 4335 public void run() { 4336 synchronized (ActivityManagerService.this) { 4337 d.dismiss(); 4338 mLaunchWarningShown = false; 4339 } 4340 } 4341 }, 4000); 4342 } 4343 } 4344 }); 4345 } 4346 } 4347 4348 @Override 4349 public boolean clearApplicationUserData(final String packageName, 4350 final IPackageDataObserver observer, int userId) { 4351 enforceNotIsolatedCaller("clearApplicationUserData"); 4352 int uid = Binder.getCallingUid(); 4353 int pid = Binder.getCallingPid(); 4354 userId = handleIncomingUser(pid, uid, 4355 userId, false, true, "clearApplicationUserData", null); 4356 long callingId = Binder.clearCallingIdentity(); 4357 try { 4358 IPackageManager pm = AppGlobals.getPackageManager(); 4359 int pkgUid = -1; 4360 synchronized(this) { 4361 try { 4362 pkgUid = pm.getPackageUid(packageName, userId); 4363 } catch (RemoteException e) { 4364 } 4365 if (pkgUid == -1) { 4366 Slog.w(TAG, "Invalid packageName: " + packageName); 4367 if (observer != null) { 4368 try { 4369 observer.onRemoveCompleted(packageName, false); 4370 } catch (RemoteException e) { 4371 Slog.i(TAG, "Observer no longer exists."); 4372 } 4373 } 4374 return false; 4375 } 4376 if (uid == pkgUid || checkComponentPermission( 4377 android.Manifest.permission.CLEAR_APP_USER_DATA, 4378 pid, uid, -1, true) 4379 == PackageManager.PERMISSION_GRANTED) { 4380 forceStopPackageLocked(packageName, pkgUid, "clear data"); 4381 } else { 4382 throw new SecurityException("PID " + pid + " does not have permission " 4383 + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data" 4384 + " of package " + packageName); 4385 } 4386 } 4387 4388 try { 4389 // Clear application user data 4390 pm.clearApplicationUserData(packageName, observer, userId); 4391 4392 // Remove all permissions granted from/to this package 4393 removeUriPermissionsForPackageLocked(packageName, userId, true); 4394 4395 Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED, 4396 Uri.fromParts("package", packageName, null)); 4397 intent.putExtra(Intent.EXTRA_UID, pkgUid); 4398 broadcastIntentInPackage("android", Process.SYSTEM_UID, intent, 4399 null, null, 0, null, null, null, false, false, userId); 4400 } catch (RemoteException e) { 4401 } 4402 } finally { 4403 Binder.restoreCallingIdentity(callingId); 4404 } 4405 return true; 4406 } 4407 4408 @Override 4409 public void killBackgroundProcesses(final String packageName, int userId) { 4410 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 4411 != PackageManager.PERMISSION_GRANTED && 4412 checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES) 4413 != PackageManager.PERMISSION_GRANTED) { 4414 String msg = "Permission Denial: killBackgroundProcesses() from pid=" 4415 + Binder.getCallingPid() 4416 + ", uid=" + Binder.getCallingUid() 4417 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 4418 Slog.w(TAG, msg); 4419 throw new SecurityException(msg); 4420 } 4421 4422 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 4423 userId, true, true, "killBackgroundProcesses", null); 4424 long callingId = Binder.clearCallingIdentity(); 4425 try { 4426 IPackageManager pm = AppGlobals.getPackageManager(); 4427 synchronized(this) { 4428 int appId = -1; 4429 try { 4430 appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0)); 4431 } catch (RemoteException e) { 4432 } 4433 if (appId == -1) { 4434 Slog.w(TAG, "Invalid packageName: " + packageName); 4435 return; 4436 } 4437 killPackageProcessesLocked(packageName, appId, userId, 4438 ProcessList.SERVICE_ADJ, false, true, true, false, "kill background"); 4439 } 4440 } finally { 4441 Binder.restoreCallingIdentity(callingId); 4442 } 4443 } 4444 4445 @Override 4446 public void killAllBackgroundProcesses() { 4447 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 4448 != PackageManager.PERMISSION_GRANTED) { 4449 String msg = "Permission Denial: killAllBackgroundProcesses() from pid=" 4450 + Binder.getCallingPid() 4451 + ", uid=" + Binder.getCallingUid() 4452 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 4453 Slog.w(TAG, msg); 4454 throw new SecurityException(msg); 4455 } 4456 4457 long callingId = Binder.clearCallingIdentity(); 4458 try { 4459 synchronized(this) { 4460 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 4461 final int NP = mProcessNames.getMap().size(); 4462 for (int ip=0; ip<NP; ip++) { 4463 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 4464 final int NA = apps.size(); 4465 for (int ia=0; ia<NA; ia++) { 4466 ProcessRecord app = apps.valueAt(ia); 4467 if (app.persistent) { 4468 // we don't kill persistent processes 4469 continue; 4470 } 4471 if (app.removed) { 4472 procs.add(app); 4473 } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 4474 app.removed = true; 4475 procs.add(app); 4476 } 4477 } 4478 } 4479 4480 int N = procs.size(); 4481 for (int i=0; i<N; i++) { 4482 removeProcessLocked(procs.get(i), false, true, "kill all background"); 4483 } 4484 mAllowLowerMemLevel = true; 4485 updateOomAdjLocked(); 4486 doLowMemReportIfNeededLocked(null); 4487 } 4488 } finally { 4489 Binder.restoreCallingIdentity(callingId); 4490 } 4491 } 4492 4493 @Override 4494 public void forceStopPackage(final String packageName, int userId) { 4495 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 4496 != PackageManager.PERMISSION_GRANTED) { 4497 String msg = "Permission Denial: forceStopPackage() from pid=" 4498 + Binder.getCallingPid() 4499 + ", uid=" + Binder.getCallingUid() 4500 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 4501 Slog.w(TAG, msg); 4502 throw new SecurityException(msg); 4503 } 4504 final int callingPid = Binder.getCallingPid(); 4505 userId = handleIncomingUser(callingPid, Binder.getCallingUid(), 4506 userId, true, true, "forceStopPackage", null); 4507 long callingId = Binder.clearCallingIdentity(); 4508 try { 4509 IPackageManager pm = AppGlobals.getPackageManager(); 4510 synchronized(this) { 4511 int[] users = userId == UserHandle.USER_ALL 4512 ? getUsersLocked() : new int[] { userId }; 4513 for (int user : users) { 4514 int pkgUid = -1; 4515 try { 4516 pkgUid = pm.getPackageUid(packageName, user); 4517 } catch (RemoteException e) { 4518 } 4519 if (pkgUid == -1) { 4520 Slog.w(TAG, "Invalid packageName: " + packageName); 4521 continue; 4522 } 4523 try { 4524 pm.setPackageStoppedState(packageName, true, user); 4525 } catch (RemoteException e) { 4526 } catch (IllegalArgumentException e) { 4527 Slog.w(TAG, "Failed trying to unstop package " 4528 + packageName + ": " + e); 4529 } 4530 if (isUserRunningLocked(user, false)) { 4531 forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid); 4532 } 4533 } 4534 } 4535 } finally { 4536 Binder.restoreCallingIdentity(callingId); 4537 } 4538 } 4539 4540 /* 4541 * The pkg name and app id have to be specified. 4542 */ 4543 @Override 4544 public void killApplicationWithAppId(String pkg, int appid, String reason) { 4545 if (pkg == null) { 4546 return; 4547 } 4548 // Make sure the uid is valid. 4549 if (appid < 0) { 4550 Slog.w(TAG, "Invalid appid specified for pkg : " + pkg); 4551 return; 4552 } 4553 int callerUid = Binder.getCallingUid(); 4554 // Only the system server can kill an application 4555 if (callerUid == Process.SYSTEM_UID) { 4556 // Post an aysnc message to kill the application 4557 Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG); 4558 msg.arg1 = appid; 4559 msg.arg2 = 0; 4560 Bundle bundle = new Bundle(); 4561 bundle.putString("pkg", pkg); 4562 bundle.putString("reason", reason); 4563 msg.obj = bundle; 4564 mHandler.sendMessage(msg); 4565 } else { 4566 throw new SecurityException(callerUid + " cannot kill pkg: " + 4567 pkg); 4568 } 4569 } 4570 4571 @Override 4572 public void closeSystemDialogs(String reason) { 4573 enforceNotIsolatedCaller("closeSystemDialogs"); 4574 4575 final int pid = Binder.getCallingPid(); 4576 final int uid = Binder.getCallingUid(); 4577 final long origId = Binder.clearCallingIdentity(); 4578 try { 4579 synchronized (this) { 4580 // Only allow this from foreground processes, so that background 4581 // applications can't abuse it to prevent system UI from being shown. 4582 if (uid >= Process.FIRST_APPLICATION_UID) { 4583 ProcessRecord proc; 4584 synchronized (mPidsSelfLocked) { 4585 proc = mPidsSelfLocked.get(pid); 4586 } 4587 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 4588 Slog.w(TAG, "Ignoring closeSystemDialogs " + reason 4589 + " from background process " + proc); 4590 return; 4591 } 4592 } 4593 closeSystemDialogsLocked(reason); 4594 } 4595 } finally { 4596 Binder.restoreCallingIdentity(origId); 4597 } 4598 } 4599 4600 void closeSystemDialogsLocked(String reason) { 4601 Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS); 4602 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 4603 | Intent.FLAG_RECEIVER_FOREGROUND); 4604 if (reason != null) { 4605 intent.putExtra("reason", reason); 4606 } 4607 mWindowManager.closeSystemDialogs(reason); 4608 4609 mStackSupervisor.closeSystemDialogsLocked(); 4610 4611 broadcastIntentLocked(null, null, intent, null, 4612 null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1, 4613 Process.SYSTEM_UID, UserHandle.USER_ALL); 4614 } 4615 4616 @Override 4617 public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) { 4618 enforceNotIsolatedCaller("getProcessMemoryInfo"); 4619 Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length]; 4620 for (int i=pids.length-1; i>=0; i--) { 4621 ProcessRecord proc; 4622 int oomAdj; 4623 synchronized (this) { 4624 synchronized (mPidsSelfLocked) { 4625 proc = mPidsSelfLocked.get(pids[i]); 4626 oomAdj = proc != null ? proc.setAdj : 0; 4627 } 4628 } 4629 infos[i] = new Debug.MemoryInfo(); 4630 Debug.getMemoryInfo(pids[i], infos[i]); 4631 if (proc != null) { 4632 synchronized (this) { 4633 if (proc.thread != null && proc.setAdj == oomAdj) { 4634 // Record this for posterity if the process has been stable. 4635 proc.baseProcessTracker.addPss(infos[i].getTotalPss(), 4636 infos[i].getTotalUss(), false, proc.pkgList); 4637 } 4638 } 4639 } 4640 } 4641 return infos; 4642 } 4643 4644 @Override 4645 public long[] getProcessPss(int[] pids) { 4646 enforceNotIsolatedCaller("getProcessPss"); 4647 long[] pss = new long[pids.length]; 4648 for (int i=pids.length-1; i>=0; i--) { 4649 ProcessRecord proc; 4650 int oomAdj; 4651 synchronized (this) { 4652 synchronized (mPidsSelfLocked) { 4653 proc = mPidsSelfLocked.get(pids[i]); 4654 oomAdj = proc != null ? proc.setAdj : 0; 4655 } 4656 } 4657 long[] tmpUss = new long[1]; 4658 pss[i] = Debug.getPss(pids[i], tmpUss); 4659 if (proc != null) { 4660 synchronized (this) { 4661 if (proc.thread != null && proc.setAdj == oomAdj) { 4662 // Record this for posterity if the process has been stable. 4663 proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList); 4664 } 4665 } 4666 } 4667 } 4668 return pss; 4669 } 4670 4671 @Override 4672 public void killApplicationProcess(String processName, int uid) { 4673 if (processName == null) { 4674 return; 4675 } 4676 4677 int callerUid = Binder.getCallingUid(); 4678 // Only the system server can kill an application 4679 if (callerUid == Process.SYSTEM_UID) { 4680 synchronized (this) { 4681 ProcessRecord app = getProcessRecordLocked(processName, uid, true); 4682 if (app != null && app.thread != null) { 4683 try { 4684 app.thread.scheduleSuicide(); 4685 } catch (RemoteException e) { 4686 // If the other end already died, then our work here is done. 4687 } 4688 } else { 4689 Slog.w(TAG, "Process/uid not found attempting kill of " 4690 + processName + " / " + uid); 4691 } 4692 } 4693 } else { 4694 throw new SecurityException(callerUid + " cannot kill app process: " + 4695 processName); 4696 } 4697 } 4698 4699 private void forceStopPackageLocked(final String packageName, int uid, String reason) { 4700 forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false, 4701 false, true, false, false, UserHandle.getUserId(uid), reason); 4702 Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED, 4703 Uri.fromParts("package", packageName, null)); 4704 if (!mProcessesReady) { 4705 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 4706 | Intent.FLAG_RECEIVER_FOREGROUND); 4707 } 4708 intent.putExtra(Intent.EXTRA_UID, uid); 4709 intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid)); 4710 broadcastIntentLocked(null, null, intent, 4711 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 4712 false, false, 4713 MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid)); 4714 } 4715 4716 private void forceStopUserLocked(int userId, String reason) { 4717 forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason); 4718 Intent intent = new Intent(Intent.ACTION_USER_STOPPED); 4719 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 4720 | Intent.FLAG_RECEIVER_FOREGROUND); 4721 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 4722 broadcastIntentLocked(null, null, intent, 4723 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 4724 false, false, 4725 MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 4726 } 4727 4728 private final boolean killPackageProcessesLocked(String packageName, int appId, 4729 int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart, 4730 boolean doit, boolean evenPersistent, String reason) { 4731 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 4732 4733 // Remove all processes this package may have touched: all with the 4734 // same UID (except for the system or root user), and all whose name 4735 // matches the package name. 4736 final String procNamePrefix = packageName != null ? (packageName + ":") : null; 4737 final int NP = mProcessNames.getMap().size(); 4738 for (int ip=0; ip<NP; ip++) { 4739 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 4740 final int NA = apps.size(); 4741 for (int ia=0; ia<NA; ia++) { 4742 ProcessRecord app = apps.valueAt(ia); 4743 if (app.persistent && !evenPersistent) { 4744 // we don't kill persistent processes 4745 continue; 4746 } 4747 if (app.removed) { 4748 if (doit) { 4749 procs.add(app); 4750 } 4751 continue; 4752 } 4753 4754 // Skip process if it doesn't meet our oom adj requirement. 4755 if (app.setAdj < minOomAdj) { 4756 continue; 4757 } 4758 4759 // If no package is specified, we call all processes under the 4760 // give user id. 4761 if (packageName == null) { 4762 if (app.userId != userId) { 4763 continue; 4764 } 4765 if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) { 4766 continue; 4767 } 4768 // Package has been specified, we want to hit all processes 4769 // that match it. We need to qualify this by the processes 4770 // that are running under the specified app and user ID. 4771 } else { 4772 if (UserHandle.getAppId(app.uid) != appId) { 4773 continue; 4774 } 4775 if (userId != UserHandle.USER_ALL && app.userId != userId) { 4776 continue; 4777 } 4778 if (!app.pkgList.containsKey(packageName)) { 4779 continue; 4780 } 4781 } 4782 4783 // Process has passed all conditions, kill it! 4784 if (!doit) { 4785 return true; 4786 } 4787 app.removed = true; 4788 procs.add(app); 4789 } 4790 } 4791 4792 int N = procs.size(); 4793 for (int i=0; i<N; i++) { 4794 removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason); 4795 } 4796 updateOomAdjLocked(); 4797 return N > 0; 4798 } 4799 4800 private final boolean forceStopPackageLocked(String name, int appId, 4801 boolean callerWillRestart, boolean purgeCache, boolean doit, 4802 boolean evenPersistent, boolean uninstalling, int userId, String reason) { 4803 int i; 4804 int N; 4805 4806 if (userId == UserHandle.USER_ALL && name == null) { 4807 Slog.w(TAG, "Can't force stop all processes of all users, that is insane!"); 4808 } 4809 4810 if (appId < 0 && name != null) { 4811 try { 4812 appId = UserHandle.getAppId( 4813 AppGlobals.getPackageManager().getPackageUid(name, 0)); 4814 } catch (RemoteException e) { 4815 } 4816 } 4817 4818 if (doit) { 4819 if (name != null) { 4820 Slog.i(TAG, "Force stopping " + name + " appid=" + appId 4821 + " user=" + userId + ": " + reason); 4822 } else { 4823 Slog.i(TAG, "Force stopping u" + userId + ": " + reason); 4824 } 4825 4826 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap(); 4827 for (int ip=pmap.size()-1; ip>=0; ip--) { 4828 SparseArray<Long> ba = pmap.valueAt(ip); 4829 for (i=ba.size()-1; i>=0; i--) { 4830 boolean remove = false; 4831 final int entUid = ba.keyAt(i); 4832 if (name != null) { 4833 if (userId == UserHandle.USER_ALL) { 4834 if (UserHandle.getAppId(entUid) == appId) { 4835 remove = true; 4836 } 4837 } else { 4838 if (entUid == UserHandle.getUid(userId, appId)) { 4839 remove = true; 4840 } 4841 } 4842 } else if (UserHandle.getUserId(entUid) == userId) { 4843 remove = true; 4844 } 4845 if (remove) { 4846 ba.removeAt(i); 4847 } 4848 } 4849 if (ba.size() == 0) { 4850 pmap.removeAt(ip); 4851 } 4852 } 4853 } 4854 4855 boolean didSomething = killPackageProcessesLocked(name, appId, userId, 4856 -100, callerWillRestart, true, doit, evenPersistent, 4857 name == null ? ("stop user " + userId) : ("stop " + name)); 4858 4859 if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) { 4860 if (!doit) { 4861 return true; 4862 } 4863 didSomething = true; 4864 } 4865 4866 if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) { 4867 if (!doit) { 4868 return true; 4869 } 4870 didSomething = true; 4871 } 4872 4873 if (name == null) { 4874 // Remove all sticky broadcasts from this user. 4875 mStickyBroadcasts.remove(userId); 4876 } 4877 4878 ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>(); 4879 if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent, 4880 userId, providers)) { 4881 if (!doit) { 4882 return true; 4883 } 4884 didSomething = true; 4885 } 4886 N = providers.size(); 4887 for (i=0; i<N; i++) { 4888 removeDyingProviderLocked(null, providers.get(i), true); 4889 } 4890 4891 // Remove transient permissions granted from/to this package/user 4892 removeUriPermissionsForPackageLocked(name, userId, false); 4893 4894 if (name == null || uninstalling) { 4895 // Remove pending intents. For now we only do this when force 4896 // stopping users, because we have some problems when doing this 4897 // for packages -- app widgets are not currently cleaned up for 4898 // such packages, so they can be left with bad pending intents. 4899 if (mIntentSenderRecords.size() > 0) { 4900 Iterator<WeakReference<PendingIntentRecord>> it 4901 = mIntentSenderRecords.values().iterator(); 4902 while (it.hasNext()) { 4903 WeakReference<PendingIntentRecord> wpir = it.next(); 4904 if (wpir == null) { 4905 it.remove(); 4906 continue; 4907 } 4908 PendingIntentRecord pir = wpir.get(); 4909 if (pir == null) { 4910 it.remove(); 4911 continue; 4912 } 4913 if (name == null) { 4914 // Stopping user, remove all objects for the user. 4915 if (pir.key.userId != userId) { 4916 // Not the same user, skip it. 4917 continue; 4918 } 4919 } else { 4920 if (UserHandle.getAppId(pir.uid) != appId) { 4921 // Different app id, skip it. 4922 continue; 4923 } 4924 if (userId != UserHandle.USER_ALL && pir.key.userId != userId) { 4925 // Different user, skip it. 4926 continue; 4927 } 4928 if (!pir.key.packageName.equals(name)) { 4929 // Different package, skip it. 4930 continue; 4931 } 4932 } 4933 if (!doit) { 4934 return true; 4935 } 4936 didSomething = true; 4937 it.remove(); 4938 pir.canceled = true; 4939 if (pir.key.activity != null) { 4940 pir.key.activity.pendingResults.remove(pir.ref); 4941 } 4942 } 4943 } 4944 } 4945 4946 if (doit) { 4947 if (purgeCache && name != null) { 4948 AttributeCache ac = AttributeCache.instance(); 4949 if (ac != null) { 4950 ac.removePackage(name); 4951 } 4952 } 4953 if (mBooted) { 4954 mStackSupervisor.resumeTopActivitiesLocked(); 4955 mStackSupervisor.scheduleIdleLocked(); 4956 } 4957 } 4958 4959 return didSomething; 4960 } 4961 4962 private final boolean removeProcessLocked(ProcessRecord app, 4963 boolean callerWillRestart, boolean allowRestart, String reason) { 4964 final String name = app.processName; 4965 final int uid = app.uid; 4966 if (DEBUG_PROCESSES) Slog.d( 4967 TAG, "Force removing proc " + app.toShortString() + " (" + name 4968 + "/" + uid + ")"); 4969 4970 mProcessNames.remove(name, uid); 4971 mIsolatedProcesses.remove(app.uid); 4972 if (mHeavyWeightProcess == app) { 4973 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 4974 mHeavyWeightProcess.userId, 0)); 4975 mHeavyWeightProcess = null; 4976 } 4977 boolean needRestart = false; 4978 if (app.pid > 0 && app.pid != MY_PID) { 4979 int pid = app.pid; 4980 synchronized (mPidsSelfLocked) { 4981 mPidsSelfLocked.remove(pid); 4982 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 4983 } 4984 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH, 4985 app.processName, app.info.uid); 4986 if (app.isolated) { 4987 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 4988 } 4989 killUnneededProcessLocked(app, reason); 4990 handleAppDiedLocked(app, true, allowRestart); 4991 removeLruProcessLocked(app); 4992 4993 if (app.persistent && !app.isolated) { 4994 if (!callerWillRestart) { 4995 addAppLocked(app.info, false); 4996 } else { 4997 needRestart = true; 4998 } 4999 } 5000 } else { 5001 mRemovedProcesses.add(app); 5002 } 5003 5004 return needRestart; 5005 } 5006 5007 private final void processStartTimedOutLocked(ProcessRecord app) { 5008 final int pid = app.pid; 5009 boolean gone = false; 5010 synchronized (mPidsSelfLocked) { 5011 ProcessRecord knownApp = mPidsSelfLocked.get(pid); 5012 if (knownApp != null && knownApp.thread == null) { 5013 mPidsSelfLocked.remove(pid); 5014 gone = true; 5015 } 5016 } 5017 5018 if (gone) { 5019 Slog.w(TAG, "Process " + app + " failed to attach"); 5020 EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId, 5021 pid, app.uid, app.processName); 5022 mProcessNames.remove(app.processName, app.uid); 5023 mIsolatedProcesses.remove(app.uid); 5024 if (mHeavyWeightProcess == app) { 5025 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 5026 mHeavyWeightProcess.userId, 0)); 5027 mHeavyWeightProcess = null; 5028 } 5029 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH, 5030 app.processName, app.info.uid); 5031 if (app.isolated) { 5032 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 5033 } 5034 // Take care of any launching providers waiting for this process. 5035 checkAppInLaunchingProvidersLocked(app, true); 5036 // Take care of any services that are waiting for the process. 5037 mServices.processStartTimedOutLocked(app); 5038 killUnneededProcessLocked(app, "start timeout"); 5039 if (mBackupTarget != null && mBackupTarget.app.pid == pid) { 5040 Slog.w(TAG, "Unattached app died before backup, skipping"); 5041 try { 5042 IBackupManager bm = IBackupManager.Stub.asInterface( 5043 ServiceManager.getService(Context.BACKUP_SERVICE)); 5044 bm.agentDisconnected(app.info.packageName); 5045 } catch (RemoteException e) { 5046 // Can't happen; the backup manager is local 5047 } 5048 } 5049 if (isPendingBroadcastProcessLocked(pid)) { 5050 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 5051 skipPendingBroadcastLocked(pid); 5052 } 5053 } else { 5054 Slog.w(TAG, "Spurious process start timeout - pid not known for " + app); 5055 } 5056 } 5057 5058 private final boolean attachApplicationLocked(IApplicationThread thread, 5059 int pid) { 5060 5061 // Find the application record that is being attached... either via 5062 // the pid if we are running in multiple processes, or just pull the 5063 // next app record if we are emulating process with anonymous threads. 5064 ProcessRecord app; 5065 if (pid != MY_PID && pid >= 0) { 5066 synchronized (mPidsSelfLocked) { 5067 app = mPidsSelfLocked.get(pid); 5068 } 5069 } else { 5070 app = null; 5071 } 5072 5073 if (app == null) { 5074 Slog.w(TAG, "No pending application record for pid " + pid 5075 + " (IApplicationThread " + thread + "); dropping process"); 5076 EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid); 5077 if (pid > 0 && pid != MY_PID) { 5078 Process.killProcessQuiet(pid); 5079 } else { 5080 try { 5081 thread.scheduleExit(); 5082 } catch (Exception e) { 5083 // Ignore exceptions. 5084 } 5085 } 5086 return false; 5087 } 5088 5089 // If this application record is still attached to a previous 5090 // process, clean it up now. 5091 if (app.thread != null) { 5092 handleAppDiedLocked(app, true, true); 5093 } 5094 5095 // Tell the process all about itself. 5096 5097 if (localLOGV) Slog.v( 5098 TAG, "Binding process pid " + pid + " to record " + app); 5099 5100 final String processName = app.processName; 5101 try { 5102 AppDeathRecipient adr = new AppDeathRecipient( 5103 app, pid, thread); 5104 thread.asBinder().linkToDeath(adr, 0); 5105 app.deathRecipient = adr; 5106 } catch (RemoteException e) { 5107 app.resetPackageList(mProcessStats); 5108 startProcessLocked(app, "link fail", processName); 5109 return false; 5110 } 5111 5112 EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName); 5113 5114 app.makeActive(thread, mProcessStats); 5115 app.curAdj = app.setAdj = -100; 5116 app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT; 5117 app.forcingToForeground = null; 5118 updateProcessForegroundLocked(app, false, false); 5119 app.hasShownUi = false; 5120 app.debugging = false; 5121 app.cached = false; 5122 5123 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 5124 5125 boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info); 5126 List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null; 5127 5128 if (!normalMode) { 5129 Slog.i(TAG, "Launching preboot mode app: " + app); 5130 } 5131 5132 if (localLOGV) Slog.v( 5133 TAG, "New app record " + app 5134 + " thread=" + thread.asBinder() + " pid=" + pid); 5135 try { 5136 int testMode = IApplicationThread.DEBUG_OFF; 5137 if (mDebugApp != null && mDebugApp.equals(processName)) { 5138 testMode = mWaitForDebugger 5139 ? IApplicationThread.DEBUG_WAIT 5140 : IApplicationThread.DEBUG_ON; 5141 app.debugging = true; 5142 if (mDebugTransient) { 5143 mDebugApp = mOrigDebugApp; 5144 mWaitForDebugger = mOrigWaitForDebugger; 5145 } 5146 } 5147 String profileFile = app.instrumentationProfileFile; 5148 ParcelFileDescriptor profileFd = null; 5149 boolean profileAutoStop = false; 5150 if (mProfileApp != null && mProfileApp.equals(processName)) { 5151 mProfileProc = app; 5152 profileFile = mProfileFile; 5153 profileFd = mProfileFd; 5154 profileAutoStop = mAutoStopProfiler; 5155 } 5156 boolean enableOpenGlTrace = false; 5157 if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) { 5158 enableOpenGlTrace = true; 5159 mOpenGlTraceApp = null; 5160 } 5161 5162 // If the app is being launched for restore or full backup, set it up specially 5163 boolean isRestrictedBackupMode = false; 5164 if (mBackupTarget != null && mBackupAppName.equals(processName)) { 5165 isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE) 5166 || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL) 5167 || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL); 5168 } 5169 5170 ensurePackageDexOpt(app.instrumentationInfo != null 5171 ? app.instrumentationInfo.packageName 5172 : app.info.packageName); 5173 if (app.instrumentationClass != null) { 5174 ensurePackageDexOpt(app.instrumentationClass.getPackageName()); 5175 } 5176 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc " 5177 + processName + " with config " + mConfiguration); 5178 ApplicationInfo appInfo = app.instrumentationInfo != null 5179 ? app.instrumentationInfo : app.info; 5180 app.compat = compatibilityInfoForPackageLocked(appInfo); 5181 if (profileFd != null) { 5182 profileFd = profileFd.dup(); 5183 } 5184 thread.bindApplication(processName, appInfo, providers, 5185 app.instrumentationClass, profileFile, profileFd, profileAutoStop, 5186 app.instrumentationArguments, app.instrumentationWatcher, 5187 app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace, 5188 isRestrictedBackupMode || !normalMode, app.persistent, 5189 new Configuration(mConfiguration), app.compat, getCommonServicesLocked(), 5190 mCoreSettingsObserver.getCoreSettingsLocked()); 5191 updateLruProcessLocked(app, false, null); 5192 app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis(); 5193 } catch (Exception e) { 5194 // todo: Yikes! What should we do? For now we will try to 5195 // start another process, but that could easily get us in 5196 // an infinite loop of restarting processes... 5197 Slog.w(TAG, "Exception thrown during bind!", e); 5198 5199 app.resetPackageList(mProcessStats); 5200 app.unlinkDeathRecipient(); 5201 startProcessLocked(app, "bind fail", processName); 5202 return false; 5203 } 5204 5205 // Remove this record from the list of starting applications. 5206 mPersistentStartingProcesses.remove(app); 5207 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 5208 "Attach application locked removing on hold: " + app); 5209 mProcessesOnHold.remove(app); 5210 5211 boolean badApp = false; 5212 boolean didSomething = false; 5213 5214 // See if the top visible activity is waiting to run in this process... 5215 if (normalMode) { 5216 try { 5217 if (mStackSupervisor.attachApplicationLocked(app)) { 5218 didSomething = true; 5219 } 5220 } catch (Exception e) { 5221 badApp = true; 5222 } 5223 } 5224 5225 // Find any services that should be running in this process... 5226 if (!badApp) { 5227 try { 5228 didSomething |= mServices.attachApplicationLocked(app, processName); 5229 } catch (Exception e) { 5230 badApp = true; 5231 } 5232 } 5233 5234 // Check if a next-broadcast receiver is in this process... 5235 if (!badApp && isPendingBroadcastProcessLocked(pid)) { 5236 try { 5237 didSomething |= sendPendingBroadcastsLocked(app); 5238 } catch (Exception e) { 5239 // If the app died trying to launch the receiver we declare it 'bad' 5240 badApp = true; 5241 } 5242 } 5243 5244 // Check whether the next backup agent is in this process... 5245 if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) { 5246 if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app); 5247 ensurePackageDexOpt(mBackupTarget.appInfo.packageName); 5248 try { 5249 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo, 5250 compatibilityInfoForPackageLocked(mBackupTarget.appInfo), 5251 mBackupTarget.backupMode); 5252 } catch (Exception e) { 5253 Slog.w(TAG, "Exception scheduling backup agent creation: "); 5254 e.printStackTrace(); 5255 } 5256 } 5257 5258 if (badApp) { 5259 // todo: Also need to kill application to deal with all 5260 // kinds of exceptions. 5261 handleAppDiedLocked(app, false, true); 5262 return false; 5263 } 5264 5265 if (!didSomething) { 5266 updateOomAdjLocked(); 5267 } 5268 5269 return true; 5270 } 5271 5272 @Override 5273 public final void attachApplication(IApplicationThread thread) { 5274 synchronized (this) { 5275 int callingPid = Binder.getCallingPid(); 5276 final long origId = Binder.clearCallingIdentity(); 5277 attachApplicationLocked(thread, callingPid); 5278 Binder.restoreCallingIdentity(origId); 5279 } 5280 } 5281 5282 @Override 5283 public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) { 5284 final long origId = Binder.clearCallingIdentity(); 5285 synchronized (this) { 5286 ActivityStack stack = ActivityRecord.getStackLocked(token); 5287 if (stack != null) { 5288 ActivityRecord r = 5289 mStackSupervisor.activityIdleInternalLocked(token, false, config); 5290 if (stopProfiling) { 5291 if ((mProfileProc == r.app) && (mProfileFd != null)) { 5292 try { 5293 mProfileFd.close(); 5294 } catch (IOException e) { 5295 } 5296 clearProfilerLocked(); 5297 } 5298 } 5299 } 5300 } 5301 Binder.restoreCallingIdentity(origId); 5302 } 5303 5304 void enableScreenAfterBoot() { 5305 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN, 5306 SystemClock.uptimeMillis()); 5307 mWindowManager.enableScreenAfterBoot(); 5308 5309 synchronized (this) { 5310 updateEventDispatchingLocked(); 5311 } 5312 } 5313 5314 @Override 5315 public void showBootMessage(final CharSequence msg, final boolean always) { 5316 enforceNotIsolatedCaller("showBootMessage"); 5317 mWindowManager.showBootMessage(msg, always); 5318 } 5319 5320 @Override 5321 public void dismissKeyguardOnNextActivity() { 5322 enforceNotIsolatedCaller("dismissKeyguardOnNextActivity"); 5323 final long token = Binder.clearCallingIdentity(); 5324 try { 5325 synchronized (this) { 5326 if (DEBUG_LOCKSCREEN) logLockScreen(""); 5327 if (mLockScreenShown) { 5328 mLockScreenShown = false; 5329 comeOutOfSleepIfNeededLocked(); 5330 } 5331 mStackSupervisor.setDismissKeyguard(true); 5332 } 5333 } finally { 5334 Binder.restoreCallingIdentity(token); 5335 } 5336 } 5337 5338 final void finishBooting() { 5339 // Register receivers to handle package update events 5340 mPackageMonitor.register(mContext, Looper.getMainLooper(), false); 5341 5342 synchronized (this) { 5343 // Ensure that any processes we had put on hold are now started 5344 // up. 5345 final int NP = mProcessesOnHold.size(); 5346 if (NP > 0) { 5347 ArrayList<ProcessRecord> procs = 5348 new ArrayList<ProcessRecord>(mProcessesOnHold); 5349 for (int ip=0; ip<NP; ip++) { 5350 if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: " 5351 + procs.get(ip)); 5352 startProcessLocked(procs.get(ip), "on-hold", null); 5353 } 5354 } 5355 5356 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 5357 // Start looking for apps that are abusing wake locks. 5358 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 5359 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 5360 // Tell anyone interested that we are done booting! 5361 SystemProperties.set("sys.boot_completed", "1"); 5362 SystemProperties.set("dev.bootcomplete", "1"); 5363 for (int i=0; i<mStartedUsers.size(); i++) { 5364 UserStartedState uss = mStartedUsers.valueAt(i); 5365 if (uss.mState == UserStartedState.STATE_BOOTING) { 5366 uss.mState = UserStartedState.STATE_RUNNING; 5367 final int userId = mStartedUsers.keyAt(i); 5368 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 5369 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 5370 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT); 5371 broadcastIntentLocked(null, null, intent, null, 5372 new IIntentReceiver.Stub() { 5373 @Override 5374 public void performReceive(Intent intent, int resultCode, 5375 String data, Bundle extras, boolean ordered, 5376 boolean sticky, int sendingUser) { 5377 synchronized (ActivityManagerService.this) { 5378 requestPssAllProcsLocked(SystemClock.uptimeMillis(), 5379 true, false); 5380 } 5381 } 5382 }, 5383 0, null, null, 5384 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, 5385 AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID, 5386 userId); 5387 } 5388 } 5389 scheduleStartProfilesLocked(); 5390 } 5391 } 5392 } 5393 5394 final void ensureBootCompleted() { 5395 boolean booting; 5396 boolean enableScreen; 5397 synchronized (this) { 5398 booting = mBooting; 5399 mBooting = false; 5400 enableScreen = !mBooted; 5401 mBooted = true; 5402 } 5403 5404 if (booting) { 5405 finishBooting(); 5406 } 5407 5408 if (enableScreen) { 5409 enableScreenAfterBoot(); 5410 } 5411 } 5412 5413 @Override 5414 public final void activityResumed(IBinder token) { 5415 final long origId = Binder.clearCallingIdentity(); 5416 synchronized(this) { 5417 ActivityStack stack = ActivityRecord.getStackLocked(token); 5418 if (stack != null) { 5419 ActivityRecord.activityResumedLocked(token); 5420 } 5421 } 5422 Binder.restoreCallingIdentity(origId); 5423 } 5424 5425 @Override 5426 public final void activityPaused(IBinder token, PersistableBundle persistentState) { 5427 final long origId = Binder.clearCallingIdentity(); 5428 synchronized(this) { 5429 ActivityStack stack = ActivityRecord.getStackLocked(token); 5430 if (stack != null) { 5431 stack.activityPausedLocked(token, false, persistentState); 5432 } 5433 } 5434 Binder.restoreCallingIdentity(origId); 5435 } 5436 5437 @Override 5438 public final void activityStopped(IBinder token, Bundle icicle, 5439 PersistableBundle persistentState, CharSequence description) { 5440 if (localLOGV) Slog.v(TAG, "Activity stopped: token=" + token); 5441 5442 // Refuse possible leaked file descriptors 5443 if (icicle != null && icicle.hasFileDescriptors()) { 5444 throw new IllegalArgumentException("File descriptors passed in Bundle"); 5445 } 5446 5447 final long origId = Binder.clearCallingIdentity(); 5448 5449 synchronized (this) { 5450 ActivityRecord r = ActivityRecord.isInStackLocked(token); 5451 if (r != null) { 5452 r.task.stack.activityStoppedLocked(r, icicle, persistentState, description); 5453 } 5454 } 5455 5456 trimApplications(); 5457 5458 Binder.restoreCallingIdentity(origId); 5459 } 5460 5461 @Override 5462 public final void activityDestroyed(IBinder token) { 5463 if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token); 5464 synchronized (this) { 5465 ActivityStack stack = ActivityRecord.getStackLocked(token); 5466 if (stack != null) { 5467 stack.activityDestroyedLocked(token); 5468 } 5469 } 5470 } 5471 5472 @Override 5473 public String getCallingPackage(IBinder token) { 5474 synchronized (this) { 5475 ActivityRecord r = getCallingRecordLocked(token); 5476 return r != null ? r.info.packageName : null; 5477 } 5478 } 5479 5480 @Override 5481 public ComponentName getCallingActivity(IBinder token) { 5482 synchronized (this) { 5483 ActivityRecord r = getCallingRecordLocked(token); 5484 return r != null ? r.intent.getComponent() : null; 5485 } 5486 } 5487 5488 private ActivityRecord getCallingRecordLocked(IBinder token) { 5489 ActivityRecord r = ActivityRecord.isInStackLocked(token); 5490 if (r == null) { 5491 return null; 5492 } 5493 return r.resultTo; 5494 } 5495 5496 @Override 5497 public ComponentName getActivityClassForToken(IBinder token) { 5498 synchronized(this) { 5499 ActivityRecord r = ActivityRecord.isInStackLocked(token); 5500 if (r == null) { 5501 return null; 5502 } 5503 return r.intent.getComponent(); 5504 } 5505 } 5506 5507 @Override 5508 public String getPackageForToken(IBinder token) { 5509 synchronized(this) { 5510 ActivityRecord r = ActivityRecord.isInStackLocked(token); 5511 if (r == null) { 5512 return null; 5513 } 5514 return r.packageName; 5515 } 5516 } 5517 5518 @Override 5519 public IIntentSender getIntentSender(int type, 5520 String packageName, IBinder token, String resultWho, 5521 int requestCode, Intent[] intents, String[] resolvedTypes, 5522 int flags, Bundle options, int userId) { 5523 enforceNotIsolatedCaller("getIntentSender"); 5524 // Refuse possible leaked file descriptors 5525 if (intents != null) { 5526 if (intents.length < 1) { 5527 throw new IllegalArgumentException("Intents array length must be >= 1"); 5528 } 5529 for (int i=0; i<intents.length; i++) { 5530 Intent intent = intents[i]; 5531 if (intent != null) { 5532 if (intent.hasFileDescriptors()) { 5533 throw new IllegalArgumentException("File descriptors passed in Intent"); 5534 } 5535 if (type == ActivityManager.INTENT_SENDER_BROADCAST && 5536 (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 5537 throw new IllegalArgumentException( 5538 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 5539 } 5540 intents[i] = new Intent(intent); 5541 } 5542 } 5543 if (resolvedTypes != null && resolvedTypes.length != intents.length) { 5544 throw new IllegalArgumentException( 5545 "Intent array length does not match resolvedTypes length"); 5546 } 5547 } 5548 if (options != null) { 5549 if (options.hasFileDescriptors()) { 5550 throw new IllegalArgumentException("File descriptors passed in options"); 5551 } 5552 } 5553 5554 synchronized(this) { 5555 int callingUid = Binder.getCallingUid(); 5556 int origUserId = userId; 5557 userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId, 5558 type == ActivityManager.INTENT_SENDER_BROADCAST, false, 5559 "getIntentSender", null); 5560 if (origUserId == UserHandle.USER_CURRENT) { 5561 // We don't want to evaluate this until the pending intent is 5562 // actually executed. However, we do want to always do the 5563 // security checking for it above. 5564 userId = UserHandle.USER_CURRENT; 5565 } 5566 try { 5567 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 5568 int uid = AppGlobals.getPackageManager() 5569 .getPackageUid(packageName, UserHandle.getUserId(callingUid)); 5570 if (!UserHandle.isSameApp(callingUid, uid)) { 5571 String msg = "Permission Denial: getIntentSender() from pid=" 5572 + Binder.getCallingPid() 5573 + ", uid=" + Binder.getCallingUid() 5574 + ", (need uid=" + uid + ")" 5575 + " is not allowed to send as package " + packageName; 5576 Slog.w(TAG, msg); 5577 throw new SecurityException(msg); 5578 } 5579 } 5580 5581 return getIntentSenderLocked(type, packageName, callingUid, userId, 5582 token, resultWho, requestCode, intents, resolvedTypes, flags, options); 5583 5584 } catch (RemoteException e) { 5585 throw new SecurityException(e); 5586 } 5587 } 5588 } 5589 5590 IIntentSender getIntentSenderLocked(int type, String packageName, 5591 int callingUid, int userId, IBinder token, String resultWho, 5592 int requestCode, Intent[] intents, String[] resolvedTypes, int flags, 5593 Bundle options) { 5594 if (DEBUG_MU) 5595 Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid); 5596 ActivityRecord activity = null; 5597 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 5598 activity = ActivityRecord.isInStackLocked(token); 5599 if (activity == null) { 5600 return null; 5601 } 5602 if (activity.finishing) { 5603 return null; 5604 } 5605 } 5606 5607 final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0; 5608 final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0; 5609 final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0; 5610 flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT 5611 |PendingIntent.FLAG_UPDATE_CURRENT); 5612 5613 PendingIntentRecord.Key key = new PendingIntentRecord.Key( 5614 type, packageName, activity, resultWho, 5615 requestCode, intents, resolvedTypes, flags, options, userId); 5616 WeakReference<PendingIntentRecord> ref; 5617 ref = mIntentSenderRecords.get(key); 5618 PendingIntentRecord rec = ref != null ? ref.get() : null; 5619 if (rec != null) { 5620 if (!cancelCurrent) { 5621 if (updateCurrent) { 5622 if (rec.key.requestIntent != null) { 5623 rec.key.requestIntent.replaceExtras(intents != null ? 5624 intents[intents.length - 1] : null); 5625 } 5626 if (intents != null) { 5627 intents[intents.length-1] = rec.key.requestIntent; 5628 rec.key.allIntents = intents; 5629 rec.key.allResolvedTypes = resolvedTypes; 5630 } else { 5631 rec.key.allIntents = null; 5632 rec.key.allResolvedTypes = null; 5633 } 5634 } 5635 return rec; 5636 } 5637 rec.canceled = true; 5638 mIntentSenderRecords.remove(key); 5639 } 5640 if (noCreate) { 5641 return rec; 5642 } 5643 rec = new PendingIntentRecord(this, key, callingUid); 5644 mIntentSenderRecords.put(key, rec.ref); 5645 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 5646 if (activity.pendingResults == null) { 5647 activity.pendingResults 5648 = new HashSet<WeakReference<PendingIntentRecord>>(); 5649 } 5650 activity.pendingResults.add(rec.ref); 5651 } 5652 return rec; 5653 } 5654 5655 @Override 5656 public void cancelIntentSender(IIntentSender sender) { 5657 if (!(sender instanceof PendingIntentRecord)) { 5658 return; 5659 } 5660 synchronized(this) { 5661 PendingIntentRecord rec = (PendingIntentRecord)sender; 5662 try { 5663 int uid = AppGlobals.getPackageManager() 5664 .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId()); 5665 if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) { 5666 String msg = "Permission Denial: cancelIntentSender() from pid=" 5667 + Binder.getCallingPid() 5668 + ", uid=" + Binder.getCallingUid() 5669 + " is not allowed to cancel packges " 5670 + rec.key.packageName; 5671 Slog.w(TAG, msg); 5672 throw new SecurityException(msg); 5673 } 5674 } catch (RemoteException e) { 5675 throw new SecurityException(e); 5676 } 5677 cancelIntentSenderLocked(rec, true); 5678 } 5679 } 5680 5681 void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) { 5682 rec.canceled = true; 5683 mIntentSenderRecords.remove(rec.key); 5684 if (cleanActivity && rec.key.activity != null) { 5685 rec.key.activity.pendingResults.remove(rec.ref); 5686 } 5687 } 5688 5689 @Override 5690 public String getPackageForIntentSender(IIntentSender pendingResult) { 5691 if (!(pendingResult instanceof PendingIntentRecord)) { 5692 return null; 5693 } 5694 try { 5695 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5696 return res.key.packageName; 5697 } catch (ClassCastException e) { 5698 } 5699 return null; 5700 } 5701 5702 @Override 5703 public int getUidForIntentSender(IIntentSender sender) { 5704 if (sender instanceof PendingIntentRecord) { 5705 try { 5706 PendingIntentRecord res = (PendingIntentRecord)sender; 5707 return res.uid; 5708 } catch (ClassCastException e) { 5709 } 5710 } 5711 return -1; 5712 } 5713 5714 @Override 5715 public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) { 5716 if (!(pendingResult instanceof PendingIntentRecord)) { 5717 return false; 5718 } 5719 try { 5720 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5721 if (res.key.allIntents == null) { 5722 return false; 5723 } 5724 for (int i=0; i<res.key.allIntents.length; i++) { 5725 Intent intent = res.key.allIntents[i]; 5726 if (intent.getPackage() != null && intent.getComponent() != null) { 5727 return false; 5728 } 5729 } 5730 return true; 5731 } catch (ClassCastException e) { 5732 } 5733 return false; 5734 } 5735 5736 @Override 5737 public boolean isIntentSenderAnActivity(IIntentSender pendingResult) { 5738 if (!(pendingResult instanceof PendingIntentRecord)) { 5739 return false; 5740 } 5741 try { 5742 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5743 if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) { 5744 return true; 5745 } 5746 return false; 5747 } catch (ClassCastException e) { 5748 } 5749 return false; 5750 } 5751 5752 @Override 5753 public Intent getIntentForIntentSender(IIntentSender pendingResult) { 5754 if (!(pendingResult instanceof PendingIntentRecord)) { 5755 return null; 5756 } 5757 try { 5758 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5759 return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null; 5760 } catch (ClassCastException e) { 5761 } 5762 return null; 5763 } 5764 5765 @Override 5766 public String getTagForIntentSender(IIntentSender pendingResult, String prefix) { 5767 if (!(pendingResult instanceof PendingIntentRecord)) { 5768 return null; 5769 } 5770 try { 5771 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5772 Intent intent = res.key.requestIntent; 5773 if (intent != null) { 5774 if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null 5775 || res.lastTagPrefix.equals(prefix))) { 5776 return res.lastTag; 5777 } 5778 res.lastTagPrefix = prefix; 5779 StringBuilder sb = new StringBuilder(128); 5780 if (prefix != null) { 5781 sb.append(prefix); 5782 } 5783 if (intent.getAction() != null) { 5784 sb.append(intent.getAction()); 5785 } else if (intent.getComponent() != null) { 5786 intent.getComponent().appendShortString(sb); 5787 } else { 5788 sb.append("?"); 5789 } 5790 return res.lastTag = sb.toString(); 5791 } 5792 } catch (ClassCastException e) { 5793 } 5794 return null; 5795 } 5796 5797 @Override 5798 public void setProcessLimit(int max) { 5799 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 5800 "setProcessLimit()"); 5801 synchronized (this) { 5802 mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max; 5803 mProcessLimitOverride = max; 5804 } 5805 trimApplications(); 5806 } 5807 5808 @Override 5809 public int getProcessLimit() { 5810 synchronized (this) { 5811 return mProcessLimitOverride; 5812 } 5813 } 5814 5815 void foregroundTokenDied(ForegroundToken token) { 5816 synchronized (ActivityManagerService.this) { 5817 synchronized (mPidsSelfLocked) { 5818 ForegroundToken cur 5819 = mForegroundProcesses.get(token.pid); 5820 if (cur != token) { 5821 return; 5822 } 5823 mForegroundProcesses.remove(token.pid); 5824 ProcessRecord pr = mPidsSelfLocked.get(token.pid); 5825 if (pr == null) { 5826 return; 5827 } 5828 pr.forcingToForeground = null; 5829 updateProcessForegroundLocked(pr, false, false); 5830 } 5831 updateOomAdjLocked(); 5832 } 5833 } 5834 5835 @Override 5836 public void setProcessForeground(IBinder token, int pid, boolean isForeground) { 5837 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 5838 "setProcessForeground()"); 5839 synchronized(this) { 5840 boolean changed = false; 5841 5842 synchronized (mPidsSelfLocked) { 5843 ProcessRecord pr = mPidsSelfLocked.get(pid); 5844 if (pr == null && isForeground) { 5845 Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid); 5846 return; 5847 } 5848 ForegroundToken oldToken = mForegroundProcesses.get(pid); 5849 if (oldToken != null) { 5850 oldToken.token.unlinkToDeath(oldToken, 0); 5851 mForegroundProcesses.remove(pid); 5852 if (pr != null) { 5853 pr.forcingToForeground = null; 5854 } 5855 changed = true; 5856 } 5857 if (isForeground && token != null) { 5858 ForegroundToken newToken = new ForegroundToken() { 5859 @Override 5860 public void binderDied() { 5861 foregroundTokenDied(this); 5862 } 5863 }; 5864 newToken.pid = pid; 5865 newToken.token = token; 5866 try { 5867 token.linkToDeath(newToken, 0); 5868 mForegroundProcesses.put(pid, newToken); 5869 pr.forcingToForeground = token; 5870 changed = true; 5871 } catch (RemoteException e) { 5872 // If the process died while doing this, we will later 5873 // do the cleanup with the process death link. 5874 } 5875 } 5876 } 5877 5878 if (changed) { 5879 updateOomAdjLocked(); 5880 } 5881 } 5882 } 5883 5884 // ========================================================= 5885 // PERMISSIONS 5886 // ========================================================= 5887 5888 static class PermissionController extends IPermissionController.Stub { 5889 ActivityManagerService mActivityManagerService; 5890 PermissionController(ActivityManagerService activityManagerService) { 5891 mActivityManagerService = activityManagerService; 5892 } 5893 5894 @Override 5895 public boolean checkPermission(String permission, int pid, int uid) { 5896 return mActivityManagerService.checkPermission(permission, pid, 5897 uid) == PackageManager.PERMISSION_GRANTED; 5898 } 5899 } 5900 5901 class IntentFirewallInterface implements IntentFirewall.AMSInterface { 5902 @Override 5903 public int checkComponentPermission(String permission, int pid, int uid, 5904 int owningUid, boolean exported) { 5905 return ActivityManagerService.this.checkComponentPermission(permission, pid, uid, 5906 owningUid, exported); 5907 } 5908 5909 @Override 5910 public Object getAMSLock() { 5911 return ActivityManagerService.this; 5912 } 5913 } 5914 5915 /** 5916 * This can be called with or without the global lock held. 5917 */ 5918 int checkComponentPermission(String permission, int pid, int uid, 5919 int owningUid, boolean exported) { 5920 // We might be performing an operation on behalf of an indirect binder 5921 // invocation, e.g. via {@link #openContentUri}. Check and adjust the 5922 // client identity accordingly before proceeding. 5923 Identity tlsIdentity = sCallerIdentity.get(); 5924 if (tlsIdentity != null) { 5925 Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {" 5926 + tlsIdentity.pid + "," + tlsIdentity.uid + "}"); 5927 uid = tlsIdentity.uid; 5928 pid = tlsIdentity.pid; 5929 } 5930 5931 if (pid == MY_PID) { 5932 return PackageManager.PERMISSION_GRANTED; 5933 } 5934 5935 return ActivityManager.checkComponentPermission(permission, uid, 5936 owningUid, exported); 5937 } 5938 5939 /** 5940 * As the only public entry point for permissions checking, this method 5941 * can enforce the semantic that requesting a check on a null global 5942 * permission is automatically denied. (Internally a null permission 5943 * string is used when calling {@link #checkComponentPermission} in cases 5944 * when only uid-based security is needed.) 5945 * 5946 * This can be called with or without the global lock held. 5947 */ 5948 @Override 5949 public int checkPermission(String permission, int pid, int uid) { 5950 if (permission == null) { 5951 return PackageManager.PERMISSION_DENIED; 5952 } 5953 return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true); 5954 } 5955 5956 /** 5957 * Binder IPC calls go through the public entry point. 5958 * This can be called with or without the global lock held. 5959 */ 5960 int checkCallingPermission(String permission) { 5961 return checkPermission(permission, 5962 Binder.getCallingPid(), 5963 UserHandle.getAppId(Binder.getCallingUid())); 5964 } 5965 5966 /** 5967 * This can be called with or without the global lock held. 5968 */ 5969 void enforceCallingPermission(String permission, String func) { 5970 if (checkCallingPermission(permission) 5971 == PackageManager.PERMISSION_GRANTED) { 5972 return; 5973 } 5974 5975 String msg = "Permission Denial: " + func + " from pid=" 5976 + Binder.getCallingPid() 5977 + ", uid=" + Binder.getCallingUid() 5978 + " requires " + permission; 5979 Slog.w(TAG, msg); 5980 throw new SecurityException(msg); 5981 } 5982 5983 /** 5984 * Determine if UID is holding permissions required to access {@link Uri} in 5985 * the given {@link ProviderInfo}. Final permission checking is always done 5986 * in {@link ContentProvider}. 5987 */ 5988 private final boolean checkHoldingPermissionsLocked( 5989 IPackageManager pm, ProviderInfo pi, Uri uri, int uid, final int modeFlags) { 5990 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5991 "checkHoldingPermissionsLocked: uri=" + uri + " uid=" + uid); 5992 5993 if (pi.applicationInfo.uid == uid) { 5994 return true; 5995 } else if (!pi.exported) { 5996 return false; 5997 } 5998 5999 boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0; 6000 boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0; 6001 try { 6002 // check if target holds top-level <provider> permissions 6003 if (!readMet && pi.readPermission != null 6004 && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) { 6005 readMet = true; 6006 } 6007 if (!writeMet && pi.writePermission != null 6008 && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) { 6009 writeMet = true; 6010 } 6011 6012 // track if unprotected read/write is allowed; any denied 6013 // <path-permission> below removes this ability 6014 boolean allowDefaultRead = pi.readPermission == null; 6015 boolean allowDefaultWrite = pi.writePermission == null; 6016 6017 // check if target holds any <path-permission> that match uri 6018 final PathPermission[] pps = pi.pathPermissions; 6019 if (pps != null) { 6020 final String path = uri.getPath(); 6021 int i = pps.length; 6022 while (i > 0 && (!readMet || !writeMet)) { 6023 i--; 6024 PathPermission pp = pps[i]; 6025 if (pp.match(path)) { 6026 if (!readMet) { 6027 final String pprperm = pp.getReadPermission(); 6028 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for " 6029 + pprperm + " for " + pp.getPath() 6030 + ": match=" + pp.match(path) 6031 + " check=" + pm.checkUidPermission(pprperm, uid)); 6032 if (pprperm != null) { 6033 if (pm.checkUidPermission(pprperm, uid) == PERMISSION_GRANTED) { 6034 readMet = true; 6035 } else { 6036 allowDefaultRead = false; 6037 } 6038 } 6039 } 6040 if (!writeMet) { 6041 final String ppwperm = pp.getWritePermission(); 6042 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm " 6043 + ppwperm + " for " + pp.getPath() 6044 + ": match=" + pp.match(path) 6045 + " check=" + pm.checkUidPermission(ppwperm, uid)); 6046 if (ppwperm != null) { 6047 if (pm.checkUidPermission(ppwperm, uid) == PERMISSION_GRANTED) { 6048 writeMet = true; 6049 } else { 6050 allowDefaultWrite = false; 6051 } 6052 } 6053 } 6054 } 6055 } 6056 } 6057 6058 // grant unprotected <provider> read/write, if not blocked by 6059 // <path-permission> above 6060 if (allowDefaultRead) readMet = true; 6061 if (allowDefaultWrite) writeMet = true; 6062 6063 } catch (RemoteException e) { 6064 return false; 6065 } 6066 6067 return readMet && writeMet; 6068 } 6069 6070 private ProviderInfo getProviderInfoLocked(String authority, int userHandle) { 6071 ProviderInfo pi = null; 6072 ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle); 6073 if (cpr != null) { 6074 pi = cpr.info; 6075 } else { 6076 try { 6077 pi = AppGlobals.getPackageManager().resolveContentProvider( 6078 authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle); 6079 } catch (RemoteException ex) { 6080 } 6081 } 6082 return pi; 6083 } 6084 6085 private UriPermission findUriPermissionLocked(int targetUid, GrantUri uri) { 6086 final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid); 6087 if (targetUris != null) { 6088 return targetUris.get(uri); 6089 } 6090 return null; 6091 } 6092 6093 private UriPermission findOrCreateUriPermissionLocked(String sourcePkg, 6094 String targetPkg, int targetUid, GrantUri uri) { 6095 ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid); 6096 if (targetUris == null) { 6097 targetUris = Maps.newArrayMap(); 6098 mGrantedUriPermissions.put(targetUid, targetUris); 6099 } 6100 6101 UriPermission perm = targetUris.get(uri); 6102 if (perm == null) { 6103 perm = new UriPermission(sourcePkg, targetPkg, targetUid, uri); 6104 targetUris.put(uri, perm); 6105 } 6106 6107 return perm; 6108 } 6109 6110 private final boolean checkUriPermissionLocked(Uri uri, int uid, final int modeFlags) { 6111 final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0; 6112 final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE 6113 : UriPermission.STRENGTH_OWNED; 6114 6115 // Root gets to do everything. 6116 if (uid == 0) { 6117 return true; 6118 } 6119 6120 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid); 6121 if (perms == null) return false; 6122 6123 // First look for exact match 6124 final UriPermission exactPerm = perms.get(new GrantUri(uri, false)); 6125 if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) { 6126 return true; 6127 } 6128 6129 // No exact match, look for prefixes 6130 final int N = perms.size(); 6131 for (int i = 0; i < N; i++) { 6132 final UriPermission perm = perms.valueAt(i); 6133 if (perm.uri.prefix && uri.isPathPrefixMatch(perm.uri.uri) 6134 && perm.getStrength(modeFlags) >= minStrength) { 6135 return true; 6136 } 6137 } 6138 6139 return false; 6140 } 6141 6142 @Override 6143 public int checkUriPermission(Uri uri, int pid, int uid, final int modeFlags) { 6144 enforceNotIsolatedCaller("checkUriPermission"); 6145 6146 // Another redirected-binder-call permissions check as in 6147 // {@link checkComponentPermission}. 6148 Identity tlsIdentity = sCallerIdentity.get(); 6149 if (tlsIdentity != null) { 6150 uid = tlsIdentity.uid; 6151 pid = tlsIdentity.pid; 6152 } 6153 6154 // Our own process gets to do everything. 6155 if (pid == MY_PID) { 6156 return PackageManager.PERMISSION_GRANTED; 6157 } 6158 synchronized (this) { 6159 return checkUriPermissionLocked(uri, uid, modeFlags) 6160 ? PackageManager.PERMISSION_GRANTED 6161 : PackageManager.PERMISSION_DENIED; 6162 } 6163 } 6164 6165 /** 6166 * Check if the targetPkg can be granted permission to access uri by 6167 * the callingUid using the given modeFlags. Throws a security exception 6168 * if callingUid is not allowed to do this. Returns the uid of the target 6169 * if the URI permission grant should be performed; returns -1 if it is not 6170 * needed (for example targetPkg already has permission to access the URI). 6171 * If you already know the uid of the target, you can supply it in 6172 * lastTargetUid else set that to -1. 6173 */ 6174 int checkGrantUriPermissionLocked(int callingUid, String targetPkg, 6175 Uri uri, final int modeFlags, int lastTargetUid) { 6176 if (!Intent.isAccessUriMode(modeFlags)) { 6177 return -1; 6178 } 6179 6180 if (targetPkg != null) { 6181 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6182 "Checking grant " + targetPkg + " permission to " + uri); 6183 } 6184 6185 final IPackageManager pm = AppGlobals.getPackageManager(); 6186 6187 // If this is not a content: uri, we can't do anything with it. 6188 if (!ContentResolver.SCHEME_CONTENT.equals(uri.getScheme())) { 6189 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6190 "Can't grant URI permission for non-content URI: " + uri); 6191 return -1; 6192 } 6193 6194 final String authority = uri.getAuthority(); 6195 final ProviderInfo pi = getProviderInfoLocked(authority, UserHandle.getUserId(callingUid)); 6196 if (pi == null) { 6197 Slog.w(TAG, "No content provider found for permission check: " + uri.toSafeString()); 6198 return -1; 6199 } 6200 6201 int targetUid = lastTargetUid; 6202 if (targetUid < 0 && targetPkg != null) { 6203 try { 6204 targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid)); 6205 if (targetUid < 0) { 6206 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6207 "Can't grant URI permission no uid for: " + targetPkg); 6208 return -1; 6209 } 6210 } catch (RemoteException ex) { 6211 return -1; 6212 } 6213 } 6214 6215 if (targetUid >= 0) { 6216 // First... does the target actually need this permission? 6217 if (checkHoldingPermissionsLocked(pm, pi, uri, targetUid, modeFlags)) { 6218 // No need to grant the target this permission. 6219 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6220 "Target " + targetPkg + " already has full permission to " + uri); 6221 return -1; 6222 } 6223 } else { 6224 // First... there is no target package, so can anyone access it? 6225 boolean allowed = pi.exported; 6226 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) { 6227 if (pi.readPermission != null) { 6228 allowed = false; 6229 } 6230 } 6231 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) { 6232 if (pi.writePermission != null) { 6233 allowed = false; 6234 } 6235 } 6236 if (allowed) { 6237 return -1; 6238 } 6239 } 6240 6241 // Second... is the provider allowing granting of URI permissions? 6242 if (!pi.grantUriPermissions) { 6243 throw new SecurityException("Provider " + pi.packageName 6244 + "/" + pi.name 6245 + " does not allow granting of Uri permissions (uri " 6246 + uri + ")"); 6247 } 6248 if (pi.uriPermissionPatterns != null) { 6249 final int N = pi.uriPermissionPatterns.length; 6250 boolean allowed = false; 6251 for (int i=0; i<N; i++) { 6252 if (pi.uriPermissionPatterns[i] != null 6253 && pi.uriPermissionPatterns[i].match(uri.getPath())) { 6254 allowed = true; 6255 break; 6256 } 6257 } 6258 if (!allowed) { 6259 throw new SecurityException("Provider " + pi.packageName 6260 + "/" + pi.name 6261 + " does not allow granting of permission to path of Uri " 6262 + uri); 6263 } 6264 } 6265 6266 // Third... does the caller itself have permission to access 6267 // this uri? 6268 if (callingUid != Process.myUid()) { 6269 if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) { 6270 // Require they hold a strong enough Uri permission 6271 if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) { 6272 throw new SecurityException("Uid " + callingUid 6273 + " does not have permission to uri " + uri); 6274 } 6275 } 6276 } 6277 6278 return targetUid; 6279 } 6280 6281 @Override 6282 public int checkGrantUriPermission(int callingUid, String targetPkg, 6283 Uri uri, final int modeFlags) { 6284 enforceNotIsolatedCaller("checkGrantUriPermission"); 6285 synchronized(this) { 6286 return checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1); 6287 } 6288 } 6289 6290 void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, Uri uri, 6291 final int modeFlags, UriPermissionOwner owner) { 6292 if (!Intent.isAccessUriMode(modeFlags)) { 6293 return; 6294 } 6295 6296 // So here we are: the caller has the assumed permission 6297 // to the uri, and the target doesn't. Let's now give this to 6298 // the target. 6299 6300 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6301 "Granting " + targetPkg + "/" + targetUid + " permission to " + uri); 6302 6303 final String authority = uri.getAuthority(); 6304 final ProviderInfo pi = getProviderInfoLocked(authority, UserHandle.getUserId(targetUid)); 6305 if (pi == null) { 6306 Slog.w(TAG, "No content provider found for grant: " + uri.toSafeString()); 6307 return; 6308 } 6309 6310 final boolean prefix = (modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0; 6311 final UriPermission perm = findOrCreateUriPermissionLocked( 6312 pi.packageName, targetPkg, targetUid, new GrantUri(uri, prefix)); 6313 perm.grantModes(modeFlags, owner); 6314 } 6315 6316 void grantUriPermissionLocked(int callingUid, String targetPkg, Uri uri, 6317 final int modeFlags, UriPermissionOwner owner) { 6318 if (targetPkg == null) { 6319 throw new NullPointerException("targetPkg"); 6320 } 6321 6322 int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1); 6323 if (targetUid < 0) { 6324 return; 6325 } 6326 6327 grantUriPermissionUncheckedLocked(targetUid, targetPkg, uri, modeFlags, owner); 6328 } 6329 6330 static class NeededUriGrants extends ArrayList<Uri> { 6331 final String targetPkg; 6332 final int targetUid; 6333 final int flags; 6334 6335 NeededUriGrants(String targetPkg, int targetUid, int flags) { 6336 this.targetPkg = targetPkg; 6337 this.targetUid = targetUid; 6338 this.flags = flags; 6339 } 6340 } 6341 6342 /** 6343 * Like checkGrantUriPermissionLocked, but takes an Intent. 6344 */ 6345 NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid, 6346 String targetPkg, Intent intent, int mode, NeededUriGrants needed) { 6347 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6348 "Checking URI perm to data=" + (intent != null ? intent.getData() : null) 6349 + " clip=" + (intent != null ? intent.getClipData() : null) 6350 + " from " + intent + "; flags=0x" 6351 + Integer.toHexString(intent != null ? intent.getFlags() : 0)); 6352 6353 if (targetPkg == null) { 6354 throw new NullPointerException("targetPkg"); 6355 } 6356 6357 if (intent == null) { 6358 return null; 6359 } 6360 Uri data = intent.getData(); 6361 ClipData clip = intent.getClipData(); 6362 if (data == null && clip == null) { 6363 return null; 6364 } 6365 6366 if (data != null) { 6367 int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, data, 6368 mode, needed != null ? needed.targetUid : -1); 6369 if (targetUid > 0) { 6370 if (needed == null) { 6371 needed = new NeededUriGrants(targetPkg, targetUid, mode); 6372 } 6373 needed.add(data); 6374 } 6375 } 6376 if (clip != null) { 6377 for (int i=0; i<clip.getItemCount(); i++) { 6378 Uri uri = clip.getItemAt(i).getUri(); 6379 if (uri != null) { 6380 int targetUid = -1; 6381 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri, 6382 mode, needed != null ? needed.targetUid : -1); 6383 if (targetUid > 0) { 6384 if (needed == null) { 6385 needed = new NeededUriGrants(targetPkg, targetUid, mode); 6386 } 6387 needed.add(uri); 6388 } 6389 } else { 6390 Intent clipIntent = clip.getItemAt(i).getIntent(); 6391 if (clipIntent != null) { 6392 NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked( 6393 callingUid, targetPkg, clipIntent, mode, needed); 6394 if (newNeeded != null) { 6395 needed = newNeeded; 6396 } 6397 } 6398 } 6399 } 6400 } 6401 6402 return needed; 6403 } 6404 6405 /** 6406 * Like grantUriPermissionUncheckedLocked, but takes an Intent. 6407 */ 6408 void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed, 6409 UriPermissionOwner owner) { 6410 if (needed != null) { 6411 for (int i=0; i<needed.size(); i++) { 6412 grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg, 6413 needed.get(i), needed.flags, owner); 6414 } 6415 } 6416 } 6417 6418 void grantUriPermissionFromIntentLocked(int callingUid, 6419 String targetPkg, Intent intent, UriPermissionOwner owner) { 6420 NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg, 6421 intent, intent != null ? intent.getFlags() : 0, null); 6422 if (needed == null) { 6423 return; 6424 } 6425 6426 grantUriPermissionUncheckedFromIntentLocked(needed, owner); 6427 } 6428 6429 @Override 6430 public void grantUriPermission(IApplicationThread caller, String targetPkg, 6431 Uri uri, final int modeFlags) { 6432 enforceNotIsolatedCaller("grantUriPermission"); 6433 synchronized(this) { 6434 final ProcessRecord r = getRecordForAppLocked(caller); 6435 if (r == null) { 6436 throw new SecurityException("Unable to find app for caller " 6437 + caller 6438 + " when granting permission to uri " + uri); 6439 } 6440 if (targetPkg == null) { 6441 throw new IllegalArgumentException("null target"); 6442 } 6443 if (uri == null) { 6444 throw new IllegalArgumentException("null uri"); 6445 } 6446 6447 Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION 6448 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION 6449 | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION 6450 | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION); 6451 6452 grantUriPermissionLocked(r.uid, targetPkg, uri, modeFlags, null); 6453 } 6454 } 6455 6456 void removeUriPermissionIfNeededLocked(UriPermission perm) { 6457 if (perm.modeFlags == 0) { 6458 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get( 6459 perm.targetUid); 6460 if (perms != null) { 6461 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6462 "Removing " + perm.targetUid + " permission to " + perm.uri); 6463 6464 perms.remove(perm.uri); 6465 if (perms.isEmpty()) { 6466 mGrantedUriPermissions.remove(perm.targetUid); 6467 } 6468 } 6469 } 6470 } 6471 6472 private void revokeUriPermissionLocked(int callingUid, Uri uri, final int modeFlags) { 6473 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + uri); 6474 6475 final IPackageManager pm = AppGlobals.getPackageManager(); 6476 final String authority = uri.getAuthority(); 6477 final ProviderInfo pi = getProviderInfoLocked(authority, UserHandle.getUserId(callingUid)); 6478 if (pi == null) { 6479 Slog.w(TAG, "No content provider found for permission revoke: " + uri.toSafeString()); 6480 return; 6481 } 6482 6483 // Does the caller have this permission on the URI? 6484 if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) { 6485 // Right now, if you are not the original owner of the permission, 6486 // you are not allowed to revoke it. 6487 //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) { 6488 throw new SecurityException("Uid " + callingUid 6489 + " does not have permission to uri " + uri); 6490 //} 6491 } 6492 6493 boolean persistChanged = false; 6494 6495 // Go through all of the permissions and remove any that match. 6496 int N = mGrantedUriPermissions.size(); 6497 for (int i = 0; i < N; i++) { 6498 final int targetUid = mGrantedUriPermissions.keyAt(i); 6499 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 6500 6501 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) { 6502 final UriPermission perm = it.next(); 6503 if (perm.uri.uri.isPathPrefixMatch(uri)) { 6504 if (DEBUG_URI_PERMISSION) 6505 Slog.v(TAG, 6506 "Revoking " + perm.targetUid + " permission to " + perm.uri); 6507 persistChanged |= perm.revokeModes( 6508 modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION); 6509 if (perm.modeFlags == 0) { 6510 it.remove(); 6511 } 6512 } 6513 } 6514 6515 if (perms.isEmpty()) { 6516 mGrantedUriPermissions.remove(targetUid); 6517 N--; 6518 i--; 6519 } 6520 } 6521 6522 if (persistChanged) { 6523 schedulePersistUriGrants(); 6524 } 6525 } 6526 6527 @Override 6528 public void revokeUriPermission(IApplicationThread caller, Uri uri, 6529 final int modeFlags) { 6530 enforceNotIsolatedCaller("revokeUriPermission"); 6531 synchronized(this) { 6532 final ProcessRecord r = getRecordForAppLocked(caller); 6533 if (r == null) { 6534 throw new SecurityException("Unable to find app for caller " 6535 + caller 6536 + " when revoking permission to uri " + uri); 6537 } 6538 if (uri == null) { 6539 Slog.w(TAG, "revokeUriPermission: null uri"); 6540 return; 6541 } 6542 6543 if (!Intent.isAccessUriMode(modeFlags)) { 6544 return; 6545 } 6546 6547 final IPackageManager pm = AppGlobals.getPackageManager(); 6548 final String authority = uri.getAuthority(); 6549 final ProviderInfo pi = getProviderInfoLocked(authority, r.userId); 6550 if (pi == null) { 6551 Slog.w(TAG, "No content provider found for permission revoke: " 6552 + uri.toSafeString()); 6553 return; 6554 } 6555 6556 revokeUriPermissionLocked(r.uid, uri, modeFlags); 6557 } 6558 } 6559 6560 /** 6561 * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the 6562 * given package. 6563 * 6564 * @param packageName Package name to match, or {@code null} to apply to all 6565 * packages. 6566 * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply 6567 * to all users. 6568 * @param persistable If persistable grants should be removed. 6569 */ 6570 private void removeUriPermissionsForPackageLocked( 6571 String packageName, int userHandle, boolean persistable) { 6572 if (userHandle == UserHandle.USER_ALL && packageName == null) { 6573 throw new IllegalArgumentException("Must narrow by either package or user"); 6574 } 6575 6576 boolean persistChanged = false; 6577 6578 int N = mGrantedUriPermissions.size(); 6579 for (int i = 0; i < N; i++) { 6580 final int targetUid = mGrantedUriPermissions.keyAt(i); 6581 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 6582 6583 // Only inspect grants matching user 6584 if (userHandle == UserHandle.USER_ALL 6585 || userHandle == UserHandle.getUserId(targetUid)) { 6586 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) { 6587 final UriPermission perm = it.next(); 6588 6589 // Only inspect grants matching package 6590 if (packageName == null || perm.sourcePkg.equals(packageName) 6591 || perm.targetPkg.equals(packageName)) { 6592 persistChanged |= perm.revokeModes( 6593 persistable ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION); 6594 6595 // Only remove when no modes remain; any persisted grants 6596 // will keep this alive. 6597 if (perm.modeFlags == 0) { 6598 it.remove(); 6599 } 6600 } 6601 } 6602 6603 if (perms.isEmpty()) { 6604 mGrantedUriPermissions.remove(targetUid); 6605 N--; 6606 i--; 6607 } 6608 } 6609 } 6610 6611 if (persistChanged) { 6612 schedulePersistUriGrants(); 6613 } 6614 } 6615 6616 @Override 6617 public IBinder newUriPermissionOwner(String name) { 6618 enforceNotIsolatedCaller("newUriPermissionOwner"); 6619 synchronized(this) { 6620 UriPermissionOwner owner = new UriPermissionOwner(this, name); 6621 return owner.getExternalTokenLocked(); 6622 } 6623 } 6624 6625 @Override 6626 public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, 6627 Uri uri, final int modeFlags) { 6628 synchronized(this) { 6629 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 6630 if (owner == null) { 6631 throw new IllegalArgumentException("Unknown owner: " + token); 6632 } 6633 if (fromUid != Binder.getCallingUid()) { 6634 if (Binder.getCallingUid() != Process.myUid()) { 6635 // Only system code can grant URI permissions on behalf 6636 // of other users. 6637 throw new SecurityException("nice try"); 6638 } 6639 } 6640 if (targetPkg == null) { 6641 throw new IllegalArgumentException("null target"); 6642 } 6643 if (uri == null) { 6644 throw new IllegalArgumentException("null uri"); 6645 } 6646 6647 grantUriPermissionLocked(fromUid, targetPkg, uri, modeFlags, owner); 6648 } 6649 } 6650 6651 @Override 6652 public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode) { 6653 synchronized(this) { 6654 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 6655 if (owner == null) { 6656 throw new IllegalArgumentException("Unknown owner: " + token); 6657 } 6658 6659 if (uri == null) { 6660 owner.removeUriPermissionsLocked(mode); 6661 } else { 6662 owner.removeUriPermissionLocked(uri, mode); 6663 } 6664 } 6665 } 6666 6667 private void schedulePersistUriGrants() { 6668 if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) { 6669 mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG), 6670 10 * DateUtils.SECOND_IN_MILLIS); 6671 } 6672 } 6673 6674 private void writeGrantedUriPermissions() { 6675 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()"); 6676 6677 // Snapshot permissions so we can persist without lock 6678 ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList(); 6679 synchronized (this) { 6680 final int size = mGrantedUriPermissions.size(); 6681 for (int i = 0; i < size; i++) { 6682 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 6683 for (UriPermission perm : perms.values()) { 6684 if (perm.persistedModeFlags != 0) { 6685 persist.add(perm.snapshot()); 6686 } 6687 } 6688 } 6689 } 6690 6691 FileOutputStream fos = null; 6692 try { 6693 fos = mGrantFile.startWrite(); 6694 6695 XmlSerializer out = new FastXmlSerializer(); 6696 out.setOutput(fos, "utf-8"); 6697 out.startDocument(null, true); 6698 out.startTag(null, TAG_URI_GRANTS); 6699 for (UriPermission.Snapshot perm : persist) { 6700 out.startTag(null, TAG_URI_GRANT); 6701 writeIntAttribute(out, ATTR_USER_HANDLE, perm.userHandle); 6702 out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg); 6703 out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg); 6704 out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri)); 6705 writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix); 6706 writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags); 6707 writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime); 6708 out.endTag(null, TAG_URI_GRANT); 6709 } 6710 out.endTag(null, TAG_URI_GRANTS); 6711 out.endDocument(); 6712 6713 mGrantFile.finishWrite(fos); 6714 } catch (IOException e) { 6715 if (fos != null) { 6716 mGrantFile.failWrite(fos); 6717 } 6718 } 6719 } 6720 6721 private void readGrantedUriPermissionsLocked() { 6722 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()"); 6723 6724 final long now = System.currentTimeMillis(); 6725 6726 FileInputStream fis = null; 6727 try { 6728 fis = mGrantFile.openRead(); 6729 final XmlPullParser in = Xml.newPullParser(); 6730 in.setInput(fis, null); 6731 6732 int type; 6733 while ((type = in.next()) != END_DOCUMENT) { 6734 final String tag = in.getName(); 6735 if (type == START_TAG) { 6736 if (TAG_URI_GRANT.equals(tag)) { 6737 final int userHandle = readIntAttribute(in, ATTR_USER_HANDLE); 6738 final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG); 6739 final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG); 6740 final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI)); 6741 final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX); 6742 final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS); 6743 final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now); 6744 6745 // Sanity check that provider still belongs to source package 6746 final ProviderInfo pi = getProviderInfoLocked( 6747 uri.getAuthority(), userHandle); 6748 if (pi != null && sourcePkg.equals(pi.packageName)) { 6749 int targetUid = -1; 6750 try { 6751 targetUid = AppGlobals.getPackageManager() 6752 .getPackageUid(targetPkg, userHandle); 6753 } catch (RemoteException e) { 6754 } 6755 if (targetUid != -1) { 6756 final UriPermission perm = findOrCreateUriPermissionLocked( 6757 sourcePkg, targetPkg, targetUid, new GrantUri(uri, prefix)); 6758 perm.initPersistedModes(modeFlags, createdTime); 6759 } 6760 } else { 6761 Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg 6762 + " but instead found " + pi); 6763 } 6764 } 6765 } 6766 } 6767 } catch (FileNotFoundException e) { 6768 // Missing grants is okay 6769 } catch (IOException e) { 6770 Log.wtf(TAG, "Failed reading Uri grants", e); 6771 } catch (XmlPullParserException e) { 6772 Log.wtf(TAG, "Failed reading Uri grants", e); 6773 } finally { 6774 IoUtils.closeQuietly(fis); 6775 } 6776 } 6777 6778 @Override 6779 public void takePersistableUriPermission(Uri uri, final int modeFlags) { 6780 enforceNotIsolatedCaller("takePersistableUriPermission"); 6781 6782 Preconditions.checkFlagsArgument(modeFlags, 6783 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 6784 6785 synchronized (this) { 6786 final int callingUid = Binder.getCallingUid(); 6787 boolean persistChanged = false; 6788 6789 UriPermission exactPerm = findUriPermissionLocked(callingUid, new GrantUri(uri, false)); 6790 UriPermission prefixPerm = findUriPermissionLocked(callingUid, new GrantUri(uri, true)); 6791 6792 final boolean exactValid = (exactPerm != null) 6793 && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags); 6794 final boolean prefixValid = (prefixPerm != null) 6795 && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags); 6796 6797 if (!(exactValid || prefixValid)) { 6798 throw new SecurityException("No persistable permission grants found for UID " 6799 + callingUid + " and Uri " + uri.toSafeString()); 6800 } 6801 6802 if (exactValid) { 6803 persistChanged |= exactPerm.takePersistableModes(modeFlags); 6804 } 6805 if (prefixValid) { 6806 persistChanged |= prefixPerm.takePersistableModes(modeFlags); 6807 } 6808 6809 persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid); 6810 6811 if (persistChanged) { 6812 schedulePersistUriGrants(); 6813 } 6814 } 6815 } 6816 6817 @Override 6818 public void releasePersistableUriPermission(Uri uri, final int modeFlags) { 6819 enforceNotIsolatedCaller("releasePersistableUriPermission"); 6820 6821 Preconditions.checkFlagsArgument(modeFlags, 6822 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 6823 6824 synchronized (this) { 6825 final int callingUid = Binder.getCallingUid(); 6826 boolean persistChanged = false; 6827 6828 UriPermission exactPerm = findUriPermissionLocked(callingUid, new GrantUri(uri, false)); 6829 UriPermission prefixPerm = findUriPermissionLocked(callingUid, new GrantUri(uri, true)); 6830 if (exactPerm == null && prefixPerm == null) { 6831 throw new SecurityException("No permission grants found for UID " + callingUid 6832 + " and Uri " + uri.toSafeString()); 6833 } 6834 6835 if (exactPerm != null) { 6836 persistChanged |= exactPerm.releasePersistableModes(modeFlags); 6837 removeUriPermissionIfNeededLocked(exactPerm); 6838 } 6839 if (prefixPerm != null) { 6840 persistChanged |= prefixPerm.releasePersistableModes(modeFlags); 6841 removeUriPermissionIfNeededLocked(prefixPerm); 6842 } 6843 6844 if (persistChanged) { 6845 schedulePersistUriGrants(); 6846 } 6847 } 6848 } 6849 6850 /** 6851 * Prune any older {@link UriPermission} for the given UID until outstanding 6852 * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}. 6853 * 6854 * @return if any mutations occured that require persisting. 6855 */ 6856 private boolean maybePrunePersistedUriGrantsLocked(int uid) { 6857 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid); 6858 if (perms == null) return false; 6859 if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false; 6860 6861 final ArrayList<UriPermission> persisted = Lists.newArrayList(); 6862 for (UriPermission perm : perms.values()) { 6863 if (perm.persistedModeFlags != 0) { 6864 persisted.add(perm); 6865 } 6866 } 6867 6868 final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS; 6869 if (trimCount <= 0) return false; 6870 6871 Collections.sort(persisted, new UriPermission.PersistedTimeComparator()); 6872 for (int i = 0; i < trimCount; i++) { 6873 final UriPermission perm = persisted.get(i); 6874 6875 if (DEBUG_URI_PERMISSION) { 6876 Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime); 6877 } 6878 6879 perm.releasePersistableModes(~0); 6880 removeUriPermissionIfNeededLocked(perm); 6881 } 6882 6883 return true; 6884 } 6885 6886 @Override 6887 public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions( 6888 String packageName, boolean incoming) { 6889 enforceNotIsolatedCaller("getPersistedUriPermissions"); 6890 Preconditions.checkNotNull(packageName, "packageName"); 6891 6892 final int callingUid = Binder.getCallingUid(); 6893 final IPackageManager pm = AppGlobals.getPackageManager(); 6894 try { 6895 final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid)); 6896 if (packageUid != callingUid) { 6897 throw new SecurityException( 6898 "Package " + packageName + " does not belong to calling UID " + callingUid); 6899 } 6900 } catch (RemoteException e) { 6901 throw new SecurityException("Failed to verify package name ownership"); 6902 } 6903 6904 final ArrayList<android.content.UriPermission> result = Lists.newArrayList(); 6905 synchronized (this) { 6906 if (incoming) { 6907 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get( 6908 callingUid); 6909 if (perms == null) { 6910 Slog.w(TAG, "No permission grants found for " + packageName); 6911 } else { 6912 for (UriPermission perm : perms.values()) { 6913 if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) { 6914 result.add(perm.buildPersistedPublicApiObject()); 6915 } 6916 } 6917 } 6918 } else { 6919 final int size = mGrantedUriPermissions.size(); 6920 for (int i = 0; i < size; i++) { 6921 final ArrayMap<GrantUri, UriPermission> perms = 6922 mGrantedUriPermissions.valueAt(i); 6923 for (UriPermission perm : perms.values()) { 6924 if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) { 6925 result.add(perm.buildPersistedPublicApiObject()); 6926 } 6927 } 6928 } 6929 } 6930 } 6931 return new ParceledListSlice<android.content.UriPermission>(result); 6932 } 6933 6934 @Override 6935 public void showWaitingForDebugger(IApplicationThread who, boolean waiting) { 6936 synchronized (this) { 6937 ProcessRecord app = 6938 who != null ? getRecordForAppLocked(who) : null; 6939 if (app == null) return; 6940 6941 Message msg = Message.obtain(); 6942 msg.what = WAIT_FOR_DEBUGGER_MSG; 6943 msg.obj = app; 6944 msg.arg1 = waiting ? 1 : 0; 6945 mHandler.sendMessage(msg); 6946 } 6947 } 6948 6949 @Override 6950 public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) { 6951 final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ); 6952 final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ); 6953 outInfo.availMem = Process.getFreeMemory(); 6954 outInfo.totalMem = Process.getTotalMemory(); 6955 outInfo.threshold = homeAppMem; 6956 outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2)); 6957 outInfo.hiddenAppThreshold = cachedAppMem; 6958 outInfo.secondaryServerThreshold = mProcessList.getMemLevel( 6959 ProcessList.SERVICE_ADJ); 6960 outInfo.visibleAppThreshold = mProcessList.getMemLevel( 6961 ProcessList.VISIBLE_APP_ADJ); 6962 outInfo.foregroundAppThreshold = mProcessList.getMemLevel( 6963 ProcessList.FOREGROUND_APP_ADJ); 6964 } 6965 6966 // ========================================================= 6967 // TASK MANAGEMENT 6968 // ========================================================= 6969 6970 @Override 6971 public List<RunningTaskInfo> getTasks(int maxNum, int flags) { 6972 final int callingUid = Binder.getCallingUid(); 6973 ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>(); 6974 6975 synchronized(this) { 6976 if (localLOGV) Slog.v( 6977 TAG, "getTasks: max=" + maxNum + ", flags=" + flags); 6978 6979 final boolean allowed = checkCallingPermission( 6980 android.Manifest.permission.GET_TASKS) 6981 == PackageManager.PERMISSION_GRANTED; 6982 if (!allowed) { 6983 Slog.w(TAG, "getTasks: caller " + callingUid 6984 + " does not hold GET_TASKS; limiting output"); 6985 } 6986 6987 // TODO: Improve with MRU list from all ActivityStacks. 6988 mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed); 6989 } 6990 6991 return list; 6992 } 6993 6994 TaskRecord getMostRecentTask() { 6995 return mRecentTasks.get(0); 6996 } 6997 6998 @Override 6999 public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, 7000 int flags, int userId) { 7001 final int callingUid = Binder.getCallingUid(); 7002 userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId, 7003 false, true, "getRecentTasks", null); 7004 7005 synchronized (this) { 7006 final boolean allowed = checkCallingPermission( 7007 android.Manifest.permission.GET_TASKS) 7008 == PackageManager.PERMISSION_GRANTED; 7009 if (!allowed) { 7010 Slog.w(TAG, "getRecentTasks: caller " + callingUid 7011 + " does not hold GET_TASKS; limiting output"); 7012 } 7013 final boolean detailed = checkCallingPermission( 7014 android.Manifest.permission.GET_DETAILED_TASKS) 7015 == PackageManager.PERMISSION_GRANTED; 7016 7017 IPackageManager pm = AppGlobals.getPackageManager(); 7018 7019 final int N = mRecentTasks.size(); 7020 ArrayList<ActivityManager.RecentTaskInfo> res 7021 = new ArrayList<ActivityManager.RecentTaskInfo>( 7022 maxNum < N ? maxNum : N); 7023 7024 final Set<Integer> includedUsers; 7025 if ((flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0) { 7026 includedUsers = getProfileIdsLocked(userId); 7027 } else { 7028 includedUsers = new HashSet<Integer>(); 7029 } 7030 includedUsers.add(Integer.valueOf(userId)); 7031 for (int i=0; i<N && maxNum > 0; i++) { 7032 TaskRecord tr = mRecentTasks.get(i); 7033 // Only add calling user or related users recent tasks 7034 if (!includedUsers.contains(Integer.valueOf(tr.userId))) continue; 7035 7036 // Return the entry if desired by the caller. We always return 7037 // the first entry, because callers always expect this to be the 7038 // foreground app. We may filter others if the caller has 7039 // not supplied RECENT_WITH_EXCLUDED and there is some reason 7040 // we should exclude the entry. 7041 7042 if (i == 0 7043 || ((flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0) 7044 || (tr.intent == null) 7045 || ((tr.intent.getFlags() 7046 &Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0)) { 7047 if (!allowed) { 7048 // If the caller doesn't have the GET_TASKS permission, then only 7049 // allow them to see a small subset of tasks -- their own and home. 7050 if (!tr.isHomeTask() && tr.creatorUid != callingUid) { 7051 continue; 7052 } 7053 } 7054 ActivityManager.RecentTaskInfo rti 7055 = new ActivityManager.RecentTaskInfo(); 7056 rti.id = tr.numActivities > 0 ? tr.taskId : -1; 7057 rti.persistentId = tr.taskId; 7058 rti.baseIntent = new Intent( 7059 tr.intent != null ? tr.intent : tr.affinityIntent); 7060 if (!detailed) { 7061 rti.baseIntent.replaceExtras((Bundle)null); 7062 } 7063 rti.origActivity = tr.origActivity; 7064 rti.description = tr.lastDescription; 7065 rti.stackId = tr.stack.mStackId; 7066 rti.userId = tr.userId; 7067 7068 // Traverse upwards looking for any break between main task activities and 7069 // utility activities. 7070 final ArrayList<ActivityRecord> activities = tr.mActivities; 7071 int activityNdx; 7072 final int numActivities = activities.size(); 7073 for (activityNdx = Math.min(numActivities, 1); activityNdx < numActivities; 7074 ++activityNdx) { 7075 final ActivityRecord r = activities.get(activityNdx); 7076 if (r.intent != null && 7077 (r.intent.getFlags() & Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET) 7078 != 0) { 7079 break; 7080 } 7081 } 7082 if (activityNdx > 0) { 7083 // Traverse downwards starting below break looking for set label, icon. 7084 // Note that if there are activities in the task but none of them set the 7085 // recent activity values, then we do not fall back to the last set 7086 // values in the TaskRecord. 7087 rti.activityValues = new ActivityManager.RecentsActivityValues(); 7088 for (--activityNdx; activityNdx >= 0; --activityNdx) { 7089 final ActivityRecord r = activities.get(activityNdx); 7090 if (r.activityValues != null) { 7091 if (rti.activityValues.label == null) { 7092 rti.activityValues.label = r.activityValues.label; 7093 tr.lastActivityValues.label = r.activityValues.label; 7094 } 7095 if (rti.activityValues.icon == null) { 7096 rti.activityValues.icon = r.activityValues.icon; 7097 tr.lastActivityValues.icon = r.activityValues.icon; 7098 } 7099 if (rti.activityValues.colorPrimary == 0) { 7100 rti.activityValues.colorPrimary = r.activityValues.colorPrimary; 7101 tr.lastActivityValues.colorPrimary = r.activityValues.colorPrimary; 7102 } 7103 } 7104 } 7105 } else { 7106 // If there are no activity records in this task, then we use the last 7107 // resolved values 7108 rti.activityValues = 7109 new ActivityManager.RecentsActivityValues(tr.lastActivityValues); 7110 } 7111 7112 if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) { 7113 // Check whether this activity is currently available. 7114 try { 7115 if (rti.origActivity != null) { 7116 if (pm.getActivityInfo(rti.origActivity, 0, userId) 7117 == null) { 7118 continue; 7119 } 7120 } else if (rti.baseIntent != null) { 7121 if (pm.queryIntentActivities(rti.baseIntent, 7122 null, 0, userId) == null) { 7123 continue; 7124 } 7125 } 7126 } catch (RemoteException e) { 7127 // Will never happen. 7128 } 7129 } 7130 7131 res.add(rti); 7132 maxNum--; 7133 } 7134 } 7135 return res; 7136 } 7137 } 7138 7139 private TaskRecord recentTaskForIdLocked(int id) { 7140 final int N = mRecentTasks.size(); 7141 for (int i=0; i<N; i++) { 7142 TaskRecord tr = mRecentTasks.get(i); 7143 if (tr.taskId == id) { 7144 return tr; 7145 } 7146 } 7147 return null; 7148 } 7149 7150 @Override 7151 public ActivityManager.TaskThumbnails getTaskThumbnails(int id) { 7152 synchronized (this) { 7153 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER, 7154 "getTaskThumbnails()"); 7155 TaskRecord tr = recentTaskForIdLocked(id); 7156 if (tr != null) { 7157 return tr.getTaskThumbnailsLocked(); 7158 } 7159 } 7160 return null; 7161 } 7162 7163 @Override 7164 public Bitmap getTaskTopThumbnail(int id) { 7165 synchronized (this) { 7166 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER, 7167 "getTaskTopThumbnail()"); 7168 TaskRecord tr = recentTaskForIdLocked(id); 7169 if (tr != null) { 7170 return tr.getTaskTopThumbnailLocked(); 7171 } 7172 } 7173 return null; 7174 } 7175 7176 @Override 7177 public void setRecentsActivityValues(IBinder token, ActivityManager.RecentsActivityValues rav) { 7178 synchronized (this) { 7179 ActivityRecord r = ActivityRecord.isInStackLocked(token); 7180 if (r != null) { 7181 r.activityValues = rav; 7182 } 7183 } 7184 } 7185 7186 @Override 7187 public boolean removeSubTask(int taskId, int subTaskIndex) { 7188 synchronized (this) { 7189 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, 7190 "removeSubTask()"); 7191 long ident = Binder.clearCallingIdentity(); 7192 try { 7193 TaskRecord tr = recentTaskForIdLocked(taskId); 7194 if (tr != null) { 7195 return tr.removeTaskActivitiesLocked(subTaskIndex, true) != null; 7196 } 7197 return false; 7198 } finally { 7199 Binder.restoreCallingIdentity(ident); 7200 } 7201 } 7202 } 7203 7204 private void killUnneededProcessLocked(ProcessRecord pr, String reason) { 7205 if (!pr.killedByAm) { 7206 Slog.i(TAG, "Killing " + pr.toShortString() + " (adj " + pr.setAdj + "): " + reason); 7207 EventLog.writeEvent(EventLogTags.AM_KILL, pr.userId, pr.pid, 7208 pr.processName, pr.setAdj, reason); 7209 pr.killedByAm = true; 7210 Process.killProcessQuiet(pr.pid); 7211 } 7212 } 7213 7214 private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) { 7215 tr.disposeThumbnail(); 7216 mRecentTasks.remove(tr); 7217 final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0; 7218 Intent baseIntent = new Intent( 7219 tr.intent != null ? tr.intent : tr.affinityIntent); 7220 ComponentName component = baseIntent.getComponent(); 7221 if (component == null) { 7222 Slog.w(TAG, "Now component for base intent of task: " + tr); 7223 return; 7224 } 7225 7226 // Find any running services associated with this app. 7227 mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent); 7228 7229 if (killProcesses) { 7230 // Find any running processes associated with this app. 7231 final String pkg = component.getPackageName(); 7232 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 7233 ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap(); 7234 for (int i=0; i<pmap.size(); i++) { 7235 SparseArray<ProcessRecord> uids = pmap.valueAt(i); 7236 for (int j=0; j<uids.size(); j++) { 7237 ProcessRecord proc = uids.valueAt(j); 7238 if (proc.userId != tr.userId) { 7239 continue; 7240 } 7241 if (!proc.pkgList.containsKey(pkg)) { 7242 continue; 7243 } 7244 procs.add(proc); 7245 } 7246 } 7247 7248 // Kill the running processes. 7249 for (int i=0; i<procs.size(); i++) { 7250 ProcessRecord pr = procs.get(i); 7251 if (pr == mHomeProcess) { 7252 // Don't kill the home process along with tasks from the same package. 7253 continue; 7254 } 7255 if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 7256 killUnneededProcessLocked(pr, "remove task"); 7257 } else { 7258 pr.waitingToKill = "remove task"; 7259 } 7260 } 7261 } 7262 } 7263 7264 /** 7265 * Removes the task with the specified task id. 7266 * 7267 * @param taskId Identifier of the task to be removed. 7268 * @param flags Additional operational flags. May be 0 or 7269 * {@link ActivityManager#REMOVE_TASK_KILL_PROCESS}. 7270 * @return Returns true if the given task was found and removed. 7271 */ 7272 private boolean removeTaskByIdLocked(int taskId, int flags) { 7273 TaskRecord tr = recentTaskForIdLocked(taskId); 7274 if (tr != null) { 7275 tr.removeTaskActivitiesLocked(-1, false); 7276 cleanUpRemovedTaskLocked(tr, flags); 7277 return true; 7278 } 7279 return false; 7280 } 7281 7282 @Override 7283 public boolean removeTask(int taskId, int flags) { 7284 synchronized (this) { 7285 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, 7286 "removeTask()"); 7287 long ident = Binder.clearCallingIdentity(); 7288 try { 7289 return removeTaskByIdLocked(taskId, flags); 7290 } finally { 7291 Binder.restoreCallingIdentity(ident); 7292 } 7293 } 7294 } 7295 7296 /** 7297 * TODO: Add mController hook 7298 */ 7299 @Override 7300 public void moveTaskToFront(int taskId, int flags, Bundle options) { 7301 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 7302 "moveTaskToFront()"); 7303 7304 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId); 7305 synchronized(this) { 7306 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 7307 Binder.getCallingUid(), "Task to front")) { 7308 ActivityOptions.abort(options); 7309 return; 7310 } 7311 final long origId = Binder.clearCallingIdentity(); 7312 try { 7313 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId); 7314 if (task == null) { 7315 return; 7316 } 7317 if (mStackSupervisor.isLockTaskModeViolation(task)) { 7318 Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode"); 7319 return; 7320 } 7321 mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options); 7322 } finally { 7323 Binder.restoreCallingIdentity(origId); 7324 } 7325 ActivityOptions.abort(options); 7326 } 7327 } 7328 7329 @Override 7330 public void moveTaskToBack(int taskId) { 7331 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 7332 "moveTaskToBack()"); 7333 7334 synchronized(this) { 7335 TaskRecord tr = recentTaskForIdLocked(taskId); 7336 if (tr != null) { 7337 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr); 7338 ActivityStack stack = tr.stack; 7339 if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) { 7340 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 7341 Binder.getCallingUid(), "Task to back")) { 7342 return; 7343 } 7344 } 7345 final long origId = Binder.clearCallingIdentity(); 7346 try { 7347 stack.moveTaskToBackLocked(taskId, null); 7348 } finally { 7349 Binder.restoreCallingIdentity(origId); 7350 } 7351 } 7352 } 7353 } 7354 7355 /** 7356 * Moves an activity, and all of the other activities within the same task, to the bottom 7357 * of the history stack. The activity's order within the task is unchanged. 7358 * 7359 * @param token A reference to the activity we wish to move 7360 * @param nonRoot If false then this only works if the activity is the root 7361 * of a task; if true it will work for any activity in a task. 7362 * @return Returns true if the move completed, false if not. 7363 */ 7364 @Override 7365 public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) { 7366 enforceNotIsolatedCaller("moveActivityTaskToBack"); 7367 synchronized(this) { 7368 final long origId = Binder.clearCallingIdentity(); 7369 int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot); 7370 if (taskId >= 0) { 7371 return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null); 7372 } 7373 Binder.restoreCallingIdentity(origId); 7374 } 7375 return false; 7376 } 7377 7378 @Override 7379 public void moveTaskBackwards(int task) { 7380 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 7381 "moveTaskBackwards()"); 7382 7383 synchronized(this) { 7384 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 7385 Binder.getCallingUid(), "Task backwards")) { 7386 return; 7387 } 7388 final long origId = Binder.clearCallingIdentity(); 7389 moveTaskBackwardsLocked(task); 7390 Binder.restoreCallingIdentity(origId); 7391 } 7392 } 7393 7394 private final void moveTaskBackwardsLocked(int task) { 7395 Slog.e(TAG, "moveTaskBackwards not yet implemented!"); 7396 } 7397 7398 @Override 7399 public IBinder getHomeActivityToken() throws RemoteException { 7400 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7401 "getHomeActivityToken()"); 7402 synchronized (this) { 7403 return mStackSupervisor.getHomeActivityToken(); 7404 } 7405 } 7406 7407 @Override 7408 public IActivityContainer createActivityContainer(IBinder parentActivityToken, 7409 IActivityContainerCallback callback) throws RemoteException { 7410 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7411 "createActivityContainer()"); 7412 synchronized (this) { 7413 if (parentActivityToken == null) { 7414 throw new IllegalArgumentException("parent token must not be null"); 7415 } 7416 ActivityRecord r = ActivityRecord.forToken(parentActivityToken); 7417 if (r == null) { 7418 return null; 7419 } 7420 if (callback == null) { 7421 throw new IllegalArgumentException("callback must not be null"); 7422 } 7423 return mStackSupervisor.createActivityContainer(r, callback); 7424 } 7425 } 7426 7427 @Override 7428 public void deleteActivityContainer(IActivityContainer container) throws RemoteException { 7429 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7430 "deleteActivityContainer()"); 7431 synchronized (this) { 7432 mStackSupervisor.deleteActivityContainer(container); 7433 } 7434 } 7435 7436 @Override 7437 public IActivityContainer getEnclosingActivityContainer(IBinder activityToken) 7438 throws RemoteException { 7439 synchronized (this) { 7440 ActivityStack stack = ActivityRecord.getStackLocked(activityToken); 7441 if (stack != null) { 7442 return stack.mActivityContainer; 7443 } 7444 return null; 7445 } 7446 } 7447 7448 @Override 7449 public void moveTaskToStack(int taskId, int stackId, boolean toTop) { 7450 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7451 "moveTaskToStack()"); 7452 if (stackId == HOME_STACK_ID) { 7453 Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack", 7454 new RuntimeException("here").fillInStackTrace()); 7455 } 7456 synchronized (this) { 7457 long ident = Binder.clearCallingIdentity(); 7458 try { 7459 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId=" 7460 + stackId + " toTop=" + toTop); 7461 mStackSupervisor.moveTaskToStack(taskId, stackId, toTop); 7462 } finally { 7463 Binder.restoreCallingIdentity(ident); 7464 } 7465 } 7466 } 7467 7468 @Override 7469 public void resizeStack(int stackBoxId, Rect bounds) { 7470 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7471 "resizeStackBox()"); 7472 long ident = Binder.clearCallingIdentity(); 7473 try { 7474 mWindowManager.resizeStack(stackBoxId, bounds); 7475 } finally { 7476 Binder.restoreCallingIdentity(ident); 7477 } 7478 } 7479 7480 @Override 7481 public List<StackInfo> getAllStackInfos() { 7482 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7483 "getAllStackInfos()"); 7484 long ident = Binder.clearCallingIdentity(); 7485 try { 7486 synchronized (this) { 7487 return mStackSupervisor.getAllStackInfosLocked(); 7488 } 7489 } finally { 7490 Binder.restoreCallingIdentity(ident); 7491 } 7492 } 7493 7494 @Override 7495 public StackInfo getStackInfo(int stackId) { 7496 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7497 "getStackInfo()"); 7498 long ident = Binder.clearCallingIdentity(); 7499 try { 7500 synchronized (this) { 7501 return mStackSupervisor.getStackInfoLocked(stackId); 7502 } 7503 } finally { 7504 Binder.restoreCallingIdentity(ident); 7505 } 7506 } 7507 7508 @Override 7509 public boolean isInHomeStack(int taskId) { 7510 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7511 "getStackInfo()"); 7512 long ident = Binder.clearCallingIdentity(); 7513 try { 7514 synchronized (this) { 7515 TaskRecord tr = recentTaskForIdLocked(taskId); 7516 if (tr != null) { 7517 return tr.stack.isHomeStack(); 7518 } 7519 } 7520 } finally { 7521 Binder.restoreCallingIdentity(ident); 7522 } 7523 return false; 7524 } 7525 7526 @Override 7527 public int getTaskForActivity(IBinder token, boolean onlyRoot) { 7528 synchronized(this) { 7529 return ActivityRecord.getTaskForActivityLocked(token, onlyRoot); 7530 } 7531 } 7532 7533 private boolean isLockTaskAuthorized(ComponentName name) { 7534// enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 7535// "startLockTaskMode()"); 7536// DevicePolicyManager dpm = (DevicePolicyManager) 7537// mContext.getSystemService(Context.DEVICE_POLICY_SERVICE); 7538// return dpm != null && dpm.isLockTaskPermitted(name); 7539 return true; 7540 } 7541 7542 private void startLockTaskMode(TaskRecord task) { 7543 if (!isLockTaskAuthorized(task.intent.getComponent())) { 7544 return; 7545 } 7546 long ident = Binder.clearCallingIdentity(); 7547 try { 7548 synchronized (this) { 7549 // Since we lost lock on task, make sure it is still there. 7550 task = mStackSupervisor.anyTaskForIdLocked(task.taskId); 7551 if (task != null) { 7552 mStackSupervisor.setLockTaskModeLocked(task); 7553 } 7554 } 7555 } finally { 7556 Binder.restoreCallingIdentity(ident); 7557 } 7558 } 7559 7560 @Override 7561 public void startLockTaskMode(int taskId) { 7562 long ident = Binder.clearCallingIdentity(); 7563 try { 7564 final TaskRecord task; 7565 synchronized (this) { 7566 task = mStackSupervisor.anyTaskForIdLocked(taskId); 7567 } 7568 if (task != null) { 7569 startLockTaskMode(task); 7570 } 7571 } finally { 7572 Binder.restoreCallingIdentity(ident); 7573 } 7574 } 7575 7576 @Override 7577 public void startLockTaskMode(IBinder token) { 7578 long ident = Binder.clearCallingIdentity(); 7579 try { 7580 final TaskRecord task; 7581 synchronized (this) { 7582 final ActivityRecord r = ActivityRecord.forToken(token); 7583 if (r == null) { 7584 return; 7585 } 7586 task = r.task; 7587 } 7588 if (task != null) { 7589 startLockTaskMode(task); 7590 } 7591 } finally { 7592 Binder.restoreCallingIdentity(ident); 7593 } 7594 } 7595 7596 @Override 7597 public void stopLockTaskMode() { 7598// enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 7599// "stopLockTaskMode()"); 7600 synchronized (this) { 7601 mStackSupervisor.setLockTaskModeLocked(null); 7602 } 7603 } 7604 7605 @Override 7606 public boolean isInLockTaskMode() { 7607 synchronized (this) { 7608 return mStackSupervisor.isInLockTaskMode(); 7609 } 7610 } 7611 7612 // ========================================================= 7613 // CONTENT PROVIDERS 7614 // ========================================================= 7615 7616 private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) { 7617 List<ProviderInfo> providers = null; 7618 try { 7619 providers = AppGlobals.getPackageManager(). 7620 queryContentProviders(app.processName, app.uid, 7621 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS); 7622 } catch (RemoteException ex) { 7623 } 7624 if (DEBUG_MU) 7625 Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid); 7626 int userId = app.userId; 7627 if (providers != null) { 7628 int N = providers.size(); 7629 app.pubProviders.ensureCapacity(N + app.pubProviders.size()); 7630 for (int i=0; i<N; i++) { 7631 ProviderInfo cpi = 7632 (ProviderInfo)providers.get(i); 7633 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo, 7634 cpi.name, cpi.flags); 7635 if (singleton && UserHandle.getUserId(app.uid) != 0) { 7636 // This is a singleton provider, but a user besides the 7637 // default user is asking to initialize a process it runs 7638 // in... well, no, it doesn't actually run in this process, 7639 // it runs in the process of the default user. Get rid of it. 7640 providers.remove(i); 7641 N--; 7642 i--; 7643 continue; 7644 } 7645 7646 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 7647 ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId); 7648 if (cpr == null) { 7649 cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton); 7650 mProviderMap.putProviderByClass(comp, cpr); 7651 } 7652 if (DEBUG_MU) 7653 Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid); 7654 app.pubProviders.put(cpi.name, cpr); 7655 if (!cpi.multiprocess || !"android".equals(cpi.packageName)) { 7656 // Don't add this if it is a platform component that is marked 7657 // to run in multiple processes, because this is actually 7658 // part of the framework so doesn't make sense to track as a 7659 // separate apk in the process. 7660 app.addPackage(cpi.applicationInfo.packageName, mProcessStats); 7661 } 7662 ensurePackageDexOpt(cpi.applicationInfo.packageName); 7663 } 7664 } 7665 return providers; 7666 } 7667 7668 /** 7669 * Check if {@link ProcessRecord} has a possible chance at accessing the 7670 * given {@link ProviderInfo}. Final permission checking is always done 7671 * in {@link ContentProvider}. 7672 */ 7673 private final String checkContentProviderPermissionLocked( 7674 ProviderInfo cpi, ProcessRecord r) { 7675 final int callingPid = (r != null) ? r.pid : Binder.getCallingPid(); 7676 final int callingUid = (r != null) ? r.uid : Binder.getCallingUid(); 7677 if (checkComponentPermission(cpi.readPermission, callingPid, callingUid, 7678 cpi.applicationInfo.uid, cpi.exported) 7679 == PackageManager.PERMISSION_GRANTED) { 7680 return null; 7681 } 7682 if (checkComponentPermission(cpi.writePermission, callingPid, callingUid, 7683 cpi.applicationInfo.uid, cpi.exported) 7684 == PackageManager.PERMISSION_GRANTED) { 7685 return null; 7686 } 7687 7688 PathPermission[] pps = cpi.pathPermissions; 7689 if (pps != null) { 7690 int i = pps.length; 7691 while (i > 0) { 7692 i--; 7693 PathPermission pp = pps[i]; 7694 if (checkComponentPermission(pp.getReadPermission(), callingPid, callingUid, 7695 cpi.applicationInfo.uid, cpi.exported) 7696 == PackageManager.PERMISSION_GRANTED) { 7697 return null; 7698 } 7699 if (checkComponentPermission(pp.getWritePermission(), callingPid, callingUid, 7700 cpi.applicationInfo.uid, cpi.exported) 7701 == PackageManager.PERMISSION_GRANTED) { 7702 return null; 7703 } 7704 } 7705 } 7706 7707 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid); 7708 if (perms != null) { 7709 for (GrantUri uri : perms.keySet()) { 7710 if (uri.uri.getAuthority().equals(cpi.authority)) { 7711 return null; 7712 } 7713 } 7714 } 7715 7716 String msg; 7717 if (!cpi.exported) { 7718 msg = "Permission Denial: opening provider " + cpi.name 7719 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 7720 + ", uid=" + callingUid + ") that is not exported from uid " 7721 + cpi.applicationInfo.uid; 7722 } else { 7723 msg = "Permission Denial: opening provider " + cpi.name 7724 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 7725 + ", uid=" + callingUid + ") requires " 7726 + cpi.readPermission + " or " + cpi.writePermission; 7727 } 7728 Slog.w(TAG, msg); 7729 return msg; 7730 } 7731 7732 ContentProviderConnection incProviderCountLocked(ProcessRecord r, 7733 final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 7734 if (r != null) { 7735 for (int i=0; i<r.conProviders.size(); i++) { 7736 ContentProviderConnection conn = r.conProviders.get(i); 7737 if (conn.provider == cpr) { 7738 if (DEBUG_PROVIDER) Slog.v(TAG, 7739 "Adding provider requested by " 7740 + r.processName + " from process " 7741 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 7742 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 7743 if (stable) { 7744 conn.stableCount++; 7745 conn.numStableIncs++; 7746 } else { 7747 conn.unstableCount++; 7748 conn.numUnstableIncs++; 7749 } 7750 return conn; 7751 } 7752 } 7753 ContentProviderConnection conn = new ContentProviderConnection(cpr, r); 7754 if (stable) { 7755 conn.stableCount = 1; 7756 conn.numStableIncs = 1; 7757 } else { 7758 conn.unstableCount = 1; 7759 conn.numUnstableIncs = 1; 7760 } 7761 cpr.connections.add(conn); 7762 r.conProviders.add(conn); 7763 return conn; 7764 } 7765 cpr.addExternalProcessHandleLocked(externalProcessToken); 7766 return null; 7767 } 7768 7769 boolean decProviderCountLocked(ContentProviderConnection conn, 7770 ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 7771 if (conn != null) { 7772 cpr = conn.provider; 7773 if (DEBUG_PROVIDER) Slog.v(TAG, 7774 "Removing provider requested by " 7775 + conn.client.processName + " from process " 7776 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 7777 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 7778 if (stable) { 7779 conn.stableCount--; 7780 } else { 7781 conn.unstableCount--; 7782 } 7783 if (conn.stableCount == 0 && conn.unstableCount == 0) { 7784 cpr.connections.remove(conn); 7785 conn.client.conProviders.remove(conn); 7786 return true; 7787 } 7788 return false; 7789 } 7790 cpr.removeExternalProcessHandleLocked(externalProcessToken); 7791 return false; 7792 } 7793 7794 private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller, 7795 String name, IBinder token, boolean stable, int userId) { 7796 ContentProviderRecord cpr; 7797 ContentProviderConnection conn = null; 7798 ProviderInfo cpi = null; 7799 7800 synchronized(this) { 7801 ProcessRecord r = null; 7802 if (caller != null) { 7803 r = getRecordForAppLocked(caller); 7804 if (r == null) { 7805 throw new SecurityException( 7806 "Unable to find app for caller " + caller 7807 + " (pid=" + Binder.getCallingPid() 7808 + ") when getting content provider " + name); 7809 } 7810 } 7811 7812 // First check if this content provider has been published... 7813 cpr = mProviderMap.getProviderByName(name, userId); 7814 boolean providerRunning = cpr != null; 7815 if (providerRunning) { 7816 cpi = cpr.info; 7817 String msg; 7818 if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) { 7819 throw new SecurityException(msg); 7820 } 7821 7822 if (r != null && cpr.canRunHere(r)) { 7823 // This provider has been published or is in the process 7824 // of being published... but it is also allowed to run 7825 // in the caller's process, so don't make a connection 7826 // and just let the caller instantiate its own instance. 7827 ContentProviderHolder holder = cpr.newHolder(null); 7828 // don't give caller the provider object, it needs 7829 // to make its own. 7830 holder.provider = null; 7831 return holder; 7832 } 7833 7834 final long origId = Binder.clearCallingIdentity(); 7835 7836 // In this case the provider instance already exists, so we can 7837 // return it right away. 7838 conn = incProviderCountLocked(r, cpr, token, stable); 7839 if (conn != null && (conn.stableCount+conn.unstableCount) == 1) { 7840 if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 7841 // If this is a perceptible app accessing the provider, 7842 // make sure to count it as being accessed and thus 7843 // back up on the LRU list. This is good because 7844 // content providers are often expensive to start. 7845 updateLruProcessLocked(cpr.proc, false, null); 7846 } 7847 } 7848 7849 if (cpr.proc != null) { 7850 if (false) { 7851 if (cpr.name.flattenToShortString().equals( 7852 "com.android.providers.calendar/.CalendarProvider2")) { 7853 Slog.v(TAG, "****************** KILLING " 7854 + cpr.name.flattenToShortString()); 7855 Process.killProcess(cpr.proc.pid); 7856 } 7857 } 7858 boolean success = updateOomAdjLocked(cpr.proc); 7859 if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success); 7860 // NOTE: there is still a race here where a signal could be 7861 // pending on the process even though we managed to update its 7862 // adj level. Not sure what to do about this, but at least 7863 // the race is now smaller. 7864 if (!success) { 7865 // Uh oh... it looks like the provider's process 7866 // has been killed on us. We need to wait for a new 7867 // process to be started, and make sure its death 7868 // doesn't kill our process. 7869 Slog.i(TAG, 7870 "Existing provider " + cpr.name.flattenToShortString() 7871 + " is crashing; detaching " + r); 7872 boolean lastRef = decProviderCountLocked(conn, cpr, token, stable); 7873 appDiedLocked(cpr.proc, cpr.proc.pid, cpr.proc.thread); 7874 if (!lastRef) { 7875 // This wasn't the last ref our process had on 7876 // the provider... we have now been killed, bail. 7877 return null; 7878 } 7879 providerRunning = false; 7880 conn = null; 7881 } 7882 } 7883 7884 Binder.restoreCallingIdentity(origId); 7885 } 7886 7887 boolean singleton; 7888 if (!providerRunning) { 7889 try { 7890 cpi = AppGlobals.getPackageManager(). 7891 resolveContentProvider(name, 7892 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId); 7893 } catch (RemoteException ex) { 7894 } 7895 if (cpi == null) { 7896 return null; 7897 } 7898 singleton = isSingleton(cpi.processName, cpi.applicationInfo, 7899 cpi.name, cpi.flags); 7900 if (singleton) { 7901 userId = 0; 7902 } 7903 cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId); 7904 7905 String msg; 7906 if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) { 7907 throw new SecurityException(msg); 7908 } 7909 7910 if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate 7911 && !cpi.processName.equals("system")) { 7912 // If this content provider does not run in the system 7913 // process, and the system is not yet ready to run other 7914 // processes, then fail fast instead of hanging. 7915 throw new IllegalArgumentException( 7916 "Attempt to launch content provider before system ready"); 7917 } 7918 7919 // Make sure that the user who owns this provider is started. If not, 7920 // we don't want to allow it to run. 7921 if (mStartedUsers.get(userId) == null) { 7922 Slog.w(TAG, "Unable to launch app " 7923 + cpi.applicationInfo.packageName + "/" 7924 + cpi.applicationInfo.uid + " for provider " 7925 + name + ": user " + userId + " is stopped"); 7926 return null; 7927 } 7928 7929 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 7930 cpr = mProviderMap.getProviderByClass(comp, userId); 7931 final boolean firstClass = cpr == null; 7932 if (firstClass) { 7933 try { 7934 ApplicationInfo ai = 7935 AppGlobals.getPackageManager(). 7936 getApplicationInfo( 7937 cpi.applicationInfo.packageName, 7938 STOCK_PM_FLAGS, userId); 7939 if (ai == null) { 7940 Slog.w(TAG, "No package info for content provider " 7941 + cpi.name); 7942 return null; 7943 } 7944 ai = getAppInfoForUser(ai, userId); 7945 cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton); 7946 } catch (RemoteException ex) { 7947 // pm is in same process, this will never happen. 7948 } 7949 } 7950 7951 if (r != null && cpr.canRunHere(r)) { 7952 // If this is a multiprocess provider, then just return its 7953 // info and allow the caller to instantiate it. Only do 7954 // this if the provider is the same user as the caller's 7955 // process, or can run as root (so can be in any process). 7956 return cpr.newHolder(null); 7957 } 7958 7959 if (DEBUG_PROVIDER) { 7960 RuntimeException e = new RuntimeException("here"); 7961 Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null) 7962 + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e); 7963 } 7964 7965 // This is single process, and our app is now connecting to it. 7966 // See if we are already in the process of launching this 7967 // provider. 7968 final int N = mLaunchingProviders.size(); 7969 int i; 7970 for (i=0; i<N; i++) { 7971 if (mLaunchingProviders.get(i) == cpr) { 7972 break; 7973 } 7974 } 7975 7976 // If the provider is not already being launched, then get it 7977 // started. 7978 if (i >= N) { 7979 final long origId = Binder.clearCallingIdentity(); 7980 7981 try { 7982 // Content provider is now in use, its package can't be stopped. 7983 try { 7984 AppGlobals.getPackageManager().setPackageStoppedState( 7985 cpr.appInfo.packageName, false, userId); 7986 } catch (RemoteException e) { 7987 } catch (IllegalArgumentException e) { 7988 Slog.w(TAG, "Failed trying to unstop package " 7989 + cpr.appInfo.packageName + ": " + e); 7990 } 7991 7992 // Use existing process if already started 7993 ProcessRecord proc = getProcessRecordLocked( 7994 cpi.processName, cpr.appInfo.uid, false); 7995 if (proc != null && proc.thread != null) { 7996 if (DEBUG_PROVIDER) { 7997 Slog.d(TAG, "Installing in existing process " + proc); 7998 } 7999 proc.pubProviders.put(cpi.name, cpr); 8000 try { 8001 proc.thread.scheduleInstallProvider(cpi); 8002 } catch (RemoteException e) { 8003 } 8004 } else { 8005 proc = startProcessLocked(cpi.processName, 8006 cpr.appInfo, false, 0, "content provider", 8007 new ComponentName(cpi.applicationInfo.packageName, 8008 cpi.name), false, false, false); 8009 if (proc == null) { 8010 Slog.w(TAG, "Unable to launch app " 8011 + cpi.applicationInfo.packageName + "/" 8012 + cpi.applicationInfo.uid + " for provider " 8013 + name + ": process is bad"); 8014 return null; 8015 } 8016 } 8017 cpr.launchingApp = proc; 8018 mLaunchingProviders.add(cpr); 8019 } finally { 8020 Binder.restoreCallingIdentity(origId); 8021 } 8022 } 8023 8024 // Make sure the provider is published (the same provider class 8025 // may be published under multiple names). 8026 if (firstClass) { 8027 mProviderMap.putProviderByClass(comp, cpr); 8028 } 8029 8030 mProviderMap.putProviderByName(name, cpr); 8031 conn = incProviderCountLocked(r, cpr, token, stable); 8032 if (conn != null) { 8033 conn.waiting = true; 8034 } 8035 } 8036 } 8037 8038 // Wait for the provider to be published... 8039 synchronized (cpr) { 8040 while (cpr.provider == null) { 8041 if (cpr.launchingApp == null) { 8042 Slog.w(TAG, "Unable to launch app " 8043 + cpi.applicationInfo.packageName + "/" 8044 + cpi.applicationInfo.uid + " for provider " 8045 + name + ": launching app became null"); 8046 EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS, 8047 UserHandle.getUserId(cpi.applicationInfo.uid), 8048 cpi.applicationInfo.packageName, 8049 cpi.applicationInfo.uid, name); 8050 return null; 8051 } 8052 try { 8053 if (DEBUG_MU) { 8054 Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp=" 8055 + cpr.launchingApp); 8056 } 8057 if (conn != null) { 8058 conn.waiting = true; 8059 } 8060 cpr.wait(); 8061 } catch (InterruptedException ex) { 8062 } finally { 8063 if (conn != null) { 8064 conn.waiting = false; 8065 } 8066 } 8067 } 8068 } 8069 return cpr != null ? cpr.newHolder(conn) : null; 8070 } 8071 8072 public final ContentProviderHolder getContentProvider( 8073 IApplicationThread caller, String name, int userId, boolean stable) { 8074 enforceNotIsolatedCaller("getContentProvider"); 8075 if (caller == null) { 8076 String msg = "null IApplicationThread when getting content provider " 8077 + name; 8078 Slog.w(TAG, msg); 8079 throw new SecurityException(msg); 8080 } 8081 8082 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 8083 false, true, "getContentProvider", null); 8084 return getContentProviderImpl(caller, name, null, stable, userId); 8085 } 8086 8087 public ContentProviderHolder getContentProviderExternal( 8088 String name, int userId, IBinder token) { 8089 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 8090 "Do not have permission in call getContentProviderExternal()"); 8091 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 8092 false, true, "getContentProvider", null); 8093 return getContentProviderExternalUnchecked(name, token, userId); 8094 } 8095 8096 private ContentProviderHolder getContentProviderExternalUnchecked(String name, 8097 IBinder token, int userId) { 8098 return getContentProviderImpl(null, name, token, true, userId); 8099 } 8100 8101 /** 8102 * Drop a content provider from a ProcessRecord's bookkeeping 8103 */ 8104 public void removeContentProvider(IBinder connection, boolean stable) { 8105 enforceNotIsolatedCaller("removeContentProvider"); 8106 long ident = Binder.clearCallingIdentity(); 8107 try { 8108 synchronized (this) { 8109 ContentProviderConnection conn; 8110 try { 8111 conn = (ContentProviderConnection)connection; 8112 } catch (ClassCastException e) { 8113 String msg ="removeContentProvider: " + connection 8114 + " not a ContentProviderConnection"; 8115 Slog.w(TAG, msg); 8116 throw new IllegalArgumentException(msg); 8117 } 8118 if (conn == null) { 8119 throw new NullPointerException("connection is null"); 8120 } 8121 if (decProviderCountLocked(conn, null, null, stable)) { 8122 updateOomAdjLocked(); 8123 } 8124 } 8125 } finally { 8126 Binder.restoreCallingIdentity(ident); 8127 } 8128 } 8129 8130 public void removeContentProviderExternal(String name, IBinder token) { 8131 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 8132 "Do not have permission in call removeContentProviderExternal()"); 8133 removeContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId()); 8134 } 8135 8136 private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) { 8137 synchronized (this) { 8138 ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId); 8139 if(cpr == null) { 8140 //remove from mProvidersByClass 8141 if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list"); 8142 return; 8143 } 8144 8145 //update content provider record entry info 8146 ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name); 8147 ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId); 8148 if (localCpr.hasExternalProcessHandles()) { 8149 if (localCpr.removeExternalProcessHandleLocked(token)) { 8150 updateOomAdjLocked(); 8151 } else { 8152 Slog.e(TAG, "Attmpt to remove content provider " + localCpr 8153 + " with no external reference for token: " 8154 + token + "."); 8155 } 8156 } else { 8157 Slog.e(TAG, "Attmpt to remove content provider: " + localCpr 8158 + " with no external references."); 8159 } 8160 } 8161 } 8162 8163 public final void publishContentProviders(IApplicationThread caller, 8164 List<ContentProviderHolder> providers) { 8165 if (providers == null) { 8166 return; 8167 } 8168 8169 enforceNotIsolatedCaller("publishContentProviders"); 8170 synchronized (this) { 8171 final ProcessRecord r = getRecordForAppLocked(caller); 8172 if (DEBUG_MU) 8173 Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid); 8174 if (r == null) { 8175 throw new SecurityException( 8176 "Unable to find app for caller " + caller 8177 + " (pid=" + Binder.getCallingPid() 8178 + ") when publishing content providers"); 8179 } 8180 8181 final long origId = Binder.clearCallingIdentity(); 8182 8183 final int N = providers.size(); 8184 for (int i=0; i<N; i++) { 8185 ContentProviderHolder src = providers.get(i); 8186 if (src == null || src.info == null || src.provider == null) { 8187 continue; 8188 } 8189 ContentProviderRecord dst = r.pubProviders.get(src.info.name); 8190 if (DEBUG_MU) 8191 Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid); 8192 if (dst != null) { 8193 ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name); 8194 mProviderMap.putProviderByClass(comp, dst); 8195 String names[] = dst.info.authority.split(";"); 8196 for (int j = 0; j < names.length; j++) { 8197 mProviderMap.putProviderByName(names[j], dst); 8198 } 8199 8200 int NL = mLaunchingProviders.size(); 8201 int j; 8202 for (j=0; j<NL; j++) { 8203 if (mLaunchingProviders.get(j) == dst) { 8204 mLaunchingProviders.remove(j); 8205 j--; 8206 NL--; 8207 } 8208 } 8209 synchronized (dst) { 8210 dst.provider = src.provider; 8211 dst.proc = r; 8212 dst.notifyAll(); 8213 } 8214 updateOomAdjLocked(r); 8215 } 8216 } 8217 8218 Binder.restoreCallingIdentity(origId); 8219 } 8220 } 8221 8222 public boolean refContentProvider(IBinder connection, int stable, int unstable) { 8223 ContentProviderConnection conn; 8224 try { 8225 conn = (ContentProviderConnection)connection; 8226 } catch (ClassCastException e) { 8227 String msg ="refContentProvider: " + connection 8228 + " not a ContentProviderConnection"; 8229 Slog.w(TAG, msg); 8230 throw new IllegalArgumentException(msg); 8231 } 8232 if (conn == null) { 8233 throw new NullPointerException("connection is null"); 8234 } 8235 8236 synchronized (this) { 8237 if (stable > 0) { 8238 conn.numStableIncs += stable; 8239 } 8240 stable = conn.stableCount + stable; 8241 if (stable < 0) { 8242 throw new IllegalStateException("stableCount < 0: " + stable); 8243 } 8244 8245 if (unstable > 0) { 8246 conn.numUnstableIncs += unstable; 8247 } 8248 unstable = conn.unstableCount + unstable; 8249 if (unstable < 0) { 8250 throw new IllegalStateException("unstableCount < 0: " + unstable); 8251 } 8252 8253 if ((stable+unstable) <= 0) { 8254 throw new IllegalStateException("ref counts can't go to zero here: stable=" 8255 + stable + " unstable=" + unstable); 8256 } 8257 conn.stableCount = stable; 8258 conn.unstableCount = unstable; 8259 return !conn.dead; 8260 } 8261 } 8262 8263 public void unstableProviderDied(IBinder connection) { 8264 ContentProviderConnection conn; 8265 try { 8266 conn = (ContentProviderConnection)connection; 8267 } catch (ClassCastException e) { 8268 String msg ="refContentProvider: " + connection 8269 + " not a ContentProviderConnection"; 8270 Slog.w(TAG, msg); 8271 throw new IllegalArgumentException(msg); 8272 } 8273 if (conn == null) { 8274 throw new NullPointerException("connection is null"); 8275 } 8276 8277 // Safely retrieve the content provider associated with the connection. 8278 IContentProvider provider; 8279 synchronized (this) { 8280 provider = conn.provider.provider; 8281 } 8282 8283 if (provider == null) { 8284 // Um, yeah, we're way ahead of you. 8285 return; 8286 } 8287 8288 // Make sure the caller is being honest with us. 8289 if (provider.asBinder().pingBinder()) { 8290 // Er, no, still looks good to us. 8291 synchronized (this) { 8292 Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid() 8293 + " says " + conn + " died, but we don't agree"); 8294 return; 8295 } 8296 } 8297 8298 // Well look at that! It's dead! 8299 synchronized (this) { 8300 if (conn.provider.provider != provider) { 8301 // But something changed... good enough. 8302 return; 8303 } 8304 8305 ProcessRecord proc = conn.provider.proc; 8306 if (proc == null || proc.thread == null) { 8307 // Seems like the process is already cleaned up. 8308 return; 8309 } 8310 8311 // As far as we're concerned, this is just like receiving a 8312 // death notification... just a bit prematurely. 8313 Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid 8314 + ") early provider death"); 8315 final long ident = Binder.clearCallingIdentity(); 8316 try { 8317 appDiedLocked(proc, proc.pid, proc.thread); 8318 } finally { 8319 Binder.restoreCallingIdentity(ident); 8320 } 8321 } 8322 } 8323 8324 @Override 8325 public void appNotRespondingViaProvider(IBinder connection) { 8326 enforceCallingPermission( 8327 android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()"); 8328 8329 final ContentProviderConnection conn = (ContentProviderConnection) connection; 8330 if (conn == null) { 8331 Slog.w(TAG, "ContentProviderConnection is null"); 8332 return; 8333 } 8334 8335 final ProcessRecord host = conn.provider.proc; 8336 if (host == null) { 8337 Slog.w(TAG, "Failed to find hosting ProcessRecord"); 8338 return; 8339 } 8340 8341 final long token = Binder.clearCallingIdentity(); 8342 try { 8343 appNotResponding(host, null, null, false, "ContentProvider not responding"); 8344 } finally { 8345 Binder.restoreCallingIdentity(token); 8346 } 8347 } 8348 8349 public final void installSystemProviders() { 8350 List<ProviderInfo> providers; 8351 synchronized (this) { 8352 ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID); 8353 providers = generateApplicationProvidersLocked(app); 8354 if (providers != null) { 8355 for (int i=providers.size()-1; i>=0; i--) { 8356 ProviderInfo pi = (ProviderInfo)providers.get(i); 8357 if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) { 8358 Slog.w(TAG, "Not installing system proc provider " + pi.name 8359 + ": not system .apk"); 8360 providers.remove(i); 8361 } 8362 } 8363 } 8364 } 8365 if (providers != null) { 8366 mSystemThread.installSystemProviders(providers); 8367 } 8368 8369 mCoreSettingsObserver = new CoreSettingsObserver(this); 8370 8371 mUsageStatsService.monitorPackages(); 8372 } 8373 8374 /** 8375 * Allows app to retrieve the MIME type of a URI without having permission 8376 * to access its content provider. 8377 * 8378 * CTS tests for this functionality can be run with "runtest cts-appsecurity". 8379 * 8380 * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/ 8381 * src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java 8382 */ 8383 public String getProviderMimeType(Uri uri, int userId) { 8384 enforceNotIsolatedCaller("getProviderMimeType"); 8385 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 8386 userId, false, true, "getProviderMimeType", null); 8387 final String name = uri.getAuthority(); 8388 final long ident = Binder.clearCallingIdentity(); 8389 ContentProviderHolder holder = null; 8390 8391 try { 8392 holder = getContentProviderExternalUnchecked(name, null, userId); 8393 if (holder != null) { 8394 return holder.provider.getType(uri); 8395 } 8396 } catch (RemoteException e) { 8397 Log.w(TAG, "Content provider dead retrieving " + uri, e); 8398 return null; 8399 } finally { 8400 if (holder != null) { 8401 removeContentProviderExternalUnchecked(name, null, userId); 8402 } 8403 Binder.restoreCallingIdentity(ident); 8404 } 8405 8406 return null; 8407 } 8408 8409 // ========================================================= 8410 // GLOBAL MANAGEMENT 8411 // ========================================================= 8412 8413 final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess, 8414 boolean isolated) { 8415 String proc = customProcess != null ? customProcess : info.processName; 8416 BatteryStatsImpl.Uid.Proc ps = null; 8417 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 8418 int uid = info.uid; 8419 if (isolated) { 8420 int userId = UserHandle.getUserId(uid); 8421 int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1; 8422 while (true) { 8423 if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID 8424 || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) { 8425 mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID; 8426 } 8427 uid = UserHandle.getUid(userId, mNextIsolatedProcessUid); 8428 mNextIsolatedProcessUid++; 8429 if (mIsolatedProcesses.indexOfKey(uid) < 0) { 8430 // No process for this uid, use it. 8431 break; 8432 } 8433 stepsLeft--; 8434 if (stepsLeft <= 0) { 8435 return null; 8436 } 8437 } 8438 } 8439 return new ProcessRecord(stats, info, proc, uid); 8440 } 8441 8442 final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated) { 8443 ProcessRecord app; 8444 if (!isolated) { 8445 app = getProcessRecordLocked(info.processName, info.uid, true); 8446 } else { 8447 app = null; 8448 } 8449 8450 if (app == null) { 8451 app = newProcessRecordLocked(info, null, isolated); 8452 mProcessNames.put(info.processName, app.uid, app); 8453 if (isolated) { 8454 mIsolatedProcesses.put(app.uid, app); 8455 } 8456 updateLruProcessLocked(app, false, null); 8457 updateOomAdjLocked(); 8458 } 8459 8460 // This package really, really can not be stopped. 8461 try { 8462 AppGlobals.getPackageManager().setPackageStoppedState( 8463 info.packageName, false, UserHandle.getUserId(app.uid)); 8464 } catch (RemoteException e) { 8465 } catch (IllegalArgumentException e) { 8466 Slog.w(TAG, "Failed trying to unstop package " 8467 + info.packageName + ": " + e); 8468 } 8469 8470 if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) 8471 == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) { 8472 app.persistent = true; 8473 app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ; 8474 } 8475 if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) { 8476 mPersistentStartingProcesses.add(app); 8477 startProcessLocked(app, "added application", app.processName); 8478 } 8479 8480 return app; 8481 } 8482 8483 public void unhandledBack() { 8484 enforceCallingPermission(android.Manifest.permission.FORCE_BACK, 8485 "unhandledBack()"); 8486 8487 synchronized(this) { 8488 final long origId = Binder.clearCallingIdentity(); 8489 try { 8490 getFocusedStack().unhandledBackLocked(); 8491 } finally { 8492 Binder.restoreCallingIdentity(origId); 8493 } 8494 } 8495 } 8496 8497 public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException { 8498 enforceNotIsolatedCaller("openContentUri"); 8499 final int userId = UserHandle.getCallingUserId(); 8500 String name = uri.getAuthority(); 8501 ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId); 8502 ParcelFileDescriptor pfd = null; 8503 if (cph != null) { 8504 // We record the binder invoker's uid in thread-local storage before 8505 // going to the content provider to open the file. Later, in the code 8506 // that handles all permissions checks, we look for this uid and use 8507 // that rather than the Activity Manager's own uid. The effect is that 8508 // we do the check against the caller's permissions even though it looks 8509 // to the content provider like the Activity Manager itself is making 8510 // the request. 8511 sCallerIdentity.set(new Identity( 8512 Binder.getCallingPid(), Binder.getCallingUid())); 8513 try { 8514 pfd = cph.provider.openFile(null, uri, "r", null); 8515 } catch (FileNotFoundException e) { 8516 // do nothing; pfd will be returned null 8517 } finally { 8518 // Ensure that whatever happens, we clean up the identity state 8519 sCallerIdentity.remove(); 8520 } 8521 8522 // We've got the fd now, so we're done with the provider. 8523 removeContentProviderExternalUnchecked(name, null, userId); 8524 } else { 8525 Slog.d(TAG, "Failed to get provider for authority '" + name + "'"); 8526 } 8527 return pfd; 8528 } 8529 8530 // Actually is sleeping or shutting down or whatever else in the future 8531 // is an inactive state. 8532 public boolean isSleepingOrShuttingDown() { 8533 return mSleeping || mShuttingDown; 8534 } 8535 8536 public boolean isSleeping() { 8537 return mSleeping; 8538 } 8539 8540 void goingToSleep() { 8541 synchronized(this) { 8542 mWentToSleep = true; 8543 updateEventDispatchingLocked(); 8544 goToSleepIfNeededLocked(); 8545 } 8546 } 8547 8548 void finishRunningVoiceLocked() { 8549 if (mRunningVoice) { 8550 mRunningVoice = false; 8551 goToSleepIfNeededLocked(); 8552 } 8553 } 8554 8555 void goToSleepIfNeededLocked() { 8556 if (mWentToSleep && !mRunningVoice) { 8557 if (!mSleeping) { 8558 mSleeping = true; 8559 mStackSupervisor.goingToSleepLocked(); 8560 8561 // Initialize the wake times of all processes. 8562 checkExcessivePowerUsageLocked(false); 8563 mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 8564 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 8565 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 8566 } 8567 } 8568 } 8569 8570 @Override 8571 public boolean shutdown(int timeout) { 8572 if (checkCallingPermission(android.Manifest.permission.SHUTDOWN) 8573 != PackageManager.PERMISSION_GRANTED) { 8574 throw new SecurityException("Requires permission " 8575 + android.Manifest.permission.SHUTDOWN); 8576 } 8577 8578 boolean timedout = false; 8579 8580 synchronized(this) { 8581 mShuttingDown = true; 8582 updateEventDispatchingLocked(); 8583 timedout = mStackSupervisor.shutdownLocked(timeout); 8584 } 8585 8586 mAppOpsService.shutdown(); 8587 mUsageStatsService.shutdown(); 8588 mBatteryStatsService.shutdown(); 8589 synchronized (this) { 8590 mProcessStats.shutdownLocked(); 8591 } 8592 8593 return timedout; 8594 } 8595 8596 public final void activitySlept(IBinder token) { 8597 if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token); 8598 8599 final long origId = Binder.clearCallingIdentity(); 8600 8601 synchronized (this) { 8602 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 8603 if (r != null) { 8604 mStackSupervisor.activitySleptLocked(r); 8605 } 8606 } 8607 8608 Binder.restoreCallingIdentity(origId); 8609 } 8610 8611 void logLockScreen(String msg) { 8612 if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg + 8613 " mLockScreenShown=" + mLockScreenShown + " mWentToSleep=" + 8614 mWentToSleep + " mSleeping=" + mSleeping + " mDismissKeyguardOnNextActivity=" + 8615 mStackSupervisor.mDismissKeyguardOnNextActivity); 8616 } 8617 8618 private void comeOutOfSleepIfNeededLocked() { 8619 if ((!mWentToSleep && !mLockScreenShown) || mRunningVoice) { 8620 if (mSleeping) { 8621 mSleeping = false; 8622 mStackSupervisor.comeOutOfSleepIfNeededLocked(); 8623 } 8624 } 8625 } 8626 8627 void wakingUp() { 8628 synchronized(this) { 8629 mWentToSleep = false; 8630 updateEventDispatchingLocked(); 8631 comeOutOfSleepIfNeededLocked(); 8632 } 8633 } 8634 8635 void startRunningVoiceLocked() { 8636 if (!mRunningVoice) { 8637 mRunningVoice = true; 8638 comeOutOfSleepIfNeededLocked(); 8639 } 8640 } 8641 8642 private void updateEventDispatchingLocked() { 8643 mWindowManager.setEventDispatching(mBooted && !mWentToSleep && !mShuttingDown); 8644 } 8645 8646 public void setLockScreenShown(boolean shown) { 8647 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER) 8648 != PackageManager.PERMISSION_GRANTED) { 8649 throw new SecurityException("Requires permission " 8650 + android.Manifest.permission.DEVICE_POWER); 8651 } 8652 8653 synchronized(this) { 8654 long ident = Binder.clearCallingIdentity(); 8655 try { 8656 if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown); 8657 mLockScreenShown = shown; 8658 comeOutOfSleepIfNeededLocked(); 8659 } finally { 8660 Binder.restoreCallingIdentity(ident); 8661 } 8662 } 8663 } 8664 8665 public void stopAppSwitches() { 8666 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 8667 != PackageManager.PERMISSION_GRANTED) { 8668 throw new SecurityException("Requires permission " 8669 + android.Manifest.permission.STOP_APP_SWITCHES); 8670 } 8671 8672 synchronized(this) { 8673 mAppSwitchesAllowedTime = SystemClock.uptimeMillis() 8674 + APP_SWITCH_DELAY_TIME; 8675 mDidAppSwitch = false; 8676 mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 8677 Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 8678 mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME); 8679 } 8680 } 8681 8682 public void resumeAppSwitches() { 8683 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 8684 != PackageManager.PERMISSION_GRANTED) { 8685 throw new SecurityException("Requires permission " 8686 + android.Manifest.permission.STOP_APP_SWITCHES); 8687 } 8688 8689 synchronized(this) { 8690 // Note that we don't execute any pending app switches... we will 8691 // let those wait until either the timeout, or the next start 8692 // activity request. 8693 mAppSwitchesAllowedTime = 0; 8694 } 8695 } 8696 8697 boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid, 8698 String name) { 8699 if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) { 8700 return true; 8701 } 8702 8703 final int perm = checkComponentPermission( 8704 android.Manifest.permission.STOP_APP_SWITCHES, callingPid, 8705 callingUid, -1, true); 8706 if (perm == PackageManager.PERMISSION_GRANTED) { 8707 return true; 8708 } 8709 8710 Slog.w(TAG, name + " request from " + callingUid + " stopped"); 8711 return false; 8712 } 8713 8714 public void setDebugApp(String packageName, boolean waitForDebugger, 8715 boolean persistent) { 8716 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP, 8717 "setDebugApp()"); 8718 8719 long ident = Binder.clearCallingIdentity(); 8720 try { 8721 // Note that this is not really thread safe if there are multiple 8722 // callers into it at the same time, but that's not a situation we 8723 // care about. 8724 if (persistent) { 8725 final ContentResolver resolver = mContext.getContentResolver(); 8726 Settings.Global.putString( 8727 resolver, Settings.Global.DEBUG_APP, 8728 packageName); 8729 Settings.Global.putInt( 8730 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 8731 waitForDebugger ? 1 : 0); 8732 } 8733 8734 synchronized (this) { 8735 if (!persistent) { 8736 mOrigDebugApp = mDebugApp; 8737 mOrigWaitForDebugger = mWaitForDebugger; 8738 } 8739 mDebugApp = packageName; 8740 mWaitForDebugger = waitForDebugger; 8741 mDebugTransient = !persistent; 8742 if (packageName != null) { 8743 forceStopPackageLocked(packageName, -1, false, false, true, true, 8744 false, UserHandle.USER_ALL, "set debug app"); 8745 } 8746 } 8747 } finally { 8748 Binder.restoreCallingIdentity(ident); 8749 } 8750 } 8751 8752 void setOpenGlTraceApp(ApplicationInfo app, String processName) { 8753 synchronized (this) { 8754 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 8755 if (!isDebuggable) { 8756 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 8757 throw new SecurityException("Process not debuggable: " + app.packageName); 8758 } 8759 } 8760 8761 mOpenGlTraceApp = processName; 8762 } 8763 } 8764 8765 void setProfileApp(ApplicationInfo app, String processName, String profileFile, 8766 ParcelFileDescriptor profileFd, boolean autoStopProfiler) { 8767 synchronized (this) { 8768 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 8769 if (!isDebuggable) { 8770 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 8771 throw new SecurityException("Process not debuggable: " + app.packageName); 8772 } 8773 } 8774 mProfileApp = processName; 8775 mProfileFile = profileFile; 8776 if (mProfileFd != null) { 8777 try { 8778 mProfileFd.close(); 8779 } catch (IOException e) { 8780 } 8781 mProfileFd = null; 8782 } 8783 mProfileFd = profileFd; 8784 mProfileType = 0; 8785 mAutoStopProfiler = autoStopProfiler; 8786 } 8787 } 8788 8789 @Override 8790 public void setAlwaysFinish(boolean enabled) { 8791 enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH, 8792 "setAlwaysFinish()"); 8793 8794 Settings.Global.putInt( 8795 mContext.getContentResolver(), 8796 Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0); 8797 8798 synchronized (this) { 8799 mAlwaysFinishActivities = enabled; 8800 } 8801 } 8802 8803 @Override 8804 public void setActivityController(IActivityController controller) { 8805 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 8806 "setActivityController()"); 8807 synchronized (this) { 8808 mController = controller; 8809 Watchdog.getInstance().setActivityController(controller); 8810 } 8811 } 8812 8813 @Override 8814 public void setUserIsMonkey(boolean userIsMonkey) { 8815 synchronized (this) { 8816 synchronized (mPidsSelfLocked) { 8817 final int callingPid = Binder.getCallingPid(); 8818 ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid); 8819 if (precessRecord == null) { 8820 throw new SecurityException("Unknown process: " + callingPid); 8821 } 8822 if (precessRecord.instrumentationUiAutomationConnection == null) { 8823 throw new SecurityException("Only an instrumentation process " 8824 + "with a UiAutomation can call setUserIsMonkey"); 8825 } 8826 } 8827 mUserIsMonkey = userIsMonkey; 8828 } 8829 } 8830 8831 @Override 8832 public boolean isUserAMonkey() { 8833 synchronized (this) { 8834 // If there is a controller also implies the user is a monkey. 8835 return (mUserIsMonkey || mController != null); 8836 } 8837 } 8838 8839 public void requestBugReport() { 8840 enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport"); 8841 SystemProperties.set("ctl.start", "bugreport"); 8842 } 8843 8844 public static long getInputDispatchingTimeoutLocked(ActivityRecord r) { 8845 return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT; 8846 } 8847 8848 public static long getInputDispatchingTimeoutLocked(ProcessRecord r) { 8849 if (r != null && (r.instrumentationClass != null || r.usingWrapper)) { 8850 return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT; 8851 } 8852 return KEY_DISPATCHING_TIMEOUT; 8853 } 8854 8855 @Override 8856 public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) { 8857 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS) 8858 != PackageManager.PERMISSION_GRANTED) { 8859 throw new SecurityException("Requires permission " 8860 + android.Manifest.permission.FILTER_EVENTS); 8861 } 8862 ProcessRecord proc; 8863 long timeout; 8864 synchronized (this) { 8865 synchronized (mPidsSelfLocked) { 8866 proc = mPidsSelfLocked.get(pid); 8867 } 8868 timeout = getInputDispatchingTimeoutLocked(proc); 8869 } 8870 8871 if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) { 8872 return -1; 8873 } 8874 8875 return timeout; 8876 } 8877 8878 /** 8879 * Handle input dispatching timeouts. 8880 * Returns whether input dispatching should be aborted or not. 8881 */ 8882 public boolean inputDispatchingTimedOut(final ProcessRecord proc, 8883 final ActivityRecord activity, final ActivityRecord parent, 8884 final boolean aboveSystem, String reason) { 8885 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS) 8886 != PackageManager.PERMISSION_GRANTED) { 8887 throw new SecurityException("Requires permission " 8888 + android.Manifest.permission.FILTER_EVENTS); 8889 } 8890 8891 final String annotation; 8892 if (reason == null) { 8893 annotation = "Input dispatching timed out"; 8894 } else { 8895 annotation = "Input dispatching timed out (" + reason + ")"; 8896 } 8897 8898 if (proc != null) { 8899 synchronized (this) { 8900 if (proc.debugging) { 8901 return false; 8902 } 8903 8904 if (mDidDexOpt) { 8905 // Give more time since we were dexopting. 8906 mDidDexOpt = false; 8907 return false; 8908 } 8909 8910 if (proc.instrumentationClass != null) { 8911 Bundle info = new Bundle(); 8912 info.putString("shortMsg", "keyDispatchingTimedOut"); 8913 info.putString("longMsg", annotation); 8914 finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info); 8915 return true; 8916 } 8917 } 8918 mHandler.post(new Runnable() { 8919 @Override 8920 public void run() { 8921 appNotResponding(proc, activity, parent, aboveSystem, annotation); 8922 } 8923 }); 8924 } 8925 8926 return true; 8927 } 8928 8929 public Bundle getAssistContextExtras(int requestType) { 8930 enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO, 8931 "getAssistContextExtras()"); 8932 PendingAssistExtras pae; 8933 Bundle extras = new Bundle(); 8934 synchronized (this) { 8935 ActivityRecord activity = getFocusedStack().mResumedActivity; 8936 if (activity == null) { 8937 Slog.w(TAG, "getAssistContextExtras failed: no resumed activity"); 8938 return null; 8939 } 8940 extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName); 8941 if (activity.app == null || activity.app.thread == null) { 8942 Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity); 8943 return extras; 8944 } 8945 if (activity.app.pid == Binder.getCallingPid()) { 8946 Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity); 8947 return extras; 8948 } 8949 pae = new PendingAssistExtras(activity); 8950 try { 8951 activity.app.thread.requestAssistContextExtras(activity.appToken, pae, 8952 requestType); 8953 mPendingAssistExtras.add(pae); 8954 mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT); 8955 } catch (RemoteException e) { 8956 Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity); 8957 return extras; 8958 } 8959 } 8960 synchronized (pae) { 8961 while (!pae.haveResult) { 8962 try { 8963 pae.wait(); 8964 } catch (InterruptedException e) { 8965 } 8966 } 8967 if (pae.result != null) { 8968 extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result); 8969 } 8970 } 8971 synchronized (this) { 8972 mPendingAssistExtras.remove(pae); 8973 mHandler.removeCallbacks(pae); 8974 } 8975 return extras; 8976 } 8977 8978 public void reportAssistContextExtras(IBinder token, Bundle extras) { 8979 PendingAssistExtras pae = (PendingAssistExtras)token; 8980 synchronized (pae) { 8981 pae.result = extras; 8982 pae.haveResult = true; 8983 pae.notifyAll(); 8984 } 8985 } 8986 8987 public void registerProcessObserver(IProcessObserver observer) { 8988 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 8989 "registerProcessObserver()"); 8990 synchronized (this) { 8991 mProcessObservers.register(observer); 8992 } 8993 } 8994 8995 @Override 8996 public void unregisterProcessObserver(IProcessObserver observer) { 8997 synchronized (this) { 8998 mProcessObservers.unregister(observer); 8999 } 9000 } 9001 9002 @Override 9003 public boolean convertFromTranslucent(IBinder token) { 9004 final long origId = Binder.clearCallingIdentity(); 9005 try { 9006 synchronized (this) { 9007 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 9008 if (r == null) { 9009 return false; 9010 } 9011 if (r.changeWindowTranslucency(true)) { 9012 mWindowManager.setAppFullscreen(token, true); 9013 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 9014 return true; 9015 } 9016 return false; 9017 } 9018 } finally { 9019 Binder.restoreCallingIdentity(origId); 9020 } 9021 } 9022 9023 @Override 9024 public boolean convertToTranslucent(IBinder token) { 9025 final long origId = Binder.clearCallingIdentity(); 9026 try { 9027 synchronized (this) { 9028 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 9029 if (r == null) { 9030 return false; 9031 } 9032 if (r.changeWindowTranslucency(false)) { 9033 r.task.stack.convertToTranslucent(r); 9034 mWindowManager.setAppFullscreen(token, false); 9035 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 9036 return true; 9037 } 9038 return false; 9039 } 9040 } finally { 9041 Binder.restoreCallingIdentity(origId); 9042 } 9043 } 9044 9045 @Override 9046 public void setImmersive(IBinder token, boolean immersive) { 9047 synchronized(this) { 9048 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 9049 if (r == null) { 9050 throw new IllegalArgumentException(); 9051 } 9052 r.immersive = immersive; 9053 9054 // update associated state if we're frontmost 9055 if (r == mFocusedActivity) { 9056 if (DEBUG_IMMERSIVE) { 9057 Slog.d(TAG, "Frontmost changed immersion: "+ r); 9058 } 9059 applyUpdateLockStateLocked(r); 9060 } 9061 } 9062 } 9063 9064 @Override 9065 public boolean isImmersive(IBinder token) { 9066 synchronized (this) { 9067 ActivityRecord r = ActivityRecord.isInStackLocked(token); 9068 if (r == null) { 9069 throw new IllegalArgumentException(); 9070 } 9071 return r.immersive; 9072 } 9073 } 9074 9075 public boolean isTopActivityImmersive() { 9076 enforceNotIsolatedCaller("startActivity"); 9077 synchronized (this) { 9078 ActivityRecord r = getFocusedStack().topRunningActivityLocked(null); 9079 return (r != null) ? r.immersive : false; 9080 } 9081 } 9082 9083 public final void enterSafeMode() { 9084 synchronized(this) { 9085 // It only makes sense to do this before the system is ready 9086 // and started launching other packages. 9087 if (!mSystemReady) { 9088 try { 9089 AppGlobals.getPackageManager().enterSafeMode(); 9090 } catch (RemoteException e) { 9091 } 9092 } 9093 9094 mSafeMode = true; 9095 } 9096 } 9097 9098 public final void showSafeModeOverlay() { 9099 View v = LayoutInflater.from(mContext).inflate( 9100 com.android.internal.R.layout.safe_mode, null); 9101 WindowManager.LayoutParams lp = new WindowManager.LayoutParams(); 9102 lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY; 9103 lp.width = WindowManager.LayoutParams.WRAP_CONTENT; 9104 lp.height = WindowManager.LayoutParams.WRAP_CONTENT; 9105 lp.gravity = Gravity.BOTTOM | Gravity.START; 9106 lp.format = v.getBackground().getOpacity(); 9107 lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE 9108 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE; 9109 lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS; 9110 ((WindowManager)mContext.getSystemService( 9111 Context.WINDOW_SERVICE)).addView(v, lp); 9112 } 9113 9114 public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) { 9115 if (!(sender instanceof PendingIntentRecord)) { 9116 return; 9117 } 9118 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 9119 synchronized (stats) { 9120 if (mBatteryStatsService.isOnBattery()) { 9121 mBatteryStatsService.enforceCallingPermission(); 9122 PendingIntentRecord rec = (PendingIntentRecord)sender; 9123 int MY_UID = Binder.getCallingUid(); 9124 int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid; 9125 BatteryStatsImpl.Uid.Pkg pkg = 9126 stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid, 9127 sourcePkg != null ? sourcePkg : rec.key.packageName); 9128 pkg.incWakeupsLocked(); 9129 } 9130 } 9131 } 9132 9133 public boolean killPids(int[] pids, String pReason, boolean secure) { 9134 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 9135 throw new SecurityException("killPids only available to the system"); 9136 } 9137 String reason = (pReason == null) ? "Unknown" : pReason; 9138 // XXX Note: don't acquire main activity lock here, because the window 9139 // manager calls in with its locks held. 9140 9141 boolean killed = false; 9142 synchronized (mPidsSelfLocked) { 9143 int[] types = new int[pids.length]; 9144 int worstType = 0; 9145 for (int i=0; i<pids.length; i++) { 9146 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 9147 if (proc != null) { 9148 int type = proc.setAdj; 9149 types[i] = type; 9150 if (type > worstType) { 9151 worstType = type; 9152 } 9153 } 9154 } 9155 9156 // If the worst oom_adj is somewhere in the cached proc LRU range, 9157 // then constrain it so we will kill all cached procs. 9158 if (worstType < ProcessList.CACHED_APP_MAX_ADJ 9159 && worstType > ProcessList.CACHED_APP_MIN_ADJ) { 9160 worstType = ProcessList.CACHED_APP_MIN_ADJ; 9161 } 9162 9163 // If this is not a secure call, don't let it kill processes that 9164 // are important. 9165 if (!secure && worstType < ProcessList.SERVICE_ADJ) { 9166 worstType = ProcessList.SERVICE_ADJ; 9167 } 9168 9169 Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType); 9170 for (int i=0; i<pids.length; i++) { 9171 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 9172 if (proc == null) { 9173 continue; 9174 } 9175 int adj = proc.setAdj; 9176 if (adj >= worstType && !proc.killedByAm) { 9177 killUnneededProcessLocked(proc, reason); 9178 killed = true; 9179 } 9180 } 9181 } 9182 return killed; 9183 } 9184 9185 @Override 9186 public void killUid(int uid, String reason) { 9187 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 9188 throw new SecurityException("killUid only available to the system"); 9189 } 9190 synchronized (this) { 9191 killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid), 9192 ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false, 9193 reason != null ? reason : "kill uid"); 9194 } 9195 } 9196 9197 @Override 9198 public boolean killProcessesBelowForeground(String reason) { 9199 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 9200 throw new SecurityException("killProcessesBelowForeground() only available to system"); 9201 } 9202 9203 return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason); 9204 } 9205 9206 private boolean killProcessesBelowAdj(int belowAdj, String reason) { 9207 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 9208 throw new SecurityException("killProcessesBelowAdj() only available to system"); 9209 } 9210 9211 boolean killed = false; 9212 synchronized (mPidsSelfLocked) { 9213 final int size = mPidsSelfLocked.size(); 9214 for (int i = 0; i < size; i++) { 9215 final int pid = mPidsSelfLocked.keyAt(i); 9216 final ProcessRecord proc = mPidsSelfLocked.valueAt(i); 9217 if (proc == null) continue; 9218 9219 final int adj = proc.setAdj; 9220 if (adj > belowAdj && !proc.killedByAm) { 9221 killUnneededProcessLocked(proc, reason); 9222 killed = true; 9223 } 9224 } 9225 } 9226 return killed; 9227 } 9228 9229 @Override 9230 public void hang(final IBinder who, boolean allowRestart) { 9231 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 9232 != PackageManager.PERMISSION_GRANTED) { 9233 throw new SecurityException("Requires permission " 9234 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 9235 } 9236 9237 final IBinder.DeathRecipient death = new DeathRecipient() { 9238 @Override 9239 public void binderDied() { 9240 synchronized (this) { 9241 notifyAll(); 9242 } 9243 } 9244 }; 9245 9246 try { 9247 who.linkToDeath(death, 0); 9248 } catch (RemoteException e) { 9249 Slog.w(TAG, "hang: given caller IBinder is already dead."); 9250 return; 9251 } 9252 9253 synchronized (this) { 9254 Watchdog.getInstance().setAllowRestart(allowRestart); 9255 Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid()); 9256 synchronized (death) { 9257 while (who.isBinderAlive()) { 9258 try { 9259 death.wait(); 9260 } catch (InterruptedException e) { 9261 } 9262 } 9263 } 9264 Watchdog.getInstance().setAllowRestart(true); 9265 } 9266 } 9267 9268 @Override 9269 public void restart() { 9270 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 9271 != PackageManager.PERMISSION_GRANTED) { 9272 throw new SecurityException("Requires permission " 9273 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 9274 } 9275 9276 Log.i(TAG, "Sending shutdown broadcast..."); 9277 9278 BroadcastReceiver br = new BroadcastReceiver() { 9279 @Override public void onReceive(Context context, Intent intent) { 9280 // Now the broadcast is done, finish up the low-level shutdown. 9281 Log.i(TAG, "Shutting down activity manager..."); 9282 shutdown(10000); 9283 Log.i(TAG, "Shutdown complete, restarting!"); 9284 Process.killProcess(Process.myPid()); 9285 System.exit(10); 9286 } 9287 }; 9288 9289 // First send the high-level shut down broadcast. 9290 Intent intent = new Intent(Intent.ACTION_SHUTDOWN); 9291 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 9292 intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true); 9293 /* For now we are not doing a clean shutdown, because things seem to get unhappy. 9294 mContext.sendOrderedBroadcastAsUser(intent, 9295 UserHandle.ALL, null, br, mHandler, 0, null, null); 9296 */ 9297 br.onReceive(mContext, intent); 9298 } 9299 9300 private long getLowRamTimeSinceIdle(long now) { 9301 return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0); 9302 } 9303 9304 @Override 9305 public void performIdleMaintenance() { 9306 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 9307 != PackageManager.PERMISSION_GRANTED) { 9308 throw new SecurityException("Requires permission " 9309 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 9310 } 9311 9312 synchronized (this) { 9313 final long now = SystemClock.uptimeMillis(); 9314 final long timeSinceLastIdle = now - mLastIdleTime; 9315 final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now); 9316 mLastIdleTime = now; 9317 mLowRamTimeSinceLastIdle = 0; 9318 if (mLowRamStartTime != 0) { 9319 mLowRamStartTime = now; 9320 } 9321 9322 StringBuilder sb = new StringBuilder(128); 9323 sb.append("Idle maintenance over "); 9324 TimeUtils.formatDuration(timeSinceLastIdle, sb); 9325 sb.append(" low RAM for "); 9326 TimeUtils.formatDuration(lowRamSinceLastIdle, sb); 9327 Slog.i(TAG, sb.toString()); 9328 9329 // If at least 1/3 of our time since the last idle period has been spent 9330 // with RAM low, then we want to kill processes. 9331 boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3); 9332 9333 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 9334 ProcessRecord proc = mLruProcesses.get(i); 9335 if (proc.notCachedSinceIdle) { 9336 if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP 9337 && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) { 9338 if (doKilling && proc.initialIdlePss != 0 9339 && proc.lastPss > ((proc.initialIdlePss*3)/2)) { 9340 killUnneededProcessLocked(proc, "idle maint (pss " + proc.lastPss 9341 + " from " + proc.initialIdlePss + ")"); 9342 } 9343 } 9344 } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) { 9345 proc.notCachedSinceIdle = true; 9346 proc.initialIdlePss = 0; 9347 proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true, 9348 isSleeping(), now); 9349 } 9350 } 9351 9352 mHandler.removeMessages(REQUEST_ALL_PSS_MSG); 9353 mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000); 9354 } 9355 } 9356 9357 private void retrieveSettings() { 9358 final ContentResolver resolver = mContext.getContentResolver(); 9359 String debugApp = Settings.Global.getString( 9360 resolver, Settings.Global.DEBUG_APP); 9361 boolean waitForDebugger = Settings.Global.getInt( 9362 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0; 9363 boolean alwaysFinishActivities = Settings.Global.getInt( 9364 resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0; 9365 boolean forceRtl = Settings.Global.getInt( 9366 resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0; 9367 // Transfer any global setting for forcing RTL layout, into a System Property 9368 SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0"); 9369 9370 Configuration configuration = new Configuration(); 9371 Settings.System.getConfiguration(resolver, configuration); 9372 if (forceRtl) { 9373 // This will take care of setting the correct layout direction flags 9374 configuration.setLayoutDirection(configuration.locale); 9375 } 9376 9377 synchronized (this) { 9378 mDebugApp = mOrigDebugApp = debugApp; 9379 mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger; 9380 mAlwaysFinishActivities = alwaysFinishActivities; 9381 // This happens before any activities are started, so we can 9382 // change mConfiguration in-place. 9383 updateConfigurationLocked(configuration, null, false, true); 9384 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration); 9385 } 9386 } 9387 9388 public boolean testIsSystemReady() { 9389 // no need to synchronize(this) just to read & return the value 9390 return mSystemReady; 9391 } 9392 9393 private static File getCalledPreBootReceiversFile() { 9394 File dataDir = Environment.getDataDirectory(); 9395 File systemDir = new File(dataDir, "system"); 9396 File fname = new File(systemDir, "called_pre_boots.dat"); 9397 return fname; 9398 } 9399 9400 static final int LAST_DONE_VERSION = 10000; 9401 9402 private static ArrayList<ComponentName> readLastDonePreBootReceivers() { 9403 ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>(); 9404 File file = getCalledPreBootReceiversFile(); 9405 FileInputStream fis = null; 9406 try { 9407 fis = new FileInputStream(file); 9408 DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048)); 9409 int fvers = dis.readInt(); 9410 if (fvers == LAST_DONE_VERSION) { 9411 String vers = dis.readUTF(); 9412 String codename = dis.readUTF(); 9413 String build = dis.readUTF(); 9414 if (android.os.Build.VERSION.RELEASE.equals(vers) 9415 && android.os.Build.VERSION.CODENAME.equals(codename) 9416 && android.os.Build.VERSION.INCREMENTAL.equals(build)) { 9417 int num = dis.readInt(); 9418 while (num > 0) { 9419 num--; 9420 String pkg = dis.readUTF(); 9421 String cls = dis.readUTF(); 9422 lastDoneReceivers.add(new ComponentName(pkg, cls)); 9423 } 9424 } 9425 } 9426 } catch (FileNotFoundException e) { 9427 } catch (IOException e) { 9428 Slog.w(TAG, "Failure reading last done pre-boot receivers", e); 9429 } finally { 9430 if (fis != null) { 9431 try { 9432 fis.close(); 9433 } catch (IOException e) { 9434 } 9435 } 9436 } 9437 return lastDoneReceivers; 9438 } 9439 9440 private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) { 9441 File file = getCalledPreBootReceiversFile(); 9442 FileOutputStream fos = null; 9443 DataOutputStream dos = null; 9444 try { 9445 Slog.i(TAG, "Writing new set of last done pre-boot receivers..."); 9446 fos = new FileOutputStream(file); 9447 dos = new DataOutputStream(new BufferedOutputStream(fos, 2048)); 9448 dos.writeInt(LAST_DONE_VERSION); 9449 dos.writeUTF(android.os.Build.VERSION.RELEASE); 9450 dos.writeUTF(android.os.Build.VERSION.CODENAME); 9451 dos.writeUTF(android.os.Build.VERSION.INCREMENTAL); 9452 dos.writeInt(list.size()); 9453 for (int i=0; i<list.size(); i++) { 9454 dos.writeUTF(list.get(i).getPackageName()); 9455 dos.writeUTF(list.get(i).getClassName()); 9456 } 9457 } catch (IOException e) { 9458 Slog.w(TAG, "Failure writing last done pre-boot receivers", e); 9459 file.delete(); 9460 } finally { 9461 FileUtils.sync(fos); 9462 if (dos != null) { 9463 try { 9464 dos.close(); 9465 } catch (IOException e) { 9466 // TODO Auto-generated catch block 9467 e.printStackTrace(); 9468 } 9469 } 9470 } 9471 } 9472 9473 public void systemReady(final Runnable goingCallback) { 9474 synchronized(this) { 9475 if (mSystemReady) { 9476 if (goingCallback != null) goingCallback.run(); 9477 return; 9478 } 9479 9480 // Check to see if there are any update receivers to run. 9481 if (!mDidUpdate) { 9482 if (mWaitingUpdate) { 9483 return; 9484 } 9485 Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED); 9486 List<ResolveInfo> ris = null; 9487 try { 9488 ris = AppGlobals.getPackageManager().queryIntentReceivers( 9489 intent, null, 0, 0); 9490 } catch (RemoteException e) { 9491 } 9492 if (ris != null) { 9493 for (int i=ris.size()-1; i>=0; i--) { 9494 if ((ris.get(i).activityInfo.applicationInfo.flags 9495 &ApplicationInfo.FLAG_SYSTEM) == 0) { 9496 ris.remove(i); 9497 } 9498 } 9499 intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE); 9500 9501 ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers(); 9502 9503 final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>(); 9504 for (int i=0; i<ris.size(); i++) { 9505 ActivityInfo ai = ris.get(i).activityInfo; 9506 ComponentName comp = new ComponentName(ai.packageName, ai.name); 9507 if (lastDoneReceivers.contains(comp)) { 9508 // We already did the pre boot receiver for this app with the current 9509 // platform version, so don't do it again... 9510 ris.remove(i); 9511 i--; 9512 // ...however, do keep it as one that has been done, so we don't 9513 // forget about it when rewriting the file of last done receivers. 9514 doneReceivers.add(comp); 9515 } 9516 } 9517 9518 final int[] users = getUsersLocked(); 9519 for (int i=0; i<ris.size(); i++) { 9520 ActivityInfo ai = ris.get(i).activityInfo; 9521 ComponentName comp = new ComponentName(ai.packageName, ai.name); 9522 doneReceivers.add(comp); 9523 intent.setComponent(comp); 9524 for (int j=0; j<users.length; j++) { 9525 IIntentReceiver finisher = null; 9526 if (i == ris.size()-1 && j == users.length-1) { 9527 finisher = new IIntentReceiver.Stub() { 9528 public void performReceive(Intent intent, int resultCode, 9529 String data, Bundle extras, boolean ordered, 9530 boolean sticky, int sendingUser) { 9531 // The raw IIntentReceiver interface is called 9532 // with the AM lock held, so redispatch to 9533 // execute our code without the lock. 9534 mHandler.post(new Runnable() { 9535 public void run() { 9536 synchronized (ActivityManagerService.this) { 9537 mDidUpdate = true; 9538 } 9539 writeLastDonePreBootReceivers(doneReceivers); 9540 showBootMessage(mContext.getText( 9541 R.string.android_upgrading_complete), 9542 false); 9543 systemReady(goingCallback); 9544 } 9545 }); 9546 } 9547 }; 9548 } 9549 Slog.i(TAG, "Sending system update to " + intent.getComponent() 9550 + " for user " + users[j]); 9551 broadcastIntentLocked(null, null, intent, null, finisher, 9552 0, null, null, null, AppOpsManager.OP_NONE, 9553 true, false, MY_PID, Process.SYSTEM_UID, 9554 users[j]); 9555 if (finisher != null) { 9556 mWaitingUpdate = true; 9557 } 9558 } 9559 } 9560 } 9561 if (mWaitingUpdate) { 9562 return; 9563 } 9564 mDidUpdate = true; 9565 } 9566 9567 mAppOpsService.systemReady(); 9568 mSystemReady = true; 9569 } 9570 9571 ArrayList<ProcessRecord> procsToKill = null; 9572 synchronized(mPidsSelfLocked) { 9573 for (int i=mPidsSelfLocked.size()-1; i>=0; i--) { 9574 ProcessRecord proc = mPidsSelfLocked.valueAt(i); 9575 if (!isAllowedWhileBooting(proc.info)){ 9576 if (procsToKill == null) { 9577 procsToKill = new ArrayList<ProcessRecord>(); 9578 } 9579 procsToKill.add(proc); 9580 } 9581 } 9582 } 9583 9584 synchronized(this) { 9585 if (procsToKill != null) { 9586 for (int i=procsToKill.size()-1; i>=0; i--) { 9587 ProcessRecord proc = procsToKill.get(i); 9588 Slog.i(TAG, "Removing system update proc: " + proc); 9589 removeProcessLocked(proc, true, false, "system update done"); 9590 } 9591 } 9592 9593 // Now that we have cleaned up any update processes, we 9594 // are ready to start launching real processes and know that 9595 // we won't trample on them any more. 9596 mProcessesReady = true; 9597 } 9598 9599 Slog.i(TAG, "System now ready"); 9600 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY, 9601 SystemClock.uptimeMillis()); 9602 9603 synchronized(this) { 9604 // Make sure we have no pre-ready processes sitting around. 9605 9606 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) { 9607 ResolveInfo ri = mContext.getPackageManager() 9608 .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST), 9609 STOCK_PM_FLAGS); 9610 CharSequence errorMsg = null; 9611 if (ri != null) { 9612 ActivityInfo ai = ri.activityInfo; 9613 ApplicationInfo app = ai.applicationInfo; 9614 if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) { 9615 mTopAction = Intent.ACTION_FACTORY_TEST; 9616 mTopData = null; 9617 mTopComponent = new ComponentName(app.packageName, 9618 ai.name); 9619 } else { 9620 errorMsg = mContext.getResources().getText( 9621 com.android.internal.R.string.factorytest_not_system); 9622 } 9623 } else { 9624 errorMsg = mContext.getResources().getText( 9625 com.android.internal.R.string.factorytest_no_action); 9626 } 9627 if (errorMsg != null) { 9628 mTopAction = null; 9629 mTopData = null; 9630 mTopComponent = null; 9631 Message msg = Message.obtain(); 9632 msg.what = SHOW_FACTORY_ERROR_MSG; 9633 msg.getData().putCharSequence("msg", errorMsg); 9634 mHandler.sendMessage(msg); 9635 } 9636 } 9637 } 9638 9639 retrieveSettings(); 9640 9641 synchronized (this) { 9642 readGrantedUriPermissionsLocked(); 9643 } 9644 9645 if (goingCallback != null) goingCallback.run(); 9646 9647 mSystemServiceManager.startUser(mCurrentUserId); 9648 9649 synchronized (this) { 9650 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 9651 try { 9652 List apps = AppGlobals.getPackageManager(). 9653 getPersistentApplications(STOCK_PM_FLAGS); 9654 if (apps != null) { 9655 int N = apps.size(); 9656 int i; 9657 for (i=0; i<N; i++) { 9658 ApplicationInfo info 9659 = (ApplicationInfo)apps.get(i); 9660 if (info != null && 9661 !info.packageName.equals("android")) { 9662 addAppLocked(info, false); 9663 } 9664 } 9665 } 9666 } catch (RemoteException ex) { 9667 // pm is in same process, this will never happen. 9668 } 9669 } 9670 9671 // Start up initial activity. 9672 mBooting = true; 9673 9674 try { 9675 if (AppGlobals.getPackageManager().hasSystemUidErrors()) { 9676 Message msg = Message.obtain(); 9677 msg.what = SHOW_UID_ERROR_MSG; 9678 mHandler.sendMessage(msg); 9679 } 9680 } catch (RemoteException e) { 9681 } 9682 9683 long ident = Binder.clearCallingIdentity(); 9684 try { 9685 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 9686 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 9687 | Intent.FLAG_RECEIVER_FOREGROUND); 9688 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); 9689 broadcastIntentLocked(null, null, intent, 9690 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 9691 false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId); 9692 intent = new Intent(Intent.ACTION_USER_STARTING); 9693 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 9694 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); 9695 broadcastIntentLocked(null, null, intent, 9696 null, new IIntentReceiver.Stub() { 9697 @Override 9698 public void performReceive(Intent intent, int resultCode, String data, 9699 Bundle extras, boolean ordered, boolean sticky, int sendingUser) 9700 throws RemoteException { 9701 } 9702 }, 0, null, null, 9703 android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 9704 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 9705 } catch (Throwable t) { 9706 Slog.wtf(TAG, "Failed sending first user broadcasts", t); 9707 } finally { 9708 Binder.restoreCallingIdentity(ident); 9709 } 9710 mStackSupervisor.resumeTopActivitiesLocked(); 9711 sendUserSwitchBroadcastsLocked(-1, mCurrentUserId); 9712 } 9713 } 9714 9715 private boolean makeAppCrashingLocked(ProcessRecord app, 9716 String shortMsg, String longMsg, String stackTrace) { 9717 app.crashing = true; 9718 app.crashingReport = generateProcessError(app, 9719 ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace); 9720 startAppProblemLocked(app); 9721 app.stopFreezingAllLocked(); 9722 return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace); 9723 } 9724 9725 private void makeAppNotRespondingLocked(ProcessRecord app, 9726 String activity, String shortMsg, String longMsg) { 9727 app.notResponding = true; 9728 app.notRespondingReport = generateProcessError(app, 9729 ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING, 9730 activity, shortMsg, longMsg, null); 9731 startAppProblemLocked(app); 9732 app.stopFreezingAllLocked(); 9733 } 9734 9735 /** 9736 * Generate a process error record, suitable for attachment to a ProcessRecord. 9737 * 9738 * @param app The ProcessRecord in which the error occurred. 9739 * @param condition Crashing, Application Not Responding, etc. Values are defined in 9740 * ActivityManager.AppErrorStateInfo 9741 * @param activity The activity associated with the crash, if known. 9742 * @param shortMsg Short message describing the crash. 9743 * @param longMsg Long message describing the crash. 9744 * @param stackTrace Full crash stack trace, may be null. 9745 * 9746 * @return Returns a fully-formed AppErrorStateInfo record. 9747 */ 9748 private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app, 9749 int condition, String activity, String shortMsg, String longMsg, String stackTrace) { 9750 ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo(); 9751 9752 report.condition = condition; 9753 report.processName = app.processName; 9754 report.pid = app.pid; 9755 report.uid = app.info.uid; 9756 report.tag = activity; 9757 report.shortMsg = shortMsg; 9758 report.longMsg = longMsg; 9759 report.stackTrace = stackTrace; 9760 9761 return report; 9762 } 9763 9764 void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) { 9765 synchronized (this) { 9766 app.crashing = false; 9767 app.crashingReport = null; 9768 app.notResponding = false; 9769 app.notRespondingReport = null; 9770 if (app.anrDialog == fromDialog) { 9771 app.anrDialog = null; 9772 } 9773 if (app.waitDialog == fromDialog) { 9774 app.waitDialog = null; 9775 } 9776 if (app.pid > 0 && app.pid != MY_PID) { 9777 handleAppCrashLocked(app, null, null, null); 9778 killUnneededProcessLocked(app, "user request after error"); 9779 } 9780 } 9781 } 9782 9783 private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg, 9784 String stackTrace) { 9785 long now = SystemClock.uptimeMillis(); 9786 9787 Long crashTime; 9788 if (!app.isolated) { 9789 crashTime = mProcessCrashTimes.get(app.info.processName, app.uid); 9790 } else { 9791 crashTime = null; 9792 } 9793 if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) { 9794 // This process loses! 9795 Slog.w(TAG, "Process " + app.info.processName 9796 + " has crashed too many times: killing!"); 9797 EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH, 9798 app.userId, app.info.processName, app.uid); 9799 mStackSupervisor.handleAppCrashLocked(app); 9800 if (!app.persistent) { 9801 // We don't want to start this process again until the user 9802 // explicitly does so... but for persistent process, we really 9803 // need to keep it running. If a persistent process is actually 9804 // repeatedly crashing, then badness for everyone. 9805 EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid, 9806 app.info.processName); 9807 if (!app.isolated) { 9808 // XXX We don't have a way to mark isolated processes 9809 // as bad, since they don't have a peristent identity. 9810 mBadProcesses.put(app.info.processName, app.uid, 9811 new BadProcessInfo(now, shortMsg, longMsg, stackTrace)); 9812 mProcessCrashTimes.remove(app.info.processName, app.uid); 9813 } 9814 app.bad = true; 9815 app.removed = true; 9816 // Don't let services in this process be restarted and potentially 9817 // annoy the user repeatedly. Unless it is persistent, since those 9818 // processes run critical code. 9819 removeProcessLocked(app, false, false, "crash"); 9820 mStackSupervisor.resumeTopActivitiesLocked(); 9821 return false; 9822 } 9823 mStackSupervisor.resumeTopActivitiesLocked(); 9824 } else { 9825 mStackSupervisor.finishTopRunningActivityLocked(app); 9826 } 9827 9828 // Bump up the crash count of any services currently running in the proc. 9829 for (int i=app.services.size()-1; i>=0; i--) { 9830 // Any services running in the application need to be placed 9831 // back in the pending list. 9832 ServiceRecord sr = app.services.valueAt(i); 9833 sr.crashCount++; 9834 } 9835 9836 // If the crashing process is what we consider to be the "home process" and it has been 9837 // replaced by a third-party app, clear the package preferred activities from packages 9838 // with a home activity running in the process to prevent a repeatedly crashing app 9839 // from blocking the user to manually clear the list. 9840 final ArrayList<ActivityRecord> activities = app.activities; 9841 if (app == mHomeProcess && activities.size() > 0 9842 && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) { 9843 for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) { 9844 final ActivityRecord r = activities.get(activityNdx); 9845 if (r.isHomeActivity()) { 9846 Log.i(TAG, "Clearing package preferred activities from " + r.packageName); 9847 try { 9848 ActivityThread.getPackageManager() 9849 .clearPackagePreferredActivities(r.packageName); 9850 } catch (RemoteException c) { 9851 // pm is in same process, this will never happen. 9852 } 9853 } 9854 } 9855 } 9856 9857 if (!app.isolated) { 9858 // XXX Can't keep track of crash times for isolated processes, 9859 // because they don't have a perisistent identity. 9860 mProcessCrashTimes.put(app.info.processName, app.uid, now); 9861 } 9862 9863 return true; 9864 } 9865 9866 void startAppProblemLocked(ProcessRecord app) { 9867 if (app.userId == mCurrentUserId) { 9868 app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver( 9869 mContext, app.info.packageName, app.info.flags); 9870 } else { 9871 // If this app is not running under the current user, then we 9872 // can't give it a report button because that would require 9873 // launching the report UI under a different user. 9874 app.errorReportReceiver = null; 9875 } 9876 skipCurrentReceiverLocked(app); 9877 } 9878 9879 void skipCurrentReceiverLocked(ProcessRecord app) { 9880 for (BroadcastQueue queue : mBroadcastQueues) { 9881 queue.skipCurrentReceiverLocked(app); 9882 } 9883 } 9884 9885 /** 9886 * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes. 9887 * The application process will exit immediately after this call returns. 9888 * @param app object of the crashing app, null for the system server 9889 * @param crashInfo describing the exception 9890 */ 9891 public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) { 9892 ProcessRecord r = findAppProcess(app, "Crash"); 9893 final String processName = app == null ? "system_server" 9894 : (r == null ? "unknown" : r.processName); 9895 9896 handleApplicationCrashInner("crash", r, processName, crashInfo); 9897 } 9898 9899 /* Native crash reporting uses this inner version because it needs to be somewhat 9900 * decoupled from the AM-managed cleanup lifecycle 9901 */ 9902 void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName, 9903 ApplicationErrorReport.CrashInfo crashInfo) { 9904 EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(), 9905 UserHandle.getUserId(Binder.getCallingUid()), processName, 9906 r == null ? -1 : r.info.flags, 9907 crashInfo.exceptionClassName, 9908 crashInfo.exceptionMessage, 9909 crashInfo.throwFileName, 9910 crashInfo.throwLineNumber); 9911 9912 addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo); 9913 9914 crashApplication(r, crashInfo); 9915 } 9916 9917 public void handleApplicationStrictModeViolation( 9918 IBinder app, 9919 int violationMask, 9920 StrictMode.ViolationInfo info) { 9921 ProcessRecord r = findAppProcess(app, "StrictMode"); 9922 if (r == null) { 9923 return; 9924 } 9925 9926 if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) { 9927 Integer stackFingerprint = info.hashCode(); 9928 boolean logIt = true; 9929 synchronized (mAlreadyLoggedViolatedStacks) { 9930 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) { 9931 logIt = false; 9932 // TODO: sub-sample into EventLog for these, with 9933 // the info.durationMillis? Then we'd get 9934 // the relative pain numbers, without logging all 9935 // the stack traces repeatedly. We'd want to do 9936 // likewise in the client code, which also does 9937 // dup suppression, before the Binder call. 9938 } else { 9939 if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) { 9940 mAlreadyLoggedViolatedStacks.clear(); 9941 } 9942 mAlreadyLoggedViolatedStacks.add(stackFingerprint); 9943 } 9944 } 9945 if (logIt) { 9946 logStrictModeViolationToDropBox(r, info); 9947 } 9948 } 9949 9950 if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) { 9951 AppErrorResult result = new AppErrorResult(); 9952 synchronized (this) { 9953 final long origId = Binder.clearCallingIdentity(); 9954 9955 Message msg = Message.obtain(); 9956 msg.what = SHOW_STRICT_MODE_VIOLATION_MSG; 9957 HashMap<String, Object> data = new HashMap<String, Object>(); 9958 data.put("result", result); 9959 data.put("app", r); 9960 data.put("violationMask", violationMask); 9961 data.put("info", info); 9962 msg.obj = data; 9963 mHandler.sendMessage(msg); 9964 9965 Binder.restoreCallingIdentity(origId); 9966 } 9967 int res = result.get(); 9968 Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res); 9969 } 9970 } 9971 9972 // Depending on the policy in effect, there could be a bunch of 9973 // these in quick succession so we try to batch these together to 9974 // minimize disk writes, number of dropbox entries, and maximize 9975 // compression, by having more fewer, larger records. 9976 private void logStrictModeViolationToDropBox( 9977 ProcessRecord process, 9978 StrictMode.ViolationInfo info) { 9979 if (info == null) { 9980 return; 9981 } 9982 final boolean isSystemApp = process == null || 9983 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM | 9984 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0; 9985 final String processName = process == null ? "unknown" : process.processName; 9986 final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode"; 9987 final DropBoxManager dbox = (DropBoxManager) 9988 mContext.getSystemService(Context.DROPBOX_SERVICE); 9989 9990 // Exit early if the dropbox isn't configured to accept this report type. 9991 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 9992 9993 boolean bufferWasEmpty; 9994 boolean needsFlush; 9995 final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024); 9996 synchronized (sb) { 9997 bufferWasEmpty = sb.length() == 0; 9998 appendDropBoxProcessHeaders(process, processName, sb); 9999 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 10000 sb.append("System-App: ").append(isSystemApp).append("\n"); 10001 sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n"); 10002 if (info.violationNumThisLoop != 0) { 10003 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n"); 10004 } 10005 if (info.numAnimationsRunning != 0) { 10006 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n"); 10007 } 10008 if (info.broadcastIntentAction != null) { 10009 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n"); 10010 } 10011 if (info.durationMillis != -1) { 10012 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n"); 10013 } 10014 if (info.numInstances != -1) { 10015 sb.append("Instance-Count: ").append(info.numInstances).append("\n"); 10016 } 10017 if (info.tags != null) { 10018 for (String tag : info.tags) { 10019 sb.append("Span-Tag: ").append(tag).append("\n"); 10020 } 10021 } 10022 sb.append("\n"); 10023 if (info.crashInfo != null && info.crashInfo.stackTrace != null) { 10024 sb.append(info.crashInfo.stackTrace); 10025 } 10026 sb.append("\n"); 10027 10028 // Only buffer up to ~64k. Various logging bits truncate 10029 // things at 128k. 10030 needsFlush = (sb.length() > 64 * 1024); 10031 } 10032 10033 // Flush immediately if the buffer's grown too large, or this 10034 // is a non-system app. Non-system apps are isolated with a 10035 // different tag & policy and not batched. 10036 // 10037 // Batching is useful during internal testing with 10038 // StrictMode settings turned up high. Without batching, 10039 // thousands of separate files could be created on boot. 10040 if (!isSystemApp || needsFlush) { 10041 new Thread("Error dump: " + dropboxTag) { 10042 @Override 10043 public void run() { 10044 String report; 10045 synchronized (sb) { 10046 report = sb.toString(); 10047 sb.delete(0, sb.length()); 10048 sb.trimToSize(); 10049 } 10050 if (report.length() != 0) { 10051 dbox.addText(dropboxTag, report); 10052 } 10053 } 10054 }.start(); 10055 return; 10056 } 10057 10058 // System app batching: 10059 if (!bufferWasEmpty) { 10060 // An existing dropbox-writing thread is outstanding, so 10061 // we don't need to start it up. The existing thread will 10062 // catch the buffer appends we just did. 10063 return; 10064 } 10065 10066 // Worker thread to both batch writes and to avoid blocking the caller on I/O. 10067 // (After this point, we shouldn't access AMS internal data structures.) 10068 new Thread("Error dump: " + dropboxTag) { 10069 @Override 10070 public void run() { 10071 // 5 second sleep to let stacks arrive and be batched together 10072 try { 10073 Thread.sleep(5000); // 5 seconds 10074 } catch (InterruptedException e) {} 10075 10076 String errorReport; 10077 synchronized (mStrictModeBuffer) { 10078 errorReport = mStrictModeBuffer.toString(); 10079 if (errorReport.length() == 0) { 10080 return; 10081 } 10082 mStrictModeBuffer.delete(0, mStrictModeBuffer.length()); 10083 mStrictModeBuffer.trimToSize(); 10084 } 10085 dbox.addText(dropboxTag, errorReport); 10086 } 10087 }.start(); 10088 } 10089 10090 /** 10091 * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors. 10092 * @param app object of the crashing app, null for the system server 10093 * @param tag reported by the caller 10094 * @param crashInfo describing the context of the error 10095 * @return true if the process should exit immediately (WTF is fatal) 10096 */ 10097 public boolean handleApplicationWtf(IBinder app, String tag, 10098 ApplicationErrorReport.CrashInfo crashInfo) { 10099 ProcessRecord r = findAppProcess(app, "WTF"); 10100 final String processName = app == null ? "system_server" 10101 : (r == null ? "unknown" : r.processName); 10102 10103 EventLog.writeEvent(EventLogTags.AM_WTF, 10104 UserHandle.getUserId(Binder.getCallingUid()), Binder.getCallingPid(), 10105 processName, 10106 r == null ? -1 : r.info.flags, 10107 tag, crashInfo.exceptionMessage); 10108 10109 addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo); 10110 10111 if (r != null && r.pid != Process.myPid() && 10112 Settings.Global.getInt(mContext.getContentResolver(), 10113 Settings.Global.WTF_IS_FATAL, 0) != 0) { 10114 crashApplication(r, crashInfo); 10115 return true; 10116 } else { 10117 return false; 10118 } 10119 } 10120 10121 /** 10122 * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit}) 10123 * @return the corresponding {@link ProcessRecord} object, or null if none could be found 10124 */ 10125 private ProcessRecord findAppProcess(IBinder app, String reason) { 10126 if (app == null) { 10127 return null; 10128 } 10129 10130 synchronized (this) { 10131 final int NP = mProcessNames.getMap().size(); 10132 for (int ip=0; ip<NP; ip++) { 10133 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 10134 final int NA = apps.size(); 10135 for (int ia=0; ia<NA; ia++) { 10136 ProcessRecord p = apps.valueAt(ia); 10137 if (p.thread != null && p.thread.asBinder() == app) { 10138 return p; 10139 } 10140 } 10141 } 10142 10143 Slog.w(TAG, "Can't find mystery application for " + reason 10144 + " from pid=" + Binder.getCallingPid() 10145 + " uid=" + Binder.getCallingUid() + ": " + app); 10146 return null; 10147 } 10148 } 10149 10150 /** 10151 * Utility function for addErrorToDropBox and handleStrictModeViolation's logging 10152 * to append various headers to the dropbox log text. 10153 */ 10154 private void appendDropBoxProcessHeaders(ProcessRecord process, String processName, 10155 StringBuilder sb) { 10156 // Watchdog thread ends up invoking this function (with 10157 // a null ProcessRecord) to add the stack file to dropbox. 10158 // Do not acquire a lock on this (am) in such cases, as it 10159 // could cause a potential deadlock, if and when watchdog 10160 // is invoked due to unavailability of lock on am and it 10161 // would prevent watchdog from killing system_server. 10162 if (process == null) { 10163 sb.append("Process: ").append(processName).append("\n"); 10164 return; 10165 } 10166 // Note: ProcessRecord 'process' is guarded by the service 10167 // instance. (notably process.pkgList, which could otherwise change 10168 // concurrently during execution of this method) 10169 synchronized (this) { 10170 sb.append("Process: ").append(processName).append("\n"); 10171 int flags = process.info.flags; 10172 IPackageManager pm = AppGlobals.getPackageManager(); 10173 sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n"); 10174 for (int ip=0; ip<process.pkgList.size(); ip++) { 10175 String pkg = process.pkgList.keyAt(ip); 10176 sb.append("Package: ").append(pkg); 10177 try { 10178 PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId()); 10179 if (pi != null) { 10180 sb.append(" v").append(pi.versionCode); 10181 if (pi.versionName != null) { 10182 sb.append(" (").append(pi.versionName).append(")"); 10183 } 10184 } 10185 } catch (RemoteException e) { 10186 Slog.e(TAG, "Error getting package info: " + pkg, e); 10187 } 10188 sb.append("\n"); 10189 } 10190 } 10191 } 10192 10193 private static String processClass(ProcessRecord process) { 10194 if (process == null || process.pid == MY_PID) { 10195 return "system_server"; 10196 } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) { 10197 return "system_app"; 10198 } else { 10199 return "data_app"; 10200 } 10201 } 10202 10203 /** 10204 * Write a description of an error (crash, WTF, ANR) to the drop box. 10205 * @param eventType to include in the drop box tag ("crash", "wtf", etc.) 10206 * @param process which caused the error, null means the system server 10207 * @param activity which triggered the error, null if unknown 10208 * @param parent activity related to the error, null if unknown 10209 * @param subject line related to the error, null if absent 10210 * @param report in long form describing the error, null if absent 10211 * @param logFile to include in the report, null if none 10212 * @param crashInfo giving an application stack trace, null if absent 10213 */ 10214 public void addErrorToDropBox(String eventType, 10215 ProcessRecord process, String processName, ActivityRecord activity, 10216 ActivityRecord parent, String subject, 10217 final String report, final File logFile, 10218 final ApplicationErrorReport.CrashInfo crashInfo) { 10219 // NOTE -- this must never acquire the ActivityManagerService lock, 10220 // otherwise the watchdog may be prevented from resetting the system. 10221 10222 final String dropboxTag = processClass(process) + "_" + eventType; 10223 final DropBoxManager dbox = (DropBoxManager) 10224 mContext.getSystemService(Context.DROPBOX_SERVICE); 10225 10226 // Exit early if the dropbox isn't configured to accept this report type. 10227 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 10228 10229 final StringBuilder sb = new StringBuilder(1024); 10230 appendDropBoxProcessHeaders(process, processName, sb); 10231 if (activity != null) { 10232 sb.append("Activity: ").append(activity.shortComponentName).append("\n"); 10233 } 10234 if (parent != null && parent.app != null && parent.app.pid != process.pid) { 10235 sb.append("Parent-Process: ").append(parent.app.processName).append("\n"); 10236 } 10237 if (parent != null && parent != activity) { 10238 sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n"); 10239 } 10240 if (subject != null) { 10241 sb.append("Subject: ").append(subject).append("\n"); 10242 } 10243 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 10244 if (Debug.isDebuggerConnected()) { 10245 sb.append("Debugger: Connected\n"); 10246 } 10247 sb.append("\n"); 10248 10249 // Do the rest in a worker thread to avoid blocking the caller on I/O 10250 // (After this point, we shouldn't access AMS internal data structures.) 10251 Thread worker = new Thread("Error dump: " + dropboxTag) { 10252 @Override 10253 public void run() { 10254 if (report != null) { 10255 sb.append(report); 10256 } 10257 if (logFile != null) { 10258 try { 10259 sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE, 10260 "\n\n[[TRUNCATED]]")); 10261 } catch (IOException e) { 10262 Slog.e(TAG, "Error reading " + logFile, e); 10263 } 10264 } 10265 if (crashInfo != null && crashInfo.stackTrace != null) { 10266 sb.append(crashInfo.stackTrace); 10267 } 10268 10269 String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag; 10270 int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0); 10271 if (lines > 0) { 10272 sb.append("\n"); 10273 10274 // Merge several logcat streams, and take the last N lines 10275 InputStreamReader input = null; 10276 try { 10277 java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat", 10278 "-v", "time", "-b", "events", "-b", "system", "-b", "main", 10279 "-t", String.valueOf(lines)).redirectErrorStream(true).start(); 10280 10281 try { logcat.getOutputStream().close(); } catch (IOException e) {} 10282 try { logcat.getErrorStream().close(); } catch (IOException e) {} 10283 input = new InputStreamReader(logcat.getInputStream()); 10284 10285 int num; 10286 char[] buf = new char[8192]; 10287 while ((num = input.read(buf)) > 0) sb.append(buf, 0, num); 10288 } catch (IOException e) { 10289 Slog.e(TAG, "Error running logcat", e); 10290 } finally { 10291 if (input != null) try { input.close(); } catch (IOException e) {} 10292 } 10293 } 10294 10295 dbox.addText(dropboxTag, sb.toString()); 10296 } 10297 }; 10298 10299 if (process == null) { 10300 // If process is null, we are being called from some internal code 10301 // and may be about to die -- run this synchronously. 10302 worker.run(); 10303 } else { 10304 worker.start(); 10305 } 10306 } 10307 10308 /** 10309 * Bring up the "unexpected error" dialog box for a crashing app. 10310 * Deal with edge cases (intercepts from instrumented applications, 10311 * ActivityController, error intent receivers, that sort of thing). 10312 * @param r the application crashing 10313 * @param crashInfo describing the failure 10314 */ 10315 private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) { 10316 long timeMillis = System.currentTimeMillis(); 10317 String shortMsg = crashInfo.exceptionClassName; 10318 String longMsg = crashInfo.exceptionMessage; 10319 String stackTrace = crashInfo.stackTrace; 10320 if (shortMsg != null && longMsg != null) { 10321 longMsg = shortMsg + ": " + longMsg; 10322 } else if (shortMsg != null) { 10323 longMsg = shortMsg; 10324 } 10325 10326 AppErrorResult result = new AppErrorResult(); 10327 synchronized (this) { 10328 if (mController != null) { 10329 try { 10330 String name = r != null ? r.processName : null; 10331 int pid = r != null ? r.pid : Binder.getCallingPid(); 10332 if (!mController.appCrashed(name, pid, 10333 shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) { 10334 Slog.w(TAG, "Force-killing crashed app " + name 10335 + " at watcher's request"); 10336 Process.killProcess(pid); 10337 return; 10338 } 10339 } catch (RemoteException e) { 10340 mController = null; 10341 Watchdog.getInstance().setActivityController(null); 10342 } 10343 } 10344 10345 final long origId = Binder.clearCallingIdentity(); 10346 10347 // If this process is running instrumentation, finish it. 10348 if (r != null && r.instrumentationClass != null) { 10349 Slog.w(TAG, "Error in app " + r.processName 10350 + " running instrumentation " + r.instrumentationClass + ":"); 10351 if (shortMsg != null) Slog.w(TAG, " " + shortMsg); 10352 if (longMsg != null) Slog.w(TAG, " " + longMsg); 10353 Bundle info = new Bundle(); 10354 info.putString("shortMsg", shortMsg); 10355 info.putString("longMsg", longMsg); 10356 finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info); 10357 Binder.restoreCallingIdentity(origId); 10358 return; 10359 } 10360 10361 // If we can't identify the process or it's already exceeded its crash quota, 10362 // quit right away without showing a crash dialog. 10363 if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) { 10364 Binder.restoreCallingIdentity(origId); 10365 return; 10366 } 10367 10368 Message msg = Message.obtain(); 10369 msg.what = SHOW_ERROR_MSG; 10370 HashMap data = new HashMap(); 10371 data.put("result", result); 10372 data.put("app", r); 10373 msg.obj = data; 10374 mHandler.sendMessage(msg); 10375 10376 Binder.restoreCallingIdentity(origId); 10377 } 10378 10379 int res = result.get(); 10380 10381 Intent appErrorIntent = null; 10382 synchronized (this) { 10383 if (r != null && !r.isolated) { 10384 // XXX Can't keep track of crash time for isolated processes, 10385 // since they don't have a persistent identity. 10386 mProcessCrashTimes.put(r.info.processName, r.uid, 10387 SystemClock.uptimeMillis()); 10388 } 10389 if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) { 10390 appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo); 10391 } 10392 } 10393 10394 if (appErrorIntent != null) { 10395 try { 10396 mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId)); 10397 } catch (ActivityNotFoundException e) { 10398 Slog.w(TAG, "bug report receiver dissappeared", e); 10399 } 10400 } 10401 } 10402 10403 Intent createAppErrorIntentLocked(ProcessRecord r, 10404 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 10405 ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo); 10406 if (report == null) { 10407 return null; 10408 } 10409 Intent result = new Intent(Intent.ACTION_APP_ERROR); 10410 result.setComponent(r.errorReportReceiver); 10411 result.putExtra(Intent.EXTRA_BUG_REPORT, report); 10412 result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 10413 return result; 10414 } 10415 10416 private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r, 10417 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 10418 if (r.errorReportReceiver == null) { 10419 return null; 10420 } 10421 10422 if (!r.crashing && !r.notResponding && !r.forceCrashReport) { 10423 return null; 10424 } 10425 10426 ApplicationErrorReport report = new ApplicationErrorReport(); 10427 report.packageName = r.info.packageName; 10428 report.installerPackageName = r.errorReportReceiver.getPackageName(); 10429 report.processName = r.processName; 10430 report.time = timeMillis; 10431 report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0; 10432 10433 if (r.crashing || r.forceCrashReport) { 10434 report.type = ApplicationErrorReport.TYPE_CRASH; 10435 report.crashInfo = crashInfo; 10436 } else if (r.notResponding) { 10437 report.type = ApplicationErrorReport.TYPE_ANR; 10438 report.anrInfo = new ApplicationErrorReport.AnrInfo(); 10439 10440 report.anrInfo.activity = r.notRespondingReport.tag; 10441 report.anrInfo.cause = r.notRespondingReport.shortMsg; 10442 report.anrInfo.info = r.notRespondingReport.longMsg; 10443 } 10444 10445 return report; 10446 } 10447 10448 public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() { 10449 enforceNotIsolatedCaller("getProcessesInErrorState"); 10450 // assume our apps are happy - lazy create the list 10451 List<ActivityManager.ProcessErrorStateInfo> errList = null; 10452 10453 final boolean allUsers = ActivityManager.checkUidPermission( 10454 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 10455 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 10456 int userId = UserHandle.getUserId(Binder.getCallingUid()); 10457 10458 synchronized (this) { 10459 10460 // iterate across all processes 10461 for (int i=mLruProcesses.size()-1; i>=0; i--) { 10462 ProcessRecord app = mLruProcesses.get(i); 10463 if (!allUsers && app.userId != userId) { 10464 continue; 10465 } 10466 if ((app.thread != null) && (app.crashing || app.notResponding)) { 10467 // This one's in trouble, so we'll generate a report for it 10468 // crashes are higher priority (in case there's a crash *and* an anr) 10469 ActivityManager.ProcessErrorStateInfo report = null; 10470 if (app.crashing) { 10471 report = app.crashingReport; 10472 } else if (app.notResponding) { 10473 report = app.notRespondingReport; 10474 } 10475 10476 if (report != null) { 10477 if (errList == null) { 10478 errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1); 10479 } 10480 errList.add(report); 10481 } else { 10482 Slog.w(TAG, "Missing app error report, app = " + app.processName + 10483 " crashing = " + app.crashing + 10484 " notResponding = " + app.notResponding); 10485 } 10486 } 10487 } 10488 } 10489 10490 return errList; 10491 } 10492 10493 static int oomAdjToImportance(int adj, ActivityManager.RunningAppProcessInfo currApp) { 10494 if (adj >= ProcessList.CACHED_APP_MIN_ADJ) { 10495 if (currApp != null) { 10496 currApp.lru = adj - ProcessList.CACHED_APP_MIN_ADJ + 1; 10497 } 10498 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 10499 } else if (adj >= ProcessList.SERVICE_B_ADJ) { 10500 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 10501 } else if (adj >= ProcessList.HOME_APP_ADJ) { 10502 if (currApp != null) { 10503 currApp.lru = 0; 10504 } 10505 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 10506 } else if (adj >= ProcessList.SERVICE_ADJ) { 10507 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 10508 } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 10509 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE; 10510 } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) { 10511 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE; 10512 } else if (adj >= ProcessList.VISIBLE_APP_ADJ) { 10513 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE; 10514 } else { 10515 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND; 10516 } 10517 } 10518 10519 private void fillInProcMemInfo(ProcessRecord app, 10520 ActivityManager.RunningAppProcessInfo outInfo) { 10521 outInfo.pid = app.pid; 10522 outInfo.uid = app.info.uid; 10523 if (mHeavyWeightProcess == app) { 10524 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE; 10525 } 10526 if (app.persistent) { 10527 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT; 10528 } 10529 if (app.activities.size() > 0) { 10530 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES; 10531 } 10532 outInfo.lastTrimLevel = app.trimMemoryLevel; 10533 int adj = app.curAdj; 10534 outInfo.importance = oomAdjToImportance(adj, outInfo); 10535 outInfo.importanceReasonCode = app.adjTypeCode; 10536 outInfo.processState = app.curProcState; 10537 } 10538 10539 public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() { 10540 enforceNotIsolatedCaller("getRunningAppProcesses"); 10541 // Lazy instantiation of list 10542 List<ActivityManager.RunningAppProcessInfo> runList = null; 10543 final boolean allUsers = ActivityManager.checkUidPermission( 10544 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 10545 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 10546 int userId = UserHandle.getUserId(Binder.getCallingUid()); 10547 synchronized (this) { 10548 // Iterate across all processes 10549 for (int i=mLruProcesses.size()-1; i>=0; i--) { 10550 ProcessRecord app = mLruProcesses.get(i); 10551 if (!allUsers && app.userId != userId) { 10552 continue; 10553 } 10554 if ((app.thread != null) && (!app.crashing && !app.notResponding)) { 10555 // Generate process state info for running application 10556 ActivityManager.RunningAppProcessInfo currApp = 10557 new ActivityManager.RunningAppProcessInfo(app.processName, 10558 app.pid, app.getPackageList()); 10559 fillInProcMemInfo(app, currApp); 10560 if (app.adjSource instanceof ProcessRecord) { 10561 currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid; 10562 currApp.importanceReasonImportance = oomAdjToImportance( 10563 app.adjSourceOom, null); 10564 } else if (app.adjSource instanceof ActivityRecord) { 10565 ActivityRecord r = (ActivityRecord)app.adjSource; 10566 if (r.app != null) currApp.importanceReasonPid = r.app.pid; 10567 } 10568 if (app.adjTarget instanceof ComponentName) { 10569 currApp.importanceReasonComponent = (ComponentName)app.adjTarget; 10570 } 10571 //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance 10572 // + " lru=" + currApp.lru); 10573 if (runList == null) { 10574 runList = new ArrayList<ActivityManager.RunningAppProcessInfo>(); 10575 } 10576 runList.add(currApp); 10577 } 10578 } 10579 } 10580 return runList; 10581 } 10582 10583 public List<ApplicationInfo> getRunningExternalApplications() { 10584 enforceNotIsolatedCaller("getRunningExternalApplications"); 10585 List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses(); 10586 List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>(); 10587 if (runningApps != null && runningApps.size() > 0) { 10588 Set<String> extList = new HashSet<String>(); 10589 for (ActivityManager.RunningAppProcessInfo app : runningApps) { 10590 if (app.pkgList != null) { 10591 for (String pkg : app.pkgList) { 10592 extList.add(pkg); 10593 } 10594 } 10595 } 10596 IPackageManager pm = AppGlobals.getPackageManager(); 10597 for (String pkg : extList) { 10598 try { 10599 ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId()); 10600 if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) { 10601 retList.add(info); 10602 } 10603 } catch (RemoteException e) { 10604 } 10605 } 10606 } 10607 return retList; 10608 } 10609 10610 @Override 10611 public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) { 10612 enforceNotIsolatedCaller("getMyMemoryState"); 10613 synchronized (this) { 10614 ProcessRecord proc; 10615 synchronized (mPidsSelfLocked) { 10616 proc = mPidsSelfLocked.get(Binder.getCallingPid()); 10617 } 10618 fillInProcMemInfo(proc, outInfo); 10619 } 10620 } 10621 10622 @Override 10623 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 10624 if (checkCallingPermission(android.Manifest.permission.DUMP) 10625 != PackageManager.PERMISSION_GRANTED) { 10626 pw.println("Permission Denial: can't dump ActivityManager from from pid=" 10627 + Binder.getCallingPid() 10628 + ", uid=" + Binder.getCallingUid() 10629 + " without permission " 10630 + android.Manifest.permission.DUMP); 10631 return; 10632 } 10633 10634 boolean dumpAll = false; 10635 boolean dumpClient = false; 10636 String dumpPackage = null; 10637 10638 int opti = 0; 10639 while (opti < args.length) { 10640 String opt = args[opti]; 10641 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 10642 break; 10643 } 10644 opti++; 10645 if ("-a".equals(opt)) { 10646 dumpAll = true; 10647 } else if ("-c".equals(opt)) { 10648 dumpClient = true; 10649 } else if ("-h".equals(opt)) { 10650 pw.println("Activity manager dump options:"); 10651 pw.println(" [-a] [-c] [-h] [cmd] ..."); 10652 pw.println(" cmd may be one of:"); 10653 pw.println(" a[ctivities]: activity stack state"); 10654 pw.println(" b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state"); 10655 pw.println(" i[ntents] [PACKAGE_NAME]: pending intent state"); 10656 pw.println(" p[rocesses] [PACKAGE_NAME]: process state"); 10657 pw.println(" o[om]: out of memory management"); 10658 pw.println(" prov[iders] [COMP_SPEC ...]: content provider state"); 10659 pw.println(" provider [COMP_SPEC]: provider client-side state"); 10660 pw.println(" s[ervices] [COMP_SPEC ...]: service state"); 10661 pw.println(" service [COMP_SPEC]: service client-side state"); 10662 pw.println(" package [PACKAGE_NAME]: all state related to given package"); 10663 pw.println(" all: dump all activities"); 10664 pw.println(" top: dump the top activity"); 10665 pw.println(" cmd may also be a COMP_SPEC to dump activities."); 10666 pw.println(" COMP_SPEC may be a component name (com.foo/.myApp),"); 10667 pw.println(" a partial substring in a component name, a"); 10668 pw.println(" hex object identifier."); 10669 pw.println(" -a: include all available server state."); 10670 pw.println(" -c: include client state."); 10671 return; 10672 } else { 10673 pw.println("Unknown argument: " + opt + "; use -h for help"); 10674 } 10675 } 10676 10677 long origId = Binder.clearCallingIdentity(); 10678 boolean more = false; 10679 // Is the caller requesting to dump a particular piece of data? 10680 if (opti < args.length) { 10681 String cmd = args[opti]; 10682 opti++; 10683 if ("activities".equals(cmd) || "a".equals(cmd)) { 10684 synchronized (this) { 10685 dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null); 10686 } 10687 } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) { 10688 String[] newArgs; 10689 String name; 10690 if (opti >= args.length) { 10691 name = null; 10692 newArgs = EMPTY_STRING_ARRAY; 10693 } else { 10694 name = args[opti]; 10695 opti++; 10696 newArgs = new String[args.length - opti]; 10697 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 10698 args.length - opti); 10699 } 10700 synchronized (this) { 10701 dumpBroadcastsLocked(fd, pw, args, opti, true, name); 10702 } 10703 } else if ("intents".equals(cmd) || "i".equals(cmd)) { 10704 String[] newArgs; 10705 String name; 10706 if (opti >= args.length) { 10707 name = null; 10708 newArgs = EMPTY_STRING_ARRAY; 10709 } else { 10710 name = args[opti]; 10711 opti++; 10712 newArgs = new String[args.length - opti]; 10713 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 10714 args.length - opti); 10715 } 10716 synchronized (this) { 10717 dumpPendingIntentsLocked(fd, pw, args, opti, true, name); 10718 } 10719 } else if ("processes".equals(cmd) || "p".equals(cmd)) { 10720 String[] newArgs; 10721 String name; 10722 if (opti >= args.length) { 10723 name = null; 10724 newArgs = EMPTY_STRING_ARRAY; 10725 } else { 10726 name = args[opti]; 10727 opti++; 10728 newArgs = new String[args.length - opti]; 10729 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 10730 args.length - opti); 10731 } 10732 synchronized (this) { 10733 dumpProcessesLocked(fd, pw, args, opti, true, name); 10734 } 10735 } else if ("oom".equals(cmd) || "o".equals(cmd)) { 10736 synchronized (this) { 10737 dumpOomLocked(fd, pw, args, opti, true); 10738 } 10739 } else if ("provider".equals(cmd)) { 10740 String[] newArgs; 10741 String name; 10742 if (opti >= args.length) { 10743 name = null; 10744 newArgs = EMPTY_STRING_ARRAY; 10745 } else { 10746 name = args[opti]; 10747 opti++; 10748 newArgs = new String[args.length - opti]; 10749 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti); 10750 } 10751 if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) { 10752 pw.println("No providers match: " + name); 10753 pw.println("Use -h for help."); 10754 } 10755 } else if ("providers".equals(cmd) || "prov".equals(cmd)) { 10756 synchronized (this) { 10757 dumpProvidersLocked(fd, pw, args, opti, true, null); 10758 } 10759 } else if ("service".equals(cmd)) { 10760 String[] newArgs; 10761 String name; 10762 if (opti >= args.length) { 10763 name = null; 10764 newArgs = EMPTY_STRING_ARRAY; 10765 } else { 10766 name = args[opti]; 10767 opti++; 10768 newArgs = new String[args.length - opti]; 10769 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 10770 args.length - opti); 10771 } 10772 if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) { 10773 pw.println("No services match: " + name); 10774 pw.println("Use -h for help."); 10775 } 10776 } else if ("package".equals(cmd)) { 10777 String[] newArgs; 10778 if (opti >= args.length) { 10779 pw.println("package: no package name specified"); 10780 pw.println("Use -h for help."); 10781 } else { 10782 dumpPackage = args[opti]; 10783 opti++; 10784 newArgs = new String[args.length - opti]; 10785 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 10786 args.length - opti); 10787 args = newArgs; 10788 opti = 0; 10789 more = true; 10790 } 10791 } else if ("services".equals(cmd) || "s".equals(cmd)) { 10792 synchronized (this) { 10793 mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null); 10794 } 10795 } else { 10796 // Dumping a single activity? 10797 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) { 10798 pw.println("Bad activity command, or no activities match: " + cmd); 10799 pw.println("Use -h for help."); 10800 } 10801 } 10802 if (!more) { 10803 Binder.restoreCallingIdentity(origId); 10804 return; 10805 } 10806 } 10807 10808 // No piece of data specified, dump everything. 10809 synchronized (this) { 10810 dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 10811 pw.println(); 10812 if (dumpAll) { 10813 pw.println("-------------------------------------------------------------------------------"); 10814 } 10815 dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 10816 pw.println(); 10817 if (dumpAll) { 10818 pw.println("-------------------------------------------------------------------------------"); 10819 } 10820 dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage); 10821 pw.println(); 10822 if (dumpAll) { 10823 pw.println("-------------------------------------------------------------------------------"); 10824 } 10825 mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 10826 pw.println(); 10827 if (dumpAll) { 10828 pw.println("-------------------------------------------------------------------------------"); 10829 } 10830 dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 10831 pw.println(); 10832 if (dumpAll) { 10833 pw.println("-------------------------------------------------------------------------------"); 10834 } 10835 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage); 10836 } 10837 Binder.restoreCallingIdentity(origId); 10838 } 10839 10840 void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 10841 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) { 10842 pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)"); 10843 10844 boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient, 10845 dumpPackage); 10846 boolean needSep = printedAnything; 10847 10848 boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity, 10849 dumpPackage, needSep, " mFocusedActivity: "); 10850 if (printed) { 10851 printedAnything = true; 10852 needSep = false; 10853 } 10854 10855 if (dumpPackage == null) { 10856 if (needSep) { 10857 pw.println(); 10858 } 10859 needSep = true; 10860 printedAnything = true; 10861 mStackSupervisor.dump(pw, " "); 10862 } 10863 10864 if (mRecentTasks.size() > 0) { 10865 boolean printedHeader = false; 10866 10867 final int N = mRecentTasks.size(); 10868 for (int i=0; i<N; i++) { 10869 TaskRecord tr = mRecentTasks.get(i); 10870 if (dumpPackage != null) { 10871 if (tr.realActivity == null || 10872 !dumpPackage.equals(tr.realActivity)) { 10873 continue; 10874 } 10875 } 10876 if (!printedHeader) { 10877 if (needSep) { 10878 pw.println(); 10879 } 10880 pw.println(" Recent tasks:"); 10881 printedHeader = true; 10882 printedAnything = true; 10883 } 10884 pw.print(" * Recent #"); pw.print(i); pw.print(": "); 10885 pw.println(tr); 10886 if (dumpAll) { 10887 mRecentTasks.get(i).dump(pw, " "); 10888 } 10889 } 10890 } 10891 10892 if (!printedAnything) { 10893 pw.println(" (nothing)"); 10894 } 10895 } 10896 10897 void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 10898 int opti, boolean dumpAll, String dumpPackage) { 10899 boolean needSep = false; 10900 boolean printedAnything = false; 10901 int numPers = 0; 10902 10903 pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)"); 10904 10905 if (dumpAll) { 10906 final int NP = mProcessNames.getMap().size(); 10907 for (int ip=0; ip<NP; ip++) { 10908 SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip); 10909 final int NA = procs.size(); 10910 for (int ia=0; ia<NA; ia++) { 10911 ProcessRecord r = procs.valueAt(ia); 10912 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 10913 continue; 10914 } 10915 if (!needSep) { 10916 pw.println(" All known processes:"); 10917 needSep = true; 10918 printedAnything = true; 10919 } 10920 pw.print(r.persistent ? " *PERS*" : " *APP*"); 10921 pw.print(" UID "); pw.print(procs.keyAt(ia)); 10922 pw.print(" "); pw.println(r); 10923 r.dump(pw, " "); 10924 if (r.persistent) { 10925 numPers++; 10926 } 10927 } 10928 } 10929 } 10930 10931 if (mIsolatedProcesses.size() > 0) { 10932 boolean printed = false; 10933 for (int i=0; i<mIsolatedProcesses.size(); i++) { 10934 ProcessRecord r = mIsolatedProcesses.valueAt(i); 10935 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 10936 continue; 10937 } 10938 if (!printed) { 10939 if (needSep) { 10940 pw.println(); 10941 } 10942 pw.println(" Isolated process list (sorted by uid):"); 10943 printedAnything = true; 10944 printed = true; 10945 needSep = true; 10946 } 10947 pw.println(String.format("%sIsolated #%2d: %s", 10948 " ", i, r.toString())); 10949 } 10950 } 10951 10952 if (mLruProcesses.size() > 0) { 10953 if (needSep) { 10954 pw.println(); 10955 } 10956 pw.print(" Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size()); 10957 pw.print(" total, non-act at "); 10958 pw.print(mLruProcesses.size()-mLruProcessActivityStart); 10959 pw.print(", non-svc at "); 10960 pw.print(mLruProcesses.size()-mLruProcessServiceStart); 10961 pw.println("):"); 10962 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", false, dumpPackage); 10963 needSep = true; 10964 printedAnything = true; 10965 } 10966 10967 if (dumpAll || dumpPackage != null) { 10968 synchronized (mPidsSelfLocked) { 10969 boolean printed = false; 10970 for (int i=0; i<mPidsSelfLocked.size(); i++) { 10971 ProcessRecord r = mPidsSelfLocked.valueAt(i); 10972 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 10973 continue; 10974 } 10975 if (!printed) { 10976 if (needSep) pw.println(); 10977 needSep = true; 10978 pw.println(" PID mappings:"); 10979 printed = true; 10980 printedAnything = true; 10981 } 10982 pw.print(" PID #"); pw.print(mPidsSelfLocked.keyAt(i)); 10983 pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i)); 10984 } 10985 } 10986 } 10987 10988 if (mForegroundProcesses.size() > 0) { 10989 synchronized (mPidsSelfLocked) { 10990 boolean printed = false; 10991 for (int i=0; i<mForegroundProcesses.size(); i++) { 10992 ProcessRecord r = mPidsSelfLocked.get( 10993 mForegroundProcesses.valueAt(i).pid); 10994 if (dumpPackage != null && (r == null 10995 || !r.pkgList.containsKey(dumpPackage))) { 10996 continue; 10997 } 10998 if (!printed) { 10999 if (needSep) pw.println(); 11000 needSep = true; 11001 pw.println(" Foreground Processes:"); 11002 printed = true; 11003 printedAnything = true; 11004 } 11005 pw.print(" PID #"); pw.print(mForegroundProcesses.keyAt(i)); 11006 pw.print(": "); pw.println(mForegroundProcesses.valueAt(i)); 11007 } 11008 } 11009 } 11010 11011 if (mPersistentStartingProcesses.size() > 0) { 11012 if (needSep) pw.println(); 11013 needSep = true; 11014 printedAnything = true; 11015 pw.println(" Persisent processes that are starting:"); 11016 dumpProcessList(pw, this, mPersistentStartingProcesses, " ", 11017 "Starting Norm", "Restarting PERS", dumpPackage); 11018 } 11019 11020 if (mRemovedProcesses.size() > 0) { 11021 if (needSep) pw.println(); 11022 needSep = true; 11023 printedAnything = true; 11024 pw.println(" Processes that are being removed:"); 11025 dumpProcessList(pw, this, mRemovedProcesses, " ", 11026 "Removed Norm", "Removed PERS", dumpPackage); 11027 } 11028 11029 if (mProcessesOnHold.size() > 0) { 11030 if (needSep) pw.println(); 11031 needSep = true; 11032 printedAnything = true; 11033 pw.println(" Processes that are on old until the system is ready:"); 11034 dumpProcessList(pw, this, mProcessesOnHold, " ", 11035 "OnHold Norm", "OnHold PERS", dumpPackage); 11036 } 11037 11038 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage); 11039 11040 if (mProcessCrashTimes.getMap().size() > 0) { 11041 boolean printed = false; 11042 long now = SystemClock.uptimeMillis(); 11043 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap(); 11044 final int NP = pmap.size(); 11045 for (int ip=0; ip<NP; ip++) { 11046 String pname = pmap.keyAt(ip); 11047 SparseArray<Long> uids = pmap.valueAt(ip); 11048 final int N = uids.size(); 11049 for (int i=0; i<N; i++) { 11050 int puid = uids.keyAt(i); 11051 ProcessRecord r = mProcessNames.get(pname, puid); 11052 if (dumpPackage != null && (r == null 11053 || !r.pkgList.containsKey(dumpPackage))) { 11054 continue; 11055 } 11056 if (!printed) { 11057 if (needSep) pw.println(); 11058 needSep = true; 11059 pw.println(" Time since processes crashed:"); 11060 printed = true; 11061 printedAnything = true; 11062 } 11063 pw.print(" Process "); pw.print(pname); 11064 pw.print(" uid "); pw.print(puid); 11065 pw.print(": last crashed "); 11066 TimeUtils.formatDuration(now-uids.valueAt(i), pw); 11067 pw.println(" ago"); 11068 } 11069 } 11070 } 11071 11072 if (mBadProcesses.getMap().size() > 0) { 11073 boolean printed = false; 11074 final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap(); 11075 final int NP = pmap.size(); 11076 for (int ip=0; ip<NP; ip++) { 11077 String pname = pmap.keyAt(ip); 11078 SparseArray<BadProcessInfo> uids = pmap.valueAt(ip); 11079 final int N = uids.size(); 11080 for (int i=0; i<N; i++) { 11081 int puid = uids.keyAt(i); 11082 ProcessRecord r = mProcessNames.get(pname, puid); 11083 if (dumpPackage != null && (r == null 11084 || !r.pkgList.containsKey(dumpPackage))) { 11085 continue; 11086 } 11087 if (!printed) { 11088 if (needSep) pw.println(); 11089 needSep = true; 11090 pw.println(" Bad processes:"); 11091 printedAnything = true; 11092 } 11093 BadProcessInfo info = uids.valueAt(i); 11094 pw.print(" Bad process "); pw.print(pname); 11095 pw.print(" uid "); pw.print(puid); 11096 pw.print(": crashed at time "); pw.println(info.time); 11097 if (info.shortMsg != null) { 11098 pw.print(" Short msg: "); pw.println(info.shortMsg); 11099 } 11100 if (info.longMsg != null) { 11101 pw.print(" Long msg: "); pw.println(info.longMsg); 11102 } 11103 if (info.stack != null) { 11104 pw.println(" Stack:"); 11105 int lastPos = 0; 11106 for (int pos=0; pos<info.stack.length(); pos++) { 11107 if (info.stack.charAt(pos) == '\n') { 11108 pw.print(" "); 11109 pw.write(info.stack, lastPos, pos-lastPos); 11110 pw.println(); 11111 lastPos = pos+1; 11112 } 11113 } 11114 if (lastPos < info.stack.length()) { 11115 pw.print(" "); 11116 pw.write(info.stack, lastPos, info.stack.length()-lastPos); 11117 pw.println(); 11118 } 11119 } 11120 } 11121 } 11122 } 11123 11124 if (dumpPackage == null) { 11125 pw.println(); 11126 needSep = false; 11127 pw.println(" mStartedUsers:"); 11128 for (int i=0; i<mStartedUsers.size(); i++) { 11129 UserStartedState uss = mStartedUsers.valueAt(i); 11130 pw.print(" User #"); pw.print(uss.mHandle.getIdentifier()); 11131 pw.print(": "); uss.dump("", pw); 11132 } 11133 pw.print(" mStartedUserArray: ["); 11134 for (int i=0; i<mStartedUserArray.length; i++) { 11135 if (i > 0) pw.print(", "); 11136 pw.print(mStartedUserArray[i]); 11137 } 11138 pw.println("]"); 11139 pw.print(" mUserLru: ["); 11140 for (int i=0; i<mUserLru.size(); i++) { 11141 if (i > 0) pw.print(", "); 11142 pw.print(mUserLru.get(i)); 11143 } 11144 pw.println("]"); 11145 if (dumpAll) { 11146 pw.print(" mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray)); 11147 } 11148 } 11149 if (mHomeProcess != null && (dumpPackage == null 11150 || mHomeProcess.pkgList.containsKey(dumpPackage))) { 11151 if (needSep) { 11152 pw.println(); 11153 needSep = false; 11154 } 11155 pw.println(" mHomeProcess: " + mHomeProcess); 11156 } 11157 if (mPreviousProcess != null && (dumpPackage == null 11158 || mPreviousProcess.pkgList.containsKey(dumpPackage))) { 11159 if (needSep) { 11160 pw.println(); 11161 needSep = false; 11162 } 11163 pw.println(" mPreviousProcess: " + mPreviousProcess); 11164 } 11165 if (dumpAll) { 11166 StringBuilder sb = new StringBuilder(128); 11167 sb.append(" mPreviousProcessVisibleTime: "); 11168 TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb); 11169 pw.println(sb); 11170 } 11171 if (mHeavyWeightProcess != null && (dumpPackage == null 11172 || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) { 11173 if (needSep) { 11174 pw.println(); 11175 needSep = false; 11176 } 11177 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 11178 } 11179 if (dumpPackage == null) { 11180 pw.println(" mConfiguration: " + mConfiguration); 11181 } 11182 if (dumpAll) { 11183 pw.println(" mConfigWillChange: " + getFocusedStack().mConfigWillChange); 11184 if (mCompatModePackages.getPackages().size() > 0) { 11185 boolean printed = false; 11186 for (Map.Entry<String, Integer> entry 11187 : mCompatModePackages.getPackages().entrySet()) { 11188 String pkg = entry.getKey(); 11189 int mode = entry.getValue(); 11190 if (dumpPackage != null && !dumpPackage.equals(pkg)) { 11191 continue; 11192 } 11193 if (!printed) { 11194 pw.println(" mScreenCompatPackages:"); 11195 printed = true; 11196 } 11197 pw.print(" "); pw.print(pkg); pw.print(": "); 11198 pw.print(mode); pw.println(); 11199 } 11200 } 11201 } 11202 if (dumpPackage == null) { 11203 if (mSleeping || mWentToSleep || mLockScreenShown) { 11204 pw.println(" mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep 11205 + " mLockScreenShown " + mLockScreenShown); 11206 } 11207 if (mShuttingDown || mRunningVoice) { 11208 pw.print(" mShuttingDown=" + mShuttingDown + " mRunningVoice=" + mRunningVoice); 11209 } 11210 } 11211 if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient 11212 || mOrigWaitForDebugger) { 11213 if (dumpPackage == null || dumpPackage.equals(mDebugApp) 11214 || dumpPackage.equals(mOrigDebugApp)) { 11215 if (needSep) { 11216 pw.println(); 11217 needSep = false; 11218 } 11219 pw.println(" mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp 11220 + " mDebugTransient=" + mDebugTransient 11221 + " mOrigWaitForDebugger=" + mOrigWaitForDebugger); 11222 } 11223 } 11224 if (mOpenGlTraceApp != null) { 11225 if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) { 11226 if (needSep) { 11227 pw.println(); 11228 needSep = false; 11229 } 11230 pw.println(" mOpenGlTraceApp=" + mOpenGlTraceApp); 11231 } 11232 } 11233 if (mProfileApp != null || mProfileProc != null || mProfileFile != null 11234 || mProfileFd != null) { 11235 if (dumpPackage == null || dumpPackage.equals(mProfileApp)) { 11236 if (needSep) { 11237 pw.println(); 11238 needSep = false; 11239 } 11240 pw.println(" mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc); 11241 pw.println(" mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd); 11242 pw.println(" mProfileType=" + mProfileType + " mAutoStopProfiler=" 11243 + mAutoStopProfiler); 11244 } 11245 } 11246 if (dumpPackage == null) { 11247 if (mAlwaysFinishActivities || mController != null) { 11248 pw.println(" mAlwaysFinishActivities=" + mAlwaysFinishActivities 11249 + " mController=" + mController); 11250 } 11251 if (dumpAll) { 11252 pw.println(" Total persistent processes: " + numPers); 11253 pw.println(" mProcessesReady=" + mProcessesReady 11254 + " mSystemReady=" + mSystemReady); 11255 pw.println(" mBooting=" + mBooting 11256 + " mBooted=" + mBooted 11257 + " mFactoryTest=" + mFactoryTest); 11258 pw.print(" mLastPowerCheckRealtime="); 11259 TimeUtils.formatDuration(mLastPowerCheckRealtime, pw); 11260 pw.println(""); 11261 pw.print(" mLastPowerCheckUptime="); 11262 TimeUtils.formatDuration(mLastPowerCheckUptime, pw); 11263 pw.println(""); 11264 pw.println(" mGoingToSleep=" + mStackSupervisor.mGoingToSleep); 11265 pw.println(" mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity); 11266 pw.println(" mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq); 11267 pw.println(" mNumNonCachedProcs=" + mNumNonCachedProcs 11268 + " (" + mLruProcesses.size() + " total)" 11269 + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs 11270 + " mNumServiceProcs=" + mNumServiceProcs 11271 + " mNewNumServiceProcs=" + mNewNumServiceProcs); 11272 pw.println(" mAllowLowerMemLevel=" + mAllowLowerMemLevel 11273 + " mLastMemoryLevel" + mLastMemoryLevel 11274 + " mLastNumProcesses" + mLastNumProcesses); 11275 long now = SystemClock.uptimeMillis(); 11276 pw.print(" mLastIdleTime="); 11277 TimeUtils.formatDuration(now, mLastIdleTime, pw); 11278 pw.print(" mLowRamSinceLastIdle="); 11279 TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw); 11280 pw.println(); 11281 } 11282 } 11283 11284 if (!printedAnything) { 11285 pw.println(" (nothing)"); 11286 } 11287 } 11288 11289 boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args, 11290 int opti, boolean needSep, boolean dumpAll, String dumpPackage) { 11291 if (mProcessesToGc.size() > 0) { 11292 boolean printed = false; 11293 long now = SystemClock.uptimeMillis(); 11294 for (int i=0; i<mProcessesToGc.size(); i++) { 11295 ProcessRecord proc = mProcessesToGc.get(i); 11296 if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) { 11297 continue; 11298 } 11299 if (!printed) { 11300 if (needSep) pw.println(); 11301 needSep = true; 11302 pw.println(" Processes that are waiting to GC:"); 11303 printed = true; 11304 } 11305 pw.print(" Process "); pw.println(proc); 11306 pw.print(" lowMem="); pw.print(proc.reportLowMemory); 11307 pw.print(", last gced="); 11308 pw.print(now-proc.lastRequestedGc); 11309 pw.print(" ms ago, last lowMem="); 11310 pw.print(now-proc.lastLowMemory); 11311 pw.println(" ms ago"); 11312 11313 } 11314 } 11315 return needSep; 11316 } 11317 11318 void printOomLevel(PrintWriter pw, String name, int adj) { 11319 pw.print(" "); 11320 if (adj >= 0) { 11321 pw.print(' '); 11322 if (adj < 10) pw.print(' '); 11323 } else { 11324 if (adj > -10) pw.print(' '); 11325 } 11326 pw.print(adj); 11327 pw.print(": "); 11328 pw.print(name); 11329 pw.print(" ("); 11330 pw.print(mProcessList.getMemLevel(adj)/1024); 11331 pw.println(" kB)"); 11332 } 11333 11334 boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args, 11335 int opti, boolean dumpAll) { 11336 boolean needSep = false; 11337 11338 if (mLruProcesses.size() > 0) { 11339 if (needSep) pw.println(); 11340 needSep = true; 11341 pw.println(" OOM levels:"); 11342 printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ); 11343 printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ); 11344 printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ); 11345 printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ); 11346 printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ); 11347 printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ); 11348 printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ); 11349 printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ); 11350 printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ); 11351 printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ); 11352 printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ); 11353 printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ); 11354 printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ); 11355 11356 if (needSep) pw.println(); 11357 pw.print(" Process OOM control ("); pw.print(mLruProcesses.size()); 11358 pw.print(" total, non-act at "); 11359 pw.print(mLruProcesses.size()-mLruProcessActivityStart); 11360 pw.print(", non-svc at "); 11361 pw.print(mLruProcesses.size()-mLruProcessServiceStart); 11362 pw.println("):"); 11363 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", true, null); 11364 needSep = true; 11365 } 11366 11367 dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null); 11368 11369 pw.println(); 11370 pw.println(" mHomeProcess: " + mHomeProcess); 11371 pw.println(" mPreviousProcess: " + mPreviousProcess); 11372 if (mHeavyWeightProcess != null) { 11373 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 11374 } 11375 11376 return true; 11377 } 11378 11379 /** 11380 * There are three ways to call this: 11381 * - no provider specified: dump all the providers 11382 * - a flattened component name that matched an existing provider was specified as the 11383 * first arg: dump that one provider 11384 * - the first arg isn't the flattened component name of an existing provider: 11385 * dump all providers whose component contains the first arg as a substring 11386 */ 11387 protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args, 11388 int opti, boolean dumpAll) { 11389 return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll); 11390 } 11391 11392 static class ItemMatcher { 11393 ArrayList<ComponentName> components; 11394 ArrayList<String> strings; 11395 ArrayList<Integer> objects; 11396 boolean all; 11397 11398 ItemMatcher() { 11399 all = true; 11400 } 11401 11402 void build(String name) { 11403 ComponentName componentName = ComponentName.unflattenFromString(name); 11404 if (componentName != null) { 11405 if (components == null) { 11406 components = new ArrayList<ComponentName>(); 11407 } 11408 components.add(componentName); 11409 all = false; 11410 } else { 11411 int objectId = 0; 11412 // Not a '/' separated full component name; maybe an object ID? 11413 try { 11414 objectId = Integer.parseInt(name, 16); 11415 if (objects == null) { 11416 objects = new ArrayList<Integer>(); 11417 } 11418 objects.add(objectId); 11419 all = false; 11420 } catch (RuntimeException e) { 11421 // Not an integer; just do string match. 11422 if (strings == null) { 11423 strings = new ArrayList<String>(); 11424 } 11425 strings.add(name); 11426 all = false; 11427 } 11428 } 11429 } 11430 11431 int build(String[] args, int opti) { 11432 for (; opti<args.length; opti++) { 11433 String name = args[opti]; 11434 if ("--".equals(name)) { 11435 return opti+1; 11436 } 11437 build(name); 11438 } 11439 return opti; 11440 } 11441 11442 boolean match(Object object, ComponentName comp) { 11443 if (all) { 11444 return true; 11445 } 11446 if (components != null) { 11447 for (int i=0; i<components.size(); i++) { 11448 if (components.get(i).equals(comp)) { 11449 return true; 11450 } 11451 } 11452 } 11453 if (objects != null) { 11454 for (int i=0; i<objects.size(); i++) { 11455 if (System.identityHashCode(object) == objects.get(i)) { 11456 return true; 11457 } 11458 } 11459 } 11460 if (strings != null) { 11461 String flat = comp.flattenToString(); 11462 for (int i=0; i<strings.size(); i++) { 11463 if (flat.contains(strings.get(i))) { 11464 return true; 11465 } 11466 } 11467 } 11468 return false; 11469 } 11470 } 11471 11472 /** 11473 * There are three things that cmd can be: 11474 * - a flattened component name that matches an existing activity 11475 * - the cmd arg isn't the flattened component name of an existing activity: 11476 * dump all activity whose component contains the cmd as a substring 11477 * - A hex number of the ActivityRecord object instance. 11478 */ 11479 protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args, 11480 int opti, boolean dumpAll) { 11481 ArrayList<ActivityRecord> activities; 11482 11483 synchronized (this) { 11484 activities = mStackSupervisor.getDumpActivitiesLocked(name); 11485 } 11486 11487 if (activities.size() <= 0) { 11488 return false; 11489 } 11490 11491 String[] newArgs = new String[args.length - opti]; 11492 System.arraycopy(args, opti, newArgs, 0, args.length - opti); 11493 11494 TaskRecord lastTask = null; 11495 boolean needSep = false; 11496 for (int i=activities.size()-1; i>=0; i--) { 11497 ActivityRecord r = activities.get(i); 11498 if (needSep) { 11499 pw.println(); 11500 } 11501 needSep = true; 11502 synchronized (this) { 11503 if (lastTask != r.task) { 11504 lastTask = r.task; 11505 pw.print("TASK "); pw.print(lastTask.affinity); 11506 pw.print(" id="); pw.println(lastTask.taskId); 11507 if (dumpAll) { 11508 lastTask.dump(pw, " "); 11509 } 11510 } 11511 } 11512 dumpActivity(" ", fd, pw, activities.get(i), newArgs, dumpAll); 11513 } 11514 return true; 11515 } 11516 11517 /** 11518 * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if 11519 * there is a thread associated with the activity. 11520 */ 11521 private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw, 11522 final ActivityRecord r, String[] args, boolean dumpAll) { 11523 String innerPrefix = prefix + " "; 11524 synchronized (this) { 11525 pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName); 11526 pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r))); 11527 pw.print(" pid="); 11528 if (r.app != null) pw.println(r.app.pid); 11529 else pw.println("(not running)"); 11530 if (dumpAll) { 11531 r.dump(pw, innerPrefix); 11532 } 11533 } 11534 if (r.app != null && r.app.thread != null) { 11535 // flush anything that is already in the PrintWriter since the thread is going 11536 // to write to the file descriptor directly 11537 pw.flush(); 11538 try { 11539 TransferPipe tp = new TransferPipe(); 11540 try { 11541 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(), 11542 r.appToken, innerPrefix, args); 11543 tp.go(fd); 11544 } finally { 11545 tp.kill(); 11546 } 11547 } catch (IOException e) { 11548 pw.println(innerPrefix + "Failure while dumping the activity: " + e); 11549 } catch (RemoteException e) { 11550 pw.println(innerPrefix + "Got a RemoteException while dumping the activity"); 11551 } 11552 } 11553 } 11554 11555 void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 11556 int opti, boolean dumpAll, String dumpPackage) { 11557 boolean needSep = false; 11558 boolean onlyHistory = false; 11559 boolean printedAnything = false; 11560 11561 if ("history".equals(dumpPackage)) { 11562 if (opti < args.length && "-s".equals(args[opti])) { 11563 dumpAll = false; 11564 } 11565 onlyHistory = true; 11566 dumpPackage = null; 11567 } 11568 11569 pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)"); 11570 if (!onlyHistory && dumpAll) { 11571 if (mRegisteredReceivers.size() > 0) { 11572 boolean printed = false; 11573 Iterator it = mRegisteredReceivers.values().iterator(); 11574 while (it.hasNext()) { 11575 ReceiverList r = (ReceiverList)it.next(); 11576 if (dumpPackage != null && (r.app == null || 11577 !dumpPackage.equals(r.app.info.packageName))) { 11578 continue; 11579 } 11580 if (!printed) { 11581 pw.println(" Registered Receivers:"); 11582 needSep = true; 11583 printed = true; 11584 printedAnything = true; 11585 } 11586 pw.print(" * "); pw.println(r); 11587 r.dump(pw, " "); 11588 } 11589 } 11590 11591 if (mReceiverResolver.dump(pw, needSep ? 11592 "\n Receiver Resolver Table:" : " Receiver Resolver Table:", 11593 " ", dumpPackage, false)) { 11594 needSep = true; 11595 printedAnything = true; 11596 } 11597 } 11598 11599 for (BroadcastQueue q : mBroadcastQueues) { 11600 needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep); 11601 printedAnything |= needSep; 11602 } 11603 11604 needSep = true; 11605 11606 if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) { 11607 for (int user=0; user<mStickyBroadcasts.size(); user++) { 11608 if (needSep) { 11609 pw.println(); 11610 } 11611 needSep = true; 11612 printedAnything = true; 11613 pw.print(" Sticky broadcasts for user "); 11614 pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":"); 11615 StringBuilder sb = new StringBuilder(128); 11616 for (Map.Entry<String, ArrayList<Intent>> ent 11617 : mStickyBroadcasts.valueAt(user).entrySet()) { 11618 pw.print(" * Sticky action "); pw.print(ent.getKey()); 11619 if (dumpAll) { 11620 pw.println(":"); 11621 ArrayList<Intent> intents = ent.getValue(); 11622 final int N = intents.size(); 11623 for (int i=0; i<N; i++) { 11624 sb.setLength(0); 11625 sb.append(" Intent: "); 11626 intents.get(i).toShortString(sb, false, true, false, false); 11627 pw.println(sb.toString()); 11628 Bundle bundle = intents.get(i).getExtras(); 11629 if (bundle != null) { 11630 pw.print(" "); 11631 pw.println(bundle.toString()); 11632 } 11633 } 11634 } else { 11635 pw.println(""); 11636 } 11637 } 11638 } 11639 } 11640 11641 if (!onlyHistory && dumpAll) { 11642 pw.println(); 11643 for (BroadcastQueue queue : mBroadcastQueues) { 11644 pw.println(" mBroadcastsScheduled [" + queue.mQueueName + "]=" 11645 + queue.mBroadcastsScheduled); 11646 } 11647 pw.println(" mHandler:"); 11648 mHandler.dump(new PrintWriterPrinter(pw), " "); 11649 needSep = true; 11650 printedAnything = true; 11651 } 11652 11653 if (!printedAnything) { 11654 pw.println(" (nothing)"); 11655 } 11656 } 11657 11658 void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args, 11659 int opti, boolean dumpAll, String dumpPackage) { 11660 boolean needSep; 11661 boolean printedAnything = false; 11662 11663 ItemMatcher matcher = new ItemMatcher(); 11664 matcher.build(args, opti); 11665 11666 pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)"); 11667 11668 needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage); 11669 printedAnything |= needSep; 11670 11671 if (mLaunchingProviders.size() > 0) { 11672 boolean printed = false; 11673 for (int i=mLaunchingProviders.size()-1; i>=0; i--) { 11674 ContentProviderRecord r = mLaunchingProviders.get(i); 11675 if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) { 11676 continue; 11677 } 11678 if (!printed) { 11679 if (needSep) pw.println(); 11680 needSep = true; 11681 pw.println(" Launching content providers:"); 11682 printed = true; 11683 printedAnything = true; 11684 } 11685 pw.print(" Launching #"); pw.print(i); pw.print(": "); 11686 pw.println(r); 11687 } 11688 } 11689 11690 if (mGrantedUriPermissions.size() > 0) { 11691 boolean printed = false; 11692 int dumpUid = -2; 11693 if (dumpPackage != null) { 11694 try { 11695 dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0); 11696 } catch (NameNotFoundException e) { 11697 dumpUid = -1; 11698 } 11699 } 11700 for (int i=0; i<mGrantedUriPermissions.size(); i++) { 11701 int uid = mGrantedUriPermissions.keyAt(i); 11702 if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) { 11703 continue; 11704 } 11705 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 11706 if (!printed) { 11707 if (needSep) pw.println(); 11708 needSep = true; 11709 pw.println(" Granted Uri Permissions:"); 11710 printed = true; 11711 printedAnything = true; 11712 } 11713 pw.print(" * UID "); pw.print(uid); pw.println(" holds:"); 11714 for (UriPermission perm : perms.values()) { 11715 pw.print(" "); pw.println(perm); 11716 if (dumpAll) { 11717 perm.dump(pw, " "); 11718 } 11719 } 11720 } 11721 } 11722 11723 if (!printedAnything) { 11724 pw.println(" (nothing)"); 11725 } 11726 } 11727 11728 void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 11729 int opti, boolean dumpAll, String dumpPackage) { 11730 boolean printed = false; 11731 11732 pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)"); 11733 11734 if (mIntentSenderRecords.size() > 0) { 11735 Iterator<WeakReference<PendingIntentRecord>> it 11736 = mIntentSenderRecords.values().iterator(); 11737 while (it.hasNext()) { 11738 WeakReference<PendingIntentRecord> ref = it.next(); 11739 PendingIntentRecord rec = ref != null ? ref.get(): null; 11740 if (dumpPackage != null && (rec == null 11741 || !dumpPackage.equals(rec.key.packageName))) { 11742 continue; 11743 } 11744 printed = true; 11745 if (rec != null) { 11746 pw.print(" * "); pw.println(rec); 11747 if (dumpAll) { 11748 rec.dump(pw, " "); 11749 } 11750 } else { 11751 pw.print(" * "); pw.println(ref); 11752 } 11753 } 11754 } 11755 11756 if (!printed) { 11757 pw.println(" (nothing)"); 11758 } 11759 } 11760 11761 private static final int dumpProcessList(PrintWriter pw, 11762 ActivityManagerService service, List list, 11763 String prefix, String normalLabel, String persistentLabel, 11764 String dumpPackage) { 11765 int numPers = 0; 11766 final int N = list.size()-1; 11767 for (int i=N; i>=0; i--) { 11768 ProcessRecord r = (ProcessRecord)list.get(i); 11769 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 11770 continue; 11771 } 11772 pw.println(String.format("%s%s #%2d: %s", 11773 prefix, (r.persistent ? persistentLabel : normalLabel), 11774 i, r.toString())); 11775 if (r.persistent) { 11776 numPers++; 11777 } 11778 } 11779 return numPers; 11780 } 11781 11782 private static final boolean dumpProcessOomList(PrintWriter pw, 11783 ActivityManagerService service, List<ProcessRecord> origList, 11784 String prefix, String normalLabel, String persistentLabel, 11785 boolean inclDetails, String dumpPackage) { 11786 11787 ArrayList<Pair<ProcessRecord, Integer>> list 11788 = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size()); 11789 for (int i=0; i<origList.size(); i++) { 11790 ProcessRecord r = origList.get(i); 11791 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 11792 continue; 11793 } 11794 list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i)); 11795 } 11796 11797 if (list.size() <= 0) { 11798 return false; 11799 } 11800 11801 Comparator<Pair<ProcessRecord, Integer>> comparator 11802 = new Comparator<Pair<ProcessRecord, Integer>>() { 11803 @Override 11804 public int compare(Pair<ProcessRecord, Integer> object1, 11805 Pair<ProcessRecord, Integer> object2) { 11806 if (object1.first.setAdj != object2.first.setAdj) { 11807 return object1.first.setAdj > object2.first.setAdj ? -1 : 1; 11808 } 11809 if (object1.second.intValue() != object2.second.intValue()) { 11810 return object1.second.intValue() > object2.second.intValue() ? -1 : 1; 11811 } 11812 return 0; 11813 } 11814 }; 11815 11816 Collections.sort(list, comparator); 11817 11818 final long curRealtime = SystemClock.elapsedRealtime(); 11819 final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime; 11820 final long curUptime = SystemClock.uptimeMillis(); 11821 final long uptimeSince = curUptime - service.mLastPowerCheckUptime; 11822 11823 for (int i=list.size()-1; i>=0; i--) { 11824 ProcessRecord r = list.get(i).first; 11825 String oomAdj = ProcessList.makeOomAdjString(r.setAdj); 11826 char schedGroup; 11827 switch (r.setSchedGroup) { 11828 case Process.THREAD_GROUP_BG_NONINTERACTIVE: 11829 schedGroup = 'B'; 11830 break; 11831 case Process.THREAD_GROUP_DEFAULT: 11832 schedGroup = 'F'; 11833 break; 11834 default: 11835 schedGroup = '?'; 11836 break; 11837 } 11838 char foreground; 11839 if (r.foregroundActivities) { 11840 foreground = 'A'; 11841 } else if (r.foregroundServices) { 11842 foreground = 'S'; 11843 } else { 11844 foreground = ' '; 11845 } 11846 String procState = ProcessList.makeProcStateString(r.curProcState); 11847 pw.print(prefix); 11848 pw.print(r.persistent ? persistentLabel : normalLabel); 11849 pw.print(" #"); 11850 int num = (origList.size()-1)-list.get(i).second; 11851 if (num < 10) pw.print(' '); 11852 pw.print(num); 11853 pw.print(": "); 11854 pw.print(oomAdj); 11855 pw.print(' '); 11856 pw.print(schedGroup); 11857 pw.print('/'); 11858 pw.print(foreground); 11859 pw.print('/'); 11860 pw.print(procState); 11861 pw.print(" trm:"); 11862 if (r.trimMemoryLevel < 10) pw.print(' '); 11863 pw.print(r.trimMemoryLevel); 11864 pw.print(' '); 11865 pw.print(r.toShortString()); 11866 pw.print(" ("); 11867 pw.print(r.adjType); 11868 pw.println(')'); 11869 if (r.adjSource != null || r.adjTarget != null) { 11870 pw.print(prefix); 11871 pw.print(" "); 11872 if (r.adjTarget instanceof ComponentName) { 11873 pw.print(((ComponentName)r.adjTarget).flattenToShortString()); 11874 } else if (r.adjTarget != null) { 11875 pw.print(r.adjTarget.toString()); 11876 } else { 11877 pw.print("{null}"); 11878 } 11879 pw.print("<="); 11880 if (r.adjSource instanceof ProcessRecord) { 11881 pw.print("Proc{"); 11882 pw.print(((ProcessRecord)r.adjSource).toShortString()); 11883 pw.println("}"); 11884 } else if (r.adjSource != null) { 11885 pw.println(r.adjSource.toString()); 11886 } else { 11887 pw.println("{null}"); 11888 } 11889 } 11890 if (inclDetails) { 11891 pw.print(prefix); 11892 pw.print(" "); 11893 pw.print("oom: max="); pw.print(r.maxAdj); 11894 pw.print(" curRaw="); pw.print(r.curRawAdj); 11895 pw.print(" setRaw="); pw.print(r.setRawAdj); 11896 pw.print(" cur="); pw.print(r.curAdj); 11897 pw.print(" set="); pw.println(r.setAdj); 11898 pw.print(prefix); 11899 pw.print(" "); 11900 pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState)); 11901 pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState)); 11902 pw.print(" lastPss="); pw.print(r.lastPss); 11903 pw.print(" lastCachedPss="); pw.println(r.lastCachedPss); 11904 pw.print(prefix); 11905 pw.print(" "); 11906 pw.print("keeping="); pw.print(r.keeping); 11907 pw.print(" cached="); pw.print(r.cached); 11908 pw.print(" empty="); pw.print(r.empty); 11909 pw.print(" hasAboveClient="); pw.println(r.hasAboveClient); 11910 11911 if (!r.keeping) { 11912 if (r.lastWakeTime != 0) { 11913 long wtime; 11914 BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics(); 11915 synchronized (stats) { 11916 wtime = stats.getProcessWakeTime(r.info.uid, 11917 r.pid, curRealtime); 11918 } 11919 long timeUsed = wtime - r.lastWakeTime; 11920 pw.print(prefix); 11921 pw.print(" "); 11922 pw.print("keep awake over "); 11923 TimeUtils.formatDuration(realtimeSince, pw); 11924 pw.print(" used "); 11925 TimeUtils.formatDuration(timeUsed, pw); 11926 pw.print(" ("); 11927 pw.print((timeUsed*100)/realtimeSince); 11928 pw.println("%)"); 11929 } 11930 if (r.lastCpuTime != 0) { 11931 long timeUsed = r.curCpuTime - r.lastCpuTime; 11932 pw.print(prefix); 11933 pw.print(" "); 11934 pw.print("run cpu over "); 11935 TimeUtils.formatDuration(uptimeSince, pw); 11936 pw.print(" used "); 11937 TimeUtils.formatDuration(timeUsed, pw); 11938 pw.print(" ("); 11939 pw.print((timeUsed*100)/uptimeSince); 11940 pw.println("%)"); 11941 } 11942 } 11943 } 11944 } 11945 return true; 11946 } 11947 11948 ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) { 11949 ArrayList<ProcessRecord> procs; 11950 synchronized (this) { 11951 if (args != null && args.length > start 11952 && args[start].charAt(0) != '-') { 11953 procs = new ArrayList<ProcessRecord>(); 11954 int pid = -1; 11955 try { 11956 pid = Integer.parseInt(args[start]); 11957 } catch (NumberFormatException e) { 11958 } 11959 for (int i=mLruProcesses.size()-1; i>=0; i--) { 11960 ProcessRecord proc = mLruProcesses.get(i); 11961 if (proc.pid == pid) { 11962 procs.add(proc); 11963 } else if (proc.processName.equals(args[start])) { 11964 procs.add(proc); 11965 } 11966 } 11967 if (procs.size() <= 0) { 11968 return null; 11969 } 11970 } else { 11971 procs = new ArrayList<ProcessRecord>(mLruProcesses); 11972 } 11973 } 11974 return procs; 11975 } 11976 11977 final void dumpGraphicsHardwareUsage(FileDescriptor fd, 11978 PrintWriter pw, String[] args) { 11979 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args); 11980 if (procs == null) { 11981 pw.println("No process found for: " + args[0]); 11982 return; 11983 } 11984 11985 long uptime = SystemClock.uptimeMillis(); 11986 long realtime = SystemClock.elapsedRealtime(); 11987 pw.println("Applications Graphics Acceleration Info:"); 11988 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 11989 11990 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 11991 ProcessRecord r = procs.get(i); 11992 if (r.thread != null) { 11993 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **"); 11994 pw.flush(); 11995 try { 11996 TransferPipe tp = new TransferPipe(); 11997 try { 11998 r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args); 11999 tp.go(fd); 12000 } finally { 12001 tp.kill(); 12002 } 12003 } catch (IOException e) { 12004 pw.println("Failure while dumping the app: " + r); 12005 pw.flush(); 12006 } catch (RemoteException e) { 12007 pw.println("Got a RemoteException while dumping the app " + r); 12008 pw.flush(); 12009 } 12010 } 12011 } 12012 } 12013 12014 final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) { 12015 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args); 12016 if (procs == null) { 12017 pw.println("No process found for: " + args[0]); 12018 return; 12019 } 12020 12021 pw.println("Applications Database Info:"); 12022 12023 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 12024 ProcessRecord r = procs.get(i); 12025 if (r.thread != null) { 12026 pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **"); 12027 pw.flush(); 12028 try { 12029 TransferPipe tp = new TransferPipe(); 12030 try { 12031 r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args); 12032 tp.go(fd); 12033 } finally { 12034 tp.kill(); 12035 } 12036 } catch (IOException e) { 12037 pw.println("Failure while dumping the app: " + r); 12038 pw.flush(); 12039 } catch (RemoteException e) { 12040 pw.println("Got a RemoteException while dumping the app " + r); 12041 pw.flush(); 12042 } 12043 } 12044 } 12045 } 12046 12047 final static class MemItem { 12048 final boolean isProc; 12049 final String label; 12050 final String shortLabel; 12051 final long pss; 12052 final int id; 12053 final boolean hasActivities; 12054 ArrayList<MemItem> subitems; 12055 12056 public MemItem(String _label, String _shortLabel, long _pss, int _id, 12057 boolean _hasActivities) { 12058 isProc = true; 12059 label = _label; 12060 shortLabel = _shortLabel; 12061 pss = _pss; 12062 id = _id; 12063 hasActivities = _hasActivities; 12064 } 12065 12066 public MemItem(String _label, String _shortLabel, long _pss, int _id) { 12067 isProc = false; 12068 label = _label; 12069 shortLabel = _shortLabel; 12070 pss = _pss; 12071 id = _id; 12072 hasActivities = false; 12073 } 12074 } 12075 12076 static final void dumpMemItems(PrintWriter pw, String prefix, String tag, 12077 ArrayList<MemItem> items, boolean sort, boolean isCompact) { 12078 if (sort && !isCompact) { 12079 Collections.sort(items, new Comparator<MemItem>() { 12080 @Override 12081 public int compare(MemItem lhs, MemItem rhs) { 12082 if (lhs.pss < rhs.pss) { 12083 return 1; 12084 } else if (lhs.pss > rhs.pss) { 12085 return -1; 12086 } 12087 return 0; 12088 } 12089 }); 12090 } 12091 12092 for (int i=0; i<items.size(); i++) { 12093 MemItem mi = items.get(i); 12094 if (!isCompact) { 12095 pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label); 12096 } else if (mi.isProc) { 12097 pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel); 12098 pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss); 12099 pw.println(mi.hasActivities ? ",a" : ",e"); 12100 } else { 12101 pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(","); 12102 pw.println(mi.pss); 12103 } 12104 if (mi.subitems != null) { 12105 dumpMemItems(pw, prefix + " ", mi.shortLabel, mi.subitems, 12106 true, isCompact); 12107 } 12108 } 12109 } 12110 12111 // These are in KB. 12112 static final long[] DUMP_MEM_BUCKETS = new long[] { 12113 5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024, 12114 120*1024, 160*1024, 200*1024, 12115 250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024, 12116 1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024 12117 }; 12118 12119 static final void appendMemBucket(StringBuilder out, long memKB, String label, 12120 boolean stackLike) { 12121 int start = label.lastIndexOf('.'); 12122 if (start >= 0) start++; 12123 else start = 0; 12124 int end = label.length(); 12125 for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) { 12126 if (DUMP_MEM_BUCKETS[i] >= memKB) { 12127 long bucket = DUMP_MEM_BUCKETS[i]/1024; 12128 out.append(bucket); 12129 out.append(stackLike ? "MB." : "MB "); 12130 out.append(label, start, end); 12131 return; 12132 } 12133 } 12134 out.append(memKB/1024); 12135 out.append(stackLike ? "MB." : "MB "); 12136 out.append(label, start, end); 12137 } 12138 12139 static final int[] DUMP_MEM_OOM_ADJ = new int[] { 12140 ProcessList.NATIVE_ADJ, 12141 ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ, 12142 ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ, 12143 ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ, 12144 ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ, 12145 ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ 12146 }; 12147 static final String[] DUMP_MEM_OOM_LABEL = new String[] { 12148 "Native", 12149 "System", "Persistent", "Foreground", 12150 "Visible", "Perceptible", 12151 "Heavy Weight", "Backup", 12152 "A Services", "Home", 12153 "Previous", "B Services", "Cached" 12154 }; 12155 static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] { 12156 "native", 12157 "sys", "pers", "fore", 12158 "vis", "percept", 12159 "heavy", "backup", 12160 "servicea", "home", 12161 "prev", "serviceb", "cached" 12162 }; 12163 12164 private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime, 12165 long realtime, boolean isCheckinRequest, boolean isCompact) { 12166 if (isCheckinRequest || isCompact) { 12167 // short checkin version 12168 pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime); 12169 } else { 12170 pw.println("Applications Memory Usage (kB):"); 12171 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 12172 } 12173 } 12174 12175 final void dumpApplicationMemoryUsage(FileDescriptor fd, 12176 PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) { 12177 boolean dumpDetails = false; 12178 boolean dumpFullDetails = false; 12179 boolean dumpDalvik = false; 12180 boolean oomOnly = false; 12181 boolean isCompact = false; 12182 boolean localOnly = false; 12183 12184 int opti = 0; 12185 while (opti < args.length) { 12186 String opt = args[opti]; 12187 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 12188 break; 12189 } 12190 opti++; 12191 if ("-a".equals(opt)) { 12192 dumpDetails = true; 12193 dumpFullDetails = true; 12194 dumpDalvik = true; 12195 } else if ("-d".equals(opt)) { 12196 dumpDalvik = true; 12197 } else if ("-c".equals(opt)) { 12198 isCompact = true; 12199 } else if ("--oom".equals(opt)) { 12200 oomOnly = true; 12201 } else if ("--local".equals(opt)) { 12202 localOnly = true; 12203 } else if ("-h".equals(opt)) { 12204 pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]"); 12205 pw.println(" -a: include all available information for each process."); 12206 pw.println(" -d: include dalvik details when dumping process details."); 12207 pw.println(" -c: dump in a compact machine-parseable representation."); 12208 pw.println(" --oom: only show processes organized by oom adj."); 12209 pw.println(" --local: only collect details locally, don't call process."); 12210 pw.println("If [process] is specified it can be the name or "); 12211 pw.println("pid of a specific process to dump."); 12212 return; 12213 } else { 12214 pw.println("Unknown argument: " + opt + "; use -h for help"); 12215 } 12216 } 12217 12218 final boolean isCheckinRequest = scanArgs(args, "--checkin"); 12219 long uptime = SystemClock.uptimeMillis(); 12220 long realtime = SystemClock.elapsedRealtime(); 12221 final long[] tmpLong = new long[1]; 12222 12223 ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args); 12224 if (procs == null) { 12225 // No Java processes. Maybe they want to print a native process. 12226 if (args != null && args.length > opti 12227 && args[opti].charAt(0) != '-') { 12228 ArrayList<ProcessCpuTracker.Stats> nativeProcs 12229 = new ArrayList<ProcessCpuTracker.Stats>(); 12230 updateCpuStatsNow(); 12231 int findPid = -1; 12232 try { 12233 findPid = Integer.parseInt(args[opti]); 12234 } catch (NumberFormatException e) { 12235 } 12236 synchronized (mProcessCpuThread) { 12237 final int N = mProcessCpuTracker.countStats(); 12238 for (int i=0; i<N; i++) { 12239 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 12240 if (st.pid == findPid || (st.baseName != null 12241 && st.baseName.equals(args[opti]))) { 12242 nativeProcs.add(st); 12243 } 12244 } 12245 } 12246 if (nativeProcs.size() > 0) { 12247 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, 12248 isCompact); 12249 Debug.MemoryInfo mi = null; 12250 for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) { 12251 final ProcessCpuTracker.Stats r = nativeProcs.get(i); 12252 final int pid = r.pid; 12253 if (!isCheckinRequest && dumpDetails) { 12254 pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **"); 12255 } 12256 if (mi == null) { 12257 mi = new Debug.MemoryInfo(); 12258 } 12259 if (dumpDetails || (!brief && !oomOnly)) { 12260 Debug.getMemoryInfo(pid, mi); 12261 } else { 12262 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong); 12263 mi.dalvikPrivateDirty = (int)tmpLong[0]; 12264 } 12265 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails, 12266 dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0); 12267 if (isCheckinRequest) { 12268 pw.println(); 12269 } 12270 } 12271 return; 12272 } 12273 } 12274 pw.println("No process found for: " + args[opti]); 12275 return; 12276 } 12277 12278 if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest)) { 12279 dumpDetails = true; 12280 } 12281 12282 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact); 12283 12284 String[] innerArgs = new String[args.length-opti]; 12285 System.arraycopy(args, opti, innerArgs, 0, args.length-opti); 12286 12287 ArrayList<MemItem> procMems = new ArrayList<MemItem>(); 12288 final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>(); 12289 long nativePss=0, dalvikPss=0, otherPss=0; 12290 long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS]; 12291 12292 long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length]; 12293 ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[]) 12294 new ArrayList[DUMP_MEM_OOM_LABEL.length]; 12295 12296 long totalPss = 0; 12297 long cachedPss = 0; 12298 12299 Debug.MemoryInfo mi = null; 12300 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 12301 final ProcessRecord r = procs.get(i); 12302 final IApplicationThread thread; 12303 final int pid; 12304 final int oomAdj; 12305 final boolean hasActivities; 12306 synchronized (this) { 12307 thread = r.thread; 12308 pid = r.pid; 12309 oomAdj = r.getSetAdjWithServices(); 12310 hasActivities = r.activities.size() > 0; 12311 } 12312 if (thread != null) { 12313 if (!isCheckinRequest && dumpDetails) { 12314 pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **"); 12315 } 12316 if (mi == null) { 12317 mi = new Debug.MemoryInfo(); 12318 } 12319 if (dumpDetails || (!brief && !oomOnly)) { 12320 Debug.getMemoryInfo(pid, mi); 12321 } else { 12322 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong); 12323 mi.dalvikPrivateDirty = (int)tmpLong[0]; 12324 } 12325 if (dumpDetails) { 12326 if (localOnly) { 12327 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails, 12328 dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0); 12329 if (isCheckinRequest) { 12330 pw.println(); 12331 } 12332 } else { 12333 try { 12334 pw.flush(); 12335 thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails, 12336 dumpDalvik, innerArgs); 12337 } catch (RemoteException e) { 12338 if (!isCheckinRequest) { 12339 pw.println("Got RemoteException!"); 12340 pw.flush(); 12341 } 12342 } 12343 } 12344 } 12345 12346 final long myTotalPss = mi.getTotalPss(); 12347 final long myTotalUss = mi.getTotalUss(); 12348 12349 synchronized (this) { 12350 if (r.thread != null && oomAdj == r.getSetAdjWithServices()) { 12351 // Record this for posterity if the process has been stable. 12352 r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList); 12353 } 12354 } 12355 12356 if (!isCheckinRequest && mi != null) { 12357 totalPss += myTotalPss; 12358 MemItem pssItem = new MemItem(r.processName + " (pid " + pid + 12359 (hasActivities ? " / activities)" : ")"), 12360 r.processName, myTotalPss, pid, hasActivities); 12361 procMems.add(pssItem); 12362 procMemsMap.put(pid, pssItem); 12363 12364 nativePss += mi.nativePss; 12365 dalvikPss += mi.dalvikPss; 12366 otherPss += mi.otherPss; 12367 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 12368 long mem = mi.getOtherPss(j); 12369 miscPss[j] += mem; 12370 otherPss -= mem; 12371 } 12372 12373 if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 12374 cachedPss += myTotalPss; 12375 } 12376 12377 for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) { 12378 if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex] 12379 || oomIndex == (oomPss.length-1)) { 12380 oomPss[oomIndex] += myTotalPss; 12381 if (oomProcs[oomIndex] == null) { 12382 oomProcs[oomIndex] = new ArrayList<MemItem>(); 12383 } 12384 oomProcs[oomIndex].add(pssItem); 12385 break; 12386 } 12387 } 12388 } 12389 } 12390 } 12391 12392 if (!isCheckinRequest && procs.size() > 1) { 12393 // If we are showing aggregations, also look for native processes to 12394 // include so that our aggregations are more accurate. 12395 updateCpuStatsNow(); 12396 synchronized (mProcessCpuThread) { 12397 final int N = mProcessCpuTracker.countStats(); 12398 for (int i=0; i<N; i++) { 12399 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 12400 if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) { 12401 if (mi == null) { 12402 mi = new Debug.MemoryInfo(); 12403 } 12404 if (!brief && !oomOnly) { 12405 Debug.getMemoryInfo(st.pid, mi); 12406 } else { 12407 mi.nativePss = (int)Debug.getPss(st.pid, tmpLong); 12408 mi.nativePrivateDirty = (int)tmpLong[0]; 12409 } 12410 12411 final long myTotalPss = mi.getTotalPss(); 12412 totalPss += myTotalPss; 12413 12414 MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")", 12415 st.name, myTotalPss, st.pid, false); 12416 procMems.add(pssItem); 12417 12418 nativePss += mi.nativePss; 12419 dalvikPss += mi.dalvikPss; 12420 otherPss += mi.otherPss; 12421 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 12422 long mem = mi.getOtherPss(j); 12423 miscPss[j] += mem; 12424 otherPss -= mem; 12425 } 12426 oomPss[0] += myTotalPss; 12427 if (oomProcs[0] == null) { 12428 oomProcs[0] = new ArrayList<MemItem>(); 12429 } 12430 oomProcs[0].add(pssItem); 12431 } 12432 } 12433 } 12434 12435 ArrayList<MemItem> catMems = new ArrayList<MemItem>(); 12436 12437 catMems.add(new MemItem("Native", "Native", nativePss, -1)); 12438 catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2)); 12439 catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3)); 12440 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 12441 String label = Debug.MemoryInfo.getOtherLabel(j); 12442 catMems.add(new MemItem(label, label, miscPss[j], j)); 12443 } 12444 12445 ArrayList<MemItem> oomMems = new ArrayList<MemItem>(); 12446 for (int j=0; j<oomPss.length; j++) { 12447 if (oomPss[j] != 0) { 12448 String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j] 12449 : DUMP_MEM_OOM_LABEL[j]; 12450 MemItem item = new MemItem(label, label, oomPss[j], 12451 DUMP_MEM_OOM_ADJ[j]); 12452 item.subitems = oomProcs[j]; 12453 oomMems.add(item); 12454 } 12455 } 12456 12457 if (!brief && !oomOnly && !isCompact) { 12458 pw.println(); 12459 pw.println("Total PSS by process:"); 12460 dumpMemItems(pw, " ", "proc", procMems, true, isCompact); 12461 pw.println(); 12462 } 12463 if (!isCompact) { 12464 pw.println("Total PSS by OOM adjustment:"); 12465 } 12466 dumpMemItems(pw, " ", "oom", oomMems, false, isCompact); 12467 if (!brief && !oomOnly) { 12468 PrintWriter out = categoryPw != null ? categoryPw : pw; 12469 if (!isCompact) { 12470 out.println(); 12471 out.println("Total PSS by category:"); 12472 } 12473 dumpMemItems(out, " ", "cat", catMems, true, isCompact); 12474 } 12475 if (!isCompact) { 12476 pw.println(); 12477 } 12478 MemInfoReader memInfo = new MemInfoReader(); 12479 memInfo.readMemInfo(); 12480 if (!brief) { 12481 if (!isCompact) { 12482 pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb()); 12483 pw.print(" kB (status "); 12484 switch (mLastMemoryLevel) { 12485 case ProcessStats.ADJ_MEM_FACTOR_NORMAL: 12486 pw.println("normal)"); 12487 break; 12488 case ProcessStats.ADJ_MEM_FACTOR_MODERATE: 12489 pw.println("moderate)"); 12490 break; 12491 case ProcessStats.ADJ_MEM_FACTOR_LOW: 12492 pw.println("low)"); 12493 break; 12494 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL: 12495 pw.println("critical)"); 12496 break; 12497 default: 12498 pw.print(mLastMemoryLevel); 12499 pw.println(")"); 12500 break; 12501 } 12502 pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb() 12503 + memInfo.getFreeSizeKb()); pw.print(" kB ("); 12504 pw.print(cachedPss); pw.print(" cached pss + "); 12505 pw.print(memInfo.getCachedSizeKb()); pw.print(" cached + "); 12506 pw.print(memInfo.getFreeSizeKb()); pw.println(" free)"); 12507 } else { 12508 pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(","); 12509 pw.print(cachedPss + memInfo.getCachedSizeKb() 12510 + memInfo.getFreeSizeKb()); pw.print(","); 12511 pw.println(totalPss - cachedPss); 12512 } 12513 } 12514 if (!isCompact) { 12515 pw.print(" Used RAM: "); pw.print(totalPss - cachedPss 12516 + memInfo.getBuffersSizeKb() + memInfo.getShmemSizeKb() 12517 + memInfo.getSlabSizeKb()); pw.print(" kB ("); 12518 pw.print(totalPss - cachedPss); pw.print(" used pss + "); 12519 pw.print(memInfo.getBuffersSizeKb()); pw.print(" buffers + "); 12520 pw.print(memInfo.getShmemSizeKb()); pw.print(" shmem + "); 12521 pw.print(memInfo.getSlabSizeKb()); pw.println(" slab)"); 12522 pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb() 12523 - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb() 12524 - memInfo.getBuffersSizeKb() - memInfo.getShmemSizeKb() 12525 - memInfo.getSlabSizeKb()); pw.println(" kB"); 12526 } 12527 if (!brief) { 12528 if (memInfo.getZramTotalSizeKb() != 0) { 12529 if (!isCompact) { 12530 pw.print(" ZRAM: "); pw.print(memInfo.getZramTotalSizeKb()); 12531 pw.print(" kB physical used for "); 12532 pw.print(memInfo.getSwapTotalSizeKb() 12533 - memInfo.getSwapFreeSizeKb()); 12534 pw.print(" kB in swap ("); 12535 pw.print(memInfo.getSwapTotalSizeKb()); 12536 pw.println(" kB total swap)"); 12537 } else { 12538 pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(","); 12539 pw.print(memInfo.getSwapTotalSizeKb()); pw.print(","); 12540 pw.println(memInfo.getSwapFreeSizeKb()); 12541 } 12542 } 12543 final int[] SINGLE_LONG_FORMAT = new int[] { 12544 Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG 12545 }; 12546 long[] longOut = new long[1]; 12547 Process.readProcFile("/sys/kernel/mm/ksm/pages_shared", 12548 SINGLE_LONG_FORMAT, null, longOut, null); 12549 long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024; 12550 longOut[0] = 0; 12551 Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing", 12552 SINGLE_LONG_FORMAT, null, longOut, null); 12553 long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024; 12554 longOut[0] = 0; 12555 Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared", 12556 SINGLE_LONG_FORMAT, null, longOut, null); 12557 long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024; 12558 longOut[0] = 0; 12559 Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile", 12560 SINGLE_LONG_FORMAT, null, longOut, null); 12561 long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024; 12562 if (!isCompact) { 12563 if (sharing != 0 || shared != 0 || unshared != 0 || voltile != 0) { 12564 pw.print(" KSM: "); pw.print(sharing); 12565 pw.print(" kB saved from shared "); 12566 pw.print(shared); pw.println(" kB"); 12567 pw.print(" "); pw.print(unshared); pw.print(" kB unshared; "); 12568 pw.print(voltile); pw.println(" kB volatile"); 12569 } 12570 pw.print(" Tuning: "); 12571 pw.print(ActivityManager.staticGetMemoryClass()); 12572 pw.print(" (large "); 12573 pw.print(ActivityManager.staticGetLargeMemoryClass()); 12574 pw.print("), oom "); 12575 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024); 12576 pw.print(" kB"); 12577 pw.print(", restore limit "); 12578 pw.print(mProcessList.getCachedRestoreThresholdKb()); 12579 pw.print(" kB"); 12580 if (ActivityManager.isLowRamDeviceStatic()) { 12581 pw.print(" (low-ram)"); 12582 } 12583 if (ActivityManager.isHighEndGfx()) { 12584 pw.print(" (high-end-gfx)"); 12585 } 12586 pw.println(); 12587 } else { 12588 pw.print("ksm,"); pw.print(sharing); pw.print(","); 12589 pw.print(shared); pw.print(","); pw.print(unshared); pw.print(","); 12590 pw.println(voltile); 12591 pw.print("tuning,"); 12592 pw.print(ActivityManager.staticGetMemoryClass()); 12593 pw.print(','); 12594 pw.print(ActivityManager.staticGetLargeMemoryClass()); 12595 pw.print(','); 12596 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024); 12597 if (ActivityManager.isLowRamDeviceStatic()) { 12598 pw.print(",low-ram"); 12599 } 12600 if (ActivityManager.isHighEndGfx()) { 12601 pw.print(",high-end-gfx"); 12602 } 12603 pw.println(); 12604 } 12605 } 12606 } 12607 } 12608 12609 /** 12610 * Searches array of arguments for the specified string 12611 * @param args array of argument strings 12612 * @param value value to search for 12613 * @return true if the value is contained in the array 12614 */ 12615 private static boolean scanArgs(String[] args, String value) { 12616 if (args != null) { 12617 for (String arg : args) { 12618 if (value.equals(arg)) { 12619 return true; 12620 } 12621 } 12622 } 12623 return false; 12624 } 12625 12626 private final boolean removeDyingProviderLocked(ProcessRecord proc, 12627 ContentProviderRecord cpr, boolean always) { 12628 final boolean inLaunching = mLaunchingProviders.contains(cpr); 12629 12630 if (!inLaunching || always) { 12631 synchronized (cpr) { 12632 cpr.launchingApp = null; 12633 cpr.notifyAll(); 12634 } 12635 mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid)); 12636 String names[] = cpr.info.authority.split(";"); 12637 for (int j = 0; j < names.length; j++) { 12638 mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid)); 12639 } 12640 } 12641 12642 for (int i=0; i<cpr.connections.size(); i++) { 12643 ContentProviderConnection conn = cpr.connections.get(i); 12644 if (conn.waiting) { 12645 // If this connection is waiting for the provider, then we don't 12646 // need to mess with its process unless we are always removing 12647 // or for some reason the provider is not currently launching. 12648 if (inLaunching && !always) { 12649 continue; 12650 } 12651 } 12652 ProcessRecord capp = conn.client; 12653 conn.dead = true; 12654 if (conn.stableCount > 0) { 12655 if (!capp.persistent && capp.thread != null 12656 && capp.pid != 0 12657 && capp.pid != MY_PID) { 12658 killUnneededProcessLocked(capp, "depends on provider " 12659 + cpr.name.flattenToShortString() 12660 + " in dying proc " + (proc != null ? proc.processName : "??")); 12661 } 12662 } else if (capp.thread != null && conn.provider.provider != null) { 12663 try { 12664 capp.thread.unstableProviderDied(conn.provider.provider.asBinder()); 12665 } catch (RemoteException e) { 12666 } 12667 // In the protocol here, we don't expect the client to correctly 12668 // clean up this connection, we'll just remove it. 12669 cpr.connections.remove(i); 12670 conn.client.conProviders.remove(conn); 12671 } 12672 } 12673 12674 if (inLaunching && always) { 12675 mLaunchingProviders.remove(cpr); 12676 } 12677 return inLaunching; 12678 } 12679 12680 /** 12681 * Main code for cleaning up a process when it has gone away. This is 12682 * called both as a result of the process dying, or directly when stopping 12683 * a process when running in single process mode. 12684 */ 12685 private final void cleanUpApplicationRecordLocked(ProcessRecord app, 12686 boolean restarting, boolean allowRestart, int index) { 12687 if (index >= 0) { 12688 removeLruProcessLocked(app); 12689 ProcessList.remove(app.pid); 12690 } 12691 12692 mProcessesToGc.remove(app); 12693 mPendingPssProcesses.remove(app); 12694 12695 // Dismiss any open dialogs. 12696 if (app.crashDialog != null && !app.forceCrashReport) { 12697 app.crashDialog.dismiss(); 12698 app.crashDialog = null; 12699 } 12700 if (app.anrDialog != null) { 12701 app.anrDialog.dismiss(); 12702 app.anrDialog = null; 12703 } 12704 if (app.waitDialog != null) { 12705 app.waitDialog.dismiss(); 12706 app.waitDialog = null; 12707 } 12708 12709 app.crashing = false; 12710 app.notResponding = false; 12711 12712 app.resetPackageList(mProcessStats); 12713 app.unlinkDeathRecipient(); 12714 app.makeInactive(mProcessStats); 12715 app.forcingToForeground = null; 12716 updateProcessForegroundLocked(app, false, false); 12717 app.foregroundActivities = false; 12718 app.hasShownUi = false; 12719 app.treatLikeActivity = false; 12720 app.hasAboveClient = false; 12721 app.hasClientActivities = false; 12722 12723 mServices.killServicesLocked(app, allowRestart); 12724 12725 boolean restart = false; 12726 12727 // Remove published content providers. 12728 for (int i=app.pubProviders.size()-1; i>=0; i--) { 12729 ContentProviderRecord cpr = app.pubProviders.valueAt(i); 12730 final boolean always = app.bad || !allowRestart; 12731 if (removeDyingProviderLocked(app, cpr, always) || always) { 12732 // We left the provider in the launching list, need to 12733 // restart it. 12734 restart = true; 12735 } 12736 12737 cpr.provider = null; 12738 cpr.proc = null; 12739 } 12740 app.pubProviders.clear(); 12741 12742 // Take care of any launching providers waiting for this process. 12743 if (checkAppInLaunchingProvidersLocked(app, false)) { 12744 restart = true; 12745 } 12746 12747 // Unregister from connected content providers. 12748 if (!app.conProviders.isEmpty()) { 12749 for (int i=0; i<app.conProviders.size(); i++) { 12750 ContentProviderConnection conn = app.conProviders.get(i); 12751 conn.provider.connections.remove(conn); 12752 } 12753 app.conProviders.clear(); 12754 } 12755 12756 // At this point there may be remaining entries in mLaunchingProviders 12757 // where we were the only one waiting, so they are no longer of use. 12758 // Look for these and clean up if found. 12759 // XXX Commented out for now. Trying to figure out a way to reproduce 12760 // the actual situation to identify what is actually going on. 12761 if (false) { 12762 for (int i=0; i<mLaunchingProviders.size(); i++) { 12763 ContentProviderRecord cpr = (ContentProviderRecord) 12764 mLaunchingProviders.get(i); 12765 if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) { 12766 synchronized (cpr) { 12767 cpr.launchingApp = null; 12768 cpr.notifyAll(); 12769 } 12770 } 12771 } 12772 } 12773 12774 skipCurrentReceiverLocked(app); 12775 12776 // Unregister any receivers. 12777 for (int i=app.receivers.size()-1; i>=0; i--) { 12778 removeReceiverLocked(app.receivers.valueAt(i)); 12779 } 12780 app.receivers.clear(); 12781 12782 // If the app is undergoing backup, tell the backup manager about it 12783 if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) { 12784 if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App " 12785 + mBackupTarget.appInfo + " died during backup"); 12786 try { 12787 IBackupManager bm = IBackupManager.Stub.asInterface( 12788 ServiceManager.getService(Context.BACKUP_SERVICE)); 12789 bm.agentDisconnected(app.info.packageName); 12790 } catch (RemoteException e) { 12791 // can't happen; backup manager is local 12792 } 12793 } 12794 12795 for (int i = mPendingProcessChanges.size()-1; i>=0; i--) { 12796 ProcessChangeItem item = mPendingProcessChanges.get(i); 12797 if (item.pid == app.pid) { 12798 mPendingProcessChanges.remove(i); 12799 mAvailProcessChanges.add(item); 12800 } 12801 } 12802 mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget(); 12803 12804 // If the caller is restarting this app, then leave it in its 12805 // current lists and let the caller take care of it. 12806 if (restarting) { 12807 return; 12808 } 12809 12810 if (!app.persistent || app.isolated) { 12811 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, 12812 "Removing non-persistent process during cleanup: " + app); 12813 mProcessNames.remove(app.processName, app.uid); 12814 mIsolatedProcesses.remove(app.uid); 12815 if (mHeavyWeightProcess == app) { 12816 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 12817 mHeavyWeightProcess.userId, 0)); 12818 mHeavyWeightProcess = null; 12819 } 12820 } else if (!app.removed) { 12821 // This app is persistent, so we need to keep its record around. 12822 // If it is not already on the pending app list, add it there 12823 // and start a new process for it. 12824 if (mPersistentStartingProcesses.indexOf(app) < 0) { 12825 mPersistentStartingProcesses.add(app); 12826 restart = true; 12827 } 12828 } 12829 if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG, 12830 "Clean-up removing on hold: " + app); 12831 mProcessesOnHold.remove(app); 12832 12833 if (app == mHomeProcess) { 12834 mHomeProcess = null; 12835 } 12836 if (app == mPreviousProcess) { 12837 mPreviousProcess = null; 12838 } 12839 12840 if (restart && !app.isolated) { 12841 // We have components that still need to be running in the 12842 // process, so re-launch it. 12843 mProcessNames.put(app.processName, app.uid, app); 12844 startProcessLocked(app, "restart", app.processName); 12845 } else if (app.pid > 0 && app.pid != MY_PID) { 12846 // Goodbye! 12847 boolean removed; 12848 synchronized (mPidsSelfLocked) { 12849 mPidsSelfLocked.remove(app.pid); 12850 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 12851 } 12852 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH, 12853 app.processName, app.info.uid); 12854 if (app.isolated) { 12855 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 12856 } 12857 app.setPid(0); 12858 } 12859 } 12860 12861 boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) { 12862 // Look through the content providers we are waiting to have launched, 12863 // and if any run in this process then either schedule a restart of 12864 // the process or kill the client waiting for it if this process has 12865 // gone bad. 12866 int NL = mLaunchingProviders.size(); 12867 boolean restart = false; 12868 for (int i=0; i<NL; i++) { 12869 ContentProviderRecord cpr = mLaunchingProviders.get(i); 12870 if (cpr.launchingApp == app) { 12871 if (!alwaysBad && !app.bad) { 12872 restart = true; 12873 } else { 12874 removeDyingProviderLocked(app, cpr, true); 12875 // cpr should have been removed from mLaunchingProviders 12876 NL = mLaunchingProviders.size(); 12877 i--; 12878 } 12879 } 12880 } 12881 return restart; 12882 } 12883 12884 // ========================================================= 12885 // SERVICES 12886 // ========================================================= 12887 12888 public List<ActivityManager.RunningServiceInfo> getServices(int maxNum, 12889 int flags) { 12890 enforceNotIsolatedCaller("getServices"); 12891 synchronized (this) { 12892 return mServices.getRunningServiceInfoLocked(maxNum, flags); 12893 } 12894 } 12895 12896 public PendingIntent getRunningServiceControlPanel(ComponentName name) { 12897 enforceNotIsolatedCaller("getRunningServiceControlPanel"); 12898 synchronized (this) { 12899 return mServices.getRunningServiceControlPanelLocked(name); 12900 } 12901 } 12902 12903 public ComponentName startService(IApplicationThread caller, Intent service, 12904 String resolvedType, int userId) { 12905 enforceNotIsolatedCaller("startService"); 12906 // Refuse possible leaked file descriptors 12907 if (service != null && service.hasFileDescriptors() == true) { 12908 throw new IllegalArgumentException("File descriptors passed in Intent"); 12909 } 12910 12911 if (DEBUG_SERVICE) 12912 Slog.v(TAG, "startService: " + service + " type=" + resolvedType); 12913 synchronized(this) { 12914 final int callingPid = Binder.getCallingPid(); 12915 final int callingUid = Binder.getCallingUid(); 12916 final long origId = Binder.clearCallingIdentity(); 12917 ComponentName res = mServices.startServiceLocked(caller, service, 12918 resolvedType, callingPid, callingUid, userId); 12919 Binder.restoreCallingIdentity(origId); 12920 return res; 12921 } 12922 } 12923 12924 ComponentName startServiceInPackage(int uid, 12925 Intent service, String resolvedType, int userId) { 12926 synchronized(this) { 12927 if (DEBUG_SERVICE) 12928 Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType); 12929 final long origId = Binder.clearCallingIdentity(); 12930 ComponentName res = mServices.startServiceLocked(null, service, 12931 resolvedType, -1, uid, userId); 12932 Binder.restoreCallingIdentity(origId); 12933 return res; 12934 } 12935 } 12936 12937 public int stopService(IApplicationThread caller, Intent service, 12938 String resolvedType, int userId) { 12939 enforceNotIsolatedCaller("stopService"); 12940 // Refuse possible leaked file descriptors 12941 if (service != null && service.hasFileDescriptors() == true) { 12942 throw new IllegalArgumentException("File descriptors passed in Intent"); 12943 } 12944 12945 synchronized(this) { 12946 return mServices.stopServiceLocked(caller, service, resolvedType, userId); 12947 } 12948 } 12949 12950 public IBinder peekService(Intent service, String resolvedType) { 12951 enforceNotIsolatedCaller("peekService"); 12952 // Refuse possible leaked file descriptors 12953 if (service != null && service.hasFileDescriptors() == true) { 12954 throw new IllegalArgumentException("File descriptors passed in Intent"); 12955 } 12956 synchronized(this) { 12957 return mServices.peekServiceLocked(service, resolvedType); 12958 } 12959 } 12960 12961 public boolean stopServiceToken(ComponentName className, IBinder token, 12962 int startId) { 12963 synchronized(this) { 12964 return mServices.stopServiceTokenLocked(className, token, startId); 12965 } 12966 } 12967 12968 public void setServiceForeground(ComponentName className, IBinder token, 12969 int id, Notification notification, boolean removeNotification) { 12970 synchronized(this) { 12971 mServices.setServiceForegroundLocked(className, token, id, notification, 12972 removeNotification); 12973 } 12974 } 12975 12976 public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll, 12977 boolean requireFull, String name, String callerPackage) { 12978 final int callingUserId = UserHandle.getUserId(callingUid); 12979 if (callingUserId != userId) { 12980 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 12981 if ((requireFull || checkComponentPermission( 12982 android.Manifest.permission.INTERACT_ACROSS_USERS, 12983 callingPid, callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) 12984 && checkComponentPermission( 12985 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 12986 callingPid, callingUid, -1, true) 12987 != PackageManager.PERMISSION_GRANTED) { 12988 if (userId == UserHandle.USER_CURRENT_OR_SELF) { 12989 // In this case, they would like to just execute as their 12990 // owner user instead of failing. 12991 userId = callingUserId; 12992 } else { 12993 StringBuilder builder = new StringBuilder(128); 12994 builder.append("Permission Denial: "); 12995 builder.append(name); 12996 if (callerPackage != null) { 12997 builder.append(" from "); 12998 builder.append(callerPackage); 12999 } 13000 builder.append(" asks to run as user "); 13001 builder.append(userId); 13002 builder.append(" but is calling from user "); 13003 builder.append(UserHandle.getUserId(callingUid)); 13004 builder.append("; this requires "); 13005 builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL); 13006 if (!requireFull) { 13007 builder.append(" or "); 13008 builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS); 13009 } 13010 String msg = builder.toString(); 13011 Slog.w(TAG, msg); 13012 throw new SecurityException(msg); 13013 } 13014 } 13015 } 13016 if (userId == UserHandle.USER_CURRENT 13017 || userId == UserHandle.USER_CURRENT_OR_SELF) { 13018 // Note that we may be accessing this outside of a lock... 13019 // shouldn't be a big deal, if this is being called outside 13020 // of a locked context there is intrinsically a race with 13021 // the value the caller will receive and someone else changing it. 13022 userId = mCurrentUserId; 13023 } 13024 if (!allowAll && userId < 0) { 13025 throw new IllegalArgumentException( 13026 "Call does not support special user #" + userId); 13027 } 13028 } 13029 return userId; 13030 } 13031 13032 boolean isSingleton(String componentProcessName, ApplicationInfo aInfo, 13033 String className, int flags) { 13034 boolean result = false; 13035 if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) { 13036 if ((flags&ServiceInfo.FLAG_SINGLE_USER) != 0) { 13037 if (ActivityManager.checkUidPermission( 13038 android.Manifest.permission.INTERACT_ACROSS_USERS, 13039 aInfo.uid) != PackageManager.PERMISSION_GRANTED) { 13040 ComponentName comp = new ComponentName(aInfo.packageName, className); 13041 String msg = "Permission Denial: Component " + comp.flattenToShortString() 13042 + " requests FLAG_SINGLE_USER, but app does not hold " 13043 + android.Manifest.permission.INTERACT_ACROSS_USERS; 13044 Slog.w(TAG, msg); 13045 throw new SecurityException(msg); 13046 } 13047 result = true; 13048 } 13049 } else if (componentProcessName == aInfo.packageName) { 13050 result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0; 13051 } else if ("system".equals(componentProcessName)) { 13052 result = true; 13053 } 13054 if (DEBUG_MU) { 13055 Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo 13056 + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result); 13057 } 13058 return result; 13059 } 13060 13061 public int bindService(IApplicationThread caller, IBinder token, 13062 Intent service, String resolvedType, 13063 IServiceConnection connection, int flags, int userId) { 13064 enforceNotIsolatedCaller("bindService"); 13065 // Refuse possible leaked file descriptors 13066 if (service != null && service.hasFileDescriptors() == true) { 13067 throw new IllegalArgumentException("File descriptors passed in Intent"); 13068 } 13069 13070 synchronized(this) { 13071 return mServices.bindServiceLocked(caller, token, service, resolvedType, 13072 connection, flags, userId); 13073 } 13074 } 13075 13076 public boolean unbindService(IServiceConnection connection) { 13077 synchronized (this) { 13078 return mServices.unbindServiceLocked(connection); 13079 } 13080 } 13081 13082 public void publishService(IBinder token, Intent intent, IBinder service) { 13083 // Refuse possible leaked file descriptors 13084 if (intent != null && intent.hasFileDescriptors() == true) { 13085 throw new IllegalArgumentException("File descriptors passed in Intent"); 13086 } 13087 13088 synchronized(this) { 13089 if (!(token instanceof ServiceRecord)) { 13090 throw new IllegalArgumentException("Invalid service token"); 13091 } 13092 mServices.publishServiceLocked((ServiceRecord)token, intent, service); 13093 } 13094 } 13095 13096 public void unbindFinished(IBinder token, Intent intent, boolean doRebind) { 13097 // Refuse possible leaked file descriptors 13098 if (intent != null && intent.hasFileDescriptors() == true) { 13099 throw new IllegalArgumentException("File descriptors passed in Intent"); 13100 } 13101 13102 synchronized(this) { 13103 mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind); 13104 } 13105 } 13106 13107 public void serviceDoneExecuting(IBinder token, int type, int startId, int res) { 13108 synchronized(this) { 13109 if (!(token instanceof ServiceRecord)) { 13110 throw new IllegalArgumentException("Invalid service token"); 13111 } 13112 mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res); 13113 } 13114 } 13115 13116 // ========================================================= 13117 // BACKUP AND RESTORE 13118 // ========================================================= 13119 13120 // Cause the target app to be launched if necessary and its backup agent 13121 // instantiated. The backup agent will invoke backupAgentCreated() on the 13122 // activity manager to announce its creation. 13123 public boolean bindBackupAgent(ApplicationInfo app, int backupMode) { 13124 if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode); 13125 enforceCallingPermission("android.permission.BACKUP", "bindBackupAgent"); 13126 13127 synchronized(this) { 13128 // !!! TODO: currently no check here that we're already bound 13129 BatteryStatsImpl.Uid.Pkg.Serv ss = null; 13130 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 13131 synchronized (stats) { 13132 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name); 13133 } 13134 13135 // Backup agent is now in use, its package can't be stopped. 13136 try { 13137 AppGlobals.getPackageManager().setPackageStoppedState( 13138 app.packageName, false, UserHandle.getUserId(app.uid)); 13139 } catch (RemoteException e) { 13140 } catch (IllegalArgumentException e) { 13141 Slog.w(TAG, "Failed trying to unstop package " 13142 + app.packageName + ": " + e); 13143 } 13144 13145 BackupRecord r = new BackupRecord(ss, app, backupMode); 13146 ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL) 13147 ? new ComponentName(app.packageName, app.backupAgentName) 13148 : new ComponentName("android", "FullBackupAgent"); 13149 // startProcessLocked() returns existing proc's record if it's already running 13150 ProcessRecord proc = startProcessLocked(app.processName, app, 13151 false, 0, "backup", hostingName, false, false, false); 13152 if (proc == null) { 13153 Slog.e(TAG, "Unable to start backup agent process " + r); 13154 return false; 13155 } 13156 13157 r.app = proc; 13158 mBackupTarget = r; 13159 mBackupAppName = app.packageName; 13160 13161 // Try not to kill the process during backup 13162 updateOomAdjLocked(proc); 13163 13164 // If the process is already attached, schedule the creation of the backup agent now. 13165 // If it is not yet live, this will be done when it attaches to the framework. 13166 if (proc.thread != null) { 13167 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc); 13168 try { 13169 proc.thread.scheduleCreateBackupAgent(app, 13170 compatibilityInfoForPackageLocked(app), backupMode); 13171 } catch (RemoteException e) { 13172 // Will time out on the backup manager side 13173 } 13174 } else { 13175 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach"); 13176 } 13177 // Invariants: at this point, the target app process exists and the application 13178 // is either already running or in the process of coming up. mBackupTarget and 13179 // mBackupAppName describe the app, so that when it binds back to the AM we 13180 // know that it's scheduled for a backup-agent operation. 13181 } 13182 13183 return true; 13184 } 13185 13186 @Override 13187 public void clearPendingBackup() { 13188 if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup"); 13189 enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup"); 13190 13191 synchronized (this) { 13192 mBackupTarget = null; 13193 mBackupAppName = null; 13194 } 13195 } 13196 13197 // A backup agent has just come up 13198 public void backupAgentCreated(String agentPackageName, IBinder agent) { 13199 if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName 13200 + " = " + agent); 13201 13202 synchronized(this) { 13203 if (!agentPackageName.equals(mBackupAppName)) { 13204 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!"); 13205 return; 13206 } 13207 } 13208 13209 long oldIdent = Binder.clearCallingIdentity(); 13210 try { 13211 IBackupManager bm = IBackupManager.Stub.asInterface( 13212 ServiceManager.getService(Context.BACKUP_SERVICE)); 13213 bm.agentConnected(agentPackageName, agent); 13214 } catch (RemoteException e) { 13215 // can't happen; the backup manager service is local 13216 } catch (Exception e) { 13217 Slog.w(TAG, "Exception trying to deliver BackupAgent binding: "); 13218 e.printStackTrace(); 13219 } finally { 13220 Binder.restoreCallingIdentity(oldIdent); 13221 } 13222 } 13223 13224 // done with this agent 13225 public void unbindBackupAgent(ApplicationInfo appInfo) { 13226 if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo); 13227 if (appInfo == null) { 13228 Slog.w(TAG, "unbind backup agent for null app"); 13229 return; 13230 } 13231 13232 synchronized(this) { 13233 try { 13234 if (mBackupAppName == null) { 13235 Slog.w(TAG, "Unbinding backup agent with no active backup"); 13236 return; 13237 } 13238 13239 if (!mBackupAppName.equals(appInfo.packageName)) { 13240 Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target"); 13241 return; 13242 } 13243 13244 // Not backing this app up any more; reset its OOM adjustment 13245 final ProcessRecord proc = mBackupTarget.app; 13246 updateOomAdjLocked(proc); 13247 13248 // If the app crashed during backup, 'thread' will be null here 13249 if (proc.thread != null) { 13250 try { 13251 proc.thread.scheduleDestroyBackupAgent(appInfo, 13252 compatibilityInfoForPackageLocked(appInfo)); 13253 } catch (Exception e) { 13254 Slog.e(TAG, "Exception when unbinding backup agent:"); 13255 e.printStackTrace(); 13256 } 13257 } 13258 } finally { 13259 mBackupTarget = null; 13260 mBackupAppName = null; 13261 } 13262 } 13263 } 13264 // ========================================================= 13265 // BROADCASTS 13266 // ========================================================= 13267 13268 private final List getStickiesLocked(String action, IntentFilter filter, 13269 List cur, int userId) { 13270 final ContentResolver resolver = mContext.getContentResolver(); 13271 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 13272 if (stickies == null) { 13273 return cur; 13274 } 13275 final ArrayList<Intent> list = stickies.get(action); 13276 if (list == null) { 13277 return cur; 13278 } 13279 int N = list.size(); 13280 for (int i=0; i<N; i++) { 13281 Intent intent = list.get(i); 13282 if (filter.match(resolver, intent, true, TAG) >= 0) { 13283 if (cur == null) { 13284 cur = new ArrayList<Intent>(); 13285 } 13286 cur.add(intent); 13287 } 13288 } 13289 return cur; 13290 } 13291 13292 boolean isPendingBroadcastProcessLocked(int pid) { 13293 return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid) 13294 || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid); 13295 } 13296 13297 void skipPendingBroadcastLocked(int pid) { 13298 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 13299 for (BroadcastQueue queue : mBroadcastQueues) { 13300 queue.skipPendingBroadcastLocked(pid); 13301 } 13302 } 13303 13304 // The app just attached; send any pending broadcasts that it should receive 13305 boolean sendPendingBroadcastsLocked(ProcessRecord app) { 13306 boolean didSomething = false; 13307 for (BroadcastQueue queue : mBroadcastQueues) { 13308 didSomething |= queue.sendPendingBroadcastsLocked(app); 13309 } 13310 return didSomething; 13311 } 13312 13313 public Intent registerReceiver(IApplicationThread caller, String callerPackage, 13314 IIntentReceiver receiver, IntentFilter filter, String permission, int userId) { 13315 enforceNotIsolatedCaller("registerReceiver"); 13316 int callingUid; 13317 int callingPid; 13318 synchronized(this) { 13319 ProcessRecord callerApp = null; 13320 if (caller != null) { 13321 callerApp = getRecordForAppLocked(caller); 13322 if (callerApp == null) { 13323 throw new SecurityException( 13324 "Unable to find app for caller " + caller 13325 + " (pid=" + Binder.getCallingPid() 13326 + ") when registering receiver " + receiver); 13327 } 13328 if (callerApp.info.uid != Process.SYSTEM_UID && 13329 !callerApp.pkgList.containsKey(callerPackage) && 13330 !"android".equals(callerPackage)) { 13331 throw new SecurityException("Given caller package " + callerPackage 13332 + " is not running in process " + callerApp); 13333 } 13334 callingUid = callerApp.info.uid; 13335 callingPid = callerApp.pid; 13336 } else { 13337 callerPackage = null; 13338 callingUid = Binder.getCallingUid(); 13339 callingPid = Binder.getCallingPid(); 13340 } 13341 13342 userId = this.handleIncomingUser(callingPid, callingUid, userId, 13343 true, true, "registerReceiver", callerPackage); 13344 13345 List allSticky = null; 13346 13347 // Look for any matching sticky broadcasts... 13348 Iterator actions = filter.actionsIterator(); 13349 if (actions != null) { 13350 while (actions.hasNext()) { 13351 String action = (String)actions.next(); 13352 allSticky = getStickiesLocked(action, filter, allSticky, 13353 UserHandle.USER_ALL); 13354 allSticky = getStickiesLocked(action, filter, allSticky, 13355 UserHandle.getUserId(callingUid)); 13356 } 13357 } else { 13358 allSticky = getStickiesLocked(null, filter, allSticky, 13359 UserHandle.USER_ALL); 13360 allSticky = getStickiesLocked(null, filter, allSticky, 13361 UserHandle.getUserId(callingUid)); 13362 } 13363 13364 // The first sticky in the list is returned directly back to 13365 // the client. 13366 Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null; 13367 13368 if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter 13369 + ": " + sticky); 13370 13371 if (receiver == null) { 13372 return sticky; 13373 } 13374 13375 ReceiverList rl 13376 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder()); 13377 if (rl == null) { 13378 rl = new ReceiverList(this, callerApp, callingPid, callingUid, 13379 userId, receiver); 13380 if (rl.app != null) { 13381 rl.app.receivers.add(rl); 13382 } else { 13383 try { 13384 receiver.asBinder().linkToDeath(rl, 0); 13385 } catch (RemoteException e) { 13386 return sticky; 13387 } 13388 rl.linkedToDeath = true; 13389 } 13390 mRegisteredReceivers.put(receiver.asBinder(), rl); 13391 } else if (rl.uid != callingUid) { 13392 throw new IllegalArgumentException( 13393 "Receiver requested to register for uid " + callingUid 13394 + " was previously registered for uid " + rl.uid); 13395 } else if (rl.pid != callingPid) { 13396 throw new IllegalArgumentException( 13397 "Receiver requested to register for pid " + callingPid 13398 + " was previously registered for pid " + rl.pid); 13399 } else if (rl.userId != userId) { 13400 throw new IllegalArgumentException( 13401 "Receiver requested to register for user " + userId 13402 + " was previously registered for user " + rl.userId); 13403 } 13404 BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage, 13405 permission, callingUid, userId); 13406 rl.add(bf); 13407 if (!bf.debugCheck()) { 13408 Slog.w(TAG, "==> For Dynamic broadast"); 13409 } 13410 mReceiverResolver.addFilter(bf); 13411 13412 // Enqueue broadcasts for all existing stickies that match 13413 // this filter. 13414 if (allSticky != null) { 13415 ArrayList receivers = new ArrayList(); 13416 receivers.add(bf); 13417 13418 int N = allSticky.size(); 13419 for (int i=0; i<N; i++) { 13420 Intent intent = (Intent)allSticky.get(i); 13421 BroadcastQueue queue = broadcastQueueForIntent(intent); 13422 BroadcastRecord r = new BroadcastRecord(queue, intent, null, 13423 null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0, 13424 null, null, false, true, true, -1); 13425 queue.enqueueParallelBroadcastLocked(r); 13426 queue.scheduleBroadcastsLocked(); 13427 } 13428 } 13429 13430 return sticky; 13431 } 13432 } 13433 13434 public void unregisterReceiver(IIntentReceiver receiver) { 13435 if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver); 13436 13437 final long origId = Binder.clearCallingIdentity(); 13438 try { 13439 boolean doTrim = false; 13440 13441 synchronized(this) { 13442 ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder()); 13443 if (rl != null) { 13444 if (rl.curBroadcast != null) { 13445 BroadcastRecord r = rl.curBroadcast; 13446 final boolean doNext = finishReceiverLocked( 13447 receiver.asBinder(), r.resultCode, r.resultData, 13448 r.resultExtras, r.resultAbort); 13449 if (doNext) { 13450 doTrim = true; 13451 r.queue.processNextBroadcast(false); 13452 } 13453 } 13454 13455 if (rl.app != null) { 13456 rl.app.receivers.remove(rl); 13457 } 13458 removeReceiverLocked(rl); 13459 if (rl.linkedToDeath) { 13460 rl.linkedToDeath = false; 13461 rl.receiver.asBinder().unlinkToDeath(rl, 0); 13462 } 13463 } 13464 } 13465 13466 // If we actually concluded any broadcasts, we might now be able 13467 // to trim the recipients' apps from our working set 13468 if (doTrim) { 13469 trimApplications(); 13470 return; 13471 } 13472 13473 } finally { 13474 Binder.restoreCallingIdentity(origId); 13475 } 13476 } 13477 13478 void removeReceiverLocked(ReceiverList rl) { 13479 mRegisteredReceivers.remove(rl.receiver.asBinder()); 13480 int N = rl.size(); 13481 for (int i=0; i<N; i++) { 13482 mReceiverResolver.removeFilter(rl.get(i)); 13483 } 13484 } 13485 13486 private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) { 13487 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 13488 ProcessRecord r = mLruProcesses.get(i); 13489 if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) { 13490 try { 13491 r.thread.dispatchPackageBroadcast(cmd, packages); 13492 } catch (RemoteException ex) { 13493 } 13494 } 13495 } 13496 } 13497 13498 private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType, 13499 int[] users) { 13500 List<ResolveInfo> receivers = null; 13501 try { 13502 HashSet<ComponentName> singleUserReceivers = null; 13503 boolean scannedFirstReceivers = false; 13504 for (int user : users) { 13505 List<ResolveInfo> newReceivers = AppGlobals.getPackageManager() 13506 .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user); 13507 if (user != 0 && newReceivers != null) { 13508 // If this is not the primary user, we need to check for 13509 // any receivers that should be filtered out. 13510 for (int i=0; i<newReceivers.size(); i++) { 13511 ResolveInfo ri = newReceivers.get(i); 13512 if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) { 13513 newReceivers.remove(i); 13514 i--; 13515 } 13516 } 13517 } 13518 if (newReceivers != null && newReceivers.size() == 0) { 13519 newReceivers = null; 13520 } 13521 if (receivers == null) { 13522 receivers = newReceivers; 13523 } else if (newReceivers != null) { 13524 // We need to concatenate the additional receivers 13525 // found with what we have do far. This would be easy, 13526 // but we also need to de-dup any receivers that are 13527 // singleUser. 13528 if (!scannedFirstReceivers) { 13529 // Collect any single user receivers we had already retrieved. 13530 scannedFirstReceivers = true; 13531 for (int i=0; i<receivers.size(); i++) { 13532 ResolveInfo ri = receivers.get(i); 13533 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 13534 ComponentName cn = new ComponentName( 13535 ri.activityInfo.packageName, ri.activityInfo.name); 13536 if (singleUserReceivers == null) { 13537 singleUserReceivers = new HashSet<ComponentName>(); 13538 } 13539 singleUserReceivers.add(cn); 13540 } 13541 } 13542 } 13543 // Add the new results to the existing results, tracking 13544 // and de-dupping single user receivers. 13545 for (int i=0; i<newReceivers.size(); i++) { 13546 ResolveInfo ri = newReceivers.get(i); 13547 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 13548 ComponentName cn = new ComponentName( 13549 ri.activityInfo.packageName, ri.activityInfo.name); 13550 if (singleUserReceivers == null) { 13551 singleUserReceivers = new HashSet<ComponentName>(); 13552 } 13553 if (!singleUserReceivers.contains(cn)) { 13554 singleUserReceivers.add(cn); 13555 receivers.add(ri); 13556 } 13557 } else { 13558 receivers.add(ri); 13559 } 13560 } 13561 } 13562 } 13563 } catch (RemoteException ex) { 13564 // pm is in same process, this will never happen. 13565 } 13566 return receivers; 13567 } 13568 13569 private final int broadcastIntentLocked(ProcessRecord callerApp, 13570 String callerPackage, Intent intent, String resolvedType, 13571 IIntentReceiver resultTo, int resultCode, String resultData, 13572 Bundle map, String requiredPermission, int appOp, 13573 boolean ordered, boolean sticky, int callingPid, int callingUid, 13574 int userId) { 13575 intent = new Intent(intent); 13576 13577 // By default broadcasts do not go to stopped apps. 13578 intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES); 13579 13580 if (DEBUG_BROADCAST_LIGHT) Slog.v( 13581 TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent 13582 + " ordered=" + ordered + " userid=" + userId); 13583 if ((resultTo != null) && !ordered) { 13584 Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!"); 13585 } 13586 13587 userId = handleIncomingUser(callingPid, callingUid, userId, 13588 true, false, "broadcast", callerPackage); 13589 13590 // Make sure that the user who is receiving this broadcast is started. 13591 // If not, we will just skip it. 13592 if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) { 13593 if (callingUid != Process.SYSTEM_UID || (intent.getFlags() 13594 & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) { 13595 Slog.w(TAG, "Skipping broadcast of " + intent 13596 + ": user " + userId + " is stopped"); 13597 return ActivityManager.BROADCAST_SUCCESS; 13598 } 13599 } 13600 13601 /* 13602 * Prevent non-system code (defined here to be non-persistent 13603 * processes) from sending protected broadcasts. 13604 */ 13605 int callingAppId = UserHandle.getAppId(callingUid); 13606 if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID 13607 || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID || 13608 callingUid == 0) { 13609 // Always okay. 13610 } else if (callerApp == null || !callerApp.persistent) { 13611 try { 13612 if (AppGlobals.getPackageManager().isProtectedBroadcast( 13613 intent.getAction())) { 13614 String msg = "Permission Denial: not allowed to send broadcast " 13615 + intent.getAction() + " from pid=" 13616 + callingPid + ", uid=" + callingUid; 13617 Slog.w(TAG, msg); 13618 throw new SecurityException(msg); 13619 } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) { 13620 // Special case for compatibility: we don't want apps to send this, 13621 // but historically it has not been protected and apps may be using it 13622 // to poke their own app widget. So, instead of making it protected, 13623 // just limit it to the caller. 13624 if (callerApp == null) { 13625 String msg = "Permission Denial: not allowed to send broadcast " 13626 + intent.getAction() + " from unknown caller."; 13627 Slog.w(TAG, msg); 13628 throw new SecurityException(msg); 13629 } else if (intent.getComponent() != null) { 13630 // They are good enough to send to an explicit component... verify 13631 // it is being sent to the calling app. 13632 if (!intent.getComponent().getPackageName().equals( 13633 callerApp.info.packageName)) { 13634 String msg = "Permission Denial: not allowed to send broadcast " 13635 + intent.getAction() + " to " 13636 + intent.getComponent().getPackageName() + " from " 13637 + callerApp.info.packageName; 13638 Slog.w(TAG, msg); 13639 throw new SecurityException(msg); 13640 } 13641 } else { 13642 // Limit broadcast to their own package. 13643 intent.setPackage(callerApp.info.packageName); 13644 } 13645 } 13646 } catch (RemoteException e) { 13647 Slog.w(TAG, "Remote exception", e); 13648 return ActivityManager.BROADCAST_SUCCESS; 13649 } 13650 } 13651 13652 // Handle special intents: if this broadcast is from the package 13653 // manager about a package being removed, we need to remove all of 13654 // its activities from the history stack. 13655 final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals( 13656 intent.getAction()); 13657 if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction()) 13658 || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction()) 13659 || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction()) 13660 || uidRemoved) { 13661 if (checkComponentPermission( 13662 android.Manifest.permission.BROADCAST_PACKAGE_REMOVED, 13663 callingPid, callingUid, -1, true) 13664 == PackageManager.PERMISSION_GRANTED) { 13665 if (uidRemoved) { 13666 final Bundle intentExtras = intent.getExtras(); 13667 final int uid = intentExtras != null 13668 ? intentExtras.getInt(Intent.EXTRA_UID) : -1; 13669 if (uid >= 0) { 13670 BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics(); 13671 synchronized (bs) { 13672 bs.removeUidStatsLocked(uid); 13673 } 13674 mAppOpsService.uidRemoved(uid); 13675 } 13676 } else { 13677 // If resources are unavailable just force stop all 13678 // those packages and flush the attribute cache as well. 13679 if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) { 13680 String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 13681 if (list != null && (list.length > 0)) { 13682 for (String pkg : list) { 13683 forceStopPackageLocked(pkg, -1, false, true, true, false, false, userId, 13684 "storage unmount"); 13685 } 13686 sendPackageBroadcastLocked( 13687 IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId); 13688 } 13689 } else { 13690 Uri data = intent.getData(); 13691 String ssp; 13692 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 13693 boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals( 13694 intent.getAction()); 13695 boolean fullUninstall = removed && 13696 !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false); 13697 if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) { 13698 forceStopPackageLocked(ssp, UserHandle.getAppId( 13699 intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true, 13700 false, fullUninstall, userId, 13701 removed ? "pkg removed" : "pkg changed"); 13702 } 13703 if (removed) { 13704 sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED, 13705 new String[] {ssp}, userId); 13706 if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) { 13707 mAppOpsService.packageRemoved( 13708 intent.getIntExtra(Intent.EXTRA_UID, -1), ssp); 13709 13710 // Remove all permissions granted from/to this package 13711 removeUriPermissionsForPackageLocked(ssp, userId, true); 13712 } 13713 } 13714 } 13715 } 13716 } 13717 } else { 13718 String msg = "Permission Denial: " + intent.getAction() 13719 + " broadcast from " + callerPackage + " (pid=" + callingPid 13720 + ", uid=" + callingUid + ")" 13721 + " requires " 13722 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED; 13723 Slog.w(TAG, msg); 13724 throw new SecurityException(msg); 13725 } 13726 13727 // Special case for adding a package: by default turn on compatibility 13728 // mode. 13729 } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) { 13730 Uri data = intent.getData(); 13731 String ssp; 13732 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 13733 mCompatModePackages.handlePackageAddedLocked(ssp, 13734 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)); 13735 } 13736 } 13737 13738 /* 13739 * If this is the time zone changed action, queue up a message that will reset the timezone 13740 * of all currently running processes. This message will get queued up before the broadcast 13741 * happens. 13742 */ 13743 if (Intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) { 13744 mHandler.sendEmptyMessage(UPDATE_TIME_ZONE); 13745 } 13746 13747 /* 13748 * If the user set the time, let all running processes know. 13749 */ 13750 if (Intent.ACTION_TIME_CHANGED.equals(intent.getAction())) { 13751 final int is24Hour = intent.getBooleanExtra( 13752 Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1 : 0; 13753 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0)); 13754 } 13755 13756 if (Intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) { 13757 mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG); 13758 } 13759 13760 if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) { 13761 ProxyProperties proxy = intent.getParcelableExtra("proxy"); 13762 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy)); 13763 } 13764 13765 // Add to the sticky list if requested. 13766 if (sticky) { 13767 if (checkPermission(android.Manifest.permission.BROADCAST_STICKY, 13768 callingPid, callingUid) 13769 != PackageManager.PERMISSION_GRANTED) { 13770 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid=" 13771 + callingPid + ", uid=" + callingUid 13772 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 13773 Slog.w(TAG, msg); 13774 throw new SecurityException(msg); 13775 } 13776 if (requiredPermission != null) { 13777 Slog.w(TAG, "Can't broadcast sticky intent " + intent 13778 + " and enforce permission " + requiredPermission); 13779 return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION; 13780 } 13781 if (intent.getComponent() != null) { 13782 throw new SecurityException( 13783 "Sticky broadcasts can't target a specific component"); 13784 } 13785 // We use userId directly here, since the "all" target is maintained 13786 // as a separate set of sticky broadcasts. 13787 if (userId != UserHandle.USER_ALL) { 13788 // But first, if this is not a broadcast to all users, then 13789 // make sure it doesn't conflict with an existing broadcast to 13790 // all users. 13791 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get( 13792 UserHandle.USER_ALL); 13793 if (stickies != null) { 13794 ArrayList<Intent> list = stickies.get(intent.getAction()); 13795 if (list != null) { 13796 int N = list.size(); 13797 int i; 13798 for (i=0; i<N; i++) { 13799 if (intent.filterEquals(list.get(i))) { 13800 throw new IllegalArgumentException( 13801 "Sticky broadcast " + intent + " for user " 13802 + userId + " conflicts with existing global broadcast"); 13803 } 13804 } 13805 } 13806 } 13807 } 13808 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 13809 if (stickies == null) { 13810 stickies = new ArrayMap<String, ArrayList<Intent>>(); 13811 mStickyBroadcasts.put(userId, stickies); 13812 } 13813 ArrayList<Intent> list = stickies.get(intent.getAction()); 13814 if (list == null) { 13815 list = new ArrayList<Intent>(); 13816 stickies.put(intent.getAction(), list); 13817 } 13818 int N = list.size(); 13819 int i; 13820 for (i=0; i<N; i++) { 13821 if (intent.filterEquals(list.get(i))) { 13822 // This sticky already exists, replace it. 13823 list.set(i, new Intent(intent)); 13824 break; 13825 } 13826 } 13827 if (i >= N) { 13828 list.add(new Intent(intent)); 13829 } 13830 } 13831 13832 int[] users; 13833 if (userId == UserHandle.USER_ALL) { 13834 // Caller wants broadcast to go to all started users. 13835 users = mStartedUserArray; 13836 } else { 13837 // Caller wants broadcast to go to one specific user. 13838 users = new int[] {userId}; 13839 } 13840 13841 // Figure out who all will receive this broadcast. 13842 List receivers = null; 13843 List<BroadcastFilter> registeredReceivers = null; 13844 // Need to resolve the intent to interested receivers... 13845 if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) 13846 == 0) { 13847 receivers = collectReceiverComponents(intent, resolvedType, users); 13848 } 13849 if (intent.getComponent() == null) { 13850 registeredReceivers = mReceiverResolver.queryIntent(intent, 13851 resolvedType, false, userId); 13852 } 13853 13854 final boolean replacePending = 13855 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0; 13856 13857 if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction() 13858 + " replacePending=" + replacePending); 13859 13860 int NR = registeredReceivers != null ? registeredReceivers.size() : 0; 13861 if (!ordered && NR > 0) { 13862 // If we are not serializing this broadcast, then send the 13863 // registered receivers separately so they don't wait for the 13864 // components to be launched. 13865 final BroadcastQueue queue = broadcastQueueForIntent(intent); 13866 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 13867 callerPackage, callingPid, callingUid, resolvedType, requiredPermission, 13868 appOp, registeredReceivers, resultTo, resultCode, resultData, map, 13869 ordered, sticky, false, userId); 13870 if (DEBUG_BROADCAST) Slog.v( 13871 TAG, "Enqueueing parallel broadcast " + r); 13872 final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r); 13873 if (!replaced) { 13874 queue.enqueueParallelBroadcastLocked(r); 13875 queue.scheduleBroadcastsLocked(); 13876 } 13877 registeredReceivers = null; 13878 NR = 0; 13879 } 13880 13881 // Merge into one list. 13882 int ir = 0; 13883 if (receivers != null) { 13884 // A special case for PACKAGE_ADDED: do not allow the package 13885 // being added to see this broadcast. This prevents them from 13886 // using this as a back door to get run as soon as they are 13887 // installed. Maybe in the future we want to have a special install 13888 // broadcast or such for apps, but we'd like to deliberately make 13889 // this decision. 13890 String skipPackages[] = null; 13891 if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction()) 13892 || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction()) 13893 || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) { 13894 Uri data = intent.getData(); 13895 if (data != null) { 13896 String pkgName = data.getSchemeSpecificPart(); 13897 if (pkgName != null) { 13898 skipPackages = new String[] { pkgName }; 13899 } 13900 } 13901 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) { 13902 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 13903 } 13904 if (skipPackages != null && (skipPackages.length > 0)) { 13905 for (String skipPackage : skipPackages) { 13906 if (skipPackage != null) { 13907 int NT = receivers.size(); 13908 for (int it=0; it<NT; it++) { 13909 ResolveInfo curt = (ResolveInfo)receivers.get(it); 13910 if (curt.activityInfo.packageName.equals(skipPackage)) { 13911 receivers.remove(it); 13912 it--; 13913 NT--; 13914 } 13915 } 13916 } 13917 } 13918 } 13919 13920 int NT = receivers != null ? receivers.size() : 0; 13921 int it = 0; 13922 ResolveInfo curt = null; 13923 BroadcastFilter curr = null; 13924 while (it < NT && ir < NR) { 13925 if (curt == null) { 13926 curt = (ResolveInfo)receivers.get(it); 13927 } 13928 if (curr == null) { 13929 curr = registeredReceivers.get(ir); 13930 } 13931 if (curr.getPriority() >= curt.priority) { 13932 // Insert this broadcast record into the final list. 13933 receivers.add(it, curr); 13934 ir++; 13935 curr = null; 13936 it++; 13937 NT++; 13938 } else { 13939 // Skip to the next ResolveInfo in the final list. 13940 it++; 13941 curt = null; 13942 } 13943 } 13944 } 13945 while (ir < NR) { 13946 if (receivers == null) { 13947 receivers = new ArrayList(); 13948 } 13949 receivers.add(registeredReceivers.get(ir)); 13950 ir++; 13951 } 13952 13953 if ((receivers != null && receivers.size() > 0) 13954 || resultTo != null) { 13955 BroadcastQueue queue = broadcastQueueForIntent(intent); 13956 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 13957 callerPackage, callingPid, callingUid, resolvedType, 13958 requiredPermission, appOp, receivers, resultTo, resultCode, 13959 resultData, map, ordered, sticky, false, userId); 13960 if (DEBUG_BROADCAST) Slog.v( 13961 TAG, "Enqueueing ordered broadcast " + r 13962 + ": prev had " + queue.mOrderedBroadcasts.size()); 13963 if (DEBUG_BROADCAST) { 13964 int seq = r.intent.getIntExtra("seq", -1); 13965 Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq); 13966 } 13967 boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r); 13968 if (!replaced) { 13969 queue.enqueueOrderedBroadcastLocked(r); 13970 queue.scheduleBroadcastsLocked(); 13971 } 13972 } 13973 13974 return ActivityManager.BROADCAST_SUCCESS; 13975 } 13976 13977 final Intent verifyBroadcastLocked(Intent intent) { 13978 // Refuse possible leaked file descriptors 13979 if (intent != null && intent.hasFileDescriptors() == true) { 13980 throw new IllegalArgumentException("File descriptors passed in Intent"); 13981 } 13982 13983 int flags = intent.getFlags(); 13984 13985 if (!mProcessesReady) { 13986 // if the caller really truly claims to know what they're doing, go 13987 // ahead and allow the broadcast without launching any receivers 13988 if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) { 13989 intent = new Intent(intent); 13990 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 13991 } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) { 13992 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent 13993 + " before boot completion"); 13994 throw new IllegalStateException("Cannot broadcast before boot completed"); 13995 } 13996 } 13997 13998 if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 13999 throw new IllegalArgumentException( 14000 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 14001 } 14002 14003 return intent; 14004 } 14005 14006 public final int broadcastIntent(IApplicationThread caller, 14007 Intent intent, String resolvedType, IIntentReceiver resultTo, 14008 int resultCode, String resultData, Bundle map, 14009 String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) { 14010 enforceNotIsolatedCaller("broadcastIntent"); 14011 synchronized(this) { 14012 intent = verifyBroadcastLocked(intent); 14013 14014 final ProcessRecord callerApp = getRecordForAppLocked(caller); 14015 final int callingPid = Binder.getCallingPid(); 14016 final int callingUid = Binder.getCallingUid(); 14017 final long origId = Binder.clearCallingIdentity(); 14018 int res = broadcastIntentLocked(callerApp, 14019 callerApp != null ? callerApp.info.packageName : null, 14020 intent, resolvedType, resultTo, 14021 resultCode, resultData, map, requiredPermission, appOp, serialized, sticky, 14022 callingPid, callingUid, userId); 14023 Binder.restoreCallingIdentity(origId); 14024 return res; 14025 } 14026 } 14027 14028 int broadcastIntentInPackage(String packageName, int uid, 14029 Intent intent, String resolvedType, IIntentReceiver resultTo, 14030 int resultCode, String resultData, Bundle map, 14031 String requiredPermission, boolean serialized, boolean sticky, int userId) { 14032 synchronized(this) { 14033 intent = verifyBroadcastLocked(intent); 14034 14035 final long origId = Binder.clearCallingIdentity(); 14036 int res = broadcastIntentLocked(null, packageName, intent, resolvedType, 14037 resultTo, resultCode, resultData, map, requiredPermission, 14038 AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId); 14039 Binder.restoreCallingIdentity(origId); 14040 return res; 14041 } 14042 } 14043 14044 public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) { 14045 // Refuse possible leaked file descriptors 14046 if (intent != null && intent.hasFileDescriptors() == true) { 14047 throw new IllegalArgumentException("File descriptors passed in Intent"); 14048 } 14049 14050 userId = handleIncomingUser(Binder.getCallingPid(), 14051 Binder.getCallingUid(), userId, true, false, "removeStickyBroadcast", null); 14052 14053 synchronized(this) { 14054 if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY) 14055 != PackageManager.PERMISSION_GRANTED) { 14056 String msg = "Permission Denial: unbroadcastIntent() from pid=" 14057 + Binder.getCallingPid() 14058 + ", uid=" + Binder.getCallingUid() 14059 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 14060 Slog.w(TAG, msg); 14061 throw new SecurityException(msg); 14062 } 14063 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 14064 if (stickies != null) { 14065 ArrayList<Intent> list = stickies.get(intent.getAction()); 14066 if (list != null) { 14067 int N = list.size(); 14068 int i; 14069 for (i=0; i<N; i++) { 14070 if (intent.filterEquals(list.get(i))) { 14071 list.remove(i); 14072 break; 14073 } 14074 } 14075 if (list.size() <= 0) { 14076 stickies.remove(intent.getAction()); 14077 } 14078 } 14079 if (stickies.size() <= 0) { 14080 mStickyBroadcasts.remove(userId); 14081 } 14082 } 14083 } 14084 } 14085 14086 private final boolean finishReceiverLocked(IBinder receiver, int resultCode, 14087 String resultData, Bundle resultExtras, boolean resultAbort) { 14088 final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver); 14089 if (r == null) { 14090 Slog.w(TAG, "finishReceiver called but not found on queue"); 14091 return false; 14092 } 14093 14094 return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false); 14095 } 14096 14097 void backgroundServicesFinishedLocked(int userId) { 14098 for (BroadcastQueue queue : mBroadcastQueues) { 14099 queue.backgroundServicesFinishedLocked(userId); 14100 } 14101 } 14102 14103 public void finishReceiver(IBinder who, int resultCode, String resultData, 14104 Bundle resultExtras, boolean resultAbort) { 14105 if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who); 14106 14107 // Refuse possible leaked file descriptors 14108 if (resultExtras != null && resultExtras.hasFileDescriptors()) { 14109 throw new IllegalArgumentException("File descriptors passed in Bundle"); 14110 } 14111 14112 final long origId = Binder.clearCallingIdentity(); 14113 try { 14114 boolean doNext = false; 14115 BroadcastRecord r; 14116 14117 synchronized(this) { 14118 r = broadcastRecordForReceiverLocked(who); 14119 if (r != null) { 14120 doNext = r.queue.finishReceiverLocked(r, resultCode, 14121 resultData, resultExtras, resultAbort, true); 14122 } 14123 } 14124 14125 if (doNext) { 14126 r.queue.processNextBroadcast(false); 14127 } 14128 trimApplications(); 14129 } finally { 14130 Binder.restoreCallingIdentity(origId); 14131 } 14132 } 14133 14134 // ========================================================= 14135 // INSTRUMENTATION 14136 // ========================================================= 14137 14138 public boolean startInstrumentation(ComponentName className, 14139 String profileFile, int flags, Bundle arguments, 14140 IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection, 14141 int userId) { 14142 enforceNotIsolatedCaller("startInstrumentation"); 14143 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 14144 userId, false, true, "startInstrumentation", null); 14145 // Refuse possible leaked file descriptors 14146 if (arguments != null && arguments.hasFileDescriptors()) { 14147 throw new IllegalArgumentException("File descriptors passed in Bundle"); 14148 } 14149 14150 synchronized(this) { 14151 InstrumentationInfo ii = null; 14152 ApplicationInfo ai = null; 14153 try { 14154 ii = mContext.getPackageManager().getInstrumentationInfo( 14155 className, STOCK_PM_FLAGS); 14156 ai = AppGlobals.getPackageManager().getApplicationInfo( 14157 ii.targetPackage, STOCK_PM_FLAGS, userId); 14158 } catch (PackageManager.NameNotFoundException e) { 14159 } catch (RemoteException e) { 14160 } 14161 if (ii == null) { 14162 reportStartInstrumentationFailure(watcher, className, 14163 "Unable to find instrumentation info for: " + className); 14164 return false; 14165 } 14166 if (ai == null) { 14167 reportStartInstrumentationFailure(watcher, className, 14168 "Unable to find instrumentation target package: " + ii.targetPackage); 14169 return false; 14170 } 14171 14172 int match = mContext.getPackageManager().checkSignatures( 14173 ii.targetPackage, ii.packageName); 14174 if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) { 14175 String msg = "Permission Denial: starting instrumentation " 14176 + className + " from pid=" 14177 + Binder.getCallingPid() 14178 + ", uid=" + Binder.getCallingPid() 14179 + " not allowed because package " + ii.packageName 14180 + " does not have a signature matching the target " 14181 + ii.targetPackage; 14182 reportStartInstrumentationFailure(watcher, className, msg); 14183 throw new SecurityException(msg); 14184 } 14185 14186 final long origId = Binder.clearCallingIdentity(); 14187 // Instrumentation can kill and relaunch even persistent processes 14188 forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId, 14189 "start instr"); 14190 ProcessRecord app = addAppLocked(ai, false); 14191 app.instrumentationClass = className; 14192 app.instrumentationInfo = ai; 14193 app.instrumentationProfileFile = profileFile; 14194 app.instrumentationArguments = arguments; 14195 app.instrumentationWatcher = watcher; 14196 app.instrumentationUiAutomationConnection = uiAutomationConnection; 14197 app.instrumentationResultClass = className; 14198 Binder.restoreCallingIdentity(origId); 14199 } 14200 14201 return true; 14202 } 14203 14204 /** 14205 * Report errors that occur while attempting to start Instrumentation. Always writes the 14206 * error to the logs, but if somebody is watching, send the report there too. This enables 14207 * the "am" command to report errors with more information. 14208 * 14209 * @param watcher The IInstrumentationWatcher. Null if there isn't one. 14210 * @param cn The component name of the instrumentation. 14211 * @param report The error report. 14212 */ 14213 private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher, 14214 ComponentName cn, String report) { 14215 Slog.w(TAG, report); 14216 try { 14217 if (watcher != null) { 14218 Bundle results = new Bundle(); 14219 results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService"); 14220 results.putString("Error", report); 14221 watcher.instrumentationStatus(cn, -1, results); 14222 } 14223 } catch (RemoteException e) { 14224 Slog.w(TAG, e); 14225 } 14226 } 14227 14228 void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) { 14229 if (app.instrumentationWatcher != null) { 14230 try { 14231 // NOTE: IInstrumentationWatcher *must* be oneway here 14232 app.instrumentationWatcher.instrumentationFinished( 14233 app.instrumentationClass, 14234 resultCode, 14235 results); 14236 } catch (RemoteException e) { 14237 } 14238 } 14239 if (app.instrumentationUiAutomationConnection != null) { 14240 try { 14241 app.instrumentationUiAutomationConnection.shutdown(); 14242 } catch (RemoteException re) { 14243 /* ignore */ 14244 } 14245 // Only a UiAutomation can set this flag and now that 14246 // it is finished we make sure it is reset to its default. 14247 mUserIsMonkey = false; 14248 } 14249 app.instrumentationWatcher = null; 14250 app.instrumentationUiAutomationConnection = null; 14251 app.instrumentationClass = null; 14252 app.instrumentationInfo = null; 14253 app.instrumentationProfileFile = null; 14254 app.instrumentationArguments = null; 14255 14256 forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId, 14257 "finished inst"); 14258 } 14259 14260 public void finishInstrumentation(IApplicationThread target, 14261 int resultCode, Bundle results) { 14262 int userId = UserHandle.getCallingUserId(); 14263 // Refuse possible leaked file descriptors 14264 if (results != null && results.hasFileDescriptors()) { 14265 throw new IllegalArgumentException("File descriptors passed in Intent"); 14266 } 14267 14268 synchronized(this) { 14269 ProcessRecord app = getRecordForAppLocked(target); 14270 if (app == null) { 14271 Slog.w(TAG, "finishInstrumentation: no app for " + target); 14272 return; 14273 } 14274 final long origId = Binder.clearCallingIdentity(); 14275 finishInstrumentationLocked(app, resultCode, results); 14276 Binder.restoreCallingIdentity(origId); 14277 } 14278 } 14279 14280 // ========================================================= 14281 // CONFIGURATION 14282 // ========================================================= 14283 14284 public ConfigurationInfo getDeviceConfigurationInfo() { 14285 ConfigurationInfo config = new ConfigurationInfo(); 14286 synchronized (this) { 14287 config.reqTouchScreen = mConfiguration.touchscreen; 14288 config.reqKeyboardType = mConfiguration.keyboard; 14289 config.reqNavigation = mConfiguration.navigation; 14290 if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD 14291 || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) { 14292 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV; 14293 } 14294 if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED 14295 && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) { 14296 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD; 14297 } 14298 config.reqGlEsVersion = GL_ES_VERSION; 14299 } 14300 return config; 14301 } 14302 14303 ActivityStack getFocusedStack() { 14304 return mStackSupervisor.getFocusedStack(); 14305 } 14306 14307 public Configuration getConfiguration() { 14308 Configuration ci; 14309 synchronized(this) { 14310 ci = new Configuration(mConfiguration); 14311 } 14312 return ci; 14313 } 14314 14315 public void updatePersistentConfiguration(Configuration values) { 14316 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 14317 "updateConfiguration()"); 14318 enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS, 14319 "updateConfiguration()"); 14320 if (values == null) { 14321 throw new NullPointerException("Configuration must not be null"); 14322 } 14323 14324 synchronized(this) { 14325 final long origId = Binder.clearCallingIdentity(); 14326 updateConfigurationLocked(values, null, true, false); 14327 Binder.restoreCallingIdentity(origId); 14328 } 14329 } 14330 14331 public void updateConfiguration(Configuration values) { 14332 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 14333 "updateConfiguration()"); 14334 14335 synchronized(this) { 14336 if (values == null && mWindowManager != null) { 14337 // sentinel: fetch the current configuration from the window manager 14338 values = mWindowManager.computeNewConfiguration(); 14339 } 14340 14341 if (mWindowManager != null) { 14342 mProcessList.applyDisplaySize(mWindowManager); 14343 } 14344 14345 final long origId = Binder.clearCallingIdentity(); 14346 if (values != null) { 14347 Settings.System.clearConfiguration(values); 14348 } 14349 updateConfigurationLocked(values, null, false, false); 14350 Binder.restoreCallingIdentity(origId); 14351 } 14352 } 14353 14354 /** 14355 * Do either or both things: (1) change the current configuration, and (2) 14356 * make sure the given activity is running with the (now) current 14357 * configuration. Returns true if the activity has been left running, or 14358 * false if <var>starting</var> is being destroyed to match the new 14359 * configuration. 14360 * @param persistent TODO 14361 */ 14362 boolean updateConfigurationLocked(Configuration values, 14363 ActivityRecord starting, boolean persistent, boolean initLocale) { 14364 int changes = 0; 14365 14366 if (values != null) { 14367 Configuration newConfig = new Configuration(mConfiguration); 14368 changes = newConfig.updateFrom(values); 14369 if (changes != 0) { 14370 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) { 14371 Slog.i(TAG, "Updating configuration to: " + values); 14372 } 14373 14374 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes); 14375 14376 if (values.locale != null && !initLocale) { 14377 saveLocaleLocked(values.locale, 14378 !values.locale.equals(mConfiguration.locale), 14379 values.userSetLocale); 14380 } 14381 14382 mConfigurationSeq++; 14383 if (mConfigurationSeq <= 0) { 14384 mConfigurationSeq = 1; 14385 } 14386 newConfig.seq = mConfigurationSeq; 14387 mConfiguration = newConfig; 14388 Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig); 14389 14390 final Configuration configCopy = new Configuration(mConfiguration); 14391 14392 // TODO: If our config changes, should we auto dismiss any currently 14393 // showing dialogs? 14394 mShowDialogs = shouldShowDialogs(newConfig); 14395 14396 AttributeCache ac = AttributeCache.instance(); 14397 if (ac != null) { 14398 ac.updateConfiguration(configCopy); 14399 } 14400 14401 // Make sure all resources in our process are updated 14402 // right now, so that anyone who is going to retrieve 14403 // resource values after we return will be sure to get 14404 // the new ones. This is especially important during 14405 // boot, where the first config change needs to guarantee 14406 // all resources have that config before following boot 14407 // code is executed. 14408 mSystemThread.applyConfigurationToResources(configCopy); 14409 14410 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) { 14411 Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG); 14412 msg.obj = new Configuration(configCopy); 14413 mHandler.sendMessage(msg); 14414 } 14415 14416 for (int i=mLruProcesses.size()-1; i>=0; i--) { 14417 ProcessRecord app = mLruProcesses.get(i); 14418 try { 14419 if (app.thread != null) { 14420 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc " 14421 + app.processName + " new config " + mConfiguration); 14422 app.thread.scheduleConfigurationChanged(configCopy); 14423 } 14424 } catch (Exception e) { 14425 } 14426 } 14427 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED); 14428 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 14429 | Intent.FLAG_RECEIVER_REPLACE_PENDING 14430 | Intent.FLAG_RECEIVER_FOREGROUND); 14431 broadcastIntentLocked(null, null, intent, null, null, 0, null, null, 14432 null, AppOpsManager.OP_NONE, false, false, MY_PID, 14433 Process.SYSTEM_UID, UserHandle.USER_ALL); 14434 if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) { 14435 intent = new Intent(Intent.ACTION_LOCALE_CHANGED); 14436 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 14437 broadcastIntentLocked(null, null, intent, 14438 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 14439 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 14440 } 14441 } 14442 } 14443 14444 boolean kept = true; 14445 final ActivityStack mainStack = mStackSupervisor.getFocusedStack(); 14446 // mainStack is null during startup. 14447 if (mainStack != null) { 14448 if (changes != 0 && starting == null) { 14449 // If the configuration changed, and the caller is not already 14450 // in the process of starting an activity, then find the top 14451 // activity to check if its configuration needs to change. 14452 starting = mainStack.topRunningActivityLocked(null); 14453 } 14454 14455 if (starting != null) { 14456 kept = mainStack.ensureActivityConfigurationLocked(starting, changes); 14457 // And we need to make sure at this point that all other activities 14458 // are made visible with the correct configuration. 14459 mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes); 14460 } 14461 } 14462 14463 if (values != null && mWindowManager != null) { 14464 mWindowManager.setNewConfiguration(mConfiguration); 14465 } 14466 14467 return kept; 14468 } 14469 14470 /** 14471 * Decide based on the configuration whether we should shouw the ANR, 14472 * crash, etc dialogs. The idea is that if there is no affordnace to 14473 * press the on-screen buttons, we shouldn't show the dialog. 14474 * 14475 * A thought: SystemUI might also want to get told about this, the Power 14476 * dialog / global actions also might want different behaviors. 14477 */ 14478 private static final boolean shouldShowDialogs(Configuration config) { 14479 return !(config.keyboard == Configuration.KEYBOARD_NOKEYS 14480 && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH); 14481 } 14482 14483 /** 14484 * Save the locale. You must be inside a synchronized (this) block. 14485 */ 14486 private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) { 14487 if(isDiff) { 14488 SystemProperties.set("user.language", l.getLanguage()); 14489 SystemProperties.set("user.region", l.getCountry()); 14490 } 14491 14492 if(isPersist) { 14493 SystemProperties.set("persist.sys.language", l.getLanguage()); 14494 SystemProperties.set("persist.sys.country", l.getCountry()); 14495 SystemProperties.set("persist.sys.localevar", l.getVariant()); 14496 } 14497 } 14498 14499 @Override 14500 public boolean targetTaskAffinityMatchesActivity(IBinder token, String destAffinity) { 14501 ActivityRecord srec = ActivityRecord.forToken(token); 14502 return srec != null && srec.task.affinity != null && 14503 srec.task.affinity.equals(destAffinity); 14504 } 14505 14506 public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode, 14507 Intent resultData) { 14508 14509 synchronized (this) { 14510 final ActivityStack stack = ActivityRecord.getStackLocked(token); 14511 if (stack != null) { 14512 return stack.navigateUpToLocked(token, destIntent, resultCode, resultData); 14513 } 14514 return false; 14515 } 14516 } 14517 14518 public int getLaunchedFromUid(IBinder activityToken) { 14519 ActivityRecord srec = ActivityRecord.forToken(activityToken); 14520 if (srec == null) { 14521 return -1; 14522 } 14523 return srec.launchedFromUid; 14524 } 14525 14526 public String getLaunchedFromPackage(IBinder activityToken) { 14527 ActivityRecord srec = ActivityRecord.forToken(activityToken); 14528 if (srec == null) { 14529 return null; 14530 } 14531 return srec.launchedFromPackage; 14532 } 14533 14534 // ========================================================= 14535 // LIFETIME MANAGEMENT 14536 // ========================================================= 14537 14538 // Returns which broadcast queue the app is the current [or imminent] receiver 14539 // on, or 'null' if the app is not an active broadcast recipient. 14540 private BroadcastQueue isReceivingBroadcast(ProcessRecord app) { 14541 BroadcastRecord r = app.curReceiver; 14542 if (r != null) { 14543 return r.queue; 14544 } 14545 14546 // It's not the current receiver, but it might be starting up to become one 14547 synchronized (this) { 14548 for (BroadcastQueue queue : mBroadcastQueues) { 14549 r = queue.mPendingBroadcast; 14550 if (r != null && r.curApp == app) { 14551 // found it; report which queue it's in 14552 return queue; 14553 } 14554 } 14555 } 14556 14557 return null; 14558 } 14559 14560 private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP, 14561 boolean doingAll, long now) { 14562 if (mAdjSeq == app.adjSeq) { 14563 // This adjustment has already been computed. 14564 return app.curRawAdj; 14565 } 14566 14567 if (app.thread == null) { 14568 app.adjSeq = mAdjSeq; 14569 app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 14570 app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 14571 return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ); 14572 } 14573 14574 app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN; 14575 app.adjSource = null; 14576 app.adjTarget = null; 14577 app.empty = false; 14578 app.cached = false; 14579 14580 final int activitiesSize = app.activities.size(); 14581 14582 if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) { 14583 // The max adjustment doesn't allow this app to be anything 14584 // below foreground, so it is not worth doing work for it. 14585 app.adjType = "fixed"; 14586 app.adjSeq = mAdjSeq; 14587 app.curRawAdj = app.maxAdj; 14588 app.foregroundActivities = false; 14589 app.keeping = true; 14590 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT; 14591 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT; 14592 // System processes can do UI, and when they do we want to have 14593 // them trim their memory after the user leaves the UI. To 14594 // facilitate this, here we need to determine whether or not it 14595 // is currently showing UI. 14596 app.systemNoUi = true; 14597 if (app == TOP_APP) { 14598 app.systemNoUi = false; 14599 } else if (activitiesSize > 0) { 14600 for (int j = 0; j < activitiesSize; j++) { 14601 final ActivityRecord r = app.activities.get(j); 14602 if (r.visible) { 14603 app.systemNoUi = false; 14604 } 14605 } 14606 } 14607 if (!app.systemNoUi) { 14608 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI; 14609 } 14610 return (app.curAdj=app.maxAdj); 14611 } 14612 14613 app.keeping = false; 14614 app.systemNoUi = false; 14615 14616 // Determine the importance of the process, starting with most 14617 // important to least, and assign an appropriate OOM adjustment. 14618 int adj; 14619 int schedGroup; 14620 int procState; 14621 boolean foregroundActivities = false; 14622 boolean interesting = false; 14623 BroadcastQueue queue; 14624 if (app == TOP_APP) { 14625 // The last app on the list is the foreground app. 14626 adj = ProcessList.FOREGROUND_APP_ADJ; 14627 schedGroup = Process.THREAD_GROUP_DEFAULT; 14628 app.adjType = "top-activity"; 14629 foregroundActivities = true; 14630 interesting = true; 14631 procState = ActivityManager.PROCESS_STATE_TOP; 14632 } else if (app.instrumentationClass != null) { 14633 // Don't want to kill running instrumentation. 14634 adj = ProcessList.FOREGROUND_APP_ADJ; 14635 schedGroup = Process.THREAD_GROUP_DEFAULT; 14636 app.adjType = "instrumentation"; 14637 interesting = true; 14638 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14639 } else if ((queue = isReceivingBroadcast(app)) != null) { 14640 // An app that is currently receiving a broadcast also 14641 // counts as being in the foreground for OOM killer purposes. 14642 // It's placed in a sched group based on the nature of the 14643 // broadcast as reflected by which queue it's active in. 14644 adj = ProcessList.FOREGROUND_APP_ADJ; 14645 schedGroup = (queue == mFgBroadcastQueue) 14646 ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 14647 app.adjType = "broadcast"; 14648 procState = ActivityManager.PROCESS_STATE_RECEIVER; 14649 } else if (app.executingServices.size() > 0) { 14650 // An app that is currently executing a service callback also 14651 // counts as being in the foreground. 14652 adj = ProcessList.FOREGROUND_APP_ADJ; 14653 schedGroup = app.execServicesFg ? 14654 Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 14655 app.adjType = "exec-service"; 14656 procState = ActivityManager.PROCESS_STATE_SERVICE; 14657 //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app); 14658 } else { 14659 // As far as we know the process is empty. We may change our mind later. 14660 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 14661 // At this point we don't actually know the adjustment. Use the cached adj 14662 // value that the caller wants us to. 14663 adj = cachedAdj; 14664 procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 14665 app.cached = true; 14666 app.empty = true; 14667 app.adjType = "cch-empty"; 14668 } 14669 14670 // Examine all activities if not already foreground. 14671 if (!foregroundActivities && activitiesSize > 0) { 14672 for (int j = 0; j < activitiesSize; j++) { 14673 final ActivityRecord r = app.activities.get(j); 14674 if (r.app != app) { 14675 Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc " 14676 + app + "?!?"); 14677 continue; 14678 } 14679 if (r.visible) { 14680 // App has a visible activity; only upgrade adjustment. 14681 if (adj > ProcessList.VISIBLE_APP_ADJ) { 14682 adj = ProcessList.VISIBLE_APP_ADJ; 14683 app.adjType = "visible"; 14684 } 14685 if (procState > ActivityManager.PROCESS_STATE_TOP) { 14686 procState = ActivityManager.PROCESS_STATE_TOP; 14687 } 14688 schedGroup = Process.THREAD_GROUP_DEFAULT; 14689 app.cached = false; 14690 app.empty = false; 14691 foregroundActivities = true; 14692 break; 14693 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) { 14694 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14695 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 14696 app.adjType = "pausing"; 14697 } 14698 if (procState > ActivityManager.PROCESS_STATE_TOP) { 14699 procState = ActivityManager.PROCESS_STATE_TOP; 14700 } 14701 schedGroup = Process.THREAD_GROUP_DEFAULT; 14702 app.cached = false; 14703 app.empty = false; 14704 foregroundActivities = true; 14705 } else if (r.state == ActivityState.STOPPING) { 14706 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14707 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 14708 app.adjType = "stopping"; 14709 } 14710 // For the process state, we will at this point consider the 14711 // process to be cached. It will be cached either as an activity 14712 // or empty depending on whether the activity is finishing. We do 14713 // this so that we can treat the process as cached for purposes of 14714 // memory trimming (determing current memory level, trim command to 14715 // send to process) since there can be an arbitrary number of stopping 14716 // processes and they should soon all go into the cached state. 14717 if (!r.finishing) { 14718 if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 14719 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 14720 } 14721 } 14722 app.cached = false; 14723 app.empty = false; 14724 foregroundActivities = true; 14725 } else { 14726 if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 14727 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 14728 app.adjType = "cch-act"; 14729 } 14730 } 14731 } 14732 } 14733 14734 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14735 if (app.foregroundServices) { 14736 // The user is aware of this app, so make it visible. 14737 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 14738 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14739 app.cached = false; 14740 app.adjType = "fg-service"; 14741 schedGroup = Process.THREAD_GROUP_DEFAULT; 14742 } else if (app.forcingToForeground != null) { 14743 // The user is aware of this app, so make it visible. 14744 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 14745 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14746 app.cached = false; 14747 app.adjType = "force-fg"; 14748 app.adjSource = app.forcingToForeground; 14749 schedGroup = Process.THREAD_GROUP_DEFAULT; 14750 } 14751 } 14752 14753 if (app.foregroundServices) { 14754 interesting = true; 14755 } 14756 14757 if (app == mHeavyWeightProcess) { 14758 if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) { 14759 // We don't want to kill the current heavy-weight process. 14760 adj = ProcessList.HEAVY_WEIGHT_APP_ADJ; 14761 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 14762 app.cached = false; 14763 app.adjType = "heavy"; 14764 } 14765 if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) { 14766 procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT; 14767 } 14768 } 14769 14770 if (app == mHomeProcess) { 14771 if (adj > ProcessList.HOME_APP_ADJ) { 14772 // This process is hosting what we currently consider to be the 14773 // home app, so we don't want to let it go into the background. 14774 adj = ProcessList.HOME_APP_ADJ; 14775 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 14776 app.cached = false; 14777 app.adjType = "home"; 14778 } 14779 if (procState > ActivityManager.PROCESS_STATE_HOME) { 14780 procState = ActivityManager.PROCESS_STATE_HOME; 14781 } 14782 } 14783 14784 if (app == mPreviousProcess && app.activities.size() > 0) { 14785 if (adj > ProcessList.PREVIOUS_APP_ADJ) { 14786 // This was the previous process that showed UI to the user. 14787 // We want to try to keep it around more aggressively, to give 14788 // a good experience around switching between two apps. 14789 adj = ProcessList.PREVIOUS_APP_ADJ; 14790 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 14791 app.cached = false; 14792 app.adjType = "previous"; 14793 } 14794 if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) { 14795 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY; 14796 } 14797 } 14798 14799 if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj 14800 + " reason=" + app.adjType); 14801 14802 // By default, we use the computed adjustment. It may be changed if 14803 // there are applications dependent on our services or providers, but 14804 // this gives us a baseline and makes sure we don't get into an 14805 // infinite recursion. 14806 app.adjSeq = mAdjSeq; 14807 app.curRawAdj = adj; 14808 app.hasStartedServices = false; 14809 14810 if (mBackupTarget != null && app == mBackupTarget.app) { 14811 // If possible we want to avoid killing apps while they're being backed up 14812 if (adj > ProcessList.BACKUP_APP_ADJ) { 14813 if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app); 14814 adj = ProcessList.BACKUP_APP_ADJ; 14815 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) { 14816 procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND; 14817 } 14818 app.adjType = "backup"; 14819 app.cached = false; 14820 } 14821 if (procState > ActivityManager.PROCESS_STATE_BACKUP) { 14822 procState = ActivityManager.PROCESS_STATE_BACKUP; 14823 } 14824 } 14825 14826 boolean mayBeTop = false; 14827 14828 for (int is = app.services.size()-1; 14829 is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 14830 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 14831 || procState > ActivityManager.PROCESS_STATE_TOP); 14832 is--) { 14833 ServiceRecord s = app.services.valueAt(is); 14834 if (s.startRequested) { 14835 app.hasStartedServices = true; 14836 if (procState > ActivityManager.PROCESS_STATE_SERVICE) { 14837 procState = ActivityManager.PROCESS_STATE_SERVICE; 14838 } 14839 if (app.hasShownUi && app != mHomeProcess) { 14840 // If this process has shown some UI, let it immediately 14841 // go to the LRU list because it may be pretty heavy with 14842 // UI stuff. We'll tag it with a label just to help 14843 // debug and understand what is going on. 14844 if (adj > ProcessList.SERVICE_ADJ) { 14845 app.adjType = "cch-started-ui-services"; 14846 } 14847 } else { 14848 if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) { 14849 // This service has seen some activity within 14850 // recent memory, so we will keep its process ahead 14851 // of the background processes. 14852 if (adj > ProcessList.SERVICE_ADJ) { 14853 adj = ProcessList.SERVICE_ADJ; 14854 app.adjType = "started-services"; 14855 app.cached = false; 14856 } 14857 } 14858 // If we have let the service slide into the background 14859 // state, still have some text describing what it is doing 14860 // even though the service no longer has an impact. 14861 if (adj > ProcessList.SERVICE_ADJ) { 14862 app.adjType = "cch-started-services"; 14863 } 14864 } 14865 // Don't kill this process because it is doing work; it 14866 // has said it is doing work. 14867 app.keeping = true; 14868 } 14869 for (int conni = s.connections.size()-1; 14870 conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 14871 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 14872 || procState > ActivityManager.PROCESS_STATE_TOP); 14873 conni--) { 14874 ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni); 14875 for (int i = 0; 14876 i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ 14877 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 14878 || procState > ActivityManager.PROCESS_STATE_TOP); 14879 i++) { 14880 // XXX should compute this based on the max of 14881 // all connected clients. 14882 ConnectionRecord cr = clist.get(i); 14883 if (cr.binding.client == app) { 14884 // Binding to ourself is not interesting. 14885 continue; 14886 } 14887 if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) { 14888 ProcessRecord client = cr.binding.client; 14889 int clientAdj = computeOomAdjLocked(client, cachedAdj, 14890 TOP_APP, doingAll, now); 14891 int clientProcState = client.curProcState; 14892 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 14893 // If the other app is cached for any reason, for purposes here 14894 // we are going to consider it empty. The specific cached state 14895 // doesn't propagate except under certain conditions. 14896 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 14897 } 14898 String adjType = null; 14899 if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) { 14900 // Not doing bind OOM management, so treat 14901 // this guy more like a started service. 14902 if (app.hasShownUi && app != mHomeProcess) { 14903 // If this process has shown some UI, let it immediately 14904 // go to the LRU list because it may be pretty heavy with 14905 // UI stuff. We'll tag it with a label just to help 14906 // debug and understand what is going on. 14907 if (adj > clientAdj) { 14908 adjType = "cch-bound-ui-services"; 14909 } 14910 app.cached = false; 14911 clientAdj = adj; 14912 clientProcState = procState; 14913 } else { 14914 if (now >= (s.lastActivity 14915 + ActiveServices.MAX_SERVICE_INACTIVITY)) { 14916 // This service has not seen activity within 14917 // recent memory, so allow it to drop to the 14918 // LRU list if there is no other reason to keep 14919 // it around. We'll also tag it with a label just 14920 // to help debug and undertand what is going on. 14921 if (adj > clientAdj) { 14922 adjType = "cch-bound-services"; 14923 } 14924 clientAdj = adj; 14925 } 14926 } 14927 } 14928 if (adj > clientAdj) { 14929 // If this process has recently shown UI, and 14930 // the process that is binding to it is less 14931 // important than being visible, then we don't 14932 // care about the binding as much as we care 14933 // about letting this process get into the LRU 14934 // list to be killed and restarted if needed for 14935 // memory. 14936 if (app.hasShownUi && app != mHomeProcess 14937 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14938 adjType = "cch-bound-ui-services"; 14939 } else { 14940 if ((cr.flags&(Context.BIND_ABOVE_CLIENT 14941 |Context.BIND_IMPORTANT)) != 0) { 14942 adj = clientAdj; 14943 } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0 14944 && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ 14945 && adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14946 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 14947 } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) { 14948 adj = clientAdj; 14949 } else { 14950 if (adj > ProcessList.VISIBLE_APP_ADJ) { 14951 adj = ProcessList.VISIBLE_APP_ADJ; 14952 } 14953 } 14954 if (!client.cached) { 14955 app.cached = false; 14956 } 14957 if (client.keeping) { 14958 app.keeping = true; 14959 } 14960 adjType = "service"; 14961 } 14962 } 14963 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 14964 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 14965 schedGroup = Process.THREAD_GROUP_DEFAULT; 14966 } 14967 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) { 14968 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) { 14969 // Special handling of clients who are in the top state. 14970 // We *may* want to consider this process to be in the 14971 // top state as well, but only if there is not another 14972 // reason for it to be running. Being on the top is a 14973 // special state, meaning you are specifically running 14974 // for the current top app. If the process is already 14975 // running in the background for some other reason, it 14976 // is more important to continue considering it to be 14977 // in the background state. 14978 mayBeTop = true; 14979 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 14980 } else { 14981 // Special handling for above-top states (persistent 14982 // processes). These should not bring the current process 14983 // into the top state, since they are not on top. Instead 14984 // give them the best state after that. 14985 clientProcState = 14986 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14987 } 14988 } 14989 } else { 14990 if (clientProcState < 14991 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) { 14992 clientProcState = 14993 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND; 14994 } 14995 } 14996 if (procState > clientProcState) { 14997 procState = clientProcState; 14998 } 14999 if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 15000 && (cr.flags&Context.BIND_SHOWING_UI) != 0) { 15001 app.pendingUiClean = true; 15002 } 15003 if (adjType != null) { 15004 app.adjType = adjType; 15005 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 15006 .REASON_SERVICE_IN_USE; 15007 app.adjSource = cr.binding.client; 15008 app.adjSourceOom = clientAdj; 15009 app.adjTarget = s.name; 15010 } 15011 } 15012 if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) { 15013 app.treatLikeActivity = true; 15014 } 15015 final ActivityRecord a = cr.activity; 15016 if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) { 15017 if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ && 15018 (a.visible || a.state == ActivityState.RESUMED 15019 || a.state == ActivityState.PAUSING)) { 15020 adj = ProcessList.FOREGROUND_APP_ADJ; 15021 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 15022 schedGroup = Process.THREAD_GROUP_DEFAULT; 15023 } 15024 app.cached = false; 15025 app.adjType = "service"; 15026 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 15027 .REASON_SERVICE_IN_USE; 15028 app.adjSource = a; 15029 app.adjSourceOom = adj; 15030 app.adjTarget = s.name; 15031 } 15032 } 15033 } 15034 } 15035 } 15036 15037 for (int provi = app.pubProviders.size()-1; 15038 provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 15039 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 15040 || procState > ActivityManager.PROCESS_STATE_TOP); 15041 provi--) { 15042 ContentProviderRecord cpr = app.pubProviders.valueAt(provi); 15043 for (int i = cpr.connections.size()-1; 15044 i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 15045 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 15046 || procState > ActivityManager.PROCESS_STATE_TOP); 15047 i--) { 15048 ContentProviderConnection conn = cpr.connections.get(i); 15049 ProcessRecord client = conn.client; 15050 if (client == app) { 15051 // Being our own client is not interesting. 15052 continue; 15053 } 15054 int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now); 15055 int clientProcState = client.curProcState; 15056 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 15057 // If the other app is cached for any reason, for purposes here 15058 // we are going to consider it empty. 15059 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 15060 } 15061 if (adj > clientAdj) { 15062 if (app.hasShownUi && app != mHomeProcess 15063 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 15064 app.adjType = "cch-ui-provider"; 15065 } else { 15066 adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ 15067 ? clientAdj : ProcessList.FOREGROUND_APP_ADJ; 15068 app.adjType = "provider"; 15069 } 15070 app.cached &= client.cached; 15071 app.keeping |= client.keeping; 15072 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 15073 .REASON_PROVIDER_IN_USE; 15074 app.adjSource = client; 15075 app.adjSourceOom = clientAdj; 15076 app.adjTarget = cpr.name; 15077 } 15078 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) { 15079 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) { 15080 // Special handling of clients who are in the top state. 15081 // We *may* want to consider this process to be in the 15082 // top state as well, but only if there is not another 15083 // reason for it to be running. Being on the top is a 15084 // special state, meaning you are specifically running 15085 // for the current top app. If the process is already 15086 // running in the background for some other reason, it 15087 // is more important to continue considering it to be 15088 // in the background state. 15089 mayBeTop = true; 15090 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 15091 } else { 15092 // Special handling for above-top states (persistent 15093 // processes). These should not bring the current process 15094 // into the top state, since they are not on top. Instead 15095 // give them the best state after that. 15096 clientProcState = 15097 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 15098 } 15099 } 15100 if (procState > clientProcState) { 15101 procState = clientProcState; 15102 } 15103 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 15104 schedGroup = Process.THREAD_GROUP_DEFAULT; 15105 } 15106 } 15107 // If the provider has external (non-framework) process 15108 // dependencies, ensure that its adjustment is at least 15109 // FOREGROUND_APP_ADJ. 15110 if (cpr.hasExternalProcessHandles()) { 15111 if (adj > ProcessList.FOREGROUND_APP_ADJ) { 15112 adj = ProcessList.FOREGROUND_APP_ADJ; 15113 schedGroup = Process.THREAD_GROUP_DEFAULT; 15114 app.cached = false; 15115 app.keeping = true; 15116 app.adjType = "provider"; 15117 app.adjTarget = cpr.name; 15118 } 15119 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) { 15120 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 15121 } 15122 } 15123 } 15124 15125 if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) { 15126 // A client of one of our services or providers is in the top state. We 15127 // *may* want to be in the top state, but not if we are already running in 15128 // the background for some other reason. For the decision here, we are going 15129 // to pick out a few specific states that we want to remain in when a client 15130 // is top (states that tend to be longer-term) and otherwise allow it to go 15131 // to the top state. 15132 switch (procState) { 15133 case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND: 15134 case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND: 15135 case ActivityManager.PROCESS_STATE_SERVICE: 15136 // These all are longer-term states, so pull them up to the top 15137 // of the background states, but not all the way to the top state. 15138 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 15139 break; 15140 default: 15141 // Otherwise, top is a better choice, so take it. 15142 procState = ActivityManager.PROCESS_STATE_TOP; 15143 break; 15144 } 15145 } 15146 15147 if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) { 15148 if (app.hasClientActivities) { 15149 // This is a cached process, but with client activities. Mark it so. 15150 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT; 15151 app.adjType = "cch-client-act"; 15152 } else if (app.treatLikeActivity) { 15153 // This is a cached process, but somebody wants us to treat it like it has 15154 // an activity, okay! 15155 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 15156 app.adjType = "cch-as-act"; 15157 } 15158 } 15159 15160 if (adj == ProcessList.SERVICE_ADJ) { 15161 if (doingAll) { 15162 app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3); 15163 mNewNumServiceProcs++; 15164 //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb); 15165 if (!app.serviceb) { 15166 // This service isn't far enough down on the LRU list to 15167 // normally be a B service, but if we are low on RAM and it 15168 // is large we want to force it down since we would prefer to 15169 // keep launcher over it. 15170 if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL 15171 && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) { 15172 app.serviceHighRam = true; 15173 app.serviceb = true; 15174 //Slog.i(TAG, "ADJ " + app + " high ram!"); 15175 } else { 15176 mNewNumAServiceProcs++; 15177 //Slog.i(TAG, "ADJ " + app + " not high ram!"); 15178 } 15179 } else { 15180 app.serviceHighRam = false; 15181 } 15182 } 15183 if (app.serviceb) { 15184 adj = ProcessList.SERVICE_B_ADJ; 15185 } 15186 } 15187 15188 app.curRawAdj = adj; 15189 15190 //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid + 15191 // " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj); 15192 if (adj > app.maxAdj) { 15193 adj = app.maxAdj; 15194 if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 15195 schedGroup = Process.THREAD_GROUP_DEFAULT; 15196 } 15197 } 15198 if (adj < ProcessList.CACHED_APP_MIN_ADJ) { 15199 app.keeping = true; 15200 } 15201 15202 // Do final modification to adj. Everything we do between here and applying 15203 // the final setAdj must be done in this function, because we will also use 15204 // it when computing the final cached adj later. Note that we don't need to 15205 // worry about this for max adj above, since max adj will always be used to 15206 // keep it out of the cached vaues. 15207 app.curAdj = app.modifyRawOomAdj(adj); 15208 app.curSchedGroup = schedGroup; 15209 app.curProcState = procState; 15210 app.foregroundActivities = foregroundActivities; 15211 15212 return app.curRawAdj; 15213 } 15214 15215 /** 15216 * Schedule PSS collection of a process. 15217 */ 15218 void requestPssLocked(ProcessRecord proc, int procState) { 15219 if (mPendingPssProcesses.contains(proc)) { 15220 return; 15221 } 15222 if (mPendingPssProcesses.size() == 0) { 15223 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG); 15224 } 15225 if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc); 15226 proc.pssProcState = procState; 15227 mPendingPssProcesses.add(proc); 15228 } 15229 15230 /** 15231 * Schedule PSS collection of all processes. 15232 */ 15233 void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) { 15234 if (!always) { 15235 if (now < (mLastFullPssTime + 15236 (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) { 15237 return; 15238 } 15239 } 15240 if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs! memLowered=" + memLowered); 15241 mLastFullPssTime = now; 15242 mPendingPssProcesses.ensureCapacity(mLruProcesses.size()); 15243 mPendingPssProcesses.clear(); 15244 for (int i=mLruProcesses.size()-1; i>=0; i--) { 15245 ProcessRecord app = mLruProcesses.get(i); 15246 if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) { 15247 app.pssProcState = app.setProcState; 15248 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true, 15249 isSleeping(), now); 15250 mPendingPssProcesses.add(app); 15251 } 15252 } 15253 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG); 15254 } 15255 15256 /** 15257 * Ask a given process to GC right now. 15258 */ 15259 final void performAppGcLocked(ProcessRecord app) { 15260 try { 15261 app.lastRequestedGc = SystemClock.uptimeMillis(); 15262 if (app.thread != null) { 15263 if (app.reportLowMemory) { 15264 app.reportLowMemory = false; 15265 app.thread.scheduleLowMemory(); 15266 } else { 15267 app.thread.processInBackground(); 15268 } 15269 } 15270 } catch (Exception e) { 15271 // whatever. 15272 } 15273 } 15274 15275 /** 15276 * Returns true if things are idle enough to perform GCs. 15277 */ 15278 private final boolean canGcNowLocked() { 15279 boolean processingBroadcasts = false; 15280 for (BroadcastQueue q : mBroadcastQueues) { 15281 if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) { 15282 processingBroadcasts = true; 15283 } 15284 } 15285 return !processingBroadcasts 15286 && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle()); 15287 } 15288 15289 /** 15290 * Perform GCs on all processes that are waiting for it, but only 15291 * if things are idle. 15292 */ 15293 final void performAppGcsLocked() { 15294 final int N = mProcessesToGc.size(); 15295 if (N <= 0) { 15296 return; 15297 } 15298 if (canGcNowLocked()) { 15299 while (mProcessesToGc.size() > 0) { 15300 ProcessRecord proc = mProcessesToGc.remove(0); 15301 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) { 15302 if ((proc.lastRequestedGc+GC_MIN_INTERVAL) 15303 <= SystemClock.uptimeMillis()) { 15304 // To avoid spamming the system, we will GC processes one 15305 // at a time, waiting a few seconds between each. 15306 performAppGcLocked(proc); 15307 scheduleAppGcsLocked(); 15308 return; 15309 } else { 15310 // It hasn't been long enough since we last GCed this 15311 // process... put it in the list to wait for its time. 15312 addProcessToGcListLocked(proc); 15313 break; 15314 } 15315 } 15316 } 15317 15318 scheduleAppGcsLocked(); 15319 } 15320 } 15321 15322 /** 15323 * If all looks good, perform GCs on all processes waiting for them. 15324 */ 15325 final void performAppGcsIfAppropriateLocked() { 15326 if (canGcNowLocked()) { 15327 performAppGcsLocked(); 15328 return; 15329 } 15330 // Still not idle, wait some more. 15331 scheduleAppGcsLocked(); 15332 } 15333 15334 /** 15335 * Schedule the execution of all pending app GCs. 15336 */ 15337 final void scheduleAppGcsLocked() { 15338 mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG); 15339 15340 if (mProcessesToGc.size() > 0) { 15341 // Schedule a GC for the time to the next process. 15342 ProcessRecord proc = mProcessesToGc.get(0); 15343 Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG); 15344 15345 long when = proc.lastRequestedGc + GC_MIN_INTERVAL; 15346 long now = SystemClock.uptimeMillis(); 15347 if (when < (now+GC_TIMEOUT)) { 15348 when = now + GC_TIMEOUT; 15349 } 15350 mHandler.sendMessageAtTime(msg, when); 15351 } 15352 } 15353 15354 /** 15355 * Add a process to the array of processes waiting to be GCed. Keeps the 15356 * list in sorted order by the last GC time. The process can't already be 15357 * on the list. 15358 */ 15359 final void addProcessToGcListLocked(ProcessRecord proc) { 15360 boolean added = false; 15361 for (int i=mProcessesToGc.size()-1; i>=0; i--) { 15362 if (mProcessesToGc.get(i).lastRequestedGc < 15363 proc.lastRequestedGc) { 15364 added = true; 15365 mProcessesToGc.add(i+1, proc); 15366 break; 15367 } 15368 } 15369 if (!added) { 15370 mProcessesToGc.add(0, proc); 15371 } 15372 } 15373 15374 /** 15375 * Set up to ask a process to GC itself. This will either do it 15376 * immediately, or put it on the list of processes to gc the next 15377 * time things are idle. 15378 */ 15379 final void scheduleAppGcLocked(ProcessRecord app) { 15380 long now = SystemClock.uptimeMillis(); 15381 if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) { 15382 return; 15383 } 15384 if (!mProcessesToGc.contains(app)) { 15385 addProcessToGcListLocked(app); 15386 scheduleAppGcsLocked(); 15387 } 15388 } 15389 15390 final void checkExcessivePowerUsageLocked(boolean doKills) { 15391 updateCpuStatsNow(); 15392 15393 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 15394 boolean doWakeKills = doKills; 15395 boolean doCpuKills = doKills; 15396 if (mLastPowerCheckRealtime == 0) { 15397 doWakeKills = false; 15398 } 15399 if (mLastPowerCheckUptime == 0) { 15400 doCpuKills = false; 15401 } 15402 if (stats.isScreenOn()) { 15403 doWakeKills = false; 15404 } 15405 final long curRealtime = SystemClock.elapsedRealtime(); 15406 final long realtimeSince = curRealtime - mLastPowerCheckRealtime; 15407 final long curUptime = SystemClock.uptimeMillis(); 15408 final long uptimeSince = curUptime - mLastPowerCheckUptime; 15409 mLastPowerCheckRealtime = curRealtime; 15410 mLastPowerCheckUptime = curUptime; 15411 if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) { 15412 doWakeKills = false; 15413 } 15414 if (uptimeSince < CPU_MIN_CHECK_DURATION) { 15415 doCpuKills = false; 15416 } 15417 int i = mLruProcesses.size(); 15418 while (i > 0) { 15419 i--; 15420 ProcessRecord app = mLruProcesses.get(i); 15421 if (!app.keeping) { 15422 long wtime; 15423 synchronized (stats) { 15424 wtime = stats.getProcessWakeTime(app.info.uid, 15425 app.pid, curRealtime); 15426 } 15427 long wtimeUsed = wtime - app.lastWakeTime; 15428 long cputimeUsed = app.curCpuTime - app.lastCpuTime; 15429 if (DEBUG_POWER) { 15430 StringBuilder sb = new StringBuilder(128); 15431 sb.append("Wake for "); 15432 app.toShortString(sb); 15433 sb.append(": over "); 15434 TimeUtils.formatDuration(realtimeSince, sb); 15435 sb.append(" used "); 15436 TimeUtils.formatDuration(wtimeUsed, sb); 15437 sb.append(" ("); 15438 sb.append((wtimeUsed*100)/realtimeSince); 15439 sb.append("%)"); 15440 Slog.i(TAG, sb.toString()); 15441 sb.setLength(0); 15442 sb.append("CPU for "); 15443 app.toShortString(sb); 15444 sb.append(": over "); 15445 TimeUtils.formatDuration(uptimeSince, sb); 15446 sb.append(" used "); 15447 TimeUtils.formatDuration(cputimeUsed, sb); 15448 sb.append(" ("); 15449 sb.append((cputimeUsed*100)/uptimeSince); 15450 sb.append("%)"); 15451 Slog.i(TAG, sb.toString()); 15452 } 15453 // If a process has held a wake lock for more 15454 // than 50% of the time during this period, 15455 // that sounds bad. Kill! 15456 if (doWakeKills && realtimeSince > 0 15457 && ((wtimeUsed*100)/realtimeSince) >= 50) { 15458 synchronized (stats) { 15459 stats.reportExcessiveWakeLocked(app.info.uid, app.processName, 15460 realtimeSince, wtimeUsed); 15461 } 15462 killUnneededProcessLocked(app, "excessive wake held " + wtimeUsed 15463 + " during " + realtimeSince); 15464 app.baseProcessTracker.reportExcessiveWake(app.pkgList); 15465 } else if (doCpuKills && uptimeSince > 0 15466 && ((cputimeUsed*100)/uptimeSince) >= 50) { 15467 synchronized (stats) { 15468 stats.reportExcessiveCpuLocked(app.info.uid, app.processName, 15469 uptimeSince, cputimeUsed); 15470 } 15471 killUnneededProcessLocked(app, "excessive cpu " + cputimeUsed 15472 + " during " + uptimeSince); 15473 app.baseProcessTracker.reportExcessiveCpu(app.pkgList); 15474 } else { 15475 app.lastWakeTime = wtime; 15476 app.lastCpuTime = app.curCpuTime; 15477 } 15478 } 15479 } 15480 } 15481 15482 private final boolean applyOomAdjLocked(ProcessRecord app, boolean wasKeeping, 15483 ProcessRecord TOP_APP, boolean doingAll, long now) { 15484 boolean success = true; 15485 15486 if (app.curRawAdj != app.setRawAdj) { 15487 if (wasKeeping && !app.keeping) { 15488 // This app is no longer something we want to keep. Note 15489 // its current wake lock time to later know to kill it if 15490 // it is not behaving well. 15491 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 15492 synchronized (stats) { 15493 app.lastWakeTime = stats.getProcessWakeTime(app.info.uid, 15494 app.pid, SystemClock.elapsedRealtime()); 15495 } 15496 app.lastCpuTime = app.curCpuTime; 15497 } 15498 15499 app.setRawAdj = app.curRawAdj; 15500 } 15501 15502 int changes = 0; 15503 15504 if (app.curAdj != app.setAdj) { 15505 ProcessList.setOomAdj(app.pid, app.curAdj); 15506 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v( 15507 TAG, "Set " + app.pid + " " + app.processName + 15508 " adj " + app.curAdj + ": " + app.adjType); 15509 app.setAdj = app.curAdj; 15510 } 15511 15512 if (app.setSchedGroup != app.curSchedGroup) { 15513 app.setSchedGroup = app.curSchedGroup; 15514 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 15515 "Setting process group of " + app.processName 15516 + " to " + app.curSchedGroup); 15517 if (app.waitingToKill != null && 15518 app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 15519 killUnneededProcessLocked(app, app.waitingToKill); 15520 success = false; 15521 } else { 15522 if (true) { 15523 long oldId = Binder.clearCallingIdentity(); 15524 try { 15525 Process.setProcessGroup(app.pid, app.curSchedGroup); 15526 } catch (Exception e) { 15527 Slog.w(TAG, "Failed setting process group of " + app.pid 15528 + " to " + app.curSchedGroup); 15529 e.printStackTrace(); 15530 } finally { 15531 Binder.restoreCallingIdentity(oldId); 15532 } 15533 } else { 15534 if (app.thread != null) { 15535 try { 15536 app.thread.setSchedulingGroup(app.curSchedGroup); 15537 } catch (RemoteException e) { 15538 } 15539 } 15540 } 15541 Process.setSwappiness(app.pid, 15542 app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE); 15543 } 15544 } 15545 if (app.repForegroundActivities != app.foregroundActivities) { 15546 app.repForegroundActivities = app.foregroundActivities; 15547 changes |= ProcessChangeItem.CHANGE_ACTIVITIES; 15548 } 15549 if (app.repProcState != app.curProcState) { 15550 app.repProcState = app.curProcState; 15551 changes |= ProcessChangeItem.CHANGE_PROCESS_STATE; 15552 if (app.thread != null) { 15553 try { 15554 if (false) { 15555 //RuntimeException h = new RuntimeException("here"); 15556 Slog.i(TAG, "Sending new process state " + app.repProcState 15557 + " to " + app /*, h*/); 15558 } 15559 app.thread.setProcessState(app.repProcState); 15560 } catch (RemoteException e) { 15561 } 15562 } 15563 } 15564 if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState, 15565 app.setProcState)) { 15566 app.lastStateTime = now; 15567 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true, 15568 isSleeping(), now); 15569 if (DEBUG_PSS) Slog.d(TAG, "Process state change from " 15570 + ProcessList.makeProcStateString(app.setProcState) + " to " 15571 + ProcessList.makeProcStateString(app.curProcState) + " next pss in " 15572 + (app.nextPssTime-now) + ": " + app); 15573 } else { 15574 if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL) 15575 && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) { 15576 requestPssLocked(app, app.setProcState); 15577 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false, 15578 isSleeping(), now); 15579 } else if (false && DEBUG_PSS) { 15580 Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now)); 15581 } 15582 } 15583 if (app.setProcState != app.curProcState) { 15584 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 15585 "Proc state change of " + app.processName 15586 + " to " + app.curProcState); 15587 app.setProcState = app.curProcState; 15588 if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) { 15589 app.notCachedSinceIdle = false; 15590 } 15591 if (!doingAll) { 15592 setProcessTrackerState(app, mProcessStats.getMemFactorLocked(), now); 15593 } else { 15594 app.procStateChanged = true; 15595 } 15596 } 15597 15598 if (changes != 0) { 15599 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes); 15600 int i = mPendingProcessChanges.size()-1; 15601 ProcessChangeItem item = null; 15602 while (i >= 0) { 15603 item = mPendingProcessChanges.get(i); 15604 if (item.pid == app.pid) { 15605 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item); 15606 break; 15607 } 15608 i--; 15609 } 15610 if (i < 0) { 15611 // No existing item in pending changes; need a new one. 15612 final int NA = mAvailProcessChanges.size(); 15613 if (NA > 0) { 15614 item = mAvailProcessChanges.remove(NA-1); 15615 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item); 15616 } else { 15617 item = new ProcessChangeItem(); 15618 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item); 15619 } 15620 item.changes = 0; 15621 item.pid = app.pid; 15622 item.uid = app.info.uid; 15623 if (mPendingProcessChanges.size() == 0) { 15624 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, 15625 "*** Enqueueing dispatch processes changed!"); 15626 mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget(); 15627 } 15628 mPendingProcessChanges.add(item); 15629 } 15630 item.changes |= changes; 15631 item.processState = app.repProcState; 15632 item.foregroundActivities = app.repForegroundActivities; 15633 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item " 15634 + Integer.toHexString(System.identityHashCode(item)) 15635 + " " + app.toShortString() + ": changes=" + item.changes 15636 + " procState=" + item.processState 15637 + " foreground=" + item.foregroundActivities 15638 + " type=" + app.adjType + " source=" + app.adjSource 15639 + " target=" + app.adjTarget); 15640 } 15641 15642 return success; 15643 } 15644 15645 private final void setProcessTrackerState(ProcessRecord proc, int memFactor, long now) { 15646 if (proc.thread != null && proc.baseProcessTracker != null) { 15647 proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList); 15648 } 15649 } 15650 15651 private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj, 15652 ProcessRecord TOP_APP, boolean doingAll, long now) { 15653 if (app.thread == null) { 15654 return false; 15655 } 15656 15657 final boolean wasKeeping = app.keeping; 15658 15659 computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now); 15660 15661 return applyOomAdjLocked(app, wasKeeping, TOP_APP, doingAll, now); 15662 } 15663 15664 final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground, 15665 boolean oomAdj) { 15666 if (isForeground != proc.foregroundServices) { 15667 proc.foregroundServices = isForeground; 15668 ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName, 15669 proc.info.uid); 15670 if (isForeground) { 15671 if (curProcs == null) { 15672 curProcs = new ArrayList<ProcessRecord>(); 15673 mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs); 15674 } 15675 if (!curProcs.contains(proc)) { 15676 curProcs.add(proc); 15677 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START, 15678 proc.info.packageName, proc.info.uid); 15679 } 15680 } else { 15681 if (curProcs != null) { 15682 if (curProcs.remove(proc)) { 15683 mBatteryStatsService.noteEvent( 15684 BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH, 15685 proc.info.packageName, proc.info.uid); 15686 if (curProcs.size() <= 0) { 15687 mForegroundPackages.remove(proc.info.packageName, proc.info.uid); 15688 } 15689 } 15690 } 15691 } 15692 if (oomAdj) { 15693 updateOomAdjLocked(); 15694 } 15695 } 15696 } 15697 15698 private final ActivityRecord resumedAppLocked() { 15699 ActivityRecord act = mStackSupervisor.resumedAppLocked(); 15700 String pkg; 15701 int uid; 15702 if (act != null && !act.sleeping) { 15703 pkg = act.packageName; 15704 uid = act.info.applicationInfo.uid; 15705 } else { 15706 pkg = null; 15707 uid = -1; 15708 } 15709 // Has the UID or resumed package name changed? 15710 if (uid != mCurResumedUid || (pkg != mCurResumedPackage 15711 && (pkg == null || !pkg.equals(mCurResumedPackage)))) { 15712 if (mCurResumedPackage != null) { 15713 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH, 15714 mCurResumedPackage, mCurResumedUid); 15715 } 15716 mCurResumedPackage = pkg; 15717 mCurResumedUid = uid; 15718 if (mCurResumedPackage != null) { 15719 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START, 15720 mCurResumedPackage, mCurResumedUid); 15721 } 15722 } 15723 return act; 15724 } 15725 15726 final boolean updateOomAdjLocked(ProcessRecord app) { 15727 final ActivityRecord TOP_ACT = resumedAppLocked(); 15728 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 15729 final boolean wasCached = app.cached; 15730 15731 mAdjSeq++; 15732 15733 // This is the desired cached adjusment we want to tell it to use. 15734 // If our app is currently cached, we know it, and that is it. Otherwise, 15735 // we don't know it yet, and it needs to now be cached we will then 15736 // need to do a complete oom adj. 15737 final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ 15738 ? app.curRawAdj : ProcessList.UNKNOWN_ADJ; 15739 boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false, 15740 SystemClock.uptimeMillis()); 15741 if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) { 15742 // Changed to/from cached state, so apps after it in the LRU 15743 // list may also be changed. 15744 updateOomAdjLocked(); 15745 } 15746 return success; 15747 } 15748 15749 final void updateOomAdjLocked() { 15750 final ActivityRecord TOP_ACT = resumedAppLocked(); 15751 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 15752 final long now = SystemClock.uptimeMillis(); 15753 final long oldTime = now - ProcessList.MAX_EMPTY_TIME; 15754 final int N = mLruProcesses.size(); 15755 15756 if (false) { 15757 RuntimeException e = new RuntimeException(); 15758 e.fillInStackTrace(); 15759 Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e); 15760 } 15761 15762 mAdjSeq++; 15763 mNewNumServiceProcs = 0; 15764 mNewNumAServiceProcs = 0; 15765 15766 final int emptyProcessLimit; 15767 final int cachedProcessLimit; 15768 if (mProcessLimit <= 0) { 15769 emptyProcessLimit = cachedProcessLimit = 0; 15770 } else if (mProcessLimit == 1) { 15771 emptyProcessLimit = 1; 15772 cachedProcessLimit = 0; 15773 } else { 15774 emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit); 15775 cachedProcessLimit = mProcessLimit - emptyProcessLimit; 15776 } 15777 15778 // Let's determine how many processes we have running vs. 15779 // how many slots we have for background processes; we may want 15780 // to put multiple processes in a slot of there are enough of 15781 // them. 15782 int numSlots = (ProcessList.CACHED_APP_MAX_ADJ 15783 - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2; 15784 int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs; 15785 if (numEmptyProcs > cachedProcessLimit) { 15786 // If there are more empty processes than our limit on cached 15787 // processes, then use the cached process limit for the factor. 15788 // This ensures that the really old empty processes get pushed 15789 // down to the bottom, so if we are running low on memory we will 15790 // have a better chance at keeping around more cached processes 15791 // instead of a gazillion empty processes. 15792 numEmptyProcs = cachedProcessLimit; 15793 } 15794 int emptyFactor = numEmptyProcs/numSlots; 15795 if (emptyFactor < 1) emptyFactor = 1; 15796 int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots; 15797 if (cachedFactor < 1) cachedFactor = 1; 15798 int stepCached = 0; 15799 int stepEmpty = 0; 15800 int numCached = 0; 15801 int numEmpty = 0; 15802 int numTrimming = 0; 15803 15804 mNumNonCachedProcs = 0; 15805 mNumCachedHiddenProcs = 0; 15806 15807 // First update the OOM adjustment for each of the 15808 // application processes based on their current state. 15809 int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ; 15810 int nextCachedAdj = curCachedAdj+1; 15811 int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ; 15812 int nextEmptyAdj = curEmptyAdj+2; 15813 for (int i=N-1; i>=0; i--) { 15814 ProcessRecord app = mLruProcesses.get(i); 15815 if (!app.killedByAm && app.thread != null) { 15816 app.procStateChanged = false; 15817 final boolean wasKeeping = app.keeping; 15818 computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now); 15819 15820 // If we haven't yet assigned the final cached adj 15821 // to the process, do that now. 15822 if (app.curAdj >= ProcessList.UNKNOWN_ADJ) { 15823 switch (app.curProcState) { 15824 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY: 15825 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: 15826 // This process is a cached process holding activities... 15827 // assign it the next cached value for that type, and then 15828 // step that cached level. 15829 app.curRawAdj = curCachedAdj; 15830 app.curAdj = app.modifyRawOomAdj(curCachedAdj); 15831 if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i 15832 + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj 15833 + ")"); 15834 if (curCachedAdj != nextCachedAdj) { 15835 stepCached++; 15836 if (stepCached >= cachedFactor) { 15837 stepCached = 0; 15838 curCachedAdj = nextCachedAdj; 15839 nextCachedAdj += 2; 15840 if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) { 15841 nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ; 15842 } 15843 } 15844 } 15845 break; 15846 default: 15847 // For everything else, assign next empty cached process 15848 // level and bump that up. Note that this means that 15849 // long-running services that have dropped down to the 15850 // cached level will be treated as empty (since their process 15851 // state is still as a service), which is what we want. 15852 app.curRawAdj = curEmptyAdj; 15853 app.curAdj = app.modifyRawOomAdj(curEmptyAdj); 15854 if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i 15855 + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj 15856 + ")"); 15857 if (curEmptyAdj != nextEmptyAdj) { 15858 stepEmpty++; 15859 if (stepEmpty >= emptyFactor) { 15860 stepEmpty = 0; 15861 curEmptyAdj = nextEmptyAdj; 15862 nextEmptyAdj += 2; 15863 if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) { 15864 nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ; 15865 } 15866 } 15867 } 15868 break; 15869 } 15870 } 15871 15872 applyOomAdjLocked(app, wasKeeping, TOP_APP, true, now); 15873 15874 // Count the number of process types. 15875 switch (app.curProcState) { 15876 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY: 15877 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: 15878 mNumCachedHiddenProcs++; 15879 numCached++; 15880 if (numCached > cachedProcessLimit) { 15881 killUnneededProcessLocked(app, "cached #" + numCached); 15882 } 15883 break; 15884 case ActivityManager.PROCESS_STATE_CACHED_EMPTY: 15885 if (numEmpty > ProcessList.TRIM_EMPTY_APPS 15886 && app.lastActivityTime < oldTime) { 15887 killUnneededProcessLocked(app, "empty for " 15888 + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime) 15889 / 1000) + "s"); 15890 } else { 15891 numEmpty++; 15892 if (numEmpty > emptyProcessLimit) { 15893 killUnneededProcessLocked(app, "empty #" + numEmpty); 15894 } 15895 } 15896 break; 15897 default: 15898 mNumNonCachedProcs++; 15899 break; 15900 } 15901 15902 if (app.isolated && app.services.size() <= 0) { 15903 // If this is an isolated process, and there are no 15904 // services running in it, then the process is no longer 15905 // needed. We agressively kill these because we can by 15906 // definition not re-use the same process again, and it is 15907 // good to avoid having whatever code was running in them 15908 // left sitting around after no longer needed. 15909 killUnneededProcessLocked(app, "isolated not needed"); 15910 } 15911 15912 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME 15913 && !app.killedByAm) { 15914 numTrimming++; 15915 } 15916 } 15917 } 15918 15919 mNumServiceProcs = mNewNumServiceProcs; 15920 15921 // Now determine the memory trimming level of background processes. 15922 // Unfortunately we need to start at the back of the list to do this 15923 // properly. We only do this if the number of background apps we 15924 // are managing to keep around is less than half the maximum we desire; 15925 // if we are keeping a good number around, we'll let them use whatever 15926 // memory they want. 15927 final int numCachedAndEmpty = numCached + numEmpty; 15928 int memFactor; 15929 if (numCached <= ProcessList.TRIM_CACHED_APPS 15930 && numEmpty <= ProcessList.TRIM_EMPTY_APPS) { 15931 if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) { 15932 memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL; 15933 } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) { 15934 memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW; 15935 } else { 15936 memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE; 15937 } 15938 } else { 15939 memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL; 15940 } 15941 // We always allow the memory level to go up (better). We only allow it to go 15942 // down if we are in a state where that is allowed, *and* the total number of processes 15943 // has gone down since last time. 15944 if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel 15945 + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size() 15946 + " last=" + mLastNumProcesses); 15947 if (memFactor > mLastMemoryLevel) { 15948 if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) { 15949 memFactor = mLastMemoryLevel; 15950 if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!"); 15951 } 15952 } 15953 mLastMemoryLevel = memFactor; 15954 mLastNumProcesses = mLruProcesses.size(); 15955 boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now); 15956 final int trackerMemFactor = mProcessStats.getMemFactorLocked(); 15957 if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) { 15958 if (mLowRamStartTime == 0) { 15959 mLowRamStartTime = now; 15960 } 15961 int step = 0; 15962 int fgTrimLevel; 15963 switch (memFactor) { 15964 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL: 15965 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL; 15966 break; 15967 case ProcessStats.ADJ_MEM_FACTOR_LOW: 15968 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW; 15969 break; 15970 default: 15971 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE; 15972 break; 15973 } 15974 int factor = numTrimming/3; 15975 int minFactor = 2; 15976 if (mHomeProcess != null) minFactor++; 15977 if (mPreviousProcess != null) minFactor++; 15978 if (factor < minFactor) factor = minFactor; 15979 int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE; 15980 for (int i=N-1; i>=0; i--) { 15981 ProcessRecord app = mLruProcesses.get(i); 15982 if (allChanged || app.procStateChanged) { 15983 setProcessTrackerState(app, trackerMemFactor, now); 15984 app.procStateChanged = false; 15985 } 15986 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME 15987 && !app.killedByAm) { 15988 if (app.trimMemoryLevel < curLevel && app.thread != null) { 15989 try { 15990 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 15991 "Trimming memory of " + app.processName 15992 + " to " + curLevel); 15993 app.thread.scheduleTrimMemory(curLevel); 15994 } catch (RemoteException e) { 15995 } 15996 if (false) { 15997 // For now we won't do this; our memory trimming seems 15998 // to be good enough at this point that destroying 15999 // activities causes more harm than good. 16000 if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE 16001 && app != mHomeProcess && app != mPreviousProcess) { 16002 // Need to do this on its own message because the stack may not 16003 // be in a consistent state at this point. 16004 // For these apps we will also finish their activities 16005 // to help them free memory. 16006 mStackSupervisor.scheduleDestroyAllActivities(app, "trim"); 16007 } 16008 } 16009 } 16010 app.trimMemoryLevel = curLevel; 16011 step++; 16012 if (step >= factor) { 16013 step = 0; 16014 switch (curLevel) { 16015 case ComponentCallbacks2.TRIM_MEMORY_COMPLETE: 16016 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE; 16017 break; 16018 case ComponentCallbacks2.TRIM_MEMORY_MODERATE: 16019 curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 16020 break; 16021 } 16022 } 16023 } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) { 16024 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND 16025 && app.thread != null) { 16026 try { 16027 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 16028 "Trimming memory of heavy-weight " + app.processName 16029 + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 16030 app.thread.scheduleTrimMemory( 16031 ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 16032 } catch (RemoteException e) { 16033 } 16034 } 16035 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 16036 } else { 16037 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 16038 || app.systemNoUi) && app.pendingUiClean) { 16039 // If this application is now in the background and it 16040 // had done UI, then give it the special trim level to 16041 // have it free UI resources. 16042 final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN; 16043 if (app.trimMemoryLevel < level && app.thread != null) { 16044 try { 16045 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 16046 "Trimming memory of bg-ui " + app.processName 16047 + " to " + level); 16048 app.thread.scheduleTrimMemory(level); 16049 } catch (RemoteException e) { 16050 } 16051 } 16052 app.pendingUiClean = false; 16053 } 16054 if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) { 16055 try { 16056 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 16057 "Trimming memory of fg " + app.processName 16058 + " to " + fgTrimLevel); 16059 app.thread.scheduleTrimMemory(fgTrimLevel); 16060 } catch (RemoteException e) { 16061 } 16062 } 16063 app.trimMemoryLevel = fgTrimLevel; 16064 } 16065 } 16066 } else { 16067 if (mLowRamStartTime != 0) { 16068 mLowRamTimeSinceLastIdle += now - mLowRamStartTime; 16069 mLowRamStartTime = 0; 16070 } 16071 for (int i=N-1; i>=0; i--) { 16072 ProcessRecord app = mLruProcesses.get(i); 16073 if (allChanged || app.procStateChanged) { 16074 setProcessTrackerState(app, trackerMemFactor, now); 16075 app.procStateChanged = false; 16076 } 16077 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 16078 || app.systemNoUi) && app.pendingUiClean) { 16079 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN 16080 && app.thread != null) { 16081 try { 16082 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 16083 "Trimming memory of ui hidden " + app.processName 16084 + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 16085 app.thread.scheduleTrimMemory( 16086 ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 16087 } catch (RemoteException e) { 16088 } 16089 } 16090 app.pendingUiClean = false; 16091 } 16092 app.trimMemoryLevel = 0; 16093 } 16094 } 16095 16096 if (mAlwaysFinishActivities) { 16097 // Need to do this on its own message because the stack may not 16098 // be in a consistent state at this point. 16099 mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish"); 16100 } 16101 16102 if (allChanged) { 16103 requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered()); 16104 } 16105 16106 if (mProcessStats.shouldWriteNowLocked(now)) { 16107 mHandler.post(new Runnable() { 16108 @Override public void run() { 16109 synchronized (ActivityManagerService.this) { 16110 mProcessStats.writeStateAsyncLocked(); 16111 } 16112 } 16113 }); 16114 } 16115 16116 if (DEBUG_OOM_ADJ) { 16117 Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms"); 16118 } 16119 } 16120 16121 final void trimApplications() { 16122 synchronized (this) { 16123 int i; 16124 16125 // First remove any unused application processes whose package 16126 // has been removed. 16127 for (i=mRemovedProcesses.size()-1; i>=0; i--) { 16128 final ProcessRecord app = mRemovedProcesses.get(i); 16129 if (app.activities.size() == 0 16130 && app.curReceiver == null && app.services.size() == 0) { 16131 Slog.i( 16132 TAG, "Exiting empty application process " 16133 + app.processName + " (" 16134 + (app.thread != null ? app.thread.asBinder() : null) 16135 + ")\n"); 16136 if (app.pid > 0 && app.pid != MY_PID) { 16137 EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid, 16138 app.processName, app.setAdj, "empty"); 16139 app.killedByAm = true; 16140 Process.killProcessQuiet(app.pid); 16141 } else { 16142 try { 16143 app.thread.scheduleExit(); 16144 } catch (Exception e) { 16145 // Ignore exceptions. 16146 } 16147 } 16148 cleanUpApplicationRecordLocked(app, false, true, -1); 16149 mRemovedProcesses.remove(i); 16150 16151 if (app.persistent) { 16152 if (app.persistent) { 16153 addAppLocked(app.info, false); 16154 } 16155 } 16156 } 16157 } 16158 16159 // Now update the oom adj for all processes. 16160 updateOomAdjLocked(); 16161 } 16162 } 16163 16164 /** This method sends the specified signal to each of the persistent apps */ 16165 public void signalPersistentProcesses(int sig) throws RemoteException { 16166 if (sig != Process.SIGNAL_USR1) { 16167 throw new SecurityException("Only SIGNAL_USR1 is allowed"); 16168 } 16169 16170 synchronized (this) { 16171 if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES) 16172 != PackageManager.PERMISSION_GRANTED) { 16173 throw new SecurityException("Requires permission " 16174 + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES); 16175 } 16176 16177 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 16178 ProcessRecord r = mLruProcesses.get(i); 16179 if (r.thread != null && r.persistent) { 16180 Process.sendSignal(r.pid, sig); 16181 } 16182 } 16183 } 16184 } 16185 16186 private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) { 16187 if (proc == null || proc == mProfileProc) { 16188 proc = mProfileProc; 16189 path = mProfileFile; 16190 profileType = mProfileType; 16191 clearProfilerLocked(); 16192 } 16193 if (proc == null) { 16194 return; 16195 } 16196 try { 16197 proc.thread.profilerControl(false, path, null, profileType); 16198 } catch (RemoteException e) { 16199 throw new IllegalStateException("Process disappeared"); 16200 } 16201 } 16202 16203 private void clearProfilerLocked() { 16204 if (mProfileFd != null) { 16205 try { 16206 mProfileFd.close(); 16207 } catch (IOException e) { 16208 } 16209 } 16210 mProfileApp = null; 16211 mProfileProc = null; 16212 mProfileFile = null; 16213 mProfileType = 0; 16214 mAutoStopProfiler = false; 16215 } 16216 16217 public boolean profileControl(String process, int userId, boolean start, 16218 String path, ParcelFileDescriptor fd, int profileType) throws RemoteException { 16219 16220 try { 16221 synchronized (this) { 16222 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 16223 // its own permission. 16224 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 16225 != PackageManager.PERMISSION_GRANTED) { 16226 throw new SecurityException("Requires permission " 16227 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 16228 } 16229 16230 if (start && fd == null) { 16231 throw new IllegalArgumentException("null fd"); 16232 } 16233 16234 ProcessRecord proc = null; 16235 if (process != null) { 16236 proc = findProcessLocked(process, userId, "profileControl"); 16237 } 16238 16239 if (start && (proc == null || proc.thread == null)) { 16240 throw new IllegalArgumentException("Unknown process: " + process); 16241 } 16242 16243 if (start) { 16244 stopProfilerLocked(null, null, 0); 16245 setProfileApp(proc.info, proc.processName, path, fd, false); 16246 mProfileProc = proc; 16247 mProfileType = profileType; 16248 try { 16249 fd = fd.dup(); 16250 } catch (IOException e) { 16251 fd = null; 16252 } 16253 proc.thread.profilerControl(start, path, fd, profileType); 16254 fd = null; 16255 mProfileFd = null; 16256 } else { 16257 stopProfilerLocked(proc, path, profileType); 16258 if (fd != null) { 16259 try { 16260 fd.close(); 16261 } catch (IOException e) { 16262 } 16263 } 16264 } 16265 16266 return true; 16267 } 16268 } catch (RemoteException e) { 16269 throw new IllegalStateException("Process disappeared"); 16270 } finally { 16271 if (fd != null) { 16272 try { 16273 fd.close(); 16274 } catch (IOException e) { 16275 } 16276 } 16277 } 16278 } 16279 16280 private ProcessRecord findProcessLocked(String process, int userId, String callName) { 16281 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 16282 userId, true, true, callName, null); 16283 ProcessRecord proc = null; 16284 try { 16285 int pid = Integer.parseInt(process); 16286 synchronized (mPidsSelfLocked) { 16287 proc = mPidsSelfLocked.get(pid); 16288 } 16289 } catch (NumberFormatException e) { 16290 } 16291 16292 if (proc == null) { 16293 ArrayMap<String, SparseArray<ProcessRecord>> all 16294 = mProcessNames.getMap(); 16295 SparseArray<ProcessRecord> procs = all.get(process); 16296 if (procs != null && procs.size() > 0) { 16297 proc = procs.valueAt(0); 16298 if (userId != UserHandle.USER_ALL && proc.userId != userId) { 16299 for (int i=1; i<procs.size(); i++) { 16300 ProcessRecord thisProc = procs.valueAt(i); 16301 if (thisProc.userId == userId) { 16302 proc = thisProc; 16303 break; 16304 } 16305 } 16306 } 16307 } 16308 } 16309 16310 return proc; 16311 } 16312 16313 public boolean dumpHeap(String process, int userId, boolean managed, 16314 String path, ParcelFileDescriptor fd) throws RemoteException { 16315 16316 try { 16317 synchronized (this) { 16318 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 16319 // its own permission (same as profileControl). 16320 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 16321 != PackageManager.PERMISSION_GRANTED) { 16322 throw new SecurityException("Requires permission " 16323 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 16324 } 16325 16326 if (fd == null) { 16327 throw new IllegalArgumentException("null fd"); 16328 } 16329 16330 ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap"); 16331 if (proc == null || proc.thread == null) { 16332 throw new IllegalArgumentException("Unknown process: " + process); 16333 } 16334 16335 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 16336 if (!isDebuggable) { 16337 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 16338 throw new SecurityException("Process not debuggable: " + proc); 16339 } 16340 } 16341 16342 proc.thread.dumpHeap(managed, path, fd); 16343 fd = null; 16344 return true; 16345 } 16346 } catch (RemoteException e) { 16347 throw new IllegalStateException("Process disappeared"); 16348 } finally { 16349 if (fd != null) { 16350 try { 16351 fd.close(); 16352 } catch (IOException e) { 16353 } 16354 } 16355 } 16356 } 16357 16358 /** In this method we try to acquire our lock to make sure that we have not deadlocked */ 16359 public void monitor() { 16360 synchronized (this) { } 16361 } 16362 16363 void onCoreSettingsChange(Bundle settings) { 16364 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 16365 ProcessRecord processRecord = mLruProcesses.get(i); 16366 try { 16367 if (processRecord.thread != null) { 16368 processRecord.thread.setCoreSettings(settings); 16369 } 16370 } catch (RemoteException re) { 16371 /* ignore */ 16372 } 16373 } 16374 } 16375 16376 // Multi-user methods 16377 16378 /** 16379 * Start user, if its not already running, but don't bring it to foreground. 16380 */ 16381 @Override 16382 public boolean startUserInBackground(final int userId) { 16383 return startUser(userId, /* foreground */ false); 16384 } 16385 16386 /** 16387 * Refreshes the list of users related to the current user when either a 16388 * user switch happens or when a new related user is started in the 16389 * background. 16390 */ 16391 private void updateCurrentProfileIdsLocked() { 16392 final List<UserInfo> profiles = getUserManagerLocked().getProfiles( 16393 mCurrentUserId, false /* enabledOnly */); 16394 int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null 16395 for (int i = 0; i < currentProfileIds.length; i++) { 16396 currentProfileIds[i] = profiles.get(i).id; 16397 } 16398 mCurrentProfileIds = currentProfileIds; 16399 } 16400 16401 private Set getProfileIdsLocked(int userId) { 16402 Set userIds = new HashSet<Integer>(); 16403 final List<UserInfo> profiles = getUserManagerLocked().getProfiles( 16404 userId, false /* enabledOnly */); 16405 for (UserInfo user : profiles) { 16406 userIds.add(Integer.valueOf(user.id)); 16407 } 16408 return userIds; 16409 } 16410 16411 @Override 16412 public boolean switchUser(final int userId) { 16413 return startUser(userId, /* foregound */ true); 16414 } 16415 16416 private boolean startUser(final int userId, boolean foreground) { 16417 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 16418 != PackageManager.PERMISSION_GRANTED) { 16419 String msg = "Permission Denial: switchUser() from pid=" 16420 + Binder.getCallingPid() 16421 + ", uid=" + Binder.getCallingUid() 16422 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 16423 Slog.w(TAG, msg); 16424 throw new SecurityException(msg); 16425 } 16426 16427 if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground); 16428 16429 final long ident = Binder.clearCallingIdentity(); 16430 try { 16431 synchronized (this) { 16432 final int oldUserId = mCurrentUserId; 16433 if (oldUserId == userId) { 16434 return true; 16435 } 16436 16437 mStackSupervisor.setLockTaskModeLocked(null); 16438 16439 final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId); 16440 if (userInfo == null) { 16441 Slog.w(TAG, "No user info for user #" + userId); 16442 return false; 16443 } 16444 16445 if (foreground) { 16446 mWindowManager.startFreezingScreen(R.anim.screen_user_exit, 16447 R.anim.screen_user_enter); 16448 } 16449 16450 boolean needStart = false; 16451 16452 // If the user we are switching to is not currently started, then 16453 // we need to start it now. 16454 if (mStartedUsers.get(userId) == null) { 16455 mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false)); 16456 updateStartedUserArrayLocked(); 16457 needStart = true; 16458 } 16459 16460 final Integer userIdInt = Integer.valueOf(userId); 16461 mUserLru.remove(userIdInt); 16462 mUserLru.add(userIdInt); 16463 16464 if (foreground) { 16465 mCurrentUserId = userId; 16466 updateCurrentProfileIdsLocked(); 16467 mWindowManager.setCurrentUser(userId, mCurrentProfileIds); 16468 // Once the internal notion of the active user has switched, we lock the device 16469 // with the option to show the user switcher on the keyguard. 16470 mWindowManager.lockNow(null); 16471 } else { 16472 final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId); 16473 updateCurrentProfileIdsLocked(); 16474 mWindowManager.setCurrentProfileIds(mCurrentProfileIds); 16475 mUserLru.remove(currentUserIdInt); 16476 mUserLru.add(currentUserIdInt); 16477 } 16478 16479 final UserStartedState uss = mStartedUsers.get(userId); 16480 16481 // Make sure user is in the started state. If it is currently 16482 // stopping, we need to knock that off. 16483 if (uss.mState == UserStartedState.STATE_STOPPING) { 16484 // If we are stopping, we haven't sent ACTION_SHUTDOWN, 16485 // so we can just fairly silently bring the user back from 16486 // the almost-dead. 16487 uss.mState = UserStartedState.STATE_RUNNING; 16488 updateStartedUserArrayLocked(); 16489 needStart = true; 16490 } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) { 16491 // This means ACTION_SHUTDOWN has been sent, so we will 16492 // need to treat this as a new boot of the user. 16493 uss.mState = UserStartedState.STATE_BOOTING; 16494 updateStartedUserArrayLocked(); 16495 needStart = true; 16496 } 16497 16498 if (uss.mState == UserStartedState.STATE_BOOTING) { 16499 // Booting up a new user, need to tell system services about it. 16500 // Note that this is on the same handler as scheduling of broadcasts, 16501 // which is important because it needs to go first. 16502 mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId)); 16503 } 16504 16505 if (foreground) { 16506 mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId)); 16507 mHandler.removeMessages(REPORT_USER_SWITCH_MSG); 16508 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 16509 mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG, 16510 oldUserId, userId, uss)); 16511 mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG, 16512 oldUserId, userId, uss), USER_SWITCH_TIMEOUT); 16513 } 16514 16515 if (needStart) { 16516 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 16517 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16518 | Intent.FLAG_RECEIVER_FOREGROUND); 16519 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 16520 broadcastIntentLocked(null, null, intent, 16521 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 16522 false, false, MY_PID, Process.SYSTEM_UID, userId); 16523 } 16524 16525 if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) { 16526 if (userId != 0) { 16527 Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE); 16528 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 16529 broadcastIntentLocked(null, null, intent, null, 16530 new IIntentReceiver.Stub() { 16531 public void performReceive(Intent intent, int resultCode, 16532 String data, Bundle extras, boolean ordered, 16533 boolean sticky, int sendingUser) { 16534 userInitialized(uss, userId); 16535 } 16536 }, 0, null, null, null, AppOpsManager.OP_NONE, 16537 true, false, MY_PID, Process.SYSTEM_UID, 16538 userId); 16539 uss.initializing = true; 16540 } else { 16541 getUserManagerLocked().makeInitialized(userInfo.id); 16542 } 16543 } 16544 16545 if (foreground) { 16546 boolean homeInFront = mStackSupervisor.switchUserLocked(userId, uss); 16547 if (homeInFront) { 16548 startHomeActivityLocked(userId); 16549 } else { 16550 mStackSupervisor.resumeTopActivitiesLocked(); 16551 } 16552 EventLogTags.writeAmSwitchUser(userId); 16553 getUserManagerLocked().userForeground(userId); 16554 sendUserSwitchBroadcastsLocked(oldUserId, userId); 16555 } 16556 16557 if (needStart) { 16558 Intent intent = new Intent(Intent.ACTION_USER_STARTING); 16559 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 16560 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 16561 broadcastIntentLocked(null, null, intent, 16562 null, new IIntentReceiver.Stub() { 16563 @Override 16564 public void performReceive(Intent intent, int resultCode, String data, 16565 Bundle extras, boolean ordered, boolean sticky, int sendingUser) 16566 throws RemoteException { 16567 } 16568 }, 0, null, null, 16569 android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 16570 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 16571 } 16572 } 16573 } finally { 16574 Binder.restoreCallingIdentity(ident); 16575 } 16576 16577 return true; 16578 } 16579 16580 void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) { 16581 long ident = Binder.clearCallingIdentity(); 16582 try { 16583 Intent intent; 16584 if (oldUserId >= 0) { 16585 intent = new Intent(Intent.ACTION_USER_BACKGROUND); 16586 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16587 | Intent.FLAG_RECEIVER_FOREGROUND); 16588 intent.putExtra(Intent.EXTRA_USER_HANDLE, oldUserId); 16589 broadcastIntentLocked(null, null, intent, 16590 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 16591 false, false, MY_PID, Process.SYSTEM_UID, oldUserId); 16592 } 16593 if (newUserId >= 0) { 16594 intent = new Intent(Intent.ACTION_USER_FOREGROUND); 16595 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16596 | Intent.FLAG_RECEIVER_FOREGROUND); 16597 intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId); 16598 broadcastIntentLocked(null, null, intent, 16599 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 16600 false, false, MY_PID, Process.SYSTEM_UID, newUserId); 16601 intent = new Intent(Intent.ACTION_USER_SWITCHED); 16602 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16603 | Intent.FLAG_RECEIVER_FOREGROUND); 16604 intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId); 16605 broadcastIntentLocked(null, null, intent, 16606 null, null, 0, null, null, 16607 android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE, 16608 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 16609 } 16610 } finally { 16611 Binder.restoreCallingIdentity(ident); 16612 } 16613 } 16614 16615 void dispatchUserSwitch(final UserStartedState uss, final int oldUserId, 16616 final int newUserId) { 16617 final int N = mUserSwitchObservers.beginBroadcast(); 16618 if (N > 0) { 16619 final IRemoteCallback callback = new IRemoteCallback.Stub() { 16620 int mCount = 0; 16621 @Override 16622 public void sendResult(Bundle data) throws RemoteException { 16623 synchronized (ActivityManagerService.this) { 16624 if (mCurUserSwitchCallback == this) { 16625 mCount++; 16626 if (mCount == N) { 16627 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 16628 } 16629 } 16630 } 16631 } 16632 }; 16633 synchronized (this) { 16634 uss.switching = true; 16635 mCurUserSwitchCallback = callback; 16636 } 16637 for (int i=0; i<N; i++) { 16638 try { 16639 mUserSwitchObservers.getBroadcastItem(i).onUserSwitching( 16640 newUserId, callback); 16641 } catch (RemoteException e) { 16642 } 16643 } 16644 } else { 16645 synchronized (this) { 16646 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 16647 } 16648 } 16649 mUserSwitchObservers.finishBroadcast(); 16650 } 16651 16652 void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 16653 synchronized (this) { 16654 Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId); 16655 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 16656 } 16657 } 16658 16659 void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) { 16660 mCurUserSwitchCallback = null; 16661 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 16662 mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG, 16663 oldUserId, newUserId, uss)); 16664 } 16665 16666 void userInitialized(UserStartedState uss, int newUserId) { 16667 completeSwitchAndInitalize(uss, newUserId, true, false); 16668 } 16669 16670 void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 16671 completeSwitchAndInitalize(uss, newUserId, false, true); 16672 } 16673 16674 void completeSwitchAndInitalize(UserStartedState uss, int newUserId, 16675 boolean clearInitializing, boolean clearSwitching) { 16676 boolean unfrozen = false; 16677 synchronized (this) { 16678 if (clearInitializing) { 16679 uss.initializing = false; 16680 getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier()); 16681 } 16682 if (clearSwitching) { 16683 uss.switching = false; 16684 } 16685 if (!uss.switching && !uss.initializing) { 16686 mWindowManager.stopFreezingScreen(); 16687 unfrozen = true; 16688 } 16689 } 16690 if (unfrozen) { 16691 final int N = mUserSwitchObservers.beginBroadcast(); 16692 for (int i=0; i<N; i++) { 16693 try { 16694 mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId); 16695 } catch (RemoteException e) { 16696 } 16697 } 16698 mUserSwitchObservers.finishBroadcast(); 16699 } 16700 } 16701 16702 void scheduleStartProfilesLocked() { 16703 if (!mHandler.hasMessages(START_PROFILES_MSG)) { 16704 mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG), 16705 DateUtils.SECOND_IN_MILLIS); 16706 } 16707 } 16708 16709 void startProfilesLocked() { 16710 if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked"); 16711 List<UserInfo> profiles = getUserManagerLocked().getProfiles( 16712 mCurrentUserId, false /* enabledOnly */); 16713 List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size()); 16714 for (UserInfo user : profiles) { 16715 if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED 16716 && user.id != mCurrentUserId) { 16717 toStart.add(user); 16718 } 16719 } 16720 final int n = toStart.size(); 16721 int i = 0; 16722 for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) { 16723 startUserInBackground(toStart.get(i).id); 16724 } 16725 if (i < n) { 16726 Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS"); 16727 } 16728 } 16729 16730 void finishUserSwitch(UserStartedState uss) { 16731 synchronized (this) { 16732 if (uss.mState == UserStartedState.STATE_BOOTING 16733 && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) { 16734 uss.mState = UserStartedState.STATE_RUNNING; 16735 final int userId = uss.mHandle.getIdentifier(); 16736 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 16737 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 16738 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT); 16739 broadcastIntentLocked(null, null, intent, 16740 null, null, 0, null, null, 16741 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE, 16742 true, false, MY_PID, Process.SYSTEM_UID, userId); 16743 } 16744 16745 startProfilesLocked(); 16746 16747 int num = mUserLru.size(); 16748 int i = 0; 16749 while (num > MAX_RUNNING_USERS && i < mUserLru.size()) { 16750 Integer oldUserId = mUserLru.get(i); 16751 UserStartedState oldUss = mStartedUsers.get(oldUserId); 16752 if (oldUss == null) { 16753 // Shouldn't happen, but be sane if it does. 16754 mUserLru.remove(i); 16755 num--; 16756 continue; 16757 } 16758 if (oldUss.mState == UserStartedState.STATE_STOPPING 16759 || oldUss.mState == UserStartedState.STATE_SHUTDOWN) { 16760 // This user is already stopping, doesn't count. 16761 num--; 16762 i++; 16763 continue; 16764 } 16765 if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) { 16766 // Owner and current can't be stopped, but count as running. 16767 i++; 16768 continue; 16769 } 16770 // This is a user to be stopped. 16771 stopUserLocked(oldUserId, null); 16772 num--; 16773 i++; 16774 } 16775 } 16776 } 16777 16778 @Override 16779 public int stopUser(final int userId, final IStopUserCallback callback) { 16780 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 16781 != PackageManager.PERMISSION_GRANTED) { 16782 String msg = "Permission Denial: switchUser() from pid=" 16783 + Binder.getCallingPid() 16784 + ", uid=" + Binder.getCallingUid() 16785 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 16786 Slog.w(TAG, msg); 16787 throw new SecurityException(msg); 16788 } 16789 if (userId <= 0) { 16790 throw new IllegalArgumentException("Can't stop primary user " + userId); 16791 } 16792 synchronized (this) { 16793 return stopUserLocked(userId, callback); 16794 } 16795 } 16796 16797 private int stopUserLocked(final int userId, final IStopUserCallback callback) { 16798 if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId); 16799 if (mCurrentUserId == userId) { 16800 return ActivityManager.USER_OP_IS_CURRENT; 16801 } 16802 16803 final UserStartedState uss = mStartedUsers.get(userId); 16804 if (uss == null) { 16805 // User is not started, nothing to do... but we do need to 16806 // callback if requested. 16807 if (callback != null) { 16808 mHandler.post(new Runnable() { 16809 @Override 16810 public void run() { 16811 try { 16812 callback.userStopped(userId); 16813 } catch (RemoteException e) { 16814 } 16815 } 16816 }); 16817 } 16818 return ActivityManager.USER_OP_SUCCESS; 16819 } 16820 16821 if (callback != null) { 16822 uss.mStopCallbacks.add(callback); 16823 } 16824 16825 if (uss.mState != UserStartedState.STATE_STOPPING 16826 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 16827 uss.mState = UserStartedState.STATE_STOPPING; 16828 updateStartedUserArrayLocked(); 16829 16830 long ident = Binder.clearCallingIdentity(); 16831 try { 16832 // We are going to broadcast ACTION_USER_STOPPING and then 16833 // once that is done send a final ACTION_SHUTDOWN and then 16834 // stop the user. 16835 final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING); 16836 stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 16837 stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 16838 stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true); 16839 final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN); 16840 // This is the result receiver for the final shutdown broadcast. 16841 final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() { 16842 @Override 16843 public void performReceive(Intent intent, int resultCode, String data, 16844 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 16845 finishUserStop(uss); 16846 } 16847 }; 16848 // This is the result receiver for the initial stopping broadcast. 16849 final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() { 16850 @Override 16851 public void performReceive(Intent intent, int resultCode, String data, 16852 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 16853 // On to the next. 16854 synchronized (ActivityManagerService.this) { 16855 if (uss.mState != UserStartedState.STATE_STOPPING) { 16856 // Whoops, we are being started back up. Abort, abort! 16857 return; 16858 } 16859 uss.mState = UserStartedState.STATE_SHUTDOWN; 16860 } 16861 mSystemServiceManager.stopUser(userId); 16862 broadcastIntentLocked(null, null, shutdownIntent, 16863 null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE, 16864 true, false, MY_PID, Process.SYSTEM_UID, userId); 16865 } 16866 }; 16867 // Kick things off. 16868 broadcastIntentLocked(null, null, stoppingIntent, 16869 null, stoppingReceiver, 0, null, null, 16870 android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 16871 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 16872 } finally { 16873 Binder.restoreCallingIdentity(ident); 16874 } 16875 } 16876 16877 return ActivityManager.USER_OP_SUCCESS; 16878 } 16879 16880 void finishUserStop(UserStartedState uss) { 16881 final int userId = uss.mHandle.getIdentifier(); 16882 boolean stopped; 16883 ArrayList<IStopUserCallback> callbacks; 16884 synchronized (this) { 16885 callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks); 16886 if (mStartedUsers.get(userId) != uss) { 16887 stopped = false; 16888 } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) { 16889 stopped = false; 16890 } else { 16891 stopped = true; 16892 // User can no longer run. 16893 mStartedUsers.remove(userId); 16894 mUserLru.remove(Integer.valueOf(userId)); 16895 updateStartedUserArrayLocked(); 16896 16897 // Clean up all state and processes associated with the user. 16898 // Kill all the processes for the user. 16899 forceStopUserLocked(userId, "finish user"); 16900 } 16901 } 16902 16903 for (int i=0; i<callbacks.size(); i++) { 16904 try { 16905 if (stopped) callbacks.get(i).userStopped(userId); 16906 else callbacks.get(i).userStopAborted(userId); 16907 } catch (RemoteException e) { 16908 } 16909 } 16910 16911 if (stopped) { 16912 mSystemServiceManager.cleanupUser(userId); 16913 synchronized (this) { 16914 mStackSupervisor.removeUserLocked(userId); 16915 } 16916 } 16917 } 16918 16919 @Override 16920 public UserInfo getCurrentUser() { 16921 if ((checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) 16922 != PackageManager.PERMISSION_GRANTED) && ( 16923 checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 16924 != PackageManager.PERMISSION_GRANTED)) { 16925 String msg = "Permission Denial: getCurrentUser() from pid=" 16926 + Binder.getCallingPid() 16927 + ", uid=" + Binder.getCallingUid() 16928 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS; 16929 Slog.w(TAG, msg); 16930 throw new SecurityException(msg); 16931 } 16932 synchronized (this) { 16933 return getUserManagerLocked().getUserInfo(mCurrentUserId); 16934 } 16935 } 16936 16937 int getCurrentUserIdLocked() { 16938 return mCurrentUserId; 16939 } 16940 16941 @Override 16942 public boolean isUserRunning(int userId, boolean orStopped) { 16943 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) 16944 != PackageManager.PERMISSION_GRANTED) { 16945 String msg = "Permission Denial: isUserRunning() from pid=" 16946 + Binder.getCallingPid() 16947 + ", uid=" + Binder.getCallingUid() 16948 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS; 16949 Slog.w(TAG, msg); 16950 throw new SecurityException(msg); 16951 } 16952 synchronized (this) { 16953 return isUserRunningLocked(userId, orStopped); 16954 } 16955 } 16956 16957 boolean isUserRunningLocked(int userId, boolean orStopped) { 16958 UserStartedState state = mStartedUsers.get(userId); 16959 if (state == null) { 16960 return false; 16961 } 16962 if (orStopped) { 16963 return true; 16964 } 16965 return state.mState != UserStartedState.STATE_STOPPING 16966 && state.mState != UserStartedState.STATE_SHUTDOWN; 16967 } 16968 16969 @Override 16970 public int[] getRunningUserIds() { 16971 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) 16972 != PackageManager.PERMISSION_GRANTED) { 16973 String msg = "Permission Denial: isUserRunning() from pid=" 16974 + Binder.getCallingPid() 16975 + ", uid=" + Binder.getCallingUid() 16976 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS; 16977 Slog.w(TAG, msg); 16978 throw new SecurityException(msg); 16979 } 16980 synchronized (this) { 16981 return mStartedUserArray; 16982 } 16983 } 16984 16985 private void updateStartedUserArrayLocked() { 16986 int num = 0; 16987 for (int i=0; i<mStartedUsers.size(); i++) { 16988 UserStartedState uss = mStartedUsers.valueAt(i); 16989 // This list does not include stopping users. 16990 if (uss.mState != UserStartedState.STATE_STOPPING 16991 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 16992 num++; 16993 } 16994 } 16995 mStartedUserArray = new int[num]; 16996 num = 0; 16997 for (int i=0; i<mStartedUsers.size(); i++) { 16998 UserStartedState uss = mStartedUsers.valueAt(i); 16999 if (uss.mState != UserStartedState.STATE_STOPPING 17000 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 17001 mStartedUserArray[num] = mStartedUsers.keyAt(i); 17002 num++; 17003 } 17004 } 17005 } 17006 17007 @Override 17008 public void registerUserSwitchObserver(IUserSwitchObserver observer) { 17009 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 17010 != PackageManager.PERMISSION_GRANTED) { 17011 String msg = "Permission Denial: registerUserSwitchObserver() from pid=" 17012 + Binder.getCallingPid() 17013 + ", uid=" + Binder.getCallingUid() 17014 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 17015 Slog.w(TAG, msg); 17016 throw new SecurityException(msg); 17017 } 17018 17019 mUserSwitchObservers.register(observer); 17020 } 17021 17022 @Override 17023 public void unregisterUserSwitchObserver(IUserSwitchObserver observer) { 17024 mUserSwitchObservers.unregister(observer); 17025 } 17026 17027 private boolean userExists(int userId) { 17028 if (userId == 0) { 17029 return true; 17030 } 17031 UserManagerService ums = getUserManagerLocked(); 17032 return ums != null ? (ums.getUserInfo(userId) != null) : false; 17033 } 17034 17035 int[] getUsersLocked() { 17036 UserManagerService ums = getUserManagerLocked(); 17037 return ums != null ? ums.getUserIds() : new int[] { 0 }; 17038 } 17039 17040 UserManagerService getUserManagerLocked() { 17041 if (mUserManager == null) { 17042 IBinder b = ServiceManager.getService(Context.USER_SERVICE); 17043 mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b); 17044 } 17045 return mUserManager; 17046 } 17047 17048 private int applyUserId(int uid, int userId) { 17049 return UserHandle.getUid(userId, uid); 17050 } 17051 17052 ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) { 17053 if (info == null) return null; 17054 ApplicationInfo newInfo = new ApplicationInfo(info); 17055 newInfo.uid = applyUserId(info.uid, userId); 17056 newInfo.dataDir = USER_DATA_DIR + userId + "/" 17057 + info.packageName; 17058 return newInfo; 17059 } 17060 17061 ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) { 17062 if (aInfo == null 17063 || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) { 17064 return aInfo; 17065 } 17066 17067 ActivityInfo info = new ActivityInfo(aInfo); 17068 info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId); 17069 return info; 17070 } 17071 17072 private final class LocalService extends ActivityManagerInternal { 17073 @Override 17074 public void goingToSleep() { 17075 ActivityManagerService.this.goingToSleep(); 17076 } 17077 17078 @Override 17079 public void wakingUp() { 17080 ActivityManagerService.this.wakingUp(); 17081 } 17082 } 17083} 17084