ActivityManagerService.java revision ee36c77acd3b92c64e53e19c570e2482382db870
1/* 2 * Copyright (C) 2006-2008 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17package com.android.server.am; 18 19import static android.content.pm.PackageManager.PERMISSION_GRANTED; 20import static com.android.internal.util.XmlUtils.readIntAttribute; 21import static com.android.internal.util.XmlUtils.readLongAttribute; 22import static com.android.internal.util.XmlUtils.writeIntAttribute; 23import static com.android.internal.util.XmlUtils.writeLongAttribute; 24import static com.android.server.Watchdog.NATIVE_STACKS_OF_INTEREST; 25import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT; 26import static org.xmlpull.v1.XmlPullParser.START_TAG; 27import static com.android.server.am.ActivityStackSupervisor.HOME_STACK_ID; 28 29import android.app.AppOpsManager; 30import android.app.IActivityContainer; 31import android.app.IActivityContainerCallback; 32import android.appwidget.AppWidgetManager; 33import android.graphics.Rect; 34import android.util.ArrayMap; 35 36import com.android.internal.R; 37import com.android.internal.annotations.GuardedBy; 38import com.android.internal.app.IAppOpsService; 39import com.android.internal.app.ProcessMap; 40import com.android.internal.app.ProcessStats; 41import com.android.internal.os.BackgroundThread; 42import com.android.internal.os.BatteryStatsImpl; 43import com.android.internal.os.ProcessCpuTracker; 44import com.android.internal.os.TransferPipe; 45import com.android.internal.util.FastPrintWriter; 46import com.android.internal.util.FastXmlSerializer; 47import com.android.internal.util.MemInfoReader; 48import com.android.internal.util.Preconditions; 49import com.android.server.AppOpsService; 50import com.android.server.AttributeCache; 51import com.android.server.IntentResolver; 52import com.android.server.LocalServices; 53import com.android.server.ServiceThread; 54import com.android.server.SystemService; 55import com.android.server.Watchdog; 56import com.android.server.am.ActivityStack.ActivityState; 57import com.android.server.firewall.IntentFirewall; 58import com.android.server.pm.UserManagerService; 59import com.android.server.wm.AppTransition; 60import com.android.server.wm.WindowManagerService; 61import com.google.android.collect.Lists; 62import com.google.android.collect.Maps; 63 64import dalvik.system.Zygote; 65import libcore.io.IoUtils; 66 67import org.xmlpull.v1.XmlPullParser; 68import org.xmlpull.v1.XmlPullParserException; 69import org.xmlpull.v1.XmlSerializer; 70 71import android.app.Activity; 72import android.app.ActivityManager; 73import android.app.ActivityManager.RunningTaskInfo; 74import android.app.ActivityManager.StackInfo; 75import android.app.ActivityManagerInternal; 76import android.app.ActivityManagerNative; 77import android.app.ActivityOptions; 78import android.app.ActivityThread; 79import android.app.AlertDialog; 80import android.app.AppGlobals; 81import android.app.ApplicationErrorReport; 82import android.app.Dialog; 83import android.app.IActivityController; 84import android.app.IApplicationThread; 85import android.app.IInstrumentationWatcher; 86import android.app.INotificationManager; 87import android.app.IProcessObserver; 88import android.app.IServiceConnection; 89import android.app.IStopUserCallback; 90import android.app.IThumbnailReceiver; 91import android.app.IUiAutomationConnection; 92import android.app.IUserSwitchObserver; 93import android.app.Instrumentation; 94import android.app.Notification; 95import android.app.NotificationManager; 96import android.app.PendingIntent; 97import android.app.backup.IBackupManager; 98import android.content.ActivityNotFoundException; 99import android.content.BroadcastReceiver; 100import android.content.ClipData; 101import android.content.ComponentCallbacks2; 102import android.content.ComponentName; 103import android.content.ContentProvider; 104import android.content.ContentResolver; 105import android.content.Context; 106import android.content.DialogInterface; 107import android.content.IContentProvider; 108import android.content.IIntentReceiver; 109import android.content.IIntentSender; 110import android.content.Intent; 111import android.content.IntentFilter; 112import android.content.IntentSender; 113import android.content.pm.ActivityInfo; 114import android.content.pm.ApplicationInfo; 115import android.content.pm.ConfigurationInfo; 116import android.content.pm.IPackageDataObserver; 117import android.content.pm.IPackageManager; 118import android.content.pm.InstrumentationInfo; 119import android.content.pm.PackageInfo; 120import android.content.pm.PackageManager; 121import android.content.pm.ParceledListSlice; 122import android.content.pm.UserInfo; 123import android.content.pm.PackageManager.NameNotFoundException; 124import android.content.pm.PathPermission; 125import android.content.pm.ProviderInfo; 126import android.content.pm.ResolveInfo; 127import android.content.pm.ServiceInfo; 128import android.content.res.CompatibilityInfo; 129import android.content.res.Configuration; 130import android.graphics.Bitmap; 131import android.net.Proxy; 132import android.net.ProxyProperties; 133import android.net.Uri; 134import android.os.Binder; 135import android.os.Build; 136import android.os.Bundle; 137import android.os.Debug; 138import android.os.DropBoxManager; 139import android.os.Environment; 140import android.os.FactoryTest; 141import android.os.FileObserver; 142import android.os.FileUtils; 143import android.os.Handler; 144import android.os.IBinder; 145import android.os.IPermissionController; 146import android.os.IRemoteCallback; 147import android.os.IUserManager; 148import android.os.Looper; 149import android.os.Message; 150import android.os.Parcel; 151import android.os.ParcelFileDescriptor; 152import android.os.Process; 153import android.os.RemoteCallbackList; 154import android.os.RemoteException; 155import android.os.SELinux; 156import android.os.ServiceManager; 157import android.os.StrictMode; 158import android.os.SystemClock; 159import android.os.SystemProperties; 160import android.os.UpdateLock; 161import android.os.UserHandle; 162import android.provider.Settings; 163import android.text.format.DateUtils; 164import android.text.format.Time; 165import android.util.AtomicFile; 166import android.util.EventLog; 167import android.util.Log; 168import android.util.Pair; 169import android.util.PrintWriterPrinter; 170import android.util.Slog; 171import android.util.SparseArray; 172import android.util.TimeUtils; 173import android.util.Xml; 174import android.view.Gravity; 175import android.view.LayoutInflater; 176import android.view.View; 177import android.view.WindowManager; 178 179import java.io.BufferedInputStream; 180import java.io.BufferedOutputStream; 181import java.io.DataInputStream; 182import java.io.DataOutputStream; 183import java.io.File; 184import java.io.FileDescriptor; 185import java.io.FileInputStream; 186import java.io.FileNotFoundException; 187import java.io.FileOutputStream; 188import java.io.IOException; 189import java.io.InputStreamReader; 190import java.io.PrintWriter; 191import java.io.StringWriter; 192import java.lang.ref.WeakReference; 193import java.util.ArrayList; 194import java.util.Arrays; 195import java.util.Collections; 196import java.util.Comparator; 197import java.util.HashMap; 198import java.util.HashSet; 199import java.util.Iterator; 200import java.util.List; 201import java.util.Locale; 202import java.util.Map; 203import java.util.Set; 204import java.util.concurrent.atomic.AtomicBoolean; 205import java.util.concurrent.atomic.AtomicLong; 206 207public final class ActivityManagerService extends ActivityManagerNative 208 implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback { 209 private static final String USER_DATA_DIR = "/data/user/"; 210 static final String TAG = "ActivityManager"; 211 static final String TAG_MU = "ActivityManagerServiceMU"; 212 static final boolean DEBUG = false; 213 static final boolean localLOGV = DEBUG; 214 static final boolean DEBUG_BACKUP = localLOGV || false; 215 static final boolean DEBUG_BROADCAST = localLOGV || false; 216 static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false; 217 static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false; 218 static final boolean DEBUG_CLEANUP = localLOGV || false; 219 static final boolean DEBUG_CONFIGURATION = localLOGV || false; 220 static final boolean DEBUG_FOCUS = false; 221 static final boolean DEBUG_IMMERSIVE = localLOGV || false; 222 static final boolean DEBUG_MU = localLOGV || false; 223 static final boolean DEBUG_OOM_ADJ = localLOGV || false; 224 static final boolean DEBUG_LRU = localLOGV || false; 225 static final boolean DEBUG_PAUSE = localLOGV || false; 226 static final boolean DEBUG_POWER = localLOGV || false; 227 static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false; 228 static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false; 229 static final boolean DEBUG_PROCESSES = localLOGV || false; 230 static final boolean DEBUG_PROVIDER = localLOGV || false; 231 static final boolean DEBUG_RESULTS = localLOGV || false; 232 static final boolean DEBUG_SERVICE = localLOGV || false; 233 static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false; 234 static final boolean DEBUG_STACK = localLOGV || false; 235 static final boolean DEBUG_SWITCH = localLOGV || false; 236 static final boolean DEBUG_TASKS = localLOGV || false; 237 static final boolean DEBUG_THUMBNAILS = localLOGV || false; 238 static final boolean DEBUG_TRANSITION = localLOGV || false; 239 static final boolean DEBUG_URI_PERMISSION = localLOGV || false; 240 static final boolean DEBUG_USER_LEAVING = localLOGV || false; 241 static final boolean DEBUG_VISBILITY = localLOGV || false; 242 static final boolean DEBUG_PSS = localLOGV || false; 243 static final boolean DEBUG_LOCKSCREEN = localLOGV || false; 244 static final boolean VALIDATE_TOKENS = false; 245 static final boolean SHOW_ACTIVITY_START_TIME = true; 246 247 // Control over CPU and battery monitoring. 248 static final long BATTERY_STATS_TIME = 30*60*1000; // write battery stats every 30 minutes. 249 static final boolean MONITOR_CPU_USAGE = true; 250 static final long MONITOR_CPU_MIN_TIME = 5*1000; // don't sample cpu less than every 5 seconds. 251 static final long MONITOR_CPU_MAX_TIME = 0x0fffffff; // wait possibly forever for next cpu sample. 252 static final boolean MONITOR_THREAD_CPU_USAGE = false; 253 254 // The flags that are set for all calls we make to the package manager. 255 static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES; 256 257 private static final String SYSTEM_DEBUGGABLE = "ro.debuggable"; 258 259 static final boolean IS_USER_BUILD = "user".equals(Build.TYPE); 260 261 // Maximum number of recent tasks that we can remember. 262 static final int MAX_RECENT_TASKS = ActivityManager.isLowRamDeviceStatic() ? 10 : 20; 263 264 // Amount of time after a call to stopAppSwitches() during which we will 265 // prevent further untrusted switches from happening. 266 static final long APP_SWITCH_DELAY_TIME = 5*1000; 267 268 // How long we wait for a launched process to attach to the activity manager 269 // before we decide it's never going to come up for real. 270 static final int PROC_START_TIMEOUT = 10*1000; 271 272 // How long we wait for a launched process to attach to the activity manager 273 // before we decide it's never going to come up for real, when the process was 274 // started with a wrapper for instrumentation (such as Valgrind) because it 275 // could take much longer than usual. 276 static final int PROC_START_TIMEOUT_WITH_WRAPPER = 300*1000; 277 278 // How long to wait after going idle before forcing apps to GC. 279 static final int GC_TIMEOUT = 5*1000; 280 281 // The minimum amount of time between successive GC requests for a process. 282 static final int GC_MIN_INTERVAL = 60*1000; 283 284 // The minimum amount of time between successive PSS requests for a process. 285 static final int FULL_PSS_MIN_INTERVAL = 10*60*1000; 286 287 // The minimum amount of time between successive PSS requests for a process 288 // when the request is due to the memory state being lowered. 289 static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000; 290 291 // The rate at which we check for apps using excessive power -- 15 mins. 292 static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000; 293 294 // The minimum sample duration we will allow before deciding we have 295 // enough data on wake locks to start killing things. 296 static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000; 297 298 // The minimum sample duration we will allow before deciding we have 299 // enough data on CPU usage to start killing things. 300 static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000; 301 302 // How long we allow a receiver to run before giving up on it. 303 static final int BROADCAST_FG_TIMEOUT = 10*1000; 304 static final int BROADCAST_BG_TIMEOUT = 60*1000; 305 306 // How long we wait until we timeout on key dispatching. 307 static final int KEY_DISPATCHING_TIMEOUT = 5*1000; 308 309 // How long we wait until we timeout on key dispatching during instrumentation. 310 static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000; 311 312 // Amount of time we wait for observers to handle a user switch before 313 // giving up on them and unfreezing the screen. 314 static final int USER_SWITCH_TIMEOUT = 2*1000; 315 316 // Maximum number of users we allow to be running at a time. 317 static final int MAX_RUNNING_USERS = 3; 318 319 // How long to wait in getAssistContextExtras for the activity and foreground services 320 // to respond with the result. 321 static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500; 322 323 // Maximum number of persisted Uri grants a package is allowed 324 static final int MAX_PERSISTED_URI_GRANTS = 128; 325 326 static final int MY_PID = Process.myPid(); 327 328 static final String[] EMPTY_STRING_ARRAY = new String[0]; 329 330 // How many bytes to write into the dropbox log before truncating 331 static final int DROPBOX_MAX_SIZE = 256 * 1024; 332 333 /** Run all ActivityStacks through this */ 334 ActivityStackSupervisor mStackSupervisor; 335 336 public IntentFirewall mIntentFirewall; 337 338 // Whether we should show our dialogs (ANR, crash, etc) or just perform their 339 // default actuion automatically. Important for devices without direct input 340 // devices. 341 private boolean mShowDialogs = true; 342 343 BroadcastQueue mFgBroadcastQueue; 344 BroadcastQueue mBgBroadcastQueue; 345 // Convenient for easy iteration over the queues. Foreground is first 346 // so that dispatch of foreground broadcasts gets precedence. 347 final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2]; 348 349 BroadcastQueue broadcastQueueForIntent(Intent intent) { 350 final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0; 351 if (DEBUG_BACKGROUND_BROADCAST) { 352 Slog.i(TAG, "Broadcast intent " + intent + " on " 353 + (isFg ? "foreground" : "background") 354 + " queue"); 355 } 356 return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue; 357 } 358 359 BroadcastRecord broadcastRecordForReceiverLocked(IBinder receiver) { 360 for (BroadcastQueue queue : mBroadcastQueues) { 361 BroadcastRecord r = queue.getMatchingOrderedReceiver(receiver); 362 if (r != null) { 363 return r; 364 } 365 } 366 return null; 367 } 368 369 /** 370 * Activity we have told the window manager to have key focus. 371 */ 372 ActivityRecord mFocusedActivity = null; 373 374 /** 375 * List of intents that were used to start the most recent tasks. 376 */ 377 private final ArrayList<TaskRecord> mRecentTasks = new ArrayList<TaskRecord>(); 378 379 public class PendingAssistExtras extends Binder implements Runnable { 380 public final ActivityRecord activity; 381 public boolean haveResult = false; 382 public Bundle result = null; 383 public PendingAssistExtras(ActivityRecord _activity) { 384 activity = _activity; 385 } 386 @Override 387 public void run() { 388 Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity); 389 synchronized (this) { 390 haveResult = true; 391 notifyAll(); 392 } 393 } 394 } 395 396 final ArrayList<PendingAssistExtras> mPendingAssistExtras 397 = new ArrayList<PendingAssistExtras>(); 398 399 /** 400 * Process management. 401 */ 402 final ProcessList mProcessList = new ProcessList(); 403 404 /** 405 * All of the applications we currently have running organized by name. 406 * The keys are strings of the application package name (as 407 * returned by the package manager), and the keys are ApplicationRecord 408 * objects. 409 */ 410 final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>(); 411 412 /** 413 * Tracking long-term execution of processes to look for abuse and other 414 * bad app behavior. 415 */ 416 final ProcessStatsService mProcessStats; 417 418 /** 419 * The currently running isolated processes. 420 */ 421 final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>(); 422 423 /** 424 * Counter for assigning isolated process uids, to avoid frequently reusing the 425 * same ones. 426 */ 427 int mNextIsolatedProcessUid = 0; 428 429 /** 430 * The currently running heavy-weight process, if any. 431 */ 432 ProcessRecord mHeavyWeightProcess = null; 433 434 /** 435 * The last time that various processes have crashed. 436 */ 437 final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>(); 438 439 /** 440 * Information about a process that is currently marked as bad. 441 */ 442 static final class BadProcessInfo { 443 BadProcessInfo(long time, String shortMsg, String longMsg, String stack) { 444 this.time = time; 445 this.shortMsg = shortMsg; 446 this.longMsg = longMsg; 447 this.stack = stack; 448 } 449 450 final long time; 451 final String shortMsg; 452 final String longMsg; 453 final String stack; 454 } 455 456 /** 457 * Set of applications that we consider to be bad, and will reject 458 * incoming broadcasts from (which the user has no control over). 459 * Processes are added to this set when they have crashed twice within 460 * a minimum amount of time; they are removed from it when they are 461 * later restarted (hopefully due to some user action). The value is the 462 * time it was added to the list. 463 */ 464 final ProcessMap<BadProcessInfo> mBadProcesses = new ProcessMap<BadProcessInfo>(); 465 466 /** 467 * All of the processes we currently have running organized by pid. 468 * The keys are the pid running the application. 469 * 470 * <p>NOTE: This object is protected by its own lock, NOT the global 471 * activity manager lock! 472 */ 473 final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>(); 474 475 /** 476 * All of the processes that have been forced to be foreground. The key 477 * is the pid of the caller who requested it (we hold a death 478 * link on it). 479 */ 480 abstract class ForegroundToken implements IBinder.DeathRecipient { 481 int pid; 482 IBinder token; 483 } 484 final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>(); 485 486 /** 487 * List of records for processes that someone had tried to start before the 488 * system was ready. We don't start them at that point, but ensure they 489 * are started by the time booting is complete. 490 */ 491 final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>(); 492 493 /** 494 * List of persistent applications that are in the process 495 * of being started. 496 */ 497 final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>(); 498 499 /** 500 * Processes that are being forcibly torn down. 501 */ 502 final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>(); 503 504 /** 505 * List of running applications, sorted by recent usage. 506 * The first entry in the list is the least recently used. 507 */ 508 final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>(); 509 510 /** 511 * Where in mLruProcesses that the processes hosting activities start. 512 */ 513 int mLruProcessActivityStart = 0; 514 515 /** 516 * Where in mLruProcesses that the processes hosting services start. 517 * This is after (lower index) than mLruProcessesActivityStart. 518 */ 519 int mLruProcessServiceStart = 0; 520 521 /** 522 * List of processes that should gc as soon as things are idle. 523 */ 524 final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>(); 525 526 /** 527 * Processes we want to collect PSS data from. 528 */ 529 final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>(); 530 531 /** 532 * Last time we requested PSS data of all processes. 533 */ 534 long mLastFullPssTime = SystemClock.uptimeMillis(); 535 536 /** 537 * This is the process holding what we currently consider to be 538 * the "home" activity. 539 */ 540 ProcessRecord mHomeProcess; 541 542 /** 543 * This is the process holding the activity the user last visited that 544 * is in a different process from the one they are currently in. 545 */ 546 ProcessRecord mPreviousProcess; 547 548 /** 549 * The time at which the previous process was last visible. 550 */ 551 long mPreviousProcessVisibleTime; 552 553 /** 554 * Which uses have been started, so are allowed to run code. 555 */ 556 final SparseArray<UserStartedState> mStartedUsers = new SparseArray<UserStartedState>(); 557 558 /** 559 * LRU list of history of current users. Most recently current is at the end. 560 */ 561 final ArrayList<Integer> mUserLru = new ArrayList<Integer>(); 562 563 /** 564 * Constant array of the users that are currently started. 565 */ 566 int[] mStartedUserArray = new int[] { 0 }; 567 568 /** 569 * Registered observers of the user switching mechanics. 570 */ 571 final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers 572 = new RemoteCallbackList<IUserSwitchObserver>(); 573 574 /** 575 * Currently active user switch. 576 */ 577 Object mCurUserSwitchCallback; 578 579 /** 580 * Packages that the user has asked to have run in screen size 581 * compatibility mode instead of filling the screen. 582 */ 583 final CompatModePackages mCompatModePackages; 584 585 /** 586 * Set of IntentSenderRecord objects that are currently active. 587 */ 588 final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords 589 = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>(); 590 591 /** 592 * Fingerprints (hashCode()) of stack traces that we've 593 * already logged DropBox entries for. Guarded by itself. If 594 * something (rogue user app) forces this over 595 * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared. 596 */ 597 private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>(); 598 private static final int MAX_DUP_SUPPRESSED_STACKS = 5000; 599 600 /** 601 * Strict Mode background batched logging state. 602 * 603 * The string buffer is guarded by itself, and its lock is also 604 * used to determine if another batched write is already 605 * in-flight. 606 */ 607 private final StringBuilder mStrictModeBuffer = new StringBuilder(); 608 609 /** 610 * Keeps track of all IIntentReceivers that have been registered for 611 * broadcasts. Hash keys are the receiver IBinder, hash value is 612 * a ReceiverList. 613 */ 614 final HashMap<IBinder, ReceiverList> mRegisteredReceivers = 615 new HashMap<IBinder, ReceiverList>(); 616 617 /** 618 * Resolver for broadcast intents to registered receivers. 619 * Holds BroadcastFilter (subclass of IntentFilter). 620 */ 621 final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver 622 = new IntentResolver<BroadcastFilter, BroadcastFilter>() { 623 @Override 624 protected boolean allowFilterResult( 625 BroadcastFilter filter, List<BroadcastFilter> dest) { 626 IBinder target = filter.receiverList.receiver.asBinder(); 627 for (int i=dest.size()-1; i>=0; i--) { 628 if (dest.get(i).receiverList.receiver.asBinder() == target) { 629 return false; 630 } 631 } 632 return true; 633 } 634 635 @Override 636 protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) { 637 if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL 638 || userId == filter.owningUserId) { 639 return super.newResult(filter, match, userId); 640 } 641 return null; 642 } 643 644 @Override 645 protected BroadcastFilter[] newArray(int size) { 646 return new BroadcastFilter[size]; 647 } 648 649 @Override 650 protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) { 651 return packageName.equals(filter.packageName); 652 } 653 }; 654 655 /** 656 * State of all active sticky broadcasts per user. Keys are the action of the 657 * sticky Intent, values are an ArrayList of all broadcasted intents with 658 * that action (which should usually be one). The SparseArray is keyed 659 * by the user ID the sticky is for, and can include UserHandle.USER_ALL 660 * for stickies that are sent to all users. 661 */ 662 final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts = 663 new SparseArray<ArrayMap<String, ArrayList<Intent>>>(); 664 665 final ActiveServices mServices; 666 667 /** 668 * Backup/restore process management 669 */ 670 String mBackupAppName = null; 671 BackupRecord mBackupTarget = null; 672 673 /** 674 * List of PendingThumbnailsRecord objects of clients who are still 675 * waiting to receive all of the thumbnails for a task. 676 */ 677 final ArrayList<PendingThumbnailsRecord> mPendingThumbnails = 678 new ArrayList<PendingThumbnailsRecord>(); 679 680 final ProviderMap mProviderMap; 681 682 /** 683 * List of content providers who have clients waiting for them. The 684 * application is currently being launched and the provider will be 685 * removed from this list once it is published. 686 */ 687 final ArrayList<ContentProviderRecord> mLaunchingProviders 688 = new ArrayList<ContentProviderRecord>(); 689 690 /** 691 * File storing persisted {@link #mGrantedUriPermissions}. 692 */ 693 private final AtomicFile mGrantFile; 694 695 /** XML constants used in {@link #mGrantFile} */ 696 private static final String TAG_URI_GRANTS = "uri-grants"; 697 private static final String TAG_URI_GRANT = "uri-grant"; 698 private static final String ATTR_USER_HANDLE = "userHandle"; 699 private static final String ATTR_SOURCE_PKG = "sourcePkg"; 700 private static final String ATTR_TARGET_PKG = "targetPkg"; 701 private static final String ATTR_URI = "uri"; 702 private static final String ATTR_MODE_FLAGS = "modeFlags"; 703 private static final String ATTR_CREATED_TIME = "createdTime"; 704 705 /** 706 * Global set of specific {@link Uri} permissions that have been granted. 707 * This optimized lookup structure maps from {@link UriPermission#targetUid} 708 * to {@link UriPermission#uri} to {@link UriPermission}. 709 */ 710 @GuardedBy("this") 711 private final SparseArray<ArrayMap<Uri, UriPermission>> 712 mGrantedUriPermissions = new SparseArray<ArrayMap<Uri, UriPermission>>(); 713 714 CoreSettingsObserver mCoreSettingsObserver; 715 716 /** 717 * Thread-local storage used to carry caller permissions over through 718 * indirect content-provider access. 719 */ 720 private class Identity { 721 public int pid; 722 public int uid; 723 724 Identity(int _pid, int _uid) { 725 pid = _pid; 726 uid = _uid; 727 } 728 } 729 730 private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>(); 731 732 /** 733 * All information we have collected about the runtime performance of 734 * any user id that can impact battery performance. 735 */ 736 final BatteryStatsService mBatteryStatsService; 737 738 /** 739 * Information about component usage 740 */ 741 final UsageStatsService mUsageStatsService; 742 743 /** 744 * Information about and control over application operations 745 */ 746 final AppOpsService mAppOpsService; 747 748 /** 749 * Current configuration information. HistoryRecord objects are given 750 * a reference to this object to indicate which configuration they are 751 * currently running in, so this object must be kept immutable. 752 */ 753 Configuration mConfiguration = new Configuration(); 754 755 /** 756 * Current sequencing integer of the configuration, for skipping old 757 * configurations. 758 */ 759 int mConfigurationSeq = 0; 760 761 /** 762 * Hardware-reported OpenGLES version. 763 */ 764 final int GL_ES_VERSION; 765 766 /** 767 * List of initialization arguments to pass to all processes when binding applications to them. 768 * For example, references to the commonly used services. 769 */ 770 HashMap<String, IBinder> mAppBindArgs; 771 772 /** 773 * Temporary to avoid allocations. Protected by main lock. 774 */ 775 final StringBuilder mStringBuilder = new StringBuilder(256); 776 777 /** 778 * Used to control how we initialize the service. 779 */ 780 ComponentName mTopComponent; 781 String mTopAction = Intent.ACTION_MAIN; 782 String mTopData; 783 boolean mProcessesReady = false; 784 boolean mSystemReady = false; 785 boolean mBooting = false; 786 boolean mWaitingUpdate = false; 787 boolean mDidUpdate = false; 788 boolean mOnBattery = false; 789 boolean mLaunchWarningShown = false; 790 791 Context mContext; 792 793 int mFactoryTest; 794 795 boolean mCheckedForSetup; 796 797 /** 798 * The time at which we will allow normal application switches again, 799 * after a call to {@link #stopAppSwitches()}. 800 */ 801 long mAppSwitchesAllowedTime; 802 803 /** 804 * This is set to true after the first switch after mAppSwitchesAllowedTime 805 * is set; any switches after that will clear the time. 806 */ 807 boolean mDidAppSwitch; 808 809 /** 810 * Last time (in realtime) at which we checked for power usage. 811 */ 812 long mLastPowerCheckRealtime; 813 814 /** 815 * Last time (in uptime) at which we checked for power usage. 816 */ 817 long mLastPowerCheckUptime; 818 819 /** 820 * Set while we are wanting to sleep, to prevent any 821 * activities from being started/resumed. 822 */ 823 boolean mSleeping = false; 824 825 /** 826 * State of external calls telling us if the device is asleep. 827 */ 828 boolean mWentToSleep = false; 829 830 /** 831 * State of external call telling us if the lock screen is shown. 832 */ 833 boolean mLockScreenShown = false; 834 835 /** 836 * Set if we are shutting down the system, similar to sleeping. 837 */ 838 boolean mShuttingDown = false; 839 840 /** 841 * Current sequence id for oom_adj computation traversal. 842 */ 843 int mAdjSeq = 0; 844 845 /** 846 * Current sequence id for process LRU updating. 847 */ 848 int mLruSeq = 0; 849 850 /** 851 * Keep track of the non-cached/empty process we last found, to help 852 * determine how to distribute cached/empty processes next time. 853 */ 854 int mNumNonCachedProcs = 0; 855 856 /** 857 * Keep track of the number of cached hidden procs, to balance oom adj 858 * distribution between those and empty procs. 859 */ 860 int mNumCachedHiddenProcs = 0; 861 862 /** 863 * Keep track of the number of service processes we last found, to 864 * determine on the next iteration which should be B services. 865 */ 866 int mNumServiceProcs = 0; 867 int mNewNumAServiceProcs = 0; 868 int mNewNumServiceProcs = 0; 869 870 /** 871 * Allow the current computed overall memory level of the system to go down? 872 * This is set to false when we are killing processes for reasons other than 873 * memory management, so that the now smaller process list will not be taken as 874 * an indication that memory is tighter. 875 */ 876 boolean mAllowLowerMemLevel = false; 877 878 /** 879 * The last computed memory level, for holding when we are in a state that 880 * processes are going away for other reasons. 881 */ 882 int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL; 883 884 /** 885 * The last total number of process we have, to determine if changes actually look 886 * like a shrinking number of process due to lower RAM. 887 */ 888 int mLastNumProcesses; 889 890 /** 891 * The uptime of the last time we performed idle maintenance. 892 */ 893 long mLastIdleTime = SystemClock.uptimeMillis(); 894 895 /** 896 * Total time spent with RAM that has been added in the past since the last idle time. 897 */ 898 long mLowRamTimeSinceLastIdle = 0; 899 900 /** 901 * If RAM is currently low, when that horrible situatin started. 902 */ 903 long mLowRamStartTime = 0; 904 905 /** 906 * This is set if we had to do a delayed dexopt of an app before launching 907 * it, to increasing the ANR timeouts in that case. 908 */ 909 boolean mDidDexOpt; 910 911 String mDebugApp = null; 912 boolean mWaitForDebugger = false; 913 boolean mDebugTransient = false; 914 String mOrigDebugApp = null; 915 boolean mOrigWaitForDebugger = false; 916 boolean mAlwaysFinishActivities = false; 917 IActivityController mController = null; 918 String mProfileApp = null; 919 ProcessRecord mProfileProc = null; 920 String mProfileFile; 921 ParcelFileDescriptor mProfileFd; 922 int mProfileType = 0; 923 boolean mAutoStopProfiler = false; 924 String mOpenGlTraceApp = null; 925 926 static class ProcessChangeItem { 927 static final int CHANGE_ACTIVITIES = 1<<0; 928 static final int CHANGE_IMPORTANCE= 1<<1; 929 int changes; 930 int uid; 931 int pid; 932 int importance; 933 boolean foregroundActivities; 934 } 935 936 final RemoteCallbackList<IProcessObserver> mProcessObservers 937 = new RemoteCallbackList<IProcessObserver>(); 938 ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5]; 939 940 final ArrayList<ProcessChangeItem> mPendingProcessChanges 941 = new ArrayList<ProcessChangeItem>(); 942 final ArrayList<ProcessChangeItem> mAvailProcessChanges 943 = new ArrayList<ProcessChangeItem>(); 944 945 /** 946 * Runtime CPU use collection thread. This object's lock is used to 947 * protect all related state. 948 */ 949 final Thread mProcessCpuThread; 950 951 /** 952 * Used to collect process stats when showing not responding dialog. 953 * Protected by mProcessCpuThread. 954 */ 955 final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker( 956 MONITOR_THREAD_CPU_USAGE); 957 final AtomicLong mLastCpuTime = new AtomicLong(0); 958 final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true); 959 960 long mLastWriteTime = 0; 961 962 /** 963 * Used to retain an update lock when the foreground activity is in 964 * immersive mode. 965 */ 966 final UpdateLock mUpdateLock = new UpdateLock("immersive"); 967 968 /** 969 * Set to true after the system has finished booting. 970 */ 971 boolean mBooted = false; 972 973 int mProcessLimit = ProcessList.MAX_CACHED_APPS; 974 int mProcessLimitOverride = -1; 975 976 WindowManagerService mWindowManager; 977 978 final ActivityThread mSystemThread; 979 980 int mCurrentUserId = 0; 981 private UserManagerService mUserManager; 982 983 private final class AppDeathRecipient implements IBinder.DeathRecipient { 984 final ProcessRecord mApp; 985 final int mPid; 986 final IApplicationThread mAppThread; 987 988 AppDeathRecipient(ProcessRecord app, int pid, 989 IApplicationThread thread) { 990 if (localLOGV) Slog.v( 991 TAG, "New death recipient " + this 992 + " for thread " + thread.asBinder()); 993 mApp = app; 994 mPid = pid; 995 mAppThread = thread; 996 } 997 998 @Override 999 public void binderDied() { 1000 if (localLOGV) Slog.v( 1001 TAG, "Death received in " + this 1002 + " for thread " + mAppThread.asBinder()); 1003 synchronized(ActivityManagerService.this) { 1004 appDiedLocked(mApp, mPid, mAppThread); 1005 } 1006 } 1007 } 1008 1009 static final int SHOW_ERROR_MSG = 1; 1010 static final int SHOW_NOT_RESPONDING_MSG = 2; 1011 static final int SHOW_FACTORY_ERROR_MSG = 3; 1012 static final int UPDATE_CONFIGURATION_MSG = 4; 1013 static final int GC_BACKGROUND_PROCESSES_MSG = 5; 1014 static final int WAIT_FOR_DEBUGGER_MSG = 6; 1015 static final int SERVICE_TIMEOUT_MSG = 12; 1016 static final int UPDATE_TIME_ZONE = 13; 1017 static final int SHOW_UID_ERROR_MSG = 14; 1018 static final int IM_FEELING_LUCKY_MSG = 15; 1019 static final int PROC_START_TIMEOUT_MSG = 20; 1020 static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21; 1021 static final int KILL_APPLICATION_MSG = 22; 1022 static final int FINALIZE_PENDING_INTENT_MSG = 23; 1023 static final int POST_HEAVY_NOTIFICATION_MSG = 24; 1024 static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25; 1025 static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26; 1026 static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27; 1027 static final int CLEAR_DNS_CACHE_MSG = 28; 1028 static final int UPDATE_HTTP_PROXY_MSG = 29; 1029 static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30; 1030 static final int DISPATCH_PROCESSES_CHANGED = 31; 1031 static final int DISPATCH_PROCESS_DIED = 32; 1032 static final int REPORT_MEM_USAGE_MSG = 33; 1033 static final int REPORT_USER_SWITCH_MSG = 34; 1034 static final int CONTINUE_USER_SWITCH_MSG = 35; 1035 static final int USER_SWITCH_TIMEOUT_MSG = 36; 1036 static final int IMMERSIVE_MODE_LOCK_MSG = 37; 1037 static final int PERSIST_URI_GRANTS_MSG = 38; 1038 static final int REQUEST_ALL_PSS_MSG = 39; 1039 1040 static final int FIRST_ACTIVITY_STACK_MSG = 100; 1041 static final int FIRST_BROADCAST_QUEUE_MSG = 200; 1042 static final int FIRST_COMPAT_MODE_MSG = 300; 1043 static final int FIRST_SUPERVISOR_STACK_MSG = 100; 1044 1045 AlertDialog mUidAlert; 1046 CompatModeDialog mCompatModeDialog; 1047 long mLastMemUsageReportTime = 0; 1048 1049 /** 1050 * Flag whether the current user is a "monkey", i.e. whether 1051 * the UI is driven by a UI automation tool. 1052 */ 1053 private boolean mUserIsMonkey; 1054 1055 /** Flag whether the device has a recents UI */ 1056 final boolean mHasRecents; 1057 1058 final ServiceThread mHandlerThread; 1059 final MainHandler mHandler; 1060 1061 final class MainHandler extends Handler { 1062 public MainHandler(Looper looper) { 1063 super(looper, null, true); 1064 } 1065 1066 @Override 1067 public void handleMessage(Message msg) { 1068 switch (msg.what) { 1069 case SHOW_ERROR_MSG: { 1070 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1071 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), 1072 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; 1073 synchronized (ActivityManagerService.this) { 1074 ProcessRecord proc = (ProcessRecord)data.get("app"); 1075 AppErrorResult res = (AppErrorResult) data.get("result"); 1076 if (proc != null && proc.crashDialog != null) { 1077 Slog.e(TAG, "App already has crash dialog: " + proc); 1078 if (res != null) { 1079 res.set(0); 1080 } 1081 return; 1082 } 1083 if (!showBackground && UserHandle.getAppId(proc.uid) 1084 >= Process.FIRST_APPLICATION_UID && proc.userId != mCurrentUserId 1085 && proc.pid != MY_PID) { 1086 Slog.w(TAG, "Skipping crash dialog of " + proc + ": background"); 1087 if (res != null) { 1088 res.set(0); 1089 } 1090 return; 1091 } 1092 if (mShowDialogs && !mSleeping && !mShuttingDown) { 1093 Dialog d = new AppErrorDialog(mContext, 1094 ActivityManagerService.this, res, proc); 1095 d.show(); 1096 proc.crashDialog = d; 1097 } else { 1098 // The device is asleep, so just pretend that the user 1099 // saw a crash dialog and hit "force quit". 1100 if (res != null) { 1101 res.set(0); 1102 } 1103 } 1104 } 1105 1106 ensureBootCompleted(); 1107 } break; 1108 case SHOW_NOT_RESPONDING_MSG: { 1109 synchronized (ActivityManagerService.this) { 1110 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1111 ProcessRecord proc = (ProcessRecord)data.get("app"); 1112 if (proc != null && proc.anrDialog != null) { 1113 Slog.e(TAG, "App already has anr dialog: " + proc); 1114 return; 1115 } 1116 1117 Intent intent = new Intent("android.intent.action.ANR"); 1118 if (!mProcessesReady) { 1119 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 1120 | Intent.FLAG_RECEIVER_FOREGROUND); 1121 } 1122 broadcastIntentLocked(null, null, intent, 1123 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 1124 false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */); 1125 1126 if (mShowDialogs) { 1127 Dialog d = new AppNotRespondingDialog(ActivityManagerService.this, 1128 mContext, proc, (ActivityRecord)data.get("activity"), 1129 msg.arg1 != 0); 1130 d.show(); 1131 proc.anrDialog = d; 1132 } else { 1133 // Just kill the app if there is no dialog to be shown. 1134 killAppAtUsersRequest(proc, null); 1135 } 1136 } 1137 1138 ensureBootCompleted(); 1139 } break; 1140 case SHOW_STRICT_MODE_VIOLATION_MSG: { 1141 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1142 synchronized (ActivityManagerService.this) { 1143 ProcessRecord proc = (ProcessRecord) data.get("app"); 1144 if (proc == null) { 1145 Slog.e(TAG, "App not found when showing strict mode dialog."); 1146 break; 1147 } 1148 if (proc.crashDialog != null) { 1149 Slog.e(TAG, "App already has strict mode dialog: " + proc); 1150 return; 1151 } 1152 AppErrorResult res = (AppErrorResult) data.get("result"); 1153 if (mShowDialogs && !mSleeping && !mShuttingDown) { 1154 Dialog d = new StrictModeViolationDialog(mContext, 1155 ActivityManagerService.this, res, proc); 1156 d.show(); 1157 proc.crashDialog = d; 1158 } else { 1159 // The device is asleep, so just pretend that the user 1160 // saw a crash dialog and hit "force quit". 1161 res.set(0); 1162 } 1163 } 1164 ensureBootCompleted(); 1165 } break; 1166 case SHOW_FACTORY_ERROR_MSG: { 1167 Dialog d = new FactoryErrorDialog( 1168 mContext, msg.getData().getCharSequence("msg")); 1169 d.show(); 1170 ensureBootCompleted(); 1171 } break; 1172 case UPDATE_CONFIGURATION_MSG: { 1173 final ContentResolver resolver = mContext.getContentResolver(); 1174 Settings.System.putConfiguration(resolver, (Configuration)msg.obj); 1175 } break; 1176 case GC_BACKGROUND_PROCESSES_MSG: { 1177 synchronized (ActivityManagerService.this) { 1178 performAppGcsIfAppropriateLocked(); 1179 } 1180 } break; 1181 case WAIT_FOR_DEBUGGER_MSG: { 1182 synchronized (ActivityManagerService.this) { 1183 ProcessRecord app = (ProcessRecord)msg.obj; 1184 if (msg.arg1 != 0) { 1185 if (!app.waitedForDebugger) { 1186 Dialog d = new AppWaitingForDebuggerDialog( 1187 ActivityManagerService.this, 1188 mContext, app); 1189 app.waitDialog = d; 1190 app.waitedForDebugger = true; 1191 d.show(); 1192 } 1193 } else { 1194 if (app.waitDialog != null) { 1195 app.waitDialog.dismiss(); 1196 app.waitDialog = null; 1197 } 1198 } 1199 } 1200 } break; 1201 case SERVICE_TIMEOUT_MSG: { 1202 if (mDidDexOpt) { 1203 mDidDexOpt = false; 1204 Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG); 1205 nmsg.obj = msg.obj; 1206 mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT); 1207 return; 1208 } 1209 mServices.serviceTimeout((ProcessRecord)msg.obj); 1210 } break; 1211 case UPDATE_TIME_ZONE: { 1212 synchronized (ActivityManagerService.this) { 1213 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1214 ProcessRecord r = mLruProcesses.get(i); 1215 if (r.thread != null) { 1216 try { 1217 r.thread.updateTimeZone(); 1218 } catch (RemoteException ex) { 1219 Slog.w(TAG, "Failed to update time zone for: " + r.info.processName); 1220 } 1221 } 1222 } 1223 } 1224 } break; 1225 case CLEAR_DNS_CACHE_MSG: { 1226 synchronized (ActivityManagerService.this) { 1227 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1228 ProcessRecord r = mLruProcesses.get(i); 1229 if (r.thread != null) { 1230 try { 1231 r.thread.clearDnsCache(); 1232 } catch (RemoteException ex) { 1233 Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName); 1234 } 1235 } 1236 } 1237 } 1238 } break; 1239 case UPDATE_HTTP_PROXY_MSG: { 1240 ProxyProperties proxy = (ProxyProperties)msg.obj; 1241 String host = ""; 1242 String port = ""; 1243 String exclList = ""; 1244 String pacFileUrl = null; 1245 if (proxy != null) { 1246 host = proxy.getHost(); 1247 port = Integer.toString(proxy.getPort()); 1248 exclList = proxy.getExclusionList(); 1249 pacFileUrl = proxy.getPacFileUrl(); 1250 } 1251 synchronized (ActivityManagerService.this) { 1252 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1253 ProcessRecord r = mLruProcesses.get(i); 1254 if (r.thread != null) { 1255 try { 1256 r.thread.setHttpProxy(host, port, exclList, pacFileUrl); 1257 } catch (RemoteException ex) { 1258 Slog.w(TAG, "Failed to update http proxy for: " + 1259 r.info.processName); 1260 } 1261 } 1262 } 1263 } 1264 } break; 1265 case SHOW_UID_ERROR_MSG: { 1266 String title = "System UIDs Inconsistent"; 1267 String text = "UIDs on the system are inconsistent, you need to wipe your" 1268 + " data partition or your device will be unstable."; 1269 Log.e(TAG, title + ": " + text); 1270 if (mShowDialogs) { 1271 // XXX This is a temporary dialog, no need to localize. 1272 AlertDialog d = new BaseErrorDialog(mContext); 1273 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR); 1274 d.setCancelable(false); 1275 d.setTitle(title); 1276 d.setMessage(text); 1277 d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky", 1278 mHandler.obtainMessage(IM_FEELING_LUCKY_MSG)); 1279 mUidAlert = d; 1280 d.show(); 1281 } 1282 } break; 1283 case IM_FEELING_LUCKY_MSG: { 1284 if (mUidAlert != null) { 1285 mUidAlert.dismiss(); 1286 mUidAlert = null; 1287 } 1288 } break; 1289 case PROC_START_TIMEOUT_MSG: { 1290 if (mDidDexOpt) { 1291 mDidDexOpt = false; 1292 Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 1293 nmsg.obj = msg.obj; 1294 mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT); 1295 return; 1296 } 1297 ProcessRecord app = (ProcessRecord)msg.obj; 1298 synchronized (ActivityManagerService.this) { 1299 processStartTimedOutLocked(app); 1300 } 1301 } break; 1302 case DO_PENDING_ACTIVITY_LAUNCHES_MSG: { 1303 synchronized (ActivityManagerService.this) { 1304 mStackSupervisor.doPendingActivityLaunchesLocked(true); 1305 } 1306 } break; 1307 case KILL_APPLICATION_MSG: { 1308 synchronized (ActivityManagerService.this) { 1309 int appid = msg.arg1; 1310 boolean restart = (msg.arg2 == 1); 1311 Bundle bundle = (Bundle)msg.obj; 1312 String pkg = bundle.getString("pkg"); 1313 String reason = bundle.getString("reason"); 1314 forceStopPackageLocked(pkg, appid, restart, false, true, false, 1315 UserHandle.USER_ALL, reason); 1316 } 1317 } break; 1318 case FINALIZE_PENDING_INTENT_MSG: { 1319 ((PendingIntentRecord)msg.obj).completeFinalize(); 1320 } break; 1321 case POST_HEAVY_NOTIFICATION_MSG: { 1322 INotificationManager inm = NotificationManager.getService(); 1323 if (inm == null) { 1324 return; 1325 } 1326 1327 ActivityRecord root = (ActivityRecord)msg.obj; 1328 ProcessRecord process = root.app; 1329 if (process == null) { 1330 return; 1331 } 1332 1333 try { 1334 Context context = mContext.createPackageContext(process.info.packageName, 0); 1335 String text = mContext.getString(R.string.heavy_weight_notification, 1336 context.getApplicationInfo().loadLabel(context.getPackageManager())); 1337 Notification notification = new Notification(); 1338 notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon; 1339 notification.when = 0; 1340 notification.flags = Notification.FLAG_ONGOING_EVENT; 1341 notification.tickerText = text; 1342 notification.defaults = 0; // please be quiet 1343 notification.sound = null; 1344 notification.vibrate = null; 1345 notification.setLatestEventInfo(context, text, 1346 mContext.getText(R.string.heavy_weight_notification_detail), 1347 PendingIntent.getActivityAsUser(mContext, 0, root.intent, 1348 PendingIntent.FLAG_CANCEL_CURRENT, null, 1349 new UserHandle(root.userId))); 1350 1351 try { 1352 int[] outId = new int[1]; 1353 inm.enqueueNotificationWithTag("android", "android", null, 1354 R.string.heavy_weight_notification, 1355 notification, outId, root.userId); 1356 } catch (RuntimeException e) { 1357 Slog.w(ActivityManagerService.TAG, 1358 "Error showing notification for heavy-weight app", e); 1359 } catch (RemoteException e) { 1360 } 1361 } catch (NameNotFoundException e) { 1362 Slog.w(TAG, "Unable to create context for heavy notification", e); 1363 } 1364 } break; 1365 case CANCEL_HEAVY_NOTIFICATION_MSG: { 1366 INotificationManager inm = NotificationManager.getService(); 1367 if (inm == null) { 1368 return; 1369 } 1370 try { 1371 inm.cancelNotificationWithTag("android", null, 1372 R.string.heavy_weight_notification, msg.arg1); 1373 } catch (RuntimeException e) { 1374 Slog.w(ActivityManagerService.TAG, 1375 "Error canceling notification for service", e); 1376 } catch (RemoteException e) { 1377 } 1378 } break; 1379 case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: { 1380 synchronized (ActivityManagerService.this) { 1381 checkExcessivePowerUsageLocked(true); 1382 removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1383 Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1384 sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 1385 } 1386 } break; 1387 case SHOW_COMPAT_MODE_DIALOG_MSG: { 1388 synchronized (ActivityManagerService.this) { 1389 ActivityRecord ar = (ActivityRecord)msg.obj; 1390 if (mCompatModeDialog != null) { 1391 if (mCompatModeDialog.mAppInfo.packageName.equals( 1392 ar.info.applicationInfo.packageName)) { 1393 return; 1394 } 1395 mCompatModeDialog.dismiss(); 1396 mCompatModeDialog = null; 1397 } 1398 if (ar != null && false) { 1399 if (mCompatModePackages.getPackageAskCompatModeLocked( 1400 ar.packageName)) { 1401 int mode = mCompatModePackages.computeCompatModeLocked( 1402 ar.info.applicationInfo); 1403 if (mode == ActivityManager.COMPAT_MODE_DISABLED 1404 || mode == ActivityManager.COMPAT_MODE_ENABLED) { 1405 mCompatModeDialog = new CompatModeDialog( 1406 ActivityManagerService.this, mContext, 1407 ar.info.applicationInfo); 1408 mCompatModeDialog.show(); 1409 } 1410 } 1411 } 1412 } 1413 break; 1414 } 1415 case DISPATCH_PROCESSES_CHANGED: { 1416 dispatchProcessesChanged(); 1417 break; 1418 } 1419 case DISPATCH_PROCESS_DIED: { 1420 final int pid = msg.arg1; 1421 final int uid = msg.arg2; 1422 dispatchProcessDied(pid, uid); 1423 break; 1424 } 1425 case REPORT_MEM_USAGE_MSG: { 1426 final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj; 1427 Thread thread = new Thread() { 1428 @Override public void run() { 1429 final SparseArray<ProcessMemInfo> infoMap 1430 = new SparseArray<ProcessMemInfo>(memInfos.size()); 1431 for (int i=0, N=memInfos.size(); i<N; i++) { 1432 ProcessMemInfo mi = memInfos.get(i); 1433 infoMap.put(mi.pid, mi); 1434 } 1435 updateCpuStatsNow(); 1436 synchronized (mProcessCpuThread) { 1437 final int N = mProcessCpuTracker.countStats(); 1438 for (int i=0; i<N; i++) { 1439 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 1440 if (st.vsize > 0) { 1441 long pss = Debug.getPss(st.pid, null); 1442 if (pss > 0) { 1443 if (infoMap.indexOfKey(st.pid) < 0) { 1444 ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid, 1445 ProcessList.NATIVE_ADJ, -1, "native", null); 1446 mi.pss = pss; 1447 memInfos.add(mi); 1448 } 1449 } 1450 } 1451 } 1452 } 1453 1454 long totalPss = 0; 1455 for (int i=0, N=memInfos.size(); i<N; i++) { 1456 ProcessMemInfo mi = memInfos.get(i); 1457 if (mi.pss == 0) { 1458 mi.pss = Debug.getPss(mi.pid, null); 1459 } 1460 totalPss += mi.pss; 1461 } 1462 Collections.sort(memInfos, new Comparator<ProcessMemInfo>() { 1463 @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) { 1464 if (lhs.oomAdj != rhs.oomAdj) { 1465 return lhs.oomAdj < rhs.oomAdj ? -1 : 1; 1466 } 1467 if (lhs.pss != rhs.pss) { 1468 return lhs.pss < rhs.pss ? 1 : -1; 1469 } 1470 return 0; 1471 } 1472 }); 1473 1474 StringBuilder tag = new StringBuilder(128); 1475 StringBuilder stack = new StringBuilder(128); 1476 tag.append("Low on memory -- "); 1477 appendMemBucket(tag, totalPss, "total", false); 1478 appendMemBucket(stack, totalPss, "total", true); 1479 1480 StringBuilder logBuilder = new StringBuilder(1024); 1481 logBuilder.append("Low on memory:\n"); 1482 1483 boolean firstLine = true; 1484 int lastOomAdj = Integer.MIN_VALUE; 1485 for (int i=0, N=memInfos.size(); i<N; i++) { 1486 ProcessMemInfo mi = memInfos.get(i); 1487 1488 if (mi.oomAdj != ProcessList.NATIVE_ADJ 1489 && (mi.oomAdj < ProcessList.SERVICE_ADJ 1490 || mi.oomAdj == ProcessList.HOME_APP_ADJ 1491 || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) { 1492 if (lastOomAdj != mi.oomAdj) { 1493 lastOomAdj = mi.oomAdj; 1494 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) { 1495 tag.append(" / "); 1496 } 1497 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) { 1498 if (firstLine) { 1499 stack.append(":"); 1500 firstLine = false; 1501 } 1502 stack.append("\n\t at "); 1503 } else { 1504 stack.append("$"); 1505 } 1506 } else { 1507 tag.append(" "); 1508 stack.append("$"); 1509 } 1510 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) { 1511 appendMemBucket(tag, mi.pss, mi.name, false); 1512 } 1513 appendMemBucket(stack, mi.pss, mi.name, true); 1514 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ 1515 && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) { 1516 stack.append("("); 1517 for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) { 1518 if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) { 1519 stack.append(DUMP_MEM_OOM_LABEL[k]); 1520 stack.append(":"); 1521 stack.append(DUMP_MEM_OOM_ADJ[k]); 1522 } 1523 } 1524 stack.append(")"); 1525 } 1526 } 1527 1528 logBuilder.append(" "); 1529 logBuilder.append(ProcessList.makeOomAdjString(mi.oomAdj)); 1530 logBuilder.append(' '); 1531 logBuilder.append(ProcessList.makeProcStateString(mi.procState)); 1532 logBuilder.append(' '); 1533 ProcessList.appendRamKb(logBuilder, mi.pss); 1534 logBuilder.append(" kB: "); 1535 logBuilder.append(mi.name); 1536 logBuilder.append(" ("); 1537 logBuilder.append(mi.pid); 1538 logBuilder.append(") "); 1539 logBuilder.append(mi.adjType); 1540 logBuilder.append('\n'); 1541 if (mi.adjReason != null) { 1542 logBuilder.append(" "); 1543 logBuilder.append(mi.adjReason); 1544 logBuilder.append('\n'); 1545 } 1546 } 1547 1548 logBuilder.append(" "); 1549 ProcessList.appendRamKb(logBuilder, totalPss); 1550 logBuilder.append(" kB: TOTAL\n"); 1551 1552 long[] infos = new long[Debug.MEMINFO_COUNT]; 1553 Debug.getMemInfo(infos); 1554 logBuilder.append(" MemInfo: "); 1555 logBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, "); 1556 logBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, "); 1557 logBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, "); 1558 logBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, "); 1559 logBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n"); 1560 if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) { 1561 logBuilder.append(" ZRAM: "); 1562 logBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]); 1563 logBuilder.append(" kB RAM, "); 1564 logBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]); 1565 logBuilder.append(" kB swap total, "); 1566 logBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]); 1567 logBuilder.append(" kB swap free\n"); 1568 } 1569 Slog.i(TAG, logBuilder.toString()); 1570 1571 StringBuilder dropBuilder = new StringBuilder(1024); 1572 /* 1573 StringWriter oomSw = new StringWriter(); 1574 PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256); 1575 StringWriter catSw = new StringWriter(); 1576 PrintWriter catPw = new FastPrintWriter(catSw, false, 256); 1577 String[] emptyArgs = new String[] { }; 1578 dumpApplicationMemoryUsage(null, oomPw, " ", emptyArgs, true, catPw); 1579 oomPw.flush(); 1580 String oomString = oomSw.toString(); 1581 */ 1582 dropBuilder.append(stack); 1583 dropBuilder.append('\n'); 1584 dropBuilder.append('\n'); 1585 dropBuilder.append(logBuilder); 1586 dropBuilder.append('\n'); 1587 /* 1588 dropBuilder.append(oomString); 1589 dropBuilder.append('\n'); 1590 */ 1591 StringWriter catSw = new StringWriter(); 1592 synchronized (ActivityManagerService.this) { 1593 PrintWriter catPw = new FastPrintWriter(catSw, false, 256); 1594 String[] emptyArgs = new String[] { }; 1595 catPw.println(); 1596 dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null); 1597 catPw.println(); 1598 mServices.dumpServicesLocked(null, catPw, emptyArgs, 0, 1599 false, false, null); 1600 catPw.println(); 1601 dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null); 1602 catPw.flush(); 1603 } 1604 dropBuilder.append(catSw.toString()); 1605 addErrorToDropBox("lowmem", null, "system_server", null, 1606 null, tag.toString(), dropBuilder.toString(), null, null); 1607 //Slog.i(TAG, "Sent to dropbox:"); 1608 //Slog.i(TAG, dropBuilder.toString()); 1609 synchronized (ActivityManagerService.this) { 1610 long now = SystemClock.uptimeMillis(); 1611 if (mLastMemUsageReportTime < now) { 1612 mLastMemUsageReportTime = now; 1613 } 1614 } 1615 } 1616 }; 1617 thread.start(); 1618 break; 1619 } 1620 case REPORT_USER_SWITCH_MSG: { 1621 dispatchUserSwitch((UserStartedState)msg.obj, msg.arg1, msg.arg2); 1622 break; 1623 } 1624 case CONTINUE_USER_SWITCH_MSG: { 1625 continueUserSwitch((UserStartedState)msg.obj, msg.arg1, msg.arg2); 1626 break; 1627 } 1628 case USER_SWITCH_TIMEOUT_MSG: { 1629 timeoutUserSwitch((UserStartedState)msg.obj, msg.arg1, msg.arg2); 1630 break; 1631 } 1632 case IMMERSIVE_MODE_LOCK_MSG: { 1633 final boolean nextState = (msg.arg1 != 0); 1634 if (mUpdateLock.isHeld() != nextState) { 1635 if (DEBUG_IMMERSIVE) { 1636 final ActivityRecord r = (ActivityRecord) msg.obj; 1637 Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r); 1638 } 1639 if (nextState) { 1640 mUpdateLock.acquire(); 1641 } else { 1642 mUpdateLock.release(); 1643 } 1644 } 1645 break; 1646 } 1647 case PERSIST_URI_GRANTS_MSG: { 1648 writeGrantedUriPermissions(); 1649 break; 1650 } 1651 case REQUEST_ALL_PSS_MSG: { 1652 requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false); 1653 break; 1654 } 1655 } 1656 } 1657 }; 1658 1659 static final int COLLECT_PSS_BG_MSG = 1; 1660 1661 final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) { 1662 @Override 1663 public void handleMessage(Message msg) { 1664 switch (msg.what) { 1665 case COLLECT_PSS_BG_MSG: { 1666 int i=0, num=0; 1667 long start = SystemClock.uptimeMillis(); 1668 long[] tmp = new long[1]; 1669 do { 1670 ProcessRecord proc; 1671 int procState; 1672 int pid; 1673 synchronized (ActivityManagerService.this) { 1674 if (i >= mPendingPssProcesses.size()) { 1675 if (DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num + " of " + i 1676 + " processes in " + (SystemClock.uptimeMillis()-start) + "ms"); 1677 mPendingPssProcesses.clear(); 1678 return; 1679 } 1680 proc = mPendingPssProcesses.get(i); 1681 procState = proc.pssProcState; 1682 if (proc.thread != null && procState == proc.setProcState) { 1683 pid = proc.pid; 1684 } else { 1685 proc = null; 1686 pid = 0; 1687 } 1688 i++; 1689 } 1690 if (proc != null) { 1691 long pss = Debug.getPss(pid, tmp); 1692 synchronized (ActivityManagerService.this) { 1693 if (proc.thread != null && proc.setProcState == procState 1694 && proc.pid == pid) { 1695 num++; 1696 proc.lastPssTime = SystemClock.uptimeMillis(); 1697 proc.baseProcessTracker.addPss(pss, tmp[0], true, proc.pkgList); 1698 if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString() 1699 + ": " + pss + " lastPss=" + proc.lastPss 1700 + " state=" + ProcessList.makeProcStateString(procState)); 1701 if (proc.initialIdlePss == 0) { 1702 proc.initialIdlePss = pss; 1703 } 1704 proc.lastPss = pss; 1705 if (procState >= ActivityManager.PROCESS_STATE_HOME) { 1706 proc.lastCachedPss = pss; 1707 } 1708 } 1709 } 1710 } 1711 } while (true); 1712 } 1713 } 1714 } 1715 }; 1716 1717 public void setSystemProcess() { 1718 try { 1719 ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true); 1720 ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats); 1721 ServiceManager.addService("meminfo", new MemBinder(this)); 1722 ServiceManager.addService("gfxinfo", new GraphicsBinder(this)); 1723 ServiceManager.addService("dbinfo", new DbBinder(this)); 1724 if (MONITOR_CPU_USAGE) { 1725 ServiceManager.addService("cpuinfo", new CpuBinder(this)); 1726 } 1727 ServiceManager.addService("permission", new PermissionController(this)); 1728 1729 ApplicationInfo info = mContext.getPackageManager().getApplicationInfo( 1730 "android", STOCK_PM_FLAGS); 1731 mSystemThread.installSystemApplicationInfo(info); 1732 1733 synchronized (this) { 1734 ProcessRecord app = newProcessRecordLocked(info, info.processName, false); 1735 app.persistent = true; 1736 app.pid = MY_PID; 1737 app.maxAdj = ProcessList.SYSTEM_ADJ; 1738 app.makeActive(mSystemThread.getApplicationThread(), mProcessStats); 1739 mProcessNames.put(app.processName, app.uid, app); 1740 synchronized (mPidsSelfLocked) { 1741 mPidsSelfLocked.put(app.pid, app); 1742 } 1743 updateLruProcessLocked(app, false, null); 1744 updateOomAdjLocked(); 1745 } 1746 } catch (PackageManager.NameNotFoundException e) { 1747 throw new RuntimeException( 1748 "Unable to find android system package", e); 1749 } 1750 } 1751 1752 public void setWindowManager(WindowManagerService wm) { 1753 mWindowManager = wm; 1754 mStackSupervisor.setWindowManager(wm); 1755 } 1756 1757 public void startObservingNativeCrashes() { 1758 final NativeCrashListener ncl = new NativeCrashListener(this); 1759 ncl.start(); 1760 } 1761 1762 public IAppOpsService getAppOpsService() { 1763 return mAppOpsService; 1764 } 1765 1766 static class MemBinder extends Binder { 1767 ActivityManagerService mActivityManagerService; 1768 MemBinder(ActivityManagerService activityManagerService) { 1769 mActivityManagerService = activityManagerService; 1770 } 1771 1772 @Override 1773 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1774 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1775 != PackageManager.PERMISSION_GRANTED) { 1776 pw.println("Permission Denial: can't dump meminfo from from pid=" 1777 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1778 + " without permission " + android.Manifest.permission.DUMP); 1779 return; 1780 } 1781 1782 mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, " ", args, false, null); 1783 } 1784 } 1785 1786 static class GraphicsBinder extends Binder { 1787 ActivityManagerService mActivityManagerService; 1788 GraphicsBinder(ActivityManagerService activityManagerService) { 1789 mActivityManagerService = activityManagerService; 1790 } 1791 1792 @Override 1793 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1794 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1795 != PackageManager.PERMISSION_GRANTED) { 1796 pw.println("Permission Denial: can't dump gfxinfo from from pid=" 1797 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1798 + " without permission " + android.Manifest.permission.DUMP); 1799 return; 1800 } 1801 1802 mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args); 1803 } 1804 } 1805 1806 static class DbBinder extends Binder { 1807 ActivityManagerService mActivityManagerService; 1808 DbBinder(ActivityManagerService activityManagerService) { 1809 mActivityManagerService = activityManagerService; 1810 } 1811 1812 @Override 1813 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1814 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1815 != PackageManager.PERMISSION_GRANTED) { 1816 pw.println("Permission Denial: can't dump dbinfo from from pid=" 1817 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1818 + " without permission " + android.Manifest.permission.DUMP); 1819 return; 1820 } 1821 1822 mActivityManagerService.dumpDbInfo(fd, pw, args); 1823 } 1824 } 1825 1826 static class CpuBinder extends Binder { 1827 ActivityManagerService mActivityManagerService; 1828 CpuBinder(ActivityManagerService activityManagerService) { 1829 mActivityManagerService = activityManagerService; 1830 } 1831 1832 @Override 1833 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1834 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1835 != PackageManager.PERMISSION_GRANTED) { 1836 pw.println("Permission Denial: can't dump cpuinfo from from pid=" 1837 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1838 + " without permission " + android.Manifest.permission.DUMP); 1839 return; 1840 } 1841 1842 synchronized (mActivityManagerService.mProcessCpuThread) { 1843 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad()); 1844 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState( 1845 SystemClock.uptimeMillis())); 1846 } 1847 } 1848 } 1849 1850 public static final class Lifecycle extends SystemService { 1851 private final ActivityManagerService mService; 1852 1853 public Lifecycle(Context context) { 1854 super(context); 1855 mService = new ActivityManagerService(context); 1856 } 1857 1858 @Override 1859 public void onStart() { 1860 mService.start(); 1861 } 1862 1863 public ActivityManagerService getService() { 1864 return mService; 1865 } 1866 } 1867 1868 // Note: This method is invoked on the main thread but may need to attach various 1869 // handlers to other threads. So take care to be explicit about the looper. 1870 public ActivityManagerService(Context systemContext) { 1871 mContext = systemContext; 1872 mFactoryTest = FactoryTest.getMode(); 1873 mSystemThread = ActivityThread.currentActivityThread(); 1874 1875 Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass()); 1876 1877 mHandlerThread = new ServiceThread(TAG, 1878 android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/); 1879 mHandlerThread.start(); 1880 mHandler = new MainHandler(mHandlerThread.getLooper()); 1881 1882 mFgBroadcastQueue = new BroadcastQueue(this, mHandler, 1883 "foreground", BROADCAST_FG_TIMEOUT, false); 1884 mBgBroadcastQueue = new BroadcastQueue(this, mHandler, 1885 "background", BROADCAST_BG_TIMEOUT, true); 1886 mBroadcastQueues[0] = mFgBroadcastQueue; 1887 mBroadcastQueues[1] = mBgBroadcastQueue; 1888 1889 mServices = new ActiveServices(this); 1890 mProviderMap = new ProviderMap(this); 1891 1892 // TODO: Move creation of battery stats service outside of activity manager service. 1893 File dataDir = Environment.getDataDirectory(); 1894 File systemDir = new File(dataDir, "system"); 1895 systemDir.mkdirs(); 1896 mBatteryStatsService = new BatteryStatsService(new File( 1897 systemDir, "batterystats.bin").toString(), mHandler); 1898 mBatteryStatsService.getActiveStatistics().readLocked(); 1899 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 1900 mOnBattery = DEBUG_POWER ? true 1901 : mBatteryStatsService.getActiveStatistics().getIsOnBattery(); 1902 mBatteryStatsService.getActiveStatistics().setCallback(this); 1903 1904 mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats")); 1905 1906 mUsageStatsService = new UsageStatsService(new File(systemDir, "usagestats").toString()); 1907 mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler); 1908 1909 mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml")); 1910 1911 // User 0 is the first and only user that runs at boot. 1912 mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true)); 1913 mUserLru.add(Integer.valueOf(0)); 1914 updateStartedUserArrayLocked(); 1915 1916 GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version", 1917 ConfigurationInfo.GL_ES_VERSION_UNDEFINED); 1918 1919 mConfiguration.setToDefaults(); 1920 mConfiguration.setLocale(Locale.getDefault()); 1921 1922 mConfigurationSeq = mConfiguration.seq = 1; 1923 mProcessCpuTracker.init(); 1924 1925 mHasRecents = mContext.getResources().getBoolean( 1926 com.android.internal.R.bool.config_hasRecents); 1927 1928 mCompatModePackages = new CompatModePackages(this, systemDir, mHandler); 1929 mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler); 1930 mStackSupervisor = new ActivityStackSupervisor(this); 1931 1932 mProcessCpuThread = new Thread("CpuTracker") { 1933 @Override 1934 public void run() { 1935 while (true) { 1936 try { 1937 try { 1938 synchronized(this) { 1939 final long now = SystemClock.uptimeMillis(); 1940 long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now; 1941 long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now; 1942 //Slog.i(TAG, "Cpu delay=" + nextCpuDelay 1943 // + ", write delay=" + nextWriteDelay); 1944 if (nextWriteDelay < nextCpuDelay) { 1945 nextCpuDelay = nextWriteDelay; 1946 } 1947 if (nextCpuDelay > 0) { 1948 mProcessCpuMutexFree.set(true); 1949 this.wait(nextCpuDelay); 1950 } 1951 } 1952 } catch (InterruptedException e) { 1953 } 1954 updateCpuStatsNow(); 1955 } catch (Exception e) { 1956 Slog.e(TAG, "Unexpected exception collecting process stats", e); 1957 } 1958 } 1959 } 1960 }; 1961 1962 Watchdog.getInstance().addMonitor(this); 1963 Watchdog.getInstance().addThread(mHandler); 1964 } 1965 1966 private void start() { 1967 mProcessCpuThread.start(); 1968 1969 mBatteryStatsService.publish(mContext); 1970 mUsageStatsService.publish(mContext); 1971 mAppOpsService.publish(mContext); 1972 1973 LocalServices.addService(ActivityManagerInternal.class, new LocalService()); 1974 } 1975 1976 @Override 1977 public boolean onTransact(int code, Parcel data, Parcel reply, int flags) 1978 throws RemoteException { 1979 if (code == SYSPROPS_TRANSACTION) { 1980 // We need to tell all apps about the system property change. 1981 ArrayList<IBinder> procs = new ArrayList<IBinder>(); 1982 synchronized(this) { 1983 final int NP = mProcessNames.getMap().size(); 1984 for (int ip=0; ip<NP; ip++) { 1985 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 1986 final int NA = apps.size(); 1987 for (int ia=0; ia<NA; ia++) { 1988 ProcessRecord app = apps.valueAt(ia); 1989 if (app.thread != null) { 1990 procs.add(app.thread.asBinder()); 1991 } 1992 } 1993 } 1994 } 1995 1996 int N = procs.size(); 1997 for (int i=0; i<N; i++) { 1998 Parcel data2 = Parcel.obtain(); 1999 try { 2000 procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0); 2001 } catch (RemoteException e) { 2002 } 2003 data2.recycle(); 2004 } 2005 } 2006 try { 2007 return super.onTransact(code, data, reply, flags); 2008 } catch (RuntimeException e) { 2009 // The activity manager only throws security exceptions, so let's 2010 // log all others. 2011 if (!(e instanceof SecurityException)) { 2012 Slog.wtf(TAG, "Activity Manager Crash", e); 2013 } 2014 throw e; 2015 } 2016 } 2017 2018 void updateCpuStats() { 2019 final long now = SystemClock.uptimeMillis(); 2020 if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) { 2021 return; 2022 } 2023 if (mProcessCpuMutexFree.compareAndSet(true, false)) { 2024 synchronized (mProcessCpuThread) { 2025 mProcessCpuThread.notify(); 2026 } 2027 } 2028 } 2029 2030 void updateCpuStatsNow() { 2031 synchronized (mProcessCpuThread) { 2032 mProcessCpuMutexFree.set(false); 2033 final long now = SystemClock.uptimeMillis(); 2034 boolean haveNewCpuStats = false; 2035 2036 if (MONITOR_CPU_USAGE && 2037 mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) { 2038 mLastCpuTime.set(now); 2039 haveNewCpuStats = true; 2040 mProcessCpuTracker.update(); 2041 //Slog.i(TAG, mProcessCpu.printCurrentState()); 2042 //Slog.i(TAG, "Total CPU usage: " 2043 // + mProcessCpu.getTotalCpuPercent() + "%"); 2044 2045 // Slog the cpu usage if the property is set. 2046 if ("true".equals(SystemProperties.get("events.cpu"))) { 2047 int user = mProcessCpuTracker.getLastUserTime(); 2048 int system = mProcessCpuTracker.getLastSystemTime(); 2049 int iowait = mProcessCpuTracker.getLastIoWaitTime(); 2050 int irq = mProcessCpuTracker.getLastIrqTime(); 2051 int softIrq = mProcessCpuTracker.getLastSoftIrqTime(); 2052 int idle = mProcessCpuTracker.getLastIdleTime(); 2053 2054 int total = user + system + iowait + irq + softIrq + idle; 2055 if (total == 0) total = 1; 2056 2057 EventLog.writeEvent(EventLogTags.CPU, 2058 ((user+system+iowait+irq+softIrq) * 100) / total, 2059 (user * 100) / total, 2060 (system * 100) / total, 2061 (iowait * 100) / total, 2062 (irq * 100) / total, 2063 (softIrq * 100) / total); 2064 } 2065 } 2066 2067 long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes(); 2068 final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics(); 2069 synchronized(bstats) { 2070 synchronized(mPidsSelfLocked) { 2071 if (haveNewCpuStats) { 2072 if (mOnBattery) { 2073 int perc = bstats.startAddingCpuLocked(); 2074 int totalUTime = 0; 2075 int totalSTime = 0; 2076 final int N = mProcessCpuTracker.countStats(); 2077 for (int i=0; i<N; i++) { 2078 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 2079 if (!st.working) { 2080 continue; 2081 } 2082 ProcessRecord pr = mPidsSelfLocked.get(st.pid); 2083 int otherUTime = (st.rel_utime*perc)/100; 2084 int otherSTime = (st.rel_stime*perc)/100; 2085 totalUTime += otherUTime; 2086 totalSTime += otherSTime; 2087 if (pr != null) { 2088 BatteryStatsImpl.Uid.Proc ps = bstats.getProcessStatsLocked( 2089 st.name, st.pid); 2090 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 2091 st.rel_stime-otherSTime); 2092 ps.addSpeedStepTimes(cpuSpeedTimes); 2093 pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10; 2094 } else if (st.uid >= Process.FIRST_APPLICATION_UID) { 2095 BatteryStatsImpl.Uid.Proc ps = st.batteryStats; 2096 if (ps == null) { 2097 st.batteryStats = ps = bstats.getProcessStatsLocked(st.uid, 2098 "(Unknown)"); 2099 } 2100 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 2101 st.rel_stime-otherSTime); 2102 ps.addSpeedStepTimes(cpuSpeedTimes); 2103 } else { 2104 BatteryStatsImpl.Uid.Proc ps = 2105 bstats.getProcessStatsLocked(st.name, st.pid); 2106 if (ps != null) { 2107 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 2108 st.rel_stime-otherSTime); 2109 ps.addSpeedStepTimes(cpuSpeedTimes); 2110 } 2111 } 2112 } 2113 bstats.finishAddingCpuLocked(perc, totalUTime, 2114 totalSTime, cpuSpeedTimes); 2115 } 2116 } 2117 } 2118 2119 if (mLastWriteTime < (now-BATTERY_STATS_TIME)) { 2120 mLastWriteTime = now; 2121 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 2122 } 2123 } 2124 } 2125 } 2126 2127 @Override 2128 public void batteryNeedsCpuUpdate() { 2129 updateCpuStatsNow(); 2130 } 2131 2132 @Override 2133 public void batteryPowerChanged(boolean onBattery) { 2134 // When plugging in, update the CPU stats first before changing 2135 // the plug state. 2136 updateCpuStatsNow(); 2137 synchronized (this) { 2138 synchronized(mPidsSelfLocked) { 2139 mOnBattery = DEBUG_POWER ? true : onBattery; 2140 } 2141 } 2142 } 2143 2144 /** 2145 * Initialize the application bind args. These are passed to each 2146 * process when the bindApplication() IPC is sent to the process. They're 2147 * lazily setup to make sure the services are running when they're asked for. 2148 */ 2149 private HashMap<String, IBinder> getCommonServicesLocked() { 2150 if (mAppBindArgs == null) { 2151 mAppBindArgs = new HashMap<String, IBinder>(); 2152 2153 // Setup the application init args 2154 mAppBindArgs.put("package", ServiceManager.getService("package")); 2155 mAppBindArgs.put("window", ServiceManager.getService("window")); 2156 mAppBindArgs.put(Context.ALARM_SERVICE, 2157 ServiceManager.getService(Context.ALARM_SERVICE)); 2158 } 2159 return mAppBindArgs; 2160 } 2161 2162 final void setFocusedActivityLocked(ActivityRecord r) { 2163 if (mFocusedActivity != r) { 2164 if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r); 2165 mFocusedActivity = r; 2166 mStackSupervisor.setFocusedStack(r); 2167 if (r != null) { 2168 mWindowManager.setFocusedApp(r.appToken, true); 2169 } 2170 applyUpdateLockStateLocked(r); 2171 } 2172 } 2173 2174 @Override 2175 public void setFocusedStack(int stackId) { 2176 if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId); 2177 synchronized (ActivityManagerService.this) { 2178 ActivityStack stack = mStackSupervisor.getStack(stackId); 2179 if (stack != null) { 2180 ActivityRecord r = stack.topRunningActivityLocked(null); 2181 if (r != null) { 2182 setFocusedActivityLocked(r); 2183 } 2184 } 2185 } 2186 } 2187 2188 @Override 2189 public void notifyActivityDrawn(IBinder token) { 2190 if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token); 2191 synchronized (this) { 2192 ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token); 2193 if (r != null) { 2194 r.task.stack.notifyActivityDrawnLocked(r); 2195 } 2196 } 2197 } 2198 2199 final void applyUpdateLockStateLocked(ActivityRecord r) { 2200 // Modifications to the UpdateLock state are done on our handler, outside 2201 // the activity manager's locks. The new state is determined based on the 2202 // state *now* of the relevant activity record. The object is passed to 2203 // the handler solely for logging detail, not to be consulted/modified. 2204 final boolean nextState = r != null && r.immersive; 2205 mHandler.sendMessage( 2206 mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r)); 2207 } 2208 2209 final void showAskCompatModeDialogLocked(ActivityRecord r) { 2210 Message msg = Message.obtain(); 2211 msg.what = SHOW_COMPAT_MODE_DIALOG_MSG; 2212 msg.obj = r.task.askedCompatMode ? null : r; 2213 mHandler.sendMessage(msg); 2214 } 2215 2216 private final int updateLruProcessInternalLocked(ProcessRecord app, long now, int index, 2217 String what, Object obj, ProcessRecord srcApp) { 2218 app.lastActivityTime = now; 2219 2220 if (app.activities.size() > 0) { 2221 // Don't want to touch dependent processes that are hosting activities. 2222 return index; 2223 } 2224 2225 int lrui = mLruProcesses.lastIndexOf(app); 2226 if (lrui < 0) { 2227 Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: " 2228 + what + " " + obj + " from " + srcApp); 2229 return index; 2230 } 2231 2232 if (lrui >= index) { 2233 // Don't want to cause this to move dependent processes *back* in the 2234 // list as if they were less frequently used. 2235 return index; 2236 } 2237 2238 if (lrui >= mLruProcessActivityStart) { 2239 // Don't want to touch dependent processes that are hosting activities. 2240 return index; 2241 } 2242 2243 mLruProcesses.remove(lrui); 2244 if (index > 0) { 2245 index--; 2246 } 2247 if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index 2248 + " in LRU list: " + app); 2249 mLruProcesses.add(index, app); 2250 return index; 2251 } 2252 2253 final void removeLruProcessLocked(ProcessRecord app) { 2254 int lrui = mLruProcesses.lastIndexOf(app); 2255 if (lrui >= 0) { 2256 if (lrui <= mLruProcessActivityStart) { 2257 mLruProcessActivityStart--; 2258 } 2259 if (lrui <= mLruProcessServiceStart) { 2260 mLruProcessServiceStart--; 2261 } 2262 mLruProcesses.remove(lrui); 2263 } 2264 } 2265 2266 final void updateLruProcessLocked(ProcessRecord app, boolean activityChange, 2267 ProcessRecord client) { 2268 final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities; 2269 final boolean hasService = false; // not impl yet. app.services.size() > 0; 2270 if (!activityChange && hasActivity) { 2271 // The process has activties, so we are only going to allow activity-based 2272 // adjustments move it. It should be kept in the front of the list with other 2273 // processes that have activities, and we don't want those to change their 2274 // order except due to activity operations. 2275 return; 2276 } 2277 2278 mLruSeq++; 2279 final long now = SystemClock.uptimeMillis(); 2280 app.lastActivityTime = now; 2281 2282 // First a quick reject: if the app is already at the position we will 2283 // put it, then there is nothing to do. 2284 if (hasActivity) { 2285 final int N = mLruProcesses.size(); 2286 if (N > 0 && mLruProcesses.get(N-1) == app) { 2287 if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app); 2288 return; 2289 } 2290 } else { 2291 if (mLruProcessServiceStart > 0 2292 && mLruProcesses.get(mLruProcessServiceStart-1) == app) { 2293 if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app); 2294 return; 2295 } 2296 } 2297 2298 int lrui = mLruProcesses.lastIndexOf(app); 2299 2300 if (app.persistent && lrui >= 0) { 2301 // We don't care about the position of persistent processes, as long as 2302 // they are in the list. 2303 if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app); 2304 return; 2305 } 2306 2307 /* In progress: compute new position first, so we can avoid doing work 2308 if the process is not actually going to move. Not yet working. 2309 int addIndex; 2310 int nextIndex; 2311 boolean inActivity = false, inService = false; 2312 if (hasActivity) { 2313 // Process has activities, put it at the very tipsy-top. 2314 addIndex = mLruProcesses.size(); 2315 nextIndex = mLruProcessServiceStart; 2316 inActivity = true; 2317 } else if (hasService) { 2318 // Process has services, put it at the top of the service list. 2319 addIndex = mLruProcessActivityStart; 2320 nextIndex = mLruProcessServiceStart; 2321 inActivity = true; 2322 inService = true; 2323 } else { 2324 // Process not otherwise of interest, it goes to the top of the non-service area. 2325 addIndex = mLruProcessServiceStart; 2326 if (client != null) { 2327 int clientIndex = mLruProcesses.lastIndexOf(client); 2328 if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating " 2329 + app); 2330 if (clientIndex >= 0 && addIndex > clientIndex) { 2331 addIndex = clientIndex; 2332 } 2333 } 2334 nextIndex = addIndex > 0 ? addIndex-1 : addIndex; 2335 } 2336 2337 Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act=" 2338 + mLruProcessActivityStart + "): " + app); 2339 */ 2340 2341 if (lrui >= 0) { 2342 if (lrui < mLruProcessActivityStart) { 2343 mLruProcessActivityStart--; 2344 } 2345 if (lrui < mLruProcessServiceStart) { 2346 mLruProcessServiceStart--; 2347 } 2348 /* 2349 if (addIndex > lrui) { 2350 addIndex--; 2351 } 2352 if (nextIndex > lrui) { 2353 nextIndex--; 2354 } 2355 */ 2356 mLruProcesses.remove(lrui); 2357 } 2358 2359 /* 2360 mLruProcesses.add(addIndex, app); 2361 if (inActivity) { 2362 mLruProcessActivityStart++; 2363 } 2364 if (inService) { 2365 mLruProcessActivityStart++; 2366 } 2367 */ 2368 2369 int nextIndex; 2370 if (hasActivity) { 2371 final int N = mLruProcesses.size(); 2372 if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) { 2373 // Process doesn't have activities, but has clients with 2374 // activities... move it up, but one below the top (the top 2375 // should always have a real activity). 2376 if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app); 2377 mLruProcesses.add(N-1, app); 2378 // To keep it from spamming the LRU list (by making a bunch of clients), 2379 // we will push down any other entries owned by the app. 2380 final int uid = app.info.uid; 2381 for (int i=N-2; i>mLruProcessActivityStart; i--) { 2382 ProcessRecord subProc = mLruProcesses.get(i); 2383 if (subProc.info.uid == uid) { 2384 // We want to push this one down the list. If the process after 2385 // it is for the same uid, however, don't do so, because we don't 2386 // want them internally to be re-ordered. 2387 if (mLruProcesses.get(i-1).info.uid != uid) { 2388 if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i 2389 + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1)); 2390 ProcessRecord tmp = mLruProcesses.get(i); 2391 mLruProcesses.set(i, mLruProcesses.get(i-1)); 2392 mLruProcesses.set(i-1, tmp); 2393 i--; 2394 } 2395 } else { 2396 // A gap, we can stop here. 2397 break; 2398 } 2399 } 2400 } else { 2401 // Process has activities, put it at the very tipsy-top. 2402 if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app); 2403 mLruProcesses.add(app); 2404 } 2405 nextIndex = mLruProcessServiceStart; 2406 } else if (hasService) { 2407 // Process has services, put it at the top of the service list. 2408 if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app); 2409 mLruProcesses.add(mLruProcessActivityStart, app); 2410 nextIndex = mLruProcessServiceStart; 2411 mLruProcessActivityStart++; 2412 } else { 2413 // Process not otherwise of interest, it goes to the top of the non-service area. 2414 int index = mLruProcessServiceStart; 2415 if (client != null) { 2416 // If there is a client, don't allow the process to be moved up higher 2417 // in the list than that client. 2418 int clientIndex = mLruProcesses.lastIndexOf(client); 2419 if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client 2420 + " when updating " + app); 2421 if (clientIndex <= lrui) { 2422 // Don't allow the client index restriction to push it down farther in the 2423 // list than it already is. 2424 clientIndex = lrui; 2425 } 2426 if (clientIndex >= 0 && index > clientIndex) { 2427 index = clientIndex; 2428 } 2429 } 2430 if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app); 2431 mLruProcesses.add(index, app); 2432 nextIndex = index-1; 2433 mLruProcessActivityStart++; 2434 mLruProcessServiceStart++; 2435 } 2436 2437 // If the app is currently using a content provider or service, 2438 // bump those processes as well. 2439 for (int j=app.connections.size()-1; j>=0; j--) { 2440 ConnectionRecord cr = app.connections.valueAt(j); 2441 if (cr.binding != null && !cr.serviceDead && cr.binding.service != null 2442 && cr.binding.service.app != null 2443 && cr.binding.service.app.lruSeq != mLruSeq 2444 && !cr.binding.service.app.persistent) { 2445 nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex, 2446 "service connection", cr, app); 2447 } 2448 } 2449 for (int j=app.conProviders.size()-1; j>=0; j--) { 2450 ContentProviderRecord cpr = app.conProviders.get(j).provider; 2451 if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) { 2452 nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex, 2453 "provider reference", cpr, app); 2454 } 2455 } 2456 } 2457 2458 final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) { 2459 if (uid == Process.SYSTEM_UID) { 2460 // The system gets to run in any process. If there are multiple 2461 // processes with the same uid, just pick the first (this 2462 // should never happen). 2463 SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName); 2464 if (procs == null) return null; 2465 final int N = procs.size(); 2466 for (int i = 0; i < N; i++) { 2467 if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i); 2468 } 2469 } 2470 ProcessRecord proc = mProcessNames.get(processName, uid); 2471 if (false && proc != null && !keepIfLarge 2472 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY 2473 && proc.lastCachedPss >= 4000) { 2474 // Turn this condition on to cause killing to happen regularly, for testing. 2475 if (proc.baseProcessTracker != null) { 2476 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss); 2477 } 2478 killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss) 2479 + "k from cached"); 2480 } else if (proc != null && !keepIfLarge 2481 && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL 2482 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) { 2483 if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss); 2484 if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) { 2485 if (proc.baseProcessTracker != null) { 2486 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss); 2487 } 2488 killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss) 2489 + "k from cached"); 2490 } 2491 } 2492 return proc; 2493 } 2494 2495 void ensurePackageDexOpt(String packageName) { 2496 IPackageManager pm = AppGlobals.getPackageManager(); 2497 try { 2498 if (pm.performDexOpt(packageName)) { 2499 mDidDexOpt = true; 2500 } 2501 } catch (RemoteException e) { 2502 } 2503 } 2504 2505 boolean isNextTransitionForward() { 2506 int transit = mWindowManager.getPendingAppTransition(); 2507 return transit == AppTransition.TRANSIT_ACTIVITY_OPEN 2508 || transit == AppTransition.TRANSIT_TASK_OPEN 2509 || transit == AppTransition.TRANSIT_TASK_TO_FRONT; 2510 } 2511 2512 final ProcessRecord startProcessLocked(String processName, 2513 ApplicationInfo info, boolean knownToBeDead, int intentFlags, 2514 String hostingType, ComponentName hostingName, boolean allowWhileBooting, 2515 boolean isolated, boolean keepIfLarge) { 2516 ProcessRecord app; 2517 if (!isolated) { 2518 app = getProcessRecordLocked(processName, info.uid, keepIfLarge); 2519 } else { 2520 // If this is an isolated process, it can't re-use an existing process. 2521 app = null; 2522 } 2523 // We don't have to do anything more if: 2524 // (1) There is an existing application record; and 2525 // (2) The caller doesn't think it is dead, OR there is no thread 2526 // object attached to it so we know it couldn't have crashed; and 2527 // (3) There is a pid assigned to it, so it is either starting or 2528 // already running. 2529 if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName 2530 + " app=" + app + " knownToBeDead=" + knownToBeDead 2531 + " thread=" + (app != null ? app.thread : null) 2532 + " pid=" + (app != null ? app.pid : -1)); 2533 if (app != null && app.pid > 0) { 2534 if (!knownToBeDead || app.thread == null) { 2535 // We already have the app running, or are waiting for it to 2536 // come up (we have a pid but not yet its thread), so keep it. 2537 if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app); 2538 // If this is a new package in the process, add the package to the list 2539 app.addPackage(info.packageName, mProcessStats); 2540 return app; 2541 } 2542 2543 // An application record is attached to a previous process, 2544 // clean it up now. 2545 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app); 2546 handleAppDiedLocked(app, true, true); 2547 } 2548 2549 String hostingNameStr = hostingName != null 2550 ? hostingName.flattenToShortString() : null; 2551 2552 if (!isolated) { 2553 if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) { 2554 // If we are in the background, then check to see if this process 2555 // is bad. If so, we will just silently fail. 2556 if (mBadProcesses.get(info.processName, info.uid) != null) { 2557 if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid 2558 + "/" + info.processName); 2559 return null; 2560 } 2561 } else { 2562 // When the user is explicitly starting a process, then clear its 2563 // crash count so that we won't make it bad until they see at 2564 // least one crash dialog again, and make the process good again 2565 // if it had been bad. 2566 if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid 2567 + "/" + info.processName); 2568 mProcessCrashTimes.remove(info.processName, info.uid); 2569 if (mBadProcesses.get(info.processName, info.uid) != null) { 2570 EventLog.writeEvent(EventLogTags.AM_PROC_GOOD, 2571 UserHandle.getUserId(info.uid), info.uid, 2572 info.processName); 2573 mBadProcesses.remove(info.processName, info.uid); 2574 if (app != null) { 2575 app.bad = false; 2576 } 2577 } 2578 } 2579 } 2580 2581 if (app == null) { 2582 app = newProcessRecordLocked(info, processName, isolated); 2583 if (app == null) { 2584 Slog.w(TAG, "Failed making new process record for " 2585 + processName + "/" + info.uid + " isolated=" + isolated); 2586 return null; 2587 } 2588 mProcessNames.put(processName, app.uid, app); 2589 if (isolated) { 2590 mIsolatedProcesses.put(app.uid, app); 2591 } 2592 } else { 2593 // If this is a new package in the process, add the package to the list 2594 app.addPackage(info.packageName, mProcessStats); 2595 } 2596 2597 // If the system is not ready yet, then hold off on starting this 2598 // process until it is. 2599 if (!mProcessesReady 2600 && !isAllowedWhileBooting(info) 2601 && !allowWhileBooting) { 2602 if (!mProcessesOnHold.contains(app)) { 2603 mProcessesOnHold.add(app); 2604 } 2605 if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app); 2606 return app; 2607 } 2608 2609 startProcessLocked(app, hostingType, hostingNameStr); 2610 return (app.pid != 0) ? app : null; 2611 } 2612 2613 boolean isAllowedWhileBooting(ApplicationInfo ai) { 2614 return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0; 2615 } 2616 2617 private final void startProcessLocked(ProcessRecord app, 2618 String hostingType, String hostingNameStr) { 2619 if (app.pid > 0 && app.pid != MY_PID) { 2620 synchronized (mPidsSelfLocked) { 2621 mPidsSelfLocked.remove(app.pid); 2622 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 2623 } 2624 app.setPid(0); 2625 } 2626 2627 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 2628 "startProcessLocked removing on hold: " + app); 2629 mProcessesOnHold.remove(app); 2630 2631 updateCpuStats(); 2632 2633 try { 2634 int uid = app.uid; 2635 2636 int[] gids = null; 2637 int mountExternal = Zygote.MOUNT_EXTERNAL_NONE; 2638 if (!app.isolated) { 2639 int[] permGids = null; 2640 try { 2641 final PackageManager pm = mContext.getPackageManager(); 2642 permGids = pm.getPackageGids(app.info.packageName); 2643 2644 if (Environment.isExternalStorageEmulated()) { 2645 if (pm.checkPermission( 2646 android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE, 2647 app.info.packageName) == PERMISSION_GRANTED) { 2648 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL; 2649 } else { 2650 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER; 2651 } 2652 } 2653 } catch (PackageManager.NameNotFoundException e) { 2654 Slog.w(TAG, "Unable to retrieve gids", e); 2655 } 2656 2657 /* 2658 * Add shared application GID so applications can share some 2659 * resources like shared libraries 2660 */ 2661 if (permGids == null) { 2662 gids = new int[1]; 2663 } else { 2664 gids = new int[permGids.length + 1]; 2665 System.arraycopy(permGids, 0, gids, 1, permGids.length); 2666 } 2667 gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid)); 2668 } 2669 if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) { 2670 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL 2671 && mTopComponent != null 2672 && app.processName.equals(mTopComponent.getPackageName())) { 2673 uid = 0; 2674 } 2675 if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL 2676 && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) { 2677 uid = 0; 2678 } 2679 } 2680 int debugFlags = 0; 2681 if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) { 2682 debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER; 2683 // Also turn on CheckJNI for debuggable apps. It's quite 2684 // awkward to turn on otherwise. 2685 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 2686 } 2687 // Run the app in safe mode if its manifest requests so or the 2688 // system is booted in safe mode. 2689 if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 || 2690 Zygote.systemInSafeMode == true) { 2691 debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE; 2692 } 2693 if ("1".equals(SystemProperties.get("debug.checkjni"))) { 2694 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 2695 } 2696 if ("1".equals(SystemProperties.get("debug.jni.logging"))) { 2697 debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING; 2698 } 2699 if ("1".equals(SystemProperties.get("debug.assert"))) { 2700 debugFlags |= Zygote.DEBUG_ENABLE_ASSERT; 2701 } 2702 2703 // Start the process. It will either succeed and return a result containing 2704 // the PID of the new process, or else throw a RuntimeException. 2705 Process.ProcessStartResult startResult = Process.start("android.app.ActivityThread", 2706 app.processName, uid, uid, gids, debugFlags, mountExternal, 2707 app.info.targetSdkVersion, app.info.seinfo, null); 2708 2709 BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics(); 2710 synchronized (bs) { 2711 if (bs.isOnBattery()) { 2712 bs.getProcessStatsLocked(app.uid, app.processName).incStartsLocked(); 2713 } 2714 } 2715 2716 EventLog.writeEvent(EventLogTags.AM_PROC_START, 2717 UserHandle.getUserId(uid), startResult.pid, uid, 2718 app.processName, hostingType, 2719 hostingNameStr != null ? hostingNameStr : ""); 2720 2721 if (app.persistent) { 2722 Watchdog.getInstance().processStarted(app.processName, startResult.pid); 2723 } 2724 2725 StringBuilder buf = mStringBuilder; 2726 buf.setLength(0); 2727 buf.append("Start proc "); 2728 buf.append(app.processName); 2729 buf.append(" for "); 2730 buf.append(hostingType); 2731 if (hostingNameStr != null) { 2732 buf.append(" "); 2733 buf.append(hostingNameStr); 2734 } 2735 buf.append(": pid="); 2736 buf.append(startResult.pid); 2737 buf.append(" uid="); 2738 buf.append(uid); 2739 buf.append(" gids={"); 2740 if (gids != null) { 2741 for (int gi=0; gi<gids.length; gi++) { 2742 if (gi != 0) buf.append(", "); 2743 buf.append(gids[gi]); 2744 2745 } 2746 } 2747 buf.append("}"); 2748 Slog.i(TAG, buf.toString()); 2749 app.setPid(startResult.pid); 2750 app.usingWrapper = startResult.usingWrapper; 2751 app.removed = false; 2752 synchronized (mPidsSelfLocked) { 2753 this.mPidsSelfLocked.put(startResult.pid, app); 2754 Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 2755 msg.obj = app; 2756 mHandler.sendMessageDelayed(msg, startResult.usingWrapper 2757 ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT); 2758 } 2759 } catch (RuntimeException e) { 2760 // XXX do better error recovery. 2761 app.setPid(0); 2762 Slog.e(TAG, "Failure starting process " + app.processName, e); 2763 } 2764 } 2765 2766 void updateUsageStats(ActivityRecord component, boolean resumed) { 2767 if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed); 2768 final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 2769 if (resumed) { 2770 mUsageStatsService.noteResumeComponent(component.realActivity); 2771 synchronized (stats) { 2772 stats.noteActivityResumedLocked(component.app.uid); 2773 } 2774 } else { 2775 mUsageStatsService.notePauseComponent(component.realActivity); 2776 synchronized (stats) { 2777 stats.noteActivityPausedLocked(component.app.uid); 2778 } 2779 } 2780 } 2781 2782 Intent getHomeIntent() { 2783 Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null); 2784 intent.setComponent(mTopComponent); 2785 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 2786 intent.addCategory(Intent.CATEGORY_HOME); 2787 } 2788 return intent; 2789 } 2790 2791 boolean startHomeActivityLocked(int userId) { 2792 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL 2793 && mTopAction == null) { 2794 // We are running in factory test mode, but unable to find 2795 // the factory test app, so just sit around displaying the 2796 // error message and don't try to start anything. 2797 return false; 2798 } 2799 Intent intent = getHomeIntent(); 2800 ActivityInfo aInfo = 2801 resolveActivityInfo(intent, STOCK_PM_FLAGS, userId); 2802 if (aInfo != null) { 2803 intent.setComponent(new ComponentName( 2804 aInfo.applicationInfo.packageName, aInfo.name)); 2805 // Don't do this if the home app is currently being 2806 // instrumented. 2807 aInfo = new ActivityInfo(aInfo); 2808 aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId); 2809 ProcessRecord app = getProcessRecordLocked(aInfo.processName, 2810 aInfo.applicationInfo.uid, true); 2811 if (app == null || app.instrumentationClass == null) { 2812 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK); 2813 mStackSupervisor.startHomeActivity(intent, aInfo); 2814 } 2815 } 2816 2817 return true; 2818 } 2819 2820 private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) { 2821 ActivityInfo ai = null; 2822 ComponentName comp = intent.getComponent(); 2823 try { 2824 if (comp != null) { 2825 ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId); 2826 } else { 2827 ResolveInfo info = AppGlobals.getPackageManager().resolveIntent( 2828 intent, 2829 intent.resolveTypeIfNeeded(mContext.getContentResolver()), 2830 flags, userId); 2831 2832 if (info != null) { 2833 ai = info.activityInfo; 2834 } 2835 } 2836 } catch (RemoteException e) { 2837 // ignore 2838 } 2839 2840 return ai; 2841 } 2842 2843 /** 2844 * Starts the "new version setup screen" if appropriate. 2845 */ 2846 void startSetupActivityLocked() { 2847 // Only do this once per boot. 2848 if (mCheckedForSetup) { 2849 return; 2850 } 2851 2852 // We will show this screen if the current one is a different 2853 // version than the last one shown, and we are not running in 2854 // low-level factory test mode. 2855 final ContentResolver resolver = mContext.getContentResolver(); 2856 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL && 2857 Settings.Global.getInt(resolver, 2858 Settings.Global.DEVICE_PROVISIONED, 0) != 0) { 2859 mCheckedForSetup = true; 2860 2861 // See if we should be showing the platform update setup UI. 2862 Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP); 2863 List<ResolveInfo> ris = mContext.getPackageManager() 2864 .queryIntentActivities(intent, PackageManager.GET_META_DATA); 2865 2866 // We don't allow third party apps to replace this. 2867 ResolveInfo ri = null; 2868 for (int i=0; ris != null && i<ris.size(); i++) { 2869 if ((ris.get(i).activityInfo.applicationInfo.flags 2870 & ApplicationInfo.FLAG_SYSTEM) != 0) { 2871 ri = ris.get(i); 2872 break; 2873 } 2874 } 2875 2876 if (ri != null) { 2877 String vers = ri.activityInfo.metaData != null 2878 ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION) 2879 : null; 2880 if (vers == null && ri.activityInfo.applicationInfo.metaData != null) { 2881 vers = ri.activityInfo.applicationInfo.metaData.getString( 2882 Intent.METADATA_SETUP_VERSION); 2883 } 2884 String lastVers = Settings.Secure.getString( 2885 resolver, Settings.Secure.LAST_SETUP_SHOWN); 2886 if (vers != null && !vers.equals(lastVers)) { 2887 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 2888 intent.setComponent(new ComponentName( 2889 ri.activityInfo.packageName, ri.activityInfo.name)); 2890 mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo, 2891 null, null, 0, 0, 0, null, 0, null, false, null, null); 2892 } 2893 } 2894 } 2895 } 2896 2897 CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) { 2898 return mCompatModePackages.compatibilityInfoForPackageLocked(ai); 2899 } 2900 2901 void enforceNotIsolatedCaller(String caller) { 2902 if (UserHandle.isIsolated(Binder.getCallingUid())) { 2903 throw new SecurityException("Isolated process not allowed to call " + caller); 2904 } 2905 } 2906 2907 @Override 2908 public int getFrontActivityScreenCompatMode() { 2909 enforceNotIsolatedCaller("getFrontActivityScreenCompatMode"); 2910 synchronized (this) { 2911 return mCompatModePackages.getFrontActivityScreenCompatModeLocked(); 2912 } 2913 } 2914 2915 @Override 2916 public void setFrontActivityScreenCompatMode(int mode) { 2917 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 2918 "setFrontActivityScreenCompatMode"); 2919 synchronized (this) { 2920 mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode); 2921 } 2922 } 2923 2924 @Override 2925 public int getPackageScreenCompatMode(String packageName) { 2926 enforceNotIsolatedCaller("getPackageScreenCompatMode"); 2927 synchronized (this) { 2928 return mCompatModePackages.getPackageScreenCompatModeLocked(packageName); 2929 } 2930 } 2931 2932 @Override 2933 public void setPackageScreenCompatMode(String packageName, int mode) { 2934 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 2935 "setPackageScreenCompatMode"); 2936 synchronized (this) { 2937 mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode); 2938 } 2939 } 2940 2941 @Override 2942 public boolean getPackageAskScreenCompat(String packageName) { 2943 enforceNotIsolatedCaller("getPackageAskScreenCompat"); 2944 synchronized (this) { 2945 return mCompatModePackages.getPackageAskCompatModeLocked(packageName); 2946 } 2947 } 2948 2949 @Override 2950 public void setPackageAskScreenCompat(String packageName, boolean ask) { 2951 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 2952 "setPackageAskScreenCompat"); 2953 synchronized (this) { 2954 mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask); 2955 } 2956 } 2957 2958 private void dispatchProcessesChanged() { 2959 int N; 2960 synchronized (this) { 2961 N = mPendingProcessChanges.size(); 2962 if (mActiveProcessChanges.length < N) { 2963 mActiveProcessChanges = new ProcessChangeItem[N]; 2964 } 2965 mPendingProcessChanges.toArray(mActiveProcessChanges); 2966 mAvailProcessChanges.addAll(mPendingProcessChanges); 2967 mPendingProcessChanges.clear(); 2968 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes"); 2969 } 2970 2971 int i = mProcessObservers.beginBroadcast(); 2972 while (i > 0) { 2973 i--; 2974 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 2975 if (observer != null) { 2976 try { 2977 for (int j=0; j<N; j++) { 2978 ProcessChangeItem item = mActiveProcessChanges[j]; 2979 if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) { 2980 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid=" 2981 + item.pid + " uid=" + item.uid + ": " 2982 + item.foregroundActivities); 2983 observer.onForegroundActivitiesChanged(item.pid, item.uid, 2984 item.foregroundActivities); 2985 } 2986 if ((item.changes&ProcessChangeItem.CHANGE_IMPORTANCE) != 0) { 2987 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "IMPORTANCE CHANGED pid=" 2988 + item.pid + " uid=" + item.uid + ": " + item.importance); 2989 observer.onImportanceChanged(item.pid, item.uid, 2990 item.importance); 2991 } 2992 } 2993 } catch (RemoteException e) { 2994 } 2995 } 2996 } 2997 mProcessObservers.finishBroadcast(); 2998 } 2999 3000 private void dispatchProcessDied(int pid, int uid) { 3001 int i = mProcessObservers.beginBroadcast(); 3002 while (i > 0) { 3003 i--; 3004 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 3005 if (observer != null) { 3006 try { 3007 observer.onProcessDied(pid, uid); 3008 } catch (RemoteException e) { 3009 } 3010 } 3011 } 3012 mProcessObservers.finishBroadcast(); 3013 } 3014 3015 @Override 3016 public final int startActivity(IApplicationThread caller, String callingPackage, 3017 Intent intent, String resolvedType, IBinder resultTo, 3018 String resultWho, int requestCode, int startFlags, 3019 String profileFile, ParcelFileDescriptor profileFd, Bundle options) { 3020 return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo, 3021 resultWho, requestCode, 3022 startFlags, profileFile, profileFd, options, UserHandle.getCallingUserId()); 3023 } 3024 3025 @Override 3026 public final int startActivityAsUser(IApplicationThread caller, String callingPackage, 3027 Intent intent, String resolvedType, IBinder resultTo, 3028 String resultWho, int requestCode, int startFlags, 3029 String profileFile, ParcelFileDescriptor profileFd, Bundle options, int userId) { 3030 enforceNotIsolatedCaller("startActivity"); 3031 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3032 false, true, "startActivity", null); 3033 // TODO: Switch to user app stacks here. 3034 return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType, 3035 resultTo, resultWho, requestCode, startFlags, profileFile, profileFd, 3036 null, null, options, userId, null); 3037 } 3038 3039 @Override 3040 public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage, 3041 Intent intent, String resolvedType, IBinder resultTo, 3042 String resultWho, int requestCode, int startFlags, String profileFile, 3043 ParcelFileDescriptor profileFd, Bundle options, int userId) { 3044 enforceNotIsolatedCaller("startActivityAndWait"); 3045 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3046 false, true, "startActivityAndWait", null); 3047 WaitResult res = new WaitResult(); 3048 // TODO: Switch to user app stacks here. 3049 mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType, 3050 resultTo, resultWho, requestCode, startFlags, profileFile, profileFd, 3051 res, null, options, UserHandle.getCallingUserId(), null); 3052 return res; 3053 } 3054 3055 @Override 3056 public final int startActivityWithConfig(IApplicationThread caller, String callingPackage, 3057 Intent intent, String resolvedType, IBinder resultTo, 3058 String resultWho, int requestCode, int startFlags, Configuration config, 3059 Bundle options, int userId) { 3060 enforceNotIsolatedCaller("startActivityWithConfig"); 3061 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3062 false, true, "startActivityWithConfig", null); 3063 // TODO: Switch to user app stacks here. 3064 int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, 3065 resolvedType, resultTo, resultWho, requestCode, startFlags, 3066 null, null, null, config, options, userId, null); 3067 return ret; 3068 } 3069 3070 @Override 3071 public int startActivityIntentSender(IApplicationThread caller, 3072 IntentSender intent, Intent fillInIntent, String resolvedType, 3073 IBinder resultTo, String resultWho, int requestCode, 3074 int flagsMask, int flagsValues, Bundle options) { 3075 enforceNotIsolatedCaller("startActivityIntentSender"); 3076 // Refuse possible leaked file descriptors 3077 if (fillInIntent != null && fillInIntent.hasFileDescriptors()) { 3078 throw new IllegalArgumentException("File descriptors passed in Intent"); 3079 } 3080 3081 IIntentSender sender = intent.getTarget(); 3082 if (!(sender instanceof PendingIntentRecord)) { 3083 throw new IllegalArgumentException("Bad PendingIntent object"); 3084 } 3085 3086 PendingIntentRecord pir = (PendingIntentRecord)sender; 3087 3088 synchronized (this) { 3089 // If this is coming from the currently resumed activity, it is 3090 // effectively saying that app switches are allowed at this point. 3091 final ActivityStack stack = getFocusedStack(); 3092 if (stack.mResumedActivity != null && 3093 stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) { 3094 mAppSwitchesAllowedTime = 0; 3095 } 3096 } 3097 int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null, 3098 resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null); 3099 return ret; 3100 } 3101 3102 @Override 3103 public boolean startNextMatchingActivity(IBinder callingActivity, 3104 Intent intent, Bundle options) { 3105 // Refuse possible leaked file descriptors 3106 if (intent != null && intent.hasFileDescriptors() == true) { 3107 throw new IllegalArgumentException("File descriptors passed in Intent"); 3108 } 3109 3110 synchronized (this) { 3111 final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity); 3112 if (r == null) { 3113 ActivityOptions.abort(options); 3114 return false; 3115 } 3116 if (r.app == null || r.app.thread == null) { 3117 // The caller is not running... d'oh! 3118 ActivityOptions.abort(options); 3119 return false; 3120 } 3121 intent = new Intent(intent); 3122 // The caller is not allowed to change the data. 3123 intent.setDataAndType(r.intent.getData(), r.intent.getType()); 3124 // And we are resetting to find the next component... 3125 intent.setComponent(null); 3126 3127 final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0); 3128 3129 ActivityInfo aInfo = null; 3130 try { 3131 List<ResolveInfo> resolves = 3132 AppGlobals.getPackageManager().queryIntentActivities( 3133 intent, r.resolvedType, 3134 PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS, 3135 UserHandle.getCallingUserId()); 3136 3137 // Look for the original activity in the list... 3138 final int N = resolves != null ? resolves.size() : 0; 3139 for (int i=0; i<N; i++) { 3140 ResolveInfo rInfo = resolves.get(i); 3141 if (rInfo.activityInfo.packageName.equals(r.packageName) 3142 && rInfo.activityInfo.name.equals(r.info.name)) { 3143 // We found the current one... the next matching is 3144 // after it. 3145 i++; 3146 if (i<N) { 3147 aInfo = resolves.get(i).activityInfo; 3148 } 3149 if (debug) { 3150 Slog.v(TAG, "Next matching activity: found current " + r.packageName 3151 + "/" + r.info.name); 3152 Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName 3153 + "/" + aInfo.name); 3154 } 3155 break; 3156 } 3157 } 3158 } catch (RemoteException e) { 3159 } 3160 3161 if (aInfo == null) { 3162 // Nobody who is next! 3163 ActivityOptions.abort(options); 3164 if (debug) Slog.d(TAG, "Next matching activity: nothing found"); 3165 return false; 3166 } 3167 3168 intent.setComponent(new ComponentName( 3169 aInfo.applicationInfo.packageName, aInfo.name)); 3170 intent.setFlags(intent.getFlags()&~( 3171 Intent.FLAG_ACTIVITY_FORWARD_RESULT| 3172 Intent.FLAG_ACTIVITY_CLEAR_TOP| 3173 Intent.FLAG_ACTIVITY_MULTIPLE_TASK| 3174 Intent.FLAG_ACTIVITY_NEW_TASK)); 3175 3176 // Okay now we need to start the new activity, replacing the 3177 // currently running activity. This is a little tricky because 3178 // we want to start the new one as if the current one is finished, 3179 // but not finish the current one first so that there is no flicker. 3180 // And thus... 3181 final boolean wasFinishing = r.finishing; 3182 r.finishing = true; 3183 3184 // Propagate reply information over to the new activity. 3185 final ActivityRecord resultTo = r.resultTo; 3186 final String resultWho = r.resultWho; 3187 final int requestCode = r.requestCode; 3188 r.resultTo = null; 3189 if (resultTo != null) { 3190 resultTo.removeResultsLocked(r, resultWho, requestCode); 3191 } 3192 3193 final long origId = Binder.clearCallingIdentity(); 3194 int res = mStackSupervisor.startActivityLocked(r.app.thread, intent, 3195 r.resolvedType, aInfo, resultTo != null ? resultTo.appToken : null, 3196 resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage, 0, 3197 options, false, null, null); 3198 Binder.restoreCallingIdentity(origId); 3199 3200 r.finishing = wasFinishing; 3201 if (res != ActivityManager.START_SUCCESS) { 3202 return false; 3203 } 3204 return true; 3205 } 3206 } 3207 3208 final int startActivityInPackage(int uid, String callingPackage, 3209 Intent intent, String resolvedType, IBinder resultTo, 3210 String resultWho, int requestCode, int startFlags, Bundle options, int userId, 3211 IActivityContainer container) { 3212 3213 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3214 false, true, "startActivityInPackage", null); 3215 3216 // TODO: Switch to user app stacks here. 3217 int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent, resolvedType, 3218 resultTo, resultWho, requestCode, startFlags, 3219 null, null, null, null, options, userId, container); 3220 return ret; 3221 } 3222 3223 @Override 3224 public final int startActivities(IApplicationThread caller, String callingPackage, 3225 Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options, 3226 int userId) { 3227 enforceNotIsolatedCaller("startActivities"); 3228 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3229 false, true, "startActivity", null); 3230 // TODO: Switch to user app stacks here. 3231 int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents, 3232 resolvedTypes, resultTo, options, userId); 3233 return ret; 3234 } 3235 3236 final int startActivitiesInPackage(int uid, String callingPackage, 3237 Intent[] intents, String[] resolvedTypes, IBinder resultTo, 3238 Bundle options, int userId) { 3239 3240 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3241 false, true, "startActivityInPackage", null); 3242 // TODO: Switch to user app stacks here. 3243 int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes, 3244 resultTo, options, userId); 3245 return ret; 3246 } 3247 3248 final void addRecentTaskLocked(TaskRecord task) { 3249 int N = mRecentTasks.size(); 3250 // Quick case: check if the top-most recent task is the same. 3251 if (N > 0 && mRecentTasks.get(0) == task) { 3252 return; 3253 } 3254 // Remove any existing entries that are the same kind of task. 3255 for (int i=0; i<N; i++) { 3256 TaskRecord tr = mRecentTasks.get(i); 3257 if (task.userId == tr.userId 3258 && ((task.affinity != null && task.affinity.equals(tr.affinity)) 3259 || (task.intent != null && task.intent.filterEquals(tr.intent)))) { 3260 tr.disposeThumbnail(); 3261 mRecentTasks.remove(i); 3262 i--; 3263 N--; 3264 if (task.intent == null) { 3265 // If the new recent task we are adding is not fully 3266 // specified, then replace it with the existing recent task. 3267 task = tr; 3268 } 3269 } 3270 } 3271 if (N >= MAX_RECENT_TASKS) { 3272 mRecentTasks.remove(N-1).disposeThumbnail(); 3273 } 3274 mRecentTasks.add(0, task); 3275 } 3276 3277 @Override 3278 public void reportActivityFullyDrawn(IBinder token) { 3279 synchronized (this) { 3280 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3281 if (r == null) { 3282 return; 3283 } 3284 r.reportFullyDrawnLocked(); 3285 } 3286 } 3287 3288 @Override 3289 public void setRequestedOrientation(IBinder token, int requestedOrientation) { 3290 synchronized (this) { 3291 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3292 if (r == null) { 3293 return; 3294 } 3295 final long origId = Binder.clearCallingIdentity(); 3296 mWindowManager.setAppOrientation(r.appToken, requestedOrientation); 3297 Configuration config = mWindowManager.updateOrientationFromAppTokens( 3298 mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null); 3299 if (config != null) { 3300 r.frozenBeforeDestroy = true; 3301 if (!updateConfigurationLocked(config, r, false, false)) { 3302 mStackSupervisor.resumeTopActivitiesLocked(); 3303 } 3304 } 3305 Binder.restoreCallingIdentity(origId); 3306 } 3307 } 3308 3309 @Override 3310 public int getRequestedOrientation(IBinder token) { 3311 synchronized (this) { 3312 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3313 if (r == null) { 3314 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; 3315 } 3316 return mWindowManager.getAppOrientation(r.appToken); 3317 } 3318 } 3319 3320 /** 3321 * This is the internal entry point for handling Activity.finish(). 3322 * 3323 * @param token The Binder token referencing the Activity we want to finish. 3324 * @param resultCode Result code, if any, from this Activity. 3325 * @param resultData Result data (Intent), if any, from this Activity. 3326 * 3327 * @return Returns true if the activity successfully finished, or false if it is still running. 3328 */ 3329 @Override 3330 public final boolean finishActivity(IBinder token, int resultCode, Intent resultData) { 3331 // Refuse possible leaked file descriptors 3332 if (resultData != null && resultData.hasFileDescriptors() == true) { 3333 throw new IllegalArgumentException("File descriptors passed in Intent"); 3334 } 3335 3336 synchronized(this) { 3337 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3338 if (r == null) { 3339 return true; 3340 } 3341 if (mController != null) { 3342 // Find the first activity that is not finishing. 3343 ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0); 3344 if (next != null) { 3345 // ask watcher if this is allowed 3346 boolean resumeOK = true; 3347 try { 3348 resumeOK = mController.activityResuming(next.packageName); 3349 } catch (RemoteException e) { 3350 mController = null; 3351 Watchdog.getInstance().setActivityController(null); 3352 } 3353 3354 if (!resumeOK) { 3355 return false; 3356 } 3357 } 3358 } 3359 final long origId = Binder.clearCallingIdentity(); 3360 boolean res = r.task.stack.requestFinishActivityLocked(token, resultCode, 3361 resultData, "app-request", true); 3362 Binder.restoreCallingIdentity(origId); 3363 return res; 3364 } 3365 } 3366 3367 @Override 3368 public final void finishHeavyWeightApp() { 3369 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 3370 != PackageManager.PERMISSION_GRANTED) { 3371 String msg = "Permission Denial: finishHeavyWeightApp() from pid=" 3372 + Binder.getCallingPid() 3373 + ", uid=" + Binder.getCallingUid() 3374 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 3375 Slog.w(TAG, msg); 3376 throw new SecurityException(msg); 3377 } 3378 3379 synchronized(this) { 3380 if (mHeavyWeightProcess == null) { 3381 return; 3382 } 3383 3384 ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>( 3385 mHeavyWeightProcess.activities); 3386 for (int i=0; i<activities.size(); i++) { 3387 ActivityRecord r = activities.get(i); 3388 if (!r.finishing) { 3389 r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED, 3390 null, "finish-heavy", true); 3391 } 3392 } 3393 3394 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 3395 mHeavyWeightProcess.userId, 0)); 3396 mHeavyWeightProcess = null; 3397 } 3398 } 3399 3400 @Override 3401 public void crashApplication(int uid, int initialPid, String packageName, 3402 String message) { 3403 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 3404 != PackageManager.PERMISSION_GRANTED) { 3405 String msg = "Permission Denial: crashApplication() from pid=" 3406 + Binder.getCallingPid() 3407 + ", uid=" + Binder.getCallingUid() 3408 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 3409 Slog.w(TAG, msg); 3410 throw new SecurityException(msg); 3411 } 3412 3413 synchronized(this) { 3414 ProcessRecord proc = null; 3415 3416 // Figure out which process to kill. We don't trust that initialPid 3417 // still has any relation to current pids, so must scan through the 3418 // list. 3419 synchronized (mPidsSelfLocked) { 3420 for (int i=0; i<mPidsSelfLocked.size(); i++) { 3421 ProcessRecord p = mPidsSelfLocked.valueAt(i); 3422 if (p.uid != uid) { 3423 continue; 3424 } 3425 if (p.pid == initialPid) { 3426 proc = p; 3427 break; 3428 } 3429 if (p.pkgList.containsKey(packageName)) { 3430 proc = p; 3431 } 3432 } 3433 } 3434 3435 if (proc == null) { 3436 Slog.w(TAG, "crashApplication: nothing for uid=" + uid 3437 + " initialPid=" + initialPid 3438 + " packageName=" + packageName); 3439 return; 3440 } 3441 3442 if (proc.thread != null) { 3443 if (proc.pid == Process.myPid()) { 3444 Log.w(TAG, "crashApplication: trying to crash self!"); 3445 return; 3446 } 3447 long ident = Binder.clearCallingIdentity(); 3448 try { 3449 proc.thread.scheduleCrash(message); 3450 } catch (RemoteException e) { 3451 } 3452 Binder.restoreCallingIdentity(ident); 3453 } 3454 } 3455 } 3456 3457 @Override 3458 public final void finishSubActivity(IBinder token, String resultWho, 3459 int requestCode) { 3460 synchronized(this) { 3461 final long origId = Binder.clearCallingIdentity(); 3462 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3463 if (r != null) { 3464 r.task.stack.finishSubActivityLocked(r, resultWho, requestCode); 3465 } 3466 Binder.restoreCallingIdentity(origId); 3467 } 3468 } 3469 3470 @Override 3471 public boolean finishActivityAffinity(IBinder token) { 3472 synchronized(this) { 3473 final long origId = Binder.clearCallingIdentity(); 3474 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3475 boolean res = false; 3476 if (r != null) { 3477 res = r.task.stack.finishActivityAffinityLocked(r); 3478 } 3479 Binder.restoreCallingIdentity(origId); 3480 return res; 3481 } 3482 } 3483 3484 @Override 3485 public boolean willActivityBeVisible(IBinder token) { 3486 synchronized(this) { 3487 ActivityStack stack = ActivityRecord.getStackLocked(token); 3488 if (stack != null) { 3489 return stack.willActivityBeVisibleLocked(token); 3490 } 3491 return false; 3492 } 3493 } 3494 3495 @Override 3496 public void overridePendingTransition(IBinder token, String packageName, 3497 int enterAnim, int exitAnim) { 3498 synchronized(this) { 3499 ActivityRecord self = ActivityRecord.isInStackLocked(token); 3500 if (self == null) { 3501 return; 3502 } 3503 3504 final long origId = Binder.clearCallingIdentity(); 3505 3506 if (self.state == ActivityState.RESUMED 3507 || self.state == ActivityState.PAUSING) { 3508 mWindowManager.overridePendingAppTransition(packageName, 3509 enterAnim, exitAnim, null); 3510 } 3511 3512 Binder.restoreCallingIdentity(origId); 3513 } 3514 } 3515 3516 /** 3517 * Main function for removing an existing process from the activity manager 3518 * as a result of that process going away. Clears out all connections 3519 * to the process. 3520 */ 3521 private final void handleAppDiedLocked(ProcessRecord app, 3522 boolean restarting, boolean allowRestart) { 3523 int pid = app.pid; 3524 cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1); 3525 if (!restarting) { 3526 removeLruProcessLocked(app); 3527 if (pid > 0) { 3528 ProcessList.remove(pid); 3529 } 3530 } 3531 3532 if (mProfileProc == app) { 3533 clearProfilerLocked(); 3534 } 3535 3536 // Remove this application's activities from active lists. 3537 boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app); 3538 3539 app.activities.clear(); 3540 3541 if (app.instrumentationClass != null) { 3542 Slog.w(TAG, "Crash of app " + app.processName 3543 + " running instrumentation " + app.instrumentationClass); 3544 Bundle info = new Bundle(); 3545 info.putString("shortMsg", "Process crashed."); 3546 finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info); 3547 } 3548 3549 if (!restarting) { 3550 if (!mStackSupervisor.resumeTopActivitiesLocked()) { 3551 // If there was nothing to resume, and we are not already 3552 // restarting this process, but there is a visible activity that 3553 // is hosted by the process... then make sure all visible 3554 // activities are running, taking care of restarting this 3555 // process. 3556 if (hasVisibleActivities) { 3557 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 3558 } 3559 } 3560 } 3561 } 3562 3563 private final int getLRURecordIndexForAppLocked(IApplicationThread thread) { 3564 IBinder threadBinder = thread.asBinder(); 3565 // Find the application record. 3566 for (int i=mLruProcesses.size()-1; i>=0; i--) { 3567 ProcessRecord rec = mLruProcesses.get(i); 3568 if (rec.thread != null && rec.thread.asBinder() == threadBinder) { 3569 return i; 3570 } 3571 } 3572 return -1; 3573 } 3574 3575 final ProcessRecord getRecordForAppLocked( 3576 IApplicationThread thread) { 3577 if (thread == null) { 3578 return null; 3579 } 3580 3581 int appIndex = getLRURecordIndexForAppLocked(thread); 3582 return appIndex >= 0 ? mLruProcesses.get(appIndex) : null; 3583 } 3584 3585 final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) { 3586 // If there are no longer any background processes running, 3587 // and the app that died was not running instrumentation, 3588 // then tell everyone we are now low on memory. 3589 boolean haveBg = false; 3590 for (int i=mLruProcesses.size()-1; i>=0; i--) { 3591 ProcessRecord rec = mLruProcesses.get(i); 3592 if (rec.thread != null 3593 && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 3594 haveBg = true; 3595 break; 3596 } 3597 } 3598 3599 if (!haveBg) { 3600 boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 3601 if (doReport) { 3602 long now = SystemClock.uptimeMillis(); 3603 if (now < (mLastMemUsageReportTime+5*60*1000)) { 3604 doReport = false; 3605 } else { 3606 mLastMemUsageReportTime = now; 3607 } 3608 } 3609 final ArrayList<ProcessMemInfo> memInfos 3610 = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null; 3611 EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size()); 3612 long now = SystemClock.uptimeMillis(); 3613 for (int i=mLruProcesses.size()-1; i>=0; i--) { 3614 ProcessRecord rec = mLruProcesses.get(i); 3615 if (rec == dyingProc || rec.thread == null) { 3616 continue; 3617 } 3618 if (doReport) { 3619 memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj, 3620 rec.setProcState, rec.adjType, rec.makeAdjReason())); 3621 } 3622 if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) { 3623 // The low memory report is overriding any current 3624 // state for a GC request. Make sure to do 3625 // heavy/important/visible/foreground processes first. 3626 if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 3627 rec.lastRequestedGc = 0; 3628 } else { 3629 rec.lastRequestedGc = rec.lastLowMemory; 3630 } 3631 rec.reportLowMemory = true; 3632 rec.lastLowMemory = now; 3633 mProcessesToGc.remove(rec); 3634 addProcessToGcListLocked(rec); 3635 } 3636 } 3637 if (doReport) { 3638 Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos); 3639 mHandler.sendMessage(msg); 3640 } 3641 scheduleAppGcsLocked(); 3642 } 3643 } 3644 3645 final void appDiedLocked(ProcessRecord app, int pid, 3646 IApplicationThread thread) { 3647 3648 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 3649 synchronized (stats) { 3650 stats.noteProcessDiedLocked(app.info.uid, pid); 3651 } 3652 3653 // Clean up already done if the process has been re-started. 3654 if (app.pid == pid && app.thread != null && 3655 app.thread.asBinder() == thread.asBinder()) { 3656 boolean doLowMem = app.instrumentationClass == null; 3657 boolean doOomAdj = doLowMem; 3658 if (!app.killedByAm) { 3659 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 3660 + ") has died."); 3661 mAllowLowerMemLevel = true; 3662 } else { 3663 // Note that we always want to do oom adj to update our state with the 3664 // new number of procs. 3665 mAllowLowerMemLevel = false; 3666 doLowMem = false; 3667 } 3668 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName); 3669 if (DEBUG_CLEANUP) Slog.v( 3670 TAG, "Dying app: " + app + ", pid: " + pid 3671 + ", thread: " + thread.asBinder()); 3672 handleAppDiedLocked(app, false, true); 3673 3674 if (doOomAdj) { 3675 updateOomAdjLocked(); 3676 } 3677 if (doLowMem) { 3678 doLowMemReportIfNeededLocked(app); 3679 } 3680 } else if (app.pid != pid) { 3681 // A new process has already been started. 3682 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 3683 + ") has died and restarted (pid " + app.pid + ")."); 3684 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName); 3685 } else if (DEBUG_PROCESSES) { 3686 Slog.d(TAG, "Received spurious death notification for thread " 3687 + thread.asBinder()); 3688 } 3689 } 3690 3691 /** 3692 * If a stack trace dump file is configured, dump process stack traces. 3693 * @param clearTraces causes the dump file to be erased prior to the new 3694 * traces being written, if true; when false, the new traces will be 3695 * appended to any existing file content. 3696 * @param firstPids of dalvik VM processes to dump stack traces for first 3697 * @param lastPids of dalvik VM processes to dump stack traces for last 3698 * @param nativeProcs optional list of native process names to dump stack crawls 3699 * @return file containing stack traces, or null if no dump file is configured 3700 */ 3701 public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids, 3702 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) { 3703 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 3704 if (tracesPath == null || tracesPath.length() == 0) { 3705 return null; 3706 } 3707 3708 File tracesFile = new File(tracesPath); 3709 try { 3710 File tracesDir = tracesFile.getParentFile(); 3711 if (!tracesDir.exists()) { 3712 tracesFile.mkdirs(); 3713 if (!SELinux.restorecon(tracesDir)) { 3714 return null; 3715 } 3716 } 3717 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 3718 3719 if (clearTraces && tracesFile.exists()) tracesFile.delete(); 3720 tracesFile.createNewFile(); 3721 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 3722 } catch (IOException e) { 3723 Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e); 3724 return null; 3725 } 3726 3727 dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs); 3728 return tracesFile; 3729 } 3730 3731 private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids, 3732 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) { 3733 // Use a FileObserver to detect when traces finish writing. 3734 // The order of traces is considered important to maintain for legibility. 3735 FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) { 3736 @Override 3737 public synchronized void onEvent(int event, String path) { notify(); } 3738 }; 3739 3740 try { 3741 observer.startWatching(); 3742 3743 // First collect all of the stacks of the most important pids. 3744 if (firstPids != null) { 3745 try { 3746 int num = firstPids.size(); 3747 for (int i = 0; i < num; i++) { 3748 synchronized (observer) { 3749 Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT); 3750 observer.wait(200); // Wait for write-close, give up after 200msec 3751 } 3752 } 3753 } catch (InterruptedException e) { 3754 Log.wtf(TAG, e); 3755 } 3756 } 3757 3758 // Next collect the stacks of the native pids 3759 if (nativeProcs != null) { 3760 int[] pids = Process.getPidsForCommands(nativeProcs); 3761 if (pids != null) { 3762 for (int pid : pids) { 3763 Debug.dumpNativeBacktraceToFile(pid, tracesPath); 3764 } 3765 } 3766 } 3767 3768 // Lastly, measure CPU usage. 3769 if (processCpuTracker != null) { 3770 processCpuTracker.init(); 3771 System.gc(); 3772 processCpuTracker.update(); 3773 try { 3774 synchronized (processCpuTracker) { 3775 processCpuTracker.wait(500); // measure over 1/2 second. 3776 } 3777 } catch (InterruptedException e) { 3778 } 3779 processCpuTracker.update(); 3780 3781 // We'll take the stack crawls of just the top apps using CPU. 3782 final int N = processCpuTracker.countWorkingStats(); 3783 int numProcs = 0; 3784 for (int i=0; i<N && numProcs<5; i++) { 3785 ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i); 3786 if (lastPids.indexOfKey(stats.pid) >= 0) { 3787 numProcs++; 3788 try { 3789 synchronized (observer) { 3790 Process.sendSignal(stats.pid, Process.SIGNAL_QUIT); 3791 observer.wait(200); // Wait for write-close, give up after 200msec 3792 } 3793 } catch (InterruptedException e) { 3794 Log.wtf(TAG, e); 3795 } 3796 3797 } 3798 } 3799 } 3800 } finally { 3801 observer.stopWatching(); 3802 } 3803 } 3804 3805 final void logAppTooSlow(ProcessRecord app, long startTime, String msg) { 3806 if (true || IS_USER_BUILD) { 3807 return; 3808 } 3809 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 3810 if (tracesPath == null || tracesPath.length() == 0) { 3811 return; 3812 } 3813 3814 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads(); 3815 StrictMode.allowThreadDiskWrites(); 3816 try { 3817 final File tracesFile = new File(tracesPath); 3818 final File tracesDir = tracesFile.getParentFile(); 3819 final File tracesTmp = new File(tracesDir, "__tmp__"); 3820 try { 3821 if (!tracesDir.exists()) { 3822 tracesFile.mkdirs(); 3823 if (!SELinux.restorecon(tracesDir.getPath())) { 3824 return; 3825 } 3826 } 3827 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 3828 3829 if (tracesFile.exists()) { 3830 tracesTmp.delete(); 3831 tracesFile.renameTo(tracesTmp); 3832 } 3833 StringBuilder sb = new StringBuilder(); 3834 Time tobj = new Time(); 3835 tobj.set(System.currentTimeMillis()); 3836 sb.append(tobj.format("%Y-%m-%d %H:%M:%S")); 3837 sb.append(": "); 3838 TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb); 3839 sb.append(" since "); 3840 sb.append(msg); 3841 FileOutputStream fos = new FileOutputStream(tracesFile); 3842 fos.write(sb.toString().getBytes()); 3843 if (app == null) { 3844 fos.write("\n*** No application process!".getBytes()); 3845 } 3846 fos.close(); 3847 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 3848 } catch (IOException e) { 3849 Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e); 3850 return; 3851 } 3852 3853 if (app != null) { 3854 ArrayList<Integer> firstPids = new ArrayList<Integer>(); 3855 firstPids.add(app.pid); 3856 dumpStackTraces(tracesPath, firstPids, null, null, null); 3857 } 3858 3859 File lastTracesFile = null; 3860 File curTracesFile = null; 3861 for (int i=9; i>=0; i--) { 3862 String name = String.format(Locale.US, "slow%02d.txt", i); 3863 curTracesFile = new File(tracesDir, name); 3864 if (curTracesFile.exists()) { 3865 if (lastTracesFile != null) { 3866 curTracesFile.renameTo(lastTracesFile); 3867 } else { 3868 curTracesFile.delete(); 3869 } 3870 } 3871 lastTracesFile = curTracesFile; 3872 } 3873 tracesFile.renameTo(curTracesFile); 3874 if (tracesTmp.exists()) { 3875 tracesTmp.renameTo(tracesFile); 3876 } 3877 } finally { 3878 StrictMode.setThreadPolicy(oldPolicy); 3879 } 3880 } 3881 3882 final void appNotResponding(ProcessRecord app, ActivityRecord activity, 3883 ActivityRecord parent, boolean aboveSystem, final String annotation) { 3884 ArrayList<Integer> firstPids = new ArrayList<Integer>(5); 3885 SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20); 3886 3887 if (mController != null) { 3888 try { 3889 // 0 == continue, -1 = kill process immediately 3890 int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation); 3891 if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid); 3892 } catch (RemoteException e) { 3893 mController = null; 3894 Watchdog.getInstance().setActivityController(null); 3895 } 3896 } 3897 3898 long anrTime = SystemClock.uptimeMillis(); 3899 if (MONITOR_CPU_USAGE) { 3900 updateCpuStatsNow(); 3901 } 3902 3903 synchronized (this) { 3904 // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down. 3905 if (mShuttingDown) { 3906 Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation); 3907 return; 3908 } else if (app.notResponding) { 3909 Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation); 3910 return; 3911 } else if (app.crashing) { 3912 Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation); 3913 return; 3914 } 3915 3916 // In case we come through here for the same app before completing 3917 // this one, mark as anring now so we will bail out. 3918 app.notResponding = true; 3919 3920 // Log the ANR to the event log. 3921 EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid, 3922 app.processName, app.info.flags, annotation); 3923 3924 // Dump thread traces as quickly as we can, starting with "interesting" processes. 3925 firstPids.add(app.pid); 3926 3927 int parentPid = app.pid; 3928 if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid; 3929 if (parentPid != app.pid) firstPids.add(parentPid); 3930 3931 if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID); 3932 3933 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 3934 ProcessRecord r = mLruProcesses.get(i); 3935 if (r != null && r.thread != null) { 3936 int pid = r.pid; 3937 if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) { 3938 if (r.persistent) { 3939 firstPids.add(pid); 3940 } else { 3941 lastPids.put(pid, Boolean.TRUE); 3942 } 3943 } 3944 } 3945 } 3946 } 3947 3948 // Log the ANR to the main log. 3949 StringBuilder info = new StringBuilder(); 3950 info.setLength(0); 3951 info.append("ANR in ").append(app.processName); 3952 if (activity != null && activity.shortComponentName != null) { 3953 info.append(" (").append(activity.shortComponentName).append(")"); 3954 } 3955 info.append("\n"); 3956 info.append("PID: ").append(app.pid).append("\n"); 3957 if (annotation != null) { 3958 info.append("Reason: ").append(annotation).append("\n"); 3959 } 3960 if (parent != null && parent != activity) { 3961 info.append("Parent: ").append(parent.shortComponentName).append("\n"); 3962 } 3963 3964 final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true); 3965 3966 File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids, 3967 NATIVE_STACKS_OF_INTEREST); 3968 3969 String cpuInfo = null; 3970 if (MONITOR_CPU_USAGE) { 3971 updateCpuStatsNow(); 3972 synchronized (mProcessCpuThread) { 3973 cpuInfo = mProcessCpuTracker.printCurrentState(anrTime); 3974 } 3975 info.append(processCpuTracker.printCurrentLoad()); 3976 info.append(cpuInfo); 3977 } 3978 3979 info.append(processCpuTracker.printCurrentState(anrTime)); 3980 3981 Slog.e(TAG, info.toString()); 3982 if (tracesFile == null) { 3983 // There is no trace file, so dump (only) the alleged culprit's threads to the log 3984 Process.sendSignal(app.pid, Process.SIGNAL_QUIT); 3985 } 3986 3987 addErrorToDropBox("anr", app, app.processName, activity, parent, annotation, 3988 cpuInfo, tracesFile, null); 3989 3990 if (mController != null) { 3991 try { 3992 // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately 3993 int res = mController.appNotResponding(app.processName, app.pid, info.toString()); 3994 if (res != 0) { 3995 if (res < 0 && app.pid != MY_PID) { 3996 Process.killProcess(app.pid); 3997 } else { 3998 synchronized (this) { 3999 mServices.scheduleServiceTimeoutLocked(app); 4000 } 4001 } 4002 return; 4003 } 4004 } catch (RemoteException e) { 4005 mController = null; 4006 Watchdog.getInstance().setActivityController(null); 4007 } 4008 } 4009 4010 // Unless configured otherwise, swallow ANRs in background processes & kill the process. 4011 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), 4012 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; 4013 4014 synchronized (this) { 4015 if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) { 4016 killUnneededProcessLocked(app, "background ANR"); 4017 return; 4018 } 4019 4020 // Set the app's notResponding state, and look up the errorReportReceiver 4021 makeAppNotRespondingLocked(app, 4022 activity != null ? activity.shortComponentName : null, 4023 annotation != null ? "ANR " + annotation : "ANR", 4024 info.toString()); 4025 4026 // Bring up the infamous App Not Responding dialog 4027 Message msg = Message.obtain(); 4028 HashMap<String, Object> map = new HashMap<String, Object>(); 4029 msg.what = SHOW_NOT_RESPONDING_MSG; 4030 msg.obj = map; 4031 msg.arg1 = aboveSystem ? 1 : 0; 4032 map.put("app", app); 4033 if (activity != null) { 4034 map.put("activity", activity); 4035 } 4036 4037 mHandler.sendMessage(msg); 4038 } 4039 } 4040 4041 final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) { 4042 if (!mLaunchWarningShown) { 4043 mLaunchWarningShown = true; 4044 mHandler.post(new Runnable() { 4045 @Override 4046 public void run() { 4047 synchronized (ActivityManagerService.this) { 4048 final Dialog d = new LaunchWarningWindow(mContext, cur, next); 4049 d.show(); 4050 mHandler.postDelayed(new Runnable() { 4051 @Override 4052 public void run() { 4053 synchronized (ActivityManagerService.this) { 4054 d.dismiss(); 4055 mLaunchWarningShown = false; 4056 } 4057 } 4058 }, 4000); 4059 } 4060 } 4061 }); 4062 } 4063 } 4064 4065 @Override 4066 public boolean clearApplicationUserData(final String packageName, 4067 final IPackageDataObserver observer, int userId) { 4068 enforceNotIsolatedCaller("clearApplicationUserData"); 4069 int uid = Binder.getCallingUid(); 4070 int pid = Binder.getCallingPid(); 4071 userId = handleIncomingUser(pid, uid, 4072 userId, false, true, "clearApplicationUserData", null); 4073 long callingId = Binder.clearCallingIdentity(); 4074 try { 4075 IPackageManager pm = AppGlobals.getPackageManager(); 4076 int pkgUid = -1; 4077 synchronized(this) { 4078 try { 4079 pkgUid = pm.getPackageUid(packageName, userId); 4080 } catch (RemoteException e) { 4081 } 4082 if (pkgUid == -1) { 4083 Slog.w(TAG, "Invalid packageName: " + packageName); 4084 if (observer != null) { 4085 try { 4086 observer.onRemoveCompleted(packageName, false); 4087 } catch (RemoteException e) { 4088 Slog.i(TAG, "Observer no longer exists."); 4089 } 4090 } 4091 return false; 4092 } 4093 if (uid == pkgUid || checkComponentPermission( 4094 android.Manifest.permission.CLEAR_APP_USER_DATA, 4095 pid, uid, -1, true) 4096 == PackageManager.PERMISSION_GRANTED) { 4097 forceStopPackageLocked(packageName, pkgUid, "clear data"); 4098 } else { 4099 throw new SecurityException("PID " + pid + " does not have permission " 4100 + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data" 4101 + " of package " + packageName); 4102 } 4103 } 4104 4105 try { 4106 // Clear application user data 4107 pm.clearApplicationUserData(packageName, observer, userId); 4108 4109 // Remove all permissions granted from/to this package 4110 removeUriPermissionsForPackageLocked(packageName, userId, true); 4111 4112 Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED, 4113 Uri.fromParts("package", packageName, null)); 4114 intent.putExtra(Intent.EXTRA_UID, pkgUid); 4115 broadcastIntentInPackage("android", Process.SYSTEM_UID, intent, 4116 null, null, 0, null, null, null, false, false, userId); 4117 } catch (RemoteException e) { 4118 } 4119 } finally { 4120 Binder.restoreCallingIdentity(callingId); 4121 } 4122 return true; 4123 } 4124 4125 @Override 4126 public void killBackgroundProcesses(final String packageName, int userId) { 4127 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 4128 != PackageManager.PERMISSION_GRANTED && 4129 checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES) 4130 != PackageManager.PERMISSION_GRANTED) { 4131 String msg = "Permission Denial: killBackgroundProcesses() from pid=" 4132 + Binder.getCallingPid() 4133 + ", uid=" + Binder.getCallingUid() 4134 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 4135 Slog.w(TAG, msg); 4136 throw new SecurityException(msg); 4137 } 4138 4139 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 4140 userId, true, true, "killBackgroundProcesses", null); 4141 long callingId = Binder.clearCallingIdentity(); 4142 try { 4143 IPackageManager pm = AppGlobals.getPackageManager(); 4144 synchronized(this) { 4145 int appId = -1; 4146 try { 4147 appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0)); 4148 } catch (RemoteException e) { 4149 } 4150 if (appId == -1) { 4151 Slog.w(TAG, "Invalid packageName: " + packageName); 4152 return; 4153 } 4154 killPackageProcessesLocked(packageName, appId, userId, 4155 ProcessList.SERVICE_ADJ, false, true, true, false, "kill background"); 4156 } 4157 } finally { 4158 Binder.restoreCallingIdentity(callingId); 4159 } 4160 } 4161 4162 @Override 4163 public void killAllBackgroundProcesses() { 4164 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 4165 != PackageManager.PERMISSION_GRANTED) { 4166 String msg = "Permission Denial: killAllBackgroundProcesses() from pid=" 4167 + Binder.getCallingPid() 4168 + ", uid=" + Binder.getCallingUid() 4169 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 4170 Slog.w(TAG, msg); 4171 throw new SecurityException(msg); 4172 } 4173 4174 long callingId = Binder.clearCallingIdentity(); 4175 try { 4176 synchronized(this) { 4177 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 4178 final int NP = mProcessNames.getMap().size(); 4179 for (int ip=0; ip<NP; ip++) { 4180 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 4181 final int NA = apps.size(); 4182 for (int ia=0; ia<NA; ia++) { 4183 ProcessRecord app = apps.valueAt(ia); 4184 if (app.persistent) { 4185 // we don't kill persistent processes 4186 continue; 4187 } 4188 if (app.removed) { 4189 procs.add(app); 4190 } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 4191 app.removed = true; 4192 procs.add(app); 4193 } 4194 } 4195 } 4196 4197 int N = procs.size(); 4198 for (int i=0; i<N; i++) { 4199 removeProcessLocked(procs.get(i), false, true, "kill all background"); 4200 } 4201 mAllowLowerMemLevel = true; 4202 updateOomAdjLocked(); 4203 doLowMemReportIfNeededLocked(null); 4204 } 4205 } finally { 4206 Binder.restoreCallingIdentity(callingId); 4207 } 4208 } 4209 4210 @Override 4211 public void forceStopPackage(final String packageName, int userId) { 4212 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 4213 != PackageManager.PERMISSION_GRANTED) { 4214 String msg = "Permission Denial: forceStopPackage() from pid=" 4215 + Binder.getCallingPid() 4216 + ", uid=" + Binder.getCallingUid() 4217 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 4218 Slog.w(TAG, msg); 4219 throw new SecurityException(msg); 4220 } 4221 final int callingPid = Binder.getCallingPid(); 4222 userId = handleIncomingUser(callingPid, Binder.getCallingUid(), 4223 userId, true, true, "forceStopPackage", null); 4224 long callingId = Binder.clearCallingIdentity(); 4225 try { 4226 IPackageManager pm = AppGlobals.getPackageManager(); 4227 synchronized(this) { 4228 int[] users = userId == UserHandle.USER_ALL 4229 ? getUsersLocked() : new int[] { userId }; 4230 for (int user : users) { 4231 int pkgUid = -1; 4232 try { 4233 pkgUid = pm.getPackageUid(packageName, user); 4234 } catch (RemoteException e) { 4235 } 4236 if (pkgUid == -1) { 4237 Slog.w(TAG, "Invalid packageName: " + packageName); 4238 continue; 4239 } 4240 try { 4241 pm.setPackageStoppedState(packageName, true, user); 4242 } catch (RemoteException e) { 4243 } catch (IllegalArgumentException e) { 4244 Slog.w(TAG, "Failed trying to unstop package " 4245 + packageName + ": " + e); 4246 } 4247 if (isUserRunningLocked(user, false)) { 4248 forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid); 4249 } 4250 } 4251 } 4252 } finally { 4253 Binder.restoreCallingIdentity(callingId); 4254 } 4255 } 4256 4257 /* 4258 * The pkg name and app id have to be specified. 4259 */ 4260 @Override 4261 public void killApplicationWithAppId(String pkg, int appid, String reason) { 4262 if (pkg == null) { 4263 return; 4264 } 4265 // Make sure the uid is valid. 4266 if (appid < 0) { 4267 Slog.w(TAG, "Invalid appid specified for pkg : " + pkg); 4268 return; 4269 } 4270 int callerUid = Binder.getCallingUid(); 4271 // Only the system server can kill an application 4272 if (callerUid == Process.SYSTEM_UID) { 4273 // Post an aysnc message to kill the application 4274 Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG); 4275 msg.arg1 = appid; 4276 msg.arg2 = 0; 4277 Bundle bundle = new Bundle(); 4278 bundle.putString("pkg", pkg); 4279 bundle.putString("reason", reason); 4280 msg.obj = bundle; 4281 mHandler.sendMessage(msg); 4282 } else { 4283 throw new SecurityException(callerUid + " cannot kill pkg: " + 4284 pkg); 4285 } 4286 } 4287 4288 @Override 4289 public void closeSystemDialogs(String reason) { 4290 enforceNotIsolatedCaller("closeSystemDialogs"); 4291 4292 final int pid = Binder.getCallingPid(); 4293 final int uid = Binder.getCallingUid(); 4294 final long origId = Binder.clearCallingIdentity(); 4295 try { 4296 synchronized (this) { 4297 // Only allow this from foreground processes, so that background 4298 // applications can't abuse it to prevent system UI from being shown. 4299 if (uid >= Process.FIRST_APPLICATION_UID) { 4300 ProcessRecord proc; 4301 synchronized (mPidsSelfLocked) { 4302 proc = mPidsSelfLocked.get(pid); 4303 } 4304 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 4305 Slog.w(TAG, "Ignoring closeSystemDialogs " + reason 4306 + " from background process " + proc); 4307 return; 4308 } 4309 } 4310 closeSystemDialogsLocked(reason); 4311 } 4312 } finally { 4313 Binder.restoreCallingIdentity(origId); 4314 } 4315 } 4316 4317 void closeSystemDialogsLocked(String reason) { 4318 Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS); 4319 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 4320 | Intent.FLAG_RECEIVER_FOREGROUND); 4321 if (reason != null) { 4322 intent.putExtra("reason", reason); 4323 } 4324 mWindowManager.closeSystemDialogs(reason); 4325 4326 mStackSupervisor.closeSystemDialogsLocked(); 4327 4328 broadcastIntentLocked(null, null, intent, null, 4329 null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1, 4330 Process.SYSTEM_UID, UserHandle.USER_ALL); 4331 } 4332 4333 @Override 4334 public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) { 4335 enforceNotIsolatedCaller("getProcessMemoryInfo"); 4336 Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length]; 4337 for (int i=pids.length-1; i>=0; i--) { 4338 ProcessRecord proc; 4339 int oomAdj; 4340 synchronized (this) { 4341 synchronized (mPidsSelfLocked) { 4342 proc = mPidsSelfLocked.get(pids[i]); 4343 oomAdj = proc != null ? proc.setAdj : 0; 4344 } 4345 } 4346 infos[i] = new Debug.MemoryInfo(); 4347 Debug.getMemoryInfo(pids[i], infos[i]); 4348 if (proc != null) { 4349 synchronized (this) { 4350 if (proc.thread != null && proc.setAdj == oomAdj) { 4351 // Record this for posterity if the process has been stable. 4352 proc.baseProcessTracker.addPss(infos[i].getTotalPss(), 4353 infos[i].getTotalUss(), false, proc.pkgList); 4354 } 4355 } 4356 } 4357 } 4358 return infos; 4359 } 4360 4361 @Override 4362 public long[] getProcessPss(int[] pids) { 4363 enforceNotIsolatedCaller("getProcessPss"); 4364 long[] pss = new long[pids.length]; 4365 for (int i=pids.length-1; i>=0; i--) { 4366 ProcessRecord proc; 4367 int oomAdj; 4368 synchronized (this) { 4369 synchronized (mPidsSelfLocked) { 4370 proc = mPidsSelfLocked.get(pids[i]); 4371 oomAdj = proc != null ? proc.setAdj : 0; 4372 } 4373 } 4374 long[] tmpUss = new long[1]; 4375 pss[i] = Debug.getPss(pids[i], tmpUss); 4376 if (proc != null) { 4377 synchronized (this) { 4378 if (proc.thread != null && proc.setAdj == oomAdj) { 4379 // Record this for posterity if the process has been stable. 4380 proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList); 4381 } 4382 } 4383 } 4384 } 4385 return pss; 4386 } 4387 4388 @Override 4389 public void killApplicationProcess(String processName, int uid) { 4390 if (processName == null) { 4391 return; 4392 } 4393 4394 int callerUid = Binder.getCallingUid(); 4395 // Only the system server can kill an application 4396 if (callerUid == Process.SYSTEM_UID) { 4397 synchronized (this) { 4398 ProcessRecord app = getProcessRecordLocked(processName, uid, true); 4399 if (app != null && app.thread != null) { 4400 try { 4401 app.thread.scheduleSuicide(); 4402 } catch (RemoteException e) { 4403 // If the other end already died, then our work here is done. 4404 } 4405 } else { 4406 Slog.w(TAG, "Process/uid not found attempting kill of " 4407 + processName + " / " + uid); 4408 } 4409 } 4410 } else { 4411 throw new SecurityException(callerUid + " cannot kill app process: " + 4412 processName); 4413 } 4414 } 4415 4416 private void forceStopPackageLocked(final String packageName, int uid, String reason) { 4417 forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false, 4418 false, true, false, UserHandle.getUserId(uid), reason); 4419 Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED, 4420 Uri.fromParts("package", packageName, null)); 4421 if (!mProcessesReady) { 4422 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 4423 | Intent.FLAG_RECEIVER_FOREGROUND); 4424 } 4425 intent.putExtra(Intent.EXTRA_UID, uid); 4426 intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid)); 4427 broadcastIntentLocked(null, null, intent, 4428 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 4429 false, false, 4430 MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid)); 4431 } 4432 4433 private void forceStopUserLocked(int userId, String reason) { 4434 forceStopPackageLocked(null, -1, false, false, true, false, userId, reason); 4435 Intent intent = new Intent(Intent.ACTION_USER_STOPPED); 4436 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 4437 | Intent.FLAG_RECEIVER_FOREGROUND); 4438 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 4439 broadcastIntentLocked(null, null, intent, 4440 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 4441 false, false, 4442 MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 4443 } 4444 4445 private final boolean killPackageProcessesLocked(String packageName, int appId, 4446 int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart, 4447 boolean doit, boolean evenPersistent, String reason) { 4448 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 4449 4450 // Remove all processes this package may have touched: all with the 4451 // same UID (except for the system or root user), and all whose name 4452 // matches the package name. 4453 final String procNamePrefix = packageName != null ? (packageName + ":") : null; 4454 final int NP = mProcessNames.getMap().size(); 4455 for (int ip=0; ip<NP; ip++) { 4456 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 4457 final int NA = apps.size(); 4458 for (int ia=0; ia<NA; ia++) { 4459 ProcessRecord app = apps.valueAt(ia); 4460 if (app.persistent && !evenPersistent) { 4461 // we don't kill persistent processes 4462 continue; 4463 } 4464 if (app.removed) { 4465 if (doit) { 4466 procs.add(app); 4467 } 4468 continue; 4469 } 4470 4471 // Skip process if it doesn't meet our oom adj requirement. 4472 if (app.setAdj < minOomAdj) { 4473 continue; 4474 } 4475 4476 // If no package is specified, we call all processes under the 4477 // give user id. 4478 if (packageName == null) { 4479 if (app.userId != userId) { 4480 continue; 4481 } 4482 if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) { 4483 continue; 4484 } 4485 // Package has been specified, we want to hit all processes 4486 // that match it. We need to qualify this by the processes 4487 // that are running under the specified app and user ID. 4488 } else { 4489 if (UserHandle.getAppId(app.uid) != appId) { 4490 continue; 4491 } 4492 if (userId != UserHandle.USER_ALL && app.userId != userId) { 4493 continue; 4494 } 4495 if (!app.pkgList.containsKey(packageName)) { 4496 continue; 4497 } 4498 } 4499 4500 // Process has passed all conditions, kill it! 4501 if (!doit) { 4502 return true; 4503 } 4504 app.removed = true; 4505 procs.add(app); 4506 } 4507 } 4508 4509 int N = procs.size(); 4510 for (int i=0; i<N; i++) { 4511 removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason); 4512 } 4513 updateOomAdjLocked(); 4514 return N > 0; 4515 } 4516 4517 private final boolean forceStopPackageLocked(String name, int appId, 4518 boolean callerWillRestart, boolean purgeCache, boolean doit, 4519 boolean evenPersistent, int userId, String reason) { 4520 int i; 4521 int N; 4522 4523 if (userId == UserHandle.USER_ALL && name == null) { 4524 Slog.w(TAG, "Can't force stop all processes of all users, that is insane!"); 4525 } 4526 4527 if (appId < 0 && name != null) { 4528 try { 4529 appId = UserHandle.getAppId( 4530 AppGlobals.getPackageManager().getPackageUid(name, 0)); 4531 } catch (RemoteException e) { 4532 } 4533 } 4534 4535 if (doit) { 4536 if (name != null) { 4537 Slog.i(TAG, "Force stopping " + name + " appid=" + appId 4538 + " user=" + userId + ": " + reason); 4539 } else { 4540 Slog.i(TAG, "Force stopping u" + userId + ": " + reason); 4541 } 4542 4543 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap(); 4544 for (int ip=pmap.size()-1; ip>=0; ip--) { 4545 SparseArray<Long> ba = pmap.valueAt(ip); 4546 for (i=ba.size()-1; i>=0; i--) { 4547 boolean remove = false; 4548 final int entUid = ba.keyAt(i); 4549 if (name != null) { 4550 if (userId == UserHandle.USER_ALL) { 4551 if (UserHandle.getAppId(entUid) == appId) { 4552 remove = true; 4553 } 4554 } else { 4555 if (entUid == UserHandle.getUid(userId, appId)) { 4556 remove = true; 4557 } 4558 } 4559 } else if (UserHandle.getUserId(entUid) == userId) { 4560 remove = true; 4561 } 4562 if (remove) { 4563 ba.removeAt(i); 4564 } 4565 } 4566 if (ba.size() == 0) { 4567 pmap.removeAt(ip); 4568 } 4569 } 4570 } 4571 4572 boolean didSomething = killPackageProcessesLocked(name, appId, userId, 4573 -100, callerWillRestart, true, doit, evenPersistent, 4574 name == null ? ("stop user " + userId) : ("stop " + name)); 4575 4576 if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) { 4577 if (!doit) { 4578 return true; 4579 } 4580 didSomething = true; 4581 } 4582 4583 if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) { 4584 if (!doit) { 4585 return true; 4586 } 4587 didSomething = true; 4588 } 4589 4590 if (name == null) { 4591 // Remove all sticky broadcasts from this user. 4592 mStickyBroadcasts.remove(userId); 4593 } 4594 4595 ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>(); 4596 if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent, 4597 userId, providers)) { 4598 if (!doit) { 4599 return true; 4600 } 4601 didSomething = true; 4602 } 4603 N = providers.size(); 4604 for (i=0; i<N; i++) { 4605 removeDyingProviderLocked(null, providers.get(i), true); 4606 } 4607 4608 // Remove transient permissions granted from/to this package/user 4609 removeUriPermissionsForPackageLocked(name, userId, false); 4610 4611 if (name == null) { 4612 // Remove pending intents. For now we only do this when force 4613 // stopping users, because we have some problems when doing this 4614 // for packages -- app widgets are not currently cleaned up for 4615 // such packages, so they can be left with bad pending intents. 4616 if (mIntentSenderRecords.size() > 0) { 4617 Iterator<WeakReference<PendingIntentRecord>> it 4618 = mIntentSenderRecords.values().iterator(); 4619 while (it.hasNext()) { 4620 WeakReference<PendingIntentRecord> wpir = it.next(); 4621 if (wpir == null) { 4622 it.remove(); 4623 continue; 4624 } 4625 PendingIntentRecord pir = wpir.get(); 4626 if (pir == null) { 4627 it.remove(); 4628 continue; 4629 } 4630 if (name == null) { 4631 // Stopping user, remove all objects for the user. 4632 if (pir.key.userId != userId) { 4633 // Not the same user, skip it. 4634 continue; 4635 } 4636 } else { 4637 if (UserHandle.getAppId(pir.uid) != appId) { 4638 // Different app id, skip it. 4639 continue; 4640 } 4641 if (userId != UserHandle.USER_ALL && pir.key.userId != userId) { 4642 // Different user, skip it. 4643 continue; 4644 } 4645 if (!pir.key.packageName.equals(name)) { 4646 // Different package, skip it. 4647 continue; 4648 } 4649 } 4650 if (!doit) { 4651 return true; 4652 } 4653 didSomething = true; 4654 it.remove(); 4655 pir.canceled = true; 4656 if (pir.key.activity != null) { 4657 pir.key.activity.pendingResults.remove(pir.ref); 4658 } 4659 } 4660 } 4661 } 4662 4663 if (doit) { 4664 if (purgeCache && name != null) { 4665 AttributeCache ac = AttributeCache.instance(); 4666 if (ac != null) { 4667 ac.removePackage(name); 4668 } 4669 } 4670 if (mBooted) { 4671 mStackSupervisor.resumeTopActivitiesLocked(); 4672 mStackSupervisor.scheduleIdleLocked(); 4673 } 4674 } 4675 4676 return didSomething; 4677 } 4678 4679 private final boolean removeProcessLocked(ProcessRecord app, 4680 boolean callerWillRestart, boolean allowRestart, String reason) { 4681 final String name = app.processName; 4682 final int uid = app.uid; 4683 if (DEBUG_PROCESSES) Slog.d( 4684 TAG, "Force removing proc " + app.toShortString() + " (" + name 4685 + "/" + uid + ")"); 4686 4687 mProcessNames.remove(name, uid); 4688 mIsolatedProcesses.remove(app.uid); 4689 if (mHeavyWeightProcess == app) { 4690 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 4691 mHeavyWeightProcess.userId, 0)); 4692 mHeavyWeightProcess = null; 4693 } 4694 boolean needRestart = false; 4695 if (app.pid > 0 && app.pid != MY_PID) { 4696 int pid = app.pid; 4697 synchronized (mPidsSelfLocked) { 4698 mPidsSelfLocked.remove(pid); 4699 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 4700 } 4701 killUnneededProcessLocked(app, reason); 4702 handleAppDiedLocked(app, true, allowRestart); 4703 removeLruProcessLocked(app); 4704 4705 if (app.persistent && !app.isolated) { 4706 if (!callerWillRestart) { 4707 addAppLocked(app.info, false); 4708 } else { 4709 needRestart = true; 4710 } 4711 } 4712 } else { 4713 mRemovedProcesses.add(app); 4714 } 4715 4716 return needRestart; 4717 } 4718 4719 private final void processStartTimedOutLocked(ProcessRecord app) { 4720 final int pid = app.pid; 4721 boolean gone = false; 4722 synchronized (mPidsSelfLocked) { 4723 ProcessRecord knownApp = mPidsSelfLocked.get(pid); 4724 if (knownApp != null && knownApp.thread == null) { 4725 mPidsSelfLocked.remove(pid); 4726 gone = true; 4727 } 4728 } 4729 4730 if (gone) { 4731 Slog.w(TAG, "Process " + app + " failed to attach"); 4732 EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId, 4733 pid, app.uid, app.processName); 4734 mProcessNames.remove(app.processName, app.uid); 4735 mIsolatedProcesses.remove(app.uid); 4736 if (mHeavyWeightProcess == app) { 4737 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 4738 mHeavyWeightProcess.userId, 0)); 4739 mHeavyWeightProcess = null; 4740 } 4741 // Take care of any launching providers waiting for this process. 4742 checkAppInLaunchingProvidersLocked(app, true); 4743 // Take care of any services that are waiting for the process. 4744 mServices.processStartTimedOutLocked(app); 4745 killUnneededProcessLocked(app, "start timeout"); 4746 if (mBackupTarget != null && mBackupTarget.app.pid == pid) { 4747 Slog.w(TAG, "Unattached app died before backup, skipping"); 4748 try { 4749 IBackupManager bm = IBackupManager.Stub.asInterface( 4750 ServiceManager.getService(Context.BACKUP_SERVICE)); 4751 bm.agentDisconnected(app.info.packageName); 4752 } catch (RemoteException e) { 4753 // Can't happen; the backup manager is local 4754 } 4755 } 4756 if (isPendingBroadcastProcessLocked(pid)) { 4757 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 4758 skipPendingBroadcastLocked(pid); 4759 } 4760 } else { 4761 Slog.w(TAG, "Spurious process start timeout - pid not known for " + app); 4762 } 4763 } 4764 4765 private final boolean attachApplicationLocked(IApplicationThread thread, 4766 int pid) { 4767 4768 // Find the application record that is being attached... either via 4769 // the pid if we are running in multiple processes, or just pull the 4770 // next app record if we are emulating process with anonymous threads. 4771 ProcessRecord app; 4772 if (pid != MY_PID && pid >= 0) { 4773 synchronized (mPidsSelfLocked) { 4774 app = mPidsSelfLocked.get(pid); 4775 } 4776 } else { 4777 app = null; 4778 } 4779 4780 if (app == null) { 4781 Slog.w(TAG, "No pending application record for pid " + pid 4782 + " (IApplicationThread " + thread + "); dropping process"); 4783 EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid); 4784 if (pid > 0 && pid != MY_PID) { 4785 Process.killProcessQuiet(pid); 4786 } else { 4787 try { 4788 thread.scheduleExit(); 4789 } catch (Exception e) { 4790 // Ignore exceptions. 4791 } 4792 } 4793 return false; 4794 } 4795 4796 // If this application record is still attached to a previous 4797 // process, clean it up now. 4798 if (app.thread != null) { 4799 handleAppDiedLocked(app, true, true); 4800 } 4801 4802 // Tell the process all about itself. 4803 4804 if (localLOGV) Slog.v( 4805 TAG, "Binding process pid " + pid + " to record " + app); 4806 4807 final String processName = app.processName; 4808 try { 4809 AppDeathRecipient adr = new AppDeathRecipient( 4810 app, pid, thread); 4811 thread.asBinder().linkToDeath(adr, 0); 4812 app.deathRecipient = adr; 4813 } catch (RemoteException e) { 4814 app.resetPackageList(mProcessStats); 4815 startProcessLocked(app, "link fail", processName); 4816 return false; 4817 } 4818 4819 EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName); 4820 4821 app.makeActive(thread, mProcessStats); 4822 app.curAdj = app.setAdj = -100; 4823 app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT; 4824 app.forcingToForeground = null; 4825 app.foregroundServices = false; 4826 app.hasShownUi = false; 4827 app.debugging = false; 4828 app.cached = false; 4829 4830 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 4831 4832 boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info); 4833 List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null; 4834 4835 if (!normalMode) { 4836 Slog.i(TAG, "Launching preboot mode app: " + app); 4837 } 4838 4839 if (localLOGV) Slog.v( 4840 TAG, "New app record " + app 4841 + " thread=" + thread.asBinder() + " pid=" + pid); 4842 try { 4843 int testMode = IApplicationThread.DEBUG_OFF; 4844 if (mDebugApp != null && mDebugApp.equals(processName)) { 4845 testMode = mWaitForDebugger 4846 ? IApplicationThread.DEBUG_WAIT 4847 : IApplicationThread.DEBUG_ON; 4848 app.debugging = true; 4849 if (mDebugTransient) { 4850 mDebugApp = mOrigDebugApp; 4851 mWaitForDebugger = mOrigWaitForDebugger; 4852 } 4853 } 4854 String profileFile = app.instrumentationProfileFile; 4855 ParcelFileDescriptor profileFd = null; 4856 boolean profileAutoStop = false; 4857 if (mProfileApp != null && mProfileApp.equals(processName)) { 4858 mProfileProc = app; 4859 profileFile = mProfileFile; 4860 profileFd = mProfileFd; 4861 profileAutoStop = mAutoStopProfiler; 4862 } 4863 boolean enableOpenGlTrace = false; 4864 if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) { 4865 enableOpenGlTrace = true; 4866 mOpenGlTraceApp = null; 4867 } 4868 4869 // If the app is being launched for restore or full backup, set it up specially 4870 boolean isRestrictedBackupMode = false; 4871 if (mBackupTarget != null && mBackupAppName.equals(processName)) { 4872 isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE) 4873 || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL) 4874 || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL); 4875 } 4876 4877 ensurePackageDexOpt(app.instrumentationInfo != null 4878 ? app.instrumentationInfo.packageName 4879 : app.info.packageName); 4880 if (app.instrumentationClass != null) { 4881 ensurePackageDexOpt(app.instrumentationClass.getPackageName()); 4882 } 4883 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc " 4884 + processName + " with config " + mConfiguration); 4885 ApplicationInfo appInfo = app.instrumentationInfo != null 4886 ? app.instrumentationInfo : app.info; 4887 app.compat = compatibilityInfoForPackageLocked(appInfo); 4888 if (profileFd != null) { 4889 profileFd = profileFd.dup(); 4890 } 4891 thread.bindApplication(processName, appInfo, providers, 4892 app.instrumentationClass, profileFile, profileFd, profileAutoStop, 4893 app.instrumentationArguments, app.instrumentationWatcher, 4894 app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace, 4895 isRestrictedBackupMode || !normalMode, app.persistent, 4896 new Configuration(mConfiguration), app.compat, getCommonServicesLocked(), 4897 mCoreSettingsObserver.getCoreSettingsLocked()); 4898 updateLruProcessLocked(app, false, null); 4899 app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis(); 4900 } catch (Exception e) { 4901 // todo: Yikes! What should we do? For now we will try to 4902 // start another process, but that could easily get us in 4903 // an infinite loop of restarting processes... 4904 Slog.w(TAG, "Exception thrown during bind!", e); 4905 4906 app.resetPackageList(mProcessStats); 4907 app.unlinkDeathRecipient(); 4908 startProcessLocked(app, "bind fail", processName); 4909 return false; 4910 } 4911 4912 // Remove this record from the list of starting applications. 4913 mPersistentStartingProcesses.remove(app); 4914 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 4915 "Attach application locked removing on hold: " + app); 4916 mProcessesOnHold.remove(app); 4917 4918 boolean badApp = false; 4919 boolean didSomething = false; 4920 4921 // See if the top visible activity is waiting to run in this process... 4922 if (normalMode) { 4923 try { 4924 if (mStackSupervisor.attachApplicationLocked(app)) { 4925 didSomething = true; 4926 } 4927 } catch (Exception e) { 4928 badApp = true; 4929 } 4930 } 4931 4932 // Find any services that should be running in this process... 4933 if (!badApp) { 4934 try { 4935 didSomething |= mServices.attachApplicationLocked(app, processName); 4936 } catch (Exception e) { 4937 badApp = true; 4938 } 4939 } 4940 4941 // Check if a next-broadcast receiver is in this process... 4942 if (!badApp && isPendingBroadcastProcessLocked(pid)) { 4943 try { 4944 didSomething |= sendPendingBroadcastsLocked(app); 4945 } catch (Exception e) { 4946 // If the app died trying to launch the receiver we declare it 'bad' 4947 badApp = true; 4948 } 4949 } 4950 4951 // Check whether the next backup agent is in this process... 4952 if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) { 4953 if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app); 4954 ensurePackageDexOpt(mBackupTarget.appInfo.packageName); 4955 try { 4956 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo, 4957 compatibilityInfoForPackageLocked(mBackupTarget.appInfo), 4958 mBackupTarget.backupMode); 4959 } catch (Exception e) { 4960 Slog.w(TAG, "Exception scheduling backup agent creation: "); 4961 e.printStackTrace(); 4962 } 4963 } 4964 4965 if (badApp) { 4966 // todo: Also need to kill application to deal with all 4967 // kinds of exceptions. 4968 handleAppDiedLocked(app, false, true); 4969 return false; 4970 } 4971 4972 if (!didSomething) { 4973 updateOomAdjLocked(); 4974 } 4975 4976 return true; 4977 } 4978 4979 @Override 4980 public final void attachApplication(IApplicationThread thread) { 4981 synchronized (this) { 4982 int callingPid = Binder.getCallingPid(); 4983 final long origId = Binder.clearCallingIdentity(); 4984 attachApplicationLocked(thread, callingPid); 4985 Binder.restoreCallingIdentity(origId); 4986 } 4987 } 4988 4989 @Override 4990 public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) { 4991 final long origId = Binder.clearCallingIdentity(); 4992 synchronized (this) { 4993 ActivityStack stack = ActivityRecord.getStackLocked(token); 4994 if (stack != null) { 4995 ActivityRecord r = 4996 mStackSupervisor.activityIdleInternalLocked(token, false, config); 4997 if (stopProfiling) { 4998 if ((mProfileProc == r.app) && (mProfileFd != null)) { 4999 try { 5000 mProfileFd.close(); 5001 } catch (IOException e) { 5002 } 5003 clearProfilerLocked(); 5004 } 5005 } 5006 } 5007 } 5008 Binder.restoreCallingIdentity(origId); 5009 } 5010 5011 void enableScreenAfterBoot() { 5012 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN, 5013 SystemClock.uptimeMillis()); 5014 mWindowManager.enableScreenAfterBoot(); 5015 5016 synchronized (this) { 5017 updateEventDispatchingLocked(); 5018 } 5019 } 5020 5021 @Override 5022 public void showBootMessage(final CharSequence msg, final boolean always) { 5023 enforceNotIsolatedCaller("showBootMessage"); 5024 mWindowManager.showBootMessage(msg, always); 5025 } 5026 5027 @Override 5028 public void dismissKeyguardOnNextActivity() { 5029 enforceNotIsolatedCaller("dismissKeyguardOnNextActivity"); 5030 final long token = Binder.clearCallingIdentity(); 5031 try { 5032 synchronized (this) { 5033 if (DEBUG_LOCKSCREEN) logLockScreen(""); 5034 if (mLockScreenShown) { 5035 mLockScreenShown = false; 5036 comeOutOfSleepIfNeededLocked(); 5037 } 5038 mStackSupervisor.setDismissKeyguard(true); 5039 } 5040 } finally { 5041 Binder.restoreCallingIdentity(token); 5042 } 5043 } 5044 5045 final void finishBooting() { 5046 IntentFilter pkgFilter = new IntentFilter(); 5047 pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART); 5048 pkgFilter.addDataScheme("package"); 5049 mContext.registerReceiver(new BroadcastReceiver() { 5050 @Override 5051 public void onReceive(Context context, Intent intent) { 5052 String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES); 5053 if (pkgs != null) { 5054 for (String pkg : pkgs) { 5055 synchronized (ActivityManagerService.this) { 5056 if (forceStopPackageLocked(pkg, -1, false, false, false, false, 0, 5057 "finished booting")) { 5058 setResultCode(Activity.RESULT_OK); 5059 return; 5060 } 5061 } 5062 } 5063 } 5064 } 5065 }, pkgFilter); 5066 5067 synchronized (this) { 5068 // Ensure that any processes we had put on hold are now started 5069 // up. 5070 final int NP = mProcessesOnHold.size(); 5071 if (NP > 0) { 5072 ArrayList<ProcessRecord> procs = 5073 new ArrayList<ProcessRecord>(mProcessesOnHold); 5074 for (int ip=0; ip<NP; ip++) { 5075 if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: " 5076 + procs.get(ip)); 5077 startProcessLocked(procs.get(ip), "on-hold", null); 5078 } 5079 } 5080 5081 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 5082 // Start looking for apps that are abusing wake locks. 5083 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 5084 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 5085 // Tell anyone interested that we are done booting! 5086 SystemProperties.set("sys.boot_completed", "1"); 5087 SystemProperties.set("dev.bootcomplete", "1"); 5088 for (int i=0; i<mStartedUsers.size(); i++) { 5089 UserStartedState uss = mStartedUsers.valueAt(i); 5090 if (uss.mState == UserStartedState.STATE_BOOTING) { 5091 uss.mState = UserStartedState.STATE_RUNNING; 5092 final int userId = mStartedUsers.keyAt(i); 5093 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 5094 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 5095 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT); 5096 broadcastIntentLocked(null, null, intent, null, 5097 new IIntentReceiver.Stub() { 5098 @Override 5099 public void performReceive(Intent intent, int resultCode, 5100 String data, Bundle extras, boolean ordered, 5101 boolean sticky, int sendingUser) { 5102 synchronized (ActivityManagerService.this) { 5103 requestPssAllProcsLocked(SystemClock.uptimeMillis(), 5104 true, false); 5105 } 5106 } 5107 }, 5108 0, null, null, 5109 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, 5110 AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID, 5111 userId); 5112 } 5113 } 5114 } 5115 } 5116 } 5117 5118 final void ensureBootCompleted() { 5119 boolean booting; 5120 boolean enableScreen; 5121 synchronized (this) { 5122 booting = mBooting; 5123 mBooting = false; 5124 enableScreen = !mBooted; 5125 mBooted = true; 5126 } 5127 5128 if (booting) { 5129 finishBooting(); 5130 } 5131 5132 if (enableScreen) { 5133 enableScreenAfterBoot(); 5134 } 5135 } 5136 5137 @Override 5138 public final void activityResumed(IBinder token) { 5139 final long origId = Binder.clearCallingIdentity(); 5140 synchronized(this) { 5141 ActivityStack stack = ActivityRecord.getStackLocked(token); 5142 if (stack != null) { 5143 ActivityRecord.activityResumedLocked(token); 5144 } 5145 } 5146 Binder.restoreCallingIdentity(origId); 5147 } 5148 5149 @Override 5150 public final void activityPaused(IBinder token) { 5151 final long origId = Binder.clearCallingIdentity(); 5152 synchronized(this) { 5153 ActivityStack stack = ActivityRecord.getStackLocked(token); 5154 if (stack != null) { 5155 stack.activityPausedLocked(token, false); 5156 } 5157 } 5158 Binder.restoreCallingIdentity(origId); 5159 } 5160 5161 @Override 5162 public final void activityStopped(IBinder token, Bundle icicle, Bitmap thumbnail, 5163 CharSequence description) { 5164 if (localLOGV) Slog.v( 5165 TAG, "Activity stopped: token=" + token); 5166 5167 // Refuse possible leaked file descriptors 5168 if (icicle != null && icicle.hasFileDescriptors()) { 5169 throw new IllegalArgumentException("File descriptors passed in Bundle"); 5170 } 5171 5172 ActivityRecord r = null; 5173 5174 final long origId = Binder.clearCallingIdentity(); 5175 5176 synchronized (this) { 5177 r = ActivityRecord.isInStackLocked(token); 5178 if (r != null) { 5179 r.task.stack.activityStoppedLocked(r, icicle, thumbnail, description); 5180 } 5181 } 5182 5183 if (r != null) { 5184 sendPendingThumbnail(r, null, null, null, false); 5185 } 5186 5187 trimApplications(); 5188 5189 Binder.restoreCallingIdentity(origId); 5190 } 5191 5192 @Override 5193 public final void activityDestroyed(IBinder token) { 5194 if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token); 5195 synchronized (this) { 5196 ActivityStack stack = ActivityRecord.getStackLocked(token); 5197 if (stack != null) { 5198 stack.activityDestroyedLocked(token); 5199 } 5200 } 5201 } 5202 5203 @Override 5204 public String getCallingPackage(IBinder token) { 5205 synchronized (this) { 5206 ActivityRecord r = getCallingRecordLocked(token); 5207 return r != null ? r.info.packageName : null; 5208 } 5209 } 5210 5211 @Override 5212 public ComponentName getCallingActivity(IBinder token) { 5213 synchronized (this) { 5214 ActivityRecord r = getCallingRecordLocked(token); 5215 return r != null ? r.intent.getComponent() : null; 5216 } 5217 } 5218 5219 private ActivityRecord getCallingRecordLocked(IBinder token) { 5220 ActivityRecord r = ActivityRecord.isInStackLocked(token); 5221 if (r == null) { 5222 return null; 5223 } 5224 return r.resultTo; 5225 } 5226 5227 @Override 5228 public ComponentName getActivityClassForToken(IBinder token) { 5229 synchronized(this) { 5230 ActivityRecord r = ActivityRecord.isInStackLocked(token); 5231 if (r == null) { 5232 return null; 5233 } 5234 return r.intent.getComponent(); 5235 } 5236 } 5237 5238 @Override 5239 public String getPackageForToken(IBinder token) { 5240 synchronized(this) { 5241 ActivityRecord r = ActivityRecord.isInStackLocked(token); 5242 if (r == null) { 5243 return null; 5244 } 5245 return r.packageName; 5246 } 5247 } 5248 5249 @Override 5250 public IIntentSender getIntentSender(int type, 5251 String packageName, IBinder token, String resultWho, 5252 int requestCode, Intent[] intents, String[] resolvedTypes, 5253 int flags, Bundle options, int userId) { 5254 enforceNotIsolatedCaller("getIntentSender"); 5255 // Refuse possible leaked file descriptors 5256 if (intents != null) { 5257 if (intents.length < 1) { 5258 throw new IllegalArgumentException("Intents array length must be >= 1"); 5259 } 5260 for (int i=0; i<intents.length; i++) { 5261 Intent intent = intents[i]; 5262 if (intent != null) { 5263 if (intent.hasFileDescriptors()) { 5264 throw new IllegalArgumentException("File descriptors passed in Intent"); 5265 } 5266 if (type == ActivityManager.INTENT_SENDER_BROADCAST && 5267 (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 5268 throw new IllegalArgumentException( 5269 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 5270 } 5271 intents[i] = new Intent(intent); 5272 } 5273 } 5274 if (resolvedTypes != null && resolvedTypes.length != intents.length) { 5275 throw new IllegalArgumentException( 5276 "Intent array length does not match resolvedTypes length"); 5277 } 5278 } 5279 if (options != null) { 5280 if (options.hasFileDescriptors()) { 5281 throw new IllegalArgumentException("File descriptors passed in options"); 5282 } 5283 } 5284 5285 synchronized(this) { 5286 int callingUid = Binder.getCallingUid(); 5287 int origUserId = userId; 5288 userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId, 5289 type == ActivityManager.INTENT_SENDER_BROADCAST, false, 5290 "getIntentSender", null); 5291 if (origUserId == UserHandle.USER_CURRENT) { 5292 // We don't want to evaluate this until the pending intent is 5293 // actually executed. However, we do want to always do the 5294 // security checking for it above. 5295 userId = UserHandle.USER_CURRENT; 5296 } 5297 try { 5298 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 5299 int uid = AppGlobals.getPackageManager() 5300 .getPackageUid(packageName, UserHandle.getUserId(callingUid)); 5301 if (!UserHandle.isSameApp(callingUid, uid)) { 5302 String msg = "Permission Denial: getIntentSender() from pid=" 5303 + Binder.getCallingPid() 5304 + ", uid=" + Binder.getCallingUid() 5305 + ", (need uid=" + uid + ")" 5306 + " is not allowed to send as package " + packageName; 5307 Slog.w(TAG, msg); 5308 throw new SecurityException(msg); 5309 } 5310 } 5311 5312 return getIntentSenderLocked(type, packageName, callingUid, userId, 5313 token, resultWho, requestCode, intents, resolvedTypes, flags, options); 5314 5315 } catch (RemoteException e) { 5316 throw new SecurityException(e); 5317 } 5318 } 5319 } 5320 5321 IIntentSender getIntentSenderLocked(int type, String packageName, 5322 int callingUid, int userId, IBinder token, String resultWho, 5323 int requestCode, Intent[] intents, String[] resolvedTypes, int flags, 5324 Bundle options) { 5325 if (DEBUG_MU) 5326 Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid); 5327 ActivityRecord activity = null; 5328 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 5329 activity = ActivityRecord.isInStackLocked(token); 5330 if (activity == null) { 5331 return null; 5332 } 5333 if (activity.finishing) { 5334 return null; 5335 } 5336 } 5337 5338 final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0; 5339 final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0; 5340 final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0; 5341 flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT 5342 |PendingIntent.FLAG_UPDATE_CURRENT); 5343 5344 PendingIntentRecord.Key key = new PendingIntentRecord.Key( 5345 type, packageName, activity, resultWho, 5346 requestCode, intents, resolvedTypes, flags, options, userId); 5347 WeakReference<PendingIntentRecord> ref; 5348 ref = mIntentSenderRecords.get(key); 5349 PendingIntentRecord rec = ref != null ? ref.get() : null; 5350 if (rec != null) { 5351 if (!cancelCurrent) { 5352 if (updateCurrent) { 5353 if (rec.key.requestIntent != null) { 5354 rec.key.requestIntent.replaceExtras(intents != null ? 5355 intents[intents.length - 1] : null); 5356 } 5357 if (intents != null) { 5358 intents[intents.length-1] = rec.key.requestIntent; 5359 rec.key.allIntents = intents; 5360 rec.key.allResolvedTypes = resolvedTypes; 5361 } else { 5362 rec.key.allIntents = null; 5363 rec.key.allResolvedTypes = null; 5364 } 5365 } 5366 return rec; 5367 } 5368 rec.canceled = true; 5369 mIntentSenderRecords.remove(key); 5370 } 5371 if (noCreate) { 5372 return rec; 5373 } 5374 rec = new PendingIntentRecord(this, key, callingUid); 5375 mIntentSenderRecords.put(key, rec.ref); 5376 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 5377 if (activity.pendingResults == null) { 5378 activity.pendingResults 5379 = new HashSet<WeakReference<PendingIntentRecord>>(); 5380 } 5381 activity.pendingResults.add(rec.ref); 5382 } 5383 return rec; 5384 } 5385 5386 @Override 5387 public void cancelIntentSender(IIntentSender sender) { 5388 if (!(sender instanceof PendingIntentRecord)) { 5389 return; 5390 } 5391 synchronized(this) { 5392 PendingIntentRecord rec = (PendingIntentRecord)sender; 5393 try { 5394 int uid = AppGlobals.getPackageManager() 5395 .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId()); 5396 if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) { 5397 String msg = "Permission Denial: cancelIntentSender() from pid=" 5398 + Binder.getCallingPid() 5399 + ", uid=" + Binder.getCallingUid() 5400 + " is not allowed to cancel packges " 5401 + rec.key.packageName; 5402 Slog.w(TAG, msg); 5403 throw new SecurityException(msg); 5404 } 5405 } catch (RemoteException e) { 5406 throw new SecurityException(e); 5407 } 5408 cancelIntentSenderLocked(rec, true); 5409 } 5410 } 5411 5412 void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) { 5413 rec.canceled = true; 5414 mIntentSenderRecords.remove(rec.key); 5415 if (cleanActivity && rec.key.activity != null) { 5416 rec.key.activity.pendingResults.remove(rec.ref); 5417 } 5418 } 5419 5420 @Override 5421 public String getPackageForIntentSender(IIntentSender pendingResult) { 5422 if (!(pendingResult instanceof PendingIntentRecord)) { 5423 return null; 5424 } 5425 try { 5426 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5427 return res.key.packageName; 5428 } catch (ClassCastException e) { 5429 } 5430 return null; 5431 } 5432 5433 @Override 5434 public int getUidForIntentSender(IIntentSender sender) { 5435 if (sender instanceof PendingIntentRecord) { 5436 try { 5437 PendingIntentRecord res = (PendingIntentRecord)sender; 5438 return res.uid; 5439 } catch (ClassCastException e) { 5440 } 5441 } 5442 return -1; 5443 } 5444 5445 @Override 5446 public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) { 5447 if (!(pendingResult instanceof PendingIntentRecord)) { 5448 return false; 5449 } 5450 try { 5451 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5452 if (res.key.allIntents == null) { 5453 return false; 5454 } 5455 for (int i=0; i<res.key.allIntents.length; i++) { 5456 Intent intent = res.key.allIntents[i]; 5457 if (intent.getPackage() != null && intent.getComponent() != null) { 5458 return false; 5459 } 5460 } 5461 return true; 5462 } catch (ClassCastException e) { 5463 } 5464 return false; 5465 } 5466 5467 @Override 5468 public boolean isIntentSenderAnActivity(IIntentSender pendingResult) { 5469 if (!(pendingResult instanceof PendingIntentRecord)) { 5470 return false; 5471 } 5472 try { 5473 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5474 if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) { 5475 return true; 5476 } 5477 return false; 5478 } catch (ClassCastException e) { 5479 } 5480 return false; 5481 } 5482 5483 @Override 5484 public Intent getIntentForIntentSender(IIntentSender pendingResult) { 5485 if (!(pendingResult instanceof PendingIntentRecord)) { 5486 return null; 5487 } 5488 try { 5489 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5490 return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null; 5491 } catch (ClassCastException e) { 5492 } 5493 return null; 5494 } 5495 5496 @Override 5497 public void setProcessLimit(int max) { 5498 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 5499 "setProcessLimit()"); 5500 synchronized (this) { 5501 mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max; 5502 mProcessLimitOverride = max; 5503 } 5504 trimApplications(); 5505 } 5506 5507 @Override 5508 public int getProcessLimit() { 5509 synchronized (this) { 5510 return mProcessLimitOverride; 5511 } 5512 } 5513 5514 void foregroundTokenDied(ForegroundToken token) { 5515 synchronized (ActivityManagerService.this) { 5516 synchronized (mPidsSelfLocked) { 5517 ForegroundToken cur 5518 = mForegroundProcesses.get(token.pid); 5519 if (cur != token) { 5520 return; 5521 } 5522 mForegroundProcesses.remove(token.pid); 5523 ProcessRecord pr = mPidsSelfLocked.get(token.pid); 5524 if (pr == null) { 5525 return; 5526 } 5527 pr.forcingToForeground = null; 5528 pr.foregroundServices = false; 5529 } 5530 updateOomAdjLocked(); 5531 } 5532 } 5533 5534 @Override 5535 public void setProcessForeground(IBinder token, int pid, boolean isForeground) { 5536 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 5537 "setProcessForeground()"); 5538 synchronized(this) { 5539 boolean changed = false; 5540 5541 synchronized (mPidsSelfLocked) { 5542 ProcessRecord pr = mPidsSelfLocked.get(pid); 5543 if (pr == null && isForeground) { 5544 Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid); 5545 return; 5546 } 5547 ForegroundToken oldToken = mForegroundProcesses.get(pid); 5548 if (oldToken != null) { 5549 oldToken.token.unlinkToDeath(oldToken, 0); 5550 mForegroundProcesses.remove(pid); 5551 if (pr != null) { 5552 pr.forcingToForeground = null; 5553 } 5554 changed = true; 5555 } 5556 if (isForeground && token != null) { 5557 ForegroundToken newToken = new ForegroundToken() { 5558 @Override 5559 public void binderDied() { 5560 foregroundTokenDied(this); 5561 } 5562 }; 5563 newToken.pid = pid; 5564 newToken.token = token; 5565 try { 5566 token.linkToDeath(newToken, 0); 5567 mForegroundProcesses.put(pid, newToken); 5568 pr.forcingToForeground = token; 5569 changed = true; 5570 } catch (RemoteException e) { 5571 // If the process died while doing this, we will later 5572 // do the cleanup with the process death link. 5573 } 5574 } 5575 } 5576 5577 if (changed) { 5578 updateOomAdjLocked(); 5579 } 5580 } 5581 } 5582 5583 // ========================================================= 5584 // PERMISSIONS 5585 // ========================================================= 5586 5587 static class PermissionController extends IPermissionController.Stub { 5588 ActivityManagerService mActivityManagerService; 5589 PermissionController(ActivityManagerService activityManagerService) { 5590 mActivityManagerService = activityManagerService; 5591 } 5592 5593 @Override 5594 public boolean checkPermission(String permission, int pid, int uid) { 5595 return mActivityManagerService.checkPermission(permission, pid, 5596 uid) == PackageManager.PERMISSION_GRANTED; 5597 } 5598 } 5599 5600 class IntentFirewallInterface implements IntentFirewall.AMSInterface { 5601 @Override 5602 public int checkComponentPermission(String permission, int pid, int uid, 5603 int owningUid, boolean exported) { 5604 return ActivityManagerService.this.checkComponentPermission(permission, pid, uid, 5605 owningUid, exported); 5606 } 5607 5608 @Override 5609 public Object getAMSLock() { 5610 return ActivityManagerService.this; 5611 } 5612 } 5613 5614 /** 5615 * This can be called with or without the global lock held. 5616 */ 5617 int checkComponentPermission(String permission, int pid, int uid, 5618 int owningUid, boolean exported) { 5619 // We might be performing an operation on behalf of an indirect binder 5620 // invocation, e.g. via {@link #openContentUri}. Check and adjust the 5621 // client identity accordingly before proceeding. 5622 Identity tlsIdentity = sCallerIdentity.get(); 5623 if (tlsIdentity != null) { 5624 Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {" 5625 + tlsIdentity.pid + "," + tlsIdentity.uid + "}"); 5626 uid = tlsIdentity.uid; 5627 pid = tlsIdentity.pid; 5628 } 5629 5630 if (pid == MY_PID) { 5631 return PackageManager.PERMISSION_GRANTED; 5632 } 5633 5634 return ActivityManager.checkComponentPermission(permission, uid, 5635 owningUid, exported); 5636 } 5637 5638 /** 5639 * As the only public entry point for permissions checking, this method 5640 * can enforce the semantic that requesting a check on a null global 5641 * permission is automatically denied. (Internally a null permission 5642 * string is used when calling {@link #checkComponentPermission} in cases 5643 * when only uid-based security is needed.) 5644 * 5645 * This can be called with or without the global lock held. 5646 */ 5647 @Override 5648 public int checkPermission(String permission, int pid, int uid) { 5649 if (permission == null) { 5650 return PackageManager.PERMISSION_DENIED; 5651 } 5652 return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true); 5653 } 5654 5655 /** 5656 * Binder IPC calls go through the public entry point. 5657 * This can be called with or without the global lock held. 5658 */ 5659 int checkCallingPermission(String permission) { 5660 return checkPermission(permission, 5661 Binder.getCallingPid(), 5662 UserHandle.getAppId(Binder.getCallingUid())); 5663 } 5664 5665 /** 5666 * This can be called with or without the global lock held. 5667 */ 5668 void enforceCallingPermission(String permission, String func) { 5669 if (checkCallingPermission(permission) 5670 == PackageManager.PERMISSION_GRANTED) { 5671 return; 5672 } 5673 5674 String msg = "Permission Denial: " + func + " from pid=" 5675 + Binder.getCallingPid() 5676 + ", uid=" + Binder.getCallingUid() 5677 + " requires " + permission; 5678 Slog.w(TAG, msg); 5679 throw new SecurityException(msg); 5680 } 5681 5682 /** 5683 * Determine if UID is holding permissions required to access {@link Uri} in 5684 * the given {@link ProviderInfo}. Final permission checking is always done 5685 * in {@link ContentProvider}. 5686 */ 5687 private final boolean checkHoldingPermissionsLocked( 5688 IPackageManager pm, ProviderInfo pi, Uri uri, int uid, int modeFlags) { 5689 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5690 "checkHoldingPermissionsLocked: uri=" + uri + " uid=" + uid); 5691 5692 if (pi.applicationInfo.uid == uid) { 5693 return true; 5694 } else if (!pi.exported) { 5695 return false; 5696 } 5697 5698 boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0; 5699 boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0; 5700 try { 5701 // check if target holds top-level <provider> permissions 5702 if (!readMet && pi.readPermission != null 5703 && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) { 5704 readMet = true; 5705 } 5706 if (!writeMet && pi.writePermission != null 5707 && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) { 5708 writeMet = true; 5709 } 5710 5711 // track if unprotected read/write is allowed; any denied 5712 // <path-permission> below removes this ability 5713 boolean allowDefaultRead = pi.readPermission == null; 5714 boolean allowDefaultWrite = pi.writePermission == null; 5715 5716 // check if target holds any <path-permission> that match uri 5717 final PathPermission[] pps = pi.pathPermissions; 5718 if (pps != null) { 5719 final String path = uri.getPath(); 5720 int i = pps.length; 5721 while (i > 0 && (!readMet || !writeMet)) { 5722 i--; 5723 PathPermission pp = pps[i]; 5724 if (pp.match(path)) { 5725 if (!readMet) { 5726 final String pprperm = pp.getReadPermission(); 5727 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for " 5728 + pprperm + " for " + pp.getPath() 5729 + ": match=" + pp.match(path) 5730 + " check=" + pm.checkUidPermission(pprperm, uid)); 5731 if (pprperm != null) { 5732 if (pm.checkUidPermission(pprperm, uid) == PERMISSION_GRANTED) { 5733 readMet = true; 5734 } else { 5735 allowDefaultRead = false; 5736 } 5737 } 5738 } 5739 if (!writeMet) { 5740 final String ppwperm = pp.getWritePermission(); 5741 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm " 5742 + ppwperm + " for " + pp.getPath() 5743 + ": match=" + pp.match(path) 5744 + " check=" + pm.checkUidPermission(ppwperm, uid)); 5745 if (ppwperm != null) { 5746 if (pm.checkUidPermission(ppwperm, uid) == PERMISSION_GRANTED) { 5747 writeMet = true; 5748 } else { 5749 allowDefaultWrite = false; 5750 } 5751 } 5752 } 5753 } 5754 } 5755 } 5756 5757 // grant unprotected <provider> read/write, if not blocked by 5758 // <path-permission> above 5759 if (allowDefaultRead) readMet = true; 5760 if (allowDefaultWrite) writeMet = true; 5761 5762 } catch (RemoteException e) { 5763 return false; 5764 } 5765 5766 return readMet && writeMet; 5767 } 5768 5769 private ProviderInfo getProviderInfoLocked(String authority, int userHandle) { 5770 ProviderInfo pi = null; 5771 ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle); 5772 if (cpr != null) { 5773 pi = cpr.info; 5774 } else { 5775 try { 5776 pi = AppGlobals.getPackageManager().resolveContentProvider( 5777 authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle); 5778 } catch (RemoteException ex) { 5779 } 5780 } 5781 return pi; 5782 } 5783 5784 private UriPermission findUriPermissionLocked(int targetUid, Uri uri) { 5785 ArrayMap<Uri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid); 5786 if (targetUris != null) { 5787 return targetUris.get(uri); 5788 } else { 5789 return null; 5790 } 5791 } 5792 5793 private UriPermission findOrCreateUriPermissionLocked( 5794 String sourcePkg, String targetPkg, int targetUid, Uri uri) { 5795 ArrayMap<Uri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid); 5796 if (targetUris == null) { 5797 targetUris = Maps.newArrayMap(); 5798 mGrantedUriPermissions.put(targetUid, targetUris); 5799 } 5800 5801 UriPermission perm = targetUris.get(uri); 5802 if (perm == null) { 5803 perm = new UriPermission(sourcePkg, targetPkg, targetUid, uri); 5804 targetUris.put(uri, perm); 5805 } 5806 5807 return perm; 5808 } 5809 5810 private final boolean checkUriPermissionLocked( 5811 Uri uri, int uid, int modeFlags, int minStrength) { 5812 // Root gets to do everything. 5813 if (uid == 0) { 5814 return true; 5815 } 5816 ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(uid); 5817 if (perms == null) return false; 5818 UriPermission perm = perms.get(uri); 5819 if (perm == null) return false; 5820 return perm.getStrength(modeFlags) >= minStrength; 5821 } 5822 5823 @Override 5824 public int checkUriPermission(Uri uri, int pid, int uid, int modeFlags) { 5825 enforceNotIsolatedCaller("checkUriPermission"); 5826 5827 // Another redirected-binder-call permissions check as in 5828 // {@link checkComponentPermission}. 5829 Identity tlsIdentity = sCallerIdentity.get(); 5830 if (tlsIdentity != null) { 5831 uid = tlsIdentity.uid; 5832 pid = tlsIdentity.pid; 5833 } 5834 5835 // Our own process gets to do everything. 5836 if (pid == MY_PID) { 5837 return PackageManager.PERMISSION_GRANTED; 5838 } 5839 synchronized(this) { 5840 return checkUriPermissionLocked(uri, uid, modeFlags, UriPermission.STRENGTH_OWNED) 5841 ? PackageManager.PERMISSION_GRANTED 5842 : PackageManager.PERMISSION_DENIED; 5843 } 5844 } 5845 5846 /** 5847 * Check if the targetPkg can be granted permission to access uri by 5848 * the callingUid using the given modeFlags. Throws a security exception 5849 * if callingUid is not allowed to do this. Returns the uid of the target 5850 * if the URI permission grant should be performed; returns -1 if it is not 5851 * needed (for example targetPkg already has permission to access the URI). 5852 * If you already know the uid of the target, you can supply it in 5853 * lastTargetUid else set that to -1. 5854 */ 5855 int checkGrantUriPermissionLocked(int callingUid, String targetPkg, 5856 Uri uri, int modeFlags, int lastTargetUid) { 5857 final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0; 5858 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION 5859 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 5860 if (modeFlags == 0) { 5861 return -1; 5862 } 5863 5864 if (targetPkg != null) { 5865 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5866 "Checking grant " + targetPkg + " permission to " + uri); 5867 } 5868 5869 final IPackageManager pm = AppGlobals.getPackageManager(); 5870 5871 // If this is not a content: uri, we can't do anything with it. 5872 if (!ContentResolver.SCHEME_CONTENT.equals(uri.getScheme())) { 5873 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5874 "Can't grant URI permission for non-content URI: " + uri); 5875 return -1; 5876 } 5877 5878 final String authority = uri.getAuthority(); 5879 final ProviderInfo pi = getProviderInfoLocked(authority, UserHandle.getUserId(callingUid)); 5880 if (pi == null) { 5881 Slog.w(TAG, "No content provider found for permission check: " + uri.toSafeString()); 5882 return -1; 5883 } 5884 5885 int targetUid = lastTargetUid; 5886 if (targetUid < 0 && targetPkg != null) { 5887 try { 5888 targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid)); 5889 if (targetUid < 0) { 5890 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5891 "Can't grant URI permission no uid for: " + targetPkg); 5892 return -1; 5893 } 5894 } catch (RemoteException ex) { 5895 return -1; 5896 } 5897 } 5898 5899 if (targetUid >= 0) { 5900 // First... does the target actually need this permission? 5901 if (checkHoldingPermissionsLocked(pm, pi, uri, targetUid, modeFlags)) { 5902 // No need to grant the target this permission. 5903 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5904 "Target " + targetPkg + " already has full permission to " + uri); 5905 return -1; 5906 } 5907 } else { 5908 // First... there is no target package, so can anyone access it? 5909 boolean allowed = pi.exported; 5910 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) { 5911 if (pi.readPermission != null) { 5912 allowed = false; 5913 } 5914 } 5915 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) { 5916 if (pi.writePermission != null) { 5917 allowed = false; 5918 } 5919 } 5920 if (allowed) { 5921 return -1; 5922 } 5923 } 5924 5925 // Second... is the provider allowing granting of URI permissions? 5926 if (!pi.grantUriPermissions) { 5927 throw new SecurityException("Provider " + pi.packageName 5928 + "/" + pi.name 5929 + " does not allow granting of Uri permissions (uri " 5930 + uri + ")"); 5931 } 5932 if (pi.uriPermissionPatterns != null) { 5933 final int N = pi.uriPermissionPatterns.length; 5934 boolean allowed = false; 5935 for (int i=0; i<N; i++) { 5936 if (pi.uriPermissionPatterns[i] != null 5937 && pi.uriPermissionPatterns[i].match(uri.getPath())) { 5938 allowed = true; 5939 break; 5940 } 5941 } 5942 if (!allowed) { 5943 throw new SecurityException("Provider " + pi.packageName 5944 + "/" + pi.name 5945 + " does not allow granting of permission to path of Uri " 5946 + uri); 5947 } 5948 } 5949 5950 // Third... does the caller itself have permission to access 5951 // this uri? 5952 if (callingUid != Process.myUid()) { 5953 if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) { 5954 // Require they hold a strong enough Uri permission 5955 final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE 5956 : UriPermission.STRENGTH_OWNED; 5957 if (!checkUriPermissionLocked(uri, callingUid, modeFlags, minStrength)) { 5958 throw new SecurityException("Uid " + callingUid 5959 + " does not have permission to uri " + uri); 5960 } 5961 } 5962 } 5963 5964 return targetUid; 5965 } 5966 5967 @Override 5968 public int checkGrantUriPermission(int callingUid, String targetPkg, 5969 Uri uri, int modeFlags) { 5970 enforceNotIsolatedCaller("checkGrantUriPermission"); 5971 synchronized(this) { 5972 return checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1); 5973 } 5974 } 5975 5976 void grantUriPermissionUncheckedLocked( 5977 int targetUid, String targetPkg, Uri uri, int modeFlags, UriPermissionOwner owner) { 5978 final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0; 5979 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION 5980 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 5981 if (modeFlags == 0) { 5982 return; 5983 } 5984 5985 // So here we are: the caller has the assumed permission 5986 // to the uri, and the target doesn't. Let's now give this to 5987 // the target. 5988 5989 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5990 "Granting " + targetPkg + "/" + targetUid + " permission to " + uri); 5991 5992 final String authority = uri.getAuthority(); 5993 final ProviderInfo pi = getProviderInfoLocked(authority, UserHandle.getUserId(targetUid)); 5994 if (pi == null) { 5995 Slog.w(TAG, "No content provider found for grant: " + uri.toSafeString()); 5996 return; 5997 } 5998 5999 final UriPermission perm = findOrCreateUriPermissionLocked( 6000 pi.packageName, targetPkg, targetUid, uri); 6001 perm.grantModes(modeFlags, persistable, owner); 6002 } 6003 6004 void grantUriPermissionLocked(int callingUid, String targetPkg, Uri uri, 6005 int modeFlags, UriPermissionOwner owner) { 6006 if (targetPkg == null) { 6007 throw new NullPointerException("targetPkg"); 6008 } 6009 6010 int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1); 6011 if (targetUid < 0) { 6012 return; 6013 } 6014 6015 grantUriPermissionUncheckedLocked(targetUid, targetPkg, uri, modeFlags, owner); 6016 } 6017 6018 static class NeededUriGrants extends ArrayList<Uri> { 6019 final String targetPkg; 6020 final int targetUid; 6021 final int flags; 6022 6023 NeededUriGrants(String targetPkg, int targetUid, int flags) { 6024 this.targetPkg = targetPkg; 6025 this.targetUid = targetUid; 6026 this.flags = flags; 6027 } 6028 } 6029 6030 /** 6031 * Like checkGrantUriPermissionLocked, but takes an Intent. 6032 */ 6033 NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid, 6034 String targetPkg, Intent intent, int mode, NeededUriGrants needed) { 6035 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6036 "Checking URI perm to data=" + (intent != null ? intent.getData() : null) 6037 + " clip=" + (intent != null ? intent.getClipData() : null) 6038 + " from " + intent + "; flags=0x" 6039 + Integer.toHexString(intent != null ? intent.getFlags() : 0)); 6040 6041 if (targetPkg == null) { 6042 throw new NullPointerException("targetPkg"); 6043 } 6044 6045 if (intent == null) { 6046 return null; 6047 } 6048 Uri data = intent.getData(); 6049 ClipData clip = intent.getClipData(); 6050 if (data == null && clip == null) { 6051 return null; 6052 } 6053 6054 if (data != null) { 6055 int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, data, 6056 mode, needed != null ? needed.targetUid : -1); 6057 if (targetUid > 0) { 6058 if (needed == null) { 6059 needed = new NeededUriGrants(targetPkg, targetUid, mode); 6060 } 6061 needed.add(data); 6062 } 6063 } 6064 if (clip != null) { 6065 for (int i=0; i<clip.getItemCount(); i++) { 6066 Uri uri = clip.getItemAt(i).getUri(); 6067 if (uri != null) { 6068 int targetUid = -1; 6069 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri, 6070 mode, needed != null ? needed.targetUid : -1); 6071 if (targetUid > 0) { 6072 if (needed == null) { 6073 needed = new NeededUriGrants(targetPkg, targetUid, mode); 6074 } 6075 needed.add(uri); 6076 } 6077 } else { 6078 Intent clipIntent = clip.getItemAt(i).getIntent(); 6079 if (clipIntent != null) { 6080 NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked( 6081 callingUid, targetPkg, clipIntent, mode, needed); 6082 if (newNeeded != null) { 6083 needed = newNeeded; 6084 } 6085 } 6086 } 6087 } 6088 } 6089 6090 return needed; 6091 } 6092 6093 /** 6094 * Like grantUriPermissionUncheckedLocked, but takes an Intent. 6095 */ 6096 void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed, 6097 UriPermissionOwner owner) { 6098 if (needed != null) { 6099 for (int i=0; i<needed.size(); i++) { 6100 grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg, 6101 needed.get(i), needed.flags, owner); 6102 } 6103 } 6104 } 6105 6106 void grantUriPermissionFromIntentLocked(int callingUid, 6107 String targetPkg, Intent intent, UriPermissionOwner owner) { 6108 NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg, 6109 intent, intent != null ? intent.getFlags() : 0, null); 6110 if (needed == null) { 6111 return; 6112 } 6113 6114 grantUriPermissionUncheckedFromIntentLocked(needed, owner); 6115 } 6116 6117 @Override 6118 public void grantUriPermission(IApplicationThread caller, String targetPkg, 6119 Uri uri, int modeFlags) { 6120 enforceNotIsolatedCaller("grantUriPermission"); 6121 synchronized(this) { 6122 final ProcessRecord r = getRecordForAppLocked(caller); 6123 if (r == null) { 6124 throw new SecurityException("Unable to find app for caller " 6125 + caller 6126 + " when granting permission to uri " + uri); 6127 } 6128 if (targetPkg == null) { 6129 throw new IllegalArgumentException("null target"); 6130 } 6131 if (uri == null) { 6132 throw new IllegalArgumentException("null uri"); 6133 } 6134 6135 // Persistable only supported through Intents 6136 Preconditions.checkFlagsArgument(modeFlags, 6137 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 6138 6139 grantUriPermissionLocked(r.uid, targetPkg, uri, modeFlags, 6140 null); 6141 } 6142 } 6143 6144 void removeUriPermissionIfNeededLocked(UriPermission perm) { 6145 if ((perm.modeFlags&(Intent.FLAG_GRANT_READ_URI_PERMISSION 6146 |Intent.FLAG_GRANT_WRITE_URI_PERMISSION)) == 0) { 6147 ArrayMap<Uri, UriPermission> perms 6148 = mGrantedUriPermissions.get(perm.targetUid); 6149 if (perms != null) { 6150 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6151 "Removing " + perm.targetUid + " permission to " + perm.uri); 6152 perms.remove(perm.uri); 6153 if (perms.size() == 0) { 6154 mGrantedUriPermissions.remove(perm.targetUid); 6155 } 6156 } 6157 } 6158 } 6159 6160 private void revokeUriPermissionLocked(int callingUid, Uri uri, int modeFlags) { 6161 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + uri); 6162 6163 final IPackageManager pm = AppGlobals.getPackageManager(); 6164 final String authority = uri.getAuthority(); 6165 final ProviderInfo pi = getProviderInfoLocked(authority, UserHandle.getUserId(callingUid)); 6166 if (pi == null) { 6167 Slog.w(TAG, "No content provider found for permission revoke: " + uri.toSafeString()); 6168 return; 6169 } 6170 6171 // Does the caller have this permission on the URI? 6172 if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) { 6173 // Right now, if you are not the original owner of the permission, 6174 // you are not allowed to revoke it. 6175 //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) { 6176 throw new SecurityException("Uid " + callingUid 6177 + " does not have permission to uri " + uri); 6178 //} 6179 } 6180 6181 boolean persistChanged = false; 6182 6183 // Go through all of the permissions and remove any that match. 6184 final List<String> SEGMENTS = uri.getPathSegments(); 6185 if (SEGMENTS != null) { 6186 final int NS = SEGMENTS.size(); 6187 int N = mGrantedUriPermissions.size(); 6188 for (int i=0; i<N; i++) { 6189 ArrayMap<Uri, UriPermission> perms 6190 = mGrantedUriPermissions.valueAt(i); 6191 Iterator<UriPermission> it = perms.values().iterator(); 6192 toploop: 6193 while (it.hasNext()) { 6194 UriPermission perm = it.next(); 6195 Uri targetUri = perm.uri; 6196 if (!authority.equals(targetUri.getAuthority())) { 6197 continue; 6198 } 6199 List<String> targetSegments = targetUri.getPathSegments(); 6200 if (targetSegments == null) { 6201 continue; 6202 } 6203 if (targetSegments.size() < NS) { 6204 continue; 6205 } 6206 for (int j=0; j<NS; j++) { 6207 if (!SEGMENTS.get(j).equals(targetSegments.get(j))) { 6208 continue toploop; 6209 } 6210 } 6211 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6212 "Revoking " + perm.targetUid + " permission to " + perm.uri); 6213 persistChanged |= perm.clearModes(modeFlags, true); 6214 if (perm.modeFlags == 0) { 6215 it.remove(); 6216 } 6217 } 6218 if (perms.size() == 0) { 6219 mGrantedUriPermissions.remove( 6220 mGrantedUriPermissions.keyAt(i)); 6221 N--; 6222 i--; 6223 } 6224 } 6225 } 6226 6227 if (persistChanged) { 6228 schedulePersistUriGrants(); 6229 } 6230 } 6231 6232 @Override 6233 public void revokeUriPermission(IApplicationThread caller, Uri uri, 6234 int modeFlags) { 6235 enforceNotIsolatedCaller("revokeUriPermission"); 6236 synchronized(this) { 6237 final ProcessRecord r = getRecordForAppLocked(caller); 6238 if (r == null) { 6239 throw new SecurityException("Unable to find app for caller " 6240 + caller 6241 + " when revoking permission to uri " + uri); 6242 } 6243 if (uri == null) { 6244 Slog.w(TAG, "revokeUriPermission: null uri"); 6245 return; 6246 } 6247 6248 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION 6249 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 6250 if (modeFlags == 0) { 6251 return; 6252 } 6253 6254 final IPackageManager pm = AppGlobals.getPackageManager(); 6255 final String authority = uri.getAuthority(); 6256 final ProviderInfo pi = getProviderInfoLocked(authority, r.userId); 6257 if (pi == null) { 6258 Slog.w(TAG, "No content provider found for permission revoke: " 6259 + uri.toSafeString()); 6260 return; 6261 } 6262 6263 revokeUriPermissionLocked(r.uid, uri, modeFlags); 6264 } 6265 } 6266 6267 /** 6268 * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the 6269 * given package. 6270 * 6271 * @param packageName Package name to match, or {@code null} to apply to all 6272 * packages. 6273 * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply 6274 * to all users. 6275 * @param persistable If persistable grants should be removed. 6276 */ 6277 private void removeUriPermissionsForPackageLocked( 6278 String packageName, int userHandle, boolean persistable) { 6279 if (userHandle == UserHandle.USER_ALL && packageName == null) { 6280 throw new IllegalArgumentException("Must narrow by either package or user"); 6281 } 6282 6283 boolean persistChanged = false; 6284 6285 final int size = mGrantedUriPermissions.size(); 6286 for (int i = 0; i < size; i++) { 6287 // Only inspect grants matching user 6288 if (userHandle == UserHandle.USER_ALL 6289 || userHandle == UserHandle.getUserId(mGrantedUriPermissions.keyAt(i))) { 6290 final Iterator<UriPermission> it = mGrantedUriPermissions.valueAt(i) 6291 .values().iterator(); 6292 while (it.hasNext()) { 6293 final UriPermission perm = it.next(); 6294 6295 // Only inspect grants matching package 6296 if (packageName == null || perm.sourcePkg.equals(packageName) 6297 || perm.targetPkg.equals(packageName)) { 6298 persistChanged |= perm.clearModes(~0, persistable); 6299 6300 // Only remove when no modes remain; any persisted grants 6301 // will keep this alive. 6302 if (perm.modeFlags == 0) { 6303 it.remove(); 6304 } 6305 } 6306 } 6307 } 6308 } 6309 6310 if (persistChanged) { 6311 schedulePersistUriGrants(); 6312 } 6313 } 6314 6315 @Override 6316 public IBinder newUriPermissionOwner(String name) { 6317 enforceNotIsolatedCaller("newUriPermissionOwner"); 6318 synchronized(this) { 6319 UriPermissionOwner owner = new UriPermissionOwner(this, name); 6320 return owner.getExternalTokenLocked(); 6321 } 6322 } 6323 6324 @Override 6325 public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, 6326 Uri uri, int modeFlags) { 6327 synchronized(this) { 6328 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 6329 if (owner == null) { 6330 throw new IllegalArgumentException("Unknown owner: " + token); 6331 } 6332 if (fromUid != Binder.getCallingUid()) { 6333 if (Binder.getCallingUid() != Process.myUid()) { 6334 // Only system code can grant URI permissions on behalf 6335 // of other users. 6336 throw new SecurityException("nice try"); 6337 } 6338 } 6339 if (targetPkg == null) { 6340 throw new IllegalArgumentException("null target"); 6341 } 6342 if (uri == null) { 6343 throw new IllegalArgumentException("null uri"); 6344 } 6345 6346 grantUriPermissionLocked(fromUid, targetPkg, uri, modeFlags, owner); 6347 } 6348 } 6349 6350 @Override 6351 public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode) { 6352 synchronized(this) { 6353 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 6354 if (owner == null) { 6355 throw new IllegalArgumentException("Unknown owner: " + token); 6356 } 6357 6358 if (uri == null) { 6359 owner.removeUriPermissionsLocked(mode); 6360 } else { 6361 owner.removeUriPermissionLocked(uri, mode); 6362 } 6363 } 6364 } 6365 6366 private void schedulePersistUriGrants() { 6367 if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) { 6368 mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG), 6369 10 * DateUtils.SECOND_IN_MILLIS); 6370 } 6371 } 6372 6373 private void writeGrantedUriPermissions() { 6374 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()"); 6375 6376 // Snapshot permissions so we can persist without lock 6377 ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList(); 6378 synchronized (this) { 6379 final int size = mGrantedUriPermissions.size(); 6380 for (int i = 0 ; i < size; i++) { 6381 for (UriPermission perm : mGrantedUriPermissions.valueAt(i).values()) { 6382 if (perm.persistedModeFlags != 0) { 6383 persist.add(perm.snapshot()); 6384 } 6385 } 6386 } 6387 } 6388 6389 FileOutputStream fos = null; 6390 try { 6391 fos = mGrantFile.startWrite(); 6392 6393 XmlSerializer out = new FastXmlSerializer(); 6394 out.setOutput(fos, "utf-8"); 6395 out.startDocument(null, true); 6396 out.startTag(null, TAG_URI_GRANTS); 6397 for (UriPermission.Snapshot perm : persist) { 6398 out.startTag(null, TAG_URI_GRANT); 6399 writeIntAttribute(out, ATTR_USER_HANDLE, perm.userHandle); 6400 out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg); 6401 out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg); 6402 out.attribute(null, ATTR_URI, String.valueOf(perm.uri)); 6403 writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags); 6404 writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime); 6405 out.endTag(null, TAG_URI_GRANT); 6406 } 6407 out.endTag(null, TAG_URI_GRANTS); 6408 out.endDocument(); 6409 6410 mGrantFile.finishWrite(fos); 6411 } catch (IOException e) { 6412 if (fos != null) { 6413 mGrantFile.failWrite(fos); 6414 } 6415 } 6416 } 6417 6418 private void readGrantedUriPermissionsLocked() { 6419 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()"); 6420 6421 final long now = System.currentTimeMillis(); 6422 6423 FileInputStream fis = null; 6424 try { 6425 fis = mGrantFile.openRead(); 6426 final XmlPullParser in = Xml.newPullParser(); 6427 in.setInput(fis, null); 6428 6429 int type; 6430 while ((type = in.next()) != END_DOCUMENT) { 6431 final String tag = in.getName(); 6432 if (type == START_TAG) { 6433 if (TAG_URI_GRANT.equals(tag)) { 6434 final int userHandle = readIntAttribute(in, ATTR_USER_HANDLE); 6435 final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG); 6436 final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG); 6437 final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI)); 6438 final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS); 6439 final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now); 6440 6441 // Sanity check that provider still belongs to source package 6442 final ProviderInfo pi = getProviderInfoLocked( 6443 uri.getAuthority(), userHandle); 6444 if (pi != null && sourcePkg.equals(pi.packageName)) { 6445 int targetUid = -1; 6446 try { 6447 targetUid = AppGlobals.getPackageManager() 6448 .getPackageUid(targetPkg, userHandle); 6449 } catch (RemoteException e) { 6450 } 6451 if (targetUid != -1) { 6452 final UriPermission perm = findOrCreateUriPermissionLocked( 6453 sourcePkg, targetPkg, targetUid, uri); 6454 perm.initPersistedModes(modeFlags, createdTime); 6455 } 6456 } else { 6457 Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg 6458 + " but instead found " + pi); 6459 } 6460 } 6461 } 6462 } 6463 } catch (FileNotFoundException e) { 6464 // Missing grants is okay 6465 } catch (IOException e) { 6466 Log.wtf(TAG, "Failed reading Uri grants", e); 6467 } catch (XmlPullParserException e) { 6468 Log.wtf(TAG, "Failed reading Uri grants", e); 6469 } finally { 6470 IoUtils.closeQuietly(fis); 6471 } 6472 } 6473 6474 @Override 6475 public void takePersistableUriPermission(Uri uri, int modeFlags) { 6476 enforceNotIsolatedCaller("takePersistableUriPermission"); 6477 6478 Preconditions.checkFlagsArgument(modeFlags, 6479 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 6480 6481 synchronized (this) { 6482 final int callingUid = Binder.getCallingUid(); 6483 final UriPermission perm = findUriPermissionLocked(callingUid, uri); 6484 if (perm == null) { 6485 throw new SecurityException("No permission grant found for UID " + callingUid 6486 + " and Uri " + uri.toSafeString()); 6487 } 6488 6489 boolean persistChanged = perm.takePersistableModes(modeFlags); 6490 persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid); 6491 6492 if (persistChanged) { 6493 schedulePersistUriGrants(); 6494 } 6495 } 6496 } 6497 6498 @Override 6499 public void releasePersistableUriPermission(Uri uri, int modeFlags) { 6500 enforceNotIsolatedCaller("releasePersistableUriPermission"); 6501 6502 Preconditions.checkFlagsArgument(modeFlags, 6503 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 6504 6505 synchronized (this) { 6506 final int callingUid = Binder.getCallingUid(); 6507 6508 final UriPermission perm = findUriPermissionLocked(callingUid, uri); 6509 if (perm == null) { 6510 Slog.w(TAG, "No permission grant found for UID " + callingUid + " and Uri " 6511 + uri.toSafeString()); 6512 return; 6513 } 6514 6515 final boolean persistChanged = perm.releasePersistableModes(modeFlags); 6516 removeUriPermissionIfNeededLocked(perm); 6517 if (persistChanged) { 6518 schedulePersistUriGrants(); 6519 } 6520 } 6521 } 6522 6523 /** 6524 * Prune any older {@link UriPermission} for the given UID until outstanding 6525 * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}. 6526 * 6527 * @return if any mutations occured that require persisting. 6528 */ 6529 private boolean maybePrunePersistedUriGrantsLocked(int uid) { 6530 final ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(uid); 6531 if (perms == null) return false; 6532 if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false; 6533 6534 final ArrayList<UriPermission> persisted = Lists.newArrayList(); 6535 for (UriPermission perm : perms.values()) { 6536 if (perm.persistedModeFlags != 0) { 6537 persisted.add(perm); 6538 } 6539 } 6540 6541 final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS; 6542 if (trimCount <= 0) return false; 6543 6544 Collections.sort(persisted, new UriPermission.PersistedTimeComparator()); 6545 for (int i = 0; i < trimCount; i++) { 6546 final UriPermission perm = persisted.get(i); 6547 6548 if (DEBUG_URI_PERMISSION) { 6549 Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime); 6550 } 6551 6552 perm.releasePersistableModes(~0); 6553 removeUriPermissionIfNeededLocked(perm); 6554 } 6555 6556 return true; 6557 } 6558 6559 @Override 6560 public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions( 6561 String packageName, boolean incoming) { 6562 enforceNotIsolatedCaller("getPersistedUriPermissions"); 6563 Preconditions.checkNotNull(packageName, "packageName"); 6564 6565 final int callingUid = Binder.getCallingUid(); 6566 final IPackageManager pm = AppGlobals.getPackageManager(); 6567 try { 6568 final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid)); 6569 if (packageUid != callingUid) { 6570 throw new SecurityException( 6571 "Package " + packageName + " does not belong to calling UID " + callingUid); 6572 } 6573 } catch (RemoteException e) { 6574 throw new SecurityException("Failed to verify package name ownership"); 6575 } 6576 6577 final ArrayList<android.content.UriPermission> result = Lists.newArrayList(); 6578 synchronized (this) { 6579 if (incoming) { 6580 final ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(callingUid); 6581 if (perms == null) { 6582 Slog.w(TAG, "No permission grants found for " + packageName); 6583 } else { 6584 final int size = perms.size(); 6585 for (int i = 0; i < size; i++) { 6586 final UriPermission perm = perms.valueAt(i); 6587 if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) { 6588 result.add(perm.buildPersistedPublicApiObject()); 6589 } 6590 } 6591 } 6592 } else { 6593 final int size = mGrantedUriPermissions.size(); 6594 for (int i = 0; i < size; i++) { 6595 final ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 6596 final int permsSize = perms.size(); 6597 for (int j = 0; j < permsSize; j++) { 6598 final UriPermission perm = perms.valueAt(j); 6599 if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) { 6600 result.add(perm.buildPersistedPublicApiObject()); 6601 } 6602 } 6603 } 6604 } 6605 } 6606 return new ParceledListSlice<android.content.UriPermission>(result); 6607 } 6608 6609 @Override 6610 public void showWaitingForDebugger(IApplicationThread who, boolean waiting) { 6611 synchronized (this) { 6612 ProcessRecord app = 6613 who != null ? getRecordForAppLocked(who) : null; 6614 if (app == null) return; 6615 6616 Message msg = Message.obtain(); 6617 msg.what = WAIT_FOR_DEBUGGER_MSG; 6618 msg.obj = app; 6619 msg.arg1 = waiting ? 1 : 0; 6620 mHandler.sendMessage(msg); 6621 } 6622 } 6623 6624 @Override 6625 public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) { 6626 final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ); 6627 final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ); 6628 outInfo.availMem = Process.getFreeMemory(); 6629 outInfo.totalMem = Process.getTotalMemory(); 6630 outInfo.threshold = homeAppMem; 6631 outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2)); 6632 outInfo.hiddenAppThreshold = cachedAppMem; 6633 outInfo.secondaryServerThreshold = mProcessList.getMemLevel( 6634 ProcessList.SERVICE_ADJ); 6635 outInfo.visibleAppThreshold = mProcessList.getMemLevel( 6636 ProcessList.VISIBLE_APP_ADJ); 6637 outInfo.foregroundAppThreshold = mProcessList.getMemLevel( 6638 ProcessList.FOREGROUND_APP_ADJ); 6639 } 6640 6641 // ========================================================= 6642 // TASK MANAGEMENT 6643 // ========================================================= 6644 6645 @Override 6646 public List<RunningTaskInfo> getTasks(int maxNum, int flags, 6647 IThumbnailReceiver receiver) { 6648 ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>(); 6649 6650 PendingThumbnailsRecord pending = new PendingThumbnailsRecord(receiver); 6651 ActivityRecord topRecord = null; 6652 6653 synchronized(this) { 6654 if (localLOGV) Slog.v( 6655 TAG, "getTasks: max=" + maxNum + ", flags=" + flags 6656 + ", receiver=" + receiver); 6657 6658 if (checkCallingPermission(android.Manifest.permission.GET_TASKS) 6659 != PackageManager.PERMISSION_GRANTED) { 6660 if (receiver != null) { 6661 // If the caller wants to wait for pending thumbnails, 6662 // it ain't gonna get them. 6663 try { 6664 receiver.finished(); 6665 } catch (RemoteException ex) { 6666 } 6667 } 6668 String msg = "Permission Denial: getTasks() from pid=" 6669 + Binder.getCallingPid() 6670 + ", uid=" + Binder.getCallingUid() 6671 + " requires " + android.Manifest.permission.GET_TASKS; 6672 Slog.w(TAG, msg); 6673 throw new SecurityException(msg); 6674 } 6675 6676 // TODO: Improve with MRU list from all ActivityStacks. 6677 topRecord = mStackSupervisor.getTasksLocked(maxNum, receiver, pending, list); 6678 6679 if (!pending.pendingRecords.isEmpty()) { 6680 mPendingThumbnails.add(pending); 6681 } 6682 } 6683 6684 if (localLOGV) Slog.v(TAG, "We have pending thumbnails: " + pending); 6685 6686 if (topRecord != null) { 6687 if (localLOGV) Slog.v(TAG, "Requesting top thumbnail"); 6688 try { 6689 IApplicationThread topThumbnail = topRecord.app.thread; 6690 topThumbnail.requestThumbnail(topRecord.appToken); 6691 } catch (Exception e) { 6692 Slog.w(TAG, "Exception thrown when requesting thumbnail", e); 6693 sendPendingThumbnail(null, topRecord.appToken, null, null, true); 6694 } 6695 } 6696 6697 if (pending == null && receiver != null) { 6698 // In this case all thumbnails were available and the client 6699 // is being asked to be told when the remaining ones come in... 6700 // which is unusually, since the top-most currently running 6701 // activity should never have a canned thumbnail! Oh well. 6702 try { 6703 receiver.finished(); 6704 } catch (RemoteException ex) { 6705 } 6706 } 6707 6708 return list; 6709 } 6710 6711 TaskRecord getMostRecentTask() { 6712 return mRecentTasks.get(0); 6713 } 6714 6715 @Override 6716 public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, 6717 int flags, int userId) { 6718 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 6719 false, true, "getRecentTasks", null); 6720 6721 synchronized (this) { 6722 enforceCallingPermission(android.Manifest.permission.GET_TASKS, 6723 "getRecentTasks()"); 6724 final boolean detailed = checkCallingPermission( 6725 android.Manifest.permission.GET_DETAILED_TASKS) 6726 == PackageManager.PERMISSION_GRANTED; 6727 6728 IPackageManager pm = AppGlobals.getPackageManager(); 6729 6730 final int N = mRecentTasks.size(); 6731 ArrayList<ActivityManager.RecentTaskInfo> res 6732 = new ArrayList<ActivityManager.RecentTaskInfo>( 6733 maxNum < N ? maxNum : N); 6734 for (int i=0; i<N && maxNum > 0; i++) { 6735 TaskRecord tr = mRecentTasks.get(i); 6736 // Only add calling user's recent tasks 6737 if (tr.userId != userId) continue; 6738 // Return the entry if desired by the caller. We always return 6739 // the first entry, because callers always expect this to be the 6740 // foreground app. We may filter others if the caller has 6741 // not supplied RECENT_WITH_EXCLUDED and there is some reason 6742 // we should exclude the entry. 6743 6744 if (i == 0 6745 || ((flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0) 6746 || (tr.intent == null) 6747 || ((tr.intent.getFlags() 6748 &Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0)) { 6749 ActivityManager.RecentTaskInfo rti 6750 = new ActivityManager.RecentTaskInfo(); 6751 rti.id = tr.numActivities > 0 ? tr.taskId : -1; 6752 rti.persistentId = tr.taskId; 6753 rti.baseIntent = new Intent( 6754 tr.intent != null ? tr.intent : tr.affinityIntent); 6755 if (!detailed) { 6756 rti.baseIntent.replaceExtras((Bundle)null); 6757 } 6758 rti.origActivity = tr.origActivity; 6759 rti.description = tr.lastDescription; 6760 rti.stackId = tr.stack.mStackId; 6761 6762 if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) { 6763 // Check whether this activity is currently available. 6764 try { 6765 if (rti.origActivity != null) { 6766 if (pm.getActivityInfo(rti.origActivity, 0, userId) 6767 == null) { 6768 continue; 6769 } 6770 } else if (rti.baseIntent != null) { 6771 if (pm.queryIntentActivities(rti.baseIntent, 6772 null, 0, userId) == null) { 6773 continue; 6774 } 6775 } 6776 } catch (RemoteException e) { 6777 // Will never happen. 6778 } 6779 } 6780 6781 res.add(rti); 6782 maxNum--; 6783 } 6784 } 6785 return res; 6786 } 6787 } 6788 6789 private TaskRecord recentTaskForIdLocked(int id) { 6790 final int N = mRecentTasks.size(); 6791 for (int i=0; i<N; i++) { 6792 TaskRecord tr = mRecentTasks.get(i); 6793 if (tr.taskId == id) { 6794 return tr; 6795 } 6796 } 6797 return null; 6798 } 6799 6800 @Override 6801 public ActivityManager.TaskThumbnails getTaskThumbnails(int id) { 6802 synchronized (this) { 6803 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER, 6804 "getTaskThumbnails()"); 6805 TaskRecord tr = recentTaskForIdLocked(id); 6806 if (tr != null) { 6807 return tr.getTaskThumbnailsLocked(); 6808 } 6809 } 6810 return null; 6811 } 6812 6813 @Override 6814 public Bitmap getTaskTopThumbnail(int id) { 6815 synchronized (this) { 6816 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER, 6817 "getTaskTopThumbnail()"); 6818 TaskRecord tr = recentTaskForIdLocked(id); 6819 if (tr != null) { 6820 return tr.getTaskTopThumbnailLocked(); 6821 } 6822 } 6823 return null; 6824 } 6825 6826 @Override 6827 public boolean removeSubTask(int taskId, int subTaskIndex) { 6828 synchronized (this) { 6829 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, 6830 "removeSubTask()"); 6831 long ident = Binder.clearCallingIdentity(); 6832 try { 6833 TaskRecord tr = recentTaskForIdLocked(taskId); 6834 if (tr != null) { 6835 return tr.removeTaskActivitiesLocked(subTaskIndex, true) != null; 6836 } 6837 return false; 6838 } finally { 6839 Binder.restoreCallingIdentity(ident); 6840 } 6841 } 6842 } 6843 6844 private void killUnneededProcessLocked(ProcessRecord pr, String reason) { 6845 if (!pr.killedByAm) { 6846 Slog.i(TAG, "Killing " + pr.toShortString() + " (adj " + pr.setAdj + "): " + reason); 6847 EventLog.writeEvent(EventLogTags.AM_KILL, pr.userId, pr.pid, 6848 pr.processName, pr.setAdj, reason); 6849 pr.killedByAm = true; 6850 Process.killProcessQuiet(pr.pid); 6851 } 6852 } 6853 6854 private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) { 6855 tr.disposeThumbnail(); 6856 mRecentTasks.remove(tr); 6857 final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0; 6858 Intent baseIntent = new Intent( 6859 tr.intent != null ? tr.intent : tr.affinityIntent); 6860 ComponentName component = baseIntent.getComponent(); 6861 if (component == null) { 6862 Slog.w(TAG, "Now component for base intent of task: " + tr); 6863 return; 6864 } 6865 6866 // Find any running services associated with this app. 6867 mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent); 6868 6869 if (killProcesses) { 6870 // Find any running processes associated with this app. 6871 final String pkg = component.getPackageName(); 6872 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 6873 ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap(); 6874 for (int i=0; i<pmap.size(); i++) { 6875 SparseArray<ProcessRecord> uids = pmap.valueAt(i); 6876 for (int j=0; j<uids.size(); j++) { 6877 ProcessRecord proc = uids.valueAt(j); 6878 if (proc.userId != tr.userId) { 6879 continue; 6880 } 6881 if (!proc.pkgList.containsKey(pkg)) { 6882 continue; 6883 } 6884 procs.add(proc); 6885 } 6886 } 6887 6888 // Kill the running processes. 6889 for (int i=0; i<procs.size(); i++) { 6890 ProcessRecord pr = procs.get(i); 6891 if (pr == mHomeProcess) { 6892 // Don't kill the home process along with tasks from the same package. 6893 continue; 6894 } 6895 if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 6896 killUnneededProcessLocked(pr, "remove task"); 6897 } else { 6898 pr.waitingToKill = "remove task"; 6899 } 6900 } 6901 } 6902 } 6903 6904 @Override 6905 public boolean removeTask(int taskId, int flags) { 6906 synchronized (this) { 6907 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, 6908 "removeTask()"); 6909 long ident = Binder.clearCallingIdentity(); 6910 try { 6911 TaskRecord tr = recentTaskForIdLocked(taskId); 6912 if (tr != null) { 6913 ActivityRecord r = tr.removeTaskActivitiesLocked(-1, false); 6914 if (r != null) { 6915 cleanUpRemovedTaskLocked(tr, flags); 6916 return true; 6917 } 6918 if (tr.mActivities.size() == 0) { 6919 // Caller is just removing a recent task that is 6920 // not actively running. That is easy! 6921 cleanUpRemovedTaskLocked(tr, flags); 6922 return true; 6923 } 6924 Slog.w(TAG, "removeTask: task " + taskId 6925 + " does not have activities to remove, " 6926 + " but numActivities=" + tr.numActivities 6927 + ": " + tr); 6928 } 6929 } finally { 6930 Binder.restoreCallingIdentity(ident); 6931 } 6932 } 6933 return false; 6934 } 6935 6936 /** 6937 * TODO: Add mController hook 6938 */ 6939 @Override 6940 public void moveTaskToFront(int task, int flags, Bundle options) { 6941 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 6942 "moveTaskToFront()"); 6943 6944 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving task=" + task); 6945 synchronized(this) { 6946 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 6947 Binder.getCallingUid(), "Task to front")) { 6948 ActivityOptions.abort(options); 6949 return; 6950 } 6951 final long origId = Binder.clearCallingIdentity(); 6952 try { 6953 mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options); 6954 } finally { 6955 Binder.restoreCallingIdentity(origId); 6956 } 6957 ActivityOptions.abort(options); 6958 } 6959 } 6960 6961 @Override 6962 public void moveTaskToBack(int taskId) { 6963 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 6964 "moveTaskToBack()"); 6965 6966 synchronized(this) { 6967 TaskRecord tr = recentTaskForIdLocked(taskId); 6968 if (tr != null) { 6969 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr); 6970 ActivityStack stack = tr.stack; 6971 if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) { 6972 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 6973 Binder.getCallingUid(), "Task to back")) { 6974 return; 6975 } 6976 } 6977 final long origId = Binder.clearCallingIdentity(); 6978 try { 6979 stack.moveTaskToBackLocked(taskId, null); 6980 } finally { 6981 Binder.restoreCallingIdentity(origId); 6982 } 6983 } 6984 } 6985 } 6986 6987 /** 6988 * Moves an activity, and all of the other activities within the same task, to the bottom 6989 * of the history stack. The activity's order within the task is unchanged. 6990 * 6991 * @param token A reference to the activity we wish to move 6992 * @param nonRoot If false then this only works if the activity is the root 6993 * of a task; if true it will work for any activity in a task. 6994 * @return Returns true if the move completed, false if not. 6995 */ 6996 @Override 6997 public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) { 6998 enforceNotIsolatedCaller("moveActivityTaskToBack"); 6999 synchronized(this) { 7000 final long origId = Binder.clearCallingIdentity(); 7001 int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot); 7002 if (taskId >= 0) { 7003 return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null); 7004 } 7005 Binder.restoreCallingIdentity(origId); 7006 } 7007 return false; 7008 } 7009 7010 @Override 7011 public void moveTaskBackwards(int task) { 7012 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 7013 "moveTaskBackwards()"); 7014 7015 synchronized(this) { 7016 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 7017 Binder.getCallingUid(), "Task backwards")) { 7018 return; 7019 } 7020 final long origId = Binder.clearCallingIdentity(); 7021 moveTaskBackwardsLocked(task); 7022 Binder.restoreCallingIdentity(origId); 7023 } 7024 } 7025 7026 private final void moveTaskBackwardsLocked(int task) { 7027 Slog.e(TAG, "moveTaskBackwards not yet implemented!"); 7028 } 7029 7030 @Override 7031 public IBinder getHomeActivityToken() throws RemoteException { 7032 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7033 "getHomeActivityToken()"); 7034 synchronized (this) { 7035 return mStackSupervisor.getHomeActivityToken(); 7036 } 7037 } 7038 7039 @Override 7040 public IActivityContainer createActivityContainer(IBinder parentActivityToken, 7041 IActivityContainerCallback callback) throws RemoteException { 7042 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7043 "createActivityContainer()"); 7044 synchronized (this) { 7045 if (parentActivityToken == null) { 7046 throw new IllegalArgumentException("parent token must not be null"); 7047 } 7048 ActivityRecord r = ActivityRecord.forToken(parentActivityToken); 7049 if (r == null) { 7050 return null; 7051 } 7052 if (callback == null) { 7053 throw new IllegalArgumentException("callback must not be null"); 7054 } 7055 return mStackSupervisor.createActivityContainer(r, callback); 7056 } 7057 } 7058 7059 @Override 7060 public void deleteActivityContainer(IActivityContainer container) throws RemoteException { 7061 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7062 "deleteActivityContainer()"); 7063 synchronized (this) { 7064 mStackSupervisor.deleteActivityContainer(container); 7065 } 7066 } 7067 7068 @Override 7069 public IActivityContainer getEnclosingActivityContainer(IBinder activityToken) 7070 throws RemoteException { 7071 synchronized (this) { 7072 ActivityStack stack = ActivityRecord.getStackLocked(activityToken); 7073 if (stack != null) { 7074 return stack.mActivityContainer; 7075 } 7076 return null; 7077 } 7078 } 7079 7080 @Override 7081 public void moveTaskToStack(int taskId, int stackId, boolean toTop) { 7082 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7083 "moveTaskToStack()"); 7084 if (stackId == HOME_STACK_ID) { 7085 Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack", 7086 new RuntimeException("here").fillInStackTrace()); 7087 } 7088 synchronized (this) { 7089 long ident = Binder.clearCallingIdentity(); 7090 try { 7091 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId=" 7092 + stackId + " toTop=" + toTop); 7093 mStackSupervisor.moveTaskToStack(taskId, stackId, toTop); 7094 } finally { 7095 Binder.restoreCallingIdentity(ident); 7096 } 7097 } 7098 } 7099 7100 @Override 7101 public void resizeStack(int stackBoxId, Rect bounds) { 7102 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7103 "resizeStackBox()"); 7104 long ident = Binder.clearCallingIdentity(); 7105 try { 7106 mWindowManager.resizeStack(stackBoxId, bounds); 7107 } finally { 7108 Binder.restoreCallingIdentity(ident); 7109 } 7110 } 7111 7112 @Override 7113 public List<StackInfo> getAllStackInfos() { 7114 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7115 "getAllStackInfos()"); 7116 long ident = Binder.clearCallingIdentity(); 7117 try { 7118 synchronized (this) { 7119 return mStackSupervisor.getAllStackInfosLocked(); 7120 } 7121 } finally { 7122 Binder.restoreCallingIdentity(ident); 7123 } 7124 } 7125 7126 @Override 7127 public StackInfo getStackInfo(int stackId) { 7128 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7129 "getStackInfo()"); 7130 long ident = Binder.clearCallingIdentity(); 7131 try { 7132 synchronized (this) { 7133 return mStackSupervisor.getStackInfoLocked(stackId); 7134 } 7135 } finally { 7136 Binder.restoreCallingIdentity(ident); 7137 } 7138 } 7139 7140 @Override 7141 public int getTaskForActivity(IBinder token, boolean onlyRoot) { 7142 synchronized(this) { 7143 return ActivityRecord.getTaskForActivityLocked(token, onlyRoot); 7144 } 7145 } 7146 7147 // ========================================================= 7148 // THUMBNAILS 7149 // ========================================================= 7150 7151 public void reportThumbnail(IBinder token, 7152 Bitmap thumbnail, CharSequence description) { 7153 //System.out.println("Report thumbnail for " + token + ": " + thumbnail); 7154 final long origId = Binder.clearCallingIdentity(); 7155 sendPendingThumbnail(null, token, thumbnail, description, true); 7156 Binder.restoreCallingIdentity(origId); 7157 } 7158 7159 final void sendPendingThumbnail(ActivityRecord r, IBinder token, 7160 Bitmap thumbnail, CharSequence description, boolean always) { 7161 TaskRecord task; 7162 ArrayList<PendingThumbnailsRecord> receivers = null; 7163 7164 //System.out.println("Send pending thumbnail: " + r); 7165 7166 synchronized(this) { 7167 if (r == null) { 7168 r = ActivityRecord.isInStackLocked(token); 7169 if (r == null) { 7170 return; 7171 } 7172 } 7173 if (thumbnail == null && r.thumbHolder != null) { 7174 thumbnail = r.thumbHolder.lastThumbnail; 7175 description = r.thumbHolder.lastDescription; 7176 } 7177 if (thumbnail == null && !always) { 7178 // If there is no thumbnail, and this entry is not actually 7179 // going away, then abort for now and pick up the next 7180 // thumbnail we get. 7181 return; 7182 } 7183 task = r.task; 7184 7185 int N = mPendingThumbnails.size(); 7186 int i=0; 7187 while (i<N) { 7188 PendingThumbnailsRecord pr = mPendingThumbnails.get(i); 7189 //System.out.println("Looking in " + pr.pendingRecords); 7190 if (pr.pendingRecords.remove(r)) { 7191 if (receivers == null) { 7192 receivers = new ArrayList<PendingThumbnailsRecord>(); 7193 } 7194 receivers.add(pr); 7195 if (pr.pendingRecords.size() == 0) { 7196 pr.finished = true; 7197 mPendingThumbnails.remove(i); 7198 N--; 7199 continue; 7200 } 7201 } 7202 i++; 7203 } 7204 } 7205 7206 if (receivers != null) { 7207 final int N = receivers.size(); 7208 for (int i=0; i<N; i++) { 7209 try { 7210 PendingThumbnailsRecord pr = receivers.get(i); 7211 pr.receiver.newThumbnail( 7212 task != null ? task.taskId : -1, thumbnail, description); 7213 if (pr.finished) { 7214 pr.receiver.finished(); 7215 } 7216 } catch (Exception e) { 7217 Slog.w(TAG, "Exception thrown when sending thumbnail", e); 7218 } 7219 } 7220 } 7221 } 7222 7223 // ========================================================= 7224 // CONTENT PROVIDERS 7225 // ========================================================= 7226 7227 private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) { 7228 List<ProviderInfo> providers = null; 7229 try { 7230 providers = AppGlobals.getPackageManager(). 7231 queryContentProviders(app.processName, app.uid, 7232 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS); 7233 } catch (RemoteException ex) { 7234 } 7235 if (DEBUG_MU) 7236 Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid); 7237 int userId = app.userId; 7238 if (providers != null) { 7239 int N = providers.size(); 7240 app.pubProviders.ensureCapacity(N + app.pubProviders.size()); 7241 for (int i=0; i<N; i++) { 7242 ProviderInfo cpi = 7243 (ProviderInfo)providers.get(i); 7244 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo, 7245 cpi.name, cpi.flags); 7246 if (singleton && UserHandle.getUserId(app.uid) != 0) { 7247 // This is a singleton provider, but a user besides the 7248 // default user is asking to initialize a process it runs 7249 // in... well, no, it doesn't actually run in this process, 7250 // it runs in the process of the default user. Get rid of it. 7251 providers.remove(i); 7252 N--; 7253 i--; 7254 continue; 7255 } 7256 7257 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 7258 ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId); 7259 if (cpr == null) { 7260 cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton); 7261 mProviderMap.putProviderByClass(comp, cpr); 7262 } 7263 if (DEBUG_MU) 7264 Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid); 7265 app.pubProviders.put(cpi.name, cpr); 7266 if (!cpi.multiprocess || !"android".equals(cpi.packageName)) { 7267 // Don't add this if it is a platform component that is marked 7268 // to run in multiple processes, because this is actually 7269 // part of the framework so doesn't make sense to track as a 7270 // separate apk in the process. 7271 app.addPackage(cpi.applicationInfo.packageName, mProcessStats); 7272 } 7273 ensurePackageDexOpt(cpi.applicationInfo.packageName); 7274 } 7275 } 7276 return providers; 7277 } 7278 7279 /** 7280 * Check if {@link ProcessRecord} has a possible chance at accessing the 7281 * given {@link ProviderInfo}. Final permission checking is always done 7282 * in {@link ContentProvider}. 7283 */ 7284 private final String checkContentProviderPermissionLocked( 7285 ProviderInfo cpi, ProcessRecord r) { 7286 final int callingPid = (r != null) ? r.pid : Binder.getCallingPid(); 7287 final int callingUid = (r != null) ? r.uid : Binder.getCallingUid(); 7288 if (checkComponentPermission(cpi.readPermission, callingPid, callingUid, 7289 cpi.applicationInfo.uid, cpi.exported) 7290 == PackageManager.PERMISSION_GRANTED) { 7291 return null; 7292 } 7293 if (checkComponentPermission(cpi.writePermission, callingPid, callingUid, 7294 cpi.applicationInfo.uid, cpi.exported) 7295 == PackageManager.PERMISSION_GRANTED) { 7296 return null; 7297 } 7298 7299 PathPermission[] pps = cpi.pathPermissions; 7300 if (pps != null) { 7301 int i = pps.length; 7302 while (i > 0) { 7303 i--; 7304 PathPermission pp = pps[i]; 7305 if (checkComponentPermission(pp.getReadPermission(), callingPid, callingUid, 7306 cpi.applicationInfo.uid, cpi.exported) 7307 == PackageManager.PERMISSION_GRANTED) { 7308 return null; 7309 } 7310 if (checkComponentPermission(pp.getWritePermission(), callingPid, callingUid, 7311 cpi.applicationInfo.uid, cpi.exported) 7312 == PackageManager.PERMISSION_GRANTED) { 7313 return null; 7314 } 7315 } 7316 } 7317 7318 ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(callingUid); 7319 if (perms != null) { 7320 for (Map.Entry<Uri, UriPermission> uri : perms.entrySet()) { 7321 if (uri.getKey().getAuthority().equals(cpi.authority)) { 7322 return null; 7323 } 7324 } 7325 } 7326 7327 String msg; 7328 if (!cpi.exported) { 7329 msg = "Permission Denial: opening provider " + cpi.name 7330 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 7331 + ", uid=" + callingUid + ") that is not exported from uid " 7332 + cpi.applicationInfo.uid; 7333 } else { 7334 msg = "Permission Denial: opening provider " + cpi.name 7335 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 7336 + ", uid=" + callingUid + ") requires " 7337 + cpi.readPermission + " or " + cpi.writePermission; 7338 } 7339 Slog.w(TAG, msg); 7340 return msg; 7341 } 7342 7343 ContentProviderConnection incProviderCountLocked(ProcessRecord r, 7344 final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 7345 if (r != null) { 7346 for (int i=0; i<r.conProviders.size(); i++) { 7347 ContentProviderConnection conn = r.conProviders.get(i); 7348 if (conn.provider == cpr) { 7349 if (DEBUG_PROVIDER) Slog.v(TAG, 7350 "Adding provider requested by " 7351 + r.processName + " from process " 7352 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 7353 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 7354 if (stable) { 7355 conn.stableCount++; 7356 conn.numStableIncs++; 7357 } else { 7358 conn.unstableCount++; 7359 conn.numUnstableIncs++; 7360 } 7361 return conn; 7362 } 7363 } 7364 ContentProviderConnection conn = new ContentProviderConnection(cpr, r); 7365 if (stable) { 7366 conn.stableCount = 1; 7367 conn.numStableIncs = 1; 7368 } else { 7369 conn.unstableCount = 1; 7370 conn.numUnstableIncs = 1; 7371 } 7372 cpr.connections.add(conn); 7373 r.conProviders.add(conn); 7374 return conn; 7375 } 7376 cpr.addExternalProcessHandleLocked(externalProcessToken); 7377 return null; 7378 } 7379 7380 boolean decProviderCountLocked(ContentProviderConnection conn, 7381 ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 7382 if (conn != null) { 7383 cpr = conn.provider; 7384 if (DEBUG_PROVIDER) Slog.v(TAG, 7385 "Removing provider requested by " 7386 + conn.client.processName + " from process " 7387 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 7388 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 7389 if (stable) { 7390 conn.stableCount--; 7391 } else { 7392 conn.unstableCount--; 7393 } 7394 if (conn.stableCount == 0 && conn.unstableCount == 0) { 7395 cpr.connections.remove(conn); 7396 conn.client.conProviders.remove(conn); 7397 return true; 7398 } 7399 return false; 7400 } 7401 cpr.removeExternalProcessHandleLocked(externalProcessToken); 7402 return false; 7403 } 7404 7405 private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller, 7406 String name, IBinder token, boolean stable, int userId) { 7407 ContentProviderRecord cpr; 7408 ContentProviderConnection conn = null; 7409 ProviderInfo cpi = null; 7410 7411 synchronized(this) { 7412 ProcessRecord r = null; 7413 if (caller != null) { 7414 r = getRecordForAppLocked(caller); 7415 if (r == null) { 7416 throw new SecurityException( 7417 "Unable to find app for caller " + caller 7418 + " (pid=" + Binder.getCallingPid() 7419 + ") when getting content provider " + name); 7420 } 7421 } 7422 7423 // First check if this content provider has been published... 7424 cpr = mProviderMap.getProviderByName(name, userId); 7425 boolean providerRunning = cpr != null; 7426 if (providerRunning) { 7427 cpi = cpr.info; 7428 String msg; 7429 if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) { 7430 throw new SecurityException(msg); 7431 } 7432 7433 if (r != null && cpr.canRunHere(r)) { 7434 // This provider has been published or is in the process 7435 // of being published... but it is also allowed to run 7436 // in the caller's process, so don't make a connection 7437 // and just let the caller instantiate its own instance. 7438 ContentProviderHolder holder = cpr.newHolder(null); 7439 // don't give caller the provider object, it needs 7440 // to make its own. 7441 holder.provider = null; 7442 return holder; 7443 } 7444 7445 final long origId = Binder.clearCallingIdentity(); 7446 7447 // In this case the provider instance already exists, so we can 7448 // return it right away. 7449 conn = incProviderCountLocked(r, cpr, token, stable); 7450 if (conn != null && (conn.stableCount+conn.unstableCount) == 1) { 7451 if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 7452 // If this is a perceptible app accessing the provider, 7453 // make sure to count it as being accessed and thus 7454 // back up on the LRU list. This is good because 7455 // content providers are often expensive to start. 7456 updateLruProcessLocked(cpr.proc, false, null); 7457 } 7458 } 7459 7460 if (cpr.proc != null) { 7461 if (false) { 7462 if (cpr.name.flattenToShortString().equals( 7463 "com.android.providers.calendar/.CalendarProvider2")) { 7464 Slog.v(TAG, "****************** KILLING " 7465 + cpr.name.flattenToShortString()); 7466 Process.killProcess(cpr.proc.pid); 7467 } 7468 } 7469 boolean success = updateOomAdjLocked(cpr.proc); 7470 if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success); 7471 // NOTE: there is still a race here where a signal could be 7472 // pending on the process even though we managed to update its 7473 // adj level. Not sure what to do about this, but at least 7474 // the race is now smaller. 7475 if (!success) { 7476 // Uh oh... it looks like the provider's process 7477 // has been killed on us. We need to wait for a new 7478 // process to be started, and make sure its death 7479 // doesn't kill our process. 7480 Slog.i(TAG, 7481 "Existing provider " + cpr.name.flattenToShortString() 7482 + " is crashing; detaching " + r); 7483 boolean lastRef = decProviderCountLocked(conn, cpr, token, stable); 7484 appDiedLocked(cpr.proc, cpr.proc.pid, cpr.proc.thread); 7485 if (!lastRef) { 7486 // This wasn't the last ref our process had on 7487 // the provider... we have now been killed, bail. 7488 return null; 7489 } 7490 providerRunning = false; 7491 conn = null; 7492 } 7493 } 7494 7495 Binder.restoreCallingIdentity(origId); 7496 } 7497 7498 boolean singleton; 7499 if (!providerRunning) { 7500 try { 7501 cpi = AppGlobals.getPackageManager(). 7502 resolveContentProvider(name, 7503 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId); 7504 } catch (RemoteException ex) { 7505 } 7506 if (cpi == null) { 7507 return null; 7508 } 7509 singleton = isSingleton(cpi.processName, cpi.applicationInfo, 7510 cpi.name, cpi.flags); 7511 if (singleton) { 7512 userId = 0; 7513 } 7514 cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId); 7515 7516 String msg; 7517 if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) { 7518 throw new SecurityException(msg); 7519 } 7520 7521 if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate 7522 && !cpi.processName.equals("system")) { 7523 // If this content provider does not run in the system 7524 // process, and the system is not yet ready to run other 7525 // processes, then fail fast instead of hanging. 7526 throw new IllegalArgumentException( 7527 "Attempt to launch content provider before system ready"); 7528 } 7529 7530 // Make sure that the user who owns this provider is started. If not, 7531 // we don't want to allow it to run. 7532 if (mStartedUsers.get(userId) == null) { 7533 Slog.w(TAG, "Unable to launch app " 7534 + cpi.applicationInfo.packageName + "/" 7535 + cpi.applicationInfo.uid + " for provider " 7536 + name + ": user " + userId + " is stopped"); 7537 return null; 7538 } 7539 7540 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 7541 cpr = mProviderMap.getProviderByClass(comp, userId); 7542 final boolean firstClass = cpr == null; 7543 if (firstClass) { 7544 try { 7545 ApplicationInfo ai = 7546 AppGlobals.getPackageManager(). 7547 getApplicationInfo( 7548 cpi.applicationInfo.packageName, 7549 STOCK_PM_FLAGS, userId); 7550 if (ai == null) { 7551 Slog.w(TAG, "No package info for content provider " 7552 + cpi.name); 7553 return null; 7554 } 7555 ai = getAppInfoForUser(ai, userId); 7556 cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton); 7557 } catch (RemoteException ex) { 7558 // pm is in same process, this will never happen. 7559 } 7560 } 7561 7562 if (r != null && cpr.canRunHere(r)) { 7563 // If this is a multiprocess provider, then just return its 7564 // info and allow the caller to instantiate it. Only do 7565 // this if the provider is the same user as the caller's 7566 // process, or can run as root (so can be in any process). 7567 return cpr.newHolder(null); 7568 } 7569 7570 if (DEBUG_PROVIDER) { 7571 RuntimeException e = new RuntimeException("here"); 7572 Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null) 7573 + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e); 7574 } 7575 7576 // This is single process, and our app is now connecting to it. 7577 // See if we are already in the process of launching this 7578 // provider. 7579 final int N = mLaunchingProviders.size(); 7580 int i; 7581 for (i=0; i<N; i++) { 7582 if (mLaunchingProviders.get(i) == cpr) { 7583 break; 7584 } 7585 } 7586 7587 // If the provider is not already being launched, then get it 7588 // started. 7589 if (i >= N) { 7590 final long origId = Binder.clearCallingIdentity(); 7591 7592 try { 7593 // Content provider is now in use, its package can't be stopped. 7594 try { 7595 AppGlobals.getPackageManager().setPackageStoppedState( 7596 cpr.appInfo.packageName, false, userId); 7597 } catch (RemoteException e) { 7598 } catch (IllegalArgumentException e) { 7599 Slog.w(TAG, "Failed trying to unstop package " 7600 + cpr.appInfo.packageName + ": " + e); 7601 } 7602 7603 // Use existing process if already started 7604 ProcessRecord proc = getProcessRecordLocked( 7605 cpi.processName, cpr.appInfo.uid, false); 7606 if (proc != null && proc.thread != null) { 7607 if (DEBUG_PROVIDER) { 7608 Slog.d(TAG, "Installing in existing process " + proc); 7609 } 7610 proc.pubProviders.put(cpi.name, cpr); 7611 try { 7612 proc.thread.scheduleInstallProvider(cpi); 7613 } catch (RemoteException e) { 7614 } 7615 } else { 7616 proc = startProcessLocked(cpi.processName, 7617 cpr.appInfo, false, 0, "content provider", 7618 new ComponentName(cpi.applicationInfo.packageName, 7619 cpi.name), false, false, false); 7620 if (proc == null) { 7621 Slog.w(TAG, "Unable to launch app " 7622 + cpi.applicationInfo.packageName + "/" 7623 + cpi.applicationInfo.uid + " for provider " 7624 + name + ": process is bad"); 7625 return null; 7626 } 7627 } 7628 cpr.launchingApp = proc; 7629 mLaunchingProviders.add(cpr); 7630 } finally { 7631 Binder.restoreCallingIdentity(origId); 7632 } 7633 } 7634 7635 // Make sure the provider is published (the same provider class 7636 // may be published under multiple names). 7637 if (firstClass) { 7638 mProviderMap.putProviderByClass(comp, cpr); 7639 } 7640 7641 mProviderMap.putProviderByName(name, cpr); 7642 conn = incProviderCountLocked(r, cpr, token, stable); 7643 if (conn != null) { 7644 conn.waiting = true; 7645 } 7646 } 7647 } 7648 7649 // Wait for the provider to be published... 7650 synchronized (cpr) { 7651 while (cpr.provider == null) { 7652 if (cpr.launchingApp == null) { 7653 Slog.w(TAG, "Unable to launch app " 7654 + cpi.applicationInfo.packageName + "/" 7655 + cpi.applicationInfo.uid + " for provider " 7656 + name + ": launching app became null"); 7657 EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS, 7658 UserHandle.getUserId(cpi.applicationInfo.uid), 7659 cpi.applicationInfo.packageName, 7660 cpi.applicationInfo.uid, name); 7661 return null; 7662 } 7663 try { 7664 if (DEBUG_MU) { 7665 Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp=" 7666 + cpr.launchingApp); 7667 } 7668 if (conn != null) { 7669 conn.waiting = true; 7670 } 7671 cpr.wait(); 7672 } catch (InterruptedException ex) { 7673 } finally { 7674 if (conn != null) { 7675 conn.waiting = false; 7676 } 7677 } 7678 } 7679 } 7680 return cpr != null ? cpr.newHolder(conn) : null; 7681 } 7682 7683 public final ContentProviderHolder getContentProvider( 7684 IApplicationThread caller, String name, int userId, boolean stable) { 7685 enforceNotIsolatedCaller("getContentProvider"); 7686 if (caller == null) { 7687 String msg = "null IApplicationThread when getting content provider " 7688 + name; 7689 Slog.w(TAG, msg); 7690 throw new SecurityException(msg); 7691 } 7692 7693 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 7694 false, true, "getContentProvider", null); 7695 return getContentProviderImpl(caller, name, null, stable, userId); 7696 } 7697 7698 public ContentProviderHolder getContentProviderExternal( 7699 String name, int userId, IBinder token) { 7700 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 7701 "Do not have permission in call getContentProviderExternal()"); 7702 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 7703 false, true, "getContentProvider", null); 7704 return getContentProviderExternalUnchecked(name, token, userId); 7705 } 7706 7707 private ContentProviderHolder getContentProviderExternalUnchecked(String name, 7708 IBinder token, int userId) { 7709 return getContentProviderImpl(null, name, token, true, userId); 7710 } 7711 7712 /** 7713 * Drop a content provider from a ProcessRecord's bookkeeping 7714 */ 7715 public void removeContentProvider(IBinder connection, boolean stable) { 7716 enforceNotIsolatedCaller("removeContentProvider"); 7717 synchronized (this) { 7718 ContentProviderConnection conn; 7719 try { 7720 conn = (ContentProviderConnection)connection; 7721 } catch (ClassCastException e) { 7722 String msg ="removeContentProvider: " + connection 7723 + " not a ContentProviderConnection"; 7724 Slog.w(TAG, msg); 7725 throw new IllegalArgumentException(msg); 7726 } 7727 if (conn == null) { 7728 throw new NullPointerException("connection is null"); 7729 } 7730 if (decProviderCountLocked(conn, null, null, stable)) { 7731 updateOomAdjLocked(); 7732 } 7733 } 7734 } 7735 7736 public void removeContentProviderExternal(String name, IBinder token) { 7737 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 7738 "Do not have permission in call removeContentProviderExternal()"); 7739 removeContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId()); 7740 } 7741 7742 private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) { 7743 synchronized (this) { 7744 ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId); 7745 if(cpr == null) { 7746 //remove from mProvidersByClass 7747 if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list"); 7748 return; 7749 } 7750 7751 //update content provider record entry info 7752 ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name); 7753 ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId); 7754 if (localCpr.hasExternalProcessHandles()) { 7755 if (localCpr.removeExternalProcessHandleLocked(token)) { 7756 updateOomAdjLocked(); 7757 } else { 7758 Slog.e(TAG, "Attmpt to remove content provider " + localCpr 7759 + " with no external reference for token: " 7760 + token + "."); 7761 } 7762 } else { 7763 Slog.e(TAG, "Attmpt to remove content provider: " + localCpr 7764 + " with no external references."); 7765 } 7766 } 7767 } 7768 7769 public final void publishContentProviders(IApplicationThread caller, 7770 List<ContentProviderHolder> providers) { 7771 if (providers == null) { 7772 return; 7773 } 7774 7775 enforceNotIsolatedCaller("publishContentProviders"); 7776 synchronized (this) { 7777 final ProcessRecord r = getRecordForAppLocked(caller); 7778 if (DEBUG_MU) 7779 Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid); 7780 if (r == null) { 7781 throw new SecurityException( 7782 "Unable to find app for caller " + caller 7783 + " (pid=" + Binder.getCallingPid() 7784 + ") when publishing content providers"); 7785 } 7786 7787 final long origId = Binder.clearCallingIdentity(); 7788 7789 final int N = providers.size(); 7790 for (int i=0; i<N; i++) { 7791 ContentProviderHolder src = providers.get(i); 7792 if (src == null || src.info == null || src.provider == null) { 7793 continue; 7794 } 7795 ContentProviderRecord dst = r.pubProviders.get(src.info.name); 7796 if (DEBUG_MU) 7797 Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid); 7798 if (dst != null) { 7799 ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name); 7800 mProviderMap.putProviderByClass(comp, dst); 7801 String names[] = dst.info.authority.split(";"); 7802 for (int j = 0; j < names.length; j++) { 7803 mProviderMap.putProviderByName(names[j], dst); 7804 } 7805 7806 int NL = mLaunchingProviders.size(); 7807 int j; 7808 for (j=0; j<NL; j++) { 7809 if (mLaunchingProviders.get(j) == dst) { 7810 mLaunchingProviders.remove(j); 7811 j--; 7812 NL--; 7813 } 7814 } 7815 synchronized (dst) { 7816 dst.provider = src.provider; 7817 dst.proc = r; 7818 dst.notifyAll(); 7819 } 7820 updateOomAdjLocked(r); 7821 } 7822 } 7823 7824 Binder.restoreCallingIdentity(origId); 7825 } 7826 } 7827 7828 public boolean refContentProvider(IBinder connection, int stable, int unstable) { 7829 ContentProviderConnection conn; 7830 try { 7831 conn = (ContentProviderConnection)connection; 7832 } catch (ClassCastException e) { 7833 String msg ="refContentProvider: " + connection 7834 + " not a ContentProviderConnection"; 7835 Slog.w(TAG, msg); 7836 throw new IllegalArgumentException(msg); 7837 } 7838 if (conn == null) { 7839 throw new NullPointerException("connection is null"); 7840 } 7841 7842 synchronized (this) { 7843 if (stable > 0) { 7844 conn.numStableIncs += stable; 7845 } 7846 stable = conn.stableCount + stable; 7847 if (stable < 0) { 7848 throw new IllegalStateException("stableCount < 0: " + stable); 7849 } 7850 7851 if (unstable > 0) { 7852 conn.numUnstableIncs += unstable; 7853 } 7854 unstable = conn.unstableCount + unstable; 7855 if (unstable < 0) { 7856 throw new IllegalStateException("unstableCount < 0: " + unstable); 7857 } 7858 7859 if ((stable+unstable) <= 0) { 7860 throw new IllegalStateException("ref counts can't go to zero here: stable=" 7861 + stable + " unstable=" + unstable); 7862 } 7863 conn.stableCount = stable; 7864 conn.unstableCount = unstable; 7865 return !conn.dead; 7866 } 7867 } 7868 7869 public void unstableProviderDied(IBinder connection) { 7870 ContentProviderConnection conn; 7871 try { 7872 conn = (ContentProviderConnection)connection; 7873 } catch (ClassCastException e) { 7874 String msg ="refContentProvider: " + connection 7875 + " not a ContentProviderConnection"; 7876 Slog.w(TAG, msg); 7877 throw new IllegalArgumentException(msg); 7878 } 7879 if (conn == null) { 7880 throw new NullPointerException("connection is null"); 7881 } 7882 7883 // Safely retrieve the content provider associated with the connection. 7884 IContentProvider provider; 7885 synchronized (this) { 7886 provider = conn.provider.provider; 7887 } 7888 7889 if (provider == null) { 7890 // Um, yeah, we're way ahead of you. 7891 return; 7892 } 7893 7894 // Make sure the caller is being honest with us. 7895 if (provider.asBinder().pingBinder()) { 7896 // Er, no, still looks good to us. 7897 synchronized (this) { 7898 Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid() 7899 + " says " + conn + " died, but we don't agree"); 7900 return; 7901 } 7902 } 7903 7904 // Well look at that! It's dead! 7905 synchronized (this) { 7906 if (conn.provider.provider != provider) { 7907 // But something changed... good enough. 7908 return; 7909 } 7910 7911 ProcessRecord proc = conn.provider.proc; 7912 if (proc == null || proc.thread == null) { 7913 // Seems like the process is already cleaned up. 7914 return; 7915 } 7916 7917 // As far as we're concerned, this is just like receiving a 7918 // death notification... just a bit prematurely. 7919 Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid 7920 + ") early provider death"); 7921 final long ident = Binder.clearCallingIdentity(); 7922 try { 7923 appDiedLocked(proc, proc.pid, proc.thread); 7924 } finally { 7925 Binder.restoreCallingIdentity(ident); 7926 } 7927 } 7928 } 7929 7930 @Override 7931 public void appNotRespondingViaProvider(IBinder connection) { 7932 enforceCallingPermission( 7933 android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()"); 7934 7935 final ContentProviderConnection conn = (ContentProviderConnection) connection; 7936 if (conn == null) { 7937 Slog.w(TAG, "ContentProviderConnection is null"); 7938 return; 7939 } 7940 7941 final ProcessRecord host = conn.provider.proc; 7942 if (host == null) { 7943 Slog.w(TAG, "Failed to find hosting ProcessRecord"); 7944 return; 7945 } 7946 7947 final long token = Binder.clearCallingIdentity(); 7948 try { 7949 appNotResponding(host, null, null, false, "ContentProvider not responding"); 7950 } finally { 7951 Binder.restoreCallingIdentity(token); 7952 } 7953 } 7954 7955 public final void installSystemProviders() { 7956 List<ProviderInfo> providers; 7957 synchronized (this) { 7958 ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID); 7959 providers = generateApplicationProvidersLocked(app); 7960 if (providers != null) { 7961 for (int i=providers.size()-1; i>=0; i--) { 7962 ProviderInfo pi = (ProviderInfo)providers.get(i); 7963 if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) { 7964 Slog.w(TAG, "Not installing system proc provider " + pi.name 7965 + ": not system .apk"); 7966 providers.remove(i); 7967 } 7968 } 7969 } 7970 } 7971 if (providers != null) { 7972 mSystemThread.installSystemProviders(providers); 7973 } 7974 7975 mCoreSettingsObserver = new CoreSettingsObserver(this); 7976 7977 mUsageStatsService.monitorPackages(); 7978 } 7979 7980 /** 7981 * Allows app to retrieve the MIME type of a URI without having permission 7982 * to access its content provider. 7983 * 7984 * CTS tests for this functionality can be run with "runtest cts-appsecurity". 7985 * 7986 * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/ 7987 * src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java 7988 */ 7989 public String getProviderMimeType(Uri uri, int userId) { 7990 enforceNotIsolatedCaller("getProviderMimeType"); 7991 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 7992 userId, false, true, "getProviderMimeType", null); 7993 final String name = uri.getAuthority(); 7994 final long ident = Binder.clearCallingIdentity(); 7995 ContentProviderHolder holder = null; 7996 7997 try { 7998 holder = getContentProviderExternalUnchecked(name, null, userId); 7999 if (holder != null) { 8000 return holder.provider.getType(uri); 8001 } 8002 } catch (RemoteException e) { 8003 Log.w(TAG, "Content provider dead retrieving " + uri, e); 8004 return null; 8005 } finally { 8006 if (holder != null) { 8007 removeContentProviderExternalUnchecked(name, null, userId); 8008 } 8009 Binder.restoreCallingIdentity(ident); 8010 } 8011 8012 return null; 8013 } 8014 8015 // ========================================================= 8016 // GLOBAL MANAGEMENT 8017 // ========================================================= 8018 8019 final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess, 8020 boolean isolated) { 8021 String proc = customProcess != null ? customProcess : info.processName; 8022 BatteryStatsImpl.Uid.Proc ps = null; 8023 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 8024 int uid = info.uid; 8025 if (isolated) { 8026 int userId = UserHandle.getUserId(uid); 8027 int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1; 8028 while (true) { 8029 if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID 8030 || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) { 8031 mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID; 8032 } 8033 uid = UserHandle.getUid(userId, mNextIsolatedProcessUid); 8034 mNextIsolatedProcessUid++; 8035 if (mIsolatedProcesses.indexOfKey(uid) < 0) { 8036 // No process for this uid, use it. 8037 break; 8038 } 8039 stepsLeft--; 8040 if (stepsLeft <= 0) { 8041 return null; 8042 } 8043 } 8044 } 8045 return new ProcessRecord(stats, info, proc, uid); 8046 } 8047 8048 final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated) { 8049 ProcessRecord app; 8050 if (!isolated) { 8051 app = getProcessRecordLocked(info.processName, info.uid, true); 8052 } else { 8053 app = null; 8054 } 8055 8056 if (app == null) { 8057 app = newProcessRecordLocked(info, null, isolated); 8058 mProcessNames.put(info.processName, app.uid, app); 8059 if (isolated) { 8060 mIsolatedProcesses.put(app.uid, app); 8061 } 8062 updateLruProcessLocked(app, false, null); 8063 updateOomAdjLocked(); 8064 } 8065 8066 // This package really, really can not be stopped. 8067 try { 8068 AppGlobals.getPackageManager().setPackageStoppedState( 8069 info.packageName, false, UserHandle.getUserId(app.uid)); 8070 } catch (RemoteException e) { 8071 } catch (IllegalArgumentException e) { 8072 Slog.w(TAG, "Failed trying to unstop package " 8073 + info.packageName + ": " + e); 8074 } 8075 8076 if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) 8077 == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) { 8078 app.persistent = true; 8079 app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ; 8080 } 8081 if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) { 8082 mPersistentStartingProcesses.add(app); 8083 startProcessLocked(app, "added application", app.processName); 8084 } 8085 8086 return app; 8087 } 8088 8089 public void unhandledBack() { 8090 enforceCallingPermission(android.Manifest.permission.FORCE_BACK, 8091 "unhandledBack()"); 8092 8093 synchronized(this) { 8094 final long origId = Binder.clearCallingIdentity(); 8095 try { 8096 getFocusedStack().unhandledBackLocked(); 8097 } finally { 8098 Binder.restoreCallingIdentity(origId); 8099 } 8100 } 8101 } 8102 8103 public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException { 8104 enforceNotIsolatedCaller("openContentUri"); 8105 final int userId = UserHandle.getCallingUserId(); 8106 String name = uri.getAuthority(); 8107 ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId); 8108 ParcelFileDescriptor pfd = null; 8109 if (cph != null) { 8110 // We record the binder invoker's uid in thread-local storage before 8111 // going to the content provider to open the file. Later, in the code 8112 // that handles all permissions checks, we look for this uid and use 8113 // that rather than the Activity Manager's own uid. The effect is that 8114 // we do the check against the caller's permissions even though it looks 8115 // to the content provider like the Activity Manager itself is making 8116 // the request. 8117 sCallerIdentity.set(new Identity( 8118 Binder.getCallingPid(), Binder.getCallingUid())); 8119 try { 8120 pfd = cph.provider.openFile(null, uri, "r", null); 8121 } catch (FileNotFoundException e) { 8122 // do nothing; pfd will be returned null 8123 } finally { 8124 // Ensure that whatever happens, we clean up the identity state 8125 sCallerIdentity.remove(); 8126 } 8127 8128 // We've got the fd now, so we're done with the provider. 8129 removeContentProviderExternalUnchecked(name, null, userId); 8130 } else { 8131 Slog.d(TAG, "Failed to get provider for authority '" + name + "'"); 8132 } 8133 return pfd; 8134 } 8135 8136 // Actually is sleeping or shutting down or whatever else in the future 8137 // is an inactive state. 8138 public boolean isSleepingOrShuttingDown() { 8139 return mSleeping || mShuttingDown; 8140 } 8141 8142 void goingToSleep() { 8143 synchronized(this) { 8144 mWentToSleep = true; 8145 updateEventDispatchingLocked(); 8146 8147 if (!mSleeping) { 8148 mSleeping = true; 8149 mStackSupervisor.goingToSleepLocked(); 8150 8151 // Initialize the wake times of all processes. 8152 checkExcessivePowerUsageLocked(false); 8153 mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 8154 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 8155 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 8156 } 8157 } 8158 } 8159 8160 @Override 8161 public boolean shutdown(int timeout) { 8162 if (checkCallingPermission(android.Manifest.permission.SHUTDOWN) 8163 != PackageManager.PERMISSION_GRANTED) { 8164 throw new SecurityException("Requires permission " 8165 + android.Manifest.permission.SHUTDOWN); 8166 } 8167 8168 boolean timedout = false; 8169 8170 synchronized(this) { 8171 mShuttingDown = true; 8172 updateEventDispatchingLocked(); 8173 timedout = mStackSupervisor.shutdownLocked(timeout); 8174 } 8175 8176 mAppOpsService.shutdown(); 8177 mUsageStatsService.shutdown(); 8178 mBatteryStatsService.shutdown(); 8179 synchronized (this) { 8180 mProcessStats.shutdownLocked(); 8181 } 8182 8183 return timedout; 8184 } 8185 8186 public final void activitySlept(IBinder token) { 8187 if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token); 8188 8189 final long origId = Binder.clearCallingIdentity(); 8190 8191 synchronized (this) { 8192 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 8193 if (r != null) { 8194 mStackSupervisor.activitySleptLocked(r); 8195 } 8196 } 8197 8198 Binder.restoreCallingIdentity(origId); 8199 } 8200 8201 void logLockScreen(String msg) { 8202 if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg + 8203 " mLockScreenShown=" + mLockScreenShown + " mWentToSleep=" + 8204 mWentToSleep + " mSleeping=" + mSleeping + " mDismissKeyguardOnNextActivity=" + 8205 mStackSupervisor.mDismissKeyguardOnNextActivity); 8206 } 8207 8208 private void comeOutOfSleepIfNeededLocked() { 8209 if (!mWentToSleep && !mLockScreenShown) { 8210 if (mSleeping) { 8211 mSleeping = false; 8212 mStackSupervisor.comeOutOfSleepIfNeededLocked(); 8213 } 8214 } 8215 } 8216 8217 void wakingUp() { 8218 synchronized(this) { 8219 mWentToSleep = false; 8220 updateEventDispatchingLocked(); 8221 comeOutOfSleepIfNeededLocked(); 8222 } 8223 } 8224 8225 private void updateEventDispatchingLocked() { 8226 mWindowManager.setEventDispatching(mBooted && !mWentToSleep && !mShuttingDown); 8227 } 8228 8229 public void setLockScreenShown(boolean shown) { 8230 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER) 8231 != PackageManager.PERMISSION_GRANTED) { 8232 throw new SecurityException("Requires permission " 8233 + android.Manifest.permission.DEVICE_POWER); 8234 } 8235 8236 synchronized(this) { 8237 long ident = Binder.clearCallingIdentity(); 8238 try { 8239 if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown); 8240 mLockScreenShown = shown; 8241 comeOutOfSleepIfNeededLocked(); 8242 } finally { 8243 Binder.restoreCallingIdentity(ident); 8244 } 8245 } 8246 } 8247 8248 @Override 8249 public void stopAppSwitches() { 8250 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 8251 != PackageManager.PERMISSION_GRANTED) { 8252 throw new SecurityException("Requires permission " 8253 + android.Manifest.permission.STOP_APP_SWITCHES); 8254 } 8255 8256 synchronized(this) { 8257 mAppSwitchesAllowedTime = SystemClock.uptimeMillis() 8258 + APP_SWITCH_DELAY_TIME; 8259 mDidAppSwitch = false; 8260 mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 8261 Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 8262 mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME); 8263 } 8264 } 8265 8266 public void resumeAppSwitches() { 8267 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 8268 != PackageManager.PERMISSION_GRANTED) { 8269 throw new SecurityException("Requires permission " 8270 + android.Manifest.permission.STOP_APP_SWITCHES); 8271 } 8272 8273 synchronized(this) { 8274 // Note that we don't execute any pending app switches... we will 8275 // let those wait until either the timeout, or the next start 8276 // activity request. 8277 mAppSwitchesAllowedTime = 0; 8278 } 8279 } 8280 8281 boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid, 8282 String name) { 8283 if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) { 8284 return true; 8285 } 8286 8287 final int perm = checkComponentPermission( 8288 android.Manifest.permission.STOP_APP_SWITCHES, callingPid, 8289 callingUid, -1, true); 8290 if (perm == PackageManager.PERMISSION_GRANTED) { 8291 return true; 8292 } 8293 8294 Slog.w(TAG, name + " request from " + callingUid + " stopped"); 8295 return false; 8296 } 8297 8298 public void setDebugApp(String packageName, boolean waitForDebugger, 8299 boolean persistent) { 8300 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP, 8301 "setDebugApp()"); 8302 8303 long ident = Binder.clearCallingIdentity(); 8304 try { 8305 // Note that this is not really thread safe if there are multiple 8306 // callers into it at the same time, but that's not a situation we 8307 // care about. 8308 if (persistent) { 8309 final ContentResolver resolver = mContext.getContentResolver(); 8310 Settings.Global.putString( 8311 resolver, Settings.Global.DEBUG_APP, 8312 packageName); 8313 Settings.Global.putInt( 8314 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 8315 waitForDebugger ? 1 : 0); 8316 } 8317 8318 synchronized (this) { 8319 if (!persistent) { 8320 mOrigDebugApp = mDebugApp; 8321 mOrigWaitForDebugger = mWaitForDebugger; 8322 } 8323 mDebugApp = packageName; 8324 mWaitForDebugger = waitForDebugger; 8325 mDebugTransient = !persistent; 8326 if (packageName != null) { 8327 forceStopPackageLocked(packageName, -1, false, false, true, true, 8328 UserHandle.USER_ALL, "set debug app"); 8329 } 8330 } 8331 } finally { 8332 Binder.restoreCallingIdentity(ident); 8333 } 8334 } 8335 8336 void setOpenGlTraceApp(ApplicationInfo app, String processName) { 8337 synchronized (this) { 8338 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 8339 if (!isDebuggable) { 8340 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 8341 throw new SecurityException("Process not debuggable: " + app.packageName); 8342 } 8343 } 8344 8345 mOpenGlTraceApp = processName; 8346 } 8347 } 8348 8349 void setProfileApp(ApplicationInfo app, String processName, String profileFile, 8350 ParcelFileDescriptor profileFd, boolean autoStopProfiler) { 8351 synchronized (this) { 8352 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 8353 if (!isDebuggable) { 8354 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 8355 throw new SecurityException("Process not debuggable: " + app.packageName); 8356 } 8357 } 8358 mProfileApp = processName; 8359 mProfileFile = profileFile; 8360 if (mProfileFd != null) { 8361 try { 8362 mProfileFd.close(); 8363 } catch (IOException e) { 8364 } 8365 mProfileFd = null; 8366 } 8367 mProfileFd = profileFd; 8368 mProfileType = 0; 8369 mAutoStopProfiler = autoStopProfiler; 8370 } 8371 } 8372 8373 @Override 8374 public void setAlwaysFinish(boolean enabled) { 8375 enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH, 8376 "setAlwaysFinish()"); 8377 8378 Settings.Global.putInt( 8379 mContext.getContentResolver(), 8380 Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0); 8381 8382 synchronized (this) { 8383 mAlwaysFinishActivities = enabled; 8384 } 8385 } 8386 8387 @Override 8388 public void setActivityController(IActivityController controller) { 8389 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 8390 "setActivityController()"); 8391 synchronized (this) { 8392 mController = controller; 8393 Watchdog.getInstance().setActivityController(controller); 8394 } 8395 } 8396 8397 @Override 8398 public void setUserIsMonkey(boolean userIsMonkey) { 8399 synchronized (this) { 8400 synchronized (mPidsSelfLocked) { 8401 final int callingPid = Binder.getCallingPid(); 8402 ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid); 8403 if (precessRecord == null) { 8404 throw new SecurityException("Unknown process: " + callingPid); 8405 } 8406 if (precessRecord.instrumentationUiAutomationConnection == null) { 8407 throw new SecurityException("Only an instrumentation process " 8408 + "with a UiAutomation can call setUserIsMonkey"); 8409 } 8410 } 8411 mUserIsMonkey = userIsMonkey; 8412 } 8413 } 8414 8415 @Override 8416 public boolean isUserAMonkey() { 8417 synchronized (this) { 8418 // If there is a controller also implies the user is a monkey. 8419 return (mUserIsMonkey || mController != null); 8420 } 8421 } 8422 8423 public void requestBugReport() { 8424 enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport"); 8425 SystemProperties.set("ctl.start", "bugreport"); 8426 } 8427 8428 public static long getInputDispatchingTimeoutLocked(ActivityRecord r) { 8429 return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT; 8430 } 8431 8432 public static long getInputDispatchingTimeoutLocked(ProcessRecord r) { 8433 if (r != null && (r.instrumentationClass != null || r.usingWrapper)) { 8434 return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT; 8435 } 8436 return KEY_DISPATCHING_TIMEOUT; 8437 } 8438 8439 @Override 8440 public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) { 8441 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS) 8442 != PackageManager.PERMISSION_GRANTED) { 8443 throw new SecurityException("Requires permission " 8444 + android.Manifest.permission.FILTER_EVENTS); 8445 } 8446 ProcessRecord proc; 8447 long timeout; 8448 synchronized (this) { 8449 synchronized (mPidsSelfLocked) { 8450 proc = mPidsSelfLocked.get(pid); 8451 } 8452 timeout = getInputDispatchingTimeoutLocked(proc); 8453 } 8454 8455 if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) { 8456 return -1; 8457 } 8458 8459 return timeout; 8460 } 8461 8462 /** 8463 * Handle input dispatching timeouts. 8464 * Returns whether input dispatching should be aborted or not. 8465 */ 8466 public boolean inputDispatchingTimedOut(final ProcessRecord proc, 8467 final ActivityRecord activity, final ActivityRecord parent, 8468 final boolean aboveSystem, String reason) { 8469 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS) 8470 != PackageManager.PERMISSION_GRANTED) { 8471 throw new SecurityException("Requires permission " 8472 + android.Manifest.permission.FILTER_EVENTS); 8473 } 8474 8475 final String annotation; 8476 if (reason == null) { 8477 annotation = "Input dispatching timed out"; 8478 } else { 8479 annotation = "Input dispatching timed out (" + reason + ")"; 8480 } 8481 8482 if (proc != null) { 8483 synchronized (this) { 8484 if (proc.debugging) { 8485 return false; 8486 } 8487 8488 if (mDidDexOpt) { 8489 // Give more time since we were dexopting. 8490 mDidDexOpt = false; 8491 return false; 8492 } 8493 8494 if (proc.instrumentationClass != null) { 8495 Bundle info = new Bundle(); 8496 info.putString("shortMsg", "keyDispatchingTimedOut"); 8497 info.putString("longMsg", annotation); 8498 finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info); 8499 return true; 8500 } 8501 } 8502 mHandler.post(new Runnable() { 8503 @Override 8504 public void run() { 8505 appNotResponding(proc, activity, parent, aboveSystem, annotation); 8506 } 8507 }); 8508 } 8509 8510 return true; 8511 } 8512 8513 public Bundle getAssistContextExtras(int requestType) { 8514 enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO, 8515 "getAssistContextExtras()"); 8516 PendingAssistExtras pae; 8517 Bundle extras = new Bundle(); 8518 synchronized (this) { 8519 ActivityRecord activity = getFocusedStack().mResumedActivity; 8520 if (activity == null) { 8521 Slog.w(TAG, "getAssistContextExtras failed: no resumed activity"); 8522 return null; 8523 } 8524 extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName); 8525 if (activity.app == null || activity.app.thread == null) { 8526 Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity); 8527 return extras; 8528 } 8529 if (activity.app.pid == Binder.getCallingPid()) { 8530 Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity); 8531 return extras; 8532 } 8533 pae = new PendingAssistExtras(activity); 8534 try { 8535 activity.app.thread.requestAssistContextExtras(activity.appToken, pae, 8536 requestType); 8537 mPendingAssistExtras.add(pae); 8538 mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT); 8539 } catch (RemoteException e) { 8540 Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity); 8541 return extras; 8542 } 8543 } 8544 synchronized (pae) { 8545 while (!pae.haveResult) { 8546 try { 8547 pae.wait(); 8548 } catch (InterruptedException e) { 8549 } 8550 } 8551 if (pae.result != null) { 8552 extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result); 8553 } 8554 } 8555 synchronized (this) { 8556 mPendingAssistExtras.remove(pae); 8557 mHandler.removeCallbacks(pae); 8558 } 8559 return extras; 8560 } 8561 8562 public void reportAssistContextExtras(IBinder token, Bundle extras) { 8563 PendingAssistExtras pae = (PendingAssistExtras)token; 8564 synchronized (pae) { 8565 pae.result = extras; 8566 pae.haveResult = true; 8567 pae.notifyAll(); 8568 } 8569 } 8570 8571 public void registerProcessObserver(IProcessObserver observer) { 8572 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 8573 "registerProcessObserver()"); 8574 synchronized (this) { 8575 mProcessObservers.register(observer); 8576 } 8577 } 8578 8579 @Override 8580 public void unregisterProcessObserver(IProcessObserver observer) { 8581 synchronized (this) { 8582 mProcessObservers.unregister(observer); 8583 } 8584 } 8585 8586 @Override 8587 public boolean convertFromTranslucent(IBinder token) { 8588 final long origId = Binder.clearCallingIdentity(); 8589 try { 8590 synchronized (this) { 8591 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 8592 if (r == null) { 8593 return false; 8594 } 8595 if (r.changeWindowTranslucency(true)) { 8596 mWindowManager.setAppFullscreen(token, true); 8597 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 8598 return true; 8599 } 8600 return false; 8601 } 8602 } finally { 8603 Binder.restoreCallingIdentity(origId); 8604 } 8605 } 8606 8607 @Override 8608 public boolean convertToTranslucent(IBinder token) { 8609 final long origId = Binder.clearCallingIdentity(); 8610 try { 8611 synchronized (this) { 8612 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 8613 if (r == null) { 8614 return false; 8615 } 8616 if (r.changeWindowTranslucency(false)) { 8617 r.task.stack.convertToTranslucent(r); 8618 mWindowManager.setAppFullscreen(token, false); 8619 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 8620 return true; 8621 } 8622 return false; 8623 } 8624 } finally { 8625 Binder.restoreCallingIdentity(origId); 8626 } 8627 } 8628 8629 @Override 8630 public void setImmersive(IBinder token, boolean immersive) { 8631 synchronized(this) { 8632 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 8633 if (r == null) { 8634 throw new IllegalArgumentException(); 8635 } 8636 r.immersive = immersive; 8637 8638 // update associated state if we're frontmost 8639 if (r == mFocusedActivity) { 8640 if (DEBUG_IMMERSIVE) { 8641 Slog.d(TAG, "Frontmost changed immersion: "+ r); 8642 } 8643 applyUpdateLockStateLocked(r); 8644 } 8645 } 8646 } 8647 8648 @Override 8649 public boolean isImmersive(IBinder token) { 8650 synchronized (this) { 8651 ActivityRecord r = ActivityRecord.isInStackLocked(token); 8652 if (r == null) { 8653 throw new IllegalArgumentException(); 8654 } 8655 return r.immersive; 8656 } 8657 } 8658 8659 public boolean isTopActivityImmersive() { 8660 enforceNotIsolatedCaller("startActivity"); 8661 synchronized (this) { 8662 ActivityRecord r = getFocusedStack().topRunningActivityLocked(null); 8663 return (r != null) ? r.immersive : false; 8664 } 8665 } 8666 8667 public final void enterSafeMode() { 8668 synchronized(this) { 8669 // It only makes sense to do this before the system is ready 8670 // and started launching other packages. 8671 if (!mSystemReady) { 8672 try { 8673 AppGlobals.getPackageManager().enterSafeMode(); 8674 } catch (RemoteException e) { 8675 } 8676 } 8677 } 8678 } 8679 8680 public final void showSafeModeOverlay() { 8681 View v = LayoutInflater.from(mContext).inflate( 8682 com.android.internal.R.layout.safe_mode, null); 8683 WindowManager.LayoutParams lp = new WindowManager.LayoutParams(); 8684 lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY; 8685 lp.width = WindowManager.LayoutParams.WRAP_CONTENT; 8686 lp.height = WindowManager.LayoutParams.WRAP_CONTENT; 8687 lp.gravity = Gravity.BOTTOM | Gravity.START; 8688 lp.format = v.getBackground().getOpacity(); 8689 lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE 8690 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE; 8691 lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS; 8692 ((WindowManager)mContext.getSystemService( 8693 Context.WINDOW_SERVICE)).addView(v, lp); 8694 } 8695 8696 public void noteWakeupAlarm(IIntentSender sender) { 8697 if (!(sender instanceof PendingIntentRecord)) { 8698 return; 8699 } 8700 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 8701 synchronized (stats) { 8702 if (mBatteryStatsService.isOnBattery()) { 8703 mBatteryStatsService.enforceCallingPermission(); 8704 PendingIntentRecord rec = (PendingIntentRecord)sender; 8705 int MY_UID = Binder.getCallingUid(); 8706 int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid; 8707 BatteryStatsImpl.Uid.Pkg pkg = 8708 stats.getPackageStatsLocked(uid, rec.key.packageName); 8709 pkg.incWakeupsLocked(); 8710 } 8711 } 8712 } 8713 8714 public boolean killPids(int[] pids, String pReason, boolean secure) { 8715 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 8716 throw new SecurityException("killPids only available to the system"); 8717 } 8718 String reason = (pReason == null) ? "Unknown" : pReason; 8719 // XXX Note: don't acquire main activity lock here, because the window 8720 // manager calls in with its locks held. 8721 8722 boolean killed = false; 8723 synchronized (mPidsSelfLocked) { 8724 int[] types = new int[pids.length]; 8725 int worstType = 0; 8726 for (int i=0; i<pids.length; i++) { 8727 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 8728 if (proc != null) { 8729 int type = proc.setAdj; 8730 types[i] = type; 8731 if (type > worstType) { 8732 worstType = type; 8733 } 8734 } 8735 } 8736 8737 // If the worst oom_adj is somewhere in the cached proc LRU range, 8738 // then constrain it so we will kill all cached procs. 8739 if (worstType < ProcessList.CACHED_APP_MAX_ADJ 8740 && worstType > ProcessList.CACHED_APP_MIN_ADJ) { 8741 worstType = ProcessList.CACHED_APP_MIN_ADJ; 8742 } 8743 8744 // If this is not a secure call, don't let it kill processes that 8745 // are important. 8746 if (!secure && worstType < ProcessList.SERVICE_ADJ) { 8747 worstType = ProcessList.SERVICE_ADJ; 8748 } 8749 8750 Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType); 8751 for (int i=0; i<pids.length; i++) { 8752 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 8753 if (proc == null) { 8754 continue; 8755 } 8756 int adj = proc.setAdj; 8757 if (adj >= worstType && !proc.killedByAm) { 8758 killUnneededProcessLocked(proc, reason); 8759 killed = true; 8760 } 8761 } 8762 } 8763 return killed; 8764 } 8765 8766 @Override 8767 public void killUid(int uid, String reason) { 8768 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 8769 throw new SecurityException("killUid only available to the system"); 8770 } 8771 synchronized (this) { 8772 killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid), 8773 ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false, 8774 reason != null ? reason : "kill uid"); 8775 } 8776 } 8777 8778 @Override 8779 public boolean killProcessesBelowForeground(String reason) { 8780 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 8781 throw new SecurityException("killProcessesBelowForeground() only available to system"); 8782 } 8783 8784 return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason); 8785 } 8786 8787 private boolean killProcessesBelowAdj(int belowAdj, String reason) { 8788 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 8789 throw new SecurityException("killProcessesBelowAdj() only available to system"); 8790 } 8791 8792 boolean killed = false; 8793 synchronized (mPidsSelfLocked) { 8794 final int size = mPidsSelfLocked.size(); 8795 for (int i = 0; i < size; i++) { 8796 final int pid = mPidsSelfLocked.keyAt(i); 8797 final ProcessRecord proc = mPidsSelfLocked.valueAt(i); 8798 if (proc == null) continue; 8799 8800 final int adj = proc.setAdj; 8801 if (adj > belowAdj && !proc.killedByAm) { 8802 killUnneededProcessLocked(proc, reason); 8803 killed = true; 8804 } 8805 } 8806 } 8807 return killed; 8808 } 8809 8810 @Override 8811 public void hang(final IBinder who, boolean allowRestart) { 8812 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 8813 != PackageManager.PERMISSION_GRANTED) { 8814 throw new SecurityException("Requires permission " 8815 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 8816 } 8817 8818 final IBinder.DeathRecipient death = new DeathRecipient() { 8819 @Override 8820 public void binderDied() { 8821 synchronized (this) { 8822 notifyAll(); 8823 } 8824 } 8825 }; 8826 8827 try { 8828 who.linkToDeath(death, 0); 8829 } catch (RemoteException e) { 8830 Slog.w(TAG, "hang: given caller IBinder is already dead."); 8831 return; 8832 } 8833 8834 synchronized (this) { 8835 Watchdog.getInstance().setAllowRestart(allowRestart); 8836 Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid()); 8837 synchronized (death) { 8838 while (who.isBinderAlive()) { 8839 try { 8840 death.wait(); 8841 } catch (InterruptedException e) { 8842 } 8843 } 8844 } 8845 Watchdog.getInstance().setAllowRestart(true); 8846 } 8847 } 8848 8849 @Override 8850 public void restart() { 8851 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 8852 != PackageManager.PERMISSION_GRANTED) { 8853 throw new SecurityException("Requires permission " 8854 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 8855 } 8856 8857 Log.i(TAG, "Sending shutdown broadcast..."); 8858 8859 BroadcastReceiver br = new BroadcastReceiver() { 8860 @Override public void onReceive(Context context, Intent intent) { 8861 // Now the broadcast is done, finish up the low-level shutdown. 8862 Log.i(TAG, "Shutting down activity manager..."); 8863 shutdown(10000); 8864 Log.i(TAG, "Shutdown complete, restarting!"); 8865 Process.killProcess(Process.myPid()); 8866 System.exit(10); 8867 } 8868 }; 8869 8870 // First send the high-level shut down broadcast. 8871 Intent intent = new Intent(Intent.ACTION_SHUTDOWN); 8872 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 8873 intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true); 8874 /* For now we are not doing a clean shutdown, because things seem to get unhappy. 8875 mContext.sendOrderedBroadcastAsUser(intent, 8876 UserHandle.ALL, null, br, mHandler, 0, null, null); 8877 */ 8878 br.onReceive(mContext, intent); 8879 } 8880 8881 private long getLowRamTimeSinceIdle(long now) { 8882 return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0); 8883 } 8884 8885 @Override 8886 public void performIdleMaintenance() { 8887 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 8888 != PackageManager.PERMISSION_GRANTED) { 8889 throw new SecurityException("Requires permission " 8890 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 8891 } 8892 8893 synchronized (this) { 8894 final long now = SystemClock.uptimeMillis(); 8895 final long timeSinceLastIdle = now - mLastIdleTime; 8896 final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now); 8897 mLastIdleTime = now; 8898 mLowRamTimeSinceLastIdle = 0; 8899 if (mLowRamStartTime != 0) { 8900 mLowRamStartTime = now; 8901 } 8902 8903 StringBuilder sb = new StringBuilder(128); 8904 sb.append("Idle maintenance over "); 8905 TimeUtils.formatDuration(timeSinceLastIdle, sb); 8906 sb.append(" low RAM for "); 8907 TimeUtils.formatDuration(lowRamSinceLastIdle, sb); 8908 Slog.i(TAG, sb.toString()); 8909 8910 // If at least 1/3 of our time since the last idle period has been spent 8911 // with RAM low, then we want to kill processes. 8912 boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3); 8913 8914 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 8915 ProcessRecord proc = mLruProcesses.get(i); 8916 if (proc.notCachedSinceIdle) { 8917 if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP 8918 && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) { 8919 if (doKilling && proc.initialIdlePss != 0 8920 && proc.lastPss > ((proc.initialIdlePss*3)/2)) { 8921 killUnneededProcessLocked(proc, "idle maint (pss " + proc.lastPss 8922 + " from " + proc.initialIdlePss + ")"); 8923 } 8924 } 8925 } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) { 8926 proc.notCachedSinceIdle = true; 8927 proc.initialIdlePss = 0; 8928 proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true, 8929 mSleeping, now); 8930 } 8931 } 8932 8933 mHandler.removeMessages(REQUEST_ALL_PSS_MSG); 8934 mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000); 8935 } 8936 } 8937 8938 private void retrieveSettings() { 8939 final ContentResolver resolver = mContext.getContentResolver(); 8940 String debugApp = Settings.Global.getString( 8941 resolver, Settings.Global.DEBUG_APP); 8942 boolean waitForDebugger = Settings.Global.getInt( 8943 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0; 8944 boolean alwaysFinishActivities = Settings.Global.getInt( 8945 resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0; 8946 boolean forceRtl = Settings.Global.getInt( 8947 resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0; 8948 // Transfer any global setting for forcing RTL layout, into a System Property 8949 SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0"); 8950 8951 Configuration configuration = new Configuration(); 8952 Settings.System.getConfiguration(resolver, configuration); 8953 if (forceRtl) { 8954 // This will take care of setting the correct layout direction flags 8955 configuration.setLayoutDirection(configuration.locale); 8956 } 8957 8958 synchronized (this) { 8959 mDebugApp = mOrigDebugApp = debugApp; 8960 mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger; 8961 mAlwaysFinishActivities = alwaysFinishActivities; 8962 // This happens before any activities are started, so we can 8963 // change mConfiguration in-place. 8964 updateConfigurationLocked(configuration, null, false, true); 8965 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration); 8966 } 8967 } 8968 8969 public boolean testIsSystemReady() { 8970 // no need to synchronize(this) just to read & return the value 8971 return mSystemReady; 8972 } 8973 8974 private static File getCalledPreBootReceiversFile() { 8975 File dataDir = Environment.getDataDirectory(); 8976 File systemDir = new File(dataDir, "system"); 8977 File fname = new File(systemDir, "called_pre_boots.dat"); 8978 return fname; 8979 } 8980 8981 static final int LAST_DONE_VERSION = 10000; 8982 8983 private static ArrayList<ComponentName> readLastDonePreBootReceivers() { 8984 ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>(); 8985 File file = getCalledPreBootReceiversFile(); 8986 FileInputStream fis = null; 8987 try { 8988 fis = new FileInputStream(file); 8989 DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048)); 8990 int fvers = dis.readInt(); 8991 if (fvers == LAST_DONE_VERSION) { 8992 String vers = dis.readUTF(); 8993 String codename = dis.readUTF(); 8994 String build = dis.readUTF(); 8995 if (android.os.Build.VERSION.RELEASE.equals(vers) 8996 && android.os.Build.VERSION.CODENAME.equals(codename) 8997 && android.os.Build.VERSION.INCREMENTAL.equals(build)) { 8998 int num = dis.readInt(); 8999 while (num > 0) { 9000 num--; 9001 String pkg = dis.readUTF(); 9002 String cls = dis.readUTF(); 9003 lastDoneReceivers.add(new ComponentName(pkg, cls)); 9004 } 9005 } 9006 } 9007 } catch (FileNotFoundException e) { 9008 } catch (IOException e) { 9009 Slog.w(TAG, "Failure reading last done pre-boot receivers", e); 9010 } finally { 9011 if (fis != null) { 9012 try { 9013 fis.close(); 9014 } catch (IOException e) { 9015 } 9016 } 9017 } 9018 return lastDoneReceivers; 9019 } 9020 9021 private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) { 9022 File file = getCalledPreBootReceiversFile(); 9023 FileOutputStream fos = null; 9024 DataOutputStream dos = null; 9025 try { 9026 Slog.i(TAG, "Writing new set of last done pre-boot receivers..."); 9027 fos = new FileOutputStream(file); 9028 dos = new DataOutputStream(new BufferedOutputStream(fos, 2048)); 9029 dos.writeInt(LAST_DONE_VERSION); 9030 dos.writeUTF(android.os.Build.VERSION.RELEASE); 9031 dos.writeUTF(android.os.Build.VERSION.CODENAME); 9032 dos.writeUTF(android.os.Build.VERSION.INCREMENTAL); 9033 dos.writeInt(list.size()); 9034 for (int i=0; i<list.size(); i++) { 9035 dos.writeUTF(list.get(i).getPackageName()); 9036 dos.writeUTF(list.get(i).getClassName()); 9037 } 9038 } catch (IOException e) { 9039 Slog.w(TAG, "Failure writing last done pre-boot receivers", e); 9040 file.delete(); 9041 } finally { 9042 FileUtils.sync(fos); 9043 if (dos != null) { 9044 try { 9045 dos.close(); 9046 } catch (IOException e) { 9047 // TODO Auto-generated catch block 9048 e.printStackTrace(); 9049 } 9050 } 9051 } 9052 } 9053 9054 public void systemReady(final Runnable goingCallback) { 9055 synchronized(this) { 9056 if (mSystemReady) { 9057 if (goingCallback != null) goingCallback.run(); 9058 return; 9059 } 9060 9061 // Check to see if there are any update receivers to run. 9062 if (!mDidUpdate) { 9063 if (mWaitingUpdate) { 9064 return; 9065 } 9066 Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED); 9067 List<ResolveInfo> ris = null; 9068 try { 9069 ris = AppGlobals.getPackageManager().queryIntentReceivers( 9070 intent, null, 0, 0); 9071 } catch (RemoteException e) { 9072 } 9073 if (ris != null) { 9074 for (int i=ris.size()-1; i>=0; i--) { 9075 if ((ris.get(i).activityInfo.applicationInfo.flags 9076 &ApplicationInfo.FLAG_SYSTEM) == 0) { 9077 ris.remove(i); 9078 } 9079 } 9080 intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE); 9081 9082 ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers(); 9083 9084 final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>(); 9085 for (int i=0; i<ris.size(); i++) { 9086 ActivityInfo ai = ris.get(i).activityInfo; 9087 ComponentName comp = new ComponentName(ai.packageName, ai.name); 9088 if (lastDoneReceivers.contains(comp)) { 9089 // We already did the pre boot receiver for this app with the current 9090 // platform version, so don't do it again... 9091 ris.remove(i); 9092 i--; 9093 // ...however, do keep it as one that has been done, so we don't 9094 // forget about it when rewriting the file of last done receivers. 9095 doneReceivers.add(comp); 9096 } 9097 } 9098 9099 final int[] users = getUsersLocked(); 9100 for (int i=0; i<ris.size(); i++) { 9101 ActivityInfo ai = ris.get(i).activityInfo; 9102 ComponentName comp = new ComponentName(ai.packageName, ai.name); 9103 doneReceivers.add(comp); 9104 intent.setComponent(comp); 9105 for (int j=0; j<users.length; j++) { 9106 IIntentReceiver finisher = null; 9107 if (i == ris.size()-1 && j == users.length-1) { 9108 finisher = new IIntentReceiver.Stub() { 9109 public void performReceive(Intent intent, int resultCode, 9110 String data, Bundle extras, boolean ordered, 9111 boolean sticky, int sendingUser) { 9112 // The raw IIntentReceiver interface is called 9113 // with the AM lock held, so redispatch to 9114 // execute our code without the lock. 9115 mHandler.post(new Runnable() { 9116 public void run() { 9117 synchronized (ActivityManagerService.this) { 9118 mDidUpdate = true; 9119 } 9120 writeLastDonePreBootReceivers(doneReceivers); 9121 showBootMessage(mContext.getText( 9122 R.string.android_upgrading_complete), 9123 false); 9124 systemReady(goingCallback); 9125 } 9126 }); 9127 } 9128 }; 9129 } 9130 Slog.i(TAG, "Sending system update to " + intent.getComponent() 9131 + " for user " + users[j]); 9132 broadcastIntentLocked(null, null, intent, null, finisher, 9133 0, null, null, null, AppOpsManager.OP_NONE, 9134 true, false, MY_PID, Process.SYSTEM_UID, 9135 users[j]); 9136 if (finisher != null) { 9137 mWaitingUpdate = true; 9138 } 9139 } 9140 } 9141 } 9142 if (mWaitingUpdate) { 9143 return; 9144 } 9145 mDidUpdate = true; 9146 } 9147 9148 mAppOpsService.systemReady(); 9149 mSystemReady = true; 9150 } 9151 9152 ArrayList<ProcessRecord> procsToKill = null; 9153 synchronized(mPidsSelfLocked) { 9154 for (int i=mPidsSelfLocked.size()-1; i>=0; i--) { 9155 ProcessRecord proc = mPidsSelfLocked.valueAt(i); 9156 if (!isAllowedWhileBooting(proc.info)){ 9157 if (procsToKill == null) { 9158 procsToKill = new ArrayList<ProcessRecord>(); 9159 } 9160 procsToKill.add(proc); 9161 } 9162 } 9163 } 9164 9165 synchronized(this) { 9166 if (procsToKill != null) { 9167 for (int i=procsToKill.size()-1; i>=0; i--) { 9168 ProcessRecord proc = procsToKill.get(i); 9169 Slog.i(TAG, "Removing system update proc: " + proc); 9170 removeProcessLocked(proc, true, false, "system update done"); 9171 } 9172 } 9173 9174 // Now that we have cleaned up any update processes, we 9175 // are ready to start launching real processes and know that 9176 // we won't trample on them any more. 9177 mProcessesReady = true; 9178 } 9179 9180 Slog.i(TAG, "System now ready"); 9181 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY, 9182 SystemClock.uptimeMillis()); 9183 9184 synchronized(this) { 9185 // Make sure we have no pre-ready processes sitting around. 9186 9187 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) { 9188 ResolveInfo ri = mContext.getPackageManager() 9189 .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST), 9190 STOCK_PM_FLAGS); 9191 CharSequence errorMsg = null; 9192 if (ri != null) { 9193 ActivityInfo ai = ri.activityInfo; 9194 ApplicationInfo app = ai.applicationInfo; 9195 if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) { 9196 mTopAction = Intent.ACTION_FACTORY_TEST; 9197 mTopData = null; 9198 mTopComponent = new ComponentName(app.packageName, 9199 ai.name); 9200 } else { 9201 errorMsg = mContext.getResources().getText( 9202 com.android.internal.R.string.factorytest_not_system); 9203 } 9204 } else { 9205 errorMsg = mContext.getResources().getText( 9206 com.android.internal.R.string.factorytest_no_action); 9207 } 9208 if (errorMsg != null) { 9209 mTopAction = null; 9210 mTopData = null; 9211 mTopComponent = null; 9212 Message msg = Message.obtain(); 9213 msg.what = SHOW_FACTORY_ERROR_MSG; 9214 msg.getData().putCharSequence("msg", errorMsg); 9215 mHandler.sendMessage(msg); 9216 } 9217 } 9218 } 9219 9220 retrieveSettings(); 9221 9222 synchronized (this) { 9223 readGrantedUriPermissionsLocked(); 9224 } 9225 9226 if (goingCallback != null) goingCallback.run(); 9227 9228 synchronized (this) { 9229 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 9230 try { 9231 List apps = AppGlobals.getPackageManager(). 9232 getPersistentApplications(STOCK_PM_FLAGS); 9233 if (apps != null) { 9234 int N = apps.size(); 9235 int i; 9236 for (i=0; i<N; i++) { 9237 ApplicationInfo info 9238 = (ApplicationInfo)apps.get(i); 9239 if (info != null && 9240 !info.packageName.equals("android")) { 9241 addAppLocked(info, false); 9242 } 9243 } 9244 } 9245 } catch (RemoteException ex) { 9246 // pm is in same process, this will never happen. 9247 } 9248 } 9249 9250 // Start up initial activity. 9251 mBooting = true; 9252 9253 try { 9254 if (AppGlobals.getPackageManager().hasSystemUidErrors()) { 9255 Message msg = Message.obtain(); 9256 msg.what = SHOW_UID_ERROR_MSG; 9257 mHandler.sendMessage(msg); 9258 } 9259 } catch (RemoteException e) { 9260 } 9261 9262 long ident = Binder.clearCallingIdentity(); 9263 try { 9264 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 9265 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 9266 | Intent.FLAG_RECEIVER_FOREGROUND); 9267 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); 9268 broadcastIntentLocked(null, null, intent, 9269 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 9270 false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId); 9271 intent = new Intent(Intent.ACTION_USER_STARTING); 9272 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 9273 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); 9274 broadcastIntentLocked(null, null, intent, 9275 null, new IIntentReceiver.Stub() { 9276 @Override 9277 public void performReceive(Intent intent, int resultCode, String data, 9278 Bundle extras, boolean ordered, boolean sticky, int sendingUser) 9279 throws RemoteException { 9280 } 9281 }, 0, null, null, 9282 android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 9283 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 9284 } finally { 9285 Binder.restoreCallingIdentity(ident); 9286 } 9287 mStackSupervisor.resumeTopActivitiesLocked(); 9288 sendUserSwitchBroadcastsLocked(-1, mCurrentUserId); 9289 } 9290 } 9291 9292 private boolean makeAppCrashingLocked(ProcessRecord app, 9293 String shortMsg, String longMsg, String stackTrace) { 9294 app.crashing = true; 9295 app.crashingReport = generateProcessError(app, 9296 ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace); 9297 startAppProblemLocked(app); 9298 app.stopFreezingAllLocked(); 9299 return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace); 9300 } 9301 9302 private void makeAppNotRespondingLocked(ProcessRecord app, 9303 String activity, String shortMsg, String longMsg) { 9304 app.notResponding = true; 9305 app.notRespondingReport = generateProcessError(app, 9306 ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING, 9307 activity, shortMsg, longMsg, null); 9308 startAppProblemLocked(app); 9309 app.stopFreezingAllLocked(); 9310 } 9311 9312 /** 9313 * Generate a process error record, suitable for attachment to a ProcessRecord. 9314 * 9315 * @param app The ProcessRecord in which the error occurred. 9316 * @param condition Crashing, Application Not Responding, etc. Values are defined in 9317 * ActivityManager.AppErrorStateInfo 9318 * @param activity The activity associated with the crash, if known. 9319 * @param shortMsg Short message describing the crash. 9320 * @param longMsg Long message describing the crash. 9321 * @param stackTrace Full crash stack trace, may be null. 9322 * 9323 * @return Returns a fully-formed AppErrorStateInfo record. 9324 */ 9325 private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app, 9326 int condition, String activity, String shortMsg, String longMsg, String stackTrace) { 9327 ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo(); 9328 9329 report.condition = condition; 9330 report.processName = app.processName; 9331 report.pid = app.pid; 9332 report.uid = app.info.uid; 9333 report.tag = activity; 9334 report.shortMsg = shortMsg; 9335 report.longMsg = longMsg; 9336 report.stackTrace = stackTrace; 9337 9338 return report; 9339 } 9340 9341 void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) { 9342 synchronized (this) { 9343 app.crashing = false; 9344 app.crashingReport = null; 9345 app.notResponding = false; 9346 app.notRespondingReport = null; 9347 if (app.anrDialog == fromDialog) { 9348 app.anrDialog = null; 9349 } 9350 if (app.waitDialog == fromDialog) { 9351 app.waitDialog = null; 9352 } 9353 if (app.pid > 0 && app.pid != MY_PID) { 9354 handleAppCrashLocked(app, null, null, null); 9355 killUnneededProcessLocked(app, "user request after error"); 9356 } 9357 } 9358 } 9359 9360 private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg, 9361 String stackTrace) { 9362 long now = SystemClock.uptimeMillis(); 9363 9364 Long crashTime; 9365 if (!app.isolated) { 9366 crashTime = mProcessCrashTimes.get(app.info.processName, app.uid); 9367 } else { 9368 crashTime = null; 9369 } 9370 if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) { 9371 // This process loses! 9372 Slog.w(TAG, "Process " + app.info.processName 9373 + " has crashed too many times: killing!"); 9374 EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH, 9375 app.userId, app.info.processName, app.uid); 9376 mStackSupervisor.handleAppCrashLocked(app); 9377 if (!app.persistent) { 9378 // We don't want to start this process again until the user 9379 // explicitly does so... but for persistent process, we really 9380 // need to keep it running. If a persistent process is actually 9381 // repeatedly crashing, then badness for everyone. 9382 EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid, 9383 app.info.processName); 9384 if (!app.isolated) { 9385 // XXX We don't have a way to mark isolated processes 9386 // as bad, since they don't have a peristent identity. 9387 mBadProcesses.put(app.info.processName, app.uid, 9388 new BadProcessInfo(now, shortMsg, longMsg, stackTrace)); 9389 mProcessCrashTimes.remove(app.info.processName, app.uid); 9390 } 9391 app.bad = true; 9392 app.removed = true; 9393 // Don't let services in this process be restarted and potentially 9394 // annoy the user repeatedly. Unless it is persistent, since those 9395 // processes run critical code. 9396 removeProcessLocked(app, false, false, "crash"); 9397 mStackSupervisor.resumeTopActivitiesLocked(); 9398 return false; 9399 } 9400 mStackSupervisor.resumeTopActivitiesLocked(); 9401 } else { 9402 mStackSupervisor.finishTopRunningActivityLocked(app); 9403 } 9404 9405 // Bump up the crash count of any services currently running in the proc. 9406 for (int i=app.services.size()-1; i>=0; i--) { 9407 // Any services running in the application need to be placed 9408 // back in the pending list. 9409 ServiceRecord sr = app.services.valueAt(i); 9410 sr.crashCount++; 9411 } 9412 9413 // If the crashing process is what we consider to be the "home process" and it has been 9414 // replaced by a third-party app, clear the package preferred activities from packages 9415 // with a home activity running in the process to prevent a repeatedly crashing app 9416 // from blocking the user to manually clear the list. 9417 final ArrayList<ActivityRecord> activities = app.activities; 9418 if (app == mHomeProcess && activities.size() > 0 9419 && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) { 9420 for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) { 9421 final ActivityRecord r = activities.get(activityNdx); 9422 if (r.isHomeActivity()) { 9423 Log.i(TAG, "Clearing package preferred activities from " + r.packageName); 9424 try { 9425 ActivityThread.getPackageManager() 9426 .clearPackagePreferredActivities(r.packageName); 9427 } catch (RemoteException c) { 9428 // pm is in same process, this will never happen. 9429 } 9430 } 9431 } 9432 } 9433 9434 if (!app.isolated) { 9435 // XXX Can't keep track of crash times for isolated processes, 9436 // because they don't have a perisistent identity. 9437 mProcessCrashTimes.put(app.info.processName, app.uid, now); 9438 } 9439 9440 return true; 9441 } 9442 9443 void startAppProblemLocked(ProcessRecord app) { 9444 if (app.userId == mCurrentUserId) { 9445 app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver( 9446 mContext, app.info.packageName, app.info.flags); 9447 } else { 9448 // If this app is not running under the current user, then we 9449 // can't give it a report button because that would require 9450 // launching the report UI under a different user. 9451 app.errorReportReceiver = null; 9452 } 9453 skipCurrentReceiverLocked(app); 9454 } 9455 9456 void skipCurrentReceiverLocked(ProcessRecord app) { 9457 for (BroadcastQueue queue : mBroadcastQueues) { 9458 queue.skipCurrentReceiverLocked(app); 9459 } 9460 } 9461 9462 /** 9463 * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes. 9464 * The application process will exit immediately after this call returns. 9465 * @param app object of the crashing app, null for the system server 9466 * @param crashInfo describing the exception 9467 */ 9468 public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) { 9469 ProcessRecord r = findAppProcess(app, "Crash"); 9470 final String processName = app == null ? "system_server" 9471 : (r == null ? "unknown" : r.processName); 9472 9473 handleApplicationCrashInner("crash", r, processName, crashInfo); 9474 } 9475 9476 /* Native crash reporting uses this inner version because it needs to be somewhat 9477 * decoupled from the AM-managed cleanup lifecycle 9478 */ 9479 void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName, 9480 ApplicationErrorReport.CrashInfo crashInfo) { 9481 EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(), 9482 UserHandle.getUserId(Binder.getCallingUid()), processName, 9483 r == null ? -1 : r.info.flags, 9484 crashInfo.exceptionClassName, 9485 crashInfo.exceptionMessage, 9486 crashInfo.throwFileName, 9487 crashInfo.throwLineNumber); 9488 9489 addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo); 9490 9491 crashApplication(r, crashInfo); 9492 } 9493 9494 public void handleApplicationStrictModeViolation( 9495 IBinder app, 9496 int violationMask, 9497 StrictMode.ViolationInfo info) { 9498 ProcessRecord r = findAppProcess(app, "StrictMode"); 9499 if (r == null) { 9500 return; 9501 } 9502 9503 if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) { 9504 Integer stackFingerprint = info.hashCode(); 9505 boolean logIt = true; 9506 synchronized (mAlreadyLoggedViolatedStacks) { 9507 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) { 9508 logIt = false; 9509 // TODO: sub-sample into EventLog for these, with 9510 // the info.durationMillis? Then we'd get 9511 // the relative pain numbers, without logging all 9512 // the stack traces repeatedly. We'd want to do 9513 // likewise in the client code, which also does 9514 // dup suppression, before the Binder call. 9515 } else { 9516 if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) { 9517 mAlreadyLoggedViolatedStacks.clear(); 9518 } 9519 mAlreadyLoggedViolatedStacks.add(stackFingerprint); 9520 } 9521 } 9522 if (logIt) { 9523 logStrictModeViolationToDropBox(r, info); 9524 } 9525 } 9526 9527 if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) { 9528 AppErrorResult result = new AppErrorResult(); 9529 synchronized (this) { 9530 final long origId = Binder.clearCallingIdentity(); 9531 9532 Message msg = Message.obtain(); 9533 msg.what = SHOW_STRICT_MODE_VIOLATION_MSG; 9534 HashMap<String, Object> data = new HashMap<String, Object>(); 9535 data.put("result", result); 9536 data.put("app", r); 9537 data.put("violationMask", violationMask); 9538 data.put("info", info); 9539 msg.obj = data; 9540 mHandler.sendMessage(msg); 9541 9542 Binder.restoreCallingIdentity(origId); 9543 } 9544 int res = result.get(); 9545 Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res); 9546 } 9547 } 9548 9549 // Depending on the policy in effect, there could be a bunch of 9550 // these in quick succession so we try to batch these together to 9551 // minimize disk writes, number of dropbox entries, and maximize 9552 // compression, by having more fewer, larger records. 9553 private void logStrictModeViolationToDropBox( 9554 ProcessRecord process, 9555 StrictMode.ViolationInfo info) { 9556 if (info == null) { 9557 return; 9558 } 9559 final boolean isSystemApp = process == null || 9560 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM | 9561 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0; 9562 final String processName = process == null ? "unknown" : process.processName; 9563 final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode"; 9564 final DropBoxManager dbox = (DropBoxManager) 9565 mContext.getSystemService(Context.DROPBOX_SERVICE); 9566 9567 // Exit early if the dropbox isn't configured to accept this report type. 9568 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 9569 9570 boolean bufferWasEmpty; 9571 boolean needsFlush; 9572 final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024); 9573 synchronized (sb) { 9574 bufferWasEmpty = sb.length() == 0; 9575 appendDropBoxProcessHeaders(process, processName, sb); 9576 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 9577 sb.append("System-App: ").append(isSystemApp).append("\n"); 9578 sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n"); 9579 if (info.violationNumThisLoop != 0) { 9580 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n"); 9581 } 9582 if (info.numAnimationsRunning != 0) { 9583 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n"); 9584 } 9585 if (info.broadcastIntentAction != null) { 9586 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n"); 9587 } 9588 if (info.durationMillis != -1) { 9589 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n"); 9590 } 9591 if (info.numInstances != -1) { 9592 sb.append("Instance-Count: ").append(info.numInstances).append("\n"); 9593 } 9594 if (info.tags != null) { 9595 for (String tag : info.tags) { 9596 sb.append("Span-Tag: ").append(tag).append("\n"); 9597 } 9598 } 9599 sb.append("\n"); 9600 if (info.crashInfo != null && info.crashInfo.stackTrace != null) { 9601 sb.append(info.crashInfo.stackTrace); 9602 } 9603 sb.append("\n"); 9604 9605 // Only buffer up to ~64k. Various logging bits truncate 9606 // things at 128k. 9607 needsFlush = (sb.length() > 64 * 1024); 9608 } 9609 9610 // Flush immediately if the buffer's grown too large, or this 9611 // is a non-system app. Non-system apps are isolated with a 9612 // different tag & policy and not batched. 9613 // 9614 // Batching is useful during internal testing with 9615 // StrictMode settings turned up high. Without batching, 9616 // thousands of separate files could be created on boot. 9617 if (!isSystemApp || needsFlush) { 9618 new Thread("Error dump: " + dropboxTag) { 9619 @Override 9620 public void run() { 9621 String report; 9622 synchronized (sb) { 9623 report = sb.toString(); 9624 sb.delete(0, sb.length()); 9625 sb.trimToSize(); 9626 } 9627 if (report.length() != 0) { 9628 dbox.addText(dropboxTag, report); 9629 } 9630 } 9631 }.start(); 9632 return; 9633 } 9634 9635 // System app batching: 9636 if (!bufferWasEmpty) { 9637 // An existing dropbox-writing thread is outstanding, so 9638 // we don't need to start it up. The existing thread will 9639 // catch the buffer appends we just did. 9640 return; 9641 } 9642 9643 // Worker thread to both batch writes and to avoid blocking the caller on I/O. 9644 // (After this point, we shouldn't access AMS internal data structures.) 9645 new Thread("Error dump: " + dropboxTag) { 9646 @Override 9647 public void run() { 9648 // 5 second sleep to let stacks arrive and be batched together 9649 try { 9650 Thread.sleep(5000); // 5 seconds 9651 } catch (InterruptedException e) {} 9652 9653 String errorReport; 9654 synchronized (mStrictModeBuffer) { 9655 errorReport = mStrictModeBuffer.toString(); 9656 if (errorReport.length() == 0) { 9657 return; 9658 } 9659 mStrictModeBuffer.delete(0, mStrictModeBuffer.length()); 9660 mStrictModeBuffer.trimToSize(); 9661 } 9662 dbox.addText(dropboxTag, errorReport); 9663 } 9664 }.start(); 9665 } 9666 9667 /** 9668 * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors. 9669 * @param app object of the crashing app, null for the system server 9670 * @param tag reported by the caller 9671 * @param crashInfo describing the context of the error 9672 * @return true if the process should exit immediately (WTF is fatal) 9673 */ 9674 public boolean handleApplicationWtf(IBinder app, String tag, 9675 ApplicationErrorReport.CrashInfo crashInfo) { 9676 ProcessRecord r = findAppProcess(app, "WTF"); 9677 final String processName = app == null ? "system_server" 9678 : (r == null ? "unknown" : r.processName); 9679 9680 EventLog.writeEvent(EventLogTags.AM_WTF, 9681 UserHandle.getUserId(Binder.getCallingUid()), Binder.getCallingPid(), 9682 processName, 9683 r == null ? -1 : r.info.flags, 9684 tag, crashInfo.exceptionMessage); 9685 9686 addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo); 9687 9688 if (r != null && r.pid != Process.myPid() && 9689 Settings.Global.getInt(mContext.getContentResolver(), 9690 Settings.Global.WTF_IS_FATAL, 0) != 0) { 9691 crashApplication(r, crashInfo); 9692 return true; 9693 } else { 9694 return false; 9695 } 9696 } 9697 9698 /** 9699 * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit}) 9700 * @return the corresponding {@link ProcessRecord} object, or null if none could be found 9701 */ 9702 private ProcessRecord findAppProcess(IBinder app, String reason) { 9703 if (app == null) { 9704 return null; 9705 } 9706 9707 synchronized (this) { 9708 final int NP = mProcessNames.getMap().size(); 9709 for (int ip=0; ip<NP; ip++) { 9710 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 9711 final int NA = apps.size(); 9712 for (int ia=0; ia<NA; ia++) { 9713 ProcessRecord p = apps.valueAt(ia); 9714 if (p.thread != null && p.thread.asBinder() == app) { 9715 return p; 9716 } 9717 } 9718 } 9719 9720 Slog.w(TAG, "Can't find mystery application for " + reason 9721 + " from pid=" + Binder.getCallingPid() 9722 + " uid=" + Binder.getCallingUid() + ": " + app); 9723 return null; 9724 } 9725 } 9726 9727 /** 9728 * Utility function for addErrorToDropBox and handleStrictModeViolation's logging 9729 * to append various headers to the dropbox log text. 9730 */ 9731 private void appendDropBoxProcessHeaders(ProcessRecord process, String processName, 9732 StringBuilder sb) { 9733 // Watchdog thread ends up invoking this function (with 9734 // a null ProcessRecord) to add the stack file to dropbox. 9735 // Do not acquire a lock on this (am) in such cases, as it 9736 // could cause a potential deadlock, if and when watchdog 9737 // is invoked due to unavailability of lock on am and it 9738 // would prevent watchdog from killing system_server. 9739 if (process == null) { 9740 sb.append("Process: ").append(processName).append("\n"); 9741 return; 9742 } 9743 // Note: ProcessRecord 'process' is guarded by the service 9744 // instance. (notably process.pkgList, which could otherwise change 9745 // concurrently during execution of this method) 9746 synchronized (this) { 9747 sb.append("Process: ").append(processName).append("\n"); 9748 int flags = process.info.flags; 9749 IPackageManager pm = AppGlobals.getPackageManager(); 9750 sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n"); 9751 for (int ip=0; ip<process.pkgList.size(); ip++) { 9752 String pkg = process.pkgList.keyAt(ip); 9753 sb.append("Package: ").append(pkg); 9754 try { 9755 PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId()); 9756 if (pi != null) { 9757 sb.append(" v").append(pi.versionCode); 9758 if (pi.versionName != null) { 9759 sb.append(" (").append(pi.versionName).append(")"); 9760 } 9761 } 9762 } catch (RemoteException e) { 9763 Slog.e(TAG, "Error getting package info: " + pkg, e); 9764 } 9765 sb.append("\n"); 9766 } 9767 } 9768 } 9769 9770 private static String processClass(ProcessRecord process) { 9771 if (process == null || process.pid == MY_PID) { 9772 return "system_server"; 9773 } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) { 9774 return "system_app"; 9775 } else { 9776 return "data_app"; 9777 } 9778 } 9779 9780 /** 9781 * Write a description of an error (crash, WTF, ANR) to the drop box. 9782 * @param eventType to include in the drop box tag ("crash", "wtf", etc.) 9783 * @param process which caused the error, null means the system server 9784 * @param activity which triggered the error, null if unknown 9785 * @param parent activity related to the error, null if unknown 9786 * @param subject line related to the error, null if absent 9787 * @param report in long form describing the error, null if absent 9788 * @param logFile to include in the report, null if none 9789 * @param crashInfo giving an application stack trace, null if absent 9790 */ 9791 public void addErrorToDropBox(String eventType, 9792 ProcessRecord process, String processName, ActivityRecord activity, 9793 ActivityRecord parent, String subject, 9794 final String report, final File logFile, 9795 final ApplicationErrorReport.CrashInfo crashInfo) { 9796 // NOTE -- this must never acquire the ActivityManagerService lock, 9797 // otherwise the watchdog may be prevented from resetting the system. 9798 9799 final String dropboxTag = processClass(process) + "_" + eventType; 9800 final DropBoxManager dbox = (DropBoxManager) 9801 mContext.getSystemService(Context.DROPBOX_SERVICE); 9802 9803 // Exit early if the dropbox isn't configured to accept this report type. 9804 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 9805 9806 final StringBuilder sb = new StringBuilder(1024); 9807 appendDropBoxProcessHeaders(process, processName, sb); 9808 if (activity != null) { 9809 sb.append("Activity: ").append(activity.shortComponentName).append("\n"); 9810 } 9811 if (parent != null && parent.app != null && parent.app.pid != process.pid) { 9812 sb.append("Parent-Process: ").append(parent.app.processName).append("\n"); 9813 } 9814 if (parent != null && parent != activity) { 9815 sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n"); 9816 } 9817 if (subject != null) { 9818 sb.append("Subject: ").append(subject).append("\n"); 9819 } 9820 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 9821 if (Debug.isDebuggerConnected()) { 9822 sb.append("Debugger: Connected\n"); 9823 } 9824 sb.append("\n"); 9825 9826 // Do the rest in a worker thread to avoid blocking the caller on I/O 9827 // (After this point, we shouldn't access AMS internal data structures.) 9828 Thread worker = new Thread("Error dump: " + dropboxTag) { 9829 @Override 9830 public void run() { 9831 if (report != null) { 9832 sb.append(report); 9833 } 9834 if (logFile != null) { 9835 try { 9836 sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE, 9837 "\n\n[[TRUNCATED]]")); 9838 } catch (IOException e) { 9839 Slog.e(TAG, "Error reading " + logFile, e); 9840 } 9841 } 9842 if (crashInfo != null && crashInfo.stackTrace != null) { 9843 sb.append(crashInfo.stackTrace); 9844 } 9845 9846 String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag; 9847 int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0); 9848 if (lines > 0) { 9849 sb.append("\n"); 9850 9851 // Merge several logcat streams, and take the last N lines 9852 InputStreamReader input = null; 9853 try { 9854 java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat", 9855 "-v", "time", "-b", "events", "-b", "system", "-b", "main", 9856 "-t", String.valueOf(lines)).redirectErrorStream(true).start(); 9857 9858 try { logcat.getOutputStream().close(); } catch (IOException e) {} 9859 try { logcat.getErrorStream().close(); } catch (IOException e) {} 9860 input = new InputStreamReader(logcat.getInputStream()); 9861 9862 int num; 9863 char[] buf = new char[8192]; 9864 while ((num = input.read(buf)) > 0) sb.append(buf, 0, num); 9865 } catch (IOException e) { 9866 Slog.e(TAG, "Error running logcat", e); 9867 } finally { 9868 if (input != null) try { input.close(); } catch (IOException e) {} 9869 } 9870 } 9871 9872 dbox.addText(dropboxTag, sb.toString()); 9873 } 9874 }; 9875 9876 if (process == null) { 9877 // If process is null, we are being called from some internal code 9878 // and may be about to die -- run this synchronously. 9879 worker.run(); 9880 } else { 9881 worker.start(); 9882 } 9883 } 9884 9885 /** 9886 * Bring up the "unexpected error" dialog box for a crashing app. 9887 * Deal with edge cases (intercepts from instrumented applications, 9888 * ActivityController, error intent receivers, that sort of thing). 9889 * @param r the application crashing 9890 * @param crashInfo describing the failure 9891 */ 9892 private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) { 9893 long timeMillis = System.currentTimeMillis(); 9894 String shortMsg = crashInfo.exceptionClassName; 9895 String longMsg = crashInfo.exceptionMessage; 9896 String stackTrace = crashInfo.stackTrace; 9897 if (shortMsg != null && longMsg != null) { 9898 longMsg = shortMsg + ": " + longMsg; 9899 } else if (shortMsg != null) { 9900 longMsg = shortMsg; 9901 } 9902 9903 AppErrorResult result = new AppErrorResult(); 9904 synchronized (this) { 9905 if (mController != null) { 9906 try { 9907 String name = r != null ? r.processName : null; 9908 int pid = r != null ? r.pid : Binder.getCallingPid(); 9909 if (!mController.appCrashed(name, pid, 9910 shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) { 9911 Slog.w(TAG, "Force-killing crashed app " + name 9912 + " at watcher's request"); 9913 Process.killProcess(pid); 9914 return; 9915 } 9916 } catch (RemoteException e) { 9917 mController = null; 9918 Watchdog.getInstance().setActivityController(null); 9919 } 9920 } 9921 9922 final long origId = Binder.clearCallingIdentity(); 9923 9924 // If this process is running instrumentation, finish it. 9925 if (r != null && r.instrumentationClass != null) { 9926 Slog.w(TAG, "Error in app " + r.processName 9927 + " running instrumentation " + r.instrumentationClass + ":"); 9928 if (shortMsg != null) Slog.w(TAG, " " + shortMsg); 9929 if (longMsg != null) Slog.w(TAG, " " + longMsg); 9930 Bundle info = new Bundle(); 9931 info.putString("shortMsg", shortMsg); 9932 info.putString("longMsg", longMsg); 9933 finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info); 9934 Binder.restoreCallingIdentity(origId); 9935 return; 9936 } 9937 9938 // If we can't identify the process or it's already exceeded its crash quota, 9939 // quit right away without showing a crash dialog. 9940 if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) { 9941 Binder.restoreCallingIdentity(origId); 9942 return; 9943 } 9944 9945 Message msg = Message.obtain(); 9946 msg.what = SHOW_ERROR_MSG; 9947 HashMap data = new HashMap(); 9948 data.put("result", result); 9949 data.put("app", r); 9950 msg.obj = data; 9951 mHandler.sendMessage(msg); 9952 9953 Binder.restoreCallingIdentity(origId); 9954 } 9955 9956 int res = result.get(); 9957 9958 Intent appErrorIntent = null; 9959 synchronized (this) { 9960 if (r != null && !r.isolated) { 9961 // XXX Can't keep track of crash time for isolated processes, 9962 // since they don't have a persistent identity. 9963 mProcessCrashTimes.put(r.info.processName, r.uid, 9964 SystemClock.uptimeMillis()); 9965 } 9966 if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) { 9967 appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo); 9968 } 9969 } 9970 9971 if (appErrorIntent != null) { 9972 try { 9973 mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId)); 9974 } catch (ActivityNotFoundException e) { 9975 Slog.w(TAG, "bug report receiver dissappeared", e); 9976 } 9977 } 9978 } 9979 9980 Intent createAppErrorIntentLocked(ProcessRecord r, 9981 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 9982 ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo); 9983 if (report == null) { 9984 return null; 9985 } 9986 Intent result = new Intent(Intent.ACTION_APP_ERROR); 9987 result.setComponent(r.errorReportReceiver); 9988 result.putExtra(Intent.EXTRA_BUG_REPORT, report); 9989 result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 9990 return result; 9991 } 9992 9993 private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r, 9994 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 9995 if (r.errorReportReceiver == null) { 9996 return null; 9997 } 9998 9999 if (!r.crashing && !r.notResponding && !r.forceCrashReport) { 10000 return null; 10001 } 10002 10003 ApplicationErrorReport report = new ApplicationErrorReport(); 10004 report.packageName = r.info.packageName; 10005 report.installerPackageName = r.errorReportReceiver.getPackageName(); 10006 report.processName = r.processName; 10007 report.time = timeMillis; 10008 report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0; 10009 10010 if (r.crashing || r.forceCrashReport) { 10011 report.type = ApplicationErrorReport.TYPE_CRASH; 10012 report.crashInfo = crashInfo; 10013 } else if (r.notResponding) { 10014 report.type = ApplicationErrorReport.TYPE_ANR; 10015 report.anrInfo = new ApplicationErrorReport.AnrInfo(); 10016 10017 report.anrInfo.activity = r.notRespondingReport.tag; 10018 report.anrInfo.cause = r.notRespondingReport.shortMsg; 10019 report.anrInfo.info = r.notRespondingReport.longMsg; 10020 } 10021 10022 return report; 10023 } 10024 10025 public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() { 10026 enforceNotIsolatedCaller("getProcessesInErrorState"); 10027 // assume our apps are happy - lazy create the list 10028 List<ActivityManager.ProcessErrorStateInfo> errList = null; 10029 10030 final boolean allUsers = ActivityManager.checkUidPermission( 10031 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 10032 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 10033 int userId = UserHandle.getUserId(Binder.getCallingUid()); 10034 10035 synchronized (this) { 10036 10037 // iterate across all processes 10038 for (int i=mLruProcesses.size()-1; i>=0; i--) { 10039 ProcessRecord app = mLruProcesses.get(i); 10040 if (!allUsers && app.userId != userId) { 10041 continue; 10042 } 10043 if ((app.thread != null) && (app.crashing || app.notResponding)) { 10044 // This one's in trouble, so we'll generate a report for it 10045 // crashes are higher priority (in case there's a crash *and* an anr) 10046 ActivityManager.ProcessErrorStateInfo report = null; 10047 if (app.crashing) { 10048 report = app.crashingReport; 10049 } else if (app.notResponding) { 10050 report = app.notRespondingReport; 10051 } 10052 10053 if (report != null) { 10054 if (errList == null) { 10055 errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1); 10056 } 10057 errList.add(report); 10058 } else { 10059 Slog.w(TAG, "Missing app error report, app = " + app.processName + 10060 " crashing = " + app.crashing + 10061 " notResponding = " + app.notResponding); 10062 } 10063 } 10064 } 10065 } 10066 10067 return errList; 10068 } 10069 10070 static int oomAdjToImportance(int adj, ActivityManager.RunningAppProcessInfo currApp) { 10071 if (adj >= ProcessList.CACHED_APP_MIN_ADJ) { 10072 if (currApp != null) { 10073 currApp.lru = adj - ProcessList.CACHED_APP_MIN_ADJ + 1; 10074 } 10075 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 10076 } else if (adj >= ProcessList.SERVICE_B_ADJ) { 10077 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 10078 } else if (adj >= ProcessList.HOME_APP_ADJ) { 10079 if (currApp != null) { 10080 currApp.lru = 0; 10081 } 10082 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 10083 } else if (adj >= ProcessList.SERVICE_ADJ) { 10084 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 10085 } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 10086 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE; 10087 } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) { 10088 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE; 10089 } else if (adj >= ProcessList.VISIBLE_APP_ADJ) { 10090 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE; 10091 } else { 10092 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND; 10093 } 10094 } 10095 10096 private void fillInProcMemInfo(ProcessRecord app, 10097 ActivityManager.RunningAppProcessInfo outInfo) { 10098 outInfo.pid = app.pid; 10099 outInfo.uid = app.info.uid; 10100 if (mHeavyWeightProcess == app) { 10101 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE; 10102 } 10103 if (app.persistent) { 10104 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT; 10105 } 10106 if (app.activities.size() > 0) { 10107 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES; 10108 } 10109 outInfo.lastTrimLevel = app.trimMemoryLevel; 10110 int adj = app.curAdj; 10111 outInfo.importance = oomAdjToImportance(adj, outInfo); 10112 outInfo.importanceReasonCode = app.adjTypeCode; 10113 } 10114 10115 public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() { 10116 enforceNotIsolatedCaller("getRunningAppProcesses"); 10117 // Lazy instantiation of list 10118 List<ActivityManager.RunningAppProcessInfo> runList = null; 10119 final boolean allUsers = ActivityManager.checkUidPermission( 10120 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 10121 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 10122 int userId = UserHandle.getUserId(Binder.getCallingUid()); 10123 synchronized (this) { 10124 // Iterate across all processes 10125 for (int i=mLruProcesses.size()-1; i>=0; i--) { 10126 ProcessRecord app = mLruProcesses.get(i); 10127 if (!allUsers && app.userId != userId) { 10128 continue; 10129 } 10130 if ((app.thread != null) && (!app.crashing && !app.notResponding)) { 10131 // Generate process state info for running application 10132 ActivityManager.RunningAppProcessInfo currApp = 10133 new ActivityManager.RunningAppProcessInfo(app.processName, 10134 app.pid, app.getPackageList()); 10135 fillInProcMemInfo(app, currApp); 10136 if (app.adjSource instanceof ProcessRecord) { 10137 currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid; 10138 currApp.importanceReasonImportance = oomAdjToImportance( 10139 app.adjSourceOom, null); 10140 } else if (app.adjSource instanceof ActivityRecord) { 10141 ActivityRecord r = (ActivityRecord)app.adjSource; 10142 if (r.app != null) currApp.importanceReasonPid = r.app.pid; 10143 } 10144 if (app.adjTarget instanceof ComponentName) { 10145 currApp.importanceReasonComponent = (ComponentName)app.adjTarget; 10146 } 10147 //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance 10148 // + " lru=" + currApp.lru); 10149 if (runList == null) { 10150 runList = new ArrayList<ActivityManager.RunningAppProcessInfo>(); 10151 } 10152 runList.add(currApp); 10153 } 10154 } 10155 } 10156 return runList; 10157 } 10158 10159 public List<ApplicationInfo> getRunningExternalApplications() { 10160 enforceNotIsolatedCaller("getRunningExternalApplications"); 10161 List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses(); 10162 List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>(); 10163 if (runningApps != null && runningApps.size() > 0) { 10164 Set<String> extList = new HashSet<String>(); 10165 for (ActivityManager.RunningAppProcessInfo app : runningApps) { 10166 if (app.pkgList != null) { 10167 for (String pkg : app.pkgList) { 10168 extList.add(pkg); 10169 } 10170 } 10171 } 10172 IPackageManager pm = AppGlobals.getPackageManager(); 10173 for (String pkg : extList) { 10174 try { 10175 ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId()); 10176 if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) { 10177 retList.add(info); 10178 } 10179 } catch (RemoteException e) { 10180 } 10181 } 10182 } 10183 return retList; 10184 } 10185 10186 @Override 10187 public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) { 10188 enforceNotIsolatedCaller("getMyMemoryState"); 10189 synchronized (this) { 10190 ProcessRecord proc; 10191 synchronized (mPidsSelfLocked) { 10192 proc = mPidsSelfLocked.get(Binder.getCallingPid()); 10193 } 10194 fillInProcMemInfo(proc, outInfo); 10195 } 10196 } 10197 10198 @Override 10199 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 10200 if (checkCallingPermission(android.Manifest.permission.DUMP) 10201 != PackageManager.PERMISSION_GRANTED) { 10202 pw.println("Permission Denial: can't dump ActivityManager from from pid=" 10203 + Binder.getCallingPid() 10204 + ", uid=" + Binder.getCallingUid() 10205 + " without permission " 10206 + android.Manifest.permission.DUMP); 10207 return; 10208 } 10209 10210 boolean dumpAll = false; 10211 boolean dumpClient = false; 10212 String dumpPackage = null; 10213 10214 int opti = 0; 10215 while (opti < args.length) { 10216 String opt = args[opti]; 10217 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 10218 break; 10219 } 10220 opti++; 10221 if ("-a".equals(opt)) { 10222 dumpAll = true; 10223 } else if ("-c".equals(opt)) { 10224 dumpClient = true; 10225 } else if ("-h".equals(opt)) { 10226 pw.println("Activity manager dump options:"); 10227 pw.println(" [-a] [-c] [-h] [cmd] ..."); 10228 pw.println(" cmd may be one of:"); 10229 pw.println(" a[ctivities]: activity stack state"); 10230 pw.println(" b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state"); 10231 pw.println(" i[ntents] [PACKAGE_NAME]: pending intent state"); 10232 pw.println(" p[rocesses] [PACKAGE_NAME]: process state"); 10233 pw.println(" o[om]: out of memory management"); 10234 pw.println(" prov[iders] [COMP_SPEC ...]: content provider state"); 10235 pw.println(" provider [COMP_SPEC]: provider client-side state"); 10236 pw.println(" s[ervices] [COMP_SPEC ...]: service state"); 10237 pw.println(" service [COMP_SPEC]: service client-side state"); 10238 pw.println(" package [PACKAGE_NAME]: all state related to given package"); 10239 pw.println(" all: dump all activities"); 10240 pw.println(" top: dump the top activity"); 10241 pw.println(" cmd may also be a COMP_SPEC to dump activities."); 10242 pw.println(" COMP_SPEC may be a component name (com.foo/.myApp),"); 10243 pw.println(" a partial substring in a component name, a"); 10244 pw.println(" hex object identifier."); 10245 pw.println(" -a: include all available server state."); 10246 pw.println(" -c: include client state."); 10247 return; 10248 } else { 10249 pw.println("Unknown argument: " + opt + "; use -h for help"); 10250 } 10251 } 10252 10253 long origId = Binder.clearCallingIdentity(); 10254 boolean more = false; 10255 // Is the caller requesting to dump a particular piece of data? 10256 if (opti < args.length) { 10257 String cmd = args[opti]; 10258 opti++; 10259 if ("activities".equals(cmd) || "a".equals(cmd)) { 10260 synchronized (this) { 10261 dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null); 10262 } 10263 } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) { 10264 String[] newArgs; 10265 String name; 10266 if (opti >= args.length) { 10267 name = null; 10268 newArgs = EMPTY_STRING_ARRAY; 10269 } else { 10270 name = args[opti]; 10271 opti++; 10272 newArgs = new String[args.length - opti]; 10273 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 10274 args.length - opti); 10275 } 10276 synchronized (this) { 10277 dumpBroadcastsLocked(fd, pw, args, opti, true, name); 10278 } 10279 } else if ("intents".equals(cmd) || "i".equals(cmd)) { 10280 String[] newArgs; 10281 String name; 10282 if (opti >= args.length) { 10283 name = null; 10284 newArgs = EMPTY_STRING_ARRAY; 10285 } else { 10286 name = args[opti]; 10287 opti++; 10288 newArgs = new String[args.length - opti]; 10289 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 10290 args.length - opti); 10291 } 10292 synchronized (this) { 10293 dumpPendingIntentsLocked(fd, pw, args, opti, true, name); 10294 } 10295 } else if ("processes".equals(cmd) || "p".equals(cmd)) { 10296 String[] newArgs; 10297 String name; 10298 if (opti >= args.length) { 10299 name = null; 10300 newArgs = EMPTY_STRING_ARRAY; 10301 } else { 10302 name = args[opti]; 10303 opti++; 10304 newArgs = new String[args.length - opti]; 10305 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 10306 args.length - opti); 10307 } 10308 synchronized (this) { 10309 dumpProcessesLocked(fd, pw, args, opti, true, name); 10310 } 10311 } else if ("oom".equals(cmd) || "o".equals(cmd)) { 10312 synchronized (this) { 10313 dumpOomLocked(fd, pw, args, opti, true); 10314 } 10315 } else if ("provider".equals(cmd)) { 10316 String[] newArgs; 10317 String name; 10318 if (opti >= args.length) { 10319 name = null; 10320 newArgs = EMPTY_STRING_ARRAY; 10321 } else { 10322 name = args[opti]; 10323 opti++; 10324 newArgs = new String[args.length - opti]; 10325 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti); 10326 } 10327 if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) { 10328 pw.println("No providers match: " + name); 10329 pw.println("Use -h for help."); 10330 } 10331 } else if ("providers".equals(cmd) || "prov".equals(cmd)) { 10332 synchronized (this) { 10333 dumpProvidersLocked(fd, pw, args, opti, true, null); 10334 } 10335 } else if ("service".equals(cmd)) { 10336 String[] newArgs; 10337 String name; 10338 if (opti >= args.length) { 10339 name = null; 10340 newArgs = EMPTY_STRING_ARRAY; 10341 } else { 10342 name = args[opti]; 10343 opti++; 10344 newArgs = new String[args.length - opti]; 10345 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 10346 args.length - opti); 10347 } 10348 if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) { 10349 pw.println("No services match: " + name); 10350 pw.println("Use -h for help."); 10351 } 10352 } else if ("package".equals(cmd)) { 10353 String[] newArgs; 10354 if (opti >= args.length) { 10355 pw.println("package: no package name specified"); 10356 pw.println("Use -h for help."); 10357 } else { 10358 dumpPackage = args[opti]; 10359 opti++; 10360 newArgs = new String[args.length - opti]; 10361 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 10362 args.length - opti); 10363 args = newArgs; 10364 opti = 0; 10365 more = true; 10366 } 10367 } else if ("services".equals(cmd) || "s".equals(cmd)) { 10368 synchronized (this) { 10369 mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null); 10370 } 10371 } else { 10372 // Dumping a single activity? 10373 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) { 10374 pw.println("Bad activity command, or no activities match: " + cmd); 10375 pw.println("Use -h for help."); 10376 } 10377 } 10378 if (!more) { 10379 Binder.restoreCallingIdentity(origId); 10380 return; 10381 } 10382 } 10383 10384 // No piece of data specified, dump everything. 10385 synchronized (this) { 10386 dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 10387 pw.println(); 10388 if (dumpAll) { 10389 pw.println("-------------------------------------------------------------------------------"); 10390 } 10391 dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 10392 pw.println(); 10393 if (dumpAll) { 10394 pw.println("-------------------------------------------------------------------------------"); 10395 } 10396 dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage); 10397 pw.println(); 10398 if (dumpAll) { 10399 pw.println("-------------------------------------------------------------------------------"); 10400 } 10401 mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 10402 pw.println(); 10403 if (dumpAll) { 10404 pw.println("-------------------------------------------------------------------------------"); 10405 } 10406 dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 10407 pw.println(); 10408 if (dumpAll) { 10409 pw.println("-------------------------------------------------------------------------------"); 10410 } 10411 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage); 10412 } 10413 Binder.restoreCallingIdentity(origId); 10414 } 10415 10416 void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 10417 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) { 10418 pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)"); 10419 10420 boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient, 10421 dumpPackage); 10422 boolean needSep = printedAnything; 10423 10424 boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity, 10425 dumpPackage, needSep, " mFocusedActivity: "); 10426 if (printed) { 10427 printedAnything = true; 10428 needSep = false; 10429 } 10430 10431 if (dumpPackage == null) { 10432 if (needSep) { 10433 pw.println(); 10434 } 10435 needSep = true; 10436 printedAnything = true; 10437 mStackSupervisor.dump(pw, " "); 10438 } 10439 10440 if (mRecentTasks.size() > 0) { 10441 boolean printedHeader = false; 10442 10443 final int N = mRecentTasks.size(); 10444 for (int i=0; i<N; i++) { 10445 TaskRecord tr = mRecentTasks.get(i); 10446 if (dumpPackage != null) { 10447 if (tr.realActivity == null || 10448 !dumpPackage.equals(tr.realActivity)) { 10449 continue; 10450 } 10451 } 10452 if (!printedHeader) { 10453 if (needSep) { 10454 pw.println(); 10455 } 10456 pw.println(" Recent tasks:"); 10457 printedHeader = true; 10458 printedAnything = true; 10459 } 10460 pw.print(" * Recent #"); pw.print(i); pw.print(": "); 10461 pw.println(tr); 10462 if (dumpAll) { 10463 mRecentTasks.get(i).dump(pw, " "); 10464 } 10465 } 10466 } 10467 10468 if (!printedAnything) { 10469 pw.println(" (nothing)"); 10470 } 10471 } 10472 10473 void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 10474 int opti, boolean dumpAll, String dumpPackage) { 10475 boolean needSep = false; 10476 boolean printedAnything = false; 10477 int numPers = 0; 10478 10479 pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)"); 10480 10481 if (dumpAll) { 10482 final int NP = mProcessNames.getMap().size(); 10483 for (int ip=0; ip<NP; ip++) { 10484 SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip); 10485 final int NA = procs.size(); 10486 for (int ia=0; ia<NA; ia++) { 10487 ProcessRecord r = procs.valueAt(ia); 10488 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 10489 continue; 10490 } 10491 if (!needSep) { 10492 pw.println(" All known processes:"); 10493 needSep = true; 10494 printedAnything = true; 10495 } 10496 pw.print(r.persistent ? " *PERS*" : " *APP*"); 10497 pw.print(" UID "); pw.print(procs.keyAt(ia)); 10498 pw.print(" "); pw.println(r); 10499 r.dump(pw, " "); 10500 if (r.persistent) { 10501 numPers++; 10502 } 10503 } 10504 } 10505 } 10506 10507 if (mIsolatedProcesses.size() > 0) { 10508 boolean printed = false; 10509 for (int i=0; i<mIsolatedProcesses.size(); i++) { 10510 ProcessRecord r = mIsolatedProcesses.valueAt(i); 10511 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 10512 continue; 10513 } 10514 if (!printed) { 10515 if (needSep) { 10516 pw.println(); 10517 } 10518 pw.println(" Isolated process list (sorted by uid):"); 10519 printedAnything = true; 10520 printed = true; 10521 needSep = true; 10522 } 10523 pw.println(String.format("%sIsolated #%2d: %s", 10524 " ", i, r.toString())); 10525 } 10526 } 10527 10528 if (mLruProcesses.size() > 0) { 10529 if (needSep) { 10530 pw.println(); 10531 } 10532 pw.print(" Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size()); 10533 pw.print(" total, non-act at "); 10534 pw.print(mLruProcesses.size()-mLruProcessActivityStart); 10535 pw.print(", non-svc at "); 10536 pw.print(mLruProcesses.size()-mLruProcessServiceStart); 10537 pw.println("):"); 10538 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", false, dumpPackage); 10539 needSep = true; 10540 printedAnything = true; 10541 } 10542 10543 if (dumpAll || dumpPackage != null) { 10544 synchronized (mPidsSelfLocked) { 10545 boolean printed = false; 10546 for (int i=0; i<mPidsSelfLocked.size(); i++) { 10547 ProcessRecord r = mPidsSelfLocked.valueAt(i); 10548 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 10549 continue; 10550 } 10551 if (!printed) { 10552 if (needSep) pw.println(); 10553 needSep = true; 10554 pw.println(" PID mappings:"); 10555 printed = true; 10556 printedAnything = true; 10557 } 10558 pw.print(" PID #"); pw.print(mPidsSelfLocked.keyAt(i)); 10559 pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i)); 10560 } 10561 } 10562 } 10563 10564 if (mForegroundProcesses.size() > 0) { 10565 synchronized (mPidsSelfLocked) { 10566 boolean printed = false; 10567 for (int i=0; i<mForegroundProcesses.size(); i++) { 10568 ProcessRecord r = mPidsSelfLocked.get( 10569 mForegroundProcesses.valueAt(i).pid); 10570 if (dumpPackage != null && (r == null 10571 || !r.pkgList.containsKey(dumpPackage))) { 10572 continue; 10573 } 10574 if (!printed) { 10575 if (needSep) pw.println(); 10576 needSep = true; 10577 pw.println(" Foreground Processes:"); 10578 printed = true; 10579 printedAnything = true; 10580 } 10581 pw.print(" PID #"); pw.print(mForegroundProcesses.keyAt(i)); 10582 pw.print(": "); pw.println(mForegroundProcesses.valueAt(i)); 10583 } 10584 } 10585 } 10586 10587 if (mPersistentStartingProcesses.size() > 0) { 10588 if (needSep) pw.println(); 10589 needSep = true; 10590 printedAnything = true; 10591 pw.println(" Persisent processes that are starting:"); 10592 dumpProcessList(pw, this, mPersistentStartingProcesses, " ", 10593 "Starting Norm", "Restarting PERS", dumpPackage); 10594 } 10595 10596 if (mRemovedProcesses.size() > 0) { 10597 if (needSep) pw.println(); 10598 needSep = true; 10599 printedAnything = true; 10600 pw.println(" Processes that are being removed:"); 10601 dumpProcessList(pw, this, mRemovedProcesses, " ", 10602 "Removed Norm", "Removed PERS", dumpPackage); 10603 } 10604 10605 if (mProcessesOnHold.size() > 0) { 10606 if (needSep) pw.println(); 10607 needSep = true; 10608 printedAnything = true; 10609 pw.println(" Processes that are on old until the system is ready:"); 10610 dumpProcessList(pw, this, mProcessesOnHold, " ", 10611 "OnHold Norm", "OnHold PERS", dumpPackage); 10612 } 10613 10614 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage); 10615 10616 if (mProcessCrashTimes.getMap().size() > 0) { 10617 boolean printed = false; 10618 long now = SystemClock.uptimeMillis(); 10619 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap(); 10620 final int NP = pmap.size(); 10621 for (int ip=0; ip<NP; ip++) { 10622 String pname = pmap.keyAt(ip); 10623 SparseArray<Long> uids = pmap.valueAt(ip); 10624 final int N = uids.size(); 10625 for (int i=0; i<N; i++) { 10626 int puid = uids.keyAt(i); 10627 ProcessRecord r = mProcessNames.get(pname, puid); 10628 if (dumpPackage != null && (r == null 10629 || !r.pkgList.containsKey(dumpPackage))) { 10630 continue; 10631 } 10632 if (!printed) { 10633 if (needSep) pw.println(); 10634 needSep = true; 10635 pw.println(" Time since processes crashed:"); 10636 printed = true; 10637 printedAnything = true; 10638 } 10639 pw.print(" Process "); pw.print(pname); 10640 pw.print(" uid "); pw.print(puid); 10641 pw.print(": last crashed "); 10642 TimeUtils.formatDuration(now-uids.valueAt(i), pw); 10643 pw.println(" ago"); 10644 } 10645 } 10646 } 10647 10648 if (mBadProcesses.getMap().size() > 0) { 10649 boolean printed = false; 10650 final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap(); 10651 final int NP = pmap.size(); 10652 for (int ip=0; ip<NP; ip++) { 10653 String pname = pmap.keyAt(ip); 10654 SparseArray<BadProcessInfo> uids = pmap.valueAt(ip); 10655 final int N = uids.size(); 10656 for (int i=0; i<N; i++) { 10657 int puid = uids.keyAt(i); 10658 ProcessRecord r = mProcessNames.get(pname, puid); 10659 if (dumpPackage != null && (r == null 10660 || !r.pkgList.containsKey(dumpPackage))) { 10661 continue; 10662 } 10663 if (!printed) { 10664 if (needSep) pw.println(); 10665 needSep = true; 10666 pw.println(" Bad processes:"); 10667 printedAnything = true; 10668 } 10669 BadProcessInfo info = uids.valueAt(i); 10670 pw.print(" Bad process "); pw.print(pname); 10671 pw.print(" uid "); pw.print(puid); 10672 pw.print(": crashed at time "); pw.println(info.time); 10673 if (info.shortMsg != null) { 10674 pw.print(" Short msg: "); pw.println(info.shortMsg); 10675 } 10676 if (info.longMsg != null) { 10677 pw.print(" Long msg: "); pw.println(info.longMsg); 10678 } 10679 if (info.stack != null) { 10680 pw.println(" Stack:"); 10681 int lastPos = 0; 10682 for (int pos=0; pos<info.stack.length(); pos++) { 10683 if (info.stack.charAt(pos) == '\n') { 10684 pw.print(" "); 10685 pw.write(info.stack, lastPos, pos-lastPos); 10686 pw.println(); 10687 lastPos = pos+1; 10688 } 10689 } 10690 if (lastPos < info.stack.length()) { 10691 pw.print(" "); 10692 pw.write(info.stack, lastPos, info.stack.length()-lastPos); 10693 pw.println(); 10694 } 10695 } 10696 } 10697 } 10698 } 10699 10700 if (dumpPackage == null) { 10701 pw.println(); 10702 needSep = false; 10703 pw.println(" mStartedUsers:"); 10704 for (int i=0; i<mStartedUsers.size(); i++) { 10705 UserStartedState uss = mStartedUsers.valueAt(i); 10706 pw.print(" User #"); pw.print(uss.mHandle.getIdentifier()); 10707 pw.print(": "); uss.dump("", pw); 10708 } 10709 pw.print(" mStartedUserArray: ["); 10710 for (int i=0; i<mStartedUserArray.length; i++) { 10711 if (i > 0) pw.print(", "); 10712 pw.print(mStartedUserArray[i]); 10713 } 10714 pw.println("]"); 10715 pw.print(" mUserLru: ["); 10716 for (int i=0; i<mUserLru.size(); i++) { 10717 if (i > 0) pw.print(", "); 10718 pw.print(mUserLru.get(i)); 10719 } 10720 pw.println("]"); 10721 if (dumpAll) { 10722 pw.print(" mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray)); 10723 } 10724 } 10725 if (mHomeProcess != null && (dumpPackage == null 10726 || mHomeProcess.pkgList.containsKey(dumpPackage))) { 10727 if (needSep) { 10728 pw.println(); 10729 needSep = false; 10730 } 10731 pw.println(" mHomeProcess: " + mHomeProcess); 10732 } 10733 if (mPreviousProcess != null && (dumpPackage == null 10734 || mPreviousProcess.pkgList.containsKey(dumpPackage))) { 10735 if (needSep) { 10736 pw.println(); 10737 needSep = false; 10738 } 10739 pw.println(" mPreviousProcess: " + mPreviousProcess); 10740 } 10741 if (dumpAll) { 10742 StringBuilder sb = new StringBuilder(128); 10743 sb.append(" mPreviousProcessVisibleTime: "); 10744 TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb); 10745 pw.println(sb); 10746 } 10747 if (mHeavyWeightProcess != null && (dumpPackage == null 10748 || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) { 10749 if (needSep) { 10750 pw.println(); 10751 needSep = false; 10752 } 10753 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 10754 } 10755 if (dumpPackage == null) { 10756 pw.println(" mConfiguration: " + mConfiguration); 10757 } 10758 if (dumpAll) { 10759 pw.println(" mConfigWillChange: " + getFocusedStack().mConfigWillChange); 10760 if (mCompatModePackages.getPackages().size() > 0) { 10761 boolean printed = false; 10762 for (Map.Entry<String, Integer> entry 10763 : mCompatModePackages.getPackages().entrySet()) { 10764 String pkg = entry.getKey(); 10765 int mode = entry.getValue(); 10766 if (dumpPackage != null && !dumpPackage.equals(pkg)) { 10767 continue; 10768 } 10769 if (!printed) { 10770 pw.println(" mScreenCompatPackages:"); 10771 printed = true; 10772 } 10773 pw.print(" "); pw.print(pkg); pw.print(": "); 10774 pw.print(mode); pw.println(); 10775 } 10776 } 10777 } 10778 if (dumpPackage == null) { 10779 if (mSleeping || mWentToSleep || mLockScreenShown) { 10780 pw.println(" mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep 10781 + " mLockScreenShown " + mLockScreenShown); 10782 } 10783 if (mShuttingDown) { 10784 pw.println(" mShuttingDown=" + mShuttingDown); 10785 } 10786 } 10787 if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient 10788 || mOrigWaitForDebugger) { 10789 if (dumpPackage == null || dumpPackage.equals(mDebugApp) 10790 || dumpPackage.equals(mOrigDebugApp)) { 10791 if (needSep) { 10792 pw.println(); 10793 needSep = false; 10794 } 10795 pw.println(" mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp 10796 + " mDebugTransient=" + mDebugTransient 10797 + " mOrigWaitForDebugger=" + mOrigWaitForDebugger); 10798 } 10799 } 10800 if (mOpenGlTraceApp != null) { 10801 if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) { 10802 if (needSep) { 10803 pw.println(); 10804 needSep = false; 10805 } 10806 pw.println(" mOpenGlTraceApp=" + mOpenGlTraceApp); 10807 } 10808 } 10809 if (mProfileApp != null || mProfileProc != null || mProfileFile != null 10810 || mProfileFd != null) { 10811 if (dumpPackage == null || dumpPackage.equals(mProfileApp)) { 10812 if (needSep) { 10813 pw.println(); 10814 needSep = false; 10815 } 10816 pw.println(" mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc); 10817 pw.println(" mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd); 10818 pw.println(" mProfileType=" + mProfileType + " mAutoStopProfiler=" 10819 + mAutoStopProfiler); 10820 } 10821 } 10822 if (dumpPackage == null) { 10823 if (mAlwaysFinishActivities || mController != null) { 10824 pw.println(" mAlwaysFinishActivities=" + mAlwaysFinishActivities 10825 + " mController=" + mController); 10826 } 10827 if (dumpAll) { 10828 pw.println(" Total persistent processes: " + numPers); 10829 pw.println(" mProcessesReady=" + mProcessesReady 10830 + " mSystemReady=" + mSystemReady); 10831 pw.println(" mBooting=" + mBooting 10832 + " mBooted=" + mBooted 10833 + " mFactoryTest=" + mFactoryTest); 10834 pw.print(" mLastPowerCheckRealtime="); 10835 TimeUtils.formatDuration(mLastPowerCheckRealtime, pw); 10836 pw.println(""); 10837 pw.print(" mLastPowerCheckUptime="); 10838 TimeUtils.formatDuration(mLastPowerCheckUptime, pw); 10839 pw.println(""); 10840 pw.println(" mGoingToSleep=" + mStackSupervisor.mGoingToSleep); 10841 pw.println(" mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity); 10842 pw.println(" mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq); 10843 pw.println(" mNumNonCachedProcs=" + mNumNonCachedProcs 10844 + " (" + mLruProcesses.size() + " total)" 10845 + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs 10846 + " mNumServiceProcs=" + mNumServiceProcs 10847 + " mNewNumServiceProcs=" + mNewNumServiceProcs); 10848 pw.println(" mAllowLowerMemLevel=" + mAllowLowerMemLevel 10849 + " mLastMemoryLevel" + mLastMemoryLevel 10850 + " mLastNumProcesses" + mLastNumProcesses); 10851 long now = SystemClock.uptimeMillis(); 10852 pw.print(" mLastIdleTime="); 10853 TimeUtils.formatDuration(now, mLastIdleTime, pw); 10854 pw.print(" mLowRamSinceLastIdle="); 10855 TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw); 10856 pw.println(); 10857 } 10858 } 10859 10860 if (!printedAnything) { 10861 pw.println(" (nothing)"); 10862 } 10863 } 10864 10865 boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args, 10866 int opti, boolean needSep, boolean dumpAll, String dumpPackage) { 10867 if (mProcessesToGc.size() > 0) { 10868 boolean printed = false; 10869 long now = SystemClock.uptimeMillis(); 10870 for (int i=0; i<mProcessesToGc.size(); i++) { 10871 ProcessRecord proc = mProcessesToGc.get(i); 10872 if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) { 10873 continue; 10874 } 10875 if (!printed) { 10876 if (needSep) pw.println(); 10877 needSep = true; 10878 pw.println(" Processes that are waiting to GC:"); 10879 printed = true; 10880 } 10881 pw.print(" Process "); pw.println(proc); 10882 pw.print(" lowMem="); pw.print(proc.reportLowMemory); 10883 pw.print(", last gced="); 10884 pw.print(now-proc.lastRequestedGc); 10885 pw.print(" ms ago, last lowMem="); 10886 pw.print(now-proc.lastLowMemory); 10887 pw.println(" ms ago"); 10888 10889 } 10890 } 10891 return needSep; 10892 } 10893 10894 void printOomLevel(PrintWriter pw, String name, int adj) { 10895 pw.print(" "); 10896 if (adj >= 0) { 10897 pw.print(' '); 10898 if (adj < 10) pw.print(' '); 10899 } else { 10900 if (adj > -10) pw.print(' '); 10901 } 10902 pw.print(adj); 10903 pw.print(": "); 10904 pw.print(name); 10905 pw.print(" ("); 10906 pw.print(mProcessList.getMemLevel(adj)/1024); 10907 pw.println(" kB)"); 10908 } 10909 10910 boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args, 10911 int opti, boolean dumpAll) { 10912 boolean needSep = false; 10913 10914 if (mLruProcesses.size() > 0) { 10915 if (needSep) pw.println(); 10916 needSep = true; 10917 pw.println(" OOM levels:"); 10918 printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ); 10919 printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ); 10920 printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ); 10921 printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ); 10922 printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ); 10923 printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ); 10924 printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ); 10925 printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ); 10926 printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ); 10927 printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ); 10928 printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ); 10929 printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ); 10930 printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ); 10931 10932 if (needSep) pw.println(); 10933 pw.print(" Process OOM control ("); pw.print(mLruProcesses.size()); 10934 pw.print(" total, non-act at "); 10935 pw.print(mLruProcesses.size()-mLruProcessActivityStart); 10936 pw.print(", non-svc at "); 10937 pw.print(mLruProcesses.size()-mLruProcessServiceStart); 10938 pw.println("):"); 10939 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", true, null); 10940 needSep = true; 10941 } 10942 10943 dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null); 10944 10945 pw.println(); 10946 pw.println(" mHomeProcess: " + mHomeProcess); 10947 pw.println(" mPreviousProcess: " + mPreviousProcess); 10948 if (mHeavyWeightProcess != null) { 10949 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 10950 } 10951 10952 return true; 10953 } 10954 10955 /** 10956 * There are three ways to call this: 10957 * - no provider specified: dump all the providers 10958 * - a flattened component name that matched an existing provider was specified as the 10959 * first arg: dump that one provider 10960 * - the first arg isn't the flattened component name of an existing provider: 10961 * dump all providers whose component contains the first arg as a substring 10962 */ 10963 protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args, 10964 int opti, boolean dumpAll) { 10965 return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll); 10966 } 10967 10968 static class ItemMatcher { 10969 ArrayList<ComponentName> components; 10970 ArrayList<String> strings; 10971 ArrayList<Integer> objects; 10972 boolean all; 10973 10974 ItemMatcher() { 10975 all = true; 10976 } 10977 10978 void build(String name) { 10979 ComponentName componentName = ComponentName.unflattenFromString(name); 10980 if (componentName != null) { 10981 if (components == null) { 10982 components = new ArrayList<ComponentName>(); 10983 } 10984 components.add(componentName); 10985 all = false; 10986 } else { 10987 int objectId = 0; 10988 // Not a '/' separated full component name; maybe an object ID? 10989 try { 10990 objectId = Integer.parseInt(name, 16); 10991 if (objects == null) { 10992 objects = new ArrayList<Integer>(); 10993 } 10994 objects.add(objectId); 10995 all = false; 10996 } catch (RuntimeException e) { 10997 // Not an integer; just do string match. 10998 if (strings == null) { 10999 strings = new ArrayList<String>(); 11000 } 11001 strings.add(name); 11002 all = false; 11003 } 11004 } 11005 } 11006 11007 int build(String[] args, int opti) { 11008 for (; opti<args.length; opti++) { 11009 String name = args[opti]; 11010 if ("--".equals(name)) { 11011 return opti+1; 11012 } 11013 build(name); 11014 } 11015 return opti; 11016 } 11017 11018 boolean match(Object object, ComponentName comp) { 11019 if (all) { 11020 return true; 11021 } 11022 if (components != null) { 11023 for (int i=0; i<components.size(); i++) { 11024 if (components.get(i).equals(comp)) { 11025 return true; 11026 } 11027 } 11028 } 11029 if (objects != null) { 11030 for (int i=0; i<objects.size(); i++) { 11031 if (System.identityHashCode(object) == objects.get(i)) { 11032 return true; 11033 } 11034 } 11035 } 11036 if (strings != null) { 11037 String flat = comp.flattenToString(); 11038 for (int i=0; i<strings.size(); i++) { 11039 if (flat.contains(strings.get(i))) { 11040 return true; 11041 } 11042 } 11043 } 11044 return false; 11045 } 11046 } 11047 11048 /** 11049 * There are three things that cmd can be: 11050 * - a flattened component name that matches an existing activity 11051 * - the cmd arg isn't the flattened component name of an existing activity: 11052 * dump all activity whose component contains the cmd as a substring 11053 * - A hex number of the ActivityRecord object instance. 11054 */ 11055 protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args, 11056 int opti, boolean dumpAll) { 11057 ArrayList<ActivityRecord> activities; 11058 11059 synchronized (this) { 11060 activities = mStackSupervisor.getDumpActivitiesLocked(name); 11061 } 11062 11063 if (activities.size() <= 0) { 11064 return false; 11065 } 11066 11067 String[] newArgs = new String[args.length - opti]; 11068 System.arraycopy(args, opti, newArgs, 0, args.length - opti); 11069 11070 TaskRecord lastTask = null; 11071 boolean needSep = false; 11072 for (int i=activities.size()-1; i>=0; i--) { 11073 ActivityRecord r = activities.get(i); 11074 if (needSep) { 11075 pw.println(); 11076 } 11077 needSep = true; 11078 synchronized (this) { 11079 if (lastTask != r.task) { 11080 lastTask = r.task; 11081 pw.print("TASK "); pw.print(lastTask.affinity); 11082 pw.print(" id="); pw.println(lastTask.taskId); 11083 if (dumpAll) { 11084 lastTask.dump(pw, " "); 11085 } 11086 } 11087 } 11088 dumpActivity(" ", fd, pw, activities.get(i), newArgs, dumpAll); 11089 } 11090 return true; 11091 } 11092 11093 /** 11094 * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if 11095 * there is a thread associated with the activity. 11096 */ 11097 private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw, 11098 final ActivityRecord r, String[] args, boolean dumpAll) { 11099 String innerPrefix = prefix + " "; 11100 synchronized (this) { 11101 pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName); 11102 pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r))); 11103 pw.print(" pid="); 11104 if (r.app != null) pw.println(r.app.pid); 11105 else pw.println("(not running)"); 11106 if (dumpAll) { 11107 r.dump(pw, innerPrefix); 11108 } 11109 } 11110 if (r.app != null && r.app.thread != null) { 11111 // flush anything that is already in the PrintWriter since the thread is going 11112 // to write to the file descriptor directly 11113 pw.flush(); 11114 try { 11115 TransferPipe tp = new TransferPipe(); 11116 try { 11117 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(), 11118 r.appToken, innerPrefix, args); 11119 tp.go(fd); 11120 } finally { 11121 tp.kill(); 11122 } 11123 } catch (IOException e) { 11124 pw.println(innerPrefix + "Failure while dumping the activity: " + e); 11125 } catch (RemoteException e) { 11126 pw.println(innerPrefix + "Got a RemoteException while dumping the activity"); 11127 } 11128 } 11129 } 11130 11131 void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 11132 int opti, boolean dumpAll, String dumpPackage) { 11133 boolean needSep = false; 11134 boolean onlyHistory = false; 11135 boolean printedAnything = false; 11136 11137 if ("history".equals(dumpPackage)) { 11138 if (opti < args.length && "-s".equals(args[opti])) { 11139 dumpAll = false; 11140 } 11141 onlyHistory = true; 11142 dumpPackage = null; 11143 } 11144 11145 pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)"); 11146 if (!onlyHistory && dumpAll) { 11147 if (mRegisteredReceivers.size() > 0) { 11148 boolean printed = false; 11149 Iterator it = mRegisteredReceivers.values().iterator(); 11150 while (it.hasNext()) { 11151 ReceiverList r = (ReceiverList)it.next(); 11152 if (dumpPackage != null && (r.app == null || 11153 !dumpPackage.equals(r.app.info.packageName))) { 11154 continue; 11155 } 11156 if (!printed) { 11157 pw.println(" Registered Receivers:"); 11158 needSep = true; 11159 printed = true; 11160 printedAnything = true; 11161 } 11162 pw.print(" * "); pw.println(r); 11163 r.dump(pw, " "); 11164 } 11165 } 11166 11167 if (mReceiverResolver.dump(pw, needSep ? 11168 "\n Receiver Resolver Table:" : " Receiver Resolver Table:", 11169 " ", dumpPackage, false)) { 11170 needSep = true; 11171 printedAnything = true; 11172 } 11173 } 11174 11175 for (BroadcastQueue q : mBroadcastQueues) { 11176 needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep); 11177 printedAnything |= needSep; 11178 } 11179 11180 needSep = true; 11181 11182 if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) { 11183 for (int user=0; user<mStickyBroadcasts.size(); user++) { 11184 if (needSep) { 11185 pw.println(); 11186 } 11187 needSep = true; 11188 printedAnything = true; 11189 pw.print(" Sticky broadcasts for user "); 11190 pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":"); 11191 StringBuilder sb = new StringBuilder(128); 11192 for (Map.Entry<String, ArrayList<Intent>> ent 11193 : mStickyBroadcasts.valueAt(user).entrySet()) { 11194 pw.print(" * Sticky action "); pw.print(ent.getKey()); 11195 if (dumpAll) { 11196 pw.println(":"); 11197 ArrayList<Intent> intents = ent.getValue(); 11198 final int N = intents.size(); 11199 for (int i=0; i<N; i++) { 11200 sb.setLength(0); 11201 sb.append(" Intent: "); 11202 intents.get(i).toShortString(sb, false, true, false, false); 11203 pw.println(sb.toString()); 11204 Bundle bundle = intents.get(i).getExtras(); 11205 if (bundle != null) { 11206 pw.print(" "); 11207 pw.println(bundle.toString()); 11208 } 11209 } 11210 } else { 11211 pw.println(""); 11212 } 11213 } 11214 } 11215 } 11216 11217 if (!onlyHistory && dumpAll) { 11218 pw.println(); 11219 for (BroadcastQueue queue : mBroadcastQueues) { 11220 pw.println(" mBroadcastsScheduled [" + queue.mQueueName + "]=" 11221 + queue.mBroadcastsScheduled); 11222 } 11223 pw.println(" mHandler:"); 11224 mHandler.dump(new PrintWriterPrinter(pw), " "); 11225 needSep = true; 11226 printedAnything = true; 11227 } 11228 11229 if (!printedAnything) { 11230 pw.println(" (nothing)"); 11231 } 11232 } 11233 11234 void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args, 11235 int opti, boolean dumpAll, String dumpPackage) { 11236 boolean needSep; 11237 boolean printedAnything = false; 11238 11239 ItemMatcher matcher = new ItemMatcher(); 11240 matcher.build(args, opti); 11241 11242 pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)"); 11243 11244 needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage); 11245 printedAnything |= needSep; 11246 11247 if (mLaunchingProviders.size() > 0) { 11248 boolean printed = false; 11249 for (int i=mLaunchingProviders.size()-1; i>=0; i--) { 11250 ContentProviderRecord r = mLaunchingProviders.get(i); 11251 if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) { 11252 continue; 11253 } 11254 if (!printed) { 11255 if (needSep) pw.println(); 11256 needSep = true; 11257 pw.println(" Launching content providers:"); 11258 printed = true; 11259 printedAnything = true; 11260 } 11261 pw.print(" Launching #"); pw.print(i); pw.print(": "); 11262 pw.println(r); 11263 } 11264 } 11265 11266 if (mGrantedUriPermissions.size() > 0) { 11267 boolean printed = false; 11268 int dumpUid = -2; 11269 if (dumpPackage != null) { 11270 try { 11271 dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0); 11272 } catch (NameNotFoundException e) { 11273 dumpUid = -1; 11274 } 11275 } 11276 for (int i=0; i<mGrantedUriPermissions.size(); i++) { 11277 int uid = mGrantedUriPermissions.keyAt(i); 11278 if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) { 11279 continue; 11280 } 11281 ArrayMap<Uri, UriPermission> perms 11282 = mGrantedUriPermissions.valueAt(i); 11283 if (!printed) { 11284 if (needSep) pw.println(); 11285 needSep = true; 11286 pw.println(" Granted Uri Permissions:"); 11287 printed = true; 11288 printedAnything = true; 11289 } 11290 pw.print(" * UID "); pw.print(uid); 11291 pw.println(" holds:"); 11292 for (UriPermission perm : perms.values()) { 11293 pw.print(" "); pw.println(perm); 11294 if (dumpAll) { 11295 perm.dump(pw, " "); 11296 } 11297 } 11298 } 11299 } 11300 11301 if (!printedAnything) { 11302 pw.println(" (nothing)"); 11303 } 11304 } 11305 11306 void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 11307 int opti, boolean dumpAll, String dumpPackage) { 11308 boolean printed = false; 11309 11310 pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)"); 11311 11312 if (mIntentSenderRecords.size() > 0) { 11313 Iterator<WeakReference<PendingIntentRecord>> it 11314 = mIntentSenderRecords.values().iterator(); 11315 while (it.hasNext()) { 11316 WeakReference<PendingIntentRecord> ref = it.next(); 11317 PendingIntentRecord rec = ref != null ? ref.get(): null; 11318 if (dumpPackage != null && (rec == null 11319 || !dumpPackage.equals(rec.key.packageName))) { 11320 continue; 11321 } 11322 printed = true; 11323 if (rec != null) { 11324 pw.print(" * "); pw.println(rec); 11325 if (dumpAll) { 11326 rec.dump(pw, " "); 11327 } 11328 } else { 11329 pw.print(" * "); pw.println(ref); 11330 } 11331 } 11332 } 11333 11334 if (!printed) { 11335 pw.println(" (nothing)"); 11336 } 11337 } 11338 11339 private static final int dumpProcessList(PrintWriter pw, 11340 ActivityManagerService service, List list, 11341 String prefix, String normalLabel, String persistentLabel, 11342 String dumpPackage) { 11343 int numPers = 0; 11344 final int N = list.size()-1; 11345 for (int i=N; i>=0; i--) { 11346 ProcessRecord r = (ProcessRecord)list.get(i); 11347 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 11348 continue; 11349 } 11350 pw.println(String.format("%s%s #%2d: %s", 11351 prefix, (r.persistent ? persistentLabel : normalLabel), 11352 i, r.toString())); 11353 if (r.persistent) { 11354 numPers++; 11355 } 11356 } 11357 return numPers; 11358 } 11359 11360 private static final boolean dumpProcessOomList(PrintWriter pw, 11361 ActivityManagerService service, List<ProcessRecord> origList, 11362 String prefix, String normalLabel, String persistentLabel, 11363 boolean inclDetails, String dumpPackage) { 11364 11365 ArrayList<Pair<ProcessRecord, Integer>> list 11366 = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size()); 11367 for (int i=0; i<origList.size(); i++) { 11368 ProcessRecord r = origList.get(i); 11369 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 11370 continue; 11371 } 11372 list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i)); 11373 } 11374 11375 if (list.size() <= 0) { 11376 return false; 11377 } 11378 11379 Comparator<Pair<ProcessRecord, Integer>> comparator 11380 = new Comparator<Pair<ProcessRecord, Integer>>() { 11381 @Override 11382 public int compare(Pair<ProcessRecord, Integer> object1, 11383 Pair<ProcessRecord, Integer> object2) { 11384 if (object1.first.setAdj != object2.first.setAdj) { 11385 return object1.first.setAdj > object2.first.setAdj ? -1 : 1; 11386 } 11387 if (object1.second.intValue() != object2.second.intValue()) { 11388 return object1.second.intValue() > object2.second.intValue() ? -1 : 1; 11389 } 11390 return 0; 11391 } 11392 }; 11393 11394 Collections.sort(list, comparator); 11395 11396 final long curRealtime = SystemClock.elapsedRealtime(); 11397 final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime; 11398 final long curUptime = SystemClock.uptimeMillis(); 11399 final long uptimeSince = curUptime - service.mLastPowerCheckUptime; 11400 11401 for (int i=list.size()-1; i>=0; i--) { 11402 ProcessRecord r = list.get(i).first; 11403 String oomAdj = ProcessList.makeOomAdjString(r.setAdj); 11404 char schedGroup; 11405 switch (r.setSchedGroup) { 11406 case Process.THREAD_GROUP_BG_NONINTERACTIVE: 11407 schedGroup = 'B'; 11408 break; 11409 case Process.THREAD_GROUP_DEFAULT: 11410 schedGroup = 'F'; 11411 break; 11412 default: 11413 schedGroup = '?'; 11414 break; 11415 } 11416 char foreground; 11417 if (r.foregroundActivities) { 11418 foreground = 'A'; 11419 } else if (r.foregroundServices) { 11420 foreground = 'S'; 11421 } else { 11422 foreground = ' '; 11423 } 11424 String procState = ProcessList.makeProcStateString(r.curProcState); 11425 pw.print(prefix); 11426 pw.print(r.persistent ? persistentLabel : normalLabel); 11427 pw.print(" #"); 11428 int num = (origList.size()-1)-list.get(i).second; 11429 if (num < 10) pw.print(' '); 11430 pw.print(num); 11431 pw.print(": "); 11432 pw.print(oomAdj); 11433 pw.print(' '); 11434 pw.print(schedGroup); 11435 pw.print('/'); 11436 pw.print(foreground); 11437 pw.print('/'); 11438 pw.print(procState); 11439 pw.print(" trm:"); 11440 if (r.trimMemoryLevel < 10) pw.print(' '); 11441 pw.print(r.trimMemoryLevel); 11442 pw.print(' '); 11443 pw.print(r.toShortString()); 11444 pw.print(" ("); 11445 pw.print(r.adjType); 11446 pw.println(')'); 11447 if (r.adjSource != null || r.adjTarget != null) { 11448 pw.print(prefix); 11449 pw.print(" "); 11450 if (r.adjTarget instanceof ComponentName) { 11451 pw.print(((ComponentName)r.adjTarget).flattenToShortString()); 11452 } else if (r.adjTarget != null) { 11453 pw.print(r.adjTarget.toString()); 11454 } else { 11455 pw.print("{null}"); 11456 } 11457 pw.print("<="); 11458 if (r.adjSource instanceof ProcessRecord) { 11459 pw.print("Proc{"); 11460 pw.print(((ProcessRecord)r.adjSource).toShortString()); 11461 pw.println("}"); 11462 } else if (r.adjSource != null) { 11463 pw.println(r.adjSource.toString()); 11464 } else { 11465 pw.println("{null}"); 11466 } 11467 } 11468 if (inclDetails) { 11469 pw.print(prefix); 11470 pw.print(" "); 11471 pw.print("oom: max="); pw.print(r.maxAdj); 11472 pw.print(" curRaw="); pw.print(r.curRawAdj); 11473 pw.print(" setRaw="); pw.print(r.setRawAdj); 11474 pw.print(" cur="); pw.print(r.curAdj); 11475 pw.print(" set="); pw.println(r.setAdj); 11476 pw.print(prefix); 11477 pw.print(" "); 11478 pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState)); 11479 pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState)); 11480 pw.print(" lastPss="); pw.print(r.lastPss); 11481 pw.print(" lastCachedPss="); pw.println(r.lastCachedPss); 11482 pw.print(prefix); 11483 pw.print(" "); 11484 pw.print("keeping="); pw.print(r.keeping); 11485 pw.print(" cached="); pw.print(r.cached); 11486 pw.print(" empty="); pw.print(r.empty); 11487 pw.print(" hasAboveClient="); pw.println(r.hasAboveClient); 11488 11489 if (!r.keeping) { 11490 if (r.lastWakeTime != 0) { 11491 long wtime; 11492 BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics(); 11493 synchronized (stats) { 11494 wtime = stats.getProcessWakeTime(r.info.uid, 11495 r.pid, curRealtime); 11496 } 11497 long timeUsed = wtime - r.lastWakeTime; 11498 pw.print(prefix); 11499 pw.print(" "); 11500 pw.print("keep awake over "); 11501 TimeUtils.formatDuration(realtimeSince, pw); 11502 pw.print(" used "); 11503 TimeUtils.formatDuration(timeUsed, pw); 11504 pw.print(" ("); 11505 pw.print((timeUsed*100)/realtimeSince); 11506 pw.println("%)"); 11507 } 11508 if (r.lastCpuTime != 0) { 11509 long timeUsed = r.curCpuTime - r.lastCpuTime; 11510 pw.print(prefix); 11511 pw.print(" "); 11512 pw.print("run cpu over "); 11513 TimeUtils.formatDuration(uptimeSince, pw); 11514 pw.print(" used "); 11515 TimeUtils.formatDuration(timeUsed, pw); 11516 pw.print(" ("); 11517 pw.print((timeUsed*100)/uptimeSince); 11518 pw.println("%)"); 11519 } 11520 } 11521 } 11522 } 11523 return true; 11524 } 11525 11526 ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) { 11527 ArrayList<ProcessRecord> procs; 11528 synchronized (this) { 11529 if (args != null && args.length > start 11530 && args[start].charAt(0) != '-') { 11531 procs = new ArrayList<ProcessRecord>(); 11532 int pid = -1; 11533 try { 11534 pid = Integer.parseInt(args[start]); 11535 } catch (NumberFormatException e) { 11536 } 11537 for (int i=mLruProcesses.size()-1; i>=0; i--) { 11538 ProcessRecord proc = mLruProcesses.get(i); 11539 if (proc.pid == pid) { 11540 procs.add(proc); 11541 } else if (proc.processName.equals(args[start])) { 11542 procs.add(proc); 11543 } 11544 } 11545 if (procs.size() <= 0) { 11546 return null; 11547 } 11548 } else { 11549 procs = new ArrayList<ProcessRecord>(mLruProcesses); 11550 } 11551 } 11552 return procs; 11553 } 11554 11555 final void dumpGraphicsHardwareUsage(FileDescriptor fd, 11556 PrintWriter pw, String[] args) { 11557 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args); 11558 if (procs == null) { 11559 pw.println("No process found for: " + args[0]); 11560 return; 11561 } 11562 11563 long uptime = SystemClock.uptimeMillis(); 11564 long realtime = SystemClock.elapsedRealtime(); 11565 pw.println("Applications Graphics Acceleration Info:"); 11566 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 11567 11568 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 11569 ProcessRecord r = procs.get(i); 11570 if (r.thread != null) { 11571 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **"); 11572 pw.flush(); 11573 try { 11574 TransferPipe tp = new TransferPipe(); 11575 try { 11576 r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args); 11577 tp.go(fd); 11578 } finally { 11579 tp.kill(); 11580 } 11581 } catch (IOException e) { 11582 pw.println("Failure while dumping the app: " + r); 11583 pw.flush(); 11584 } catch (RemoteException e) { 11585 pw.println("Got a RemoteException while dumping the app " + r); 11586 pw.flush(); 11587 } 11588 } 11589 } 11590 } 11591 11592 final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) { 11593 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args); 11594 if (procs == null) { 11595 pw.println("No process found for: " + args[0]); 11596 return; 11597 } 11598 11599 pw.println("Applications Database Info:"); 11600 11601 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 11602 ProcessRecord r = procs.get(i); 11603 if (r.thread != null) { 11604 pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **"); 11605 pw.flush(); 11606 try { 11607 TransferPipe tp = new TransferPipe(); 11608 try { 11609 r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args); 11610 tp.go(fd); 11611 } finally { 11612 tp.kill(); 11613 } 11614 } catch (IOException e) { 11615 pw.println("Failure while dumping the app: " + r); 11616 pw.flush(); 11617 } catch (RemoteException e) { 11618 pw.println("Got a RemoteException while dumping the app " + r); 11619 pw.flush(); 11620 } 11621 } 11622 } 11623 } 11624 11625 final static class MemItem { 11626 final boolean isProc; 11627 final String label; 11628 final String shortLabel; 11629 final long pss; 11630 final int id; 11631 final boolean hasActivities; 11632 ArrayList<MemItem> subitems; 11633 11634 public MemItem(String _label, String _shortLabel, long _pss, int _id, 11635 boolean _hasActivities) { 11636 isProc = true; 11637 label = _label; 11638 shortLabel = _shortLabel; 11639 pss = _pss; 11640 id = _id; 11641 hasActivities = _hasActivities; 11642 } 11643 11644 public MemItem(String _label, String _shortLabel, long _pss, int _id) { 11645 isProc = false; 11646 label = _label; 11647 shortLabel = _shortLabel; 11648 pss = _pss; 11649 id = _id; 11650 hasActivities = false; 11651 } 11652 } 11653 11654 static final void dumpMemItems(PrintWriter pw, String prefix, String tag, 11655 ArrayList<MemItem> items, boolean sort, boolean isCompact) { 11656 if (sort && !isCompact) { 11657 Collections.sort(items, new Comparator<MemItem>() { 11658 @Override 11659 public int compare(MemItem lhs, MemItem rhs) { 11660 if (lhs.pss < rhs.pss) { 11661 return 1; 11662 } else if (lhs.pss > rhs.pss) { 11663 return -1; 11664 } 11665 return 0; 11666 } 11667 }); 11668 } 11669 11670 for (int i=0; i<items.size(); i++) { 11671 MemItem mi = items.get(i); 11672 if (!isCompact) { 11673 pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label); 11674 } else if (mi.isProc) { 11675 pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel); 11676 pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss); 11677 pw.println(mi.hasActivities ? ",a" : ",e"); 11678 } else { 11679 pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(","); 11680 pw.println(mi.pss); 11681 } 11682 if (mi.subitems != null) { 11683 dumpMemItems(pw, prefix + " ", mi.shortLabel, mi.subitems, 11684 true, isCompact); 11685 } 11686 } 11687 } 11688 11689 // These are in KB. 11690 static final long[] DUMP_MEM_BUCKETS = new long[] { 11691 5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024, 11692 120*1024, 160*1024, 200*1024, 11693 250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024, 11694 1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024 11695 }; 11696 11697 static final void appendMemBucket(StringBuilder out, long memKB, String label, 11698 boolean stackLike) { 11699 int start = label.lastIndexOf('.'); 11700 if (start >= 0) start++; 11701 else start = 0; 11702 int end = label.length(); 11703 for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) { 11704 if (DUMP_MEM_BUCKETS[i] >= memKB) { 11705 long bucket = DUMP_MEM_BUCKETS[i]/1024; 11706 out.append(bucket); 11707 out.append(stackLike ? "MB." : "MB "); 11708 out.append(label, start, end); 11709 return; 11710 } 11711 } 11712 out.append(memKB/1024); 11713 out.append(stackLike ? "MB." : "MB "); 11714 out.append(label, start, end); 11715 } 11716 11717 static final int[] DUMP_MEM_OOM_ADJ = new int[] { 11718 ProcessList.NATIVE_ADJ, 11719 ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ, 11720 ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ, 11721 ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ, 11722 ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ, 11723 ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ 11724 }; 11725 static final String[] DUMP_MEM_OOM_LABEL = new String[] { 11726 "Native", 11727 "System", "Persistent", "Foreground", 11728 "Visible", "Perceptible", 11729 "Heavy Weight", "Backup", 11730 "A Services", "Home", 11731 "Previous", "B Services", "Cached" 11732 }; 11733 static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] { 11734 "native", 11735 "sys", "pers", "fore", 11736 "vis", "percept", 11737 "heavy", "backup", 11738 "servicea", "home", 11739 "prev", "serviceb", "cached" 11740 }; 11741 11742 private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime, 11743 long realtime, boolean isCheckinRequest, boolean isCompact) { 11744 if (isCheckinRequest || isCompact) { 11745 // short checkin version 11746 pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime); 11747 } else { 11748 pw.println("Applications Memory Usage (kB):"); 11749 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 11750 } 11751 } 11752 11753 final void dumpApplicationMemoryUsage(FileDescriptor fd, 11754 PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) { 11755 boolean dumpDetails = false; 11756 boolean dumpFullDetails = false; 11757 boolean dumpDalvik = false; 11758 boolean oomOnly = false; 11759 boolean isCompact = false; 11760 boolean localOnly = false; 11761 11762 int opti = 0; 11763 while (opti < args.length) { 11764 String opt = args[opti]; 11765 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 11766 break; 11767 } 11768 opti++; 11769 if ("-a".equals(opt)) { 11770 dumpDetails = true; 11771 dumpFullDetails = true; 11772 dumpDalvik = true; 11773 } else if ("-d".equals(opt)) { 11774 dumpDalvik = true; 11775 } else if ("-c".equals(opt)) { 11776 isCompact = true; 11777 } else if ("--oom".equals(opt)) { 11778 oomOnly = true; 11779 } else if ("--local".equals(opt)) { 11780 localOnly = true; 11781 } else if ("-h".equals(opt)) { 11782 pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]"); 11783 pw.println(" -a: include all available information for each process."); 11784 pw.println(" -d: include dalvik details when dumping process details."); 11785 pw.println(" -c: dump in a compact machine-parseable representation."); 11786 pw.println(" --oom: only show processes organized by oom adj."); 11787 pw.println(" --local: only collect details locally, don't call process."); 11788 pw.println("If [process] is specified it can be the name or "); 11789 pw.println("pid of a specific process to dump."); 11790 return; 11791 } else { 11792 pw.println("Unknown argument: " + opt + "; use -h for help"); 11793 } 11794 } 11795 11796 final boolean isCheckinRequest = scanArgs(args, "--checkin"); 11797 long uptime = SystemClock.uptimeMillis(); 11798 long realtime = SystemClock.elapsedRealtime(); 11799 final long[] tmpLong = new long[1]; 11800 11801 ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args); 11802 if (procs == null) { 11803 // No Java processes. Maybe they want to print a native process. 11804 if (args != null && args.length > opti 11805 && args[opti].charAt(0) != '-') { 11806 ArrayList<ProcessCpuTracker.Stats> nativeProcs 11807 = new ArrayList<ProcessCpuTracker.Stats>(); 11808 updateCpuStatsNow(); 11809 int findPid = -1; 11810 try { 11811 findPid = Integer.parseInt(args[opti]); 11812 } catch (NumberFormatException e) { 11813 } 11814 synchronized (mProcessCpuThread) { 11815 final int N = mProcessCpuTracker.countStats(); 11816 for (int i=0; i<N; i++) { 11817 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 11818 if (st.pid == findPid || (st.baseName != null 11819 && st.baseName.equals(args[opti]))) { 11820 nativeProcs.add(st); 11821 } 11822 } 11823 } 11824 if (nativeProcs.size() > 0) { 11825 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, 11826 isCompact); 11827 Debug.MemoryInfo mi = null; 11828 for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) { 11829 final ProcessCpuTracker.Stats r = nativeProcs.get(i); 11830 final int pid = r.pid; 11831 if (!isCheckinRequest && dumpDetails) { 11832 pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **"); 11833 } 11834 if (mi == null) { 11835 mi = new Debug.MemoryInfo(); 11836 } 11837 if (dumpDetails || (!brief && !oomOnly)) { 11838 Debug.getMemoryInfo(pid, mi); 11839 } else { 11840 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong); 11841 mi.dalvikPrivateDirty = (int)tmpLong[0]; 11842 } 11843 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails, 11844 dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0); 11845 if (isCheckinRequest) { 11846 pw.println(); 11847 } 11848 } 11849 return; 11850 } 11851 } 11852 pw.println("No process found for: " + args[opti]); 11853 return; 11854 } 11855 11856 if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest)) { 11857 dumpDetails = true; 11858 } 11859 11860 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact); 11861 11862 String[] innerArgs = new String[args.length-opti]; 11863 System.arraycopy(args, opti, innerArgs, 0, args.length-opti); 11864 11865 ArrayList<MemItem> procMems = new ArrayList<MemItem>(); 11866 final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>(); 11867 long nativePss=0, dalvikPss=0, otherPss=0; 11868 long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS]; 11869 11870 long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length]; 11871 ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[]) 11872 new ArrayList[DUMP_MEM_OOM_LABEL.length]; 11873 11874 long totalPss = 0; 11875 long cachedPss = 0; 11876 11877 Debug.MemoryInfo mi = null; 11878 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 11879 final ProcessRecord r = procs.get(i); 11880 final IApplicationThread thread; 11881 final int pid; 11882 final int oomAdj; 11883 final boolean hasActivities; 11884 synchronized (this) { 11885 thread = r.thread; 11886 pid = r.pid; 11887 oomAdj = r.getSetAdjWithServices(); 11888 hasActivities = r.activities.size() > 0; 11889 } 11890 if (thread != null) { 11891 if (!isCheckinRequest && dumpDetails) { 11892 pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **"); 11893 } 11894 if (mi == null) { 11895 mi = new Debug.MemoryInfo(); 11896 } 11897 if (dumpDetails || (!brief && !oomOnly)) { 11898 Debug.getMemoryInfo(pid, mi); 11899 } else { 11900 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong); 11901 mi.dalvikPrivateDirty = (int)tmpLong[0]; 11902 } 11903 if (dumpDetails) { 11904 if (localOnly) { 11905 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails, 11906 dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0); 11907 if (isCheckinRequest) { 11908 pw.println(); 11909 } 11910 } else { 11911 try { 11912 pw.flush(); 11913 thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails, 11914 dumpDalvik, innerArgs); 11915 } catch (RemoteException e) { 11916 if (!isCheckinRequest) { 11917 pw.println("Got RemoteException!"); 11918 pw.flush(); 11919 } 11920 } 11921 } 11922 } 11923 11924 final long myTotalPss = mi.getTotalPss(); 11925 final long myTotalUss = mi.getTotalUss(); 11926 11927 synchronized (this) { 11928 if (r.thread != null && oomAdj == r.getSetAdjWithServices()) { 11929 // Record this for posterity if the process has been stable. 11930 r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList); 11931 } 11932 } 11933 11934 if (!isCheckinRequest && mi != null) { 11935 totalPss += myTotalPss; 11936 MemItem pssItem = new MemItem(r.processName + " (pid " + pid + 11937 (hasActivities ? " / activities)" : ")"), 11938 r.processName, myTotalPss, pid, hasActivities); 11939 procMems.add(pssItem); 11940 procMemsMap.put(pid, pssItem); 11941 11942 nativePss += mi.nativePss; 11943 dalvikPss += mi.dalvikPss; 11944 otherPss += mi.otherPss; 11945 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 11946 long mem = mi.getOtherPss(j); 11947 miscPss[j] += mem; 11948 otherPss -= mem; 11949 } 11950 11951 if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 11952 cachedPss += myTotalPss; 11953 } 11954 11955 for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) { 11956 if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex] 11957 || oomIndex == (oomPss.length-1)) { 11958 oomPss[oomIndex] += myTotalPss; 11959 if (oomProcs[oomIndex] == null) { 11960 oomProcs[oomIndex] = new ArrayList<MemItem>(); 11961 } 11962 oomProcs[oomIndex].add(pssItem); 11963 break; 11964 } 11965 } 11966 } 11967 } 11968 } 11969 11970 if (!isCheckinRequest && procs.size() > 1) { 11971 // If we are showing aggregations, also look for native processes to 11972 // include so that our aggregations are more accurate. 11973 updateCpuStatsNow(); 11974 synchronized (mProcessCpuThread) { 11975 final int N = mProcessCpuTracker.countStats(); 11976 for (int i=0; i<N; i++) { 11977 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 11978 if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) { 11979 if (mi == null) { 11980 mi = new Debug.MemoryInfo(); 11981 } 11982 if (!brief && !oomOnly) { 11983 Debug.getMemoryInfo(st.pid, mi); 11984 } else { 11985 mi.nativePss = (int)Debug.getPss(st.pid, tmpLong); 11986 mi.nativePrivateDirty = (int)tmpLong[0]; 11987 } 11988 11989 final long myTotalPss = mi.getTotalPss(); 11990 totalPss += myTotalPss; 11991 11992 MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")", 11993 st.name, myTotalPss, st.pid, false); 11994 procMems.add(pssItem); 11995 11996 nativePss += mi.nativePss; 11997 dalvikPss += mi.dalvikPss; 11998 otherPss += mi.otherPss; 11999 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 12000 long mem = mi.getOtherPss(j); 12001 miscPss[j] += mem; 12002 otherPss -= mem; 12003 } 12004 oomPss[0] += myTotalPss; 12005 if (oomProcs[0] == null) { 12006 oomProcs[0] = new ArrayList<MemItem>(); 12007 } 12008 oomProcs[0].add(pssItem); 12009 } 12010 } 12011 } 12012 12013 ArrayList<MemItem> catMems = new ArrayList<MemItem>(); 12014 12015 catMems.add(new MemItem("Native", "Native", nativePss, -1)); 12016 catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2)); 12017 catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3)); 12018 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 12019 String label = Debug.MemoryInfo.getOtherLabel(j); 12020 catMems.add(new MemItem(label, label, miscPss[j], j)); 12021 } 12022 12023 ArrayList<MemItem> oomMems = new ArrayList<MemItem>(); 12024 for (int j=0; j<oomPss.length; j++) { 12025 if (oomPss[j] != 0) { 12026 String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j] 12027 : DUMP_MEM_OOM_LABEL[j]; 12028 MemItem item = new MemItem(label, label, oomPss[j], 12029 DUMP_MEM_OOM_ADJ[j]); 12030 item.subitems = oomProcs[j]; 12031 oomMems.add(item); 12032 } 12033 } 12034 12035 if (!brief && !oomOnly && !isCompact) { 12036 pw.println(); 12037 pw.println("Total PSS by process:"); 12038 dumpMemItems(pw, " ", "proc", procMems, true, isCompact); 12039 pw.println(); 12040 } 12041 if (!isCompact) { 12042 pw.println("Total PSS by OOM adjustment:"); 12043 } 12044 dumpMemItems(pw, " ", "oom", oomMems, false, isCompact); 12045 if (!brief && !oomOnly) { 12046 PrintWriter out = categoryPw != null ? categoryPw : pw; 12047 if (!isCompact) { 12048 out.println(); 12049 out.println("Total PSS by category:"); 12050 } 12051 dumpMemItems(out, " ", "cat", catMems, true, isCompact); 12052 } 12053 if (!isCompact) { 12054 pw.println(); 12055 } 12056 MemInfoReader memInfo = new MemInfoReader(); 12057 memInfo.readMemInfo(); 12058 if (!brief) { 12059 if (!isCompact) { 12060 pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb()); 12061 pw.println(" kB"); 12062 pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb() 12063 + memInfo.getFreeSizeKb()); pw.print(" kB ("); 12064 pw.print(cachedPss); pw.print(" cached pss + "); 12065 pw.print(memInfo.getCachedSizeKb()); pw.print(" cached + "); 12066 pw.print(memInfo.getFreeSizeKb()); pw.println(" free)"); 12067 } else { 12068 pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(","); 12069 pw.print(cachedPss + memInfo.getCachedSizeKb() 12070 + memInfo.getFreeSizeKb()); pw.print(","); 12071 pw.println(totalPss - cachedPss); 12072 } 12073 } 12074 if (!isCompact) { 12075 pw.print(" Used RAM: "); pw.print(totalPss - cachedPss 12076 + memInfo.getBuffersSizeKb() + memInfo.getShmemSizeKb() 12077 + memInfo.getSlabSizeKb()); pw.print(" kB ("); 12078 pw.print(totalPss - cachedPss); pw.print(" used pss + "); 12079 pw.print(memInfo.getBuffersSizeKb()); pw.print(" buffers + "); 12080 pw.print(memInfo.getShmemSizeKb()); pw.print(" shmem + "); 12081 pw.print(memInfo.getSlabSizeKb()); pw.println(" slab)"); 12082 pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb() 12083 - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb() 12084 - memInfo.getBuffersSizeKb() - memInfo.getShmemSizeKb() 12085 - memInfo.getSlabSizeKb()); pw.println(" kB"); 12086 } 12087 if (!brief) { 12088 if (memInfo.getZramTotalSizeKb() != 0) { 12089 if (!isCompact) { 12090 pw.print(" ZRAM: "); pw.print(memInfo.getZramTotalSizeKb()); 12091 pw.print(" kB physical used for "); 12092 pw.print(memInfo.getSwapTotalSizeKb() 12093 - memInfo.getSwapFreeSizeKb()); 12094 pw.print(" kB in swap ("); 12095 pw.print(memInfo.getSwapTotalSizeKb()); 12096 pw.println(" kB total swap)"); 12097 } else { 12098 pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(","); 12099 pw.print(memInfo.getSwapTotalSizeKb()); pw.print(","); 12100 pw.println(memInfo.getSwapFreeSizeKb()); 12101 } 12102 } 12103 final int[] SINGLE_LONG_FORMAT = new int[] { 12104 Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG 12105 }; 12106 long[] longOut = new long[1]; 12107 Process.readProcFile("/sys/kernel/mm/ksm/pages_shared", 12108 SINGLE_LONG_FORMAT, null, longOut, null); 12109 long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024; 12110 longOut[0] = 0; 12111 Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing", 12112 SINGLE_LONG_FORMAT, null, longOut, null); 12113 long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024; 12114 longOut[0] = 0; 12115 Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared", 12116 SINGLE_LONG_FORMAT, null, longOut, null); 12117 long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024; 12118 longOut[0] = 0; 12119 Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile", 12120 SINGLE_LONG_FORMAT, null, longOut, null); 12121 long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024; 12122 if (!isCompact) { 12123 if (sharing != 0 || shared != 0 || unshared != 0 || voltile != 0) { 12124 pw.print(" KSM: "); pw.print(sharing); 12125 pw.print(" kB saved from shared "); 12126 pw.print(shared); pw.println(" kB"); 12127 pw.print(" "); pw.print(unshared); pw.print(" kB unshared; "); 12128 pw.print(voltile); pw.println(" kB volatile"); 12129 } 12130 pw.print(" Tuning: "); 12131 pw.print(ActivityManager.staticGetMemoryClass()); 12132 pw.print(" (large "); 12133 pw.print(ActivityManager.staticGetLargeMemoryClass()); 12134 pw.print("), oom "); 12135 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024); 12136 pw.print(" kB"); 12137 pw.print(", restore limit "); 12138 pw.print(mProcessList.getCachedRestoreThresholdKb()); 12139 pw.print(" kB"); 12140 if (ActivityManager.isLowRamDeviceStatic()) { 12141 pw.print(" (low-ram)"); 12142 } 12143 if (ActivityManager.isHighEndGfx()) { 12144 pw.print(" (high-end-gfx)"); 12145 } 12146 pw.println(); 12147 } else { 12148 pw.print("ksm,"); pw.print(sharing); pw.print(","); 12149 pw.print(shared); pw.print(","); pw.print(unshared); pw.print(","); 12150 pw.println(voltile); 12151 pw.print("tuning,"); 12152 pw.print(ActivityManager.staticGetMemoryClass()); 12153 pw.print(','); 12154 pw.print(ActivityManager.staticGetLargeMemoryClass()); 12155 pw.print(','); 12156 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024); 12157 if (ActivityManager.isLowRamDeviceStatic()) { 12158 pw.print(",low-ram"); 12159 } 12160 if (ActivityManager.isHighEndGfx()) { 12161 pw.print(",high-end-gfx"); 12162 } 12163 pw.println(); 12164 } 12165 } 12166 } 12167 } 12168 12169 /** 12170 * Searches array of arguments for the specified string 12171 * @param args array of argument strings 12172 * @param value value to search for 12173 * @return true if the value is contained in the array 12174 */ 12175 private static boolean scanArgs(String[] args, String value) { 12176 if (args != null) { 12177 for (String arg : args) { 12178 if (value.equals(arg)) { 12179 return true; 12180 } 12181 } 12182 } 12183 return false; 12184 } 12185 12186 private final boolean removeDyingProviderLocked(ProcessRecord proc, 12187 ContentProviderRecord cpr, boolean always) { 12188 final boolean inLaunching = mLaunchingProviders.contains(cpr); 12189 12190 if (!inLaunching || always) { 12191 synchronized (cpr) { 12192 cpr.launchingApp = null; 12193 cpr.notifyAll(); 12194 } 12195 mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid)); 12196 String names[] = cpr.info.authority.split(";"); 12197 for (int j = 0; j < names.length; j++) { 12198 mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid)); 12199 } 12200 } 12201 12202 for (int i=0; i<cpr.connections.size(); i++) { 12203 ContentProviderConnection conn = cpr.connections.get(i); 12204 if (conn.waiting) { 12205 // If this connection is waiting for the provider, then we don't 12206 // need to mess with its process unless we are always removing 12207 // or for some reason the provider is not currently launching. 12208 if (inLaunching && !always) { 12209 continue; 12210 } 12211 } 12212 ProcessRecord capp = conn.client; 12213 conn.dead = true; 12214 if (conn.stableCount > 0) { 12215 if (!capp.persistent && capp.thread != null 12216 && capp.pid != 0 12217 && capp.pid != MY_PID) { 12218 killUnneededProcessLocked(capp, "depends on provider " 12219 + cpr.name.flattenToShortString() 12220 + " in dying proc " + (proc != null ? proc.processName : "??")); 12221 } 12222 } else if (capp.thread != null && conn.provider.provider != null) { 12223 try { 12224 capp.thread.unstableProviderDied(conn.provider.provider.asBinder()); 12225 } catch (RemoteException e) { 12226 } 12227 // In the protocol here, we don't expect the client to correctly 12228 // clean up this connection, we'll just remove it. 12229 cpr.connections.remove(i); 12230 conn.client.conProviders.remove(conn); 12231 } 12232 } 12233 12234 if (inLaunching && always) { 12235 mLaunchingProviders.remove(cpr); 12236 } 12237 return inLaunching; 12238 } 12239 12240 /** 12241 * Main code for cleaning up a process when it has gone away. This is 12242 * called both as a result of the process dying, or directly when stopping 12243 * a process when running in single process mode. 12244 */ 12245 private final void cleanUpApplicationRecordLocked(ProcessRecord app, 12246 boolean restarting, boolean allowRestart, int index) { 12247 if (index >= 0) { 12248 removeLruProcessLocked(app); 12249 ProcessList.remove(app.pid); 12250 } 12251 12252 mProcessesToGc.remove(app); 12253 mPendingPssProcesses.remove(app); 12254 12255 // Dismiss any open dialogs. 12256 if (app.crashDialog != null && !app.forceCrashReport) { 12257 app.crashDialog.dismiss(); 12258 app.crashDialog = null; 12259 } 12260 if (app.anrDialog != null) { 12261 app.anrDialog.dismiss(); 12262 app.anrDialog = null; 12263 } 12264 if (app.waitDialog != null) { 12265 app.waitDialog.dismiss(); 12266 app.waitDialog = null; 12267 } 12268 12269 app.crashing = false; 12270 app.notResponding = false; 12271 12272 app.resetPackageList(mProcessStats); 12273 app.unlinkDeathRecipient(); 12274 app.makeInactive(mProcessStats); 12275 app.forcingToForeground = null; 12276 app.foregroundServices = false; 12277 app.foregroundActivities = false; 12278 app.hasShownUi = false; 12279 app.hasAboveClient = false; 12280 12281 mServices.killServicesLocked(app, allowRestart); 12282 12283 boolean restart = false; 12284 12285 // Remove published content providers. 12286 for (int i=app.pubProviders.size()-1; i>=0; i--) { 12287 ContentProviderRecord cpr = app.pubProviders.valueAt(i); 12288 final boolean always = app.bad || !allowRestart; 12289 if (removeDyingProviderLocked(app, cpr, always) || always) { 12290 // We left the provider in the launching list, need to 12291 // restart it. 12292 restart = true; 12293 } 12294 12295 cpr.provider = null; 12296 cpr.proc = null; 12297 } 12298 app.pubProviders.clear(); 12299 12300 // Take care of any launching providers waiting for this process. 12301 if (checkAppInLaunchingProvidersLocked(app, false)) { 12302 restart = true; 12303 } 12304 12305 // Unregister from connected content providers. 12306 if (!app.conProviders.isEmpty()) { 12307 for (int i=0; i<app.conProviders.size(); i++) { 12308 ContentProviderConnection conn = app.conProviders.get(i); 12309 conn.provider.connections.remove(conn); 12310 } 12311 app.conProviders.clear(); 12312 } 12313 12314 // At this point there may be remaining entries in mLaunchingProviders 12315 // where we were the only one waiting, so they are no longer of use. 12316 // Look for these and clean up if found. 12317 // XXX Commented out for now. Trying to figure out a way to reproduce 12318 // the actual situation to identify what is actually going on. 12319 if (false) { 12320 for (int i=0; i<mLaunchingProviders.size(); i++) { 12321 ContentProviderRecord cpr = (ContentProviderRecord) 12322 mLaunchingProviders.get(i); 12323 if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) { 12324 synchronized (cpr) { 12325 cpr.launchingApp = null; 12326 cpr.notifyAll(); 12327 } 12328 } 12329 } 12330 } 12331 12332 skipCurrentReceiverLocked(app); 12333 12334 // Unregister any receivers. 12335 for (int i=app.receivers.size()-1; i>=0; i--) { 12336 removeReceiverLocked(app.receivers.valueAt(i)); 12337 } 12338 app.receivers.clear(); 12339 12340 // If the app is undergoing backup, tell the backup manager about it 12341 if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) { 12342 if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App " 12343 + mBackupTarget.appInfo + " died during backup"); 12344 try { 12345 IBackupManager bm = IBackupManager.Stub.asInterface( 12346 ServiceManager.getService(Context.BACKUP_SERVICE)); 12347 bm.agentDisconnected(app.info.packageName); 12348 } catch (RemoteException e) { 12349 // can't happen; backup manager is local 12350 } 12351 } 12352 12353 for (int i = mPendingProcessChanges.size()-1; i>=0; i--) { 12354 ProcessChangeItem item = mPendingProcessChanges.get(i); 12355 if (item.pid == app.pid) { 12356 mPendingProcessChanges.remove(i); 12357 mAvailProcessChanges.add(item); 12358 } 12359 } 12360 mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget(); 12361 12362 // If the caller is restarting this app, then leave it in its 12363 // current lists and let the caller take care of it. 12364 if (restarting) { 12365 return; 12366 } 12367 12368 if (!app.persistent || app.isolated) { 12369 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, 12370 "Removing non-persistent process during cleanup: " + app); 12371 mProcessNames.remove(app.processName, app.uid); 12372 mIsolatedProcesses.remove(app.uid); 12373 if (mHeavyWeightProcess == app) { 12374 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 12375 mHeavyWeightProcess.userId, 0)); 12376 mHeavyWeightProcess = null; 12377 } 12378 } else if (!app.removed) { 12379 // This app is persistent, so we need to keep its record around. 12380 // If it is not already on the pending app list, add it there 12381 // and start a new process for it. 12382 if (mPersistentStartingProcesses.indexOf(app) < 0) { 12383 mPersistentStartingProcesses.add(app); 12384 restart = true; 12385 } 12386 } 12387 if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG, 12388 "Clean-up removing on hold: " + app); 12389 mProcessesOnHold.remove(app); 12390 12391 if (app == mHomeProcess) { 12392 mHomeProcess = null; 12393 } 12394 if (app == mPreviousProcess) { 12395 mPreviousProcess = null; 12396 } 12397 12398 if (restart && !app.isolated) { 12399 // We have components that still need to be running in the 12400 // process, so re-launch it. 12401 mProcessNames.put(app.processName, app.uid, app); 12402 startProcessLocked(app, "restart", app.processName); 12403 } else if (app.pid > 0 && app.pid != MY_PID) { 12404 // Goodbye! 12405 synchronized (mPidsSelfLocked) { 12406 mPidsSelfLocked.remove(app.pid); 12407 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 12408 } 12409 app.setPid(0); 12410 } 12411 } 12412 12413 boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) { 12414 // Look through the content providers we are waiting to have launched, 12415 // and if any run in this process then either schedule a restart of 12416 // the process or kill the client waiting for it if this process has 12417 // gone bad. 12418 int NL = mLaunchingProviders.size(); 12419 boolean restart = false; 12420 for (int i=0; i<NL; i++) { 12421 ContentProviderRecord cpr = mLaunchingProviders.get(i); 12422 if (cpr.launchingApp == app) { 12423 if (!alwaysBad && !app.bad) { 12424 restart = true; 12425 } else { 12426 removeDyingProviderLocked(app, cpr, true); 12427 // cpr should have been removed from mLaunchingProviders 12428 NL = mLaunchingProviders.size(); 12429 i--; 12430 } 12431 } 12432 } 12433 return restart; 12434 } 12435 12436 // ========================================================= 12437 // SERVICES 12438 // ========================================================= 12439 12440 public List<ActivityManager.RunningServiceInfo> getServices(int maxNum, 12441 int flags) { 12442 enforceNotIsolatedCaller("getServices"); 12443 synchronized (this) { 12444 return mServices.getRunningServiceInfoLocked(maxNum, flags); 12445 } 12446 } 12447 12448 public PendingIntent getRunningServiceControlPanel(ComponentName name) { 12449 enforceNotIsolatedCaller("getRunningServiceControlPanel"); 12450 synchronized (this) { 12451 return mServices.getRunningServiceControlPanelLocked(name); 12452 } 12453 } 12454 12455 public ComponentName startService(IApplicationThread caller, Intent service, 12456 String resolvedType, int userId) { 12457 enforceNotIsolatedCaller("startService"); 12458 // Refuse possible leaked file descriptors 12459 if (service != null && service.hasFileDescriptors() == true) { 12460 throw new IllegalArgumentException("File descriptors passed in Intent"); 12461 } 12462 12463 if (DEBUG_SERVICE) 12464 Slog.v(TAG, "startService: " + service + " type=" + resolvedType); 12465 synchronized(this) { 12466 final int callingPid = Binder.getCallingPid(); 12467 final int callingUid = Binder.getCallingUid(); 12468 final long origId = Binder.clearCallingIdentity(); 12469 ComponentName res = mServices.startServiceLocked(caller, service, 12470 resolvedType, callingPid, callingUid, userId); 12471 Binder.restoreCallingIdentity(origId); 12472 return res; 12473 } 12474 } 12475 12476 ComponentName startServiceInPackage(int uid, 12477 Intent service, String resolvedType, int userId) { 12478 synchronized(this) { 12479 if (DEBUG_SERVICE) 12480 Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType); 12481 final long origId = Binder.clearCallingIdentity(); 12482 ComponentName res = mServices.startServiceLocked(null, service, 12483 resolvedType, -1, uid, userId); 12484 Binder.restoreCallingIdentity(origId); 12485 return res; 12486 } 12487 } 12488 12489 public int stopService(IApplicationThread caller, Intent service, 12490 String resolvedType, int userId) { 12491 enforceNotIsolatedCaller("stopService"); 12492 // Refuse possible leaked file descriptors 12493 if (service != null && service.hasFileDescriptors() == true) { 12494 throw new IllegalArgumentException("File descriptors passed in Intent"); 12495 } 12496 12497 synchronized(this) { 12498 return mServices.stopServiceLocked(caller, service, resolvedType, userId); 12499 } 12500 } 12501 12502 public IBinder peekService(Intent service, String resolvedType) { 12503 enforceNotIsolatedCaller("peekService"); 12504 // Refuse possible leaked file descriptors 12505 if (service != null && service.hasFileDescriptors() == true) { 12506 throw new IllegalArgumentException("File descriptors passed in Intent"); 12507 } 12508 synchronized(this) { 12509 return mServices.peekServiceLocked(service, resolvedType); 12510 } 12511 } 12512 12513 public boolean stopServiceToken(ComponentName className, IBinder token, 12514 int startId) { 12515 synchronized(this) { 12516 return mServices.stopServiceTokenLocked(className, token, startId); 12517 } 12518 } 12519 12520 public void setServiceForeground(ComponentName className, IBinder token, 12521 int id, Notification notification, boolean removeNotification) { 12522 synchronized(this) { 12523 mServices.setServiceForegroundLocked(className, token, id, notification, 12524 removeNotification); 12525 } 12526 } 12527 12528 public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll, 12529 boolean requireFull, String name, String callerPackage) { 12530 final int callingUserId = UserHandle.getUserId(callingUid); 12531 if (callingUserId != userId) { 12532 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 12533 if ((requireFull || checkComponentPermission( 12534 android.Manifest.permission.INTERACT_ACROSS_USERS, 12535 callingPid, callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) 12536 && checkComponentPermission( 12537 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 12538 callingPid, callingUid, -1, true) 12539 != PackageManager.PERMISSION_GRANTED) { 12540 if (userId == UserHandle.USER_CURRENT_OR_SELF) { 12541 // In this case, they would like to just execute as their 12542 // owner user instead of failing. 12543 userId = callingUserId; 12544 } else { 12545 StringBuilder builder = new StringBuilder(128); 12546 builder.append("Permission Denial: "); 12547 builder.append(name); 12548 if (callerPackage != null) { 12549 builder.append(" from "); 12550 builder.append(callerPackage); 12551 } 12552 builder.append(" asks to run as user "); 12553 builder.append(userId); 12554 builder.append(" but is calling from user "); 12555 builder.append(UserHandle.getUserId(callingUid)); 12556 builder.append("; this requires "); 12557 builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL); 12558 if (!requireFull) { 12559 builder.append(" or "); 12560 builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS); 12561 } 12562 String msg = builder.toString(); 12563 Slog.w(TAG, msg); 12564 throw new SecurityException(msg); 12565 } 12566 } 12567 } 12568 if (userId == UserHandle.USER_CURRENT 12569 || userId == UserHandle.USER_CURRENT_OR_SELF) { 12570 // Note that we may be accessing this outside of a lock... 12571 // shouldn't be a big deal, if this is being called outside 12572 // of a locked context there is intrinsically a race with 12573 // the value the caller will receive and someone else changing it. 12574 userId = mCurrentUserId; 12575 } 12576 if (!allowAll && userId < 0) { 12577 throw new IllegalArgumentException( 12578 "Call does not support special user #" + userId); 12579 } 12580 } 12581 return userId; 12582 } 12583 12584 boolean isSingleton(String componentProcessName, ApplicationInfo aInfo, 12585 String className, int flags) { 12586 boolean result = false; 12587 if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) { 12588 if ((flags&ServiceInfo.FLAG_SINGLE_USER) != 0) { 12589 if (ActivityManager.checkUidPermission( 12590 android.Manifest.permission.INTERACT_ACROSS_USERS, 12591 aInfo.uid) != PackageManager.PERMISSION_GRANTED) { 12592 ComponentName comp = new ComponentName(aInfo.packageName, className); 12593 String msg = "Permission Denial: Component " + comp.flattenToShortString() 12594 + " requests FLAG_SINGLE_USER, but app does not hold " 12595 + android.Manifest.permission.INTERACT_ACROSS_USERS; 12596 Slog.w(TAG, msg); 12597 throw new SecurityException(msg); 12598 } 12599 result = true; 12600 } 12601 } else if (componentProcessName == aInfo.packageName) { 12602 result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0; 12603 } else if ("system".equals(componentProcessName)) { 12604 result = true; 12605 } 12606 if (DEBUG_MU) { 12607 Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo 12608 + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result); 12609 } 12610 return result; 12611 } 12612 12613 public int bindService(IApplicationThread caller, IBinder token, 12614 Intent service, String resolvedType, 12615 IServiceConnection connection, int flags, int userId) { 12616 enforceNotIsolatedCaller("bindService"); 12617 // Refuse possible leaked file descriptors 12618 if (service != null && service.hasFileDescriptors() == true) { 12619 throw new IllegalArgumentException("File descriptors passed in Intent"); 12620 } 12621 12622 synchronized(this) { 12623 return mServices.bindServiceLocked(caller, token, service, resolvedType, 12624 connection, flags, userId); 12625 } 12626 } 12627 12628 public boolean unbindService(IServiceConnection connection) { 12629 synchronized (this) { 12630 return mServices.unbindServiceLocked(connection); 12631 } 12632 } 12633 12634 public void publishService(IBinder token, Intent intent, IBinder service) { 12635 // Refuse possible leaked file descriptors 12636 if (intent != null && intent.hasFileDescriptors() == true) { 12637 throw new IllegalArgumentException("File descriptors passed in Intent"); 12638 } 12639 12640 synchronized(this) { 12641 if (!(token instanceof ServiceRecord)) { 12642 throw new IllegalArgumentException("Invalid service token"); 12643 } 12644 mServices.publishServiceLocked((ServiceRecord)token, intent, service); 12645 } 12646 } 12647 12648 public void unbindFinished(IBinder token, Intent intent, boolean doRebind) { 12649 // Refuse possible leaked file descriptors 12650 if (intent != null && intent.hasFileDescriptors() == true) { 12651 throw new IllegalArgumentException("File descriptors passed in Intent"); 12652 } 12653 12654 synchronized(this) { 12655 mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind); 12656 } 12657 } 12658 12659 public void serviceDoneExecuting(IBinder token, int type, int startId, int res) { 12660 synchronized(this) { 12661 if (!(token instanceof ServiceRecord)) { 12662 throw new IllegalArgumentException("Invalid service token"); 12663 } 12664 mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res); 12665 } 12666 } 12667 12668 // ========================================================= 12669 // BACKUP AND RESTORE 12670 // ========================================================= 12671 12672 // Cause the target app to be launched if necessary and its backup agent 12673 // instantiated. The backup agent will invoke backupAgentCreated() on the 12674 // activity manager to announce its creation. 12675 public boolean bindBackupAgent(ApplicationInfo app, int backupMode) { 12676 if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode); 12677 enforceCallingPermission("android.permission.BACKUP", "bindBackupAgent"); 12678 12679 synchronized(this) { 12680 // !!! TODO: currently no check here that we're already bound 12681 BatteryStatsImpl.Uid.Pkg.Serv ss = null; 12682 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 12683 synchronized (stats) { 12684 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name); 12685 } 12686 12687 // Backup agent is now in use, its package can't be stopped. 12688 try { 12689 AppGlobals.getPackageManager().setPackageStoppedState( 12690 app.packageName, false, UserHandle.getUserId(app.uid)); 12691 } catch (RemoteException e) { 12692 } catch (IllegalArgumentException e) { 12693 Slog.w(TAG, "Failed trying to unstop package " 12694 + app.packageName + ": " + e); 12695 } 12696 12697 BackupRecord r = new BackupRecord(ss, app, backupMode); 12698 ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL) 12699 ? new ComponentName(app.packageName, app.backupAgentName) 12700 : new ComponentName("android", "FullBackupAgent"); 12701 // startProcessLocked() returns existing proc's record if it's already running 12702 ProcessRecord proc = startProcessLocked(app.processName, app, 12703 false, 0, "backup", hostingName, false, false, false); 12704 if (proc == null) { 12705 Slog.e(TAG, "Unable to start backup agent process " + r); 12706 return false; 12707 } 12708 12709 r.app = proc; 12710 mBackupTarget = r; 12711 mBackupAppName = app.packageName; 12712 12713 // Try not to kill the process during backup 12714 updateOomAdjLocked(proc); 12715 12716 // If the process is already attached, schedule the creation of the backup agent now. 12717 // If it is not yet live, this will be done when it attaches to the framework. 12718 if (proc.thread != null) { 12719 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc); 12720 try { 12721 proc.thread.scheduleCreateBackupAgent(app, 12722 compatibilityInfoForPackageLocked(app), backupMode); 12723 } catch (RemoteException e) { 12724 // Will time out on the backup manager side 12725 } 12726 } else { 12727 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach"); 12728 } 12729 // Invariants: at this point, the target app process exists and the application 12730 // is either already running or in the process of coming up. mBackupTarget and 12731 // mBackupAppName describe the app, so that when it binds back to the AM we 12732 // know that it's scheduled for a backup-agent operation. 12733 } 12734 12735 return true; 12736 } 12737 12738 @Override 12739 public void clearPendingBackup() { 12740 if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup"); 12741 enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup"); 12742 12743 synchronized (this) { 12744 mBackupTarget = null; 12745 mBackupAppName = null; 12746 } 12747 } 12748 12749 // A backup agent has just come up 12750 public void backupAgentCreated(String agentPackageName, IBinder agent) { 12751 if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName 12752 + " = " + agent); 12753 12754 synchronized(this) { 12755 if (!agentPackageName.equals(mBackupAppName)) { 12756 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!"); 12757 return; 12758 } 12759 } 12760 12761 long oldIdent = Binder.clearCallingIdentity(); 12762 try { 12763 IBackupManager bm = IBackupManager.Stub.asInterface( 12764 ServiceManager.getService(Context.BACKUP_SERVICE)); 12765 bm.agentConnected(agentPackageName, agent); 12766 } catch (RemoteException e) { 12767 // can't happen; the backup manager service is local 12768 } catch (Exception e) { 12769 Slog.w(TAG, "Exception trying to deliver BackupAgent binding: "); 12770 e.printStackTrace(); 12771 } finally { 12772 Binder.restoreCallingIdentity(oldIdent); 12773 } 12774 } 12775 12776 // done with this agent 12777 public void unbindBackupAgent(ApplicationInfo appInfo) { 12778 if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo); 12779 if (appInfo == null) { 12780 Slog.w(TAG, "unbind backup agent for null app"); 12781 return; 12782 } 12783 12784 synchronized(this) { 12785 try { 12786 if (mBackupAppName == null) { 12787 Slog.w(TAG, "Unbinding backup agent with no active backup"); 12788 return; 12789 } 12790 12791 if (!mBackupAppName.equals(appInfo.packageName)) { 12792 Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target"); 12793 return; 12794 } 12795 12796 // Not backing this app up any more; reset its OOM adjustment 12797 final ProcessRecord proc = mBackupTarget.app; 12798 updateOomAdjLocked(proc); 12799 12800 // If the app crashed during backup, 'thread' will be null here 12801 if (proc.thread != null) { 12802 try { 12803 proc.thread.scheduleDestroyBackupAgent(appInfo, 12804 compatibilityInfoForPackageLocked(appInfo)); 12805 } catch (Exception e) { 12806 Slog.e(TAG, "Exception when unbinding backup agent:"); 12807 e.printStackTrace(); 12808 } 12809 } 12810 } finally { 12811 mBackupTarget = null; 12812 mBackupAppName = null; 12813 } 12814 } 12815 } 12816 // ========================================================= 12817 // BROADCASTS 12818 // ========================================================= 12819 12820 private final List getStickiesLocked(String action, IntentFilter filter, 12821 List cur, int userId) { 12822 final ContentResolver resolver = mContext.getContentResolver(); 12823 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 12824 if (stickies == null) { 12825 return cur; 12826 } 12827 final ArrayList<Intent> list = stickies.get(action); 12828 if (list == null) { 12829 return cur; 12830 } 12831 int N = list.size(); 12832 for (int i=0; i<N; i++) { 12833 Intent intent = list.get(i); 12834 if (filter.match(resolver, intent, true, TAG) >= 0) { 12835 if (cur == null) { 12836 cur = new ArrayList<Intent>(); 12837 } 12838 cur.add(intent); 12839 } 12840 } 12841 return cur; 12842 } 12843 12844 boolean isPendingBroadcastProcessLocked(int pid) { 12845 return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid) 12846 || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid); 12847 } 12848 12849 void skipPendingBroadcastLocked(int pid) { 12850 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 12851 for (BroadcastQueue queue : mBroadcastQueues) { 12852 queue.skipPendingBroadcastLocked(pid); 12853 } 12854 } 12855 12856 // The app just attached; send any pending broadcasts that it should receive 12857 boolean sendPendingBroadcastsLocked(ProcessRecord app) { 12858 boolean didSomething = false; 12859 for (BroadcastQueue queue : mBroadcastQueues) { 12860 didSomething |= queue.sendPendingBroadcastsLocked(app); 12861 } 12862 return didSomething; 12863 } 12864 12865 public Intent registerReceiver(IApplicationThread caller, String callerPackage, 12866 IIntentReceiver receiver, IntentFilter filter, String permission, int userId) { 12867 enforceNotIsolatedCaller("registerReceiver"); 12868 int callingUid; 12869 int callingPid; 12870 synchronized(this) { 12871 ProcessRecord callerApp = null; 12872 if (caller != null) { 12873 callerApp = getRecordForAppLocked(caller); 12874 if (callerApp == null) { 12875 throw new SecurityException( 12876 "Unable to find app for caller " + caller 12877 + " (pid=" + Binder.getCallingPid() 12878 + ") when registering receiver " + receiver); 12879 } 12880 if (callerApp.info.uid != Process.SYSTEM_UID && 12881 !callerApp.pkgList.containsKey(callerPackage) && 12882 !"android".equals(callerPackage)) { 12883 throw new SecurityException("Given caller package " + callerPackage 12884 + " is not running in process " + callerApp); 12885 } 12886 callingUid = callerApp.info.uid; 12887 callingPid = callerApp.pid; 12888 } else { 12889 callerPackage = null; 12890 callingUid = Binder.getCallingUid(); 12891 callingPid = Binder.getCallingPid(); 12892 } 12893 12894 userId = this.handleIncomingUser(callingPid, callingUid, userId, 12895 true, true, "registerReceiver", callerPackage); 12896 12897 List allSticky = null; 12898 12899 // Look for any matching sticky broadcasts... 12900 Iterator actions = filter.actionsIterator(); 12901 if (actions != null) { 12902 while (actions.hasNext()) { 12903 String action = (String)actions.next(); 12904 allSticky = getStickiesLocked(action, filter, allSticky, 12905 UserHandle.USER_ALL); 12906 allSticky = getStickiesLocked(action, filter, allSticky, 12907 UserHandle.getUserId(callingUid)); 12908 } 12909 } else { 12910 allSticky = getStickiesLocked(null, filter, allSticky, 12911 UserHandle.USER_ALL); 12912 allSticky = getStickiesLocked(null, filter, allSticky, 12913 UserHandle.getUserId(callingUid)); 12914 } 12915 12916 // The first sticky in the list is returned directly back to 12917 // the client. 12918 Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null; 12919 12920 if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter 12921 + ": " + sticky); 12922 12923 if (receiver == null) { 12924 return sticky; 12925 } 12926 12927 ReceiverList rl 12928 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder()); 12929 if (rl == null) { 12930 rl = new ReceiverList(this, callerApp, callingPid, callingUid, 12931 userId, receiver); 12932 if (rl.app != null) { 12933 rl.app.receivers.add(rl); 12934 } else { 12935 try { 12936 receiver.asBinder().linkToDeath(rl, 0); 12937 } catch (RemoteException e) { 12938 return sticky; 12939 } 12940 rl.linkedToDeath = true; 12941 } 12942 mRegisteredReceivers.put(receiver.asBinder(), rl); 12943 } else if (rl.uid != callingUid) { 12944 throw new IllegalArgumentException( 12945 "Receiver requested to register for uid " + callingUid 12946 + " was previously registered for uid " + rl.uid); 12947 } else if (rl.pid != callingPid) { 12948 throw new IllegalArgumentException( 12949 "Receiver requested to register for pid " + callingPid 12950 + " was previously registered for pid " + rl.pid); 12951 } else if (rl.userId != userId) { 12952 throw new IllegalArgumentException( 12953 "Receiver requested to register for user " + userId 12954 + " was previously registered for user " + rl.userId); 12955 } 12956 BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage, 12957 permission, callingUid, userId); 12958 rl.add(bf); 12959 if (!bf.debugCheck()) { 12960 Slog.w(TAG, "==> For Dynamic broadast"); 12961 } 12962 mReceiverResolver.addFilter(bf); 12963 12964 // Enqueue broadcasts for all existing stickies that match 12965 // this filter. 12966 if (allSticky != null) { 12967 ArrayList receivers = new ArrayList(); 12968 receivers.add(bf); 12969 12970 int N = allSticky.size(); 12971 for (int i=0; i<N; i++) { 12972 Intent intent = (Intent)allSticky.get(i); 12973 BroadcastQueue queue = broadcastQueueForIntent(intent); 12974 BroadcastRecord r = new BroadcastRecord(queue, intent, null, 12975 null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0, 12976 null, null, false, true, true, -1); 12977 queue.enqueueParallelBroadcastLocked(r); 12978 queue.scheduleBroadcastsLocked(); 12979 } 12980 } 12981 12982 return sticky; 12983 } 12984 } 12985 12986 public void unregisterReceiver(IIntentReceiver receiver) { 12987 if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver); 12988 12989 final long origId = Binder.clearCallingIdentity(); 12990 try { 12991 boolean doTrim = false; 12992 12993 synchronized(this) { 12994 ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder()); 12995 if (rl != null) { 12996 if (rl.curBroadcast != null) { 12997 BroadcastRecord r = rl.curBroadcast; 12998 final boolean doNext = finishReceiverLocked( 12999 receiver.asBinder(), r.resultCode, r.resultData, 13000 r.resultExtras, r.resultAbort); 13001 if (doNext) { 13002 doTrim = true; 13003 r.queue.processNextBroadcast(false); 13004 } 13005 } 13006 13007 if (rl.app != null) { 13008 rl.app.receivers.remove(rl); 13009 } 13010 removeReceiverLocked(rl); 13011 if (rl.linkedToDeath) { 13012 rl.linkedToDeath = false; 13013 rl.receiver.asBinder().unlinkToDeath(rl, 0); 13014 } 13015 } 13016 } 13017 13018 // If we actually concluded any broadcasts, we might now be able 13019 // to trim the recipients' apps from our working set 13020 if (doTrim) { 13021 trimApplications(); 13022 return; 13023 } 13024 13025 } finally { 13026 Binder.restoreCallingIdentity(origId); 13027 } 13028 } 13029 13030 void removeReceiverLocked(ReceiverList rl) { 13031 mRegisteredReceivers.remove(rl.receiver.asBinder()); 13032 int N = rl.size(); 13033 for (int i=0; i<N; i++) { 13034 mReceiverResolver.removeFilter(rl.get(i)); 13035 } 13036 } 13037 13038 private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) { 13039 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 13040 ProcessRecord r = mLruProcesses.get(i); 13041 if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) { 13042 try { 13043 r.thread.dispatchPackageBroadcast(cmd, packages); 13044 } catch (RemoteException ex) { 13045 } 13046 } 13047 } 13048 } 13049 13050 private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType, 13051 int[] users) { 13052 List<ResolveInfo> receivers = null; 13053 try { 13054 HashSet<ComponentName> singleUserReceivers = null; 13055 boolean scannedFirstReceivers = false; 13056 for (int user : users) { 13057 List<ResolveInfo> newReceivers = AppGlobals.getPackageManager() 13058 .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user); 13059 if (user != 0 && newReceivers != null) { 13060 // If this is not the primary user, we need to check for 13061 // any receivers that should be filtered out. 13062 for (int i=0; i<newReceivers.size(); i++) { 13063 ResolveInfo ri = newReceivers.get(i); 13064 if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) { 13065 newReceivers.remove(i); 13066 i--; 13067 } 13068 } 13069 } 13070 if (newReceivers != null && newReceivers.size() == 0) { 13071 newReceivers = null; 13072 } 13073 if (receivers == null) { 13074 receivers = newReceivers; 13075 } else if (newReceivers != null) { 13076 // We need to concatenate the additional receivers 13077 // found with what we have do far. This would be easy, 13078 // but we also need to de-dup any receivers that are 13079 // singleUser. 13080 if (!scannedFirstReceivers) { 13081 // Collect any single user receivers we had already retrieved. 13082 scannedFirstReceivers = true; 13083 for (int i=0; i<receivers.size(); i++) { 13084 ResolveInfo ri = receivers.get(i); 13085 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 13086 ComponentName cn = new ComponentName( 13087 ri.activityInfo.packageName, ri.activityInfo.name); 13088 if (singleUserReceivers == null) { 13089 singleUserReceivers = new HashSet<ComponentName>(); 13090 } 13091 singleUserReceivers.add(cn); 13092 } 13093 } 13094 } 13095 // Add the new results to the existing results, tracking 13096 // and de-dupping single user receivers. 13097 for (int i=0; i<newReceivers.size(); i++) { 13098 ResolveInfo ri = newReceivers.get(i); 13099 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 13100 ComponentName cn = new ComponentName( 13101 ri.activityInfo.packageName, ri.activityInfo.name); 13102 if (singleUserReceivers == null) { 13103 singleUserReceivers = new HashSet<ComponentName>(); 13104 } 13105 if (!singleUserReceivers.contains(cn)) { 13106 singleUserReceivers.add(cn); 13107 receivers.add(ri); 13108 } 13109 } else { 13110 receivers.add(ri); 13111 } 13112 } 13113 } 13114 } 13115 } catch (RemoteException ex) { 13116 // pm is in same process, this will never happen. 13117 } 13118 return receivers; 13119 } 13120 13121 private final int broadcastIntentLocked(ProcessRecord callerApp, 13122 String callerPackage, Intent intent, String resolvedType, 13123 IIntentReceiver resultTo, int resultCode, String resultData, 13124 Bundle map, String requiredPermission, int appOp, 13125 boolean ordered, boolean sticky, int callingPid, int callingUid, 13126 int userId) { 13127 intent = new Intent(intent); 13128 13129 // By default broadcasts do not go to stopped apps. 13130 intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES); 13131 13132 if (DEBUG_BROADCAST_LIGHT) Slog.v( 13133 TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent 13134 + " ordered=" + ordered + " userid=" + userId); 13135 if ((resultTo != null) && !ordered) { 13136 Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!"); 13137 } 13138 13139 userId = handleIncomingUser(callingPid, callingUid, userId, 13140 true, false, "broadcast", callerPackage); 13141 13142 // Make sure that the user who is receiving this broadcast is started. 13143 // If not, we will just skip it. 13144 if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) { 13145 if (callingUid != Process.SYSTEM_UID || (intent.getFlags() 13146 & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) { 13147 Slog.w(TAG, "Skipping broadcast of " + intent 13148 + ": user " + userId + " is stopped"); 13149 return ActivityManager.BROADCAST_SUCCESS; 13150 } 13151 } 13152 13153 /* 13154 * Prevent non-system code (defined here to be non-persistent 13155 * processes) from sending protected broadcasts. 13156 */ 13157 int callingAppId = UserHandle.getAppId(callingUid); 13158 if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID 13159 || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID || 13160 callingUid == 0) { 13161 // Always okay. 13162 } else if (callerApp == null || !callerApp.persistent) { 13163 try { 13164 if (AppGlobals.getPackageManager().isProtectedBroadcast( 13165 intent.getAction())) { 13166 String msg = "Permission Denial: not allowed to send broadcast " 13167 + intent.getAction() + " from pid=" 13168 + callingPid + ", uid=" + callingUid; 13169 Slog.w(TAG, msg); 13170 throw new SecurityException(msg); 13171 } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) { 13172 // Special case for compatibility: we don't want apps to send this, 13173 // but historically it has not been protected and apps may be using it 13174 // to poke their own app widget. So, instead of making it protected, 13175 // just limit it to the caller. 13176 if (callerApp == null) { 13177 String msg = "Permission Denial: not allowed to send broadcast " 13178 + intent.getAction() + " from unknown caller."; 13179 Slog.w(TAG, msg); 13180 throw new SecurityException(msg); 13181 } else if (intent.getComponent() != null) { 13182 // They are good enough to send to an explicit component... verify 13183 // it is being sent to the calling app. 13184 if (!intent.getComponent().getPackageName().equals( 13185 callerApp.info.packageName)) { 13186 String msg = "Permission Denial: not allowed to send broadcast " 13187 + intent.getAction() + " to " 13188 + intent.getComponent().getPackageName() + " from " 13189 + callerApp.info.packageName; 13190 Slog.w(TAG, msg); 13191 throw new SecurityException(msg); 13192 } 13193 } else { 13194 // Limit broadcast to their own package. 13195 intent.setPackage(callerApp.info.packageName); 13196 } 13197 } 13198 } catch (RemoteException e) { 13199 Slog.w(TAG, "Remote exception", e); 13200 return ActivityManager.BROADCAST_SUCCESS; 13201 } 13202 } 13203 13204 // Handle special intents: if this broadcast is from the package 13205 // manager about a package being removed, we need to remove all of 13206 // its activities from the history stack. 13207 final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals( 13208 intent.getAction()); 13209 if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction()) 13210 || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction()) 13211 || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction()) 13212 || uidRemoved) { 13213 if (checkComponentPermission( 13214 android.Manifest.permission.BROADCAST_PACKAGE_REMOVED, 13215 callingPid, callingUid, -1, true) 13216 == PackageManager.PERMISSION_GRANTED) { 13217 if (uidRemoved) { 13218 final Bundle intentExtras = intent.getExtras(); 13219 final int uid = intentExtras != null 13220 ? intentExtras.getInt(Intent.EXTRA_UID) : -1; 13221 if (uid >= 0) { 13222 BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics(); 13223 synchronized (bs) { 13224 bs.removeUidStatsLocked(uid); 13225 } 13226 mAppOpsService.uidRemoved(uid); 13227 } 13228 } else { 13229 // If resources are unavailable just force stop all 13230 // those packages and flush the attribute cache as well. 13231 if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) { 13232 String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 13233 if (list != null && (list.length > 0)) { 13234 for (String pkg : list) { 13235 forceStopPackageLocked(pkg, -1, false, true, true, false, userId, 13236 "storage unmount"); 13237 } 13238 sendPackageBroadcastLocked( 13239 IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId); 13240 } 13241 } else { 13242 Uri data = intent.getData(); 13243 String ssp; 13244 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 13245 boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals( 13246 intent.getAction()); 13247 if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) { 13248 forceStopPackageLocked(ssp, UserHandle.getAppId( 13249 intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true, 13250 false, userId, removed ? "pkg removed" : "pkg changed"); 13251 } 13252 if (removed) { 13253 sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED, 13254 new String[] {ssp}, userId); 13255 if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) { 13256 mAppOpsService.packageRemoved( 13257 intent.getIntExtra(Intent.EXTRA_UID, -1), ssp); 13258 13259 // Remove all permissions granted from/to this package 13260 removeUriPermissionsForPackageLocked(ssp, userId, true); 13261 } 13262 } 13263 } 13264 } 13265 } 13266 } else { 13267 String msg = "Permission Denial: " + intent.getAction() 13268 + " broadcast from " + callerPackage + " (pid=" + callingPid 13269 + ", uid=" + callingUid + ")" 13270 + " requires " 13271 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED; 13272 Slog.w(TAG, msg); 13273 throw new SecurityException(msg); 13274 } 13275 13276 // Special case for adding a package: by default turn on compatibility 13277 // mode. 13278 } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) { 13279 Uri data = intent.getData(); 13280 String ssp; 13281 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 13282 mCompatModePackages.handlePackageAddedLocked(ssp, 13283 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)); 13284 } 13285 } 13286 13287 /* 13288 * If this is the time zone changed action, queue up a message that will reset the timezone 13289 * of all currently running processes. This message will get queued up before the broadcast 13290 * happens. 13291 */ 13292 if (intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) { 13293 mHandler.sendEmptyMessage(UPDATE_TIME_ZONE); 13294 } 13295 13296 if (intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) { 13297 mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG); 13298 } 13299 13300 if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) { 13301 ProxyProperties proxy = intent.getParcelableExtra("proxy"); 13302 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy)); 13303 } 13304 13305 // Add to the sticky list if requested. 13306 if (sticky) { 13307 if (checkPermission(android.Manifest.permission.BROADCAST_STICKY, 13308 callingPid, callingUid) 13309 != PackageManager.PERMISSION_GRANTED) { 13310 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid=" 13311 + callingPid + ", uid=" + callingUid 13312 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 13313 Slog.w(TAG, msg); 13314 throw new SecurityException(msg); 13315 } 13316 if (requiredPermission != null) { 13317 Slog.w(TAG, "Can't broadcast sticky intent " + intent 13318 + " and enforce permission " + requiredPermission); 13319 return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION; 13320 } 13321 if (intent.getComponent() != null) { 13322 throw new SecurityException( 13323 "Sticky broadcasts can't target a specific component"); 13324 } 13325 // We use userId directly here, since the "all" target is maintained 13326 // as a separate set of sticky broadcasts. 13327 if (userId != UserHandle.USER_ALL) { 13328 // But first, if this is not a broadcast to all users, then 13329 // make sure it doesn't conflict with an existing broadcast to 13330 // all users. 13331 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get( 13332 UserHandle.USER_ALL); 13333 if (stickies != null) { 13334 ArrayList<Intent> list = stickies.get(intent.getAction()); 13335 if (list != null) { 13336 int N = list.size(); 13337 int i; 13338 for (i=0; i<N; i++) { 13339 if (intent.filterEquals(list.get(i))) { 13340 throw new IllegalArgumentException( 13341 "Sticky broadcast " + intent + " for user " 13342 + userId + " conflicts with existing global broadcast"); 13343 } 13344 } 13345 } 13346 } 13347 } 13348 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 13349 if (stickies == null) { 13350 stickies = new ArrayMap<String, ArrayList<Intent>>(); 13351 mStickyBroadcasts.put(userId, stickies); 13352 } 13353 ArrayList<Intent> list = stickies.get(intent.getAction()); 13354 if (list == null) { 13355 list = new ArrayList<Intent>(); 13356 stickies.put(intent.getAction(), list); 13357 } 13358 int N = list.size(); 13359 int i; 13360 for (i=0; i<N; i++) { 13361 if (intent.filterEquals(list.get(i))) { 13362 // This sticky already exists, replace it. 13363 list.set(i, new Intent(intent)); 13364 break; 13365 } 13366 } 13367 if (i >= N) { 13368 list.add(new Intent(intent)); 13369 } 13370 } 13371 13372 int[] users; 13373 if (userId == UserHandle.USER_ALL) { 13374 // Caller wants broadcast to go to all started users. 13375 users = mStartedUserArray; 13376 } else { 13377 // Caller wants broadcast to go to one specific user. 13378 users = new int[] {userId}; 13379 } 13380 13381 // Figure out who all will receive this broadcast. 13382 List receivers = null; 13383 List<BroadcastFilter> registeredReceivers = null; 13384 // Need to resolve the intent to interested receivers... 13385 if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) 13386 == 0) { 13387 receivers = collectReceiverComponents(intent, resolvedType, users); 13388 } 13389 if (intent.getComponent() == null) { 13390 registeredReceivers = mReceiverResolver.queryIntent(intent, 13391 resolvedType, false, userId); 13392 } 13393 13394 final boolean replacePending = 13395 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0; 13396 13397 if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction() 13398 + " replacePending=" + replacePending); 13399 13400 int NR = registeredReceivers != null ? registeredReceivers.size() : 0; 13401 if (!ordered && NR > 0) { 13402 // If we are not serializing this broadcast, then send the 13403 // registered receivers separately so they don't wait for the 13404 // components to be launched. 13405 final BroadcastQueue queue = broadcastQueueForIntent(intent); 13406 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 13407 callerPackage, callingPid, callingUid, resolvedType, requiredPermission, 13408 appOp, registeredReceivers, resultTo, resultCode, resultData, map, 13409 ordered, sticky, false, userId); 13410 if (DEBUG_BROADCAST) Slog.v( 13411 TAG, "Enqueueing parallel broadcast " + r); 13412 final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r); 13413 if (!replaced) { 13414 queue.enqueueParallelBroadcastLocked(r); 13415 queue.scheduleBroadcastsLocked(); 13416 } 13417 registeredReceivers = null; 13418 NR = 0; 13419 } 13420 13421 // Merge into one list. 13422 int ir = 0; 13423 if (receivers != null) { 13424 // A special case for PACKAGE_ADDED: do not allow the package 13425 // being added to see this broadcast. This prevents them from 13426 // using this as a back door to get run as soon as they are 13427 // installed. Maybe in the future we want to have a special install 13428 // broadcast or such for apps, but we'd like to deliberately make 13429 // this decision. 13430 String skipPackages[] = null; 13431 if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction()) 13432 || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction()) 13433 || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) { 13434 Uri data = intent.getData(); 13435 if (data != null) { 13436 String pkgName = data.getSchemeSpecificPart(); 13437 if (pkgName != null) { 13438 skipPackages = new String[] { pkgName }; 13439 } 13440 } 13441 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) { 13442 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 13443 } 13444 if (skipPackages != null && (skipPackages.length > 0)) { 13445 for (String skipPackage : skipPackages) { 13446 if (skipPackage != null) { 13447 int NT = receivers.size(); 13448 for (int it=0; it<NT; it++) { 13449 ResolveInfo curt = (ResolveInfo)receivers.get(it); 13450 if (curt.activityInfo.packageName.equals(skipPackage)) { 13451 receivers.remove(it); 13452 it--; 13453 NT--; 13454 } 13455 } 13456 } 13457 } 13458 } 13459 13460 int NT = receivers != null ? receivers.size() : 0; 13461 int it = 0; 13462 ResolveInfo curt = null; 13463 BroadcastFilter curr = null; 13464 while (it < NT && ir < NR) { 13465 if (curt == null) { 13466 curt = (ResolveInfo)receivers.get(it); 13467 } 13468 if (curr == null) { 13469 curr = registeredReceivers.get(ir); 13470 } 13471 if (curr.getPriority() >= curt.priority) { 13472 // Insert this broadcast record into the final list. 13473 receivers.add(it, curr); 13474 ir++; 13475 curr = null; 13476 it++; 13477 NT++; 13478 } else { 13479 // Skip to the next ResolveInfo in the final list. 13480 it++; 13481 curt = null; 13482 } 13483 } 13484 } 13485 while (ir < NR) { 13486 if (receivers == null) { 13487 receivers = new ArrayList(); 13488 } 13489 receivers.add(registeredReceivers.get(ir)); 13490 ir++; 13491 } 13492 13493 if ((receivers != null && receivers.size() > 0) 13494 || resultTo != null) { 13495 BroadcastQueue queue = broadcastQueueForIntent(intent); 13496 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 13497 callerPackage, callingPid, callingUid, resolvedType, 13498 requiredPermission, appOp, receivers, resultTo, resultCode, 13499 resultData, map, ordered, sticky, false, userId); 13500 if (DEBUG_BROADCAST) Slog.v( 13501 TAG, "Enqueueing ordered broadcast " + r 13502 + ": prev had " + queue.mOrderedBroadcasts.size()); 13503 if (DEBUG_BROADCAST) { 13504 int seq = r.intent.getIntExtra("seq", -1); 13505 Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq); 13506 } 13507 boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r); 13508 if (!replaced) { 13509 queue.enqueueOrderedBroadcastLocked(r); 13510 queue.scheduleBroadcastsLocked(); 13511 } 13512 } 13513 13514 return ActivityManager.BROADCAST_SUCCESS; 13515 } 13516 13517 final Intent verifyBroadcastLocked(Intent intent) { 13518 // Refuse possible leaked file descriptors 13519 if (intent != null && intent.hasFileDescriptors() == true) { 13520 throw new IllegalArgumentException("File descriptors passed in Intent"); 13521 } 13522 13523 int flags = intent.getFlags(); 13524 13525 if (!mProcessesReady) { 13526 // if the caller really truly claims to know what they're doing, go 13527 // ahead and allow the broadcast without launching any receivers 13528 if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) { 13529 intent = new Intent(intent); 13530 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 13531 } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) { 13532 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent 13533 + " before boot completion"); 13534 throw new IllegalStateException("Cannot broadcast before boot completed"); 13535 } 13536 } 13537 13538 if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 13539 throw new IllegalArgumentException( 13540 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 13541 } 13542 13543 return intent; 13544 } 13545 13546 public final int broadcastIntent(IApplicationThread caller, 13547 Intent intent, String resolvedType, IIntentReceiver resultTo, 13548 int resultCode, String resultData, Bundle map, 13549 String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) { 13550 enforceNotIsolatedCaller("broadcastIntent"); 13551 synchronized(this) { 13552 intent = verifyBroadcastLocked(intent); 13553 13554 final ProcessRecord callerApp = getRecordForAppLocked(caller); 13555 final int callingPid = Binder.getCallingPid(); 13556 final int callingUid = Binder.getCallingUid(); 13557 final long origId = Binder.clearCallingIdentity(); 13558 int res = broadcastIntentLocked(callerApp, 13559 callerApp != null ? callerApp.info.packageName : null, 13560 intent, resolvedType, resultTo, 13561 resultCode, resultData, map, requiredPermission, appOp, serialized, sticky, 13562 callingPid, callingUid, userId); 13563 Binder.restoreCallingIdentity(origId); 13564 return res; 13565 } 13566 } 13567 13568 int broadcastIntentInPackage(String packageName, int uid, 13569 Intent intent, String resolvedType, IIntentReceiver resultTo, 13570 int resultCode, String resultData, Bundle map, 13571 String requiredPermission, boolean serialized, boolean sticky, int userId) { 13572 synchronized(this) { 13573 intent = verifyBroadcastLocked(intent); 13574 13575 final long origId = Binder.clearCallingIdentity(); 13576 int res = broadcastIntentLocked(null, packageName, intent, resolvedType, 13577 resultTo, resultCode, resultData, map, requiredPermission, 13578 AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId); 13579 Binder.restoreCallingIdentity(origId); 13580 return res; 13581 } 13582 } 13583 13584 public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) { 13585 // Refuse possible leaked file descriptors 13586 if (intent != null && intent.hasFileDescriptors() == true) { 13587 throw new IllegalArgumentException("File descriptors passed in Intent"); 13588 } 13589 13590 userId = handleIncomingUser(Binder.getCallingPid(), 13591 Binder.getCallingUid(), userId, true, false, "removeStickyBroadcast", null); 13592 13593 synchronized(this) { 13594 if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY) 13595 != PackageManager.PERMISSION_GRANTED) { 13596 String msg = "Permission Denial: unbroadcastIntent() from pid=" 13597 + Binder.getCallingPid() 13598 + ", uid=" + Binder.getCallingUid() 13599 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 13600 Slog.w(TAG, msg); 13601 throw new SecurityException(msg); 13602 } 13603 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 13604 if (stickies != null) { 13605 ArrayList<Intent> list = stickies.get(intent.getAction()); 13606 if (list != null) { 13607 int N = list.size(); 13608 int i; 13609 for (i=0; i<N; i++) { 13610 if (intent.filterEquals(list.get(i))) { 13611 list.remove(i); 13612 break; 13613 } 13614 } 13615 if (list.size() <= 0) { 13616 stickies.remove(intent.getAction()); 13617 } 13618 } 13619 if (stickies.size() <= 0) { 13620 mStickyBroadcasts.remove(userId); 13621 } 13622 } 13623 } 13624 } 13625 13626 private final boolean finishReceiverLocked(IBinder receiver, int resultCode, 13627 String resultData, Bundle resultExtras, boolean resultAbort) { 13628 final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver); 13629 if (r == null) { 13630 Slog.w(TAG, "finishReceiver called but not found on queue"); 13631 return false; 13632 } 13633 13634 return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false); 13635 } 13636 13637 void backgroundServicesFinishedLocked(int userId) { 13638 for (BroadcastQueue queue : mBroadcastQueues) { 13639 queue.backgroundServicesFinishedLocked(userId); 13640 } 13641 } 13642 13643 public void finishReceiver(IBinder who, int resultCode, String resultData, 13644 Bundle resultExtras, boolean resultAbort) { 13645 if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who); 13646 13647 // Refuse possible leaked file descriptors 13648 if (resultExtras != null && resultExtras.hasFileDescriptors()) { 13649 throw new IllegalArgumentException("File descriptors passed in Bundle"); 13650 } 13651 13652 final long origId = Binder.clearCallingIdentity(); 13653 try { 13654 boolean doNext = false; 13655 BroadcastRecord r; 13656 13657 synchronized(this) { 13658 r = broadcastRecordForReceiverLocked(who); 13659 if (r != null) { 13660 doNext = r.queue.finishReceiverLocked(r, resultCode, 13661 resultData, resultExtras, resultAbort, true); 13662 } 13663 } 13664 13665 if (doNext) { 13666 r.queue.processNextBroadcast(false); 13667 } 13668 trimApplications(); 13669 } finally { 13670 Binder.restoreCallingIdentity(origId); 13671 } 13672 } 13673 13674 // ========================================================= 13675 // INSTRUMENTATION 13676 // ========================================================= 13677 13678 public boolean startInstrumentation(ComponentName className, 13679 String profileFile, int flags, Bundle arguments, 13680 IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection, 13681 int userId) { 13682 enforceNotIsolatedCaller("startInstrumentation"); 13683 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 13684 userId, false, true, "startInstrumentation", null); 13685 // Refuse possible leaked file descriptors 13686 if (arguments != null && arguments.hasFileDescriptors()) { 13687 throw new IllegalArgumentException("File descriptors passed in Bundle"); 13688 } 13689 13690 synchronized(this) { 13691 InstrumentationInfo ii = null; 13692 ApplicationInfo ai = null; 13693 try { 13694 ii = mContext.getPackageManager().getInstrumentationInfo( 13695 className, STOCK_PM_FLAGS); 13696 ai = AppGlobals.getPackageManager().getApplicationInfo( 13697 ii.targetPackage, STOCK_PM_FLAGS, userId); 13698 } catch (PackageManager.NameNotFoundException e) { 13699 } catch (RemoteException e) { 13700 } 13701 if (ii == null) { 13702 reportStartInstrumentationFailure(watcher, className, 13703 "Unable to find instrumentation info for: " + className); 13704 return false; 13705 } 13706 if (ai == null) { 13707 reportStartInstrumentationFailure(watcher, className, 13708 "Unable to find instrumentation target package: " + ii.targetPackage); 13709 return false; 13710 } 13711 13712 int match = mContext.getPackageManager().checkSignatures( 13713 ii.targetPackage, ii.packageName); 13714 if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) { 13715 String msg = "Permission Denial: starting instrumentation " 13716 + className + " from pid=" 13717 + Binder.getCallingPid() 13718 + ", uid=" + Binder.getCallingPid() 13719 + " not allowed because package " + ii.packageName 13720 + " does not have a signature matching the target " 13721 + ii.targetPackage; 13722 reportStartInstrumentationFailure(watcher, className, msg); 13723 throw new SecurityException(msg); 13724 } 13725 13726 final long origId = Binder.clearCallingIdentity(); 13727 // Instrumentation can kill and relaunch even persistent processes 13728 forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, userId, 13729 "start instr"); 13730 ProcessRecord app = addAppLocked(ai, false); 13731 app.instrumentationClass = className; 13732 app.instrumentationInfo = ai; 13733 app.instrumentationProfileFile = profileFile; 13734 app.instrumentationArguments = arguments; 13735 app.instrumentationWatcher = watcher; 13736 app.instrumentationUiAutomationConnection = uiAutomationConnection; 13737 app.instrumentationResultClass = className; 13738 Binder.restoreCallingIdentity(origId); 13739 } 13740 13741 return true; 13742 } 13743 13744 /** 13745 * Report errors that occur while attempting to start Instrumentation. Always writes the 13746 * error to the logs, but if somebody is watching, send the report there too. This enables 13747 * the "am" command to report errors with more information. 13748 * 13749 * @param watcher The IInstrumentationWatcher. Null if there isn't one. 13750 * @param cn The component name of the instrumentation. 13751 * @param report The error report. 13752 */ 13753 private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher, 13754 ComponentName cn, String report) { 13755 Slog.w(TAG, report); 13756 try { 13757 if (watcher != null) { 13758 Bundle results = new Bundle(); 13759 results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService"); 13760 results.putString("Error", report); 13761 watcher.instrumentationStatus(cn, -1, results); 13762 } 13763 } catch (RemoteException e) { 13764 Slog.w(TAG, e); 13765 } 13766 } 13767 13768 void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) { 13769 if (app.instrumentationWatcher != null) { 13770 try { 13771 // NOTE: IInstrumentationWatcher *must* be oneway here 13772 app.instrumentationWatcher.instrumentationFinished( 13773 app.instrumentationClass, 13774 resultCode, 13775 results); 13776 } catch (RemoteException e) { 13777 } 13778 } 13779 if (app.instrumentationUiAutomationConnection != null) { 13780 try { 13781 app.instrumentationUiAutomationConnection.shutdown(); 13782 } catch (RemoteException re) { 13783 /* ignore */ 13784 } 13785 // Only a UiAutomation can set this flag and now that 13786 // it is finished we make sure it is reset to its default. 13787 mUserIsMonkey = false; 13788 } 13789 app.instrumentationWatcher = null; 13790 app.instrumentationUiAutomationConnection = null; 13791 app.instrumentationClass = null; 13792 app.instrumentationInfo = null; 13793 app.instrumentationProfileFile = null; 13794 app.instrumentationArguments = null; 13795 13796 forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, app.userId, 13797 "finished inst"); 13798 } 13799 13800 public void finishInstrumentation(IApplicationThread target, 13801 int resultCode, Bundle results) { 13802 int userId = UserHandle.getCallingUserId(); 13803 // Refuse possible leaked file descriptors 13804 if (results != null && results.hasFileDescriptors()) { 13805 throw new IllegalArgumentException("File descriptors passed in Intent"); 13806 } 13807 13808 synchronized(this) { 13809 ProcessRecord app = getRecordForAppLocked(target); 13810 if (app == null) { 13811 Slog.w(TAG, "finishInstrumentation: no app for " + target); 13812 return; 13813 } 13814 final long origId = Binder.clearCallingIdentity(); 13815 finishInstrumentationLocked(app, resultCode, results); 13816 Binder.restoreCallingIdentity(origId); 13817 } 13818 } 13819 13820 // ========================================================= 13821 // CONFIGURATION 13822 // ========================================================= 13823 13824 public ConfigurationInfo getDeviceConfigurationInfo() { 13825 ConfigurationInfo config = new ConfigurationInfo(); 13826 synchronized (this) { 13827 config.reqTouchScreen = mConfiguration.touchscreen; 13828 config.reqKeyboardType = mConfiguration.keyboard; 13829 config.reqNavigation = mConfiguration.navigation; 13830 if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD 13831 || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) { 13832 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV; 13833 } 13834 if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED 13835 && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) { 13836 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD; 13837 } 13838 config.reqGlEsVersion = GL_ES_VERSION; 13839 } 13840 return config; 13841 } 13842 13843 ActivityStack getFocusedStack() { 13844 return mStackSupervisor.getFocusedStack(); 13845 } 13846 13847 public Configuration getConfiguration() { 13848 Configuration ci; 13849 synchronized(this) { 13850 ci = new Configuration(mConfiguration); 13851 } 13852 return ci; 13853 } 13854 13855 public void updatePersistentConfiguration(Configuration values) { 13856 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 13857 "updateConfiguration()"); 13858 enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS, 13859 "updateConfiguration()"); 13860 if (values == null) { 13861 throw new NullPointerException("Configuration must not be null"); 13862 } 13863 13864 synchronized(this) { 13865 final long origId = Binder.clearCallingIdentity(); 13866 updateConfigurationLocked(values, null, true, false); 13867 Binder.restoreCallingIdentity(origId); 13868 } 13869 } 13870 13871 public void updateConfiguration(Configuration values) { 13872 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 13873 "updateConfiguration()"); 13874 13875 synchronized(this) { 13876 if (values == null && mWindowManager != null) { 13877 // sentinel: fetch the current configuration from the window manager 13878 values = mWindowManager.computeNewConfiguration(); 13879 } 13880 13881 if (mWindowManager != null) { 13882 mProcessList.applyDisplaySize(mWindowManager); 13883 } 13884 13885 final long origId = Binder.clearCallingIdentity(); 13886 if (values != null) { 13887 Settings.System.clearConfiguration(values); 13888 } 13889 updateConfigurationLocked(values, null, false, false); 13890 Binder.restoreCallingIdentity(origId); 13891 } 13892 } 13893 13894 /** 13895 * Do either or both things: (1) change the current configuration, and (2) 13896 * make sure the given activity is running with the (now) current 13897 * configuration. Returns true if the activity has been left running, or 13898 * false if <var>starting</var> is being destroyed to match the new 13899 * configuration. 13900 * @param persistent TODO 13901 */ 13902 boolean updateConfigurationLocked(Configuration values, 13903 ActivityRecord starting, boolean persistent, boolean initLocale) { 13904 int changes = 0; 13905 13906 if (values != null) { 13907 Configuration newConfig = new Configuration(mConfiguration); 13908 changes = newConfig.updateFrom(values); 13909 if (changes != 0) { 13910 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) { 13911 Slog.i(TAG, "Updating configuration to: " + values); 13912 } 13913 13914 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes); 13915 13916 if (values.locale != null && !initLocale) { 13917 saveLocaleLocked(values.locale, 13918 !values.locale.equals(mConfiguration.locale), 13919 values.userSetLocale); 13920 } 13921 13922 mConfigurationSeq++; 13923 if (mConfigurationSeq <= 0) { 13924 mConfigurationSeq = 1; 13925 } 13926 newConfig.seq = mConfigurationSeq; 13927 mConfiguration = newConfig; 13928 Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig); 13929 13930 final Configuration configCopy = new Configuration(mConfiguration); 13931 13932 // TODO: If our config changes, should we auto dismiss any currently 13933 // showing dialogs? 13934 mShowDialogs = shouldShowDialogs(newConfig); 13935 13936 AttributeCache ac = AttributeCache.instance(); 13937 if (ac != null) { 13938 ac.updateConfiguration(configCopy); 13939 } 13940 13941 // Make sure all resources in our process are updated 13942 // right now, so that anyone who is going to retrieve 13943 // resource values after we return will be sure to get 13944 // the new ones. This is especially important during 13945 // boot, where the first config change needs to guarantee 13946 // all resources have that config before following boot 13947 // code is executed. 13948 mSystemThread.applyConfigurationToResources(configCopy); 13949 13950 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) { 13951 Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG); 13952 msg.obj = new Configuration(configCopy); 13953 mHandler.sendMessage(msg); 13954 } 13955 13956 for (int i=mLruProcesses.size()-1; i>=0; i--) { 13957 ProcessRecord app = mLruProcesses.get(i); 13958 try { 13959 if (app.thread != null) { 13960 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc " 13961 + app.processName + " new config " + mConfiguration); 13962 app.thread.scheduleConfigurationChanged(configCopy); 13963 } 13964 } catch (Exception e) { 13965 } 13966 } 13967 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED); 13968 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 13969 | Intent.FLAG_RECEIVER_REPLACE_PENDING 13970 | Intent.FLAG_RECEIVER_FOREGROUND); 13971 broadcastIntentLocked(null, null, intent, null, null, 0, null, null, 13972 null, AppOpsManager.OP_NONE, false, false, MY_PID, 13973 Process.SYSTEM_UID, UserHandle.USER_ALL); 13974 if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) { 13975 intent = new Intent(Intent.ACTION_LOCALE_CHANGED); 13976 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 13977 broadcastIntentLocked(null, null, intent, 13978 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 13979 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 13980 } 13981 } 13982 } 13983 13984 boolean kept = true; 13985 final ActivityStack mainStack = mStackSupervisor.getFocusedStack(); 13986 // mainStack is null during startup. 13987 if (mainStack != null) { 13988 if (changes != 0 && starting == null) { 13989 // If the configuration changed, and the caller is not already 13990 // in the process of starting an activity, then find the top 13991 // activity to check if its configuration needs to change. 13992 starting = mainStack.topRunningActivityLocked(null); 13993 } 13994 13995 if (starting != null) { 13996 kept = mainStack.ensureActivityConfigurationLocked(starting, changes); 13997 // And we need to make sure at this point that all other activities 13998 // are made visible with the correct configuration. 13999 mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes); 14000 } 14001 } 14002 14003 if (values != null && mWindowManager != null) { 14004 mWindowManager.setNewConfiguration(mConfiguration); 14005 } 14006 14007 return kept; 14008 } 14009 14010 /** 14011 * Decide based on the configuration whether we should shouw the ANR, 14012 * crash, etc dialogs. The idea is that if there is no affordnace to 14013 * press the on-screen buttons, we shouldn't show the dialog. 14014 * 14015 * A thought: SystemUI might also want to get told about this, the Power 14016 * dialog / global actions also might want different behaviors. 14017 */ 14018 private static final boolean shouldShowDialogs(Configuration config) { 14019 return !(config.keyboard == Configuration.KEYBOARD_NOKEYS 14020 && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH); 14021 } 14022 14023 /** 14024 * Save the locale. You must be inside a synchronized (this) block. 14025 */ 14026 private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) { 14027 if(isDiff) { 14028 SystemProperties.set("user.language", l.getLanguage()); 14029 SystemProperties.set("user.region", l.getCountry()); 14030 } 14031 14032 if(isPersist) { 14033 SystemProperties.set("persist.sys.language", l.getLanguage()); 14034 SystemProperties.set("persist.sys.country", l.getCountry()); 14035 SystemProperties.set("persist.sys.localevar", l.getVariant()); 14036 } 14037 } 14038 14039 @Override 14040 public boolean targetTaskAffinityMatchesActivity(IBinder token, String destAffinity) { 14041 ActivityRecord srec = ActivityRecord.forToken(token); 14042 return srec != null && srec.task.affinity != null && 14043 srec.task.affinity.equals(destAffinity); 14044 } 14045 14046 public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode, 14047 Intent resultData) { 14048 14049 synchronized (this) { 14050 final ActivityStack stack = ActivityRecord.getStackLocked(token); 14051 if (stack != null) { 14052 return stack.navigateUpToLocked(token, destIntent, resultCode, resultData); 14053 } 14054 return false; 14055 } 14056 } 14057 14058 public int getLaunchedFromUid(IBinder activityToken) { 14059 ActivityRecord srec = ActivityRecord.forToken(activityToken); 14060 if (srec == null) { 14061 return -1; 14062 } 14063 return srec.launchedFromUid; 14064 } 14065 14066 public String getLaunchedFromPackage(IBinder activityToken) { 14067 ActivityRecord srec = ActivityRecord.forToken(activityToken); 14068 if (srec == null) { 14069 return null; 14070 } 14071 return srec.launchedFromPackage; 14072 } 14073 14074 // ========================================================= 14075 // LIFETIME MANAGEMENT 14076 // ========================================================= 14077 14078 // Returns which broadcast queue the app is the current [or imminent] receiver 14079 // on, or 'null' if the app is not an active broadcast recipient. 14080 private BroadcastQueue isReceivingBroadcast(ProcessRecord app) { 14081 BroadcastRecord r = app.curReceiver; 14082 if (r != null) { 14083 return r.queue; 14084 } 14085 14086 // It's not the current receiver, but it might be starting up to become one 14087 synchronized (this) { 14088 for (BroadcastQueue queue : mBroadcastQueues) { 14089 r = queue.mPendingBroadcast; 14090 if (r != null && r.curApp == app) { 14091 // found it; report which queue it's in 14092 return queue; 14093 } 14094 } 14095 } 14096 14097 return null; 14098 } 14099 14100 private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP, 14101 boolean doingAll, long now) { 14102 if (mAdjSeq == app.adjSeq) { 14103 // This adjustment has already been computed. 14104 return app.curRawAdj; 14105 } 14106 14107 if (app.thread == null) { 14108 app.adjSeq = mAdjSeq; 14109 app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 14110 app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 14111 return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ); 14112 } 14113 14114 app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN; 14115 app.adjSource = null; 14116 app.adjTarget = null; 14117 app.empty = false; 14118 app.cached = false; 14119 14120 final int activitiesSize = app.activities.size(); 14121 14122 if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) { 14123 // The max adjustment doesn't allow this app to be anything 14124 // below foreground, so it is not worth doing work for it. 14125 app.adjType = "fixed"; 14126 app.adjSeq = mAdjSeq; 14127 app.curRawAdj = app.maxAdj; 14128 app.foregroundActivities = false; 14129 app.keeping = true; 14130 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT; 14131 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT; 14132 // System process can do UI, and when they do we want to have 14133 // them trim their memory after the user leaves the UI. To 14134 // facilitate this, here we need to determine whether or not it 14135 // is currently showing UI. 14136 app.systemNoUi = true; 14137 if (app == TOP_APP) { 14138 app.systemNoUi = false; 14139 } else if (activitiesSize > 0) { 14140 for (int j = 0; j < activitiesSize; j++) { 14141 final ActivityRecord r = app.activities.get(j); 14142 if (r.visible) { 14143 app.systemNoUi = false; 14144 } 14145 } 14146 } 14147 if (!app.systemNoUi) { 14148 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI; 14149 } 14150 return (app.curAdj=app.maxAdj); 14151 } 14152 14153 app.keeping = false; 14154 app.systemNoUi = false; 14155 14156 // Determine the importance of the process, starting with most 14157 // important to least, and assign an appropriate OOM adjustment. 14158 int adj; 14159 int schedGroup; 14160 int procState; 14161 boolean foregroundActivities = false; 14162 boolean interesting = false; 14163 BroadcastQueue queue; 14164 if (app == TOP_APP) { 14165 // The last app on the list is the foreground app. 14166 adj = ProcessList.FOREGROUND_APP_ADJ; 14167 schedGroup = Process.THREAD_GROUP_DEFAULT; 14168 app.adjType = "top-activity"; 14169 foregroundActivities = true; 14170 interesting = true; 14171 procState = ActivityManager.PROCESS_STATE_TOP; 14172 } else if (app.instrumentationClass != null) { 14173 // Don't want to kill running instrumentation. 14174 adj = ProcessList.FOREGROUND_APP_ADJ; 14175 schedGroup = Process.THREAD_GROUP_DEFAULT; 14176 app.adjType = "instrumentation"; 14177 interesting = true; 14178 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14179 } else if ((queue = isReceivingBroadcast(app)) != null) { 14180 // An app that is currently receiving a broadcast also 14181 // counts as being in the foreground for OOM killer purposes. 14182 // It's placed in a sched group based on the nature of the 14183 // broadcast as reflected by which queue it's active in. 14184 adj = ProcessList.FOREGROUND_APP_ADJ; 14185 schedGroup = (queue == mFgBroadcastQueue) 14186 ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 14187 app.adjType = "broadcast"; 14188 procState = ActivityManager.PROCESS_STATE_RECEIVER; 14189 } else if (app.executingServices.size() > 0) { 14190 // An app that is currently executing a service callback also 14191 // counts as being in the foreground. 14192 adj = ProcessList.FOREGROUND_APP_ADJ; 14193 schedGroup = app.execServicesFg ? 14194 Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 14195 app.adjType = "exec-service"; 14196 procState = ActivityManager.PROCESS_STATE_SERVICE; 14197 //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app); 14198 } else { 14199 // As far as we know the process is empty. We may change our mind later. 14200 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 14201 // At this point we don't actually know the adjustment. Use the cached adj 14202 // value that the caller wants us to. 14203 adj = cachedAdj; 14204 procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 14205 app.cached = true; 14206 app.empty = true; 14207 app.adjType = "cch-empty"; 14208 } 14209 14210 // Examine all activities if not already foreground. 14211 if (!foregroundActivities && activitiesSize > 0) { 14212 for (int j = 0; j < activitiesSize; j++) { 14213 final ActivityRecord r = app.activities.get(j); 14214 if (r.app != app) { 14215 Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc " 14216 + app + "?!?"); 14217 continue; 14218 } 14219 if (r.visible) { 14220 // App has a visible activity; only upgrade adjustment. 14221 if (adj > ProcessList.VISIBLE_APP_ADJ) { 14222 adj = ProcessList.VISIBLE_APP_ADJ; 14223 app.adjType = "visible"; 14224 } 14225 if (procState > ActivityManager.PROCESS_STATE_TOP) { 14226 procState = ActivityManager.PROCESS_STATE_TOP; 14227 } 14228 schedGroup = Process.THREAD_GROUP_DEFAULT; 14229 app.cached = false; 14230 app.empty = false; 14231 foregroundActivities = true; 14232 break; 14233 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) { 14234 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14235 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 14236 app.adjType = "pausing"; 14237 } 14238 if (procState > ActivityManager.PROCESS_STATE_TOP) { 14239 procState = ActivityManager.PROCESS_STATE_TOP; 14240 } 14241 schedGroup = Process.THREAD_GROUP_DEFAULT; 14242 app.cached = false; 14243 app.empty = false; 14244 foregroundActivities = true; 14245 } else if (r.state == ActivityState.STOPPING) { 14246 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14247 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 14248 app.adjType = "stopping"; 14249 } 14250 // For the process state, we will at this point consider the 14251 // process to be cached. It will be cached either as an activity 14252 // or empty depending on whether the activity is finishing. We do 14253 // this so that we can treat the process as cached for purposes of 14254 // memory trimming (determing current memory level, trim command to 14255 // send to process) since there can be an arbitrary number of stopping 14256 // processes and they should soon all go into the cached state. 14257 if (!r.finishing) { 14258 if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 14259 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 14260 } 14261 } 14262 app.cached = false; 14263 app.empty = false; 14264 foregroundActivities = true; 14265 } else { 14266 if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 14267 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 14268 app.adjType = "cch-act"; 14269 } 14270 } 14271 } 14272 } 14273 14274 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14275 if (app.foregroundServices) { 14276 // The user is aware of this app, so make it visible. 14277 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 14278 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14279 app.cached = false; 14280 app.adjType = "fg-service"; 14281 schedGroup = Process.THREAD_GROUP_DEFAULT; 14282 } else if (app.forcingToForeground != null) { 14283 // The user is aware of this app, so make it visible. 14284 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 14285 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14286 app.cached = false; 14287 app.adjType = "force-fg"; 14288 app.adjSource = app.forcingToForeground; 14289 schedGroup = Process.THREAD_GROUP_DEFAULT; 14290 } 14291 } 14292 14293 if (app.foregroundServices) { 14294 interesting = true; 14295 } 14296 14297 if (app == mHeavyWeightProcess) { 14298 if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) { 14299 // We don't want to kill the current heavy-weight process. 14300 adj = ProcessList.HEAVY_WEIGHT_APP_ADJ; 14301 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 14302 app.cached = false; 14303 app.adjType = "heavy"; 14304 } 14305 if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) { 14306 procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT; 14307 } 14308 } 14309 14310 if (app == mHomeProcess) { 14311 if (adj > ProcessList.HOME_APP_ADJ) { 14312 // This process is hosting what we currently consider to be the 14313 // home app, so we don't want to let it go into the background. 14314 adj = ProcessList.HOME_APP_ADJ; 14315 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 14316 app.cached = false; 14317 app.adjType = "home"; 14318 } 14319 if (procState > ActivityManager.PROCESS_STATE_HOME) { 14320 procState = ActivityManager.PROCESS_STATE_HOME; 14321 } 14322 } 14323 14324 if (app == mPreviousProcess && app.activities.size() > 0) { 14325 if (adj > ProcessList.PREVIOUS_APP_ADJ) { 14326 // This was the previous process that showed UI to the user. 14327 // We want to try to keep it around more aggressively, to give 14328 // a good experience around switching between two apps. 14329 adj = ProcessList.PREVIOUS_APP_ADJ; 14330 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 14331 app.cached = false; 14332 app.adjType = "previous"; 14333 } 14334 if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) { 14335 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY; 14336 } 14337 } 14338 14339 if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj 14340 + " reason=" + app.adjType); 14341 14342 // By default, we use the computed adjustment. It may be changed if 14343 // there are applications dependent on our services or providers, but 14344 // this gives us a baseline and makes sure we don't get into an 14345 // infinite recursion. 14346 app.adjSeq = mAdjSeq; 14347 app.curRawAdj = adj; 14348 app.hasStartedServices = false; 14349 14350 if (mBackupTarget != null && app == mBackupTarget.app) { 14351 // If possible we want to avoid killing apps while they're being backed up 14352 if (adj > ProcessList.BACKUP_APP_ADJ) { 14353 if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app); 14354 adj = ProcessList.BACKUP_APP_ADJ; 14355 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) { 14356 procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND; 14357 } 14358 app.adjType = "backup"; 14359 app.cached = false; 14360 } 14361 if (procState > ActivityManager.PROCESS_STATE_BACKUP) { 14362 procState = ActivityManager.PROCESS_STATE_BACKUP; 14363 } 14364 } 14365 14366 boolean mayBeTop = false; 14367 14368 for (int is = app.services.size()-1; 14369 is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 14370 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 14371 || procState > ActivityManager.PROCESS_STATE_TOP); 14372 is--) { 14373 ServiceRecord s = app.services.valueAt(is); 14374 if (s.startRequested) { 14375 app.hasStartedServices = true; 14376 if (procState > ActivityManager.PROCESS_STATE_SERVICE) { 14377 procState = ActivityManager.PROCESS_STATE_SERVICE; 14378 } 14379 if (app.hasShownUi && app != mHomeProcess) { 14380 // If this process has shown some UI, let it immediately 14381 // go to the LRU list because it may be pretty heavy with 14382 // UI stuff. We'll tag it with a label just to help 14383 // debug and understand what is going on. 14384 if (adj > ProcessList.SERVICE_ADJ) { 14385 app.adjType = "cch-started-ui-services"; 14386 } 14387 } else { 14388 if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) { 14389 // This service has seen some activity within 14390 // recent memory, so we will keep its process ahead 14391 // of the background processes. 14392 if (adj > ProcessList.SERVICE_ADJ) { 14393 adj = ProcessList.SERVICE_ADJ; 14394 app.adjType = "started-services"; 14395 app.cached = false; 14396 } 14397 } 14398 // If we have let the service slide into the background 14399 // state, still have some text describing what it is doing 14400 // even though the service no longer has an impact. 14401 if (adj > ProcessList.SERVICE_ADJ) { 14402 app.adjType = "cch-started-services"; 14403 } 14404 } 14405 // Don't kill this process because it is doing work; it 14406 // has said it is doing work. 14407 app.keeping = true; 14408 } 14409 for (int conni = s.connections.size()-1; 14410 conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 14411 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 14412 || procState > ActivityManager.PROCESS_STATE_TOP); 14413 conni--) { 14414 ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni); 14415 for (int i = 0; 14416 i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ 14417 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 14418 || procState > ActivityManager.PROCESS_STATE_TOP); 14419 i++) { 14420 // XXX should compute this based on the max of 14421 // all connected clients. 14422 ConnectionRecord cr = clist.get(i); 14423 if (cr.binding.client == app) { 14424 // Binding to ourself is not interesting. 14425 continue; 14426 } 14427 if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) { 14428 ProcessRecord client = cr.binding.client; 14429 int clientAdj = computeOomAdjLocked(client, cachedAdj, 14430 TOP_APP, doingAll, now); 14431 int clientProcState = client.curProcState; 14432 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 14433 // If the other app is cached for any reason, for purposes here 14434 // we are going to consider it empty. The specific cached state 14435 // doesn't propagate except under certain conditions. 14436 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 14437 } 14438 String adjType = null; 14439 if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) { 14440 // Not doing bind OOM management, so treat 14441 // this guy more like a started service. 14442 if (app.hasShownUi && app != mHomeProcess) { 14443 // If this process has shown some UI, let it immediately 14444 // go to the LRU list because it may be pretty heavy with 14445 // UI stuff. We'll tag it with a label just to help 14446 // debug and understand what is going on. 14447 if (adj > clientAdj) { 14448 adjType = "cch-bound-ui-services"; 14449 } 14450 app.cached = false; 14451 clientAdj = adj; 14452 clientProcState = procState; 14453 } else { 14454 if (now >= (s.lastActivity 14455 + ActiveServices.MAX_SERVICE_INACTIVITY)) { 14456 // This service has not seen activity within 14457 // recent memory, so allow it to drop to the 14458 // LRU list if there is no other reason to keep 14459 // it around. We'll also tag it with a label just 14460 // to help debug and undertand what is going on. 14461 if (adj > clientAdj) { 14462 adjType = "cch-bound-services"; 14463 } 14464 clientAdj = adj; 14465 } 14466 } 14467 } 14468 if (adj > clientAdj) { 14469 // If this process has recently shown UI, and 14470 // the process that is binding to it is less 14471 // important than being visible, then we don't 14472 // care about the binding as much as we care 14473 // about letting this process get into the LRU 14474 // list to be killed and restarted if needed for 14475 // memory. 14476 if (app.hasShownUi && app != mHomeProcess 14477 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14478 adjType = "cch-bound-ui-services"; 14479 } else { 14480 if ((cr.flags&(Context.BIND_ABOVE_CLIENT 14481 |Context.BIND_IMPORTANT)) != 0) { 14482 adj = clientAdj; 14483 } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0 14484 && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ 14485 && adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14486 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 14487 } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) { 14488 adj = clientAdj; 14489 } else { 14490 if (adj > ProcessList.VISIBLE_APP_ADJ) { 14491 adj = ProcessList.VISIBLE_APP_ADJ; 14492 } 14493 } 14494 if (!client.cached) { 14495 app.cached = false; 14496 } 14497 if (client.keeping) { 14498 app.keeping = true; 14499 } 14500 adjType = "service"; 14501 } 14502 } 14503 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 14504 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 14505 schedGroup = Process.THREAD_GROUP_DEFAULT; 14506 } 14507 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) { 14508 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) { 14509 // Special handling of clients who are in the top state. 14510 // We *may* want to consider this process to be in the 14511 // top state as well, but only if there is not another 14512 // reason for it to be running. Being on the top is a 14513 // special state, meaning you are specifically running 14514 // for the current top app. If the process is already 14515 // running in the background for some other reason, it 14516 // is more important to continue considering it to be 14517 // in the background state. 14518 mayBeTop = true; 14519 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 14520 } else { 14521 // Special handling for above-top states (persistent 14522 // processes). These should not bring the current process 14523 // into the top state, since they are not on top. Instead 14524 // give them the best state after that. 14525 clientProcState = 14526 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14527 } 14528 } 14529 } else { 14530 if (clientProcState < 14531 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) { 14532 clientProcState = 14533 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND; 14534 } 14535 } 14536 if (procState > clientProcState) { 14537 procState = clientProcState; 14538 } 14539 if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 14540 && (cr.flags&Context.BIND_SHOWING_UI) != 0) { 14541 app.pendingUiClean = true; 14542 } 14543 if (adjType != null) { 14544 app.adjType = adjType; 14545 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 14546 .REASON_SERVICE_IN_USE; 14547 app.adjSource = cr.binding.client; 14548 app.adjSourceOom = clientAdj; 14549 app.adjTarget = s.name; 14550 } 14551 } 14552 final ActivityRecord a = cr.activity; 14553 if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) { 14554 if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ && 14555 (a.visible || a.state == ActivityState.RESUMED 14556 || a.state == ActivityState.PAUSING)) { 14557 adj = ProcessList.FOREGROUND_APP_ADJ; 14558 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 14559 schedGroup = Process.THREAD_GROUP_DEFAULT; 14560 } 14561 app.cached = false; 14562 app.adjType = "service"; 14563 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 14564 .REASON_SERVICE_IN_USE; 14565 app.adjSource = a; 14566 app.adjSourceOom = adj; 14567 app.adjTarget = s.name; 14568 } 14569 } 14570 } 14571 } 14572 } 14573 14574 for (int provi = app.pubProviders.size()-1; 14575 provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 14576 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 14577 || procState > ActivityManager.PROCESS_STATE_TOP); 14578 provi--) { 14579 ContentProviderRecord cpr = app.pubProviders.valueAt(provi); 14580 for (int i = cpr.connections.size()-1; 14581 i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 14582 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 14583 || procState > ActivityManager.PROCESS_STATE_TOP); 14584 i--) { 14585 ContentProviderConnection conn = cpr.connections.get(i); 14586 ProcessRecord client = conn.client; 14587 if (client == app) { 14588 // Being our own client is not interesting. 14589 continue; 14590 } 14591 int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now); 14592 int clientProcState = client.curProcState; 14593 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 14594 // If the other app is cached for any reason, for purposes here 14595 // we are going to consider it empty. 14596 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 14597 } 14598 if (adj > clientAdj) { 14599 if (app.hasShownUi && app != mHomeProcess 14600 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14601 app.adjType = "cch-ui-provider"; 14602 } else { 14603 adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ 14604 ? clientAdj : ProcessList.FOREGROUND_APP_ADJ; 14605 app.adjType = "provider"; 14606 } 14607 app.cached &= client.cached; 14608 app.keeping |= client.keeping; 14609 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 14610 .REASON_PROVIDER_IN_USE; 14611 app.adjSource = client; 14612 app.adjSourceOom = clientAdj; 14613 app.adjTarget = cpr.name; 14614 } 14615 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) { 14616 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) { 14617 // Special handling of clients who are in the top state. 14618 // We *may* want to consider this process to be in the 14619 // top state as well, but only if there is not another 14620 // reason for it to be running. Being on the top is a 14621 // special state, meaning you are specifically running 14622 // for the current top app. If the process is already 14623 // running in the background for some other reason, it 14624 // is more important to continue considering it to be 14625 // in the background state. 14626 mayBeTop = true; 14627 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 14628 } else { 14629 // Special handling for above-top states (persistent 14630 // processes). These should not bring the current process 14631 // into the top state, since they are not on top. Instead 14632 // give them the best state after that. 14633 clientProcState = 14634 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14635 } 14636 } 14637 if (procState > clientProcState) { 14638 procState = clientProcState; 14639 } 14640 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 14641 schedGroup = Process.THREAD_GROUP_DEFAULT; 14642 } 14643 } 14644 // If the provider has external (non-framework) process 14645 // dependencies, ensure that its adjustment is at least 14646 // FOREGROUND_APP_ADJ. 14647 if (cpr.hasExternalProcessHandles()) { 14648 if (adj > ProcessList.FOREGROUND_APP_ADJ) { 14649 adj = ProcessList.FOREGROUND_APP_ADJ; 14650 schedGroup = Process.THREAD_GROUP_DEFAULT; 14651 app.cached = false; 14652 app.keeping = true; 14653 app.adjType = "provider"; 14654 app.adjTarget = cpr.name; 14655 } 14656 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) { 14657 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14658 } 14659 } 14660 } 14661 14662 if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) { 14663 // A client of one of our services or providers is in the top state. We 14664 // *may* want to be in the top state, but not if we are already running in 14665 // the background for some other reason. For the decision here, we are going 14666 // to pick out a few specific states that we want to remain in when a client 14667 // is top (states that tend to be longer-term) and otherwise allow it to go 14668 // to the top state. 14669 switch (procState) { 14670 case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND: 14671 case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND: 14672 case ActivityManager.PROCESS_STATE_SERVICE: 14673 // These all are longer-term states, so pull them up to the top 14674 // of the background states, but not all the way to the top state. 14675 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14676 break; 14677 default: 14678 // Otherwise, top is a better choice, so take it. 14679 procState = ActivityManager.PROCESS_STATE_TOP; 14680 break; 14681 } 14682 } 14683 14684 if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY && app.hasClientActivities) { 14685 // This is a cached process, but with client activities. Mark it so. 14686 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT; 14687 app.adjType = "cch-client-act"; 14688 } 14689 14690 if (adj == ProcessList.SERVICE_ADJ) { 14691 if (doingAll) { 14692 app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3); 14693 mNewNumServiceProcs++; 14694 //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb); 14695 if (!app.serviceb) { 14696 // This service isn't far enough down on the LRU list to 14697 // normally be a B service, but if we are low on RAM and it 14698 // is large we want to force it down since we would prefer to 14699 // keep launcher over it. 14700 if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL 14701 && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) { 14702 app.serviceHighRam = true; 14703 app.serviceb = true; 14704 //Slog.i(TAG, "ADJ " + app + " high ram!"); 14705 } else { 14706 mNewNumAServiceProcs++; 14707 //Slog.i(TAG, "ADJ " + app + " not high ram!"); 14708 } 14709 } else { 14710 app.serviceHighRam = false; 14711 } 14712 } 14713 if (app.serviceb) { 14714 adj = ProcessList.SERVICE_B_ADJ; 14715 } 14716 } 14717 14718 app.curRawAdj = adj; 14719 14720 //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid + 14721 // " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj); 14722 if (adj > app.maxAdj) { 14723 adj = app.maxAdj; 14724 if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 14725 schedGroup = Process.THREAD_GROUP_DEFAULT; 14726 } 14727 } 14728 if (adj < ProcessList.CACHED_APP_MIN_ADJ) { 14729 app.keeping = true; 14730 } 14731 14732 // Do final modification to adj. Everything we do between here and applying 14733 // the final setAdj must be done in this function, because we will also use 14734 // it when computing the final cached adj later. Note that we don't need to 14735 // worry about this for max adj above, since max adj will always be used to 14736 // keep it out of the cached vaues. 14737 adj = app.modifyRawOomAdj(adj); 14738 14739 app.curProcState = procState; 14740 14741 int importance = app.memImportance; 14742 if (importance == 0 || adj != app.curAdj || schedGroup != app.curSchedGroup) { 14743 app.curAdj = adj; 14744 app.curSchedGroup = schedGroup; 14745 if (!interesting) { 14746 // For this reporting, if there is not something explicitly 14747 // interesting in this process then we will push it to the 14748 // background importance. 14749 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 14750 } else if (adj >= ProcessList.CACHED_APP_MIN_ADJ) { 14751 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 14752 } else if (adj >= ProcessList.SERVICE_B_ADJ) { 14753 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 14754 } else if (adj >= ProcessList.HOME_APP_ADJ) { 14755 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 14756 } else if (adj >= ProcessList.SERVICE_ADJ) { 14757 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 14758 } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 14759 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE; 14760 } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) { 14761 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE; 14762 } else if (adj >= ProcessList.VISIBLE_APP_ADJ) { 14763 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE; 14764 } else if (adj >= ProcessList.FOREGROUND_APP_ADJ) { 14765 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND; 14766 } else { 14767 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERSISTENT; 14768 } 14769 } 14770 14771 int changes = importance != app.memImportance ? ProcessChangeItem.CHANGE_IMPORTANCE : 0; 14772 if (foregroundActivities != app.foregroundActivities) { 14773 changes |= ProcessChangeItem.CHANGE_ACTIVITIES; 14774 } 14775 if (changes != 0) { 14776 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes); 14777 app.memImportance = importance; 14778 app.foregroundActivities = foregroundActivities; 14779 int i = mPendingProcessChanges.size()-1; 14780 ProcessChangeItem item = null; 14781 while (i >= 0) { 14782 item = mPendingProcessChanges.get(i); 14783 if (item.pid == app.pid) { 14784 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item); 14785 break; 14786 } 14787 i--; 14788 } 14789 if (i < 0) { 14790 // No existing item in pending changes; need a new one. 14791 final int NA = mAvailProcessChanges.size(); 14792 if (NA > 0) { 14793 item = mAvailProcessChanges.remove(NA-1); 14794 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item); 14795 } else { 14796 item = new ProcessChangeItem(); 14797 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item); 14798 } 14799 item.changes = 0; 14800 item.pid = app.pid; 14801 item.uid = app.info.uid; 14802 if (mPendingProcessChanges.size() == 0) { 14803 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, 14804 "*** Enqueueing dispatch processes changed!"); 14805 mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget(); 14806 } 14807 mPendingProcessChanges.add(item); 14808 } 14809 item.changes |= changes; 14810 item.importance = importance; 14811 item.foregroundActivities = foregroundActivities; 14812 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item " 14813 + Integer.toHexString(System.identityHashCode(item)) 14814 + " " + app.toShortString() + ": changes=" + item.changes 14815 + " importance=" + item.importance 14816 + " foreground=" + item.foregroundActivities 14817 + " type=" + app.adjType + " source=" + app.adjSource 14818 + " target=" + app.adjTarget); 14819 } 14820 14821 return app.curRawAdj; 14822 } 14823 14824 /** 14825 * Schedule PSS collection of a process. 14826 */ 14827 void requestPssLocked(ProcessRecord proc, int procState) { 14828 if (mPendingPssProcesses.contains(proc)) { 14829 return; 14830 } 14831 if (mPendingPssProcesses.size() == 0) { 14832 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG); 14833 } 14834 if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc); 14835 proc.pssProcState = procState; 14836 mPendingPssProcesses.add(proc); 14837 } 14838 14839 /** 14840 * Schedule PSS collection of all processes. 14841 */ 14842 void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) { 14843 if (!always) { 14844 if (now < (mLastFullPssTime + 14845 (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) { 14846 return; 14847 } 14848 } 14849 if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs! memLowered=" + memLowered); 14850 mLastFullPssTime = now; 14851 mPendingPssProcesses.ensureCapacity(mLruProcesses.size()); 14852 mPendingPssProcesses.clear(); 14853 for (int i=mLruProcesses.size()-1; i>=0; i--) { 14854 ProcessRecord app = mLruProcesses.get(i); 14855 if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) { 14856 app.pssProcState = app.setProcState; 14857 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true, 14858 mSleeping, now); 14859 mPendingPssProcesses.add(app); 14860 } 14861 } 14862 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG); 14863 } 14864 14865 /** 14866 * Ask a given process to GC right now. 14867 */ 14868 final void performAppGcLocked(ProcessRecord app) { 14869 try { 14870 app.lastRequestedGc = SystemClock.uptimeMillis(); 14871 if (app.thread != null) { 14872 if (app.reportLowMemory) { 14873 app.reportLowMemory = false; 14874 app.thread.scheduleLowMemory(); 14875 } else { 14876 app.thread.processInBackground(); 14877 } 14878 } 14879 } catch (Exception e) { 14880 // whatever. 14881 } 14882 } 14883 14884 /** 14885 * Returns true if things are idle enough to perform GCs. 14886 */ 14887 private final boolean canGcNowLocked() { 14888 boolean processingBroadcasts = false; 14889 for (BroadcastQueue q : mBroadcastQueues) { 14890 if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) { 14891 processingBroadcasts = true; 14892 } 14893 } 14894 return !processingBroadcasts 14895 && (mSleeping || mStackSupervisor.allResumedActivitiesIdle()); 14896 } 14897 14898 /** 14899 * Perform GCs on all processes that are waiting for it, but only 14900 * if things are idle. 14901 */ 14902 final void performAppGcsLocked() { 14903 final int N = mProcessesToGc.size(); 14904 if (N <= 0) { 14905 return; 14906 } 14907 if (canGcNowLocked()) { 14908 while (mProcessesToGc.size() > 0) { 14909 ProcessRecord proc = mProcessesToGc.remove(0); 14910 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) { 14911 if ((proc.lastRequestedGc+GC_MIN_INTERVAL) 14912 <= SystemClock.uptimeMillis()) { 14913 // To avoid spamming the system, we will GC processes one 14914 // at a time, waiting a few seconds between each. 14915 performAppGcLocked(proc); 14916 scheduleAppGcsLocked(); 14917 return; 14918 } else { 14919 // It hasn't been long enough since we last GCed this 14920 // process... put it in the list to wait for its time. 14921 addProcessToGcListLocked(proc); 14922 break; 14923 } 14924 } 14925 } 14926 14927 scheduleAppGcsLocked(); 14928 } 14929 } 14930 14931 /** 14932 * If all looks good, perform GCs on all processes waiting for them. 14933 */ 14934 final void performAppGcsIfAppropriateLocked() { 14935 if (canGcNowLocked()) { 14936 performAppGcsLocked(); 14937 return; 14938 } 14939 // Still not idle, wait some more. 14940 scheduleAppGcsLocked(); 14941 } 14942 14943 /** 14944 * Schedule the execution of all pending app GCs. 14945 */ 14946 final void scheduleAppGcsLocked() { 14947 mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG); 14948 14949 if (mProcessesToGc.size() > 0) { 14950 // Schedule a GC for the time to the next process. 14951 ProcessRecord proc = mProcessesToGc.get(0); 14952 Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG); 14953 14954 long when = proc.lastRequestedGc + GC_MIN_INTERVAL; 14955 long now = SystemClock.uptimeMillis(); 14956 if (when < (now+GC_TIMEOUT)) { 14957 when = now + GC_TIMEOUT; 14958 } 14959 mHandler.sendMessageAtTime(msg, when); 14960 } 14961 } 14962 14963 /** 14964 * Add a process to the array of processes waiting to be GCed. Keeps the 14965 * list in sorted order by the last GC time. The process can't already be 14966 * on the list. 14967 */ 14968 final void addProcessToGcListLocked(ProcessRecord proc) { 14969 boolean added = false; 14970 for (int i=mProcessesToGc.size()-1; i>=0; i--) { 14971 if (mProcessesToGc.get(i).lastRequestedGc < 14972 proc.lastRequestedGc) { 14973 added = true; 14974 mProcessesToGc.add(i+1, proc); 14975 break; 14976 } 14977 } 14978 if (!added) { 14979 mProcessesToGc.add(0, proc); 14980 } 14981 } 14982 14983 /** 14984 * Set up to ask a process to GC itself. This will either do it 14985 * immediately, or put it on the list of processes to gc the next 14986 * time things are idle. 14987 */ 14988 final void scheduleAppGcLocked(ProcessRecord app) { 14989 long now = SystemClock.uptimeMillis(); 14990 if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) { 14991 return; 14992 } 14993 if (!mProcessesToGc.contains(app)) { 14994 addProcessToGcListLocked(app); 14995 scheduleAppGcsLocked(); 14996 } 14997 } 14998 14999 final void checkExcessivePowerUsageLocked(boolean doKills) { 15000 updateCpuStatsNow(); 15001 15002 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 15003 boolean doWakeKills = doKills; 15004 boolean doCpuKills = doKills; 15005 if (mLastPowerCheckRealtime == 0) { 15006 doWakeKills = false; 15007 } 15008 if (mLastPowerCheckUptime == 0) { 15009 doCpuKills = false; 15010 } 15011 if (stats.isScreenOn()) { 15012 doWakeKills = false; 15013 } 15014 final long curRealtime = SystemClock.elapsedRealtime(); 15015 final long realtimeSince = curRealtime - mLastPowerCheckRealtime; 15016 final long curUptime = SystemClock.uptimeMillis(); 15017 final long uptimeSince = curUptime - mLastPowerCheckUptime; 15018 mLastPowerCheckRealtime = curRealtime; 15019 mLastPowerCheckUptime = curUptime; 15020 if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) { 15021 doWakeKills = false; 15022 } 15023 if (uptimeSince < CPU_MIN_CHECK_DURATION) { 15024 doCpuKills = false; 15025 } 15026 int i = mLruProcesses.size(); 15027 while (i > 0) { 15028 i--; 15029 ProcessRecord app = mLruProcesses.get(i); 15030 if (!app.keeping) { 15031 long wtime; 15032 synchronized (stats) { 15033 wtime = stats.getProcessWakeTime(app.info.uid, 15034 app.pid, curRealtime); 15035 } 15036 long wtimeUsed = wtime - app.lastWakeTime; 15037 long cputimeUsed = app.curCpuTime - app.lastCpuTime; 15038 if (DEBUG_POWER) { 15039 StringBuilder sb = new StringBuilder(128); 15040 sb.append("Wake for "); 15041 app.toShortString(sb); 15042 sb.append(": over "); 15043 TimeUtils.formatDuration(realtimeSince, sb); 15044 sb.append(" used "); 15045 TimeUtils.formatDuration(wtimeUsed, sb); 15046 sb.append(" ("); 15047 sb.append((wtimeUsed*100)/realtimeSince); 15048 sb.append("%)"); 15049 Slog.i(TAG, sb.toString()); 15050 sb.setLength(0); 15051 sb.append("CPU for "); 15052 app.toShortString(sb); 15053 sb.append(": over "); 15054 TimeUtils.formatDuration(uptimeSince, sb); 15055 sb.append(" used "); 15056 TimeUtils.formatDuration(cputimeUsed, sb); 15057 sb.append(" ("); 15058 sb.append((cputimeUsed*100)/uptimeSince); 15059 sb.append("%)"); 15060 Slog.i(TAG, sb.toString()); 15061 } 15062 // If a process has held a wake lock for more 15063 // than 50% of the time during this period, 15064 // that sounds bad. Kill! 15065 if (doWakeKills && realtimeSince > 0 15066 && ((wtimeUsed*100)/realtimeSince) >= 50) { 15067 synchronized (stats) { 15068 stats.reportExcessiveWakeLocked(app.info.uid, app.processName, 15069 realtimeSince, wtimeUsed); 15070 } 15071 killUnneededProcessLocked(app, "excessive wake held " + wtimeUsed 15072 + " during " + realtimeSince); 15073 app.baseProcessTracker.reportExcessiveWake(app.pkgList); 15074 } else if (doCpuKills && uptimeSince > 0 15075 && ((cputimeUsed*100)/uptimeSince) >= 50) { 15076 synchronized (stats) { 15077 stats.reportExcessiveCpuLocked(app.info.uid, app.processName, 15078 uptimeSince, cputimeUsed); 15079 } 15080 killUnneededProcessLocked(app, "excessive cpu " + cputimeUsed 15081 + " during " + uptimeSince); 15082 app.baseProcessTracker.reportExcessiveCpu(app.pkgList); 15083 } else { 15084 app.lastWakeTime = wtime; 15085 app.lastCpuTime = app.curCpuTime; 15086 } 15087 } 15088 } 15089 } 15090 15091 private final boolean applyOomAdjLocked(ProcessRecord app, boolean wasKeeping, 15092 ProcessRecord TOP_APP, boolean doingAll, boolean reportingProcessState, long now) { 15093 boolean success = true; 15094 15095 if (app.curRawAdj != app.setRawAdj) { 15096 if (wasKeeping && !app.keeping) { 15097 // This app is no longer something we want to keep. Note 15098 // its current wake lock time to later know to kill it if 15099 // it is not behaving well. 15100 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 15101 synchronized (stats) { 15102 app.lastWakeTime = stats.getProcessWakeTime(app.info.uid, 15103 app.pid, SystemClock.elapsedRealtime()); 15104 } 15105 app.lastCpuTime = app.curCpuTime; 15106 } 15107 15108 app.setRawAdj = app.curRawAdj; 15109 } 15110 15111 if (app.curAdj != app.setAdj) { 15112 ProcessList.setOomAdj(app.pid, app.curAdj); 15113 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v( 15114 TAG, "Set " + app.pid + " " + app.processName + 15115 " adj " + app.curAdj + ": " + app.adjType); 15116 app.setAdj = app.curAdj; 15117 } 15118 15119 if (app.setSchedGroup != app.curSchedGroup) { 15120 app.setSchedGroup = app.curSchedGroup; 15121 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 15122 "Setting process group of " + app.processName 15123 + " to " + app.curSchedGroup); 15124 if (app.waitingToKill != null && 15125 app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 15126 killUnneededProcessLocked(app, app.waitingToKill); 15127 success = false; 15128 } else { 15129 if (true) { 15130 long oldId = Binder.clearCallingIdentity(); 15131 try { 15132 Process.setProcessGroup(app.pid, app.curSchedGroup); 15133 } catch (Exception e) { 15134 Slog.w(TAG, "Failed setting process group of " + app.pid 15135 + " to " + app.curSchedGroup); 15136 e.printStackTrace(); 15137 } finally { 15138 Binder.restoreCallingIdentity(oldId); 15139 } 15140 } else { 15141 if (app.thread != null) { 15142 try { 15143 app.thread.setSchedulingGroup(app.curSchedGroup); 15144 } catch (RemoteException e) { 15145 } 15146 } 15147 } 15148 Process.setSwappiness(app.pid, 15149 app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE); 15150 } 15151 } 15152 if (app.repProcState != app.curProcState) { 15153 app.repProcState = app.curProcState; 15154 if (!reportingProcessState && app.thread != null) { 15155 try { 15156 if (false) { 15157 //RuntimeException h = new RuntimeException("here"); 15158 Slog.i(TAG, "Sending new process state " + app.repProcState 15159 + " to " + app /*, h*/); 15160 } 15161 app.thread.setProcessState(app.repProcState); 15162 } catch (RemoteException e) { 15163 } 15164 } 15165 } 15166 if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState, 15167 app.setProcState)) { 15168 app.lastStateTime = now; 15169 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true, 15170 mSleeping, now); 15171 if (DEBUG_PSS) Slog.d(TAG, "Process state change from " 15172 + ProcessList.makeProcStateString(app.setProcState) + " to " 15173 + ProcessList.makeProcStateString(app.curProcState) + " next pss in " 15174 + (app.nextPssTime-now) + ": " + app); 15175 } else { 15176 if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL) 15177 && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) { 15178 requestPssLocked(app, app.setProcState); 15179 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false, 15180 mSleeping, now); 15181 } else if (false && DEBUG_PSS) { 15182 Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now)); 15183 } 15184 } 15185 if (app.setProcState != app.curProcState) { 15186 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 15187 "Proc state change of " + app.processName 15188 + " to " + app.curProcState); 15189 app.setProcState = app.curProcState; 15190 if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) { 15191 app.notCachedSinceIdle = false; 15192 } 15193 if (!doingAll) { 15194 setProcessTrackerState(app, mProcessStats.getMemFactorLocked(), now); 15195 } else { 15196 app.procStateChanged = true; 15197 } 15198 } 15199 return success; 15200 } 15201 15202 private final void setProcessTrackerState(ProcessRecord proc, int memFactor, long now) { 15203 if (proc.thread != null && proc.baseProcessTracker != null) { 15204 proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList); 15205 } 15206 } 15207 15208 private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj, 15209 ProcessRecord TOP_APP, boolean doingAll, boolean reportingProcessState, long now) { 15210 if (app.thread == null) { 15211 return false; 15212 } 15213 15214 final boolean wasKeeping = app.keeping; 15215 15216 computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now); 15217 15218 return applyOomAdjLocked(app, wasKeeping, TOP_APP, doingAll, 15219 reportingProcessState, now); 15220 } 15221 15222 private final ActivityRecord resumedAppLocked() { 15223 return mStackSupervisor.resumedAppLocked(); 15224 } 15225 15226 final boolean updateOomAdjLocked(ProcessRecord app) { 15227 return updateOomAdjLocked(app, false); 15228 } 15229 15230 final boolean updateOomAdjLocked(ProcessRecord app, boolean doingProcessState) { 15231 final ActivityRecord TOP_ACT = resumedAppLocked(); 15232 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 15233 final boolean wasCached = app.cached; 15234 15235 mAdjSeq++; 15236 15237 // This is the desired cached adjusment we want to tell it to use. 15238 // If our app is currently cached, we know it, and that is it. Otherwise, 15239 // we don't know it yet, and it needs to now be cached we will then 15240 // need to do a complete oom adj. 15241 final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ 15242 ? app.curRawAdj : ProcessList.UNKNOWN_ADJ; 15243 boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false, doingProcessState, 15244 SystemClock.uptimeMillis()); 15245 if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) { 15246 // Changed to/from cached state, so apps after it in the LRU 15247 // list may also be changed. 15248 updateOomAdjLocked(); 15249 } 15250 return success; 15251 } 15252 15253 final void updateOomAdjLocked() { 15254 final ActivityRecord TOP_ACT = resumedAppLocked(); 15255 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 15256 final long now = SystemClock.uptimeMillis(); 15257 final long oldTime = now - ProcessList.MAX_EMPTY_TIME; 15258 final int N = mLruProcesses.size(); 15259 15260 if (false) { 15261 RuntimeException e = new RuntimeException(); 15262 e.fillInStackTrace(); 15263 Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e); 15264 } 15265 15266 mAdjSeq++; 15267 mNewNumServiceProcs = 0; 15268 mNewNumAServiceProcs = 0; 15269 15270 final int emptyProcessLimit; 15271 final int cachedProcessLimit; 15272 if (mProcessLimit <= 0) { 15273 emptyProcessLimit = cachedProcessLimit = 0; 15274 } else if (mProcessLimit == 1) { 15275 emptyProcessLimit = 1; 15276 cachedProcessLimit = 0; 15277 } else { 15278 emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit); 15279 cachedProcessLimit = mProcessLimit - emptyProcessLimit; 15280 } 15281 15282 // Let's determine how many processes we have running vs. 15283 // how many slots we have for background processes; we may want 15284 // to put multiple processes in a slot of there are enough of 15285 // them. 15286 int numSlots = (ProcessList.CACHED_APP_MAX_ADJ 15287 - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2; 15288 int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs; 15289 if (numEmptyProcs > cachedProcessLimit) { 15290 // If there are more empty processes than our limit on cached 15291 // processes, then use the cached process limit for the factor. 15292 // This ensures that the really old empty processes get pushed 15293 // down to the bottom, so if we are running low on memory we will 15294 // have a better chance at keeping around more cached processes 15295 // instead of a gazillion empty processes. 15296 numEmptyProcs = cachedProcessLimit; 15297 } 15298 int emptyFactor = numEmptyProcs/numSlots; 15299 if (emptyFactor < 1) emptyFactor = 1; 15300 int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots; 15301 if (cachedFactor < 1) cachedFactor = 1; 15302 int stepCached = 0; 15303 int stepEmpty = 0; 15304 int numCached = 0; 15305 int numEmpty = 0; 15306 int numTrimming = 0; 15307 15308 mNumNonCachedProcs = 0; 15309 mNumCachedHiddenProcs = 0; 15310 15311 // First update the OOM adjustment for each of the 15312 // application processes based on their current state. 15313 int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ; 15314 int nextCachedAdj = curCachedAdj+1; 15315 int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ; 15316 int nextEmptyAdj = curEmptyAdj+2; 15317 for (int i=N-1; i>=0; i--) { 15318 ProcessRecord app = mLruProcesses.get(i); 15319 if (!app.killedByAm && app.thread != null) { 15320 app.procStateChanged = false; 15321 final boolean wasKeeping = app.keeping; 15322 computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now); 15323 15324 // If we haven't yet assigned the final cached adj 15325 // to the process, do that now. 15326 if (app.curAdj >= ProcessList.UNKNOWN_ADJ) { 15327 switch (app.curProcState) { 15328 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY: 15329 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: 15330 // This process is a cached process holding activities... 15331 // assign it the next cached value for that type, and then 15332 // step that cached level. 15333 app.curRawAdj = curCachedAdj; 15334 app.curAdj = app.modifyRawOomAdj(curCachedAdj); 15335 if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i 15336 + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj 15337 + ")"); 15338 if (curCachedAdj != nextCachedAdj) { 15339 stepCached++; 15340 if (stepCached >= cachedFactor) { 15341 stepCached = 0; 15342 curCachedAdj = nextCachedAdj; 15343 nextCachedAdj += 2; 15344 if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) { 15345 nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ; 15346 } 15347 } 15348 } 15349 break; 15350 default: 15351 // For everything else, assign next empty cached process 15352 // level and bump that up. Note that this means that 15353 // long-running services that have dropped down to the 15354 // cached level will be treated as empty (since their process 15355 // state is still as a service), which is what we want. 15356 app.curRawAdj = curEmptyAdj; 15357 app.curAdj = app.modifyRawOomAdj(curEmptyAdj); 15358 if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i 15359 + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj 15360 + ")"); 15361 if (curEmptyAdj != nextEmptyAdj) { 15362 stepEmpty++; 15363 if (stepEmpty >= emptyFactor) { 15364 stepEmpty = 0; 15365 curEmptyAdj = nextEmptyAdj; 15366 nextEmptyAdj += 2; 15367 if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) { 15368 nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ; 15369 } 15370 } 15371 } 15372 break; 15373 } 15374 } 15375 15376 applyOomAdjLocked(app, wasKeeping, TOP_APP, true, false, now); 15377 15378 // Count the number of process types. 15379 switch (app.curProcState) { 15380 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY: 15381 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: 15382 mNumCachedHiddenProcs++; 15383 numCached++; 15384 if (numCached > cachedProcessLimit) { 15385 killUnneededProcessLocked(app, "cached #" + numCached); 15386 } 15387 break; 15388 case ActivityManager.PROCESS_STATE_CACHED_EMPTY: 15389 if (numEmpty > ProcessList.TRIM_EMPTY_APPS 15390 && app.lastActivityTime < oldTime) { 15391 killUnneededProcessLocked(app, "empty for " 15392 + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime) 15393 / 1000) + "s"); 15394 } else { 15395 numEmpty++; 15396 if (numEmpty > emptyProcessLimit) { 15397 killUnneededProcessLocked(app, "empty #" + numEmpty); 15398 } 15399 } 15400 break; 15401 default: 15402 mNumNonCachedProcs++; 15403 break; 15404 } 15405 15406 if (app.isolated && app.services.size() <= 0) { 15407 // If this is an isolated process, and there are no 15408 // services running in it, then the process is no longer 15409 // needed. We agressively kill these because we can by 15410 // definition not re-use the same process again, and it is 15411 // good to avoid having whatever code was running in them 15412 // left sitting around after no longer needed. 15413 killUnneededProcessLocked(app, "isolated not needed"); 15414 } 15415 15416 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME 15417 && !app.killedByAm) { 15418 numTrimming++; 15419 } 15420 } 15421 } 15422 15423 mNumServiceProcs = mNewNumServiceProcs; 15424 15425 // Now determine the memory trimming level of background processes. 15426 // Unfortunately we need to start at the back of the list to do this 15427 // properly. We only do this if the number of background apps we 15428 // are managing to keep around is less than half the maximum we desire; 15429 // if we are keeping a good number around, we'll let them use whatever 15430 // memory they want. 15431 final int numCachedAndEmpty = numCached + numEmpty; 15432 int memFactor; 15433 if (numCached <= ProcessList.TRIM_CACHED_APPS 15434 && numEmpty <= ProcessList.TRIM_EMPTY_APPS) { 15435 if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) { 15436 memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL; 15437 } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) { 15438 memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW; 15439 } else { 15440 memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE; 15441 } 15442 } else { 15443 memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL; 15444 } 15445 // We always allow the memory level to go up (better). We only allow it to go 15446 // down if we are in a state where that is allowed, *and* the total number of processes 15447 // has gone down since last time. 15448 if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel 15449 + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size() 15450 + " last=" + mLastNumProcesses); 15451 if (memFactor > mLastMemoryLevel) { 15452 if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) { 15453 memFactor = mLastMemoryLevel; 15454 if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!"); 15455 } 15456 } 15457 mLastMemoryLevel = memFactor; 15458 mLastNumProcesses = mLruProcesses.size(); 15459 boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !mSleeping, now); 15460 final int trackerMemFactor = mProcessStats.getMemFactorLocked(); 15461 if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) { 15462 if (mLowRamStartTime == 0) { 15463 mLowRamStartTime = now; 15464 } 15465 int step = 0; 15466 int fgTrimLevel; 15467 switch (memFactor) { 15468 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL: 15469 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL; 15470 break; 15471 case ProcessStats.ADJ_MEM_FACTOR_LOW: 15472 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW; 15473 break; 15474 default: 15475 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE; 15476 break; 15477 } 15478 int factor = numTrimming/3; 15479 int minFactor = 2; 15480 if (mHomeProcess != null) minFactor++; 15481 if (mPreviousProcess != null) minFactor++; 15482 if (factor < minFactor) factor = minFactor; 15483 int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE; 15484 for (int i=N-1; i>=0; i--) { 15485 ProcessRecord app = mLruProcesses.get(i); 15486 if (allChanged || app.procStateChanged) { 15487 setProcessTrackerState(app, trackerMemFactor, now); 15488 app.procStateChanged = false; 15489 } 15490 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME 15491 && !app.killedByAm) { 15492 if (app.trimMemoryLevel < curLevel && app.thread != null) { 15493 try { 15494 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 15495 "Trimming memory of " + app.processName 15496 + " to " + curLevel); 15497 app.thread.scheduleTrimMemory(curLevel); 15498 } catch (RemoteException e) { 15499 } 15500 if (false) { 15501 // For now we won't do this; our memory trimming seems 15502 // to be good enough at this point that destroying 15503 // activities causes more harm than good. 15504 if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE 15505 && app != mHomeProcess && app != mPreviousProcess) { 15506 // Need to do this on its own message because the stack may not 15507 // be in a consistent state at this point. 15508 // For these apps we will also finish their activities 15509 // to help them free memory. 15510 mStackSupervisor.scheduleDestroyAllActivities(app, "trim"); 15511 } 15512 } 15513 } 15514 app.trimMemoryLevel = curLevel; 15515 step++; 15516 if (step >= factor) { 15517 step = 0; 15518 switch (curLevel) { 15519 case ComponentCallbacks2.TRIM_MEMORY_COMPLETE: 15520 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE; 15521 break; 15522 case ComponentCallbacks2.TRIM_MEMORY_MODERATE: 15523 curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 15524 break; 15525 } 15526 } 15527 } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) { 15528 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND 15529 && app.thread != null) { 15530 try { 15531 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 15532 "Trimming memory of heavy-weight " + app.processName 15533 + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 15534 app.thread.scheduleTrimMemory( 15535 ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 15536 } catch (RemoteException e) { 15537 } 15538 } 15539 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 15540 } else { 15541 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 15542 || app.systemNoUi) && app.pendingUiClean) { 15543 // If this application is now in the background and it 15544 // had done UI, then give it the special trim level to 15545 // have it free UI resources. 15546 final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN; 15547 if (app.trimMemoryLevel < level && app.thread != null) { 15548 try { 15549 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 15550 "Trimming memory of bg-ui " + app.processName 15551 + " to " + level); 15552 app.thread.scheduleTrimMemory(level); 15553 } catch (RemoteException e) { 15554 } 15555 } 15556 app.pendingUiClean = false; 15557 } 15558 if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) { 15559 try { 15560 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 15561 "Trimming memory of fg " + app.processName 15562 + " to " + fgTrimLevel); 15563 app.thread.scheduleTrimMemory(fgTrimLevel); 15564 } catch (RemoteException e) { 15565 } 15566 } 15567 app.trimMemoryLevel = fgTrimLevel; 15568 } 15569 } 15570 } else { 15571 if (mLowRamStartTime != 0) { 15572 mLowRamTimeSinceLastIdle += now - mLowRamStartTime; 15573 mLowRamStartTime = 0; 15574 } 15575 for (int i=N-1; i>=0; i--) { 15576 ProcessRecord app = mLruProcesses.get(i); 15577 if (allChanged || app.procStateChanged) { 15578 setProcessTrackerState(app, trackerMemFactor, now); 15579 app.procStateChanged = false; 15580 } 15581 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 15582 || app.systemNoUi) && app.pendingUiClean) { 15583 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN 15584 && app.thread != null) { 15585 try { 15586 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 15587 "Trimming memory of ui hidden " + app.processName 15588 + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 15589 app.thread.scheduleTrimMemory( 15590 ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 15591 } catch (RemoteException e) { 15592 } 15593 } 15594 app.pendingUiClean = false; 15595 } 15596 app.trimMemoryLevel = 0; 15597 } 15598 } 15599 15600 if (mAlwaysFinishActivities) { 15601 // Need to do this on its own message because the stack may not 15602 // be in a consistent state at this point. 15603 mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish"); 15604 } 15605 15606 if (allChanged) { 15607 requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered()); 15608 } 15609 15610 if (mProcessStats.shouldWriteNowLocked(now)) { 15611 mHandler.post(new Runnable() { 15612 @Override public void run() { 15613 synchronized (ActivityManagerService.this) { 15614 mProcessStats.writeStateAsyncLocked(); 15615 } 15616 } 15617 }); 15618 } 15619 15620 if (DEBUG_OOM_ADJ) { 15621 Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms"); 15622 } 15623 } 15624 15625 final void trimApplications() { 15626 synchronized (this) { 15627 int i; 15628 15629 // First remove any unused application processes whose package 15630 // has been removed. 15631 for (i=mRemovedProcesses.size()-1; i>=0; i--) { 15632 final ProcessRecord app = mRemovedProcesses.get(i); 15633 if (app.activities.size() == 0 15634 && app.curReceiver == null && app.services.size() == 0) { 15635 Slog.i( 15636 TAG, "Exiting empty application process " 15637 + app.processName + " (" 15638 + (app.thread != null ? app.thread.asBinder() : null) 15639 + ")\n"); 15640 if (app.pid > 0 && app.pid != MY_PID) { 15641 EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid, 15642 app.processName, app.setAdj, "empty"); 15643 app.killedByAm = true; 15644 Process.killProcessQuiet(app.pid); 15645 } else { 15646 try { 15647 app.thread.scheduleExit(); 15648 } catch (Exception e) { 15649 // Ignore exceptions. 15650 } 15651 } 15652 cleanUpApplicationRecordLocked(app, false, true, -1); 15653 mRemovedProcesses.remove(i); 15654 15655 if (app.persistent) { 15656 if (app.persistent) { 15657 addAppLocked(app.info, false); 15658 } 15659 } 15660 } 15661 } 15662 15663 // Now update the oom adj for all processes. 15664 updateOomAdjLocked(); 15665 } 15666 } 15667 15668 /** This method sends the specified signal to each of the persistent apps */ 15669 public void signalPersistentProcesses(int sig) throws RemoteException { 15670 if (sig != Process.SIGNAL_USR1) { 15671 throw new SecurityException("Only SIGNAL_USR1 is allowed"); 15672 } 15673 15674 synchronized (this) { 15675 if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES) 15676 != PackageManager.PERMISSION_GRANTED) { 15677 throw new SecurityException("Requires permission " 15678 + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES); 15679 } 15680 15681 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 15682 ProcessRecord r = mLruProcesses.get(i); 15683 if (r.thread != null && r.persistent) { 15684 Process.sendSignal(r.pid, sig); 15685 } 15686 } 15687 } 15688 } 15689 15690 private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) { 15691 if (proc == null || proc == mProfileProc) { 15692 proc = mProfileProc; 15693 path = mProfileFile; 15694 profileType = mProfileType; 15695 clearProfilerLocked(); 15696 } 15697 if (proc == null) { 15698 return; 15699 } 15700 try { 15701 proc.thread.profilerControl(false, path, null, profileType); 15702 } catch (RemoteException e) { 15703 throw new IllegalStateException("Process disappeared"); 15704 } 15705 } 15706 15707 private void clearProfilerLocked() { 15708 if (mProfileFd != null) { 15709 try { 15710 mProfileFd.close(); 15711 } catch (IOException e) { 15712 } 15713 } 15714 mProfileApp = null; 15715 mProfileProc = null; 15716 mProfileFile = null; 15717 mProfileType = 0; 15718 mAutoStopProfiler = false; 15719 } 15720 15721 public boolean profileControl(String process, int userId, boolean start, 15722 String path, ParcelFileDescriptor fd, int profileType) throws RemoteException { 15723 15724 try { 15725 synchronized (this) { 15726 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 15727 // its own permission. 15728 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 15729 != PackageManager.PERMISSION_GRANTED) { 15730 throw new SecurityException("Requires permission " 15731 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 15732 } 15733 15734 if (start && fd == null) { 15735 throw new IllegalArgumentException("null fd"); 15736 } 15737 15738 ProcessRecord proc = null; 15739 if (process != null) { 15740 proc = findProcessLocked(process, userId, "profileControl"); 15741 } 15742 15743 if (start && (proc == null || proc.thread == null)) { 15744 throw new IllegalArgumentException("Unknown process: " + process); 15745 } 15746 15747 if (start) { 15748 stopProfilerLocked(null, null, 0); 15749 setProfileApp(proc.info, proc.processName, path, fd, false); 15750 mProfileProc = proc; 15751 mProfileType = profileType; 15752 try { 15753 fd = fd.dup(); 15754 } catch (IOException e) { 15755 fd = null; 15756 } 15757 proc.thread.profilerControl(start, path, fd, profileType); 15758 fd = null; 15759 mProfileFd = null; 15760 } else { 15761 stopProfilerLocked(proc, path, profileType); 15762 if (fd != null) { 15763 try { 15764 fd.close(); 15765 } catch (IOException e) { 15766 } 15767 } 15768 } 15769 15770 return true; 15771 } 15772 } catch (RemoteException e) { 15773 throw new IllegalStateException("Process disappeared"); 15774 } finally { 15775 if (fd != null) { 15776 try { 15777 fd.close(); 15778 } catch (IOException e) { 15779 } 15780 } 15781 } 15782 } 15783 15784 private ProcessRecord findProcessLocked(String process, int userId, String callName) { 15785 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 15786 userId, true, true, callName, null); 15787 ProcessRecord proc = null; 15788 try { 15789 int pid = Integer.parseInt(process); 15790 synchronized (mPidsSelfLocked) { 15791 proc = mPidsSelfLocked.get(pid); 15792 } 15793 } catch (NumberFormatException e) { 15794 } 15795 15796 if (proc == null) { 15797 ArrayMap<String, SparseArray<ProcessRecord>> all 15798 = mProcessNames.getMap(); 15799 SparseArray<ProcessRecord> procs = all.get(process); 15800 if (procs != null && procs.size() > 0) { 15801 proc = procs.valueAt(0); 15802 if (userId != UserHandle.USER_ALL && proc.userId != userId) { 15803 for (int i=1; i<procs.size(); i++) { 15804 ProcessRecord thisProc = procs.valueAt(i); 15805 if (thisProc.userId == userId) { 15806 proc = thisProc; 15807 break; 15808 } 15809 } 15810 } 15811 } 15812 } 15813 15814 return proc; 15815 } 15816 15817 public boolean dumpHeap(String process, int userId, boolean managed, 15818 String path, ParcelFileDescriptor fd) throws RemoteException { 15819 15820 try { 15821 synchronized (this) { 15822 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 15823 // its own permission (same as profileControl). 15824 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 15825 != PackageManager.PERMISSION_GRANTED) { 15826 throw new SecurityException("Requires permission " 15827 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 15828 } 15829 15830 if (fd == null) { 15831 throw new IllegalArgumentException("null fd"); 15832 } 15833 15834 ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap"); 15835 if (proc == null || proc.thread == null) { 15836 throw new IllegalArgumentException("Unknown process: " + process); 15837 } 15838 15839 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 15840 if (!isDebuggable) { 15841 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 15842 throw new SecurityException("Process not debuggable: " + proc); 15843 } 15844 } 15845 15846 proc.thread.dumpHeap(managed, path, fd); 15847 fd = null; 15848 return true; 15849 } 15850 } catch (RemoteException e) { 15851 throw new IllegalStateException("Process disappeared"); 15852 } finally { 15853 if (fd != null) { 15854 try { 15855 fd.close(); 15856 } catch (IOException e) { 15857 } 15858 } 15859 } 15860 } 15861 15862 /** In this method we try to acquire our lock to make sure that we have not deadlocked */ 15863 public void monitor() { 15864 synchronized (this) { } 15865 } 15866 15867 void onCoreSettingsChange(Bundle settings) { 15868 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 15869 ProcessRecord processRecord = mLruProcesses.get(i); 15870 try { 15871 if (processRecord.thread != null) { 15872 processRecord.thread.setCoreSettings(settings); 15873 } 15874 } catch (RemoteException re) { 15875 /* ignore */ 15876 } 15877 } 15878 } 15879 15880 // Multi-user methods 15881 15882 @Override 15883 public boolean switchUser(final int userId) { 15884 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 15885 != PackageManager.PERMISSION_GRANTED) { 15886 String msg = "Permission Denial: switchUser() from pid=" 15887 + Binder.getCallingPid() 15888 + ", uid=" + Binder.getCallingUid() 15889 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 15890 Slog.w(TAG, msg); 15891 throw new SecurityException(msg); 15892 } 15893 15894 final long ident = Binder.clearCallingIdentity(); 15895 try { 15896 synchronized (this) { 15897 final int oldUserId = mCurrentUserId; 15898 if (oldUserId == userId) { 15899 return true; 15900 } 15901 15902 final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId); 15903 if (userInfo == null) { 15904 Slog.w(TAG, "No user info for user #" + userId); 15905 return false; 15906 } 15907 15908 mWindowManager.startFreezingScreen(R.anim.screen_user_exit, 15909 R.anim.screen_user_enter); 15910 15911 boolean needStart = false; 15912 15913 // If the user we are switching to is not currently started, then 15914 // we need to start it now. 15915 if (mStartedUsers.get(userId) == null) { 15916 mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false)); 15917 updateStartedUserArrayLocked(); 15918 needStart = true; 15919 } 15920 15921 mCurrentUserId = userId; 15922 final Integer userIdInt = Integer.valueOf(userId); 15923 mUserLru.remove(userIdInt); 15924 mUserLru.add(userIdInt); 15925 15926 mWindowManager.setCurrentUser(userId); 15927 15928 // Once the internal notion of the active user has switched, we lock the device 15929 // with the option to show the user switcher on the keyguard. 15930 mWindowManager.lockNow(null); 15931 15932 final UserStartedState uss = mStartedUsers.get(userId); 15933 15934 // Make sure user is in the started state. If it is currently 15935 // stopping, we need to knock that off. 15936 if (uss.mState == UserStartedState.STATE_STOPPING) { 15937 // If we are stopping, we haven't sent ACTION_SHUTDOWN, 15938 // so we can just fairly silently bring the user back from 15939 // the almost-dead. 15940 uss.mState = UserStartedState.STATE_RUNNING; 15941 updateStartedUserArrayLocked(); 15942 needStart = true; 15943 } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) { 15944 // This means ACTION_SHUTDOWN has been sent, so we will 15945 // need to treat this as a new boot of the user. 15946 uss.mState = UserStartedState.STATE_BOOTING; 15947 updateStartedUserArrayLocked(); 15948 needStart = true; 15949 } 15950 15951 mHandler.removeMessages(REPORT_USER_SWITCH_MSG); 15952 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 15953 mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG, 15954 oldUserId, userId, uss)); 15955 mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG, 15956 oldUserId, userId, uss), USER_SWITCH_TIMEOUT); 15957 if (needStart) { 15958 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 15959 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 15960 | Intent.FLAG_RECEIVER_FOREGROUND); 15961 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 15962 broadcastIntentLocked(null, null, intent, 15963 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 15964 false, false, MY_PID, Process.SYSTEM_UID, userId); 15965 } 15966 15967 if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) { 15968 if (userId != 0) { 15969 Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE); 15970 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 15971 broadcastIntentLocked(null, null, intent, null, 15972 new IIntentReceiver.Stub() { 15973 public void performReceive(Intent intent, int resultCode, 15974 String data, Bundle extras, boolean ordered, 15975 boolean sticky, int sendingUser) { 15976 userInitialized(uss, userId); 15977 } 15978 }, 0, null, null, null, AppOpsManager.OP_NONE, 15979 true, false, MY_PID, Process.SYSTEM_UID, 15980 userId); 15981 uss.initializing = true; 15982 } else { 15983 getUserManagerLocked().makeInitialized(userInfo.id); 15984 } 15985 } 15986 15987 boolean homeInFront = mStackSupervisor.switchUserLocked(userId, uss); 15988 if (homeInFront) { 15989 startHomeActivityLocked(userId); 15990 } else { 15991 mStackSupervisor.resumeTopActivitiesLocked(); 15992 } 15993 15994 EventLogTags.writeAmSwitchUser(userId); 15995 getUserManagerLocked().userForeground(userId); 15996 sendUserSwitchBroadcastsLocked(oldUserId, userId); 15997 if (needStart) { 15998 Intent intent = new Intent(Intent.ACTION_USER_STARTING); 15999 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 16000 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 16001 broadcastIntentLocked(null, null, intent, 16002 null, new IIntentReceiver.Stub() { 16003 @Override 16004 public void performReceive(Intent intent, int resultCode, String data, 16005 Bundle extras, boolean ordered, boolean sticky, int sendingUser) 16006 throws RemoteException { 16007 } 16008 }, 0, null, null, 16009 android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 16010 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 16011 } 16012 } 16013 } finally { 16014 Binder.restoreCallingIdentity(ident); 16015 } 16016 16017 return true; 16018 } 16019 16020 void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) { 16021 long ident = Binder.clearCallingIdentity(); 16022 try { 16023 Intent intent; 16024 if (oldUserId >= 0) { 16025 intent = new Intent(Intent.ACTION_USER_BACKGROUND); 16026 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16027 | Intent.FLAG_RECEIVER_FOREGROUND); 16028 intent.putExtra(Intent.EXTRA_USER_HANDLE, oldUserId); 16029 broadcastIntentLocked(null, null, intent, 16030 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 16031 false, false, MY_PID, Process.SYSTEM_UID, oldUserId); 16032 } 16033 if (newUserId >= 0) { 16034 intent = new Intent(Intent.ACTION_USER_FOREGROUND); 16035 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16036 | Intent.FLAG_RECEIVER_FOREGROUND); 16037 intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId); 16038 broadcastIntentLocked(null, null, intent, 16039 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 16040 false, false, MY_PID, Process.SYSTEM_UID, newUserId); 16041 intent = new Intent(Intent.ACTION_USER_SWITCHED); 16042 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16043 | Intent.FLAG_RECEIVER_FOREGROUND); 16044 intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId); 16045 broadcastIntentLocked(null, null, intent, 16046 null, null, 0, null, null, 16047 android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE, 16048 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 16049 } 16050 } finally { 16051 Binder.restoreCallingIdentity(ident); 16052 } 16053 } 16054 16055 void dispatchUserSwitch(final UserStartedState uss, final int oldUserId, 16056 final int newUserId) { 16057 final int N = mUserSwitchObservers.beginBroadcast(); 16058 if (N > 0) { 16059 final IRemoteCallback callback = new IRemoteCallback.Stub() { 16060 int mCount = 0; 16061 @Override 16062 public void sendResult(Bundle data) throws RemoteException { 16063 synchronized (ActivityManagerService.this) { 16064 if (mCurUserSwitchCallback == this) { 16065 mCount++; 16066 if (mCount == N) { 16067 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 16068 } 16069 } 16070 } 16071 } 16072 }; 16073 synchronized (this) { 16074 uss.switching = true; 16075 mCurUserSwitchCallback = callback; 16076 } 16077 for (int i=0; i<N; i++) { 16078 try { 16079 mUserSwitchObservers.getBroadcastItem(i).onUserSwitching( 16080 newUserId, callback); 16081 } catch (RemoteException e) { 16082 } 16083 } 16084 } else { 16085 synchronized (this) { 16086 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 16087 } 16088 } 16089 mUserSwitchObservers.finishBroadcast(); 16090 } 16091 16092 void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 16093 synchronized (this) { 16094 Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId); 16095 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 16096 } 16097 } 16098 16099 void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) { 16100 mCurUserSwitchCallback = null; 16101 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 16102 mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG, 16103 oldUserId, newUserId, uss)); 16104 } 16105 16106 void userInitialized(UserStartedState uss, int newUserId) { 16107 completeSwitchAndInitalize(uss, newUserId, true, false); 16108 } 16109 16110 void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 16111 completeSwitchAndInitalize(uss, newUserId, false, true); 16112 } 16113 16114 void completeSwitchAndInitalize(UserStartedState uss, int newUserId, 16115 boolean clearInitializing, boolean clearSwitching) { 16116 boolean unfrozen = false; 16117 synchronized (this) { 16118 if (clearInitializing) { 16119 uss.initializing = false; 16120 getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier()); 16121 } 16122 if (clearSwitching) { 16123 uss.switching = false; 16124 } 16125 if (!uss.switching && !uss.initializing) { 16126 mWindowManager.stopFreezingScreen(); 16127 unfrozen = true; 16128 } 16129 } 16130 if (unfrozen) { 16131 final int N = mUserSwitchObservers.beginBroadcast(); 16132 for (int i=0; i<N; i++) { 16133 try { 16134 mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId); 16135 } catch (RemoteException e) { 16136 } 16137 } 16138 mUserSwitchObservers.finishBroadcast(); 16139 } 16140 } 16141 16142 void finishUserSwitch(UserStartedState uss) { 16143 synchronized (this) { 16144 if (uss.mState == UserStartedState.STATE_BOOTING 16145 && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) { 16146 uss.mState = UserStartedState.STATE_RUNNING; 16147 final int userId = uss.mHandle.getIdentifier(); 16148 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 16149 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 16150 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT); 16151 broadcastIntentLocked(null, null, intent, 16152 null, null, 0, null, null, 16153 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE, 16154 true, false, MY_PID, Process.SYSTEM_UID, userId); 16155 } 16156 int num = mUserLru.size(); 16157 int i = 0; 16158 while (num > MAX_RUNNING_USERS && i < mUserLru.size()) { 16159 Integer oldUserId = mUserLru.get(i); 16160 UserStartedState oldUss = mStartedUsers.get(oldUserId); 16161 if (oldUss == null) { 16162 // Shouldn't happen, but be sane if it does. 16163 mUserLru.remove(i); 16164 num--; 16165 continue; 16166 } 16167 if (oldUss.mState == UserStartedState.STATE_STOPPING 16168 || oldUss.mState == UserStartedState.STATE_SHUTDOWN) { 16169 // This user is already stopping, doesn't count. 16170 num--; 16171 i++; 16172 continue; 16173 } 16174 if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) { 16175 // Owner and current can't be stopped, but count as running. 16176 i++; 16177 continue; 16178 } 16179 // This is a user to be stopped. 16180 stopUserLocked(oldUserId, null); 16181 num--; 16182 i++; 16183 } 16184 } 16185 } 16186 16187 @Override 16188 public int stopUser(final int userId, final IStopUserCallback callback) { 16189 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 16190 != PackageManager.PERMISSION_GRANTED) { 16191 String msg = "Permission Denial: switchUser() from pid=" 16192 + Binder.getCallingPid() 16193 + ", uid=" + Binder.getCallingUid() 16194 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 16195 Slog.w(TAG, msg); 16196 throw new SecurityException(msg); 16197 } 16198 if (userId <= 0) { 16199 throw new IllegalArgumentException("Can't stop primary user " + userId); 16200 } 16201 synchronized (this) { 16202 return stopUserLocked(userId, callback); 16203 } 16204 } 16205 16206 private int stopUserLocked(final int userId, final IStopUserCallback callback) { 16207 if (mCurrentUserId == userId) { 16208 return ActivityManager.USER_OP_IS_CURRENT; 16209 } 16210 16211 final UserStartedState uss = mStartedUsers.get(userId); 16212 if (uss == null) { 16213 // User is not started, nothing to do... but we do need to 16214 // callback if requested. 16215 if (callback != null) { 16216 mHandler.post(new Runnable() { 16217 @Override 16218 public void run() { 16219 try { 16220 callback.userStopped(userId); 16221 } catch (RemoteException e) { 16222 } 16223 } 16224 }); 16225 } 16226 return ActivityManager.USER_OP_SUCCESS; 16227 } 16228 16229 if (callback != null) { 16230 uss.mStopCallbacks.add(callback); 16231 } 16232 16233 if (uss.mState != UserStartedState.STATE_STOPPING 16234 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 16235 uss.mState = UserStartedState.STATE_STOPPING; 16236 updateStartedUserArrayLocked(); 16237 16238 long ident = Binder.clearCallingIdentity(); 16239 try { 16240 // We are going to broadcast ACTION_USER_STOPPING and then 16241 // once that is done send a final ACTION_SHUTDOWN and then 16242 // stop the user. 16243 final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING); 16244 stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 16245 stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 16246 stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true); 16247 final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN); 16248 // This is the result receiver for the final shutdown broadcast. 16249 final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() { 16250 @Override 16251 public void performReceive(Intent intent, int resultCode, String data, 16252 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 16253 finishUserStop(uss); 16254 } 16255 }; 16256 // This is the result receiver for the initial stopping broadcast. 16257 final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() { 16258 @Override 16259 public void performReceive(Intent intent, int resultCode, String data, 16260 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 16261 // On to the next. 16262 synchronized (ActivityManagerService.this) { 16263 if (uss.mState != UserStartedState.STATE_STOPPING) { 16264 // Whoops, we are being started back up. Abort, abort! 16265 return; 16266 } 16267 uss.mState = UserStartedState.STATE_SHUTDOWN; 16268 } 16269 broadcastIntentLocked(null, null, shutdownIntent, 16270 null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE, 16271 true, false, MY_PID, Process.SYSTEM_UID, userId); 16272 } 16273 }; 16274 // Kick things off. 16275 broadcastIntentLocked(null, null, stoppingIntent, 16276 null, stoppingReceiver, 0, null, null, 16277 android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 16278 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 16279 } finally { 16280 Binder.restoreCallingIdentity(ident); 16281 } 16282 } 16283 16284 return ActivityManager.USER_OP_SUCCESS; 16285 } 16286 16287 void finishUserStop(UserStartedState uss) { 16288 final int userId = uss.mHandle.getIdentifier(); 16289 boolean stopped; 16290 ArrayList<IStopUserCallback> callbacks; 16291 synchronized (this) { 16292 callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks); 16293 if (mStartedUsers.get(userId) != uss) { 16294 stopped = false; 16295 } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) { 16296 stopped = false; 16297 } else { 16298 stopped = true; 16299 // User can no longer run. 16300 mStartedUsers.remove(userId); 16301 mUserLru.remove(Integer.valueOf(userId)); 16302 updateStartedUserArrayLocked(); 16303 16304 // Clean up all state and processes associated with the user. 16305 // Kill all the processes for the user. 16306 forceStopUserLocked(userId, "finish user"); 16307 } 16308 } 16309 16310 for (int i=0; i<callbacks.size(); i++) { 16311 try { 16312 if (stopped) callbacks.get(i).userStopped(userId); 16313 else callbacks.get(i).userStopAborted(userId); 16314 } catch (RemoteException e) { 16315 } 16316 } 16317 16318 mStackSupervisor.removeUserLocked(userId); 16319 } 16320 16321 @Override 16322 public UserInfo getCurrentUser() { 16323 if ((checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) 16324 != PackageManager.PERMISSION_GRANTED) && ( 16325 checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 16326 != PackageManager.PERMISSION_GRANTED)) { 16327 String msg = "Permission Denial: getCurrentUser() from pid=" 16328 + Binder.getCallingPid() 16329 + ", uid=" + Binder.getCallingUid() 16330 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS; 16331 Slog.w(TAG, msg); 16332 throw new SecurityException(msg); 16333 } 16334 synchronized (this) { 16335 return getUserManagerLocked().getUserInfo(mCurrentUserId); 16336 } 16337 } 16338 16339 int getCurrentUserIdLocked() { 16340 return mCurrentUserId; 16341 } 16342 16343 @Override 16344 public boolean isUserRunning(int userId, boolean orStopped) { 16345 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) 16346 != PackageManager.PERMISSION_GRANTED) { 16347 String msg = "Permission Denial: isUserRunning() from pid=" 16348 + Binder.getCallingPid() 16349 + ", uid=" + Binder.getCallingUid() 16350 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS; 16351 Slog.w(TAG, msg); 16352 throw new SecurityException(msg); 16353 } 16354 synchronized (this) { 16355 return isUserRunningLocked(userId, orStopped); 16356 } 16357 } 16358 16359 boolean isUserRunningLocked(int userId, boolean orStopped) { 16360 UserStartedState state = mStartedUsers.get(userId); 16361 if (state == null) { 16362 return false; 16363 } 16364 if (orStopped) { 16365 return true; 16366 } 16367 return state.mState != UserStartedState.STATE_STOPPING 16368 && state.mState != UserStartedState.STATE_SHUTDOWN; 16369 } 16370 16371 @Override 16372 public int[] getRunningUserIds() { 16373 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) 16374 != PackageManager.PERMISSION_GRANTED) { 16375 String msg = "Permission Denial: isUserRunning() from pid=" 16376 + Binder.getCallingPid() 16377 + ", uid=" + Binder.getCallingUid() 16378 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS; 16379 Slog.w(TAG, msg); 16380 throw new SecurityException(msg); 16381 } 16382 synchronized (this) { 16383 return mStartedUserArray; 16384 } 16385 } 16386 16387 private void updateStartedUserArrayLocked() { 16388 int num = 0; 16389 for (int i=0; i<mStartedUsers.size(); i++) { 16390 UserStartedState uss = mStartedUsers.valueAt(i); 16391 // This list does not include stopping users. 16392 if (uss.mState != UserStartedState.STATE_STOPPING 16393 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 16394 num++; 16395 } 16396 } 16397 mStartedUserArray = new int[num]; 16398 num = 0; 16399 for (int i=0; i<mStartedUsers.size(); i++) { 16400 UserStartedState uss = mStartedUsers.valueAt(i); 16401 if (uss.mState != UserStartedState.STATE_STOPPING 16402 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 16403 mStartedUserArray[num] = mStartedUsers.keyAt(i); 16404 num++; 16405 } 16406 } 16407 } 16408 16409 @Override 16410 public void registerUserSwitchObserver(IUserSwitchObserver observer) { 16411 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 16412 != PackageManager.PERMISSION_GRANTED) { 16413 String msg = "Permission Denial: registerUserSwitchObserver() from pid=" 16414 + Binder.getCallingPid() 16415 + ", uid=" + Binder.getCallingUid() 16416 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 16417 Slog.w(TAG, msg); 16418 throw new SecurityException(msg); 16419 } 16420 16421 mUserSwitchObservers.register(observer); 16422 } 16423 16424 @Override 16425 public void unregisterUserSwitchObserver(IUserSwitchObserver observer) { 16426 mUserSwitchObservers.unregister(observer); 16427 } 16428 16429 private boolean userExists(int userId) { 16430 if (userId == 0) { 16431 return true; 16432 } 16433 UserManagerService ums = getUserManagerLocked(); 16434 return ums != null ? (ums.getUserInfo(userId) != null) : false; 16435 } 16436 16437 int[] getUsersLocked() { 16438 UserManagerService ums = getUserManagerLocked(); 16439 return ums != null ? ums.getUserIds() : new int[] { 0 }; 16440 } 16441 16442 UserManagerService getUserManagerLocked() { 16443 if (mUserManager == null) { 16444 IBinder b = ServiceManager.getService(Context.USER_SERVICE); 16445 mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b); 16446 } 16447 return mUserManager; 16448 } 16449 16450 private int applyUserId(int uid, int userId) { 16451 return UserHandle.getUid(userId, uid); 16452 } 16453 16454 ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) { 16455 if (info == null) return null; 16456 ApplicationInfo newInfo = new ApplicationInfo(info); 16457 newInfo.uid = applyUserId(info.uid, userId); 16458 newInfo.dataDir = USER_DATA_DIR + userId + "/" 16459 + info.packageName; 16460 return newInfo; 16461 } 16462 16463 ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) { 16464 if (aInfo == null 16465 || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) { 16466 return aInfo; 16467 } 16468 16469 ActivityInfo info = new ActivityInfo(aInfo); 16470 info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId); 16471 return info; 16472 } 16473 16474 private final class LocalService extends ActivityManagerInternal { 16475 @Override 16476 public void goingToSleep() { 16477 ActivityManagerService.this.goingToSleep(); 16478 } 16479 16480 @Override 16481 public void wakingUp() { 16482 ActivityManagerService.this.wakingUp(); 16483 } 16484 } 16485} 16486