ActivityManagerService.java revision 9e289d70a8baaed0030413b5991653792e2a816d
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.os.Zygote; 46import com.android.internal.util.FastPrintWriter; 47import com.android.internal.util.FastXmlSerializer; 48import com.android.internal.util.MemInfoReader; 49import com.android.internal.util.Preconditions; 50import com.android.server.AppOpsService; 51import com.android.server.AttributeCache; 52import com.android.server.IntentResolver; 53import com.android.server.LocalServices; 54import com.android.server.ServiceThread; 55import com.android.server.SystemService; 56import com.android.server.Watchdog; 57import com.android.server.am.ActivityStack.ActivityState; 58import com.android.server.firewall.IntentFirewall; 59import com.android.server.pm.UserManagerService; 60import com.android.server.wm.AppTransition; 61import com.android.server.wm.WindowManagerService; 62import com.google.android.collect.Lists; 63import com.google.android.collect.Maps; 64 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 /** 344 * Description of a request to start a new activity, which has been held 345 * due to app switches being disabled. 346 */ 347 static class PendingActivityLaunch { 348 final ActivityRecord r; 349 final ActivityRecord sourceRecord; 350 final int startFlags; 351 final ActivityStack stack; 352 353 PendingActivityLaunch(ActivityRecord _r, ActivityRecord _sourceRecord, 354 int _startFlags, ActivityStack _stack) { 355 r = _r; 356 sourceRecord = _sourceRecord; 357 startFlags = _startFlags; 358 stack = _stack; 359 } 360 } 361 362 final ArrayList<PendingActivityLaunch> mPendingActivityLaunches 363 = new ArrayList<PendingActivityLaunch>(); 364 365 BroadcastQueue mFgBroadcastQueue; 366 BroadcastQueue mBgBroadcastQueue; 367 // Convenient for easy iteration over the queues. Foreground is first 368 // so that dispatch of foreground broadcasts gets precedence. 369 final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2]; 370 371 BroadcastQueue broadcastQueueForIntent(Intent intent) { 372 final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0; 373 if (DEBUG_BACKGROUND_BROADCAST) { 374 Slog.i(TAG, "Broadcast intent " + intent + " on " 375 + (isFg ? "foreground" : "background") 376 + " queue"); 377 } 378 return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue; 379 } 380 381 BroadcastRecord broadcastRecordForReceiverLocked(IBinder receiver) { 382 for (BroadcastQueue queue : mBroadcastQueues) { 383 BroadcastRecord r = queue.getMatchingOrderedReceiver(receiver); 384 if (r != null) { 385 return r; 386 } 387 } 388 return null; 389 } 390 391 /** 392 * Activity we have told the window manager to have key focus. 393 */ 394 ActivityRecord mFocusedActivity = null; 395 396 /** 397 * List of intents that were used to start the most recent tasks. 398 */ 399 private final ArrayList<TaskRecord> mRecentTasks = new ArrayList<TaskRecord>(); 400 401 public class PendingAssistExtras extends Binder implements Runnable { 402 public final ActivityRecord activity; 403 public boolean haveResult = false; 404 public Bundle result = null; 405 public PendingAssistExtras(ActivityRecord _activity) { 406 activity = _activity; 407 } 408 @Override 409 public void run() { 410 Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity); 411 synchronized (this) { 412 haveResult = true; 413 notifyAll(); 414 } 415 } 416 } 417 418 final ArrayList<PendingAssistExtras> mPendingAssistExtras 419 = new ArrayList<PendingAssistExtras>(); 420 421 /** 422 * Process management. 423 */ 424 final ProcessList mProcessList = new ProcessList(); 425 426 /** 427 * All of the applications we currently have running organized by name. 428 * The keys are strings of the application package name (as 429 * returned by the package manager), and the keys are ApplicationRecord 430 * objects. 431 */ 432 final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>(); 433 434 /** 435 * Tracking long-term execution of processes to look for abuse and other 436 * bad app behavior. 437 */ 438 final ProcessStatsService mProcessStats; 439 440 /** 441 * The currently running isolated processes. 442 */ 443 final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>(); 444 445 /** 446 * Counter for assigning isolated process uids, to avoid frequently reusing the 447 * same ones. 448 */ 449 int mNextIsolatedProcessUid = 0; 450 451 /** 452 * The currently running heavy-weight process, if any. 453 */ 454 ProcessRecord mHeavyWeightProcess = null; 455 456 /** 457 * The last time that various processes have crashed. 458 */ 459 final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>(); 460 461 /** 462 * Information about a process that is currently marked as bad. 463 */ 464 static final class BadProcessInfo { 465 BadProcessInfo(long time, String shortMsg, String longMsg, String stack) { 466 this.time = time; 467 this.shortMsg = shortMsg; 468 this.longMsg = longMsg; 469 this.stack = stack; 470 } 471 472 final long time; 473 final String shortMsg; 474 final String longMsg; 475 final String stack; 476 } 477 478 /** 479 * Set of applications that we consider to be bad, and will reject 480 * incoming broadcasts from (which the user has no control over). 481 * Processes are added to this set when they have crashed twice within 482 * a minimum amount of time; they are removed from it when they are 483 * later restarted (hopefully due to some user action). The value is the 484 * time it was added to the list. 485 */ 486 final ProcessMap<BadProcessInfo> mBadProcesses = new ProcessMap<BadProcessInfo>(); 487 488 /** 489 * All of the processes we currently have running organized by pid. 490 * The keys are the pid running the application. 491 * 492 * <p>NOTE: This object is protected by its own lock, NOT the global 493 * activity manager lock! 494 */ 495 final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>(); 496 497 /** 498 * All of the processes that have been forced to be foreground. The key 499 * is the pid of the caller who requested it (we hold a death 500 * link on it). 501 */ 502 abstract class ForegroundToken implements IBinder.DeathRecipient { 503 int pid; 504 IBinder token; 505 } 506 final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>(); 507 508 /** 509 * List of records for processes that someone had tried to start before the 510 * system was ready. We don't start them at that point, but ensure they 511 * are started by the time booting is complete. 512 */ 513 final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>(); 514 515 /** 516 * List of persistent applications that are in the process 517 * of being started. 518 */ 519 final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>(); 520 521 /** 522 * Processes that are being forcibly torn down. 523 */ 524 final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>(); 525 526 /** 527 * List of running applications, sorted by recent usage. 528 * The first entry in the list is the least recently used. 529 */ 530 final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>(); 531 532 /** 533 * Where in mLruProcesses that the processes hosting activities start. 534 */ 535 int mLruProcessActivityStart = 0; 536 537 /** 538 * Where in mLruProcesses that the processes hosting services start. 539 * This is after (lower index) than mLruProcessesActivityStart. 540 */ 541 int mLruProcessServiceStart = 0; 542 543 /** 544 * List of processes that should gc as soon as things are idle. 545 */ 546 final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>(); 547 548 /** 549 * Processes we want to collect PSS data from. 550 */ 551 final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>(); 552 553 /** 554 * Last time we requested PSS data of all processes. 555 */ 556 long mLastFullPssTime = SystemClock.uptimeMillis(); 557 558 /** 559 * This is the process holding what we currently consider to be 560 * the "home" activity. 561 */ 562 ProcessRecord mHomeProcess; 563 564 /** 565 * This is the process holding the activity the user last visited that 566 * is in a different process from the one they are currently in. 567 */ 568 ProcessRecord mPreviousProcess; 569 570 /** 571 * The time at which the previous process was last visible. 572 */ 573 long mPreviousProcessVisibleTime; 574 575 /** 576 * Which uses have been started, so are allowed to run code. 577 */ 578 final SparseArray<UserStartedState> mStartedUsers = new SparseArray<UserStartedState>(); 579 580 /** 581 * LRU list of history of current users. Most recently current is at the end. 582 */ 583 final ArrayList<Integer> mUserLru = new ArrayList<Integer>(); 584 585 /** 586 * Constant array of the users that are currently started. 587 */ 588 int[] mStartedUserArray = new int[] { 0 }; 589 590 /** 591 * Registered observers of the user switching mechanics. 592 */ 593 final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers 594 = new RemoteCallbackList<IUserSwitchObserver>(); 595 596 /** 597 * Currently active user switch. 598 */ 599 Object mCurUserSwitchCallback; 600 601 /** 602 * Packages that the user has asked to have run in screen size 603 * compatibility mode instead of filling the screen. 604 */ 605 final CompatModePackages mCompatModePackages; 606 607 /** 608 * Set of IntentSenderRecord objects that are currently active. 609 */ 610 final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords 611 = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>(); 612 613 /** 614 * Fingerprints (hashCode()) of stack traces that we've 615 * already logged DropBox entries for. Guarded by itself. If 616 * something (rogue user app) forces this over 617 * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared. 618 */ 619 private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>(); 620 private static final int MAX_DUP_SUPPRESSED_STACKS = 5000; 621 622 /** 623 * Strict Mode background batched logging state. 624 * 625 * The string buffer is guarded by itself, and its lock is also 626 * used to determine if another batched write is already 627 * in-flight. 628 */ 629 private final StringBuilder mStrictModeBuffer = new StringBuilder(); 630 631 /** 632 * Keeps track of all IIntentReceivers that have been registered for 633 * broadcasts. Hash keys are the receiver IBinder, hash value is 634 * a ReceiverList. 635 */ 636 final HashMap<IBinder, ReceiverList> mRegisteredReceivers = 637 new HashMap<IBinder, ReceiverList>(); 638 639 /** 640 * Resolver for broadcast intents to registered receivers. 641 * Holds BroadcastFilter (subclass of IntentFilter). 642 */ 643 final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver 644 = new IntentResolver<BroadcastFilter, BroadcastFilter>() { 645 @Override 646 protected boolean allowFilterResult( 647 BroadcastFilter filter, List<BroadcastFilter> dest) { 648 IBinder target = filter.receiverList.receiver.asBinder(); 649 for (int i=dest.size()-1; i>=0; i--) { 650 if (dest.get(i).receiverList.receiver.asBinder() == target) { 651 return false; 652 } 653 } 654 return true; 655 } 656 657 @Override 658 protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) { 659 if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL 660 || userId == filter.owningUserId) { 661 return super.newResult(filter, match, userId); 662 } 663 return null; 664 } 665 666 @Override 667 protected BroadcastFilter[] newArray(int size) { 668 return new BroadcastFilter[size]; 669 } 670 671 @Override 672 protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) { 673 return packageName.equals(filter.packageName); 674 } 675 }; 676 677 /** 678 * State of all active sticky broadcasts per user. Keys are the action of the 679 * sticky Intent, values are an ArrayList of all broadcasted intents with 680 * that action (which should usually be one). The SparseArray is keyed 681 * by the user ID the sticky is for, and can include UserHandle.USER_ALL 682 * for stickies that are sent to all users. 683 */ 684 final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts = 685 new SparseArray<ArrayMap<String, ArrayList<Intent>>>(); 686 687 final ActiveServices mServices; 688 689 /** 690 * Backup/restore process management 691 */ 692 String mBackupAppName = null; 693 BackupRecord mBackupTarget = null; 694 695 /** 696 * List of PendingThumbnailsRecord objects of clients who are still 697 * waiting to receive all of the thumbnails for a task. 698 */ 699 final ArrayList<PendingThumbnailsRecord> mPendingThumbnails = 700 new ArrayList<PendingThumbnailsRecord>(); 701 702 final ProviderMap mProviderMap; 703 704 /** 705 * List of content providers who have clients waiting for them. The 706 * application is currently being launched and the provider will be 707 * removed from this list once it is published. 708 */ 709 final ArrayList<ContentProviderRecord> mLaunchingProviders 710 = new ArrayList<ContentProviderRecord>(); 711 712 /** 713 * File storing persisted {@link #mGrantedUriPermissions}. 714 */ 715 private final AtomicFile mGrantFile; 716 717 /** XML constants used in {@link #mGrantFile} */ 718 private static final String TAG_URI_GRANTS = "uri-grants"; 719 private static final String TAG_URI_GRANT = "uri-grant"; 720 private static final String ATTR_USER_HANDLE = "userHandle"; 721 private static final String ATTR_SOURCE_PKG = "sourcePkg"; 722 private static final String ATTR_TARGET_PKG = "targetPkg"; 723 private static final String ATTR_URI = "uri"; 724 private static final String ATTR_MODE_FLAGS = "modeFlags"; 725 private static final String ATTR_CREATED_TIME = "createdTime"; 726 727 /** 728 * Global set of specific {@link Uri} permissions that have been granted. 729 * This optimized lookup structure maps from {@link UriPermission#targetUid} 730 * to {@link UriPermission#uri} to {@link UriPermission}. 731 */ 732 @GuardedBy("this") 733 private final SparseArray<ArrayMap<Uri, UriPermission>> 734 mGrantedUriPermissions = new SparseArray<ArrayMap<Uri, UriPermission>>(); 735 736 CoreSettingsObserver mCoreSettingsObserver; 737 738 /** 739 * Thread-local storage used to carry caller permissions over through 740 * indirect content-provider access. 741 */ 742 private class Identity { 743 public int pid; 744 public int uid; 745 746 Identity(int _pid, int _uid) { 747 pid = _pid; 748 uid = _uid; 749 } 750 } 751 752 private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>(); 753 754 /** 755 * All information we have collected about the runtime performance of 756 * any user id that can impact battery performance. 757 */ 758 final BatteryStatsService mBatteryStatsService; 759 760 /** 761 * Information about component usage 762 */ 763 final UsageStatsService mUsageStatsService; 764 765 /** 766 * Information about and control over application operations 767 */ 768 final AppOpsService mAppOpsService; 769 770 /** 771 * Current configuration information. HistoryRecord objects are given 772 * a reference to this object to indicate which configuration they are 773 * currently running in, so this object must be kept immutable. 774 */ 775 Configuration mConfiguration = new Configuration(); 776 777 /** 778 * Current sequencing integer of the configuration, for skipping old 779 * configurations. 780 */ 781 int mConfigurationSeq = 0; 782 783 /** 784 * Hardware-reported OpenGLES version. 785 */ 786 final int GL_ES_VERSION; 787 788 /** 789 * List of initialization arguments to pass to all processes when binding applications to them. 790 * For example, references to the commonly used services. 791 */ 792 HashMap<String, IBinder> mAppBindArgs; 793 794 /** 795 * Temporary to avoid allocations. Protected by main lock. 796 */ 797 final StringBuilder mStringBuilder = new StringBuilder(256); 798 799 /** 800 * Used to control how we initialize the service. 801 */ 802 ComponentName mTopComponent; 803 String mTopAction = Intent.ACTION_MAIN; 804 String mTopData; 805 boolean mProcessesReady = false; 806 boolean mSystemReady = false; 807 boolean mBooting = false; 808 boolean mWaitingUpdate = false; 809 boolean mDidUpdate = false; 810 boolean mOnBattery = false; 811 boolean mLaunchWarningShown = false; 812 813 Context mContext; 814 815 int mFactoryTest; 816 817 boolean mCheckedForSetup; 818 819 /** 820 * The time at which we will allow normal application switches again, 821 * after a call to {@link #stopAppSwitches()}. 822 */ 823 long mAppSwitchesAllowedTime; 824 825 /** 826 * This is set to true after the first switch after mAppSwitchesAllowedTime 827 * is set; any switches after that will clear the time. 828 */ 829 boolean mDidAppSwitch; 830 831 /** 832 * Last time (in realtime) at which we checked for power usage. 833 */ 834 long mLastPowerCheckRealtime; 835 836 /** 837 * Last time (in uptime) at which we checked for power usage. 838 */ 839 long mLastPowerCheckUptime; 840 841 /** 842 * Set while we are wanting to sleep, to prevent any 843 * activities from being started/resumed. 844 */ 845 boolean mSleeping = false; 846 847 /** 848 * State of external calls telling us if the device is asleep. 849 */ 850 boolean mWentToSleep = false; 851 852 /** 853 * State of external call telling us if the lock screen is shown. 854 */ 855 boolean mLockScreenShown = false; 856 857 /** 858 * Set if we are shutting down the system, similar to sleeping. 859 */ 860 boolean mShuttingDown = false; 861 862 /** 863 * Current sequence id for oom_adj computation traversal. 864 */ 865 int mAdjSeq = 0; 866 867 /** 868 * Current sequence id for process LRU updating. 869 */ 870 int mLruSeq = 0; 871 872 /** 873 * Keep track of the non-cached/empty process we last found, to help 874 * determine how to distribute cached/empty processes next time. 875 */ 876 int mNumNonCachedProcs = 0; 877 878 /** 879 * Keep track of the number of cached hidden procs, to balance oom adj 880 * distribution between those and empty procs. 881 */ 882 int mNumCachedHiddenProcs = 0; 883 884 /** 885 * Keep track of the number of service processes we last found, to 886 * determine on the next iteration which should be B services. 887 */ 888 int mNumServiceProcs = 0; 889 int mNewNumAServiceProcs = 0; 890 int mNewNumServiceProcs = 0; 891 892 /** 893 * Allow the current computed overall memory level of the system to go down? 894 * This is set to false when we are killing processes for reasons other than 895 * memory management, so that the now smaller process list will not be taken as 896 * an indication that memory is tighter. 897 */ 898 boolean mAllowLowerMemLevel = false; 899 900 /** 901 * The last computed memory level, for holding when we are in a state that 902 * processes are going away for other reasons. 903 */ 904 int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL; 905 906 /** 907 * The last total number of process we have, to determine if changes actually look 908 * like a shrinking number of process due to lower RAM. 909 */ 910 int mLastNumProcesses; 911 912 /** 913 * The uptime of the last time we performed idle maintenance. 914 */ 915 long mLastIdleTime = SystemClock.uptimeMillis(); 916 917 /** 918 * Total time spent with RAM that has been added in the past since the last idle time. 919 */ 920 long mLowRamTimeSinceLastIdle = 0; 921 922 /** 923 * If RAM is currently low, when that horrible situatin started. 924 */ 925 long mLowRamStartTime = 0; 926 927 /** 928 * This is set if we had to do a delayed dexopt of an app before launching 929 * it, to increasing the ANR timeouts in that case. 930 */ 931 boolean mDidDexOpt; 932 933 /** 934 * Set if the systemServer made a call to enterSafeMode. 935 */ 936 boolean mSafeMode; 937 938 String mDebugApp = null; 939 boolean mWaitForDebugger = false; 940 boolean mDebugTransient = false; 941 String mOrigDebugApp = null; 942 boolean mOrigWaitForDebugger = false; 943 boolean mAlwaysFinishActivities = false; 944 IActivityController mController = null; 945 String mProfileApp = null; 946 ProcessRecord mProfileProc = null; 947 String mProfileFile; 948 ParcelFileDescriptor mProfileFd; 949 int mProfileType = 0; 950 boolean mAutoStopProfiler = false; 951 String mOpenGlTraceApp = null; 952 953 static class ProcessChangeItem { 954 static final int CHANGE_ACTIVITIES = 1<<0; 955 static final int CHANGE_IMPORTANCE= 1<<1; 956 int changes; 957 int uid; 958 int pid; 959 int importance; 960 boolean foregroundActivities; 961 } 962 963 final RemoteCallbackList<IProcessObserver> mProcessObservers 964 = new RemoteCallbackList<IProcessObserver>(); 965 ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5]; 966 967 final ArrayList<ProcessChangeItem> mPendingProcessChanges 968 = new ArrayList<ProcessChangeItem>(); 969 final ArrayList<ProcessChangeItem> mAvailProcessChanges 970 = new ArrayList<ProcessChangeItem>(); 971 972 /** 973 * Runtime CPU use collection thread. This object's lock is used to 974 * protect all related state. 975 */ 976 final Thread mProcessCpuThread; 977 978 /** 979 * Used to collect process stats when showing not responding dialog. 980 * Protected by mProcessCpuThread. 981 */ 982 final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker( 983 MONITOR_THREAD_CPU_USAGE); 984 final AtomicLong mLastCpuTime = new AtomicLong(0); 985 final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true); 986 987 long mLastWriteTime = 0; 988 989 /** 990 * Used to retain an update lock when the foreground activity is in 991 * immersive mode. 992 */ 993 final UpdateLock mUpdateLock = new UpdateLock("immersive"); 994 995 /** 996 * Set to true after the system has finished booting. 997 */ 998 boolean mBooted = false; 999 1000 int mProcessLimit = ProcessList.MAX_CACHED_APPS; 1001 int mProcessLimitOverride = -1; 1002 1003 WindowManagerService mWindowManager; 1004 1005 final ActivityThread mSystemThread; 1006 1007 int mCurrentUserId = 0; 1008 private UserManagerService mUserManager; 1009 1010 private final class AppDeathRecipient implements IBinder.DeathRecipient { 1011 final ProcessRecord mApp; 1012 final int mPid; 1013 final IApplicationThread mAppThread; 1014 1015 AppDeathRecipient(ProcessRecord app, int pid, 1016 IApplicationThread thread) { 1017 if (localLOGV) Slog.v( 1018 TAG, "New death recipient " + this 1019 + " for thread " + thread.asBinder()); 1020 mApp = app; 1021 mPid = pid; 1022 mAppThread = thread; 1023 } 1024 1025 @Override 1026 public void binderDied() { 1027 if (localLOGV) Slog.v( 1028 TAG, "Death received in " + this 1029 + " for thread " + mAppThread.asBinder()); 1030 synchronized(ActivityManagerService.this) { 1031 appDiedLocked(mApp, mPid, mAppThread); 1032 } 1033 } 1034 } 1035 1036 static final int SHOW_ERROR_MSG = 1; 1037 static final int SHOW_NOT_RESPONDING_MSG = 2; 1038 static final int SHOW_FACTORY_ERROR_MSG = 3; 1039 static final int UPDATE_CONFIGURATION_MSG = 4; 1040 static final int GC_BACKGROUND_PROCESSES_MSG = 5; 1041 static final int WAIT_FOR_DEBUGGER_MSG = 6; 1042 static final int SERVICE_TIMEOUT_MSG = 12; 1043 static final int UPDATE_TIME_ZONE = 13; 1044 static final int SHOW_UID_ERROR_MSG = 14; 1045 static final int IM_FEELING_LUCKY_MSG = 15; 1046 static final int PROC_START_TIMEOUT_MSG = 20; 1047 static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21; 1048 static final int KILL_APPLICATION_MSG = 22; 1049 static final int FINALIZE_PENDING_INTENT_MSG = 23; 1050 static final int POST_HEAVY_NOTIFICATION_MSG = 24; 1051 static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25; 1052 static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26; 1053 static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27; 1054 static final int CLEAR_DNS_CACHE_MSG = 28; 1055 static final int UPDATE_HTTP_PROXY_MSG = 29; 1056 static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30; 1057 static final int DISPATCH_PROCESSES_CHANGED = 31; 1058 static final int DISPATCH_PROCESS_DIED = 32; 1059 static final int REPORT_MEM_USAGE_MSG = 33; 1060 static final int REPORT_USER_SWITCH_MSG = 34; 1061 static final int CONTINUE_USER_SWITCH_MSG = 35; 1062 static final int USER_SWITCH_TIMEOUT_MSG = 36; 1063 static final int IMMERSIVE_MODE_LOCK_MSG = 37; 1064 static final int PERSIST_URI_GRANTS_MSG = 38; 1065 static final int REQUEST_ALL_PSS_MSG = 39; 1066 static final int UPDATE_TIME = 40; 1067 1068 static final int FIRST_ACTIVITY_STACK_MSG = 100; 1069 static final int FIRST_BROADCAST_QUEUE_MSG = 200; 1070 static final int FIRST_COMPAT_MODE_MSG = 300; 1071 static final int FIRST_SUPERVISOR_STACK_MSG = 100; 1072 1073 AlertDialog mUidAlert; 1074 CompatModeDialog mCompatModeDialog; 1075 long mLastMemUsageReportTime = 0; 1076 1077 /** 1078 * Flag whether the current user is a "monkey", i.e. whether 1079 * the UI is driven by a UI automation tool. 1080 */ 1081 private boolean mUserIsMonkey; 1082 1083 final ServiceThread mHandlerThread; 1084 final MainHandler mHandler; 1085 1086 final class MainHandler extends Handler { 1087 public MainHandler(Looper looper) { 1088 super(looper, null, true); 1089 } 1090 1091 @Override 1092 public void handleMessage(Message msg) { 1093 switch (msg.what) { 1094 case SHOW_ERROR_MSG: { 1095 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1096 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), 1097 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; 1098 synchronized (ActivityManagerService.this) { 1099 ProcessRecord proc = (ProcessRecord)data.get("app"); 1100 AppErrorResult res = (AppErrorResult) data.get("result"); 1101 if (proc != null && proc.crashDialog != null) { 1102 Slog.e(TAG, "App already has crash dialog: " + proc); 1103 if (res != null) { 1104 res.set(0); 1105 } 1106 return; 1107 } 1108 if (!showBackground && UserHandle.getAppId(proc.uid) 1109 >= Process.FIRST_APPLICATION_UID && proc.userId != mCurrentUserId 1110 && proc.pid != MY_PID) { 1111 Slog.w(TAG, "Skipping crash dialog of " + proc + ": background"); 1112 if (res != null) { 1113 res.set(0); 1114 } 1115 return; 1116 } 1117 if (mShowDialogs && !mSleeping && !mShuttingDown) { 1118 Dialog d = new AppErrorDialog(mContext, 1119 ActivityManagerService.this, res, proc); 1120 d.show(); 1121 proc.crashDialog = d; 1122 } else { 1123 // The device is asleep, so just pretend that the user 1124 // saw a crash dialog and hit "force quit". 1125 if (res != null) { 1126 res.set(0); 1127 } 1128 } 1129 } 1130 1131 ensureBootCompleted(); 1132 } break; 1133 case SHOW_NOT_RESPONDING_MSG: { 1134 synchronized (ActivityManagerService.this) { 1135 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1136 ProcessRecord proc = (ProcessRecord)data.get("app"); 1137 if (proc != null && proc.anrDialog != null) { 1138 Slog.e(TAG, "App already has anr dialog: " + proc); 1139 return; 1140 } 1141 1142 Intent intent = new Intent("android.intent.action.ANR"); 1143 if (!mProcessesReady) { 1144 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 1145 | Intent.FLAG_RECEIVER_FOREGROUND); 1146 } 1147 broadcastIntentLocked(null, null, intent, 1148 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 1149 false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */); 1150 1151 if (mShowDialogs) { 1152 Dialog d = new AppNotRespondingDialog(ActivityManagerService.this, 1153 mContext, proc, (ActivityRecord)data.get("activity"), 1154 msg.arg1 != 0); 1155 d.show(); 1156 proc.anrDialog = d; 1157 } else { 1158 // Just kill the app if there is no dialog to be shown. 1159 killAppAtUsersRequest(proc, null); 1160 } 1161 } 1162 1163 ensureBootCompleted(); 1164 } break; 1165 case SHOW_STRICT_MODE_VIOLATION_MSG: { 1166 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1167 synchronized (ActivityManagerService.this) { 1168 ProcessRecord proc = (ProcessRecord) data.get("app"); 1169 if (proc == null) { 1170 Slog.e(TAG, "App not found when showing strict mode dialog."); 1171 break; 1172 } 1173 if (proc.crashDialog != null) { 1174 Slog.e(TAG, "App already has strict mode dialog: " + proc); 1175 return; 1176 } 1177 AppErrorResult res = (AppErrorResult) data.get("result"); 1178 if (mShowDialogs && !mSleeping && !mShuttingDown) { 1179 Dialog d = new StrictModeViolationDialog(mContext, 1180 ActivityManagerService.this, res, proc); 1181 d.show(); 1182 proc.crashDialog = d; 1183 } else { 1184 // The device is asleep, so just pretend that the user 1185 // saw a crash dialog and hit "force quit". 1186 res.set(0); 1187 } 1188 } 1189 ensureBootCompleted(); 1190 } break; 1191 case SHOW_FACTORY_ERROR_MSG: { 1192 Dialog d = new FactoryErrorDialog( 1193 mContext, msg.getData().getCharSequence("msg")); 1194 d.show(); 1195 ensureBootCompleted(); 1196 } break; 1197 case UPDATE_CONFIGURATION_MSG: { 1198 final ContentResolver resolver = mContext.getContentResolver(); 1199 Settings.System.putConfiguration(resolver, (Configuration)msg.obj); 1200 } break; 1201 case GC_BACKGROUND_PROCESSES_MSG: { 1202 synchronized (ActivityManagerService.this) { 1203 performAppGcsIfAppropriateLocked(); 1204 } 1205 } break; 1206 case WAIT_FOR_DEBUGGER_MSG: { 1207 synchronized (ActivityManagerService.this) { 1208 ProcessRecord app = (ProcessRecord)msg.obj; 1209 if (msg.arg1 != 0) { 1210 if (!app.waitedForDebugger) { 1211 Dialog d = new AppWaitingForDebuggerDialog( 1212 ActivityManagerService.this, 1213 mContext, app); 1214 app.waitDialog = d; 1215 app.waitedForDebugger = true; 1216 d.show(); 1217 } 1218 } else { 1219 if (app.waitDialog != null) { 1220 app.waitDialog.dismiss(); 1221 app.waitDialog = null; 1222 } 1223 } 1224 } 1225 } break; 1226 case SERVICE_TIMEOUT_MSG: { 1227 if (mDidDexOpt) { 1228 mDidDexOpt = false; 1229 Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG); 1230 nmsg.obj = msg.obj; 1231 mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT); 1232 return; 1233 } 1234 mServices.serviceTimeout((ProcessRecord)msg.obj); 1235 } break; 1236 case UPDATE_TIME_ZONE: { 1237 synchronized (ActivityManagerService.this) { 1238 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1239 ProcessRecord r = mLruProcesses.get(i); 1240 if (r.thread != null) { 1241 try { 1242 r.thread.updateTimeZone(); 1243 } catch (RemoteException ex) { 1244 Slog.w(TAG, "Failed to update time zone for: " + r.info.processName); 1245 } 1246 } 1247 } 1248 } 1249 } break; 1250 case CLEAR_DNS_CACHE_MSG: { 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.clearDnsCache(); 1257 } catch (RemoteException ex) { 1258 Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName); 1259 } 1260 } 1261 } 1262 } 1263 } break; 1264 case UPDATE_HTTP_PROXY_MSG: { 1265 ProxyProperties proxy = (ProxyProperties)msg.obj; 1266 String host = ""; 1267 String port = ""; 1268 String exclList = ""; 1269 String pacFileUrl = null; 1270 if (proxy != null) { 1271 host = proxy.getHost(); 1272 port = Integer.toString(proxy.getPort()); 1273 exclList = proxy.getExclusionList(); 1274 pacFileUrl = proxy.getPacFileUrl(); 1275 } 1276 synchronized (ActivityManagerService.this) { 1277 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1278 ProcessRecord r = mLruProcesses.get(i); 1279 if (r.thread != null) { 1280 try { 1281 r.thread.setHttpProxy(host, port, exclList, pacFileUrl); 1282 } catch (RemoteException ex) { 1283 Slog.w(TAG, "Failed to update http proxy for: " + 1284 r.info.processName); 1285 } 1286 } 1287 } 1288 } 1289 } break; 1290 case SHOW_UID_ERROR_MSG: { 1291 String title = "System UIDs Inconsistent"; 1292 String text = "UIDs on the system are inconsistent, you need to wipe your" 1293 + " data partition or your device will be unstable."; 1294 Log.e(TAG, title + ": " + text); 1295 if (mShowDialogs) { 1296 // XXX This is a temporary dialog, no need to localize. 1297 AlertDialog d = new BaseErrorDialog(mContext); 1298 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR); 1299 d.setCancelable(false); 1300 d.setTitle(title); 1301 d.setMessage(text); 1302 d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky", 1303 mHandler.obtainMessage(IM_FEELING_LUCKY_MSG)); 1304 mUidAlert = d; 1305 d.show(); 1306 } 1307 } break; 1308 case IM_FEELING_LUCKY_MSG: { 1309 if (mUidAlert != null) { 1310 mUidAlert.dismiss(); 1311 mUidAlert = null; 1312 } 1313 } break; 1314 case PROC_START_TIMEOUT_MSG: { 1315 if (mDidDexOpt) { 1316 mDidDexOpt = false; 1317 Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 1318 nmsg.obj = msg.obj; 1319 mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT); 1320 return; 1321 } 1322 ProcessRecord app = (ProcessRecord)msg.obj; 1323 synchronized (ActivityManagerService.this) { 1324 processStartTimedOutLocked(app); 1325 } 1326 } break; 1327 case DO_PENDING_ACTIVITY_LAUNCHES_MSG: { 1328 synchronized (ActivityManagerService.this) { 1329 doPendingActivityLaunchesLocked(true); 1330 } 1331 } break; 1332 case KILL_APPLICATION_MSG: { 1333 synchronized (ActivityManagerService.this) { 1334 int appid = msg.arg1; 1335 boolean restart = (msg.arg2 == 1); 1336 Bundle bundle = (Bundle)msg.obj; 1337 String pkg = bundle.getString("pkg"); 1338 String reason = bundle.getString("reason"); 1339 forceStopPackageLocked(pkg, appid, restart, false, true, false, 1340 UserHandle.USER_ALL, reason); 1341 } 1342 } break; 1343 case FINALIZE_PENDING_INTENT_MSG: { 1344 ((PendingIntentRecord)msg.obj).completeFinalize(); 1345 } break; 1346 case POST_HEAVY_NOTIFICATION_MSG: { 1347 INotificationManager inm = NotificationManager.getService(); 1348 if (inm == null) { 1349 return; 1350 } 1351 1352 ActivityRecord root = (ActivityRecord)msg.obj; 1353 ProcessRecord process = root.app; 1354 if (process == null) { 1355 return; 1356 } 1357 1358 try { 1359 Context context = mContext.createPackageContext(process.info.packageName, 0); 1360 String text = mContext.getString(R.string.heavy_weight_notification, 1361 context.getApplicationInfo().loadLabel(context.getPackageManager())); 1362 Notification notification = new Notification(); 1363 notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon; 1364 notification.when = 0; 1365 notification.flags = Notification.FLAG_ONGOING_EVENT; 1366 notification.tickerText = text; 1367 notification.defaults = 0; // please be quiet 1368 notification.sound = null; 1369 notification.vibrate = null; 1370 notification.setLatestEventInfo(context, text, 1371 mContext.getText(R.string.heavy_weight_notification_detail), 1372 PendingIntent.getActivityAsUser(mContext, 0, root.intent, 1373 PendingIntent.FLAG_CANCEL_CURRENT, null, 1374 new UserHandle(root.userId))); 1375 1376 try { 1377 int[] outId = new int[1]; 1378 inm.enqueueNotificationWithTag("android", "android", null, 1379 R.string.heavy_weight_notification, 1380 notification, outId, root.userId); 1381 } catch (RuntimeException e) { 1382 Slog.w(ActivityManagerService.TAG, 1383 "Error showing notification for heavy-weight app", e); 1384 } catch (RemoteException e) { 1385 } 1386 } catch (NameNotFoundException e) { 1387 Slog.w(TAG, "Unable to create context for heavy notification", e); 1388 } 1389 } break; 1390 case CANCEL_HEAVY_NOTIFICATION_MSG: { 1391 INotificationManager inm = NotificationManager.getService(); 1392 if (inm == null) { 1393 return; 1394 } 1395 try { 1396 inm.cancelNotificationWithTag("android", null, 1397 R.string.heavy_weight_notification, msg.arg1); 1398 } catch (RuntimeException e) { 1399 Slog.w(ActivityManagerService.TAG, 1400 "Error canceling notification for service", e); 1401 } catch (RemoteException e) { 1402 } 1403 } break; 1404 case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: { 1405 synchronized (ActivityManagerService.this) { 1406 checkExcessivePowerUsageLocked(true); 1407 removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1408 Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1409 sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 1410 } 1411 } break; 1412 case SHOW_COMPAT_MODE_DIALOG_MSG: { 1413 synchronized (ActivityManagerService.this) { 1414 ActivityRecord ar = (ActivityRecord)msg.obj; 1415 if (mCompatModeDialog != null) { 1416 if (mCompatModeDialog.mAppInfo.packageName.equals( 1417 ar.info.applicationInfo.packageName)) { 1418 return; 1419 } 1420 mCompatModeDialog.dismiss(); 1421 mCompatModeDialog = null; 1422 } 1423 if (ar != null && false) { 1424 if (mCompatModePackages.getPackageAskCompatModeLocked( 1425 ar.packageName)) { 1426 int mode = mCompatModePackages.computeCompatModeLocked( 1427 ar.info.applicationInfo); 1428 if (mode == ActivityManager.COMPAT_MODE_DISABLED 1429 || mode == ActivityManager.COMPAT_MODE_ENABLED) { 1430 mCompatModeDialog = new CompatModeDialog( 1431 ActivityManagerService.this, mContext, 1432 ar.info.applicationInfo); 1433 mCompatModeDialog.show(); 1434 } 1435 } 1436 } 1437 } 1438 break; 1439 } 1440 case DISPATCH_PROCESSES_CHANGED: { 1441 dispatchProcessesChanged(); 1442 break; 1443 } 1444 case DISPATCH_PROCESS_DIED: { 1445 final int pid = msg.arg1; 1446 final int uid = msg.arg2; 1447 dispatchProcessDied(pid, uid); 1448 break; 1449 } 1450 case REPORT_MEM_USAGE_MSG: { 1451 final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj; 1452 Thread thread = new Thread() { 1453 @Override public void run() { 1454 final SparseArray<ProcessMemInfo> infoMap 1455 = new SparseArray<ProcessMemInfo>(memInfos.size()); 1456 for (int i=0, N=memInfos.size(); i<N; i++) { 1457 ProcessMemInfo mi = memInfos.get(i); 1458 infoMap.put(mi.pid, mi); 1459 } 1460 updateCpuStatsNow(); 1461 synchronized (mProcessCpuThread) { 1462 final int N = mProcessCpuTracker.countStats(); 1463 for (int i=0; i<N; i++) { 1464 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 1465 if (st.vsize > 0) { 1466 long pss = Debug.getPss(st.pid, null); 1467 if (pss > 0) { 1468 if (infoMap.indexOfKey(st.pid) < 0) { 1469 ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid, 1470 ProcessList.NATIVE_ADJ, -1, "native", null); 1471 mi.pss = pss; 1472 memInfos.add(mi); 1473 } 1474 } 1475 } 1476 } 1477 } 1478 1479 long totalPss = 0; 1480 for (int i=0, N=memInfos.size(); i<N; i++) { 1481 ProcessMemInfo mi = memInfos.get(i); 1482 if (mi.pss == 0) { 1483 mi.pss = Debug.getPss(mi.pid, null); 1484 } 1485 totalPss += mi.pss; 1486 } 1487 Collections.sort(memInfos, new Comparator<ProcessMemInfo>() { 1488 @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) { 1489 if (lhs.oomAdj != rhs.oomAdj) { 1490 return lhs.oomAdj < rhs.oomAdj ? -1 : 1; 1491 } 1492 if (lhs.pss != rhs.pss) { 1493 return lhs.pss < rhs.pss ? 1 : -1; 1494 } 1495 return 0; 1496 } 1497 }); 1498 1499 StringBuilder tag = new StringBuilder(128); 1500 StringBuilder stack = new StringBuilder(128); 1501 tag.append("Low on memory -- "); 1502 appendMemBucket(tag, totalPss, "total", false); 1503 appendMemBucket(stack, totalPss, "total", true); 1504 1505 StringBuilder logBuilder = new StringBuilder(1024); 1506 logBuilder.append("Low on memory:\n"); 1507 1508 boolean firstLine = true; 1509 int lastOomAdj = Integer.MIN_VALUE; 1510 for (int i=0, N=memInfos.size(); i<N; i++) { 1511 ProcessMemInfo mi = memInfos.get(i); 1512 1513 if (mi.oomAdj != ProcessList.NATIVE_ADJ 1514 && (mi.oomAdj < ProcessList.SERVICE_ADJ 1515 || mi.oomAdj == ProcessList.HOME_APP_ADJ 1516 || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) { 1517 if (lastOomAdj != mi.oomAdj) { 1518 lastOomAdj = mi.oomAdj; 1519 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) { 1520 tag.append(" / "); 1521 } 1522 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) { 1523 if (firstLine) { 1524 stack.append(":"); 1525 firstLine = false; 1526 } 1527 stack.append("\n\t at "); 1528 } else { 1529 stack.append("$"); 1530 } 1531 } else { 1532 tag.append(" "); 1533 stack.append("$"); 1534 } 1535 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) { 1536 appendMemBucket(tag, mi.pss, mi.name, false); 1537 } 1538 appendMemBucket(stack, mi.pss, mi.name, true); 1539 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ 1540 && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) { 1541 stack.append("("); 1542 for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) { 1543 if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) { 1544 stack.append(DUMP_MEM_OOM_LABEL[k]); 1545 stack.append(":"); 1546 stack.append(DUMP_MEM_OOM_ADJ[k]); 1547 } 1548 } 1549 stack.append(")"); 1550 } 1551 } 1552 1553 logBuilder.append(" "); 1554 logBuilder.append(ProcessList.makeOomAdjString(mi.oomAdj)); 1555 logBuilder.append(' '); 1556 logBuilder.append(ProcessList.makeProcStateString(mi.procState)); 1557 logBuilder.append(' '); 1558 ProcessList.appendRamKb(logBuilder, mi.pss); 1559 logBuilder.append(" kB: "); 1560 logBuilder.append(mi.name); 1561 logBuilder.append(" ("); 1562 logBuilder.append(mi.pid); 1563 logBuilder.append(") "); 1564 logBuilder.append(mi.adjType); 1565 logBuilder.append('\n'); 1566 if (mi.adjReason != null) { 1567 logBuilder.append(" "); 1568 logBuilder.append(mi.adjReason); 1569 logBuilder.append('\n'); 1570 } 1571 } 1572 1573 logBuilder.append(" "); 1574 ProcessList.appendRamKb(logBuilder, totalPss); 1575 logBuilder.append(" kB: TOTAL\n"); 1576 1577 long[] infos = new long[Debug.MEMINFO_COUNT]; 1578 Debug.getMemInfo(infos); 1579 logBuilder.append(" MemInfo: "); 1580 logBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, "); 1581 logBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, "); 1582 logBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, "); 1583 logBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, "); 1584 logBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n"); 1585 if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) { 1586 logBuilder.append(" ZRAM: "); 1587 logBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]); 1588 logBuilder.append(" kB RAM, "); 1589 logBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]); 1590 logBuilder.append(" kB swap total, "); 1591 logBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]); 1592 logBuilder.append(" kB swap free\n"); 1593 } 1594 Slog.i(TAG, logBuilder.toString()); 1595 1596 StringBuilder dropBuilder = new StringBuilder(1024); 1597 /* 1598 StringWriter oomSw = new StringWriter(); 1599 PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256); 1600 StringWriter catSw = new StringWriter(); 1601 PrintWriter catPw = new FastPrintWriter(catSw, false, 256); 1602 String[] emptyArgs = new String[] { }; 1603 dumpApplicationMemoryUsage(null, oomPw, " ", emptyArgs, true, catPw); 1604 oomPw.flush(); 1605 String oomString = oomSw.toString(); 1606 */ 1607 dropBuilder.append(stack); 1608 dropBuilder.append('\n'); 1609 dropBuilder.append('\n'); 1610 dropBuilder.append(logBuilder); 1611 dropBuilder.append('\n'); 1612 /* 1613 dropBuilder.append(oomString); 1614 dropBuilder.append('\n'); 1615 */ 1616 StringWriter catSw = new StringWriter(); 1617 synchronized (ActivityManagerService.this) { 1618 PrintWriter catPw = new FastPrintWriter(catSw, false, 256); 1619 String[] emptyArgs = new String[] { }; 1620 catPw.println(); 1621 dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null); 1622 catPw.println(); 1623 mServices.dumpServicesLocked(null, catPw, emptyArgs, 0, 1624 false, false, null); 1625 catPw.println(); 1626 dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null); 1627 catPw.flush(); 1628 } 1629 dropBuilder.append(catSw.toString()); 1630 addErrorToDropBox("lowmem", null, "system_server", null, 1631 null, tag.toString(), dropBuilder.toString(), null, null); 1632 //Slog.i(TAG, "Sent to dropbox:"); 1633 //Slog.i(TAG, dropBuilder.toString()); 1634 synchronized (ActivityManagerService.this) { 1635 long now = SystemClock.uptimeMillis(); 1636 if (mLastMemUsageReportTime < now) { 1637 mLastMemUsageReportTime = now; 1638 } 1639 } 1640 } 1641 }; 1642 thread.start(); 1643 break; 1644 } 1645 case REPORT_USER_SWITCH_MSG: { 1646 dispatchUserSwitch((UserStartedState)msg.obj, msg.arg1, msg.arg2); 1647 break; 1648 } 1649 case CONTINUE_USER_SWITCH_MSG: { 1650 continueUserSwitch((UserStartedState)msg.obj, msg.arg1, msg.arg2); 1651 break; 1652 } 1653 case USER_SWITCH_TIMEOUT_MSG: { 1654 timeoutUserSwitch((UserStartedState)msg.obj, msg.arg1, msg.arg2); 1655 break; 1656 } 1657 case IMMERSIVE_MODE_LOCK_MSG: { 1658 final boolean nextState = (msg.arg1 != 0); 1659 if (mUpdateLock.isHeld() != nextState) { 1660 if (DEBUG_IMMERSIVE) { 1661 final ActivityRecord r = (ActivityRecord) msg.obj; 1662 Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r); 1663 } 1664 if (nextState) { 1665 mUpdateLock.acquire(); 1666 } else { 1667 mUpdateLock.release(); 1668 } 1669 } 1670 break; 1671 } 1672 case PERSIST_URI_GRANTS_MSG: { 1673 writeGrantedUriPermissions(); 1674 break; 1675 } 1676 case REQUEST_ALL_PSS_MSG: { 1677 requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false); 1678 break; 1679 } 1680 case UPDATE_TIME: { 1681 synchronized (ActivityManagerService.this) { 1682 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1683 ProcessRecord r = mLruProcesses.get(i); 1684 if (r.thread != null) { 1685 try { 1686 r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true); 1687 } catch (RemoteException ex) { 1688 Slog.w(TAG, "Failed to update preferences for: " + r.info.processName); 1689 } 1690 } 1691 } 1692 } 1693 1694 break; 1695 } 1696 } 1697 } 1698 }; 1699 1700 static final int COLLECT_PSS_BG_MSG = 1; 1701 1702 final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) { 1703 @Override 1704 public void handleMessage(Message msg) { 1705 switch (msg.what) { 1706 case COLLECT_PSS_BG_MSG: { 1707 int i=0, num=0; 1708 long start = SystemClock.uptimeMillis(); 1709 long[] tmp = new long[1]; 1710 do { 1711 ProcessRecord proc; 1712 int procState; 1713 int pid; 1714 synchronized (ActivityManagerService.this) { 1715 if (i >= mPendingPssProcesses.size()) { 1716 if (DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num + " of " + i 1717 + " processes in " + (SystemClock.uptimeMillis()-start) + "ms"); 1718 mPendingPssProcesses.clear(); 1719 return; 1720 } 1721 proc = mPendingPssProcesses.get(i); 1722 procState = proc.pssProcState; 1723 if (proc.thread != null && procState == proc.setProcState) { 1724 pid = proc.pid; 1725 } else { 1726 proc = null; 1727 pid = 0; 1728 } 1729 i++; 1730 } 1731 if (proc != null) { 1732 long pss = Debug.getPss(pid, tmp); 1733 synchronized (ActivityManagerService.this) { 1734 if (proc.thread != null && proc.setProcState == procState 1735 && proc.pid == pid) { 1736 num++; 1737 proc.lastPssTime = SystemClock.uptimeMillis(); 1738 proc.baseProcessTracker.addPss(pss, tmp[0], true, proc.pkgList); 1739 if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString() 1740 + ": " + pss + " lastPss=" + proc.lastPss 1741 + " state=" + ProcessList.makeProcStateString(procState)); 1742 if (proc.initialIdlePss == 0) { 1743 proc.initialIdlePss = pss; 1744 } 1745 proc.lastPss = pss; 1746 if (procState >= ActivityManager.PROCESS_STATE_HOME) { 1747 proc.lastCachedPss = pss; 1748 } 1749 } 1750 } 1751 } 1752 } while (true); 1753 } 1754 } 1755 } 1756 }; 1757 1758 public void setSystemProcess() { 1759 try { 1760 ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true); 1761 ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats); 1762 ServiceManager.addService("meminfo", new MemBinder(this)); 1763 ServiceManager.addService("gfxinfo", new GraphicsBinder(this)); 1764 ServiceManager.addService("dbinfo", new DbBinder(this)); 1765 if (MONITOR_CPU_USAGE) { 1766 ServiceManager.addService("cpuinfo", new CpuBinder(this)); 1767 } 1768 ServiceManager.addService("permission", new PermissionController(this)); 1769 1770 ApplicationInfo info = mContext.getPackageManager().getApplicationInfo( 1771 "android", STOCK_PM_FLAGS); 1772 mSystemThread.installSystemApplicationInfo(info); 1773 1774 synchronized (this) { 1775 ProcessRecord app = newProcessRecordLocked(info, info.processName, false); 1776 app.persistent = true; 1777 app.pid = MY_PID; 1778 app.maxAdj = ProcessList.SYSTEM_ADJ; 1779 app.makeActive(mSystemThread.getApplicationThread(), mProcessStats); 1780 mProcessNames.put(app.processName, app.uid, app); 1781 synchronized (mPidsSelfLocked) { 1782 mPidsSelfLocked.put(app.pid, app); 1783 } 1784 updateLruProcessLocked(app, false, null); 1785 updateOomAdjLocked(); 1786 } 1787 } catch (PackageManager.NameNotFoundException e) { 1788 throw new RuntimeException( 1789 "Unable to find android system package", e); 1790 } 1791 } 1792 1793 public void setWindowManager(WindowManagerService wm) { 1794 mWindowManager = wm; 1795 mStackSupervisor.setWindowManager(wm); 1796 } 1797 1798 public void startObservingNativeCrashes() { 1799 final NativeCrashListener ncl = new NativeCrashListener(this); 1800 ncl.start(); 1801 } 1802 1803 public IAppOpsService getAppOpsService() { 1804 return mAppOpsService; 1805 } 1806 1807 static class MemBinder extends Binder { 1808 ActivityManagerService mActivityManagerService; 1809 MemBinder(ActivityManagerService activityManagerService) { 1810 mActivityManagerService = activityManagerService; 1811 } 1812 1813 @Override 1814 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1815 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1816 != PackageManager.PERMISSION_GRANTED) { 1817 pw.println("Permission Denial: can't dump meminfo from from pid=" 1818 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1819 + " without permission " + android.Manifest.permission.DUMP); 1820 return; 1821 } 1822 1823 mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, " ", args, false, null); 1824 } 1825 } 1826 1827 static class GraphicsBinder extends Binder { 1828 ActivityManagerService mActivityManagerService; 1829 GraphicsBinder(ActivityManagerService activityManagerService) { 1830 mActivityManagerService = activityManagerService; 1831 } 1832 1833 @Override 1834 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1835 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1836 != PackageManager.PERMISSION_GRANTED) { 1837 pw.println("Permission Denial: can't dump gfxinfo from from pid=" 1838 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1839 + " without permission " + android.Manifest.permission.DUMP); 1840 return; 1841 } 1842 1843 mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args); 1844 } 1845 } 1846 1847 static class DbBinder extends Binder { 1848 ActivityManagerService mActivityManagerService; 1849 DbBinder(ActivityManagerService activityManagerService) { 1850 mActivityManagerService = activityManagerService; 1851 } 1852 1853 @Override 1854 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1855 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1856 != PackageManager.PERMISSION_GRANTED) { 1857 pw.println("Permission Denial: can't dump dbinfo from from pid=" 1858 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1859 + " without permission " + android.Manifest.permission.DUMP); 1860 return; 1861 } 1862 1863 mActivityManagerService.dumpDbInfo(fd, pw, args); 1864 } 1865 } 1866 1867 static class CpuBinder extends Binder { 1868 ActivityManagerService mActivityManagerService; 1869 CpuBinder(ActivityManagerService activityManagerService) { 1870 mActivityManagerService = activityManagerService; 1871 } 1872 1873 @Override 1874 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1875 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1876 != PackageManager.PERMISSION_GRANTED) { 1877 pw.println("Permission Denial: can't dump cpuinfo from from pid=" 1878 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1879 + " without permission " + android.Manifest.permission.DUMP); 1880 return; 1881 } 1882 1883 synchronized (mActivityManagerService.mProcessCpuThread) { 1884 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad()); 1885 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState( 1886 SystemClock.uptimeMillis())); 1887 } 1888 } 1889 } 1890 1891 public static final class Lifecycle extends SystemService { 1892 private final ActivityManagerService mService; 1893 1894 public Lifecycle(Context context) { 1895 super(context); 1896 mService = new ActivityManagerService(context); 1897 } 1898 1899 @Override 1900 public void onStart() { 1901 mService.start(); 1902 } 1903 1904 public ActivityManagerService getService() { 1905 return mService; 1906 } 1907 } 1908 1909 // Note: This method is invoked on the main thread but may need to attach various 1910 // handlers to other threads. So take care to be explicit about the looper. 1911 public ActivityManagerService(Context systemContext) { 1912 mContext = systemContext; 1913 mFactoryTest = FactoryTest.getMode(); 1914 mSystemThread = ActivityThread.currentActivityThread(); 1915 1916 Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass()); 1917 1918 mHandlerThread = new ServiceThread(TAG, 1919 android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/); 1920 mHandlerThread.start(); 1921 mHandler = new MainHandler(mHandlerThread.getLooper()); 1922 1923 mFgBroadcastQueue = new BroadcastQueue(this, mHandler, 1924 "foreground", BROADCAST_FG_TIMEOUT, false); 1925 mBgBroadcastQueue = new BroadcastQueue(this, mHandler, 1926 "background", BROADCAST_BG_TIMEOUT, true); 1927 mBroadcastQueues[0] = mFgBroadcastQueue; 1928 mBroadcastQueues[1] = mBgBroadcastQueue; 1929 1930 mServices = new ActiveServices(this); 1931 mProviderMap = new ProviderMap(this); 1932 1933 // TODO: Move creation of battery stats service outside of activity manager service. 1934 File dataDir = Environment.getDataDirectory(); 1935 File systemDir = new File(dataDir, "system"); 1936 systemDir.mkdirs(); 1937 mBatteryStatsService = new BatteryStatsService(new File( 1938 systemDir, "batterystats.bin").toString(), mHandler); 1939 mBatteryStatsService.getActiveStatistics().readLocked(); 1940 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 1941 mOnBattery = DEBUG_POWER ? true 1942 : mBatteryStatsService.getActiveStatistics().getIsOnBattery(); 1943 mBatteryStatsService.getActiveStatistics().setCallback(this); 1944 1945 mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats")); 1946 1947 mUsageStatsService = new UsageStatsService(new File(systemDir, "usagestats").toString()); 1948 mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler); 1949 1950 mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml")); 1951 1952 // User 0 is the first and only user that runs at boot. 1953 mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true)); 1954 mUserLru.add(Integer.valueOf(0)); 1955 updateStartedUserArrayLocked(); 1956 1957 GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version", 1958 ConfigurationInfo.GL_ES_VERSION_UNDEFINED); 1959 1960 mConfiguration.setToDefaults(); 1961 mConfiguration.setLocale(Locale.getDefault()); 1962 1963 mConfigurationSeq = mConfiguration.seq = 1; 1964 mProcessCpuTracker.init(); 1965 1966 mCompatModePackages = new CompatModePackages(this, systemDir, mHandler); 1967 mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler); 1968 mStackSupervisor = new ActivityStackSupervisor(this); 1969 1970 mProcessCpuThread = new Thread("CpuTracker") { 1971 @Override 1972 public void run() { 1973 while (true) { 1974 try { 1975 try { 1976 synchronized(this) { 1977 final long now = SystemClock.uptimeMillis(); 1978 long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now; 1979 long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now; 1980 //Slog.i(TAG, "Cpu delay=" + nextCpuDelay 1981 // + ", write delay=" + nextWriteDelay); 1982 if (nextWriteDelay < nextCpuDelay) { 1983 nextCpuDelay = nextWriteDelay; 1984 } 1985 if (nextCpuDelay > 0) { 1986 mProcessCpuMutexFree.set(true); 1987 this.wait(nextCpuDelay); 1988 } 1989 } 1990 } catch (InterruptedException e) { 1991 } 1992 updateCpuStatsNow(); 1993 } catch (Exception e) { 1994 Slog.e(TAG, "Unexpected exception collecting process stats", e); 1995 } 1996 } 1997 } 1998 }; 1999 2000 Watchdog.getInstance().addMonitor(this); 2001 Watchdog.getInstance().addThread(mHandler); 2002 } 2003 2004 private void start() { 2005 mProcessCpuThread.start(); 2006 2007 mBatteryStatsService.publish(mContext); 2008 mUsageStatsService.publish(mContext); 2009 mAppOpsService.publish(mContext); 2010 2011 LocalServices.addService(ActivityManagerInternal.class, new LocalService()); 2012 } 2013 2014 @Override 2015 public boolean onTransact(int code, Parcel data, Parcel reply, int flags) 2016 throws RemoteException { 2017 if (code == SYSPROPS_TRANSACTION) { 2018 // We need to tell all apps about the system property change. 2019 ArrayList<IBinder> procs = new ArrayList<IBinder>(); 2020 synchronized(this) { 2021 final int NP = mProcessNames.getMap().size(); 2022 for (int ip=0; ip<NP; ip++) { 2023 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 2024 final int NA = apps.size(); 2025 for (int ia=0; ia<NA; ia++) { 2026 ProcessRecord app = apps.valueAt(ia); 2027 if (app.thread != null) { 2028 procs.add(app.thread.asBinder()); 2029 } 2030 } 2031 } 2032 } 2033 2034 int N = procs.size(); 2035 for (int i=0; i<N; i++) { 2036 Parcel data2 = Parcel.obtain(); 2037 try { 2038 procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0); 2039 } catch (RemoteException e) { 2040 } 2041 data2.recycle(); 2042 } 2043 } 2044 try { 2045 return super.onTransact(code, data, reply, flags); 2046 } catch (RuntimeException e) { 2047 // The activity manager only throws security exceptions, so let's 2048 // log all others. 2049 if (!(e instanceof SecurityException)) { 2050 Slog.wtf(TAG, "Activity Manager Crash", e); 2051 } 2052 throw e; 2053 } 2054 } 2055 2056 void updateCpuStats() { 2057 final long now = SystemClock.uptimeMillis(); 2058 if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) { 2059 return; 2060 } 2061 if (mProcessCpuMutexFree.compareAndSet(true, false)) { 2062 synchronized (mProcessCpuThread) { 2063 mProcessCpuThread.notify(); 2064 } 2065 } 2066 } 2067 2068 void updateCpuStatsNow() { 2069 synchronized (mProcessCpuThread) { 2070 mProcessCpuMutexFree.set(false); 2071 final long now = SystemClock.uptimeMillis(); 2072 boolean haveNewCpuStats = false; 2073 2074 if (MONITOR_CPU_USAGE && 2075 mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) { 2076 mLastCpuTime.set(now); 2077 haveNewCpuStats = true; 2078 mProcessCpuTracker.update(); 2079 //Slog.i(TAG, mProcessCpu.printCurrentState()); 2080 //Slog.i(TAG, "Total CPU usage: " 2081 // + mProcessCpu.getTotalCpuPercent() + "%"); 2082 2083 // Slog the cpu usage if the property is set. 2084 if ("true".equals(SystemProperties.get("events.cpu"))) { 2085 int user = mProcessCpuTracker.getLastUserTime(); 2086 int system = mProcessCpuTracker.getLastSystemTime(); 2087 int iowait = mProcessCpuTracker.getLastIoWaitTime(); 2088 int irq = mProcessCpuTracker.getLastIrqTime(); 2089 int softIrq = mProcessCpuTracker.getLastSoftIrqTime(); 2090 int idle = mProcessCpuTracker.getLastIdleTime(); 2091 2092 int total = user + system + iowait + irq + softIrq + idle; 2093 if (total == 0) total = 1; 2094 2095 EventLog.writeEvent(EventLogTags.CPU, 2096 ((user+system+iowait+irq+softIrq) * 100) / total, 2097 (user * 100) / total, 2098 (system * 100) / total, 2099 (iowait * 100) / total, 2100 (irq * 100) / total, 2101 (softIrq * 100) / total); 2102 } 2103 } 2104 2105 long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes(); 2106 final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics(); 2107 synchronized(bstats) { 2108 synchronized(mPidsSelfLocked) { 2109 if (haveNewCpuStats) { 2110 if (mOnBattery) { 2111 int perc = bstats.startAddingCpuLocked(); 2112 int totalUTime = 0; 2113 int totalSTime = 0; 2114 final int N = mProcessCpuTracker.countStats(); 2115 for (int i=0; i<N; i++) { 2116 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 2117 if (!st.working) { 2118 continue; 2119 } 2120 ProcessRecord pr = mPidsSelfLocked.get(st.pid); 2121 int otherUTime = (st.rel_utime*perc)/100; 2122 int otherSTime = (st.rel_stime*perc)/100; 2123 totalUTime += otherUTime; 2124 totalSTime += otherSTime; 2125 if (pr != null) { 2126 BatteryStatsImpl.Uid.Proc ps = bstats.getProcessStatsLocked( 2127 st.name, st.pid); 2128 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 2129 st.rel_stime-otherSTime); 2130 ps.addSpeedStepTimes(cpuSpeedTimes); 2131 pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10; 2132 } else if (st.uid >= Process.FIRST_APPLICATION_UID) { 2133 BatteryStatsImpl.Uid.Proc ps = st.batteryStats; 2134 if (ps == null) { 2135 st.batteryStats = ps = bstats.getProcessStatsLocked(st.uid, 2136 "(Unknown)"); 2137 } 2138 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 2139 st.rel_stime-otherSTime); 2140 ps.addSpeedStepTimes(cpuSpeedTimes); 2141 } else { 2142 BatteryStatsImpl.Uid.Proc ps = 2143 bstats.getProcessStatsLocked(st.name, st.pid); 2144 if (ps != null) { 2145 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 2146 st.rel_stime-otherSTime); 2147 ps.addSpeedStepTimes(cpuSpeedTimes); 2148 } 2149 } 2150 } 2151 bstats.finishAddingCpuLocked(perc, totalUTime, 2152 totalSTime, cpuSpeedTimes); 2153 } 2154 } 2155 } 2156 2157 if (mLastWriteTime < (now-BATTERY_STATS_TIME)) { 2158 mLastWriteTime = now; 2159 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 2160 } 2161 } 2162 } 2163 } 2164 2165 @Override 2166 public void batteryNeedsCpuUpdate() { 2167 updateCpuStatsNow(); 2168 } 2169 2170 @Override 2171 public void batteryPowerChanged(boolean onBattery) { 2172 // When plugging in, update the CPU stats first before changing 2173 // the plug state. 2174 updateCpuStatsNow(); 2175 synchronized (this) { 2176 synchronized(mPidsSelfLocked) { 2177 mOnBattery = DEBUG_POWER ? true : onBattery; 2178 } 2179 } 2180 } 2181 2182 /** 2183 * Initialize the application bind args. These are passed to each 2184 * process when the bindApplication() IPC is sent to the process. They're 2185 * lazily setup to make sure the services are running when they're asked for. 2186 */ 2187 private HashMap<String, IBinder> getCommonServicesLocked() { 2188 if (mAppBindArgs == null) { 2189 mAppBindArgs = new HashMap<String, IBinder>(); 2190 2191 // Setup the application init args 2192 mAppBindArgs.put("package", ServiceManager.getService("package")); 2193 mAppBindArgs.put("window", ServiceManager.getService("window")); 2194 mAppBindArgs.put(Context.ALARM_SERVICE, 2195 ServiceManager.getService(Context.ALARM_SERVICE)); 2196 } 2197 return mAppBindArgs; 2198 } 2199 2200 final void setFocusedActivityLocked(ActivityRecord r) { 2201 if (mFocusedActivity != r) { 2202 if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r); 2203 mFocusedActivity = r; 2204 mStackSupervisor.setFocusedStack(r); 2205 if (r != null) { 2206 mWindowManager.setFocusedApp(r.appToken, true); 2207 } 2208 applyUpdateLockStateLocked(r); 2209 } 2210 } 2211 2212 @Override 2213 public void setFocusedStack(int stackId) { 2214 if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId); 2215 synchronized (ActivityManagerService.this) { 2216 ActivityStack stack = mStackSupervisor.getStack(stackId); 2217 if (stack != null) { 2218 ActivityRecord r = stack.topRunningActivityLocked(null); 2219 if (r != null) { 2220 setFocusedActivityLocked(r); 2221 } 2222 } 2223 } 2224 } 2225 2226 @Override 2227 public void notifyActivityDrawn(IBinder token) { 2228 if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token); 2229 synchronized (this) { 2230 ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token); 2231 if (r != null) { 2232 r.task.stack.notifyActivityDrawnLocked(r); 2233 } 2234 } 2235 } 2236 2237 final void applyUpdateLockStateLocked(ActivityRecord r) { 2238 // Modifications to the UpdateLock state are done on our handler, outside 2239 // the activity manager's locks. The new state is determined based on the 2240 // state *now* of the relevant activity record. The object is passed to 2241 // the handler solely for logging detail, not to be consulted/modified. 2242 final boolean nextState = r != null && r.immersive; 2243 mHandler.sendMessage( 2244 mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r)); 2245 } 2246 2247 final void showAskCompatModeDialogLocked(ActivityRecord r) { 2248 Message msg = Message.obtain(); 2249 msg.what = SHOW_COMPAT_MODE_DIALOG_MSG; 2250 msg.obj = r.task.askedCompatMode ? null : r; 2251 mHandler.sendMessage(msg); 2252 } 2253 2254 private final int updateLruProcessInternalLocked(ProcessRecord app, long now, int index, 2255 String what, Object obj, ProcessRecord srcApp) { 2256 app.lastActivityTime = now; 2257 2258 if (app.activities.size() > 0) { 2259 // Don't want to touch dependent processes that are hosting activities. 2260 return index; 2261 } 2262 2263 int lrui = mLruProcesses.lastIndexOf(app); 2264 if (lrui < 0) { 2265 Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: " 2266 + what + " " + obj + " from " + srcApp); 2267 return index; 2268 } 2269 2270 if (lrui >= index) { 2271 // Don't want to cause this to move dependent processes *back* in the 2272 // list as if they were less frequently used. 2273 return index; 2274 } 2275 2276 if (lrui >= mLruProcessActivityStart) { 2277 // Don't want to touch dependent processes that are hosting activities. 2278 return index; 2279 } 2280 2281 mLruProcesses.remove(lrui); 2282 if (index > 0) { 2283 index--; 2284 } 2285 if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index 2286 + " in LRU list: " + app); 2287 mLruProcesses.add(index, app); 2288 return index; 2289 } 2290 2291 final void removeLruProcessLocked(ProcessRecord app) { 2292 int lrui = mLruProcesses.lastIndexOf(app); 2293 if (lrui >= 0) { 2294 if (lrui <= mLruProcessActivityStart) { 2295 mLruProcessActivityStart--; 2296 } 2297 if (lrui <= mLruProcessServiceStart) { 2298 mLruProcessServiceStart--; 2299 } 2300 mLruProcesses.remove(lrui); 2301 } 2302 } 2303 2304 final void updateLruProcessLocked(ProcessRecord app, boolean activityChange, 2305 ProcessRecord client) { 2306 final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities; 2307 final boolean hasService = false; // not impl yet. app.services.size() > 0; 2308 if (!activityChange && hasActivity) { 2309 // The process has activties, so we are only going to allow activity-based 2310 // adjustments move it. It should be kept in the front of the list with other 2311 // processes that have activities, and we don't want those to change their 2312 // order except due to activity operations. 2313 return; 2314 } 2315 2316 mLruSeq++; 2317 final long now = SystemClock.uptimeMillis(); 2318 app.lastActivityTime = now; 2319 2320 // First a quick reject: if the app is already at the position we will 2321 // put it, then there is nothing to do. 2322 if (hasActivity) { 2323 final int N = mLruProcesses.size(); 2324 if (N > 0 && mLruProcesses.get(N-1) == app) { 2325 if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app); 2326 return; 2327 } 2328 } else { 2329 if (mLruProcessServiceStart > 0 2330 && mLruProcesses.get(mLruProcessServiceStart-1) == app) { 2331 if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app); 2332 return; 2333 } 2334 } 2335 2336 int lrui = mLruProcesses.lastIndexOf(app); 2337 2338 if (app.persistent && lrui >= 0) { 2339 // We don't care about the position of persistent processes, as long as 2340 // they are in the list. 2341 if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app); 2342 return; 2343 } 2344 2345 /* In progress: compute new position first, so we can avoid doing work 2346 if the process is not actually going to move. Not yet working. 2347 int addIndex; 2348 int nextIndex; 2349 boolean inActivity = false, inService = false; 2350 if (hasActivity) { 2351 // Process has activities, put it at the very tipsy-top. 2352 addIndex = mLruProcesses.size(); 2353 nextIndex = mLruProcessServiceStart; 2354 inActivity = true; 2355 } else if (hasService) { 2356 // Process has services, put it at the top of the service list. 2357 addIndex = mLruProcessActivityStart; 2358 nextIndex = mLruProcessServiceStart; 2359 inActivity = true; 2360 inService = true; 2361 } else { 2362 // Process not otherwise of interest, it goes to the top of the non-service area. 2363 addIndex = mLruProcessServiceStart; 2364 if (client != null) { 2365 int clientIndex = mLruProcesses.lastIndexOf(client); 2366 if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating " 2367 + app); 2368 if (clientIndex >= 0 && addIndex > clientIndex) { 2369 addIndex = clientIndex; 2370 } 2371 } 2372 nextIndex = addIndex > 0 ? addIndex-1 : addIndex; 2373 } 2374 2375 Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act=" 2376 + mLruProcessActivityStart + "): " + app); 2377 */ 2378 2379 if (lrui >= 0) { 2380 if (lrui < mLruProcessActivityStart) { 2381 mLruProcessActivityStart--; 2382 } 2383 if (lrui < mLruProcessServiceStart) { 2384 mLruProcessServiceStart--; 2385 } 2386 /* 2387 if (addIndex > lrui) { 2388 addIndex--; 2389 } 2390 if (nextIndex > lrui) { 2391 nextIndex--; 2392 } 2393 */ 2394 mLruProcesses.remove(lrui); 2395 } 2396 2397 /* 2398 mLruProcesses.add(addIndex, app); 2399 if (inActivity) { 2400 mLruProcessActivityStart++; 2401 } 2402 if (inService) { 2403 mLruProcessActivityStart++; 2404 } 2405 */ 2406 2407 int nextIndex; 2408 if (hasActivity) { 2409 final int N = mLruProcesses.size(); 2410 if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) { 2411 // Process doesn't have activities, but has clients with 2412 // activities... move it up, but one below the top (the top 2413 // should always have a real activity). 2414 if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app); 2415 mLruProcesses.add(N-1, app); 2416 // To keep it from spamming the LRU list (by making a bunch of clients), 2417 // we will push down any other entries owned by the app. 2418 final int uid = app.info.uid; 2419 for (int i=N-2; i>mLruProcessActivityStart; i--) { 2420 ProcessRecord subProc = mLruProcesses.get(i); 2421 if (subProc.info.uid == uid) { 2422 // We want to push this one down the list. If the process after 2423 // it is for the same uid, however, don't do so, because we don't 2424 // want them internally to be re-ordered. 2425 if (mLruProcesses.get(i-1).info.uid != uid) { 2426 if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i 2427 + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1)); 2428 ProcessRecord tmp = mLruProcesses.get(i); 2429 mLruProcesses.set(i, mLruProcesses.get(i-1)); 2430 mLruProcesses.set(i-1, tmp); 2431 i--; 2432 } 2433 } else { 2434 // A gap, we can stop here. 2435 break; 2436 } 2437 } 2438 } else { 2439 // Process has activities, put it at the very tipsy-top. 2440 if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app); 2441 mLruProcesses.add(app); 2442 } 2443 nextIndex = mLruProcessServiceStart; 2444 } else if (hasService) { 2445 // Process has services, put it at the top of the service list. 2446 if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app); 2447 mLruProcesses.add(mLruProcessActivityStart, app); 2448 nextIndex = mLruProcessServiceStart; 2449 mLruProcessActivityStart++; 2450 } else { 2451 // Process not otherwise of interest, it goes to the top of the non-service area. 2452 int index = mLruProcessServiceStart; 2453 if (client != null) { 2454 // If there is a client, don't allow the process to be moved up higher 2455 // in the list than that client. 2456 int clientIndex = mLruProcesses.lastIndexOf(client); 2457 if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client 2458 + " when updating " + app); 2459 if (clientIndex <= lrui) { 2460 // Don't allow the client index restriction to push it down farther in the 2461 // list than it already is. 2462 clientIndex = lrui; 2463 } 2464 if (clientIndex >= 0 && index > clientIndex) { 2465 index = clientIndex; 2466 } 2467 } 2468 if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app); 2469 mLruProcesses.add(index, app); 2470 nextIndex = index-1; 2471 mLruProcessActivityStart++; 2472 mLruProcessServiceStart++; 2473 } 2474 2475 // If the app is currently using a content provider or service, 2476 // bump those processes as well. 2477 for (int j=app.connections.size()-1; j>=0; j--) { 2478 ConnectionRecord cr = app.connections.valueAt(j); 2479 if (cr.binding != null && !cr.serviceDead && cr.binding.service != null 2480 && cr.binding.service.app != null 2481 && cr.binding.service.app.lruSeq != mLruSeq 2482 && !cr.binding.service.app.persistent) { 2483 nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex, 2484 "service connection", cr, app); 2485 } 2486 } 2487 for (int j=app.conProviders.size()-1; j>=0; j--) { 2488 ContentProviderRecord cpr = app.conProviders.get(j).provider; 2489 if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) { 2490 nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex, 2491 "provider reference", cpr, app); 2492 } 2493 } 2494 } 2495 2496 final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) { 2497 if (uid == Process.SYSTEM_UID) { 2498 // The system gets to run in any process. If there are multiple 2499 // processes with the same uid, just pick the first (this 2500 // should never happen). 2501 SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName); 2502 if (procs == null) return null; 2503 final int N = procs.size(); 2504 for (int i = 0; i < N; i++) { 2505 if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i); 2506 } 2507 } 2508 ProcessRecord proc = mProcessNames.get(processName, uid); 2509 if (false && proc != null && !keepIfLarge 2510 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY 2511 && proc.lastCachedPss >= 4000) { 2512 // Turn this condition on to cause killing to happen regularly, for testing. 2513 if (proc.baseProcessTracker != null) { 2514 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss); 2515 } 2516 killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss) 2517 + "k from cached"); 2518 } else if (proc != null && !keepIfLarge 2519 && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL 2520 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) { 2521 if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss); 2522 if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) { 2523 if (proc.baseProcessTracker != null) { 2524 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss); 2525 } 2526 killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss) 2527 + "k from cached"); 2528 } 2529 } 2530 return proc; 2531 } 2532 2533 void ensurePackageDexOpt(String packageName) { 2534 IPackageManager pm = AppGlobals.getPackageManager(); 2535 try { 2536 if (pm.performDexOpt(packageName)) { 2537 mDidDexOpt = true; 2538 } 2539 } catch (RemoteException e) { 2540 } 2541 } 2542 2543 boolean isNextTransitionForward() { 2544 int transit = mWindowManager.getPendingAppTransition(); 2545 return transit == AppTransition.TRANSIT_ACTIVITY_OPEN 2546 || transit == AppTransition.TRANSIT_TASK_OPEN 2547 || transit == AppTransition.TRANSIT_TASK_TO_FRONT; 2548 } 2549 2550 final ProcessRecord startProcessLocked(String processName, 2551 ApplicationInfo info, boolean knownToBeDead, int intentFlags, 2552 String hostingType, ComponentName hostingName, boolean allowWhileBooting, 2553 boolean isolated, boolean keepIfLarge) { 2554 ProcessRecord app; 2555 if (!isolated) { 2556 app = getProcessRecordLocked(processName, info.uid, keepIfLarge); 2557 } else { 2558 // If this is an isolated process, it can't re-use an existing process. 2559 app = null; 2560 } 2561 // We don't have to do anything more if: 2562 // (1) There is an existing application record; and 2563 // (2) The caller doesn't think it is dead, OR there is no thread 2564 // object attached to it so we know it couldn't have crashed; and 2565 // (3) There is a pid assigned to it, so it is either starting or 2566 // already running. 2567 if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName 2568 + " app=" + app + " knownToBeDead=" + knownToBeDead 2569 + " thread=" + (app != null ? app.thread : null) 2570 + " pid=" + (app != null ? app.pid : -1)); 2571 if (app != null && app.pid > 0) { 2572 if (!knownToBeDead || app.thread == null) { 2573 // We already have the app running, or are waiting for it to 2574 // come up (we have a pid but not yet its thread), so keep it. 2575 if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app); 2576 // If this is a new package in the process, add the package to the list 2577 app.addPackage(info.packageName, mProcessStats); 2578 return app; 2579 } 2580 2581 // An application record is attached to a previous process, 2582 // clean it up now. 2583 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app); 2584 handleAppDiedLocked(app, true, true); 2585 } 2586 2587 String hostingNameStr = hostingName != null 2588 ? hostingName.flattenToShortString() : null; 2589 2590 if (!isolated) { 2591 if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) { 2592 // If we are in the background, then check to see if this process 2593 // is bad. If so, we will just silently fail. 2594 if (mBadProcesses.get(info.processName, info.uid) != null) { 2595 if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid 2596 + "/" + info.processName); 2597 return null; 2598 } 2599 } else { 2600 // When the user is explicitly starting a process, then clear its 2601 // crash count so that we won't make it bad until they see at 2602 // least one crash dialog again, and make the process good again 2603 // if it had been bad. 2604 if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid 2605 + "/" + info.processName); 2606 mProcessCrashTimes.remove(info.processName, info.uid); 2607 if (mBadProcesses.get(info.processName, info.uid) != null) { 2608 EventLog.writeEvent(EventLogTags.AM_PROC_GOOD, 2609 UserHandle.getUserId(info.uid), info.uid, 2610 info.processName); 2611 mBadProcesses.remove(info.processName, info.uid); 2612 if (app != null) { 2613 app.bad = false; 2614 } 2615 } 2616 } 2617 } 2618 2619 if (app == null) { 2620 app = newProcessRecordLocked(info, processName, isolated); 2621 if (app == null) { 2622 Slog.w(TAG, "Failed making new process record for " 2623 + processName + "/" + info.uid + " isolated=" + isolated); 2624 return null; 2625 } 2626 mProcessNames.put(processName, app.uid, app); 2627 if (isolated) { 2628 mIsolatedProcesses.put(app.uid, app); 2629 } 2630 } else { 2631 // If this is a new package in the process, add the package to the list 2632 app.addPackage(info.packageName, mProcessStats); 2633 } 2634 2635 // If the system is not ready yet, then hold off on starting this 2636 // process until it is. 2637 if (!mProcessesReady 2638 && !isAllowedWhileBooting(info) 2639 && !allowWhileBooting) { 2640 if (!mProcessesOnHold.contains(app)) { 2641 mProcessesOnHold.add(app); 2642 } 2643 if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app); 2644 return app; 2645 } 2646 2647 startProcessLocked(app, hostingType, hostingNameStr); 2648 return (app.pid != 0) ? app : null; 2649 } 2650 2651 boolean isAllowedWhileBooting(ApplicationInfo ai) { 2652 return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0; 2653 } 2654 2655 private final void startProcessLocked(ProcessRecord app, 2656 String hostingType, String hostingNameStr) { 2657 if (app.pid > 0 && app.pid != MY_PID) { 2658 synchronized (mPidsSelfLocked) { 2659 mPidsSelfLocked.remove(app.pid); 2660 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 2661 } 2662 app.setPid(0); 2663 } 2664 2665 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 2666 "startProcessLocked removing on hold: " + app); 2667 mProcessesOnHold.remove(app); 2668 2669 updateCpuStats(); 2670 2671 try { 2672 int uid = app.uid; 2673 2674 int[] gids = null; 2675 int mountExternal = Zygote.MOUNT_EXTERNAL_NONE; 2676 if (!app.isolated) { 2677 int[] permGids = null; 2678 try { 2679 final PackageManager pm = mContext.getPackageManager(); 2680 permGids = pm.getPackageGids(app.info.packageName); 2681 2682 if (Environment.isExternalStorageEmulated()) { 2683 if (pm.checkPermission( 2684 android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE, 2685 app.info.packageName) == PERMISSION_GRANTED) { 2686 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL; 2687 } else { 2688 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER; 2689 } 2690 } 2691 } catch (PackageManager.NameNotFoundException e) { 2692 Slog.w(TAG, "Unable to retrieve gids", e); 2693 } 2694 2695 /* 2696 * Add shared application GID so applications can share some 2697 * resources like shared libraries 2698 */ 2699 if (permGids == null) { 2700 gids = new int[1]; 2701 } else { 2702 gids = new int[permGids.length + 1]; 2703 System.arraycopy(permGids, 0, gids, 1, permGids.length); 2704 } 2705 gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid)); 2706 } 2707 if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) { 2708 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL 2709 && mTopComponent != null 2710 && app.processName.equals(mTopComponent.getPackageName())) { 2711 uid = 0; 2712 } 2713 if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL 2714 && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) { 2715 uid = 0; 2716 } 2717 } 2718 int debugFlags = 0; 2719 if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) { 2720 debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER; 2721 // Also turn on CheckJNI for debuggable apps. It's quite 2722 // awkward to turn on otherwise. 2723 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 2724 } 2725 // Run the app in safe mode if its manifest requests so or the 2726 // system is booted in safe mode. 2727 if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 || 2728 mSafeMode == true) { 2729 debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE; 2730 } 2731 if ("1".equals(SystemProperties.get("debug.checkjni"))) { 2732 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 2733 } 2734 if ("1".equals(SystemProperties.get("debug.jni.logging"))) { 2735 debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING; 2736 } 2737 if ("1".equals(SystemProperties.get("debug.assert"))) { 2738 debugFlags |= Zygote.DEBUG_ENABLE_ASSERT; 2739 } 2740 2741 String requiredAbi = app.info.requiredCpuAbi; 2742 if (requiredAbi == null) { 2743 requiredAbi = Build.SUPPORTED_ABIS[0]; 2744 } 2745 2746 // Start the process. It will either succeed and return a result containing 2747 // the PID of the new process, or else throw a RuntimeException. 2748 Process.ProcessStartResult startResult = Process.start("android.app.ActivityThread", 2749 app.processName, uid, uid, gids, debugFlags, mountExternal, 2750 app.info.targetSdkVersion, app.info.seinfo, requiredAbi, null); 2751 2752 BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics(); 2753 synchronized (bs) { 2754 if (bs.isOnBattery()) { 2755 bs.getProcessStatsLocked(app.uid, app.processName).incStartsLocked(); 2756 } 2757 } 2758 2759 EventLog.writeEvent(EventLogTags.AM_PROC_START, 2760 UserHandle.getUserId(uid), startResult.pid, uid, 2761 app.processName, hostingType, 2762 hostingNameStr != null ? hostingNameStr : ""); 2763 2764 if (app.persistent) { 2765 Watchdog.getInstance().processStarted(app.processName, startResult.pid); 2766 } 2767 2768 StringBuilder buf = mStringBuilder; 2769 buf.setLength(0); 2770 buf.append("Start proc "); 2771 buf.append(app.processName); 2772 buf.append(" for "); 2773 buf.append(hostingType); 2774 if (hostingNameStr != null) { 2775 buf.append(" "); 2776 buf.append(hostingNameStr); 2777 } 2778 buf.append(": pid="); 2779 buf.append(startResult.pid); 2780 buf.append(" uid="); 2781 buf.append(uid); 2782 buf.append(" gids={"); 2783 if (gids != null) { 2784 for (int gi=0; gi<gids.length; gi++) { 2785 if (gi != 0) buf.append(", "); 2786 buf.append(gids[gi]); 2787 2788 } 2789 } 2790 buf.append("}"); 2791 Slog.i(TAG, buf.toString()); 2792 app.setPid(startResult.pid); 2793 app.usingWrapper = startResult.usingWrapper; 2794 app.removed = false; 2795 synchronized (mPidsSelfLocked) { 2796 this.mPidsSelfLocked.put(startResult.pid, app); 2797 Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 2798 msg.obj = app; 2799 mHandler.sendMessageDelayed(msg, startResult.usingWrapper 2800 ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT); 2801 } 2802 } catch (RuntimeException e) { 2803 // XXX do better error recovery. 2804 app.setPid(0); 2805 Slog.e(TAG, "Failure starting process " + app.processName, e); 2806 } 2807 } 2808 2809 void updateUsageStats(ActivityRecord component, boolean resumed) { 2810 if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed); 2811 final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 2812 if (resumed) { 2813 mUsageStatsService.noteResumeComponent(component.realActivity); 2814 synchronized (stats) { 2815 stats.noteActivityResumedLocked(component.app.uid); 2816 } 2817 } else { 2818 mUsageStatsService.notePauseComponent(component.realActivity); 2819 synchronized (stats) { 2820 stats.noteActivityPausedLocked(component.app.uid); 2821 } 2822 } 2823 } 2824 2825 Intent getHomeIntent() { 2826 Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null); 2827 intent.setComponent(mTopComponent); 2828 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 2829 intent.addCategory(Intent.CATEGORY_HOME); 2830 } 2831 return intent; 2832 } 2833 2834 boolean startHomeActivityLocked(int userId) { 2835 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL 2836 && mTopAction == null) { 2837 // We are running in factory test mode, but unable to find 2838 // the factory test app, so just sit around displaying the 2839 // error message and don't try to start anything. 2840 return false; 2841 } 2842 Intent intent = getHomeIntent(); 2843 ActivityInfo aInfo = 2844 resolveActivityInfo(intent, STOCK_PM_FLAGS, userId); 2845 if (aInfo != null) { 2846 intent.setComponent(new ComponentName( 2847 aInfo.applicationInfo.packageName, aInfo.name)); 2848 // Don't do this if the home app is currently being 2849 // instrumented. 2850 aInfo = new ActivityInfo(aInfo); 2851 aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId); 2852 ProcessRecord app = getProcessRecordLocked(aInfo.processName, 2853 aInfo.applicationInfo.uid, true); 2854 if (app == null || app.instrumentationClass == null) { 2855 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK); 2856 mStackSupervisor.startHomeActivity(intent, aInfo); 2857 } 2858 } 2859 2860 return true; 2861 } 2862 2863 private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) { 2864 ActivityInfo ai = null; 2865 ComponentName comp = intent.getComponent(); 2866 try { 2867 if (comp != null) { 2868 ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId); 2869 } else { 2870 ResolveInfo info = AppGlobals.getPackageManager().resolveIntent( 2871 intent, 2872 intent.resolveTypeIfNeeded(mContext.getContentResolver()), 2873 flags, userId); 2874 2875 if (info != null) { 2876 ai = info.activityInfo; 2877 } 2878 } 2879 } catch (RemoteException e) { 2880 // ignore 2881 } 2882 2883 return ai; 2884 } 2885 2886 /** 2887 * Starts the "new version setup screen" if appropriate. 2888 */ 2889 void startSetupActivityLocked() { 2890 // Only do this once per boot. 2891 if (mCheckedForSetup) { 2892 return; 2893 } 2894 2895 // We will show this screen if the current one is a different 2896 // version than the last one shown, and we are not running in 2897 // low-level factory test mode. 2898 final ContentResolver resolver = mContext.getContentResolver(); 2899 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL && 2900 Settings.Global.getInt(resolver, 2901 Settings.Global.DEVICE_PROVISIONED, 0) != 0) { 2902 mCheckedForSetup = true; 2903 2904 // See if we should be showing the platform update setup UI. 2905 Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP); 2906 List<ResolveInfo> ris = mContext.getPackageManager() 2907 .queryIntentActivities(intent, PackageManager.GET_META_DATA); 2908 2909 // We don't allow third party apps to replace this. 2910 ResolveInfo ri = null; 2911 for (int i=0; ris != null && i<ris.size(); i++) { 2912 if ((ris.get(i).activityInfo.applicationInfo.flags 2913 & ApplicationInfo.FLAG_SYSTEM) != 0) { 2914 ri = ris.get(i); 2915 break; 2916 } 2917 } 2918 2919 if (ri != null) { 2920 String vers = ri.activityInfo.metaData != null 2921 ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION) 2922 : null; 2923 if (vers == null && ri.activityInfo.applicationInfo.metaData != null) { 2924 vers = ri.activityInfo.applicationInfo.metaData.getString( 2925 Intent.METADATA_SETUP_VERSION); 2926 } 2927 String lastVers = Settings.Secure.getString( 2928 resolver, Settings.Secure.LAST_SETUP_SHOWN); 2929 if (vers != null && !vers.equals(lastVers)) { 2930 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 2931 intent.setComponent(new ComponentName( 2932 ri.activityInfo.packageName, ri.activityInfo.name)); 2933 mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo, 2934 null, null, 0, 0, 0, null, 0, null, false, null, null); 2935 } 2936 } 2937 } 2938 } 2939 2940 CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) { 2941 return mCompatModePackages.compatibilityInfoForPackageLocked(ai); 2942 } 2943 2944 void enforceNotIsolatedCaller(String caller) { 2945 if (UserHandle.isIsolated(Binder.getCallingUid())) { 2946 throw new SecurityException("Isolated process not allowed to call " + caller); 2947 } 2948 } 2949 2950 @Override 2951 public int getFrontActivityScreenCompatMode() { 2952 enforceNotIsolatedCaller("getFrontActivityScreenCompatMode"); 2953 synchronized (this) { 2954 return mCompatModePackages.getFrontActivityScreenCompatModeLocked(); 2955 } 2956 } 2957 2958 @Override 2959 public void setFrontActivityScreenCompatMode(int mode) { 2960 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 2961 "setFrontActivityScreenCompatMode"); 2962 synchronized (this) { 2963 mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode); 2964 } 2965 } 2966 2967 @Override 2968 public int getPackageScreenCompatMode(String packageName) { 2969 enforceNotIsolatedCaller("getPackageScreenCompatMode"); 2970 synchronized (this) { 2971 return mCompatModePackages.getPackageScreenCompatModeLocked(packageName); 2972 } 2973 } 2974 2975 @Override 2976 public void setPackageScreenCompatMode(String packageName, int mode) { 2977 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 2978 "setPackageScreenCompatMode"); 2979 synchronized (this) { 2980 mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode); 2981 } 2982 } 2983 2984 @Override 2985 public boolean getPackageAskScreenCompat(String packageName) { 2986 enforceNotIsolatedCaller("getPackageAskScreenCompat"); 2987 synchronized (this) { 2988 return mCompatModePackages.getPackageAskCompatModeLocked(packageName); 2989 } 2990 } 2991 2992 @Override 2993 public void setPackageAskScreenCompat(String packageName, boolean ask) { 2994 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 2995 "setPackageAskScreenCompat"); 2996 synchronized (this) { 2997 mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask); 2998 } 2999 } 3000 3001 private void dispatchProcessesChanged() { 3002 int N; 3003 synchronized (this) { 3004 N = mPendingProcessChanges.size(); 3005 if (mActiveProcessChanges.length < N) { 3006 mActiveProcessChanges = new ProcessChangeItem[N]; 3007 } 3008 mPendingProcessChanges.toArray(mActiveProcessChanges); 3009 mAvailProcessChanges.addAll(mPendingProcessChanges); 3010 mPendingProcessChanges.clear(); 3011 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes"); 3012 } 3013 3014 int i = mProcessObservers.beginBroadcast(); 3015 while (i > 0) { 3016 i--; 3017 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 3018 if (observer != null) { 3019 try { 3020 for (int j=0; j<N; j++) { 3021 ProcessChangeItem item = mActiveProcessChanges[j]; 3022 if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) { 3023 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid=" 3024 + item.pid + " uid=" + item.uid + ": " 3025 + item.foregroundActivities); 3026 observer.onForegroundActivitiesChanged(item.pid, item.uid, 3027 item.foregroundActivities); 3028 } 3029 if ((item.changes&ProcessChangeItem.CHANGE_IMPORTANCE) != 0) { 3030 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "IMPORTANCE CHANGED pid=" 3031 + item.pid + " uid=" + item.uid + ": " + item.importance); 3032 observer.onImportanceChanged(item.pid, item.uid, 3033 item.importance); 3034 } 3035 } 3036 } catch (RemoteException e) { 3037 } 3038 } 3039 } 3040 mProcessObservers.finishBroadcast(); 3041 } 3042 3043 private void dispatchProcessDied(int pid, int uid) { 3044 int i = mProcessObservers.beginBroadcast(); 3045 while (i > 0) { 3046 i--; 3047 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 3048 if (observer != null) { 3049 try { 3050 observer.onProcessDied(pid, uid); 3051 } catch (RemoteException e) { 3052 } 3053 } 3054 } 3055 mProcessObservers.finishBroadcast(); 3056 } 3057 3058 final void doPendingActivityLaunchesLocked(boolean doResume) { 3059 final int N = mPendingActivityLaunches.size(); 3060 if (N <= 0) { 3061 return; 3062 } 3063 for (int i=0; i<N; i++) { 3064 PendingActivityLaunch pal = mPendingActivityLaunches.get(i); 3065 mStackSupervisor.startActivityUncheckedLocked(pal.r, pal.sourceRecord, pal.startFlags, 3066 doResume && i == (N-1), null); 3067 } 3068 mPendingActivityLaunches.clear(); 3069 } 3070 3071 @Override 3072 public final int startActivity(IApplicationThread caller, String callingPackage, 3073 Intent intent, String resolvedType, IBinder resultTo, 3074 String resultWho, int requestCode, int startFlags, 3075 String profileFile, ParcelFileDescriptor profileFd, Bundle options) { 3076 return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo, 3077 resultWho, requestCode, 3078 startFlags, profileFile, profileFd, options, UserHandle.getCallingUserId()); 3079 } 3080 3081 @Override 3082 public final int startActivityAsUser(IApplicationThread caller, String callingPackage, 3083 Intent intent, String resolvedType, IBinder resultTo, 3084 String resultWho, int requestCode, int startFlags, 3085 String profileFile, ParcelFileDescriptor profileFd, Bundle options, int userId) { 3086 enforceNotIsolatedCaller("startActivity"); 3087 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3088 false, true, "startActivity", null); 3089 // TODO: Switch to user app stacks here. 3090 return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType, 3091 resultTo, resultWho, requestCode, startFlags, profileFile, profileFd, 3092 null, null, options, userId, null); 3093 } 3094 3095 @Override 3096 public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage, 3097 Intent intent, String resolvedType, IBinder resultTo, 3098 String resultWho, int requestCode, int startFlags, String profileFile, 3099 ParcelFileDescriptor profileFd, Bundle options, int userId) { 3100 enforceNotIsolatedCaller("startActivityAndWait"); 3101 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3102 false, true, "startActivityAndWait", null); 3103 WaitResult res = new WaitResult(); 3104 // TODO: Switch to user app stacks here. 3105 mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType, 3106 resultTo, resultWho, requestCode, startFlags, profileFile, profileFd, 3107 res, null, options, UserHandle.getCallingUserId(), null); 3108 return res; 3109 } 3110 3111 @Override 3112 public final int startActivityWithConfig(IApplicationThread caller, String callingPackage, 3113 Intent intent, String resolvedType, IBinder resultTo, 3114 String resultWho, int requestCode, int startFlags, Configuration config, 3115 Bundle options, int userId) { 3116 enforceNotIsolatedCaller("startActivityWithConfig"); 3117 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3118 false, true, "startActivityWithConfig", null); 3119 // TODO: Switch to user app stacks here. 3120 int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, 3121 resolvedType, resultTo, resultWho, requestCode, startFlags, 3122 null, null, null, config, options, userId, null); 3123 return ret; 3124 } 3125 3126 @Override 3127 public int startActivityIntentSender(IApplicationThread caller, 3128 IntentSender intent, Intent fillInIntent, String resolvedType, 3129 IBinder resultTo, String resultWho, int requestCode, 3130 int flagsMask, int flagsValues, Bundle options) { 3131 enforceNotIsolatedCaller("startActivityIntentSender"); 3132 // Refuse possible leaked file descriptors 3133 if (fillInIntent != null && fillInIntent.hasFileDescriptors()) { 3134 throw new IllegalArgumentException("File descriptors passed in Intent"); 3135 } 3136 3137 IIntentSender sender = intent.getTarget(); 3138 if (!(sender instanceof PendingIntentRecord)) { 3139 throw new IllegalArgumentException("Bad PendingIntent object"); 3140 } 3141 3142 PendingIntentRecord pir = (PendingIntentRecord)sender; 3143 3144 synchronized (this) { 3145 // If this is coming from the currently resumed activity, it is 3146 // effectively saying that app switches are allowed at this point. 3147 final ActivityStack stack = getFocusedStack(); 3148 if (stack.mResumedActivity != null && 3149 stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) { 3150 mAppSwitchesAllowedTime = 0; 3151 } 3152 } 3153 int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null, 3154 resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null); 3155 return ret; 3156 } 3157 3158 @Override 3159 public boolean startNextMatchingActivity(IBinder callingActivity, 3160 Intent intent, Bundle options) { 3161 // Refuse possible leaked file descriptors 3162 if (intent != null && intent.hasFileDescriptors() == true) { 3163 throw new IllegalArgumentException("File descriptors passed in Intent"); 3164 } 3165 3166 synchronized (this) { 3167 final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity); 3168 if (r == null) { 3169 ActivityOptions.abort(options); 3170 return false; 3171 } 3172 if (r.app == null || r.app.thread == null) { 3173 // The caller is not running... d'oh! 3174 ActivityOptions.abort(options); 3175 return false; 3176 } 3177 intent = new Intent(intent); 3178 // The caller is not allowed to change the data. 3179 intent.setDataAndType(r.intent.getData(), r.intent.getType()); 3180 // And we are resetting to find the next component... 3181 intent.setComponent(null); 3182 3183 final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0); 3184 3185 ActivityInfo aInfo = null; 3186 try { 3187 List<ResolveInfo> resolves = 3188 AppGlobals.getPackageManager().queryIntentActivities( 3189 intent, r.resolvedType, 3190 PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS, 3191 UserHandle.getCallingUserId()); 3192 3193 // Look for the original activity in the list... 3194 final int N = resolves != null ? resolves.size() : 0; 3195 for (int i=0; i<N; i++) { 3196 ResolveInfo rInfo = resolves.get(i); 3197 if (rInfo.activityInfo.packageName.equals(r.packageName) 3198 && rInfo.activityInfo.name.equals(r.info.name)) { 3199 // We found the current one... the next matching is 3200 // after it. 3201 i++; 3202 if (i<N) { 3203 aInfo = resolves.get(i).activityInfo; 3204 } 3205 if (debug) { 3206 Slog.v(TAG, "Next matching activity: found current " + r.packageName 3207 + "/" + r.info.name); 3208 Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName 3209 + "/" + aInfo.name); 3210 } 3211 break; 3212 } 3213 } 3214 } catch (RemoteException e) { 3215 } 3216 3217 if (aInfo == null) { 3218 // Nobody who is next! 3219 ActivityOptions.abort(options); 3220 if (debug) Slog.d(TAG, "Next matching activity: nothing found"); 3221 return false; 3222 } 3223 3224 intent.setComponent(new ComponentName( 3225 aInfo.applicationInfo.packageName, aInfo.name)); 3226 intent.setFlags(intent.getFlags()&~( 3227 Intent.FLAG_ACTIVITY_FORWARD_RESULT| 3228 Intent.FLAG_ACTIVITY_CLEAR_TOP| 3229 Intent.FLAG_ACTIVITY_MULTIPLE_TASK| 3230 Intent.FLAG_ACTIVITY_NEW_TASK)); 3231 3232 // Okay now we need to start the new activity, replacing the 3233 // currently running activity. This is a little tricky because 3234 // we want to start the new one as if the current one is finished, 3235 // but not finish the current one first so that there is no flicker. 3236 // And thus... 3237 final boolean wasFinishing = r.finishing; 3238 r.finishing = true; 3239 3240 // Propagate reply information over to the new activity. 3241 final ActivityRecord resultTo = r.resultTo; 3242 final String resultWho = r.resultWho; 3243 final int requestCode = r.requestCode; 3244 r.resultTo = null; 3245 if (resultTo != null) { 3246 resultTo.removeResultsLocked(r, resultWho, requestCode); 3247 } 3248 3249 final long origId = Binder.clearCallingIdentity(); 3250 int res = mStackSupervisor.startActivityLocked(r.app.thread, intent, 3251 r.resolvedType, aInfo, resultTo != null ? resultTo.appToken : null, 3252 resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage, 0, 3253 options, false, null, null); 3254 Binder.restoreCallingIdentity(origId); 3255 3256 r.finishing = wasFinishing; 3257 if (res != ActivityManager.START_SUCCESS) { 3258 return false; 3259 } 3260 return true; 3261 } 3262 } 3263 3264 final int startActivityInPackage(int uid, String callingPackage, 3265 Intent intent, String resolvedType, IBinder resultTo, 3266 String resultWho, int requestCode, int startFlags, Bundle options, int userId, 3267 IActivityContainer container) { 3268 3269 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3270 false, true, "startActivityInPackage", null); 3271 3272 // TODO: Switch to user app stacks here. 3273 int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent, resolvedType, 3274 resultTo, resultWho, requestCode, startFlags, 3275 null, null, null, null, options, userId, container); 3276 return ret; 3277 } 3278 3279 @Override 3280 public final int startActivities(IApplicationThread caller, String callingPackage, 3281 Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options, 3282 int userId) { 3283 enforceNotIsolatedCaller("startActivities"); 3284 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3285 false, true, "startActivity", null); 3286 // TODO: Switch to user app stacks here. 3287 int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents, 3288 resolvedTypes, resultTo, options, userId); 3289 return ret; 3290 } 3291 3292 final int startActivitiesInPackage(int uid, String callingPackage, 3293 Intent[] intents, String[] resolvedTypes, IBinder resultTo, 3294 Bundle options, int userId) { 3295 3296 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3297 false, true, "startActivityInPackage", null); 3298 // TODO: Switch to user app stacks here. 3299 int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes, 3300 resultTo, options, userId); 3301 return ret; 3302 } 3303 3304 final void addRecentTaskLocked(TaskRecord task) { 3305 int N = mRecentTasks.size(); 3306 // Quick case: check if the top-most recent task is the same. 3307 if (N > 0 && mRecentTasks.get(0) == task) { 3308 return; 3309 } 3310 // Remove any existing entries that are the same kind of task. 3311 for (int i=0; i<N; i++) { 3312 TaskRecord tr = mRecentTasks.get(i); 3313 if (task.userId == tr.userId 3314 && ((task.affinity != null && task.affinity.equals(tr.affinity)) 3315 || (task.intent != null && task.intent.filterEquals(tr.intent)))) { 3316 tr.disposeThumbnail(); 3317 mRecentTasks.remove(i); 3318 i--; 3319 N--; 3320 if (task.intent == null) { 3321 // If the new recent task we are adding is not fully 3322 // specified, then replace it with the existing recent task. 3323 task = tr; 3324 } 3325 } 3326 } 3327 if (N >= MAX_RECENT_TASKS) { 3328 mRecentTasks.remove(N-1).disposeThumbnail(); 3329 } 3330 mRecentTasks.add(0, task); 3331 } 3332 3333 @Override 3334 public void reportActivityFullyDrawn(IBinder token) { 3335 synchronized (this) { 3336 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3337 if (r == null) { 3338 return; 3339 } 3340 r.reportFullyDrawnLocked(); 3341 } 3342 } 3343 3344 @Override 3345 public void setRequestedOrientation(IBinder token, int requestedOrientation) { 3346 synchronized (this) { 3347 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3348 if (r == null) { 3349 return; 3350 } 3351 final long origId = Binder.clearCallingIdentity(); 3352 mWindowManager.setAppOrientation(r.appToken, requestedOrientation); 3353 Configuration config = mWindowManager.updateOrientationFromAppTokens( 3354 mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null); 3355 if (config != null) { 3356 r.frozenBeforeDestroy = true; 3357 if (!updateConfigurationLocked(config, r, false, false)) { 3358 mStackSupervisor.resumeTopActivitiesLocked(); 3359 } 3360 } 3361 Binder.restoreCallingIdentity(origId); 3362 } 3363 } 3364 3365 @Override 3366 public int getRequestedOrientation(IBinder token) { 3367 synchronized (this) { 3368 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3369 if (r == null) { 3370 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; 3371 } 3372 return mWindowManager.getAppOrientation(r.appToken); 3373 } 3374 } 3375 3376 /** 3377 * This is the internal entry point for handling Activity.finish(). 3378 * 3379 * @param token The Binder token referencing the Activity we want to finish. 3380 * @param resultCode Result code, if any, from this Activity. 3381 * @param resultData Result data (Intent), if any, from this Activity. 3382 * 3383 * @return Returns true if the activity successfully finished, or false if it is still running. 3384 */ 3385 @Override 3386 public final boolean finishActivity(IBinder token, int resultCode, Intent resultData) { 3387 // Refuse possible leaked file descriptors 3388 if (resultData != null && resultData.hasFileDescriptors() == true) { 3389 throw new IllegalArgumentException("File descriptors passed in Intent"); 3390 } 3391 3392 synchronized(this) { 3393 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3394 if (r == null) { 3395 return true; 3396 } 3397 if (mController != null) { 3398 // Find the first activity that is not finishing. 3399 ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0); 3400 if (next != null) { 3401 // ask watcher if this is allowed 3402 boolean resumeOK = true; 3403 try { 3404 resumeOK = mController.activityResuming(next.packageName); 3405 } catch (RemoteException e) { 3406 mController = null; 3407 Watchdog.getInstance().setActivityController(null); 3408 } 3409 3410 if (!resumeOK) { 3411 return false; 3412 } 3413 } 3414 } 3415 final long origId = Binder.clearCallingIdentity(); 3416 boolean res = r.task.stack.requestFinishActivityLocked(token, resultCode, 3417 resultData, "app-request", true); 3418 Binder.restoreCallingIdentity(origId); 3419 return res; 3420 } 3421 } 3422 3423 @Override 3424 public final void finishHeavyWeightApp() { 3425 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 3426 != PackageManager.PERMISSION_GRANTED) { 3427 String msg = "Permission Denial: finishHeavyWeightApp() from pid=" 3428 + Binder.getCallingPid() 3429 + ", uid=" + Binder.getCallingUid() 3430 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 3431 Slog.w(TAG, msg); 3432 throw new SecurityException(msg); 3433 } 3434 3435 synchronized(this) { 3436 if (mHeavyWeightProcess == null) { 3437 return; 3438 } 3439 3440 ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>( 3441 mHeavyWeightProcess.activities); 3442 for (int i=0; i<activities.size(); i++) { 3443 ActivityRecord r = activities.get(i); 3444 if (!r.finishing) { 3445 r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED, 3446 null, "finish-heavy", true); 3447 } 3448 } 3449 3450 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 3451 mHeavyWeightProcess.userId, 0)); 3452 mHeavyWeightProcess = null; 3453 } 3454 } 3455 3456 @Override 3457 public void crashApplication(int uid, int initialPid, String packageName, 3458 String message) { 3459 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 3460 != PackageManager.PERMISSION_GRANTED) { 3461 String msg = "Permission Denial: crashApplication() from pid=" 3462 + Binder.getCallingPid() 3463 + ", uid=" + Binder.getCallingUid() 3464 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 3465 Slog.w(TAG, msg); 3466 throw new SecurityException(msg); 3467 } 3468 3469 synchronized(this) { 3470 ProcessRecord proc = null; 3471 3472 // Figure out which process to kill. We don't trust that initialPid 3473 // still has any relation to current pids, so must scan through the 3474 // list. 3475 synchronized (mPidsSelfLocked) { 3476 for (int i=0; i<mPidsSelfLocked.size(); i++) { 3477 ProcessRecord p = mPidsSelfLocked.valueAt(i); 3478 if (p.uid != uid) { 3479 continue; 3480 } 3481 if (p.pid == initialPid) { 3482 proc = p; 3483 break; 3484 } 3485 if (p.pkgList.containsKey(packageName)) { 3486 proc = p; 3487 } 3488 } 3489 } 3490 3491 if (proc == null) { 3492 Slog.w(TAG, "crashApplication: nothing for uid=" + uid 3493 + " initialPid=" + initialPid 3494 + " packageName=" + packageName); 3495 return; 3496 } 3497 3498 if (proc.thread != null) { 3499 if (proc.pid == Process.myPid()) { 3500 Log.w(TAG, "crashApplication: trying to crash self!"); 3501 return; 3502 } 3503 long ident = Binder.clearCallingIdentity(); 3504 try { 3505 proc.thread.scheduleCrash(message); 3506 } catch (RemoteException e) { 3507 } 3508 Binder.restoreCallingIdentity(ident); 3509 } 3510 } 3511 } 3512 3513 @Override 3514 public final void finishSubActivity(IBinder token, String resultWho, 3515 int requestCode) { 3516 synchronized(this) { 3517 final long origId = Binder.clearCallingIdentity(); 3518 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3519 if (r != null) { 3520 r.task.stack.finishSubActivityLocked(r, resultWho, requestCode); 3521 } 3522 Binder.restoreCallingIdentity(origId); 3523 } 3524 } 3525 3526 @Override 3527 public boolean finishActivityAffinity(IBinder token) { 3528 synchronized(this) { 3529 final long origId = Binder.clearCallingIdentity(); 3530 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3531 boolean res = false; 3532 if (r != null) { 3533 res = r.task.stack.finishActivityAffinityLocked(r); 3534 } 3535 Binder.restoreCallingIdentity(origId); 3536 return res; 3537 } 3538 } 3539 3540 @Override 3541 public boolean willActivityBeVisible(IBinder token) { 3542 synchronized(this) { 3543 ActivityStack stack = ActivityRecord.getStackLocked(token); 3544 if (stack != null) { 3545 return stack.willActivityBeVisibleLocked(token); 3546 } 3547 return false; 3548 } 3549 } 3550 3551 @Override 3552 public void overridePendingTransition(IBinder token, String packageName, 3553 int enterAnim, int exitAnim) { 3554 synchronized(this) { 3555 ActivityRecord self = ActivityRecord.isInStackLocked(token); 3556 if (self == null) { 3557 return; 3558 } 3559 3560 final long origId = Binder.clearCallingIdentity(); 3561 3562 if (self.state == ActivityState.RESUMED 3563 || self.state == ActivityState.PAUSING) { 3564 mWindowManager.overridePendingAppTransition(packageName, 3565 enterAnim, exitAnim, null); 3566 } 3567 3568 Binder.restoreCallingIdentity(origId); 3569 } 3570 } 3571 3572 /** 3573 * Main function for removing an existing process from the activity manager 3574 * as a result of that process going away. Clears out all connections 3575 * to the process. 3576 */ 3577 private final void handleAppDiedLocked(ProcessRecord app, 3578 boolean restarting, boolean allowRestart) { 3579 int pid = app.pid; 3580 cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1); 3581 if (!restarting) { 3582 removeLruProcessLocked(app); 3583 if (pid > 0) { 3584 ProcessList.remove(pid); 3585 } 3586 } 3587 3588 if (mProfileProc == app) { 3589 clearProfilerLocked(); 3590 } 3591 3592 // Remove this application's activities from active lists. 3593 boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app); 3594 3595 app.activities.clear(); 3596 3597 if (app.instrumentationClass != null) { 3598 Slog.w(TAG, "Crash of app " + app.processName 3599 + " running instrumentation " + app.instrumentationClass); 3600 Bundle info = new Bundle(); 3601 info.putString("shortMsg", "Process crashed."); 3602 finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info); 3603 } 3604 3605 if (!restarting) { 3606 if (!mStackSupervisor.resumeTopActivitiesLocked()) { 3607 // If there was nothing to resume, and we are not already 3608 // restarting this process, but there is a visible activity that 3609 // is hosted by the process... then make sure all visible 3610 // activities are running, taking care of restarting this 3611 // process. 3612 if (hasVisibleActivities) { 3613 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 3614 } 3615 } 3616 } 3617 } 3618 3619 private final int getLRURecordIndexForAppLocked(IApplicationThread thread) { 3620 IBinder threadBinder = thread.asBinder(); 3621 // Find the application record. 3622 for (int i=mLruProcesses.size()-1; i>=0; i--) { 3623 ProcessRecord rec = mLruProcesses.get(i); 3624 if (rec.thread != null && rec.thread.asBinder() == threadBinder) { 3625 return i; 3626 } 3627 } 3628 return -1; 3629 } 3630 3631 final ProcessRecord getRecordForAppLocked( 3632 IApplicationThread thread) { 3633 if (thread == null) { 3634 return null; 3635 } 3636 3637 int appIndex = getLRURecordIndexForAppLocked(thread); 3638 return appIndex >= 0 ? mLruProcesses.get(appIndex) : null; 3639 } 3640 3641 final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) { 3642 // If there are no longer any background processes running, 3643 // and the app that died was not running instrumentation, 3644 // then tell everyone we are now low on memory. 3645 boolean haveBg = false; 3646 for (int i=mLruProcesses.size()-1; i>=0; i--) { 3647 ProcessRecord rec = mLruProcesses.get(i); 3648 if (rec.thread != null 3649 && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 3650 haveBg = true; 3651 break; 3652 } 3653 } 3654 3655 if (!haveBg) { 3656 boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 3657 if (doReport) { 3658 long now = SystemClock.uptimeMillis(); 3659 if (now < (mLastMemUsageReportTime+5*60*1000)) { 3660 doReport = false; 3661 } else { 3662 mLastMemUsageReportTime = now; 3663 } 3664 } 3665 final ArrayList<ProcessMemInfo> memInfos 3666 = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null; 3667 EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size()); 3668 long now = SystemClock.uptimeMillis(); 3669 for (int i=mLruProcesses.size()-1; i>=0; i--) { 3670 ProcessRecord rec = mLruProcesses.get(i); 3671 if (rec == dyingProc || rec.thread == null) { 3672 continue; 3673 } 3674 if (doReport) { 3675 memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj, 3676 rec.setProcState, rec.adjType, rec.makeAdjReason())); 3677 } 3678 if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) { 3679 // The low memory report is overriding any current 3680 // state for a GC request. Make sure to do 3681 // heavy/important/visible/foreground processes first. 3682 if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 3683 rec.lastRequestedGc = 0; 3684 } else { 3685 rec.lastRequestedGc = rec.lastLowMemory; 3686 } 3687 rec.reportLowMemory = true; 3688 rec.lastLowMemory = now; 3689 mProcessesToGc.remove(rec); 3690 addProcessToGcListLocked(rec); 3691 } 3692 } 3693 if (doReport) { 3694 Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos); 3695 mHandler.sendMessage(msg); 3696 } 3697 scheduleAppGcsLocked(); 3698 } 3699 } 3700 3701 final void appDiedLocked(ProcessRecord app, int pid, 3702 IApplicationThread thread) { 3703 3704 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 3705 synchronized (stats) { 3706 stats.noteProcessDiedLocked(app.info.uid, pid); 3707 } 3708 3709 // Clean up already done if the process has been re-started. 3710 if (app.pid == pid && app.thread != null && 3711 app.thread.asBinder() == thread.asBinder()) { 3712 boolean doLowMem = app.instrumentationClass == null; 3713 boolean doOomAdj = doLowMem; 3714 if (!app.killedByAm) { 3715 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 3716 + ") has died."); 3717 mAllowLowerMemLevel = true; 3718 } else { 3719 // Note that we always want to do oom adj to update our state with the 3720 // new number of procs. 3721 mAllowLowerMemLevel = false; 3722 doLowMem = false; 3723 } 3724 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName); 3725 if (DEBUG_CLEANUP) Slog.v( 3726 TAG, "Dying app: " + app + ", pid: " + pid 3727 + ", thread: " + thread.asBinder()); 3728 handleAppDiedLocked(app, false, true); 3729 3730 if (doOomAdj) { 3731 updateOomAdjLocked(); 3732 } 3733 if (doLowMem) { 3734 doLowMemReportIfNeededLocked(app); 3735 } 3736 } else if (app.pid != pid) { 3737 // A new process has already been started. 3738 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 3739 + ") has died and restarted (pid " + app.pid + ")."); 3740 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName); 3741 } else if (DEBUG_PROCESSES) { 3742 Slog.d(TAG, "Received spurious death notification for thread " 3743 + thread.asBinder()); 3744 } 3745 } 3746 3747 /** 3748 * If a stack trace dump file is configured, dump process stack traces. 3749 * @param clearTraces causes the dump file to be erased prior to the new 3750 * traces being written, if true; when false, the new traces will be 3751 * appended to any existing file content. 3752 * @param firstPids of dalvik VM processes to dump stack traces for first 3753 * @param lastPids of dalvik VM processes to dump stack traces for last 3754 * @param nativeProcs optional list of native process names to dump stack crawls 3755 * @return file containing stack traces, or null if no dump file is configured 3756 */ 3757 public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids, 3758 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) { 3759 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 3760 if (tracesPath == null || tracesPath.length() == 0) { 3761 return null; 3762 } 3763 3764 File tracesFile = new File(tracesPath); 3765 try { 3766 File tracesDir = tracesFile.getParentFile(); 3767 if (!tracesDir.exists()) { 3768 tracesFile.mkdirs(); 3769 if (!SELinux.restorecon(tracesDir)) { 3770 return null; 3771 } 3772 } 3773 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 3774 3775 if (clearTraces && tracesFile.exists()) tracesFile.delete(); 3776 tracesFile.createNewFile(); 3777 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 3778 } catch (IOException e) { 3779 Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e); 3780 return null; 3781 } 3782 3783 dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs); 3784 return tracesFile; 3785 } 3786 3787 private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids, 3788 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) { 3789 // Use a FileObserver to detect when traces finish writing. 3790 // The order of traces is considered important to maintain for legibility. 3791 FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) { 3792 @Override 3793 public synchronized void onEvent(int event, String path) { notify(); } 3794 }; 3795 3796 try { 3797 observer.startWatching(); 3798 3799 // First collect all of the stacks of the most important pids. 3800 if (firstPids != null) { 3801 try { 3802 int num = firstPids.size(); 3803 for (int i = 0; i < num; i++) { 3804 synchronized (observer) { 3805 Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT); 3806 observer.wait(200); // Wait for write-close, give up after 200msec 3807 } 3808 } 3809 } catch (InterruptedException e) { 3810 Log.wtf(TAG, e); 3811 } 3812 } 3813 3814 // Next collect the stacks of the native pids 3815 if (nativeProcs != null) { 3816 int[] pids = Process.getPidsForCommands(nativeProcs); 3817 if (pids != null) { 3818 for (int pid : pids) { 3819 Debug.dumpNativeBacktraceToFile(pid, tracesPath); 3820 } 3821 } 3822 } 3823 3824 // Lastly, measure CPU usage. 3825 if (processCpuTracker != null) { 3826 processCpuTracker.init(); 3827 System.gc(); 3828 processCpuTracker.update(); 3829 try { 3830 synchronized (processCpuTracker) { 3831 processCpuTracker.wait(500); // measure over 1/2 second. 3832 } 3833 } catch (InterruptedException e) { 3834 } 3835 processCpuTracker.update(); 3836 3837 // We'll take the stack crawls of just the top apps using CPU. 3838 final int N = processCpuTracker.countWorkingStats(); 3839 int numProcs = 0; 3840 for (int i=0; i<N && numProcs<5; i++) { 3841 ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i); 3842 if (lastPids.indexOfKey(stats.pid) >= 0) { 3843 numProcs++; 3844 try { 3845 synchronized (observer) { 3846 Process.sendSignal(stats.pid, Process.SIGNAL_QUIT); 3847 observer.wait(200); // Wait for write-close, give up after 200msec 3848 } 3849 } catch (InterruptedException e) { 3850 Log.wtf(TAG, e); 3851 } 3852 3853 } 3854 } 3855 } 3856 } finally { 3857 observer.stopWatching(); 3858 } 3859 } 3860 3861 final void logAppTooSlow(ProcessRecord app, long startTime, String msg) { 3862 if (true || IS_USER_BUILD) { 3863 return; 3864 } 3865 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 3866 if (tracesPath == null || tracesPath.length() == 0) { 3867 return; 3868 } 3869 3870 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads(); 3871 StrictMode.allowThreadDiskWrites(); 3872 try { 3873 final File tracesFile = new File(tracesPath); 3874 final File tracesDir = tracesFile.getParentFile(); 3875 final File tracesTmp = new File(tracesDir, "__tmp__"); 3876 try { 3877 if (!tracesDir.exists()) { 3878 tracesFile.mkdirs(); 3879 if (!SELinux.restorecon(tracesDir.getPath())) { 3880 return; 3881 } 3882 } 3883 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 3884 3885 if (tracesFile.exists()) { 3886 tracesTmp.delete(); 3887 tracesFile.renameTo(tracesTmp); 3888 } 3889 StringBuilder sb = new StringBuilder(); 3890 Time tobj = new Time(); 3891 tobj.set(System.currentTimeMillis()); 3892 sb.append(tobj.format("%Y-%m-%d %H:%M:%S")); 3893 sb.append(": "); 3894 TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb); 3895 sb.append(" since "); 3896 sb.append(msg); 3897 FileOutputStream fos = new FileOutputStream(tracesFile); 3898 fos.write(sb.toString().getBytes()); 3899 if (app == null) { 3900 fos.write("\n*** No application process!".getBytes()); 3901 } 3902 fos.close(); 3903 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 3904 } catch (IOException e) { 3905 Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e); 3906 return; 3907 } 3908 3909 if (app != null) { 3910 ArrayList<Integer> firstPids = new ArrayList<Integer>(); 3911 firstPids.add(app.pid); 3912 dumpStackTraces(tracesPath, firstPids, null, null, null); 3913 } 3914 3915 File lastTracesFile = null; 3916 File curTracesFile = null; 3917 for (int i=9; i>=0; i--) { 3918 String name = String.format(Locale.US, "slow%02d.txt", i); 3919 curTracesFile = new File(tracesDir, name); 3920 if (curTracesFile.exists()) { 3921 if (lastTracesFile != null) { 3922 curTracesFile.renameTo(lastTracesFile); 3923 } else { 3924 curTracesFile.delete(); 3925 } 3926 } 3927 lastTracesFile = curTracesFile; 3928 } 3929 tracesFile.renameTo(curTracesFile); 3930 if (tracesTmp.exists()) { 3931 tracesTmp.renameTo(tracesFile); 3932 } 3933 } finally { 3934 StrictMode.setThreadPolicy(oldPolicy); 3935 } 3936 } 3937 3938 final void appNotResponding(ProcessRecord app, ActivityRecord activity, 3939 ActivityRecord parent, boolean aboveSystem, final String annotation) { 3940 ArrayList<Integer> firstPids = new ArrayList<Integer>(5); 3941 SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20); 3942 3943 if (mController != null) { 3944 try { 3945 // 0 == continue, -1 = kill process immediately 3946 int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation); 3947 if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid); 3948 } catch (RemoteException e) { 3949 mController = null; 3950 Watchdog.getInstance().setActivityController(null); 3951 } 3952 } 3953 3954 long anrTime = SystemClock.uptimeMillis(); 3955 if (MONITOR_CPU_USAGE) { 3956 updateCpuStatsNow(); 3957 } 3958 3959 synchronized (this) { 3960 // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down. 3961 if (mShuttingDown) { 3962 Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation); 3963 return; 3964 } else if (app.notResponding) { 3965 Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation); 3966 return; 3967 } else if (app.crashing) { 3968 Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation); 3969 return; 3970 } 3971 3972 // In case we come through here for the same app before completing 3973 // this one, mark as anring now so we will bail out. 3974 app.notResponding = true; 3975 3976 // Log the ANR to the event log. 3977 EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid, 3978 app.processName, app.info.flags, annotation); 3979 3980 // Dump thread traces as quickly as we can, starting with "interesting" processes. 3981 firstPids.add(app.pid); 3982 3983 int parentPid = app.pid; 3984 if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid; 3985 if (parentPid != app.pid) firstPids.add(parentPid); 3986 3987 if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID); 3988 3989 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 3990 ProcessRecord r = mLruProcesses.get(i); 3991 if (r != null && r.thread != null) { 3992 int pid = r.pid; 3993 if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) { 3994 if (r.persistent) { 3995 firstPids.add(pid); 3996 } else { 3997 lastPids.put(pid, Boolean.TRUE); 3998 } 3999 } 4000 } 4001 } 4002 } 4003 4004 // Log the ANR to the main log. 4005 StringBuilder info = new StringBuilder(); 4006 info.setLength(0); 4007 info.append("ANR in ").append(app.processName); 4008 if (activity != null && activity.shortComponentName != null) { 4009 info.append(" (").append(activity.shortComponentName).append(")"); 4010 } 4011 info.append("\n"); 4012 info.append("PID: ").append(app.pid).append("\n"); 4013 if (annotation != null) { 4014 info.append("Reason: ").append(annotation).append("\n"); 4015 } 4016 if (parent != null && parent != activity) { 4017 info.append("Parent: ").append(parent.shortComponentName).append("\n"); 4018 } 4019 4020 final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true); 4021 4022 File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids, 4023 NATIVE_STACKS_OF_INTEREST); 4024 4025 String cpuInfo = null; 4026 if (MONITOR_CPU_USAGE) { 4027 updateCpuStatsNow(); 4028 synchronized (mProcessCpuThread) { 4029 cpuInfo = mProcessCpuTracker.printCurrentState(anrTime); 4030 } 4031 info.append(processCpuTracker.printCurrentLoad()); 4032 info.append(cpuInfo); 4033 } 4034 4035 info.append(processCpuTracker.printCurrentState(anrTime)); 4036 4037 Slog.e(TAG, info.toString()); 4038 if (tracesFile == null) { 4039 // There is no trace file, so dump (only) the alleged culprit's threads to the log 4040 Process.sendSignal(app.pid, Process.SIGNAL_QUIT); 4041 } 4042 4043 addErrorToDropBox("anr", app, app.processName, activity, parent, annotation, 4044 cpuInfo, tracesFile, null); 4045 4046 if (mController != null) { 4047 try { 4048 // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately 4049 int res = mController.appNotResponding(app.processName, app.pid, info.toString()); 4050 if (res != 0) { 4051 if (res < 0 && app.pid != MY_PID) { 4052 Process.killProcess(app.pid); 4053 } else { 4054 synchronized (this) { 4055 mServices.scheduleServiceTimeoutLocked(app); 4056 } 4057 } 4058 return; 4059 } 4060 } catch (RemoteException e) { 4061 mController = null; 4062 Watchdog.getInstance().setActivityController(null); 4063 } 4064 } 4065 4066 // Unless configured otherwise, swallow ANRs in background processes & kill the process. 4067 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), 4068 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; 4069 4070 synchronized (this) { 4071 if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) { 4072 killUnneededProcessLocked(app, "background ANR"); 4073 return; 4074 } 4075 4076 // Set the app's notResponding state, and look up the errorReportReceiver 4077 makeAppNotRespondingLocked(app, 4078 activity != null ? activity.shortComponentName : null, 4079 annotation != null ? "ANR " + annotation : "ANR", 4080 info.toString()); 4081 4082 // Bring up the infamous App Not Responding dialog 4083 Message msg = Message.obtain(); 4084 HashMap<String, Object> map = new HashMap<String, Object>(); 4085 msg.what = SHOW_NOT_RESPONDING_MSG; 4086 msg.obj = map; 4087 msg.arg1 = aboveSystem ? 1 : 0; 4088 map.put("app", app); 4089 if (activity != null) { 4090 map.put("activity", activity); 4091 } 4092 4093 mHandler.sendMessage(msg); 4094 } 4095 } 4096 4097 final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) { 4098 if (!mLaunchWarningShown) { 4099 mLaunchWarningShown = true; 4100 mHandler.post(new Runnable() { 4101 @Override 4102 public void run() { 4103 synchronized (ActivityManagerService.this) { 4104 final Dialog d = new LaunchWarningWindow(mContext, cur, next); 4105 d.show(); 4106 mHandler.postDelayed(new Runnable() { 4107 @Override 4108 public void run() { 4109 synchronized (ActivityManagerService.this) { 4110 d.dismiss(); 4111 mLaunchWarningShown = false; 4112 } 4113 } 4114 }, 4000); 4115 } 4116 } 4117 }); 4118 } 4119 } 4120 4121 @Override 4122 public boolean clearApplicationUserData(final String packageName, 4123 final IPackageDataObserver observer, int userId) { 4124 enforceNotIsolatedCaller("clearApplicationUserData"); 4125 int uid = Binder.getCallingUid(); 4126 int pid = Binder.getCallingPid(); 4127 userId = handleIncomingUser(pid, uid, 4128 userId, false, true, "clearApplicationUserData", null); 4129 long callingId = Binder.clearCallingIdentity(); 4130 try { 4131 IPackageManager pm = AppGlobals.getPackageManager(); 4132 int pkgUid = -1; 4133 synchronized(this) { 4134 try { 4135 pkgUid = pm.getPackageUid(packageName, userId); 4136 } catch (RemoteException e) { 4137 } 4138 if (pkgUid == -1) { 4139 Slog.w(TAG, "Invalid packageName: " + packageName); 4140 if (observer != null) { 4141 try { 4142 observer.onRemoveCompleted(packageName, false); 4143 } catch (RemoteException e) { 4144 Slog.i(TAG, "Observer no longer exists."); 4145 } 4146 } 4147 return false; 4148 } 4149 if (uid == pkgUid || checkComponentPermission( 4150 android.Manifest.permission.CLEAR_APP_USER_DATA, 4151 pid, uid, -1, true) 4152 == PackageManager.PERMISSION_GRANTED) { 4153 forceStopPackageLocked(packageName, pkgUid, "clear data"); 4154 } else { 4155 throw new SecurityException("PID " + pid + " does not have permission " 4156 + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data" 4157 + " of package " + packageName); 4158 } 4159 } 4160 4161 try { 4162 // Clear application user data 4163 pm.clearApplicationUserData(packageName, observer, userId); 4164 4165 // Remove all permissions granted from/to this package 4166 removeUriPermissionsForPackageLocked(packageName, userId, true); 4167 4168 Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED, 4169 Uri.fromParts("package", packageName, null)); 4170 intent.putExtra(Intent.EXTRA_UID, pkgUid); 4171 broadcastIntentInPackage("android", Process.SYSTEM_UID, intent, 4172 null, null, 0, null, null, null, false, false, userId); 4173 } catch (RemoteException e) { 4174 } 4175 } finally { 4176 Binder.restoreCallingIdentity(callingId); 4177 } 4178 return true; 4179 } 4180 4181 @Override 4182 public void killBackgroundProcesses(final String packageName, int userId) { 4183 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 4184 != PackageManager.PERMISSION_GRANTED && 4185 checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES) 4186 != PackageManager.PERMISSION_GRANTED) { 4187 String msg = "Permission Denial: killBackgroundProcesses() from pid=" 4188 + Binder.getCallingPid() 4189 + ", uid=" + Binder.getCallingUid() 4190 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 4191 Slog.w(TAG, msg); 4192 throw new SecurityException(msg); 4193 } 4194 4195 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 4196 userId, true, true, "killBackgroundProcesses", null); 4197 long callingId = Binder.clearCallingIdentity(); 4198 try { 4199 IPackageManager pm = AppGlobals.getPackageManager(); 4200 synchronized(this) { 4201 int appId = -1; 4202 try { 4203 appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0)); 4204 } catch (RemoteException e) { 4205 } 4206 if (appId == -1) { 4207 Slog.w(TAG, "Invalid packageName: " + packageName); 4208 return; 4209 } 4210 killPackageProcessesLocked(packageName, appId, userId, 4211 ProcessList.SERVICE_ADJ, false, true, true, false, "kill background"); 4212 } 4213 } finally { 4214 Binder.restoreCallingIdentity(callingId); 4215 } 4216 } 4217 4218 @Override 4219 public void killAllBackgroundProcesses() { 4220 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 4221 != PackageManager.PERMISSION_GRANTED) { 4222 String msg = "Permission Denial: killAllBackgroundProcesses() from pid=" 4223 + Binder.getCallingPid() 4224 + ", uid=" + Binder.getCallingUid() 4225 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 4226 Slog.w(TAG, msg); 4227 throw new SecurityException(msg); 4228 } 4229 4230 long callingId = Binder.clearCallingIdentity(); 4231 try { 4232 synchronized(this) { 4233 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 4234 final int NP = mProcessNames.getMap().size(); 4235 for (int ip=0; ip<NP; ip++) { 4236 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 4237 final int NA = apps.size(); 4238 for (int ia=0; ia<NA; ia++) { 4239 ProcessRecord app = apps.valueAt(ia); 4240 if (app.persistent) { 4241 // we don't kill persistent processes 4242 continue; 4243 } 4244 if (app.removed) { 4245 procs.add(app); 4246 } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 4247 app.removed = true; 4248 procs.add(app); 4249 } 4250 } 4251 } 4252 4253 int N = procs.size(); 4254 for (int i=0; i<N; i++) { 4255 removeProcessLocked(procs.get(i), false, true, "kill all background"); 4256 } 4257 mAllowLowerMemLevel = true; 4258 updateOomAdjLocked(); 4259 doLowMemReportIfNeededLocked(null); 4260 } 4261 } finally { 4262 Binder.restoreCallingIdentity(callingId); 4263 } 4264 } 4265 4266 @Override 4267 public void forceStopPackage(final String packageName, int userId) { 4268 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 4269 != PackageManager.PERMISSION_GRANTED) { 4270 String msg = "Permission Denial: forceStopPackage() from pid=" 4271 + Binder.getCallingPid() 4272 + ", uid=" + Binder.getCallingUid() 4273 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 4274 Slog.w(TAG, msg); 4275 throw new SecurityException(msg); 4276 } 4277 final int callingPid = Binder.getCallingPid(); 4278 userId = handleIncomingUser(callingPid, Binder.getCallingUid(), 4279 userId, true, true, "forceStopPackage", null); 4280 long callingId = Binder.clearCallingIdentity(); 4281 try { 4282 IPackageManager pm = AppGlobals.getPackageManager(); 4283 synchronized(this) { 4284 int[] users = userId == UserHandle.USER_ALL 4285 ? getUsersLocked() : new int[] { userId }; 4286 for (int user : users) { 4287 int pkgUid = -1; 4288 try { 4289 pkgUid = pm.getPackageUid(packageName, user); 4290 } catch (RemoteException e) { 4291 } 4292 if (pkgUid == -1) { 4293 Slog.w(TAG, "Invalid packageName: " + packageName); 4294 continue; 4295 } 4296 try { 4297 pm.setPackageStoppedState(packageName, true, user); 4298 } catch (RemoteException e) { 4299 } catch (IllegalArgumentException e) { 4300 Slog.w(TAG, "Failed trying to unstop package " 4301 + packageName + ": " + e); 4302 } 4303 if (isUserRunningLocked(user, false)) { 4304 forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid); 4305 } 4306 } 4307 } 4308 } finally { 4309 Binder.restoreCallingIdentity(callingId); 4310 } 4311 } 4312 4313 /* 4314 * The pkg name and app id have to be specified. 4315 */ 4316 @Override 4317 public void killApplicationWithAppId(String pkg, int appid, String reason) { 4318 if (pkg == null) { 4319 return; 4320 } 4321 // Make sure the uid is valid. 4322 if (appid < 0) { 4323 Slog.w(TAG, "Invalid appid specified for pkg : " + pkg); 4324 return; 4325 } 4326 int callerUid = Binder.getCallingUid(); 4327 // Only the system server can kill an application 4328 if (callerUid == Process.SYSTEM_UID) { 4329 // Post an aysnc message to kill the application 4330 Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG); 4331 msg.arg1 = appid; 4332 msg.arg2 = 0; 4333 Bundle bundle = new Bundle(); 4334 bundle.putString("pkg", pkg); 4335 bundle.putString("reason", reason); 4336 msg.obj = bundle; 4337 mHandler.sendMessage(msg); 4338 } else { 4339 throw new SecurityException(callerUid + " cannot kill pkg: " + 4340 pkg); 4341 } 4342 } 4343 4344 @Override 4345 public void closeSystemDialogs(String reason) { 4346 enforceNotIsolatedCaller("closeSystemDialogs"); 4347 4348 final int pid = Binder.getCallingPid(); 4349 final int uid = Binder.getCallingUid(); 4350 final long origId = Binder.clearCallingIdentity(); 4351 try { 4352 synchronized (this) { 4353 // Only allow this from foreground processes, so that background 4354 // applications can't abuse it to prevent system UI from being shown. 4355 if (uid >= Process.FIRST_APPLICATION_UID) { 4356 ProcessRecord proc; 4357 synchronized (mPidsSelfLocked) { 4358 proc = mPidsSelfLocked.get(pid); 4359 } 4360 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 4361 Slog.w(TAG, "Ignoring closeSystemDialogs " + reason 4362 + " from background process " + proc); 4363 return; 4364 } 4365 } 4366 closeSystemDialogsLocked(reason); 4367 } 4368 } finally { 4369 Binder.restoreCallingIdentity(origId); 4370 } 4371 } 4372 4373 void closeSystemDialogsLocked(String reason) { 4374 Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS); 4375 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 4376 | Intent.FLAG_RECEIVER_FOREGROUND); 4377 if (reason != null) { 4378 intent.putExtra("reason", reason); 4379 } 4380 mWindowManager.closeSystemDialogs(reason); 4381 4382 mStackSupervisor.closeSystemDialogsLocked(); 4383 4384 broadcastIntentLocked(null, null, intent, null, 4385 null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1, 4386 Process.SYSTEM_UID, UserHandle.USER_ALL); 4387 } 4388 4389 @Override 4390 public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) { 4391 enforceNotIsolatedCaller("getProcessMemoryInfo"); 4392 Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length]; 4393 for (int i=pids.length-1; i>=0; i--) { 4394 ProcessRecord proc; 4395 int oomAdj; 4396 synchronized (this) { 4397 synchronized (mPidsSelfLocked) { 4398 proc = mPidsSelfLocked.get(pids[i]); 4399 oomAdj = proc != null ? proc.setAdj : 0; 4400 } 4401 } 4402 infos[i] = new Debug.MemoryInfo(); 4403 Debug.getMemoryInfo(pids[i], infos[i]); 4404 if (proc != null) { 4405 synchronized (this) { 4406 if (proc.thread != null && proc.setAdj == oomAdj) { 4407 // Record this for posterity if the process has been stable. 4408 proc.baseProcessTracker.addPss(infos[i].getTotalPss(), 4409 infos[i].getTotalUss(), false, proc.pkgList); 4410 } 4411 } 4412 } 4413 } 4414 return infos; 4415 } 4416 4417 @Override 4418 public long[] getProcessPss(int[] pids) { 4419 enforceNotIsolatedCaller("getProcessPss"); 4420 long[] pss = new long[pids.length]; 4421 for (int i=pids.length-1; i>=0; i--) { 4422 ProcessRecord proc; 4423 int oomAdj; 4424 synchronized (this) { 4425 synchronized (mPidsSelfLocked) { 4426 proc = mPidsSelfLocked.get(pids[i]); 4427 oomAdj = proc != null ? proc.setAdj : 0; 4428 } 4429 } 4430 long[] tmpUss = new long[1]; 4431 pss[i] = Debug.getPss(pids[i], tmpUss); 4432 if (proc != null) { 4433 synchronized (this) { 4434 if (proc.thread != null && proc.setAdj == oomAdj) { 4435 // Record this for posterity if the process has been stable. 4436 proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList); 4437 } 4438 } 4439 } 4440 } 4441 return pss; 4442 } 4443 4444 @Override 4445 public void killApplicationProcess(String processName, int uid) { 4446 if (processName == null) { 4447 return; 4448 } 4449 4450 int callerUid = Binder.getCallingUid(); 4451 // Only the system server can kill an application 4452 if (callerUid == Process.SYSTEM_UID) { 4453 synchronized (this) { 4454 ProcessRecord app = getProcessRecordLocked(processName, uid, true); 4455 if (app != null && app.thread != null) { 4456 try { 4457 app.thread.scheduleSuicide(); 4458 } catch (RemoteException e) { 4459 // If the other end already died, then our work here is done. 4460 } 4461 } else { 4462 Slog.w(TAG, "Process/uid not found attempting kill of " 4463 + processName + " / " + uid); 4464 } 4465 } 4466 } else { 4467 throw new SecurityException(callerUid + " cannot kill app process: " + 4468 processName); 4469 } 4470 } 4471 4472 private void forceStopPackageLocked(final String packageName, int uid, String reason) { 4473 forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false, 4474 false, true, false, UserHandle.getUserId(uid), reason); 4475 Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED, 4476 Uri.fromParts("package", packageName, null)); 4477 if (!mProcessesReady) { 4478 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 4479 | Intent.FLAG_RECEIVER_FOREGROUND); 4480 } 4481 intent.putExtra(Intent.EXTRA_UID, uid); 4482 intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid)); 4483 broadcastIntentLocked(null, null, intent, 4484 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 4485 false, false, 4486 MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid)); 4487 } 4488 4489 private void forceStopUserLocked(int userId, String reason) { 4490 forceStopPackageLocked(null, -1, false, false, true, false, userId, reason); 4491 Intent intent = new Intent(Intent.ACTION_USER_STOPPED); 4492 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 4493 | Intent.FLAG_RECEIVER_FOREGROUND); 4494 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 4495 broadcastIntentLocked(null, null, intent, 4496 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 4497 false, false, 4498 MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 4499 } 4500 4501 private final boolean killPackageProcessesLocked(String packageName, int appId, 4502 int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart, 4503 boolean doit, boolean evenPersistent, String reason) { 4504 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 4505 4506 // Remove all processes this package may have touched: all with the 4507 // same UID (except for the system or root user), and all whose name 4508 // matches the package name. 4509 final String procNamePrefix = packageName != null ? (packageName + ":") : null; 4510 final int NP = mProcessNames.getMap().size(); 4511 for (int ip=0; ip<NP; ip++) { 4512 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 4513 final int NA = apps.size(); 4514 for (int ia=0; ia<NA; ia++) { 4515 ProcessRecord app = apps.valueAt(ia); 4516 if (app.persistent && !evenPersistent) { 4517 // we don't kill persistent processes 4518 continue; 4519 } 4520 if (app.removed) { 4521 if (doit) { 4522 procs.add(app); 4523 } 4524 continue; 4525 } 4526 4527 // Skip process if it doesn't meet our oom adj requirement. 4528 if (app.setAdj < minOomAdj) { 4529 continue; 4530 } 4531 4532 // If no package is specified, we call all processes under the 4533 // give user id. 4534 if (packageName == null) { 4535 if (app.userId != userId) { 4536 continue; 4537 } 4538 if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) { 4539 continue; 4540 } 4541 // Package has been specified, we want to hit all processes 4542 // that match it. We need to qualify this by the processes 4543 // that are running under the specified app and user ID. 4544 } else { 4545 if (UserHandle.getAppId(app.uid) != appId) { 4546 continue; 4547 } 4548 if (userId != UserHandle.USER_ALL && app.userId != userId) { 4549 continue; 4550 } 4551 if (!app.pkgList.containsKey(packageName)) { 4552 continue; 4553 } 4554 } 4555 4556 // Process has passed all conditions, kill it! 4557 if (!doit) { 4558 return true; 4559 } 4560 app.removed = true; 4561 procs.add(app); 4562 } 4563 } 4564 4565 int N = procs.size(); 4566 for (int i=0; i<N; i++) { 4567 removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason); 4568 } 4569 updateOomAdjLocked(); 4570 return N > 0; 4571 } 4572 4573 private final boolean forceStopPackageLocked(String name, int appId, 4574 boolean callerWillRestart, boolean purgeCache, boolean doit, 4575 boolean evenPersistent, int userId, String reason) { 4576 int i; 4577 int N; 4578 4579 if (userId == UserHandle.USER_ALL && name == null) { 4580 Slog.w(TAG, "Can't force stop all processes of all users, that is insane!"); 4581 } 4582 4583 if (appId < 0 && name != null) { 4584 try { 4585 appId = UserHandle.getAppId( 4586 AppGlobals.getPackageManager().getPackageUid(name, 0)); 4587 } catch (RemoteException e) { 4588 } 4589 } 4590 4591 if (doit) { 4592 if (name != null) { 4593 Slog.i(TAG, "Force stopping " + name + " appid=" + appId 4594 + " user=" + userId + ": " + reason); 4595 } else { 4596 Slog.i(TAG, "Force stopping u" + userId + ": " + reason); 4597 } 4598 4599 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap(); 4600 for (int ip=pmap.size()-1; ip>=0; ip--) { 4601 SparseArray<Long> ba = pmap.valueAt(ip); 4602 for (i=ba.size()-1; i>=0; i--) { 4603 boolean remove = false; 4604 final int entUid = ba.keyAt(i); 4605 if (name != null) { 4606 if (userId == UserHandle.USER_ALL) { 4607 if (UserHandle.getAppId(entUid) == appId) { 4608 remove = true; 4609 } 4610 } else { 4611 if (entUid == UserHandle.getUid(userId, appId)) { 4612 remove = true; 4613 } 4614 } 4615 } else if (UserHandle.getUserId(entUid) == userId) { 4616 remove = true; 4617 } 4618 if (remove) { 4619 ba.removeAt(i); 4620 } 4621 } 4622 if (ba.size() == 0) { 4623 pmap.removeAt(ip); 4624 } 4625 } 4626 } 4627 4628 boolean didSomething = killPackageProcessesLocked(name, appId, userId, 4629 -100, callerWillRestart, true, doit, evenPersistent, 4630 name == null ? ("stop user " + userId) : ("stop " + name)); 4631 4632 if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) { 4633 if (!doit) { 4634 return true; 4635 } 4636 didSomething = true; 4637 } 4638 4639 if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) { 4640 if (!doit) { 4641 return true; 4642 } 4643 didSomething = true; 4644 } 4645 4646 if (name == null) { 4647 // Remove all sticky broadcasts from this user. 4648 mStickyBroadcasts.remove(userId); 4649 } 4650 4651 ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>(); 4652 if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent, 4653 userId, providers)) { 4654 if (!doit) { 4655 return true; 4656 } 4657 didSomething = true; 4658 } 4659 N = providers.size(); 4660 for (i=0; i<N; i++) { 4661 removeDyingProviderLocked(null, providers.get(i), true); 4662 } 4663 4664 // Remove transient permissions granted from/to this package/user 4665 removeUriPermissionsForPackageLocked(name, userId, false); 4666 4667 if (name == null) { 4668 // Remove pending intents. For now we only do this when force 4669 // stopping users, because we have some problems when doing this 4670 // for packages -- app widgets are not currently cleaned up for 4671 // such packages, so they can be left with bad pending intents. 4672 if (mIntentSenderRecords.size() > 0) { 4673 Iterator<WeakReference<PendingIntentRecord>> it 4674 = mIntentSenderRecords.values().iterator(); 4675 while (it.hasNext()) { 4676 WeakReference<PendingIntentRecord> wpir = it.next(); 4677 if (wpir == null) { 4678 it.remove(); 4679 continue; 4680 } 4681 PendingIntentRecord pir = wpir.get(); 4682 if (pir == null) { 4683 it.remove(); 4684 continue; 4685 } 4686 if (name == null) { 4687 // Stopping user, remove all objects for the user. 4688 if (pir.key.userId != userId) { 4689 // Not the same user, skip it. 4690 continue; 4691 } 4692 } else { 4693 if (UserHandle.getAppId(pir.uid) != appId) { 4694 // Different app id, skip it. 4695 continue; 4696 } 4697 if (userId != UserHandle.USER_ALL && pir.key.userId != userId) { 4698 // Different user, skip it. 4699 continue; 4700 } 4701 if (!pir.key.packageName.equals(name)) { 4702 // Different package, skip it. 4703 continue; 4704 } 4705 } 4706 if (!doit) { 4707 return true; 4708 } 4709 didSomething = true; 4710 it.remove(); 4711 pir.canceled = true; 4712 if (pir.key.activity != null) { 4713 pir.key.activity.pendingResults.remove(pir.ref); 4714 } 4715 } 4716 } 4717 } 4718 4719 if (doit) { 4720 if (purgeCache && name != null) { 4721 AttributeCache ac = AttributeCache.instance(); 4722 if (ac != null) { 4723 ac.removePackage(name); 4724 } 4725 } 4726 if (mBooted) { 4727 mStackSupervisor.resumeTopActivitiesLocked(); 4728 mStackSupervisor.scheduleIdleLocked(); 4729 } 4730 } 4731 4732 return didSomething; 4733 } 4734 4735 private final boolean removeProcessLocked(ProcessRecord app, 4736 boolean callerWillRestart, boolean allowRestart, String reason) { 4737 final String name = app.processName; 4738 final int uid = app.uid; 4739 if (DEBUG_PROCESSES) Slog.d( 4740 TAG, "Force removing proc " + app.toShortString() + " (" + name 4741 + "/" + uid + ")"); 4742 4743 mProcessNames.remove(name, uid); 4744 mIsolatedProcesses.remove(app.uid); 4745 if (mHeavyWeightProcess == app) { 4746 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 4747 mHeavyWeightProcess.userId, 0)); 4748 mHeavyWeightProcess = null; 4749 } 4750 boolean needRestart = false; 4751 if (app.pid > 0 && app.pid != MY_PID) { 4752 int pid = app.pid; 4753 synchronized (mPidsSelfLocked) { 4754 mPidsSelfLocked.remove(pid); 4755 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 4756 } 4757 killUnneededProcessLocked(app, reason); 4758 handleAppDiedLocked(app, true, allowRestart); 4759 removeLruProcessLocked(app); 4760 4761 if (app.persistent && !app.isolated) { 4762 if (!callerWillRestart) { 4763 addAppLocked(app.info, false); 4764 } else { 4765 needRestart = true; 4766 } 4767 } 4768 } else { 4769 mRemovedProcesses.add(app); 4770 } 4771 4772 return needRestart; 4773 } 4774 4775 private final void processStartTimedOutLocked(ProcessRecord app) { 4776 final int pid = app.pid; 4777 boolean gone = false; 4778 synchronized (mPidsSelfLocked) { 4779 ProcessRecord knownApp = mPidsSelfLocked.get(pid); 4780 if (knownApp != null && knownApp.thread == null) { 4781 mPidsSelfLocked.remove(pid); 4782 gone = true; 4783 } 4784 } 4785 4786 if (gone) { 4787 Slog.w(TAG, "Process " + app + " failed to attach"); 4788 EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId, 4789 pid, app.uid, app.processName); 4790 mProcessNames.remove(app.processName, app.uid); 4791 mIsolatedProcesses.remove(app.uid); 4792 if (mHeavyWeightProcess == app) { 4793 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 4794 mHeavyWeightProcess.userId, 0)); 4795 mHeavyWeightProcess = null; 4796 } 4797 // Take care of any launching providers waiting for this process. 4798 checkAppInLaunchingProvidersLocked(app, true); 4799 // Take care of any services that are waiting for the process. 4800 mServices.processStartTimedOutLocked(app); 4801 killUnneededProcessLocked(app, "start timeout"); 4802 if (mBackupTarget != null && mBackupTarget.app.pid == pid) { 4803 Slog.w(TAG, "Unattached app died before backup, skipping"); 4804 try { 4805 IBackupManager bm = IBackupManager.Stub.asInterface( 4806 ServiceManager.getService(Context.BACKUP_SERVICE)); 4807 bm.agentDisconnected(app.info.packageName); 4808 } catch (RemoteException e) { 4809 // Can't happen; the backup manager is local 4810 } 4811 } 4812 if (isPendingBroadcastProcessLocked(pid)) { 4813 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 4814 skipPendingBroadcastLocked(pid); 4815 } 4816 } else { 4817 Slog.w(TAG, "Spurious process start timeout - pid not known for " + app); 4818 } 4819 } 4820 4821 private final boolean attachApplicationLocked(IApplicationThread thread, 4822 int pid) { 4823 4824 // Find the application record that is being attached... either via 4825 // the pid if we are running in multiple processes, or just pull the 4826 // next app record if we are emulating process with anonymous threads. 4827 ProcessRecord app; 4828 if (pid != MY_PID && pid >= 0) { 4829 synchronized (mPidsSelfLocked) { 4830 app = mPidsSelfLocked.get(pid); 4831 } 4832 } else { 4833 app = null; 4834 } 4835 4836 if (app == null) { 4837 Slog.w(TAG, "No pending application record for pid " + pid 4838 + " (IApplicationThread " + thread + "); dropping process"); 4839 EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid); 4840 if (pid > 0 && pid != MY_PID) { 4841 Process.killProcessQuiet(pid); 4842 } else { 4843 try { 4844 thread.scheduleExit(); 4845 } catch (Exception e) { 4846 // Ignore exceptions. 4847 } 4848 } 4849 return false; 4850 } 4851 4852 // If this application record is still attached to a previous 4853 // process, clean it up now. 4854 if (app.thread != null) { 4855 handleAppDiedLocked(app, true, true); 4856 } 4857 4858 // Tell the process all about itself. 4859 4860 if (localLOGV) Slog.v( 4861 TAG, "Binding process pid " + pid + " to record " + app); 4862 4863 final String processName = app.processName; 4864 try { 4865 AppDeathRecipient adr = new AppDeathRecipient( 4866 app, pid, thread); 4867 thread.asBinder().linkToDeath(adr, 0); 4868 app.deathRecipient = adr; 4869 } catch (RemoteException e) { 4870 app.resetPackageList(mProcessStats); 4871 startProcessLocked(app, "link fail", processName); 4872 return false; 4873 } 4874 4875 EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName); 4876 4877 app.makeActive(thread, mProcessStats); 4878 app.curAdj = app.setAdj = -100; 4879 app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT; 4880 app.forcingToForeground = null; 4881 app.foregroundServices = false; 4882 app.hasShownUi = false; 4883 app.debugging = false; 4884 app.cached = false; 4885 4886 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 4887 4888 boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info); 4889 List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null; 4890 4891 if (!normalMode) { 4892 Slog.i(TAG, "Launching preboot mode app: " + app); 4893 } 4894 4895 if (localLOGV) Slog.v( 4896 TAG, "New app record " + app 4897 + " thread=" + thread.asBinder() + " pid=" + pid); 4898 try { 4899 int testMode = IApplicationThread.DEBUG_OFF; 4900 if (mDebugApp != null && mDebugApp.equals(processName)) { 4901 testMode = mWaitForDebugger 4902 ? IApplicationThread.DEBUG_WAIT 4903 : IApplicationThread.DEBUG_ON; 4904 app.debugging = true; 4905 if (mDebugTransient) { 4906 mDebugApp = mOrigDebugApp; 4907 mWaitForDebugger = mOrigWaitForDebugger; 4908 } 4909 } 4910 String profileFile = app.instrumentationProfileFile; 4911 ParcelFileDescriptor profileFd = null; 4912 boolean profileAutoStop = false; 4913 if (mProfileApp != null && mProfileApp.equals(processName)) { 4914 mProfileProc = app; 4915 profileFile = mProfileFile; 4916 profileFd = mProfileFd; 4917 profileAutoStop = mAutoStopProfiler; 4918 } 4919 boolean enableOpenGlTrace = false; 4920 if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) { 4921 enableOpenGlTrace = true; 4922 mOpenGlTraceApp = null; 4923 } 4924 4925 // If the app is being launched for restore or full backup, set it up specially 4926 boolean isRestrictedBackupMode = false; 4927 if (mBackupTarget != null && mBackupAppName.equals(processName)) { 4928 isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE) 4929 || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL) 4930 || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL); 4931 } 4932 4933 ensurePackageDexOpt(app.instrumentationInfo != null 4934 ? app.instrumentationInfo.packageName 4935 : app.info.packageName); 4936 if (app.instrumentationClass != null) { 4937 ensurePackageDexOpt(app.instrumentationClass.getPackageName()); 4938 } 4939 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc " 4940 + processName + " with config " + mConfiguration); 4941 ApplicationInfo appInfo = app.instrumentationInfo != null 4942 ? app.instrumentationInfo : app.info; 4943 app.compat = compatibilityInfoForPackageLocked(appInfo); 4944 if (profileFd != null) { 4945 profileFd = profileFd.dup(); 4946 } 4947 thread.bindApplication(processName, appInfo, providers, 4948 app.instrumentationClass, profileFile, profileFd, profileAutoStop, 4949 app.instrumentationArguments, app.instrumentationWatcher, 4950 app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace, 4951 isRestrictedBackupMode || !normalMode, app.persistent, 4952 new Configuration(mConfiguration), app.compat, getCommonServicesLocked(), 4953 mCoreSettingsObserver.getCoreSettingsLocked()); 4954 updateLruProcessLocked(app, false, null); 4955 app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis(); 4956 } catch (Exception e) { 4957 // todo: Yikes! What should we do? For now we will try to 4958 // start another process, but that could easily get us in 4959 // an infinite loop of restarting processes... 4960 Slog.w(TAG, "Exception thrown during bind!", e); 4961 4962 app.resetPackageList(mProcessStats); 4963 app.unlinkDeathRecipient(); 4964 startProcessLocked(app, "bind fail", processName); 4965 return false; 4966 } 4967 4968 // Remove this record from the list of starting applications. 4969 mPersistentStartingProcesses.remove(app); 4970 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 4971 "Attach application locked removing on hold: " + app); 4972 mProcessesOnHold.remove(app); 4973 4974 boolean badApp = false; 4975 boolean didSomething = false; 4976 4977 // See if the top visible activity is waiting to run in this process... 4978 if (normalMode) { 4979 try { 4980 if (mStackSupervisor.attachApplicationLocked(app)) { 4981 didSomething = true; 4982 } 4983 } catch (Exception e) { 4984 badApp = true; 4985 } 4986 } 4987 4988 // Find any services that should be running in this process... 4989 if (!badApp) { 4990 try { 4991 didSomething |= mServices.attachApplicationLocked(app, processName); 4992 } catch (Exception e) { 4993 badApp = true; 4994 } 4995 } 4996 4997 // Check if a next-broadcast receiver is in this process... 4998 if (!badApp && isPendingBroadcastProcessLocked(pid)) { 4999 try { 5000 didSomething |= sendPendingBroadcastsLocked(app); 5001 } catch (Exception e) { 5002 // If the app died trying to launch the receiver we declare it 'bad' 5003 badApp = true; 5004 } 5005 } 5006 5007 // Check whether the next backup agent is in this process... 5008 if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) { 5009 if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app); 5010 ensurePackageDexOpt(mBackupTarget.appInfo.packageName); 5011 try { 5012 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo, 5013 compatibilityInfoForPackageLocked(mBackupTarget.appInfo), 5014 mBackupTarget.backupMode); 5015 } catch (Exception e) { 5016 Slog.w(TAG, "Exception scheduling backup agent creation: "); 5017 e.printStackTrace(); 5018 } 5019 } 5020 5021 if (badApp) { 5022 // todo: Also need to kill application to deal with all 5023 // kinds of exceptions. 5024 handleAppDiedLocked(app, false, true); 5025 return false; 5026 } 5027 5028 if (!didSomething) { 5029 updateOomAdjLocked(); 5030 } 5031 5032 return true; 5033 } 5034 5035 @Override 5036 public final void attachApplication(IApplicationThread thread) { 5037 synchronized (this) { 5038 int callingPid = Binder.getCallingPid(); 5039 final long origId = Binder.clearCallingIdentity(); 5040 attachApplicationLocked(thread, callingPid); 5041 Binder.restoreCallingIdentity(origId); 5042 } 5043 } 5044 5045 @Override 5046 public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) { 5047 final long origId = Binder.clearCallingIdentity(); 5048 synchronized (this) { 5049 ActivityStack stack = ActivityRecord.getStackLocked(token); 5050 if (stack != null) { 5051 ActivityRecord r = 5052 mStackSupervisor.activityIdleInternalLocked(token, false, config); 5053 if (stopProfiling) { 5054 if ((mProfileProc == r.app) && (mProfileFd != null)) { 5055 try { 5056 mProfileFd.close(); 5057 } catch (IOException e) { 5058 } 5059 clearProfilerLocked(); 5060 } 5061 } 5062 } 5063 } 5064 Binder.restoreCallingIdentity(origId); 5065 } 5066 5067 void enableScreenAfterBoot() { 5068 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN, 5069 SystemClock.uptimeMillis()); 5070 mWindowManager.enableScreenAfterBoot(); 5071 5072 synchronized (this) { 5073 updateEventDispatchingLocked(); 5074 } 5075 } 5076 5077 @Override 5078 public void showBootMessage(final CharSequence msg, final boolean always) { 5079 enforceNotIsolatedCaller("showBootMessage"); 5080 mWindowManager.showBootMessage(msg, always); 5081 } 5082 5083 @Override 5084 public void dismissKeyguardOnNextActivity() { 5085 enforceNotIsolatedCaller("dismissKeyguardOnNextActivity"); 5086 final long token = Binder.clearCallingIdentity(); 5087 try { 5088 synchronized (this) { 5089 if (DEBUG_LOCKSCREEN) logLockScreen(""); 5090 if (mLockScreenShown) { 5091 mLockScreenShown = false; 5092 comeOutOfSleepIfNeededLocked(); 5093 } 5094 mStackSupervisor.setDismissKeyguard(true); 5095 } 5096 } finally { 5097 Binder.restoreCallingIdentity(token); 5098 } 5099 } 5100 5101 final void finishBooting() { 5102 IntentFilter pkgFilter = new IntentFilter(); 5103 pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART); 5104 pkgFilter.addDataScheme("package"); 5105 mContext.registerReceiver(new BroadcastReceiver() { 5106 @Override 5107 public void onReceive(Context context, Intent intent) { 5108 String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES); 5109 if (pkgs != null) { 5110 for (String pkg : pkgs) { 5111 synchronized (ActivityManagerService.this) { 5112 if (forceStopPackageLocked(pkg, -1, false, false, false, false, 0, 5113 "finished booting")) { 5114 setResultCode(Activity.RESULT_OK); 5115 return; 5116 } 5117 } 5118 } 5119 } 5120 } 5121 }, pkgFilter); 5122 5123 synchronized (this) { 5124 // Ensure that any processes we had put on hold are now started 5125 // up. 5126 final int NP = mProcessesOnHold.size(); 5127 if (NP > 0) { 5128 ArrayList<ProcessRecord> procs = 5129 new ArrayList<ProcessRecord>(mProcessesOnHold); 5130 for (int ip=0; ip<NP; ip++) { 5131 if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: " 5132 + procs.get(ip)); 5133 startProcessLocked(procs.get(ip), "on-hold", null); 5134 } 5135 } 5136 5137 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 5138 // Start looking for apps that are abusing wake locks. 5139 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 5140 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 5141 // Tell anyone interested that we are done booting! 5142 SystemProperties.set("sys.boot_completed", "1"); 5143 SystemProperties.set("dev.bootcomplete", "1"); 5144 for (int i=0; i<mStartedUsers.size(); i++) { 5145 UserStartedState uss = mStartedUsers.valueAt(i); 5146 if (uss.mState == UserStartedState.STATE_BOOTING) { 5147 uss.mState = UserStartedState.STATE_RUNNING; 5148 final int userId = mStartedUsers.keyAt(i); 5149 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 5150 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 5151 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT); 5152 broadcastIntentLocked(null, null, intent, null, 5153 new IIntentReceiver.Stub() { 5154 @Override 5155 public void performReceive(Intent intent, int resultCode, 5156 String data, Bundle extras, boolean ordered, 5157 boolean sticky, int sendingUser) { 5158 synchronized (ActivityManagerService.this) { 5159 requestPssAllProcsLocked(SystemClock.uptimeMillis(), 5160 true, false); 5161 } 5162 } 5163 }, 5164 0, null, null, 5165 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, 5166 AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID, 5167 userId); 5168 } 5169 } 5170 } 5171 } 5172 } 5173 5174 final void ensureBootCompleted() { 5175 boolean booting; 5176 boolean enableScreen; 5177 synchronized (this) { 5178 booting = mBooting; 5179 mBooting = false; 5180 enableScreen = !mBooted; 5181 mBooted = true; 5182 } 5183 5184 if (booting) { 5185 finishBooting(); 5186 } 5187 5188 if (enableScreen) { 5189 enableScreenAfterBoot(); 5190 } 5191 } 5192 5193 @Override 5194 public final void activityResumed(IBinder token) { 5195 final long origId = Binder.clearCallingIdentity(); 5196 synchronized(this) { 5197 ActivityStack stack = ActivityRecord.getStackLocked(token); 5198 if (stack != null) { 5199 ActivityRecord.activityResumedLocked(token); 5200 } 5201 } 5202 Binder.restoreCallingIdentity(origId); 5203 } 5204 5205 @Override 5206 public final void activityPaused(IBinder token) { 5207 final long origId = Binder.clearCallingIdentity(); 5208 synchronized(this) { 5209 ActivityStack stack = ActivityRecord.getStackLocked(token); 5210 if (stack != null) { 5211 stack.activityPausedLocked(token, false); 5212 } 5213 } 5214 Binder.restoreCallingIdentity(origId); 5215 } 5216 5217 @Override 5218 public final void activityStopped(IBinder token, Bundle icicle, Bitmap thumbnail, 5219 CharSequence description) { 5220 if (localLOGV) Slog.v( 5221 TAG, "Activity stopped: token=" + token); 5222 5223 // Refuse possible leaked file descriptors 5224 if (icicle != null && icicle.hasFileDescriptors()) { 5225 throw new IllegalArgumentException("File descriptors passed in Bundle"); 5226 } 5227 5228 ActivityRecord r = null; 5229 5230 final long origId = Binder.clearCallingIdentity(); 5231 5232 synchronized (this) { 5233 r = ActivityRecord.isInStackLocked(token); 5234 if (r != null) { 5235 r.task.stack.activityStoppedLocked(r, icicle, thumbnail, description); 5236 } 5237 } 5238 5239 if (r != null) { 5240 sendPendingThumbnail(r, null, null, null, false); 5241 } 5242 5243 trimApplications(); 5244 5245 Binder.restoreCallingIdentity(origId); 5246 } 5247 5248 @Override 5249 public final void activityDestroyed(IBinder token) { 5250 if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token); 5251 synchronized (this) { 5252 ActivityStack stack = ActivityRecord.getStackLocked(token); 5253 if (stack != null) { 5254 stack.activityDestroyedLocked(token); 5255 } 5256 } 5257 } 5258 5259 @Override 5260 public String getCallingPackage(IBinder token) { 5261 synchronized (this) { 5262 ActivityRecord r = getCallingRecordLocked(token); 5263 return r != null ? r.info.packageName : null; 5264 } 5265 } 5266 5267 @Override 5268 public ComponentName getCallingActivity(IBinder token) { 5269 synchronized (this) { 5270 ActivityRecord r = getCallingRecordLocked(token); 5271 return r != null ? r.intent.getComponent() : null; 5272 } 5273 } 5274 5275 private ActivityRecord getCallingRecordLocked(IBinder token) { 5276 ActivityRecord r = ActivityRecord.isInStackLocked(token); 5277 if (r == null) { 5278 return null; 5279 } 5280 return r.resultTo; 5281 } 5282 5283 @Override 5284 public ComponentName getActivityClassForToken(IBinder token) { 5285 synchronized(this) { 5286 ActivityRecord r = ActivityRecord.isInStackLocked(token); 5287 if (r == null) { 5288 return null; 5289 } 5290 return r.intent.getComponent(); 5291 } 5292 } 5293 5294 @Override 5295 public String getPackageForToken(IBinder token) { 5296 synchronized(this) { 5297 ActivityRecord r = ActivityRecord.isInStackLocked(token); 5298 if (r == null) { 5299 return null; 5300 } 5301 return r.packageName; 5302 } 5303 } 5304 5305 @Override 5306 public IIntentSender getIntentSender(int type, 5307 String packageName, IBinder token, String resultWho, 5308 int requestCode, Intent[] intents, String[] resolvedTypes, 5309 int flags, Bundle options, int userId) { 5310 enforceNotIsolatedCaller("getIntentSender"); 5311 // Refuse possible leaked file descriptors 5312 if (intents != null) { 5313 if (intents.length < 1) { 5314 throw new IllegalArgumentException("Intents array length must be >= 1"); 5315 } 5316 for (int i=0; i<intents.length; i++) { 5317 Intent intent = intents[i]; 5318 if (intent != null) { 5319 if (intent.hasFileDescriptors()) { 5320 throw new IllegalArgumentException("File descriptors passed in Intent"); 5321 } 5322 if (type == ActivityManager.INTENT_SENDER_BROADCAST && 5323 (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 5324 throw new IllegalArgumentException( 5325 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 5326 } 5327 intents[i] = new Intent(intent); 5328 } 5329 } 5330 if (resolvedTypes != null && resolvedTypes.length != intents.length) { 5331 throw new IllegalArgumentException( 5332 "Intent array length does not match resolvedTypes length"); 5333 } 5334 } 5335 if (options != null) { 5336 if (options.hasFileDescriptors()) { 5337 throw new IllegalArgumentException("File descriptors passed in options"); 5338 } 5339 } 5340 5341 synchronized(this) { 5342 int callingUid = Binder.getCallingUid(); 5343 int origUserId = userId; 5344 userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId, 5345 type == ActivityManager.INTENT_SENDER_BROADCAST, false, 5346 "getIntentSender", null); 5347 if (origUserId == UserHandle.USER_CURRENT) { 5348 // We don't want to evaluate this until the pending intent is 5349 // actually executed. However, we do want to always do the 5350 // security checking for it above. 5351 userId = UserHandle.USER_CURRENT; 5352 } 5353 try { 5354 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 5355 int uid = AppGlobals.getPackageManager() 5356 .getPackageUid(packageName, UserHandle.getUserId(callingUid)); 5357 if (!UserHandle.isSameApp(callingUid, uid)) { 5358 String msg = "Permission Denial: getIntentSender() from pid=" 5359 + Binder.getCallingPid() 5360 + ", uid=" + Binder.getCallingUid() 5361 + ", (need uid=" + uid + ")" 5362 + " is not allowed to send as package " + packageName; 5363 Slog.w(TAG, msg); 5364 throw new SecurityException(msg); 5365 } 5366 } 5367 5368 return getIntentSenderLocked(type, packageName, callingUid, userId, 5369 token, resultWho, requestCode, intents, resolvedTypes, flags, options); 5370 5371 } catch (RemoteException e) { 5372 throw new SecurityException(e); 5373 } 5374 } 5375 } 5376 5377 IIntentSender getIntentSenderLocked(int type, String packageName, 5378 int callingUid, int userId, IBinder token, String resultWho, 5379 int requestCode, Intent[] intents, String[] resolvedTypes, int flags, 5380 Bundle options) { 5381 if (DEBUG_MU) 5382 Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid); 5383 ActivityRecord activity = null; 5384 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 5385 activity = ActivityRecord.isInStackLocked(token); 5386 if (activity == null) { 5387 return null; 5388 } 5389 if (activity.finishing) { 5390 return null; 5391 } 5392 } 5393 5394 final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0; 5395 final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0; 5396 final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0; 5397 flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT 5398 |PendingIntent.FLAG_UPDATE_CURRENT); 5399 5400 PendingIntentRecord.Key key = new PendingIntentRecord.Key( 5401 type, packageName, activity, resultWho, 5402 requestCode, intents, resolvedTypes, flags, options, userId); 5403 WeakReference<PendingIntentRecord> ref; 5404 ref = mIntentSenderRecords.get(key); 5405 PendingIntentRecord rec = ref != null ? ref.get() : null; 5406 if (rec != null) { 5407 if (!cancelCurrent) { 5408 if (updateCurrent) { 5409 if (rec.key.requestIntent != null) { 5410 rec.key.requestIntent.replaceExtras(intents != null ? 5411 intents[intents.length - 1] : null); 5412 } 5413 if (intents != null) { 5414 intents[intents.length-1] = rec.key.requestIntent; 5415 rec.key.allIntents = intents; 5416 rec.key.allResolvedTypes = resolvedTypes; 5417 } else { 5418 rec.key.allIntents = null; 5419 rec.key.allResolvedTypes = null; 5420 } 5421 } 5422 return rec; 5423 } 5424 rec.canceled = true; 5425 mIntentSenderRecords.remove(key); 5426 } 5427 if (noCreate) { 5428 return rec; 5429 } 5430 rec = new PendingIntentRecord(this, key, callingUid); 5431 mIntentSenderRecords.put(key, rec.ref); 5432 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 5433 if (activity.pendingResults == null) { 5434 activity.pendingResults 5435 = new HashSet<WeakReference<PendingIntentRecord>>(); 5436 } 5437 activity.pendingResults.add(rec.ref); 5438 } 5439 return rec; 5440 } 5441 5442 @Override 5443 public void cancelIntentSender(IIntentSender sender) { 5444 if (!(sender instanceof PendingIntentRecord)) { 5445 return; 5446 } 5447 synchronized(this) { 5448 PendingIntentRecord rec = (PendingIntentRecord)sender; 5449 try { 5450 int uid = AppGlobals.getPackageManager() 5451 .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId()); 5452 if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) { 5453 String msg = "Permission Denial: cancelIntentSender() from pid=" 5454 + Binder.getCallingPid() 5455 + ", uid=" + Binder.getCallingUid() 5456 + " is not allowed to cancel packges " 5457 + rec.key.packageName; 5458 Slog.w(TAG, msg); 5459 throw new SecurityException(msg); 5460 } 5461 } catch (RemoteException e) { 5462 throw new SecurityException(e); 5463 } 5464 cancelIntentSenderLocked(rec, true); 5465 } 5466 } 5467 5468 void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) { 5469 rec.canceled = true; 5470 mIntentSenderRecords.remove(rec.key); 5471 if (cleanActivity && rec.key.activity != null) { 5472 rec.key.activity.pendingResults.remove(rec.ref); 5473 } 5474 } 5475 5476 @Override 5477 public String getPackageForIntentSender(IIntentSender pendingResult) { 5478 if (!(pendingResult instanceof PendingIntentRecord)) { 5479 return null; 5480 } 5481 try { 5482 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5483 return res.key.packageName; 5484 } catch (ClassCastException e) { 5485 } 5486 return null; 5487 } 5488 5489 @Override 5490 public int getUidForIntentSender(IIntentSender sender) { 5491 if (sender instanceof PendingIntentRecord) { 5492 try { 5493 PendingIntentRecord res = (PendingIntentRecord)sender; 5494 return res.uid; 5495 } catch (ClassCastException e) { 5496 } 5497 } 5498 return -1; 5499 } 5500 5501 @Override 5502 public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) { 5503 if (!(pendingResult instanceof PendingIntentRecord)) { 5504 return false; 5505 } 5506 try { 5507 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5508 if (res.key.allIntents == null) { 5509 return false; 5510 } 5511 for (int i=0; i<res.key.allIntents.length; i++) { 5512 Intent intent = res.key.allIntents[i]; 5513 if (intent.getPackage() != null && intent.getComponent() != null) { 5514 return false; 5515 } 5516 } 5517 return true; 5518 } catch (ClassCastException e) { 5519 } 5520 return false; 5521 } 5522 5523 @Override 5524 public boolean isIntentSenderAnActivity(IIntentSender pendingResult) { 5525 if (!(pendingResult instanceof PendingIntentRecord)) { 5526 return false; 5527 } 5528 try { 5529 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5530 if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) { 5531 return true; 5532 } 5533 return false; 5534 } catch (ClassCastException e) { 5535 } 5536 return false; 5537 } 5538 5539 @Override 5540 public Intent getIntentForIntentSender(IIntentSender pendingResult) { 5541 if (!(pendingResult instanceof PendingIntentRecord)) { 5542 return null; 5543 } 5544 try { 5545 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5546 return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null; 5547 } catch (ClassCastException e) { 5548 } 5549 return null; 5550 } 5551 5552 @Override 5553 public void setProcessLimit(int max) { 5554 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 5555 "setProcessLimit()"); 5556 synchronized (this) { 5557 mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max; 5558 mProcessLimitOverride = max; 5559 } 5560 trimApplications(); 5561 } 5562 5563 @Override 5564 public int getProcessLimit() { 5565 synchronized (this) { 5566 return mProcessLimitOverride; 5567 } 5568 } 5569 5570 void foregroundTokenDied(ForegroundToken token) { 5571 synchronized (ActivityManagerService.this) { 5572 synchronized (mPidsSelfLocked) { 5573 ForegroundToken cur 5574 = mForegroundProcesses.get(token.pid); 5575 if (cur != token) { 5576 return; 5577 } 5578 mForegroundProcesses.remove(token.pid); 5579 ProcessRecord pr = mPidsSelfLocked.get(token.pid); 5580 if (pr == null) { 5581 return; 5582 } 5583 pr.forcingToForeground = null; 5584 pr.foregroundServices = false; 5585 } 5586 updateOomAdjLocked(); 5587 } 5588 } 5589 5590 @Override 5591 public void setProcessForeground(IBinder token, int pid, boolean isForeground) { 5592 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 5593 "setProcessForeground()"); 5594 synchronized(this) { 5595 boolean changed = false; 5596 5597 synchronized (mPidsSelfLocked) { 5598 ProcessRecord pr = mPidsSelfLocked.get(pid); 5599 if (pr == null && isForeground) { 5600 Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid); 5601 return; 5602 } 5603 ForegroundToken oldToken = mForegroundProcesses.get(pid); 5604 if (oldToken != null) { 5605 oldToken.token.unlinkToDeath(oldToken, 0); 5606 mForegroundProcesses.remove(pid); 5607 if (pr != null) { 5608 pr.forcingToForeground = null; 5609 } 5610 changed = true; 5611 } 5612 if (isForeground && token != null) { 5613 ForegroundToken newToken = new ForegroundToken() { 5614 @Override 5615 public void binderDied() { 5616 foregroundTokenDied(this); 5617 } 5618 }; 5619 newToken.pid = pid; 5620 newToken.token = token; 5621 try { 5622 token.linkToDeath(newToken, 0); 5623 mForegroundProcesses.put(pid, newToken); 5624 pr.forcingToForeground = token; 5625 changed = true; 5626 } catch (RemoteException e) { 5627 // If the process died while doing this, we will later 5628 // do the cleanup with the process death link. 5629 } 5630 } 5631 } 5632 5633 if (changed) { 5634 updateOomAdjLocked(); 5635 } 5636 } 5637 } 5638 5639 // ========================================================= 5640 // PERMISSIONS 5641 // ========================================================= 5642 5643 static class PermissionController extends IPermissionController.Stub { 5644 ActivityManagerService mActivityManagerService; 5645 PermissionController(ActivityManagerService activityManagerService) { 5646 mActivityManagerService = activityManagerService; 5647 } 5648 5649 @Override 5650 public boolean checkPermission(String permission, int pid, int uid) { 5651 return mActivityManagerService.checkPermission(permission, pid, 5652 uid) == PackageManager.PERMISSION_GRANTED; 5653 } 5654 } 5655 5656 class IntentFirewallInterface implements IntentFirewall.AMSInterface { 5657 @Override 5658 public int checkComponentPermission(String permission, int pid, int uid, 5659 int owningUid, boolean exported) { 5660 return ActivityManagerService.this.checkComponentPermission(permission, pid, uid, 5661 owningUid, exported); 5662 } 5663 5664 @Override 5665 public Object getAMSLock() { 5666 return ActivityManagerService.this; 5667 } 5668 } 5669 5670 /** 5671 * This can be called with or without the global lock held. 5672 */ 5673 int checkComponentPermission(String permission, int pid, int uid, 5674 int owningUid, boolean exported) { 5675 // We might be performing an operation on behalf of an indirect binder 5676 // invocation, e.g. via {@link #openContentUri}. Check and adjust the 5677 // client identity accordingly before proceeding. 5678 Identity tlsIdentity = sCallerIdentity.get(); 5679 if (tlsIdentity != null) { 5680 Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {" 5681 + tlsIdentity.pid + "," + tlsIdentity.uid + "}"); 5682 uid = tlsIdentity.uid; 5683 pid = tlsIdentity.pid; 5684 } 5685 5686 if (pid == MY_PID) { 5687 return PackageManager.PERMISSION_GRANTED; 5688 } 5689 5690 return ActivityManager.checkComponentPermission(permission, uid, 5691 owningUid, exported); 5692 } 5693 5694 /** 5695 * As the only public entry point for permissions checking, this method 5696 * can enforce the semantic that requesting a check on a null global 5697 * permission is automatically denied. (Internally a null permission 5698 * string is used when calling {@link #checkComponentPermission} in cases 5699 * when only uid-based security is needed.) 5700 * 5701 * This can be called with or without the global lock held. 5702 */ 5703 @Override 5704 public int checkPermission(String permission, int pid, int uid) { 5705 if (permission == null) { 5706 return PackageManager.PERMISSION_DENIED; 5707 } 5708 return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true); 5709 } 5710 5711 /** 5712 * Binder IPC calls go through the public entry point. 5713 * This can be called with or without the global lock held. 5714 */ 5715 int checkCallingPermission(String permission) { 5716 return checkPermission(permission, 5717 Binder.getCallingPid(), 5718 UserHandle.getAppId(Binder.getCallingUid())); 5719 } 5720 5721 /** 5722 * This can be called with or without the global lock held. 5723 */ 5724 void enforceCallingPermission(String permission, String func) { 5725 if (checkCallingPermission(permission) 5726 == PackageManager.PERMISSION_GRANTED) { 5727 return; 5728 } 5729 5730 String msg = "Permission Denial: " + func + " from pid=" 5731 + Binder.getCallingPid() 5732 + ", uid=" + Binder.getCallingUid() 5733 + " requires " + permission; 5734 Slog.w(TAG, msg); 5735 throw new SecurityException(msg); 5736 } 5737 5738 /** 5739 * Determine if UID is holding permissions required to access {@link Uri} in 5740 * the given {@link ProviderInfo}. Final permission checking is always done 5741 * in {@link ContentProvider}. 5742 */ 5743 private final boolean checkHoldingPermissionsLocked( 5744 IPackageManager pm, ProviderInfo pi, Uri uri, int uid, int modeFlags) { 5745 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5746 "checkHoldingPermissionsLocked: uri=" + uri + " uid=" + uid); 5747 5748 if (pi.applicationInfo.uid == uid) { 5749 return true; 5750 } else if (!pi.exported) { 5751 return false; 5752 } 5753 5754 boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0; 5755 boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0; 5756 try { 5757 // check if target holds top-level <provider> permissions 5758 if (!readMet && pi.readPermission != null 5759 && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) { 5760 readMet = true; 5761 } 5762 if (!writeMet && pi.writePermission != null 5763 && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) { 5764 writeMet = true; 5765 } 5766 5767 // track if unprotected read/write is allowed; any denied 5768 // <path-permission> below removes this ability 5769 boolean allowDefaultRead = pi.readPermission == null; 5770 boolean allowDefaultWrite = pi.writePermission == null; 5771 5772 // check if target holds any <path-permission> that match uri 5773 final PathPermission[] pps = pi.pathPermissions; 5774 if (pps != null) { 5775 final String path = uri.getPath(); 5776 int i = pps.length; 5777 while (i > 0 && (!readMet || !writeMet)) { 5778 i--; 5779 PathPermission pp = pps[i]; 5780 if (pp.match(path)) { 5781 if (!readMet) { 5782 final String pprperm = pp.getReadPermission(); 5783 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for " 5784 + pprperm + " for " + pp.getPath() 5785 + ": match=" + pp.match(path) 5786 + " check=" + pm.checkUidPermission(pprperm, uid)); 5787 if (pprperm != null) { 5788 if (pm.checkUidPermission(pprperm, uid) == PERMISSION_GRANTED) { 5789 readMet = true; 5790 } else { 5791 allowDefaultRead = false; 5792 } 5793 } 5794 } 5795 if (!writeMet) { 5796 final String ppwperm = pp.getWritePermission(); 5797 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm " 5798 + ppwperm + " for " + pp.getPath() 5799 + ": match=" + pp.match(path) 5800 + " check=" + pm.checkUidPermission(ppwperm, uid)); 5801 if (ppwperm != null) { 5802 if (pm.checkUidPermission(ppwperm, uid) == PERMISSION_GRANTED) { 5803 writeMet = true; 5804 } else { 5805 allowDefaultWrite = false; 5806 } 5807 } 5808 } 5809 } 5810 } 5811 } 5812 5813 // grant unprotected <provider> read/write, if not blocked by 5814 // <path-permission> above 5815 if (allowDefaultRead) readMet = true; 5816 if (allowDefaultWrite) writeMet = true; 5817 5818 } catch (RemoteException e) { 5819 return false; 5820 } 5821 5822 return readMet && writeMet; 5823 } 5824 5825 private ProviderInfo getProviderInfoLocked(String authority, int userHandle) { 5826 ProviderInfo pi = null; 5827 ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle); 5828 if (cpr != null) { 5829 pi = cpr.info; 5830 } else { 5831 try { 5832 pi = AppGlobals.getPackageManager().resolveContentProvider( 5833 authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle); 5834 } catch (RemoteException ex) { 5835 } 5836 } 5837 return pi; 5838 } 5839 5840 private UriPermission findUriPermissionLocked(int targetUid, Uri uri) { 5841 ArrayMap<Uri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid); 5842 if (targetUris != null) { 5843 return targetUris.get(uri); 5844 } else { 5845 return null; 5846 } 5847 } 5848 5849 private UriPermission findOrCreateUriPermissionLocked( 5850 String sourcePkg, String targetPkg, int targetUid, Uri uri) { 5851 ArrayMap<Uri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid); 5852 if (targetUris == null) { 5853 targetUris = Maps.newArrayMap(); 5854 mGrantedUriPermissions.put(targetUid, targetUris); 5855 } 5856 5857 UriPermission perm = targetUris.get(uri); 5858 if (perm == null) { 5859 perm = new UriPermission(sourcePkg, targetPkg, targetUid, uri); 5860 targetUris.put(uri, perm); 5861 } 5862 5863 return perm; 5864 } 5865 5866 private final boolean checkUriPermissionLocked( 5867 Uri uri, int uid, int modeFlags, int minStrength) { 5868 // Root gets to do everything. 5869 if (uid == 0) { 5870 return true; 5871 } 5872 ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(uid); 5873 if (perms == null) return false; 5874 UriPermission perm = perms.get(uri); 5875 if (perm == null) return false; 5876 return perm.getStrength(modeFlags) >= minStrength; 5877 } 5878 5879 @Override 5880 public int checkUriPermission(Uri uri, int pid, int uid, int modeFlags) { 5881 enforceNotIsolatedCaller("checkUriPermission"); 5882 5883 // Another redirected-binder-call permissions check as in 5884 // {@link checkComponentPermission}. 5885 Identity tlsIdentity = sCallerIdentity.get(); 5886 if (tlsIdentity != null) { 5887 uid = tlsIdentity.uid; 5888 pid = tlsIdentity.pid; 5889 } 5890 5891 // Our own process gets to do everything. 5892 if (pid == MY_PID) { 5893 return PackageManager.PERMISSION_GRANTED; 5894 } 5895 synchronized(this) { 5896 return checkUriPermissionLocked(uri, uid, modeFlags, UriPermission.STRENGTH_OWNED) 5897 ? PackageManager.PERMISSION_GRANTED 5898 : PackageManager.PERMISSION_DENIED; 5899 } 5900 } 5901 5902 /** 5903 * Check if the targetPkg can be granted permission to access uri by 5904 * the callingUid using the given modeFlags. Throws a security exception 5905 * if callingUid is not allowed to do this. Returns the uid of the target 5906 * if the URI permission grant should be performed; returns -1 if it is not 5907 * needed (for example targetPkg already has permission to access the URI). 5908 * If you already know the uid of the target, you can supply it in 5909 * lastTargetUid else set that to -1. 5910 */ 5911 int checkGrantUriPermissionLocked(int callingUid, String targetPkg, 5912 Uri uri, int modeFlags, int lastTargetUid) { 5913 final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0; 5914 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION 5915 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 5916 if (modeFlags == 0) { 5917 return -1; 5918 } 5919 5920 if (targetPkg != null) { 5921 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5922 "Checking grant " + targetPkg + " permission to " + uri); 5923 } 5924 5925 final IPackageManager pm = AppGlobals.getPackageManager(); 5926 5927 // If this is not a content: uri, we can't do anything with it. 5928 if (!ContentResolver.SCHEME_CONTENT.equals(uri.getScheme())) { 5929 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5930 "Can't grant URI permission for non-content URI: " + uri); 5931 return -1; 5932 } 5933 5934 final String authority = uri.getAuthority(); 5935 final ProviderInfo pi = getProviderInfoLocked(authority, UserHandle.getUserId(callingUid)); 5936 if (pi == null) { 5937 Slog.w(TAG, "No content provider found for permission check: " + uri.toSafeString()); 5938 return -1; 5939 } 5940 5941 int targetUid = lastTargetUid; 5942 if (targetUid < 0 && targetPkg != null) { 5943 try { 5944 targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid)); 5945 if (targetUid < 0) { 5946 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5947 "Can't grant URI permission no uid for: " + targetPkg); 5948 return -1; 5949 } 5950 } catch (RemoteException ex) { 5951 return -1; 5952 } 5953 } 5954 5955 if (targetUid >= 0) { 5956 // First... does the target actually need this permission? 5957 if (checkHoldingPermissionsLocked(pm, pi, uri, targetUid, modeFlags)) { 5958 // No need to grant the target this permission. 5959 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5960 "Target " + targetPkg + " already has full permission to " + uri); 5961 return -1; 5962 } 5963 } else { 5964 // First... there is no target package, so can anyone access it? 5965 boolean allowed = pi.exported; 5966 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) { 5967 if (pi.readPermission != null) { 5968 allowed = false; 5969 } 5970 } 5971 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) { 5972 if (pi.writePermission != null) { 5973 allowed = false; 5974 } 5975 } 5976 if (allowed) { 5977 return -1; 5978 } 5979 } 5980 5981 // Second... is the provider allowing granting of URI permissions? 5982 if (!pi.grantUriPermissions) { 5983 throw new SecurityException("Provider " + pi.packageName 5984 + "/" + pi.name 5985 + " does not allow granting of Uri permissions (uri " 5986 + uri + ")"); 5987 } 5988 if (pi.uriPermissionPatterns != null) { 5989 final int N = pi.uriPermissionPatterns.length; 5990 boolean allowed = false; 5991 for (int i=0; i<N; i++) { 5992 if (pi.uriPermissionPatterns[i] != null 5993 && pi.uriPermissionPatterns[i].match(uri.getPath())) { 5994 allowed = true; 5995 break; 5996 } 5997 } 5998 if (!allowed) { 5999 throw new SecurityException("Provider " + pi.packageName 6000 + "/" + pi.name 6001 + " does not allow granting of permission to path of Uri " 6002 + uri); 6003 } 6004 } 6005 6006 // Third... does the caller itself have permission to access 6007 // this uri? 6008 if (callingUid != Process.myUid()) { 6009 if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) { 6010 // Require they hold a strong enough Uri permission 6011 final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE 6012 : UriPermission.STRENGTH_OWNED; 6013 if (!checkUriPermissionLocked(uri, callingUid, modeFlags, minStrength)) { 6014 throw new SecurityException("Uid " + callingUid 6015 + " does not have permission to uri " + uri); 6016 } 6017 } 6018 } 6019 6020 return targetUid; 6021 } 6022 6023 @Override 6024 public int checkGrantUriPermission(int callingUid, String targetPkg, 6025 Uri uri, int modeFlags) { 6026 enforceNotIsolatedCaller("checkGrantUriPermission"); 6027 synchronized(this) { 6028 return checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1); 6029 } 6030 } 6031 6032 void grantUriPermissionUncheckedLocked( 6033 int targetUid, String targetPkg, Uri uri, int modeFlags, UriPermissionOwner owner) { 6034 final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0; 6035 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION 6036 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 6037 if (modeFlags == 0) { 6038 return; 6039 } 6040 6041 // So here we are: the caller has the assumed permission 6042 // to the uri, and the target doesn't. Let's now give this to 6043 // the target. 6044 6045 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6046 "Granting " + targetPkg + "/" + targetUid + " permission to " + uri); 6047 6048 final String authority = uri.getAuthority(); 6049 final ProviderInfo pi = getProviderInfoLocked(authority, UserHandle.getUserId(targetUid)); 6050 if (pi == null) { 6051 Slog.w(TAG, "No content provider found for grant: " + uri.toSafeString()); 6052 return; 6053 } 6054 6055 final UriPermission perm = findOrCreateUriPermissionLocked( 6056 pi.packageName, targetPkg, targetUid, uri); 6057 perm.grantModes(modeFlags, persistable, owner); 6058 } 6059 6060 void grantUriPermissionLocked(int callingUid, String targetPkg, Uri uri, 6061 int modeFlags, UriPermissionOwner owner) { 6062 if (targetPkg == null) { 6063 throw new NullPointerException("targetPkg"); 6064 } 6065 6066 int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1); 6067 if (targetUid < 0) { 6068 return; 6069 } 6070 6071 grantUriPermissionUncheckedLocked(targetUid, targetPkg, uri, modeFlags, owner); 6072 } 6073 6074 static class NeededUriGrants extends ArrayList<Uri> { 6075 final String targetPkg; 6076 final int targetUid; 6077 final int flags; 6078 6079 NeededUriGrants(String targetPkg, int targetUid, int flags) { 6080 this.targetPkg = targetPkg; 6081 this.targetUid = targetUid; 6082 this.flags = flags; 6083 } 6084 } 6085 6086 /** 6087 * Like checkGrantUriPermissionLocked, but takes an Intent. 6088 */ 6089 NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid, 6090 String targetPkg, Intent intent, int mode, NeededUriGrants needed) { 6091 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6092 "Checking URI perm to data=" + (intent != null ? intent.getData() : null) 6093 + " clip=" + (intent != null ? intent.getClipData() : null) 6094 + " from " + intent + "; flags=0x" 6095 + Integer.toHexString(intent != null ? intent.getFlags() : 0)); 6096 6097 if (targetPkg == null) { 6098 throw new NullPointerException("targetPkg"); 6099 } 6100 6101 if (intent == null) { 6102 return null; 6103 } 6104 Uri data = intent.getData(); 6105 ClipData clip = intent.getClipData(); 6106 if (data == null && clip == null) { 6107 return null; 6108 } 6109 6110 if (data != null) { 6111 int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, data, 6112 mode, needed != null ? needed.targetUid : -1); 6113 if (targetUid > 0) { 6114 if (needed == null) { 6115 needed = new NeededUriGrants(targetPkg, targetUid, mode); 6116 } 6117 needed.add(data); 6118 } 6119 } 6120 if (clip != null) { 6121 for (int i=0; i<clip.getItemCount(); i++) { 6122 Uri uri = clip.getItemAt(i).getUri(); 6123 if (uri != null) { 6124 int targetUid = -1; 6125 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri, 6126 mode, needed != null ? needed.targetUid : -1); 6127 if (targetUid > 0) { 6128 if (needed == null) { 6129 needed = new NeededUriGrants(targetPkg, targetUid, mode); 6130 } 6131 needed.add(uri); 6132 } 6133 } else { 6134 Intent clipIntent = clip.getItemAt(i).getIntent(); 6135 if (clipIntent != null) { 6136 NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked( 6137 callingUid, targetPkg, clipIntent, mode, needed); 6138 if (newNeeded != null) { 6139 needed = newNeeded; 6140 } 6141 } 6142 } 6143 } 6144 } 6145 6146 return needed; 6147 } 6148 6149 /** 6150 * Like grantUriPermissionUncheckedLocked, but takes an Intent. 6151 */ 6152 void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed, 6153 UriPermissionOwner owner) { 6154 if (needed != null) { 6155 for (int i=0; i<needed.size(); i++) { 6156 grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg, 6157 needed.get(i), needed.flags, owner); 6158 } 6159 } 6160 } 6161 6162 void grantUriPermissionFromIntentLocked(int callingUid, 6163 String targetPkg, Intent intent, UriPermissionOwner owner) { 6164 NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg, 6165 intent, intent != null ? intent.getFlags() : 0, null); 6166 if (needed == null) { 6167 return; 6168 } 6169 6170 grantUriPermissionUncheckedFromIntentLocked(needed, owner); 6171 } 6172 6173 @Override 6174 public void grantUriPermission(IApplicationThread caller, String targetPkg, 6175 Uri uri, int modeFlags) { 6176 enforceNotIsolatedCaller("grantUriPermission"); 6177 synchronized(this) { 6178 final ProcessRecord r = getRecordForAppLocked(caller); 6179 if (r == null) { 6180 throw new SecurityException("Unable to find app for caller " 6181 + caller 6182 + " when granting permission to uri " + uri); 6183 } 6184 if (targetPkg == null) { 6185 throw new IllegalArgumentException("null target"); 6186 } 6187 if (uri == null) { 6188 throw new IllegalArgumentException("null uri"); 6189 } 6190 6191 // Persistable only supported through Intents 6192 Preconditions.checkFlagsArgument(modeFlags, 6193 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 6194 6195 grantUriPermissionLocked(r.uid, targetPkg, uri, modeFlags, 6196 null); 6197 } 6198 } 6199 6200 void removeUriPermissionIfNeededLocked(UriPermission perm) { 6201 if ((perm.modeFlags&(Intent.FLAG_GRANT_READ_URI_PERMISSION 6202 |Intent.FLAG_GRANT_WRITE_URI_PERMISSION)) == 0) { 6203 ArrayMap<Uri, UriPermission> perms 6204 = mGrantedUriPermissions.get(perm.targetUid); 6205 if (perms != null) { 6206 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6207 "Removing " + perm.targetUid + " permission to " + perm.uri); 6208 perms.remove(perm.uri); 6209 if (perms.size() == 0) { 6210 mGrantedUriPermissions.remove(perm.targetUid); 6211 } 6212 } 6213 } 6214 } 6215 6216 private void revokeUriPermissionLocked(int callingUid, Uri uri, int modeFlags) { 6217 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + uri); 6218 6219 final IPackageManager pm = AppGlobals.getPackageManager(); 6220 final String authority = uri.getAuthority(); 6221 final ProviderInfo pi = getProviderInfoLocked(authority, UserHandle.getUserId(callingUid)); 6222 if (pi == null) { 6223 Slog.w(TAG, "No content provider found for permission revoke: " + uri.toSafeString()); 6224 return; 6225 } 6226 6227 // Does the caller have this permission on the URI? 6228 if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) { 6229 // Right now, if you are not the original owner of the permission, 6230 // you are not allowed to revoke it. 6231 //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) { 6232 throw new SecurityException("Uid " + callingUid 6233 + " does not have permission to uri " + uri); 6234 //} 6235 } 6236 6237 boolean persistChanged = false; 6238 6239 // Go through all of the permissions and remove any that match. 6240 final List<String> SEGMENTS = uri.getPathSegments(); 6241 if (SEGMENTS != null) { 6242 final int NS = SEGMENTS.size(); 6243 int N = mGrantedUriPermissions.size(); 6244 for (int i=0; i<N; i++) { 6245 ArrayMap<Uri, UriPermission> perms 6246 = mGrantedUriPermissions.valueAt(i); 6247 Iterator<UriPermission> it = perms.values().iterator(); 6248 toploop: 6249 while (it.hasNext()) { 6250 UriPermission perm = it.next(); 6251 Uri targetUri = perm.uri; 6252 if (!authority.equals(targetUri.getAuthority())) { 6253 continue; 6254 } 6255 List<String> targetSegments = targetUri.getPathSegments(); 6256 if (targetSegments == null) { 6257 continue; 6258 } 6259 if (targetSegments.size() < NS) { 6260 continue; 6261 } 6262 for (int j=0; j<NS; j++) { 6263 if (!SEGMENTS.get(j).equals(targetSegments.get(j))) { 6264 continue toploop; 6265 } 6266 } 6267 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6268 "Revoking " + perm.targetUid + " permission to " + perm.uri); 6269 persistChanged |= perm.clearModes(modeFlags, true); 6270 if (perm.modeFlags == 0) { 6271 it.remove(); 6272 } 6273 } 6274 if (perms.size() == 0) { 6275 mGrantedUriPermissions.remove( 6276 mGrantedUriPermissions.keyAt(i)); 6277 N--; 6278 i--; 6279 } 6280 } 6281 } 6282 6283 if (persistChanged) { 6284 schedulePersistUriGrants(); 6285 } 6286 } 6287 6288 @Override 6289 public void revokeUriPermission(IApplicationThread caller, Uri uri, 6290 int modeFlags) { 6291 enforceNotIsolatedCaller("revokeUriPermission"); 6292 synchronized(this) { 6293 final ProcessRecord r = getRecordForAppLocked(caller); 6294 if (r == null) { 6295 throw new SecurityException("Unable to find app for caller " 6296 + caller 6297 + " when revoking permission to uri " + uri); 6298 } 6299 if (uri == null) { 6300 Slog.w(TAG, "revokeUriPermission: null uri"); 6301 return; 6302 } 6303 6304 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION 6305 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 6306 if (modeFlags == 0) { 6307 return; 6308 } 6309 6310 final IPackageManager pm = AppGlobals.getPackageManager(); 6311 final String authority = uri.getAuthority(); 6312 final ProviderInfo pi = getProviderInfoLocked(authority, r.userId); 6313 if (pi == null) { 6314 Slog.w(TAG, "No content provider found for permission revoke: " 6315 + uri.toSafeString()); 6316 return; 6317 } 6318 6319 revokeUriPermissionLocked(r.uid, uri, modeFlags); 6320 } 6321 } 6322 6323 /** 6324 * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the 6325 * given package. 6326 * 6327 * @param packageName Package name to match, or {@code null} to apply to all 6328 * packages. 6329 * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply 6330 * to all users. 6331 * @param persistable If persistable grants should be removed. 6332 */ 6333 private void removeUriPermissionsForPackageLocked( 6334 String packageName, int userHandle, boolean persistable) { 6335 if (userHandle == UserHandle.USER_ALL && packageName == null) { 6336 throw new IllegalArgumentException("Must narrow by either package or user"); 6337 } 6338 6339 boolean persistChanged = false; 6340 6341 final int size = mGrantedUriPermissions.size(); 6342 for (int i = 0; i < size; i++) { 6343 // Only inspect grants matching user 6344 if (userHandle == UserHandle.USER_ALL 6345 || userHandle == UserHandle.getUserId(mGrantedUriPermissions.keyAt(i))) { 6346 final Iterator<UriPermission> it = mGrantedUriPermissions.valueAt(i) 6347 .values().iterator(); 6348 while (it.hasNext()) { 6349 final UriPermission perm = it.next(); 6350 6351 // Only inspect grants matching package 6352 if (packageName == null || perm.sourcePkg.equals(packageName) 6353 || perm.targetPkg.equals(packageName)) { 6354 persistChanged |= perm.clearModes(~0, persistable); 6355 6356 // Only remove when no modes remain; any persisted grants 6357 // will keep this alive. 6358 if (perm.modeFlags == 0) { 6359 it.remove(); 6360 } 6361 } 6362 } 6363 } 6364 } 6365 6366 if (persistChanged) { 6367 schedulePersistUriGrants(); 6368 } 6369 } 6370 6371 @Override 6372 public IBinder newUriPermissionOwner(String name) { 6373 enforceNotIsolatedCaller("newUriPermissionOwner"); 6374 synchronized(this) { 6375 UriPermissionOwner owner = new UriPermissionOwner(this, name); 6376 return owner.getExternalTokenLocked(); 6377 } 6378 } 6379 6380 @Override 6381 public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, 6382 Uri uri, int modeFlags) { 6383 synchronized(this) { 6384 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 6385 if (owner == null) { 6386 throw new IllegalArgumentException("Unknown owner: " + token); 6387 } 6388 if (fromUid != Binder.getCallingUid()) { 6389 if (Binder.getCallingUid() != Process.myUid()) { 6390 // Only system code can grant URI permissions on behalf 6391 // of other users. 6392 throw new SecurityException("nice try"); 6393 } 6394 } 6395 if (targetPkg == null) { 6396 throw new IllegalArgumentException("null target"); 6397 } 6398 if (uri == null) { 6399 throw new IllegalArgumentException("null uri"); 6400 } 6401 6402 grantUriPermissionLocked(fromUid, targetPkg, uri, modeFlags, owner); 6403 } 6404 } 6405 6406 @Override 6407 public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode) { 6408 synchronized(this) { 6409 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 6410 if (owner == null) { 6411 throw new IllegalArgumentException("Unknown owner: " + token); 6412 } 6413 6414 if (uri == null) { 6415 owner.removeUriPermissionsLocked(mode); 6416 } else { 6417 owner.removeUriPermissionLocked(uri, mode); 6418 } 6419 } 6420 } 6421 6422 private void schedulePersistUriGrants() { 6423 if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) { 6424 mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG), 6425 10 * DateUtils.SECOND_IN_MILLIS); 6426 } 6427 } 6428 6429 private void writeGrantedUriPermissions() { 6430 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()"); 6431 6432 // Snapshot permissions so we can persist without lock 6433 ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList(); 6434 synchronized (this) { 6435 final int size = mGrantedUriPermissions.size(); 6436 for (int i = 0 ; i < size; i++) { 6437 for (UriPermission perm : mGrantedUriPermissions.valueAt(i).values()) { 6438 if (perm.persistedModeFlags != 0) { 6439 persist.add(perm.snapshot()); 6440 } 6441 } 6442 } 6443 } 6444 6445 FileOutputStream fos = null; 6446 try { 6447 fos = mGrantFile.startWrite(); 6448 6449 XmlSerializer out = new FastXmlSerializer(); 6450 out.setOutput(fos, "utf-8"); 6451 out.startDocument(null, true); 6452 out.startTag(null, TAG_URI_GRANTS); 6453 for (UriPermission.Snapshot perm : persist) { 6454 out.startTag(null, TAG_URI_GRANT); 6455 writeIntAttribute(out, ATTR_USER_HANDLE, perm.userHandle); 6456 out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg); 6457 out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg); 6458 out.attribute(null, ATTR_URI, String.valueOf(perm.uri)); 6459 writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags); 6460 writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime); 6461 out.endTag(null, TAG_URI_GRANT); 6462 } 6463 out.endTag(null, TAG_URI_GRANTS); 6464 out.endDocument(); 6465 6466 mGrantFile.finishWrite(fos); 6467 } catch (IOException e) { 6468 if (fos != null) { 6469 mGrantFile.failWrite(fos); 6470 } 6471 } 6472 } 6473 6474 private void readGrantedUriPermissionsLocked() { 6475 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()"); 6476 6477 final long now = System.currentTimeMillis(); 6478 6479 FileInputStream fis = null; 6480 try { 6481 fis = mGrantFile.openRead(); 6482 final XmlPullParser in = Xml.newPullParser(); 6483 in.setInput(fis, null); 6484 6485 int type; 6486 while ((type = in.next()) != END_DOCUMENT) { 6487 final String tag = in.getName(); 6488 if (type == START_TAG) { 6489 if (TAG_URI_GRANT.equals(tag)) { 6490 final int userHandle = readIntAttribute(in, ATTR_USER_HANDLE); 6491 final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG); 6492 final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG); 6493 final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI)); 6494 final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS); 6495 final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now); 6496 6497 // Sanity check that provider still belongs to source package 6498 final ProviderInfo pi = getProviderInfoLocked( 6499 uri.getAuthority(), userHandle); 6500 if (pi != null && sourcePkg.equals(pi.packageName)) { 6501 int targetUid = -1; 6502 try { 6503 targetUid = AppGlobals.getPackageManager() 6504 .getPackageUid(targetPkg, userHandle); 6505 } catch (RemoteException e) { 6506 } 6507 if (targetUid != -1) { 6508 final UriPermission perm = findOrCreateUriPermissionLocked( 6509 sourcePkg, targetPkg, targetUid, uri); 6510 perm.initPersistedModes(modeFlags, createdTime); 6511 } 6512 } else { 6513 Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg 6514 + " but instead found " + pi); 6515 } 6516 } 6517 } 6518 } 6519 } catch (FileNotFoundException e) { 6520 // Missing grants is okay 6521 } catch (IOException e) { 6522 Log.wtf(TAG, "Failed reading Uri grants", e); 6523 } catch (XmlPullParserException e) { 6524 Log.wtf(TAG, "Failed reading Uri grants", e); 6525 } finally { 6526 IoUtils.closeQuietly(fis); 6527 } 6528 } 6529 6530 @Override 6531 public void takePersistableUriPermission(Uri uri, int modeFlags) { 6532 enforceNotIsolatedCaller("takePersistableUriPermission"); 6533 6534 Preconditions.checkFlagsArgument(modeFlags, 6535 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 6536 6537 synchronized (this) { 6538 final int callingUid = Binder.getCallingUid(); 6539 final UriPermission perm = findUriPermissionLocked(callingUid, uri); 6540 if (perm == null) { 6541 throw new SecurityException("No permission grant found for UID " + callingUid 6542 + " and Uri " + uri.toSafeString()); 6543 } 6544 6545 boolean persistChanged = perm.takePersistableModes(modeFlags); 6546 persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid); 6547 6548 if (persistChanged) { 6549 schedulePersistUriGrants(); 6550 } 6551 } 6552 } 6553 6554 @Override 6555 public void releasePersistableUriPermission(Uri uri, int modeFlags) { 6556 enforceNotIsolatedCaller("releasePersistableUriPermission"); 6557 6558 Preconditions.checkFlagsArgument(modeFlags, 6559 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 6560 6561 synchronized (this) { 6562 final int callingUid = Binder.getCallingUid(); 6563 6564 final UriPermission perm = findUriPermissionLocked(callingUid, uri); 6565 if (perm == null) { 6566 Slog.w(TAG, "No permission grant found for UID " + callingUid + " and Uri " 6567 + uri.toSafeString()); 6568 return; 6569 } 6570 6571 final boolean persistChanged = perm.releasePersistableModes(modeFlags); 6572 removeUriPermissionIfNeededLocked(perm); 6573 if (persistChanged) { 6574 schedulePersistUriGrants(); 6575 } 6576 } 6577 } 6578 6579 /** 6580 * Prune any older {@link UriPermission} for the given UID until outstanding 6581 * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}. 6582 * 6583 * @return if any mutations occured that require persisting. 6584 */ 6585 private boolean maybePrunePersistedUriGrantsLocked(int uid) { 6586 final ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(uid); 6587 if (perms == null) return false; 6588 if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false; 6589 6590 final ArrayList<UriPermission> persisted = Lists.newArrayList(); 6591 for (UriPermission perm : perms.values()) { 6592 if (perm.persistedModeFlags != 0) { 6593 persisted.add(perm); 6594 } 6595 } 6596 6597 final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS; 6598 if (trimCount <= 0) return false; 6599 6600 Collections.sort(persisted, new UriPermission.PersistedTimeComparator()); 6601 for (int i = 0; i < trimCount; i++) { 6602 final UriPermission perm = persisted.get(i); 6603 6604 if (DEBUG_URI_PERMISSION) { 6605 Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime); 6606 } 6607 6608 perm.releasePersistableModes(~0); 6609 removeUriPermissionIfNeededLocked(perm); 6610 } 6611 6612 return true; 6613 } 6614 6615 @Override 6616 public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions( 6617 String packageName, boolean incoming) { 6618 enforceNotIsolatedCaller("getPersistedUriPermissions"); 6619 Preconditions.checkNotNull(packageName, "packageName"); 6620 6621 final int callingUid = Binder.getCallingUid(); 6622 final IPackageManager pm = AppGlobals.getPackageManager(); 6623 try { 6624 final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid)); 6625 if (packageUid != callingUid) { 6626 throw new SecurityException( 6627 "Package " + packageName + " does not belong to calling UID " + callingUid); 6628 } 6629 } catch (RemoteException e) { 6630 throw new SecurityException("Failed to verify package name ownership"); 6631 } 6632 6633 final ArrayList<android.content.UriPermission> result = Lists.newArrayList(); 6634 synchronized (this) { 6635 if (incoming) { 6636 final ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(callingUid); 6637 if (perms == null) { 6638 Slog.w(TAG, "No permission grants found for " + packageName); 6639 } else { 6640 final int size = perms.size(); 6641 for (int i = 0; i < size; i++) { 6642 final UriPermission perm = perms.valueAt(i); 6643 if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) { 6644 result.add(perm.buildPersistedPublicApiObject()); 6645 } 6646 } 6647 } 6648 } else { 6649 final int size = mGrantedUriPermissions.size(); 6650 for (int i = 0; i < size; i++) { 6651 final ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 6652 final int permsSize = perms.size(); 6653 for (int j = 0; j < permsSize; j++) { 6654 final UriPermission perm = perms.valueAt(j); 6655 if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) { 6656 result.add(perm.buildPersistedPublicApiObject()); 6657 } 6658 } 6659 } 6660 } 6661 } 6662 return new ParceledListSlice<android.content.UriPermission>(result); 6663 } 6664 6665 @Override 6666 public void showWaitingForDebugger(IApplicationThread who, boolean waiting) { 6667 synchronized (this) { 6668 ProcessRecord app = 6669 who != null ? getRecordForAppLocked(who) : null; 6670 if (app == null) return; 6671 6672 Message msg = Message.obtain(); 6673 msg.what = WAIT_FOR_DEBUGGER_MSG; 6674 msg.obj = app; 6675 msg.arg1 = waiting ? 1 : 0; 6676 mHandler.sendMessage(msg); 6677 } 6678 } 6679 6680 @Override 6681 public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) { 6682 final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ); 6683 final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ); 6684 outInfo.availMem = Process.getFreeMemory(); 6685 outInfo.totalMem = Process.getTotalMemory(); 6686 outInfo.threshold = homeAppMem; 6687 outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2)); 6688 outInfo.hiddenAppThreshold = cachedAppMem; 6689 outInfo.secondaryServerThreshold = mProcessList.getMemLevel( 6690 ProcessList.SERVICE_ADJ); 6691 outInfo.visibleAppThreshold = mProcessList.getMemLevel( 6692 ProcessList.VISIBLE_APP_ADJ); 6693 outInfo.foregroundAppThreshold = mProcessList.getMemLevel( 6694 ProcessList.FOREGROUND_APP_ADJ); 6695 } 6696 6697 // ========================================================= 6698 // TASK MANAGEMENT 6699 // ========================================================= 6700 6701 @Override 6702 public List<RunningTaskInfo> getTasks(int maxNum, int flags, 6703 IThumbnailReceiver receiver) { 6704 ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>(); 6705 6706 PendingThumbnailsRecord pending = new PendingThumbnailsRecord(receiver); 6707 ActivityRecord topRecord = null; 6708 6709 synchronized(this) { 6710 if (localLOGV) Slog.v( 6711 TAG, "getTasks: max=" + maxNum + ", flags=" + flags 6712 + ", receiver=" + receiver); 6713 6714 if (checkCallingPermission(android.Manifest.permission.GET_TASKS) 6715 != PackageManager.PERMISSION_GRANTED) { 6716 if (receiver != null) { 6717 // If the caller wants to wait for pending thumbnails, 6718 // it ain't gonna get them. 6719 try { 6720 receiver.finished(); 6721 } catch (RemoteException ex) { 6722 } 6723 } 6724 String msg = "Permission Denial: getTasks() from pid=" 6725 + Binder.getCallingPid() 6726 + ", uid=" + Binder.getCallingUid() 6727 + " requires " + android.Manifest.permission.GET_TASKS; 6728 Slog.w(TAG, msg); 6729 throw new SecurityException(msg); 6730 } 6731 6732 // TODO: Improve with MRU list from all ActivityStacks. 6733 topRecord = mStackSupervisor.getTasksLocked(maxNum, receiver, pending, list); 6734 6735 if (!pending.pendingRecords.isEmpty()) { 6736 mPendingThumbnails.add(pending); 6737 } 6738 } 6739 6740 if (localLOGV) Slog.v(TAG, "We have pending thumbnails: " + pending); 6741 6742 if (topRecord != null) { 6743 if (localLOGV) Slog.v(TAG, "Requesting top thumbnail"); 6744 try { 6745 IApplicationThread topThumbnail = topRecord.app.thread; 6746 topThumbnail.requestThumbnail(topRecord.appToken); 6747 } catch (Exception e) { 6748 Slog.w(TAG, "Exception thrown when requesting thumbnail", e); 6749 sendPendingThumbnail(null, topRecord.appToken, null, null, true); 6750 } 6751 } 6752 6753 if (pending == null && receiver != null) { 6754 // In this case all thumbnails were available and the client 6755 // is being asked to be told when the remaining ones come in... 6756 // which is unusually, since the top-most currently running 6757 // activity should never have a canned thumbnail! Oh well. 6758 try { 6759 receiver.finished(); 6760 } catch (RemoteException ex) { 6761 } 6762 } 6763 6764 return list; 6765 } 6766 6767 TaskRecord getMostRecentTask() { 6768 return mRecentTasks.get(0); 6769 } 6770 6771 @Override 6772 public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, 6773 int flags, int userId) { 6774 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 6775 false, true, "getRecentTasks", null); 6776 6777 synchronized (this) { 6778 enforceCallingPermission(android.Manifest.permission.GET_TASKS, 6779 "getRecentTasks()"); 6780 final boolean detailed = checkCallingPermission( 6781 android.Manifest.permission.GET_DETAILED_TASKS) 6782 == PackageManager.PERMISSION_GRANTED; 6783 6784 IPackageManager pm = AppGlobals.getPackageManager(); 6785 6786 final int N = mRecentTasks.size(); 6787 ArrayList<ActivityManager.RecentTaskInfo> res 6788 = new ArrayList<ActivityManager.RecentTaskInfo>( 6789 maxNum < N ? maxNum : N); 6790 for (int i=0; i<N && maxNum > 0; i++) { 6791 TaskRecord tr = mRecentTasks.get(i); 6792 // Only add calling user's recent tasks 6793 if (tr.userId != userId) continue; 6794 // Return the entry if desired by the caller. We always return 6795 // the first entry, because callers always expect this to be the 6796 // foreground app. We may filter others if the caller has 6797 // not supplied RECENT_WITH_EXCLUDED and there is some reason 6798 // we should exclude the entry. 6799 6800 if (i == 0 6801 || ((flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0) 6802 || (tr.intent == null) 6803 || ((tr.intent.getFlags() 6804 &Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0)) { 6805 ActivityManager.RecentTaskInfo rti 6806 = new ActivityManager.RecentTaskInfo(); 6807 rti.id = tr.numActivities > 0 ? tr.taskId : -1; 6808 rti.persistentId = tr.taskId; 6809 rti.baseIntent = new Intent( 6810 tr.intent != null ? tr.intent : tr.affinityIntent); 6811 if (!detailed) { 6812 rti.baseIntent.replaceExtras((Bundle)null); 6813 } 6814 rti.origActivity = tr.origActivity; 6815 rti.description = tr.lastDescription; 6816 rti.stackId = tr.stack.mStackId; 6817 6818 if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) { 6819 // Check whether this activity is currently available. 6820 try { 6821 if (rti.origActivity != null) { 6822 if (pm.getActivityInfo(rti.origActivity, 0, userId) 6823 == null) { 6824 continue; 6825 } 6826 } else if (rti.baseIntent != null) { 6827 if (pm.queryIntentActivities(rti.baseIntent, 6828 null, 0, userId) == null) { 6829 continue; 6830 } 6831 } 6832 } catch (RemoteException e) { 6833 // Will never happen. 6834 } 6835 } 6836 6837 res.add(rti); 6838 maxNum--; 6839 } 6840 } 6841 return res; 6842 } 6843 } 6844 6845 private TaskRecord recentTaskForIdLocked(int id) { 6846 final int N = mRecentTasks.size(); 6847 for (int i=0; i<N; i++) { 6848 TaskRecord tr = mRecentTasks.get(i); 6849 if (tr.taskId == id) { 6850 return tr; 6851 } 6852 } 6853 return null; 6854 } 6855 6856 @Override 6857 public ActivityManager.TaskThumbnails getTaskThumbnails(int id) { 6858 synchronized (this) { 6859 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER, 6860 "getTaskThumbnails()"); 6861 TaskRecord tr = recentTaskForIdLocked(id); 6862 if (tr != null) { 6863 return tr.getTaskThumbnailsLocked(); 6864 } 6865 } 6866 return null; 6867 } 6868 6869 @Override 6870 public Bitmap getTaskTopThumbnail(int id) { 6871 synchronized (this) { 6872 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER, 6873 "getTaskTopThumbnail()"); 6874 TaskRecord tr = recentTaskForIdLocked(id); 6875 if (tr != null) { 6876 return tr.getTaskTopThumbnailLocked(); 6877 } 6878 } 6879 return null; 6880 } 6881 6882 @Override 6883 public boolean removeSubTask(int taskId, int subTaskIndex) { 6884 synchronized (this) { 6885 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, 6886 "removeSubTask()"); 6887 long ident = Binder.clearCallingIdentity(); 6888 try { 6889 TaskRecord tr = recentTaskForIdLocked(taskId); 6890 if (tr != null) { 6891 return tr.removeTaskActivitiesLocked(subTaskIndex, true) != null; 6892 } 6893 return false; 6894 } finally { 6895 Binder.restoreCallingIdentity(ident); 6896 } 6897 } 6898 } 6899 6900 private void killUnneededProcessLocked(ProcessRecord pr, String reason) { 6901 if (!pr.killedByAm) { 6902 Slog.i(TAG, "Killing " + pr.toShortString() + " (adj " + pr.setAdj + "): " + reason); 6903 EventLog.writeEvent(EventLogTags.AM_KILL, pr.userId, pr.pid, 6904 pr.processName, pr.setAdj, reason); 6905 pr.killedByAm = true; 6906 Process.killProcessQuiet(pr.pid); 6907 } 6908 } 6909 6910 private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) { 6911 tr.disposeThumbnail(); 6912 mRecentTasks.remove(tr); 6913 final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0; 6914 Intent baseIntent = new Intent( 6915 tr.intent != null ? tr.intent : tr.affinityIntent); 6916 ComponentName component = baseIntent.getComponent(); 6917 if (component == null) { 6918 Slog.w(TAG, "Now component for base intent of task: " + tr); 6919 return; 6920 } 6921 6922 // Find any running services associated with this app. 6923 mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent); 6924 6925 if (killProcesses) { 6926 // Find any running processes associated with this app. 6927 final String pkg = component.getPackageName(); 6928 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 6929 ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap(); 6930 for (int i=0; i<pmap.size(); i++) { 6931 SparseArray<ProcessRecord> uids = pmap.valueAt(i); 6932 for (int j=0; j<uids.size(); j++) { 6933 ProcessRecord proc = uids.valueAt(j); 6934 if (proc.userId != tr.userId) { 6935 continue; 6936 } 6937 if (!proc.pkgList.containsKey(pkg)) { 6938 continue; 6939 } 6940 procs.add(proc); 6941 } 6942 } 6943 6944 // Kill the running processes. 6945 for (int i=0; i<procs.size(); i++) { 6946 ProcessRecord pr = procs.get(i); 6947 if (pr == mHomeProcess) { 6948 // Don't kill the home process along with tasks from the same package. 6949 continue; 6950 } 6951 if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 6952 killUnneededProcessLocked(pr, "remove task"); 6953 } else { 6954 pr.waitingToKill = "remove task"; 6955 } 6956 } 6957 } 6958 } 6959 6960 @Override 6961 public boolean removeTask(int taskId, int flags) { 6962 synchronized (this) { 6963 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, 6964 "removeTask()"); 6965 long ident = Binder.clearCallingIdentity(); 6966 try { 6967 TaskRecord tr = recentTaskForIdLocked(taskId); 6968 if (tr != null) { 6969 ActivityRecord r = tr.removeTaskActivitiesLocked(-1, false); 6970 if (r != null) { 6971 cleanUpRemovedTaskLocked(tr, flags); 6972 return true; 6973 } 6974 if (tr.mActivities.size() == 0) { 6975 // Caller is just removing a recent task that is 6976 // not actively running. That is easy! 6977 cleanUpRemovedTaskLocked(tr, flags); 6978 return true; 6979 } 6980 Slog.w(TAG, "removeTask: task " + taskId 6981 + " does not have activities to remove, " 6982 + " but numActivities=" + tr.numActivities 6983 + ": " + tr); 6984 } 6985 } finally { 6986 Binder.restoreCallingIdentity(ident); 6987 } 6988 } 6989 return false; 6990 } 6991 6992 /** 6993 * TODO: Add mController hook 6994 */ 6995 @Override 6996 public void moveTaskToFront(int task, int flags, Bundle options) { 6997 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 6998 "moveTaskToFront()"); 6999 7000 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving task=" + task); 7001 synchronized(this) { 7002 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 7003 Binder.getCallingUid(), "Task to front")) { 7004 ActivityOptions.abort(options); 7005 return; 7006 } 7007 final long origId = Binder.clearCallingIdentity(); 7008 try { 7009 mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options); 7010 } finally { 7011 Binder.restoreCallingIdentity(origId); 7012 } 7013 ActivityOptions.abort(options); 7014 } 7015 } 7016 7017 @Override 7018 public void moveTaskToBack(int taskId) { 7019 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 7020 "moveTaskToBack()"); 7021 7022 synchronized(this) { 7023 TaskRecord tr = recentTaskForIdLocked(taskId); 7024 if (tr != null) { 7025 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr); 7026 ActivityStack stack = tr.stack; 7027 if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) { 7028 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 7029 Binder.getCallingUid(), "Task to back")) { 7030 return; 7031 } 7032 } 7033 final long origId = Binder.clearCallingIdentity(); 7034 try { 7035 stack.moveTaskToBackLocked(taskId, null); 7036 } finally { 7037 Binder.restoreCallingIdentity(origId); 7038 } 7039 } 7040 } 7041 } 7042 7043 /** 7044 * Moves an activity, and all of the other activities within the same task, to the bottom 7045 * of the history stack. The activity's order within the task is unchanged. 7046 * 7047 * @param token A reference to the activity we wish to move 7048 * @param nonRoot If false then this only works if the activity is the root 7049 * of a task; if true it will work for any activity in a task. 7050 * @return Returns true if the move completed, false if not. 7051 */ 7052 @Override 7053 public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) { 7054 enforceNotIsolatedCaller("moveActivityTaskToBack"); 7055 synchronized(this) { 7056 final long origId = Binder.clearCallingIdentity(); 7057 int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot); 7058 if (taskId >= 0) { 7059 return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null); 7060 } 7061 Binder.restoreCallingIdentity(origId); 7062 } 7063 return false; 7064 } 7065 7066 @Override 7067 public void moveTaskBackwards(int task) { 7068 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 7069 "moveTaskBackwards()"); 7070 7071 synchronized(this) { 7072 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 7073 Binder.getCallingUid(), "Task backwards")) { 7074 return; 7075 } 7076 final long origId = Binder.clearCallingIdentity(); 7077 moveTaskBackwardsLocked(task); 7078 Binder.restoreCallingIdentity(origId); 7079 } 7080 } 7081 7082 private final void moveTaskBackwardsLocked(int task) { 7083 Slog.e(TAG, "moveTaskBackwards not yet implemented!"); 7084 } 7085 7086 @Override 7087 public IBinder getHomeActivityToken() throws RemoteException { 7088 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7089 "getHomeActivityToken()"); 7090 synchronized (this) { 7091 return mStackSupervisor.getHomeActivityToken(); 7092 } 7093 } 7094 7095 @Override 7096 public IActivityContainer createActivityContainer(IBinder parentActivityToken, 7097 IActivityContainerCallback callback) throws RemoteException { 7098 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7099 "createActivityContainer()"); 7100 synchronized (this) { 7101 if (parentActivityToken == null) { 7102 throw new IllegalArgumentException("parent token must not be null"); 7103 } 7104 ActivityRecord r = ActivityRecord.forToken(parentActivityToken); 7105 if (r == null) { 7106 return null; 7107 } 7108 return mStackSupervisor.createActivityContainer(r, callback); 7109 } 7110 } 7111 7112 @Override 7113 public void deleteActivityContainer(IActivityContainer container) throws RemoteException { 7114 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7115 "deleteActivityContainer()"); 7116 synchronized (this) { 7117 mStackSupervisor.deleteActivityContainer(container); 7118 } 7119 } 7120 7121 @Override 7122 public IActivityContainer getEnclosingActivityContainer(IBinder activityToken) 7123 throws RemoteException { 7124 synchronized (this) { 7125 ActivityStack stack = ActivityRecord.getStackLocked(activityToken); 7126 if (stack != null) { 7127 return stack.mActivityContainer; 7128 } 7129 return null; 7130 } 7131 } 7132 7133 @Override 7134 public void moveTaskToStack(int taskId, int stackId, boolean toTop) { 7135 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7136 "moveTaskToStack()"); 7137 if (stackId == HOME_STACK_ID) { 7138 Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack", 7139 new RuntimeException("here").fillInStackTrace()); 7140 } 7141 synchronized (this) { 7142 long ident = Binder.clearCallingIdentity(); 7143 try { 7144 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId=" 7145 + stackId + " toTop=" + toTop); 7146 mStackSupervisor.moveTaskToStack(taskId, stackId, toTop); 7147 } finally { 7148 Binder.restoreCallingIdentity(ident); 7149 } 7150 } 7151 } 7152 7153 @Override 7154 public void resizeStack(int stackBoxId, Rect bounds) { 7155 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7156 "resizeStackBox()"); 7157 long ident = Binder.clearCallingIdentity(); 7158 try { 7159 mWindowManager.resizeStack(stackBoxId, bounds); 7160 } finally { 7161 Binder.restoreCallingIdentity(ident); 7162 } 7163 } 7164 7165 @Override 7166 public List<StackInfo> getAllStackInfos() { 7167 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7168 "getAllStackInfos()"); 7169 long ident = Binder.clearCallingIdentity(); 7170 try { 7171 synchronized (this) { 7172 return mStackSupervisor.getAllStackInfosLocked(); 7173 } 7174 } finally { 7175 Binder.restoreCallingIdentity(ident); 7176 } 7177 } 7178 7179 @Override 7180 public StackInfo getStackInfo(int stackId) { 7181 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7182 "getStackInfo()"); 7183 long ident = Binder.clearCallingIdentity(); 7184 try { 7185 synchronized (this) { 7186 return mStackSupervisor.getStackInfoLocked(stackId); 7187 } 7188 } finally { 7189 Binder.restoreCallingIdentity(ident); 7190 } 7191 } 7192 7193 @Override 7194 public int getTaskForActivity(IBinder token, boolean onlyRoot) { 7195 synchronized(this) { 7196 return ActivityRecord.getTaskForActivityLocked(token, onlyRoot); 7197 } 7198 } 7199 7200 // ========================================================= 7201 // THUMBNAILS 7202 // ========================================================= 7203 7204 public void reportThumbnail(IBinder token, 7205 Bitmap thumbnail, CharSequence description) { 7206 //System.out.println("Report thumbnail for " + token + ": " + thumbnail); 7207 final long origId = Binder.clearCallingIdentity(); 7208 sendPendingThumbnail(null, token, thumbnail, description, true); 7209 Binder.restoreCallingIdentity(origId); 7210 } 7211 7212 final void sendPendingThumbnail(ActivityRecord r, IBinder token, 7213 Bitmap thumbnail, CharSequence description, boolean always) { 7214 TaskRecord task; 7215 ArrayList<PendingThumbnailsRecord> receivers = null; 7216 7217 //System.out.println("Send pending thumbnail: " + r); 7218 7219 synchronized(this) { 7220 if (r == null) { 7221 r = ActivityRecord.isInStackLocked(token); 7222 if (r == null) { 7223 return; 7224 } 7225 } 7226 if (thumbnail == null && r.thumbHolder != null) { 7227 thumbnail = r.thumbHolder.lastThumbnail; 7228 description = r.thumbHolder.lastDescription; 7229 } 7230 if (thumbnail == null && !always) { 7231 // If there is no thumbnail, and this entry is not actually 7232 // going away, then abort for now and pick up the next 7233 // thumbnail we get. 7234 return; 7235 } 7236 task = r.task; 7237 7238 int N = mPendingThumbnails.size(); 7239 int i=0; 7240 while (i<N) { 7241 PendingThumbnailsRecord pr = mPendingThumbnails.get(i); 7242 //System.out.println("Looking in " + pr.pendingRecords); 7243 if (pr.pendingRecords.remove(r)) { 7244 if (receivers == null) { 7245 receivers = new ArrayList<PendingThumbnailsRecord>(); 7246 } 7247 receivers.add(pr); 7248 if (pr.pendingRecords.size() == 0) { 7249 pr.finished = true; 7250 mPendingThumbnails.remove(i); 7251 N--; 7252 continue; 7253 } 7254 } 7255 i++; 7256 } 7257 } 7258 7259 if (receivers != null) { 7260 final int N = receivers.size(); 7261 for (int i=0; i<N; i++) { 7262 try { 7263 PendingThumbnailsRecord pr = receivers.get(i); 7264 pr.receiver.newThumbnail( 7265 task != null ? task.taskId : -1, thumbnail, description); 7266 if (pr.finished) { 7267 pr.receiver.finished(); 7268 } 7269 } catch (Exception e) { 7270 Slog.w(TAG, "Exception thrown when sending thumbnail", e); 7271 } 7272 } 7273 } 7274 } 7275 7276 // ========================================================= 7277 // CONTENT PROVIDERS 7278 // ========================================================= 7279 7280 private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) { 7281 List<ProviderInfo> providers = null; 7282 try { 7283 providers = AppGlobals.getPackageManager(). 7284 queryContentProviders(app.processName, app.uid, 7285 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS); 7286 } catch (RemoteException ex) { 7287 } 7288 if (DEBUG_MU) 7289 Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid); 7290 int userId = app.userId; 7291 if (providers != null) { 7292 int N = providers.size(); 7293 app.pubProviders.ensureCapacity(N + app.pubProviders.size()); 7294 for (int i=0; i<N; i++) { 7295 ProviderInfo cpi = 7296 (ProviderInfo)providers.get(i); 7297 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo, 7298 cpi.name, cpi.flags); 7299 if (singleton && UserHandle.getUserId(app.uid) != 0) { 7300 // This is a singleton provider, but a user besides the 7301 // default user is asking to initialize a process it runs 7302 // in... well, no, it doesn't actually run in this process, 7303 // it runs in the process of the default user. Get rid of it. 7304 providers.remove(i); 7305 N--; 7306 i--; 7307 continue; 7308 } 7309 7310 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 7311 ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId); 7312 if (cpr == null) { 7313 cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton); 7314 mProviderMap.putProviderByClass(comp, cpr); 7315 } 7316 if (DEBUG_MU) 7317 Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid); 7318 app.pubProviders.put(cpi.name, cpr); 7319 if (!cpi.multiprocess || !"android".equals(cpi.packageName)) { 7320 // Don't add this if it is a platform component that is marked 7321 // to run in multiple processes, because this is actually 7322 // part of the framework so doesn't make sense to track as a 7323 // separate apk in the process. 7324 app.addPackage(cpi.applicationInfo.packageName, mProcessStats); 7325 } 7326 ensurePackageDexOpt(cpi.applicationInfo.packageName); 7327 } 7328 } 7329 return providers; 7330 } 7331 7332 /** 7333 * Check if {@link ProcessRecord} has a possible chance at accessing the 7334 * given {@link ProviderInfo}. Final permission checking is always done 7335 * in {@link ContentProvider}. 7336 */ 7337 private final String checkContentProviderPermissionLocked( 7338 ProviderInfo cpi, ProcessRecord r) { 7339 final int callingPid = (r != null) ? r.pid : Binder.getCallingPid(); 7340 final int callingUid = (r != null) ? r.uid : Binder.getCallingUid(); 7341 if (checkComponentPermission(cpi.readPermission, callingPid, callingUid, 7342 cpi.applicationInfo.uid, cpi.exported) 7343 == PackageManager.PERMISSION_GRANTED) { 7344 return null; 7345 } 7346 if (checkComponentPermission(cpi.writePermission, callingPid, callingUid, 7347 cpi.applicationInfo.uid, cpi.exported) 7348 == PackageManager.PERMISSION_GRANTED) { 7349 return null; 7350 } 7351 7352 PathPermission[] pps = cpi.pathPermissions; 7353 if (pps != null) { 7354 int i = pps.length; 7355 while (i > 0) { 7356 i--; 7357 PathPermission pp = pps[i]; 7358 if (checkComponentPermission(pp.getReadPermission(), callingPid, callingUid, 7359 cpi.applicationInfo.uid, cpi.exported) 7360 == PackageManager.PERMISSION_GRANTED) { 7361 return null; 7362 } 7363 if (checkComponentPermission(pp.getWritePermission(), callingPid, callingUid, 7364 cpi.applicationInfo.uid, cpi.exported) 7365 == PackageManager.PERMISSION_GRANTED) { 7366 return null; 7367 } 7368 } 7369 } 7370 7371 ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(callingUid); 7372 if (perms != null) { 7373 for (Map.Entry<Uri, UriPermission> uri : perms.entrySet()) { 7374 if (uri.getKey().getAuthority().equals(cpi.authority)) { 7375 return null; 7376 } 7377 } 7378 } 7379 7380 String msg; 7381 if (!cpi.exported) { 7382 msg = "Permission Denial: opening provider " + cpi.name 7383 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 7384 + ", uid=" + callingUid + ") that is not exported from uid " 7385 + cpi.applicationInfo.uid; 7386 } else { 7387 msg = "Permission Denial: opening provider " + cpi.name 7388 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 7389 + ", uid=" + callingUid + ") requires " 7390 + cpi.readPermission + " or " + cpi.writePermission; 7391 } 7392 Slog.w(TAG, msg); 7393 return msg; 7394 } 7395 7396 ContentProviderConnection incProviderCountLocked(ProcessRecord r, 7397 final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 7398 if (r != null) { 7399 for (int i=0; i<r.conProviders.size(); i++) { 7400 ContentProviderConnection conn = r.conProviders.get(i); 7401 if (conn.provider == cpr) { 7402 if (DEBUG_PROVIDER) Slog.v(TAG, 7403 "Adding provider requested by " 7404 + r.processName + " from process " 7405 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 7406 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 7407 if (stable) { 7408 conn.stableCount++; 7409 conn.numStableIncs++; 7410 } else { 7411 conn.unstableCount++; 7412 conn.numUnstableIncs++; 7413 } 7414 return conn; 7415 } 7416 } 7417 ContentProviderConnection conn = new ContentProviderConnection(cpr, r); 7418 if (stable) { 7419 conn.stableCount = 1; 7420 conn.numStableIncs = 1; 7421 } else { 7422 conn.unstableCount = 1; 7423 conn.numUnstableIncs = 1; 7424 } 7425 cpr.connections.add(conn); 7426 r.conProviders.add(conn); 7427 return conn; 7428 } 7429 cpr.addExternalProcessHandleLocked(externalProcessToken); 7430 return null; 7431 } 7432 7433 boolean decProviderCountLocked(ContentProviderConnection conn, 7434 ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 7435 if (conn != null) { 7436 cpr = conn.provider; 7437 if (DEBUG_PROVIDER) Slog.v(TAG, 7438 "Removing provider requested by " 7439 + conn.client.processName + " from process " 7440 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 7441 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 7442 if (stable) { 7443 conn.stableCount--; 7444 } else { 7445 conn.unstableCount--; 7446 } 7447 if (conn.stableCount == 0 && conn.unstableCount == 0) { 7448 cpr.connections.remove(conn); 7449 conn.client.conProviders.remove(conn); 7450 return true; 7451 } 7452 return false; 7453 } 7454 cpr.removeExternalProcessHandleLocked(externalProcessToken); 7455 return false; 7456 } 7457 7458 private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller, 7459 String name, IBinder token, boolean stable, int userId) { 7460 ContentProviderRecord cpr; 7461 ContentProviderConnection conn = null; 7462 ProviderInfo cpi = null; 7463 7464 synchronized(this) { 7465 ProcessRecord r = null; 7466 if (caller != null) { 7467 r = getRecordForAppLocked(caller); 7468 if (r == null) { 7469 throw new SecurityException( 7470 "Unable to find app for caller " + caller 7471 + " (pid=" + Binder.getCallingPid() 7472 + ") when getting content provider " + name); 7473 } 7474 } 7475 7476 // First check if this content provider has been published... 7477 cpr = mProviderMap.getProviderByName(name, userId); 7478 boolean providerRunning = cpr != null; 7479 if (providerRunning) { 7480 cpi = cpr.info; 7481 String msg; 7482 if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) { 7483 throw new SecurityException(msg); 7484 } 7485 7486 if (r != null && cpr.canRunHere(r)) { 7487 // This provider has been published or is in the process 7488 // of being published... but it is also allowed to run 7489 // in the caller's process, so don't make a connection 7490 // and just let the caller instantiate its own instance. 7491 ContentProviderHolder holder = cpr.newHolder(null); 7492 // don't give caller the provider object, it needs 7493 // to make its own. 7494 holder.provider = null; 7495 return holder; 7496 } 7497 7498 final long origId = Binder.clearCallingIdentity(); 7499 7500 // In this case the provider instance already exists, so we can 7501 // return it right away. 7502 conn = incProviderCountLocked(r, cpr, token, stable); 7503 if (conn != null && (conn.stableCount+conn.unstableCount) == 1) { 7504 if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 7505 // If this is a perceptible app accessing the provider, 7506 // make sure to count it as being accessed and thus 7507 // back up on the LRU list. This is good because 7508 // content providers are often expensive to start. 7509 updateLruProcessLocked(cpr.proc, false, null); 7510 } 7511 } 7512 7513 if (cpr.proc != null) { 7514 if (false) { 7515 if (cpr.name.flattenToShortString().equals( 7516 "com.android.providers.calendar/.CalendarProvider2")) { 7517 Slog.v(TAG, "****************** KILLING " 7518 + cpr.name.flattenToShortString()); 7519 Process.killProcess(cpr.proc.pid); 7520 } 7521 } 7522 boolean success = updateOomAdjLocked(cpr.proc); 7523 if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success); 7524 // NOTE: there is still a race here where a signal could be 7525 // pending on the process even though we managed to update its 7526 // adj level. Not sure what to do about this, but at least 7527 // the race is now smaller. 7528 if (!success) { 7529 // Uh oh... it looks like the provider's process 7530 // has been killed on us. We need to wait for a new 7531 // process to be started, and make sure its death 7532 // doesn't kill our process. 7533 Slog.i(TAG, 7534 "Existing provider " + cpr.name.flattenToShortString() 7535 + " is crashing; detaching " + r); 7536 boolean lastRef = decProviderCountLocked(conn, cpr, token, stable); 7537 appDiedLocked(cpr.proc, cpr.proc.pid, cpr.proc.thread); 7538 if (!lastRef) { 7539 // This wasn't the last ref our process had on 7540 // the provider... we have now been killed, bail. 7541 return null; 7542 } 7543 providerRunning = false; 7544 conn = null; 7545 } 7546 } 7547 7548 Binder.restoreCallingIdentity(origId); 7549 } 7550 7551 boolean singleton; 7552 if (!providerRunning) { 7553 try { 7554 cpi = AppGlobals.getPackageManager(). 7555 resolveContentProvider(name, 7556 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId); 7557 } catch (RemoteException ex) { 7558 } 7559 if (cpi == null) { 7560 return null; 7561 } 7562 singleton = isSingleton(cpi.processName, cpi.applicationInfo, 7563 cpi.name, cpi.flags); 7564 if (singleton) { 7565 userId = 0; 7566 } 7567 cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId); 7568 7569 String msg; 7570 if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) { 7571 throw new SecurityException(msg); 7572 } 7573 7574 if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate 7575 && !cpi.processName.equals("system")) { 7576 // If this content provider does not run in the system 7577 // process, and the system is not yet ready to run other 7578 // processes, then fail fast instead of hanging. 7579 throw new IllegalArgumentException( 7580 "Attempt to launch content provider before system ready"); 7581 } 7582 7583 // Make sure that the user who owns this provider is started. If not, 7584 // we don't want to allow it to run. 7585 if (mStartedUsers.get(userId) == null) { 7586 Slog.w(TAG, "Unable to launch app " 7587 + cpi.applicationInfo.packageName + "/" 7588 + cpi.applicationInfo.uid + " for provider " 7589 + name + ": user " + userId + " is stopped"); 7590 return null; 7591 } 7592 7593 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 7594 cpr = mProviderMap.getProviderByClass(comp, userId); 7595 final boolean firstClass = cpr == null; 7596 if (firstClass) { 7597 try { 7598 ApplicationInfo ai = 7599 AppGlobals.getPackageManager(). 7600 getApplicationInfo( 7601 cpi.applicationInfo.packageName, 7602 STOCK_PM_FLAGS, userId); 7603 if (ai == null) { 7604 Slog.w(TAG, "No package info for content provider " 7605 + cpi.name); 7606 return null; 7607 } 7608 ai = getAppInfoForUser(ai, userId); 7609 cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton); 7610 } catch (RemoteException ex) { 7611 // pm is in same process, this will never happen. 7612 } 7613 } 7614 7615 if (r != null && cpr.canRunHere(r)) { 7616 // If this is a multiprocess provider, then just return its 7617 // info and allow the caller to instantiate it. Only do 7618 // this if the provider is the same user as the caller's 7619 // process, or can run as root (so can be in any process). 7620 return cpr.newHolder(null); 7621 } 7622 7623 if (DEBUG_PROVIDER) { 7624 RuntimeException e = new RuntimeException("here"); 7625 Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null) 7626 + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e); 7627 } 7628 7629 // This is single process, and our app is now connecting to it. 7630 // See if we are already in the process of launching this 7631 // provider. 7632 final int N = mLaunchingProviders.size(); 7633 int i; 7634 for (i=0; i<N; i++) { 7635 if (mLaunchingProviders.get(i) == cpr) { 7636 break; 7637 } 7638 } 7639 7640 // If the provider is not already being launched, then get it 7641 // started. 7642 if (i >= N) { 7643 final long origId = Binder.clearCallingIdentity(); 7644 7645 try { 7646 // Content provider is now in use, its package can't be stopped. 7647 try { 7648 AppGlobals.getPackageManager().setPackageStoppedState( 7649 cpr.appInfo.packageName, false, userId); 7650 } catch (RemoteException e) { 7651 } catch (IllegalArgumentException e) { 7652 Slog.w(TAG, "Failed trying to unstop package " 7653 + cpr.appInfo.packageName + ": " + e); 7654 } 7655 7656 // Use existing process if already started 7657 ProcessRecord proc = getProcessRecordLocked( 7658 cpi.processName, cpr.appInfo.uid, false); 7659 if (proc != null && proc.thread != null) { 7660 if (DEBUG_PROVIDER) { 7661 Slog.d(TAG, "Installing in existing process " + proc); 7662 } 7663 proc.pubProviders.put(cpi.name, cpr); 7664 try { 7665 proc.thread.scheduleInstallProvider(cpi); 7666 } catch (RemoteException e) { 7667 } 7668 } else { 7669 proc = startProcessLocked(cpi.processName, 7670 cpr.appInfo, false, 0, "content provider", 7671 new ComponentName(cpi.applicationInfo.packageName, 7672 cpi.name), false, false, false); 7673 if (proc == null) { 7674 Slog.w(TAG, "Unable to launch app " 7675 + cpi.applicationInfo.packageName + "/" 7676 + cpi.applicationInfo.uid + " for provider " 7677 + name + ": process is bad"); 7678 return null; 7679 } 7680 } 7681 cpr.launchingApp = proc; 7682 mLaunchingProviders.add(cpr); 7683 } finally { 7684 Binder.restoreCallingIdentity(origId); 7685 } 7686 } 7687 7688 // Make sure the provider is published (the same provider class 7689 // may be published under multiple names). 7690 if (firstClass) { 7691 mProviderMap.putProviderByClass(comp, cpr); 7692 } 7693 7694 mProviderMap.putProviderByName(name, cpr); 7695 conn = incProviderCountLocked(r, cpr, token, stable); 7696 if (conn != null) { 7697 conn.waiting = true; 7698 } 7699 } 7700 } 7701 7702 // Wait for the provider to be published... 7703 synchronized (cpr) { 7704 while (cpr.provider == null) { 7705 if (cpr.launchingApp == null) { 7706 Slog.w(TAG, "Unable to launch app " 7707 + cpi.applicationInfo.packageName + "/" 7708 + cpi.applicationInfo.uid + " for provider " 7709 + name + ": launching app became null"); 7710 EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS, 7711 UserHandle.getUserId(cpi.applicationInfo.uid), 7712 cpi.applicationInfo.packageName, 7713 cpi.applicationInfo.uid, name); 7714 return null; 7715 } 7716 try { 7717 if (DEBUG_MU) { 7718 Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp=" 7719 + cpr.launchingApp); 7720 } 7721 if (conn != null) { 7722 conn.waiting = true; 7723 } 7724 cpr.wait(); 7725 } catch (InterruptedException ex) { 7726 } finally { 7727 if (conn != null) { 7728 conn.waiting = false; 7729 } 7730 } 7731 } 7732 } 7733 return cpr != null ? cpr.newHolder(conn) : null; 7734 } 7735 7736 public final ContentProviderHolder getContentProvider( 7737 IApplicationThread caller, String name, int userId, boolean stable) { 7738 enforceNotIsolatedCaller("getContentProvider"); 7739 if (caller == null) { 7740 String msg = "null IApplicationThread when getting content provider " 7741 + name; 7742 Slog.w(TAG, msg); 7743 throw new SecurityException(msg); 7744 } 7745 7746 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 7747 false, true, "getContentProvider", null); 7748 return getContentProviderImpl(caller, name, null, stable, userId); 7749 } 7750 7751 public ContentProviderHolder getContentProviderExternal( 7752 String name, int userId, IBinder token) { 7753 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 7754 "Do not have permission in call getContentProviderExternal()"); 7755 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 7756 false, true, "getContentProvider", null); 7757 return getContentProviderExternalUnchecked(name, token, userId); 7758 } 7759 7760 private ContentProviderHolder getContentProviderExternalUnchecked(String name, 7761 IBinder token, int userId) { 7762 return getContentProviderImpl(null, name, token, true, userId); 7763 } 7764 7765 /** 7766 * Drop a content provider from a ProcessRecord's bookkeeping 7767 */ 7768 public void removeContentProvider(IBinder connection, boolean stable) { 7769 enforceNotIsolatedCaller("removeContentProvider"); 7770 synchronized (this) { 7771 ContentProviderConnection conn; 7772 try { 7773 conn = (ContentProviderConnection)connection; 7774 } catch (ClassCastException e) { 7775 String msg ="removeContentProvider: " + connection 7776 + " not a ContentProviderConnection"; 7777 Slog.w(TAG, msg); 7778 throw new IllegalArgumentException(msg); 7779 } 7780 if (conn == null) { 7781 throw new NullPointerException("connection is null"); 7782 } 7783 if (decProviderCountLocked(conn, null, null, stable)) { 7784 updateOomAdjLocked(); 7785 } 7786 } 7787 } 7788 7789 public void removeContentProviderExternal(String name, IBinder token) { 7790 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 7791 "Do not have permission in call removeContentProviderExternal()"); 7792 removeContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId()); 7793 } 7794 7795 private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) { 7796 synchronized (this) { 7797 ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId); 7798 if(cpr == null) { 7799 //remove from mProvidersByClass 7800 if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list"); 7801 return; 7802 } 7803 7804 //update content provider record entry info 7805 ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name); 7806 ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId); 7807 if (localCpr.hasExternalProcessHandles()) { 7808 if (localCpr.removeExternalProcessHandleLocked(token)) { 7809 updateOomAdjLocked(); 7810 } else { 7811 Slog.e(TAG, "Attmpt to remove content provider " + localCpr 7812 + " with no external reference for token: " 7813 + token + "."); 7814 } 7815 } else { 7816 Slog.e(TAG, "Attmpt to remove content provider: " + localCpr 7817 + " with no external references."); 7818 } 7819 } 7820 } 7821 7822 public final void publishContentProviders(IApplicationThread caller, 7823 List<ContentProviderHolder> providers) { 7824 if (providers == null) { 7825 return; 7826 } 7827 7828 enforceNotIsolatedCaller("publishContentProviders"); 7829 synchronized (this) { 7830 final ProcessRecord r = getRecordForAppLocked(caller); 7831 if (DEBUG_MU) 7832 Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid); 7833 if (r == null) { 7834 throw new SecurityException( 7835 "Unable to find app for caller " + caller 7836 + " (pid=" + Binder.getCallingPid() 7837 + ") when publishing content providers"); 7838 } 7839 7840 final long origId = Binder.clearCallingIdentity(); 7841 7842 final int N = providers.size(); 7843 for (int i=0; i<N; i++) { 7844 ContentProviderHolder src = providers.get(i); 7845 if (src == null || src.info == null || src.provider == null) { 7846 continue; 7847 } 7848 ContentProviderRecord dst = r.pubProviders.get(src.info.name); 7849 if (DEBUG_MU) 7850 Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid); 7851 if (dst != null) { 7852 ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name); 7853 mProviderMap.putProviderByClass(comp, dst); 7854 String names[] = dst.info.authority.split(";"); 7855 for (int j = 0; j < names.length; j++) { 7856 mProviderMap.putProviderByName(names[j], dst); 7857 } 7858 7859 int NL = mLaunchingProviders.size(); 7860 int j; 7861 for (j=0; j<NL; j++) { 7862 if (mLaunchingProviders.get(j) == dst) { 7863 mLaunchingProviders.remove(j); 7864 j--; 7865 NL--; 7866 } 7867 } 7868 synchronized (dst) { 7869 dst.provider = src.provider; 7870 dst.proc = r; 7871 dst.notifyAll(); 7872 } 7873 updateOomAdjLocked(r); 7874 } 7875 } 7876 7877 Binder.restoreCallingIdentity(origId); 7878 } 7879 } 7880 7881 public boolean refContentProvider(IBinder connection, int stable, int unstable) { 7882 ContentProviderConnection conn; 7883 try { 7884 conn = (ContentProviderConnection)connection; 7885 } catch (ClassCastException e) { 7886 String msg ="refContentProvider: " + connection 7887 + " not a ContentProviderConnection"; 7888 Slog.w(TAG, msg); 7889 throw new IllegalArgumentException(msg); 7890 } 7891 if (conn == null) { 7892 throw new NullPointerException("connection is null"); 7893 } 7894 7895 synchronized (this) { 7896 if (stable > 0) { 7897 conn.numStableIncs += stable; 7898 } 7899 stable = conn.stableCount + stable; 7900 if (stable < 0) { 7901 throw new IllegalStateException("stableCount < 0: " + stable); 7902 } 7903 7904 if (unstable > 0) { 7905 conn.numUnstableIncs += unstable; 7906 } 7907 unstable = conn.unstableCount + unstable; 7908 if (unstable < 0) { 7909 throw new IllegalStateException("unstableCount < 0: " + unstable); 7910 } 7911 7912 if ((stable+unstable) <= 0) { 7913 throw new IllegalStateException("ref counts can't go to zero here: stable=" 7914 + stable + " unstable=" + unstable); 7915 } 7916 conn.stableCount = stable; 7917 conn.unstableCount = unstable; 7918 return !conn.dead; 7919 } 7920 } 7921 7922 public void unstableProviderDied(IBinder connection) { 7923 ContentProviderConnection conn; 7924 try { 7925 conn = (ContentProviderConnection)connection; 7926 } catch (ClassCastException e) { 7927 String msg ="refContentProvider: " + connection 7928 + " not a ContentProviderConnection"; 7929 Slog.w(TAG, msg); 7930 throw new IllegalArgumentException(msg); 7931 } 7932 if (conn == null) { 7933 throw new NullPointerException("connection is null"); 7934 } 7935 7936 // Safely retrieve the content provider associated with the connection. 7937 IContentProvider provider; 7938 synchronized (this) { 7939 provider = conn.provider.provider; 7940 } 7941 7942 if (provider == null) { 7943 // Um, yeah, we're way ahead of you. 7944 return; 7945 } 7946 7947 // Make sure the caller is being honest with us. 7948 if (provider.asBinder().pingBinder()) { 7949 // Er, no, still looks good to us. 7950 synchronized (this) { 7951 Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid() 7952 + " says " + conn + " died, but we don't agree"); 7953 return; 7954 } 7955 } 7956 7957 // Well look at that! It's dead! 7958 synchronized (this) { 7959 if (conn.provider.provider != provider) { 7960 // But something changed... good enough. 7961 return; 7962 } 7963 7964 ProcessRecord proc = conn.provider.proc; 7965 if (proc == null || proc.thread == null) { 7966 // Seems like the process is already cleaned up. 7967 return; 7968 } 7969 7970 // As far as we're concerned, this is just like receiving a 7971 // death notification... just a bit prematurely. 7972 Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid 7973 + ") early provider death"); 7974 final long ident = Binder.clearCallingIdentity(); 7975 try { 7976 appDiedLocked(proc, proc.pid, proc.thread); 7977 } finally { 7978 Binder.restoreCallingIdentity(ident); 7979 } 7980 } 7981 } 7982 7983 @Override 7984 public void appNotRespondingViaProvider(IBinder connection) { 7985 enforceCallingPermission( 7986 android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()"); 7987 7988 final ContentProviderConnection conn = (ContentProviderConnection) connection; 7989 if (conn == null) { 7990 Slog.w(TAG, "ContentProviderConnection is null"); 7991 return; 7992 } 7993 7994 final ProcessRecord host = conn.provider.proc; 7995 if (host == null) { 7996 Slog.w(TAG, "Failed to find hosting ProcessRecord"); 7997 return; 7998 } 7999 8000 final long token = Binder.clearCallingIdentity(); 8001 try { 8002 appNotResponding(host, null, null, false, "ContentProvider not responding"); 8003 } finally { 8004 Binder.restoreCallingIdentity(token); 8005 } 8006 } 8007 8008 public final void installSystemProviders() { 8009 List<ProviderInfo> providers; 8010 synchronized (this) { 8011 ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID); 8012 providers = generateApplicationProvidersLocked(app); 8013 if (providers != null) { 8014 for (int i=providers.size()-1; i>=0; i--) { 8015 ProviderInfo pi = (ProviderInfo)providers.get(i); 8016 if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) { 8017 Slog.w(TAG, "Not installing system proc provider " + pi.name 8018 + ": not system .apk"); 8019 providers.remove(i); 8020 } 8021 } 8022 } 8023 } 8024 if (providers != null) { 8025 mSystemThread.installSystemProviders(providers); 8026 } 8027 8028 mCoreSettingsObserver = new CoreSettingsObserver(this); 8029 8030 mUsageStatsService.monitorPackages(); 8031 } 8032 8033 /** 8034 * Allows app to retrieve the MIME type of a URI without having permission 8035 * to access its content provider. 8036 * 8037 * CTS tests for this functionality can be run with "runtest cts-appsecurity". 8038 * 8039 * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/ 8040 * src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java 8041 */ 8042 public String getProviderMimeType(Uri uri, int userId) { 8043 enforceNotIsolatedCaller("getProviderMimeType"); 8044 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 8045 userId, false, true, "getProviderMimeType", null); 8046 final String name = uri.getAuthority(); 8047 final long ident = Binder.clearCallingIdentity(); 8048 ContentProviderHolder holder = null; 8049 8050 try { 8051 holder = getContentProviderExternalUnchecked(name, null, userId); 8052 if (holder != null) { 8053 return holder.provider.getType(uri); 8054 } 8055 } catch (RemoteException e) { 8056 Log.w(TAG, "Content provider dead retrieving " + uri, e); 8057 return null; 8058 } finally { 8059 if (holder != null) { 8060 removeContentProviderExternalUnchecked(name, null, userId); 8061 } 8062 Binder.restoreCallingIdentity(ident); 8063 } 8064 8065 return null; 8066 } 8067 8068 // ========================================================= 8069 // GLOBAL MANAGEMENT 8070 // ========================================================= 8071 8072 final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess, 8073 boolean isolated) { 8074 String proc = customProcess != null ? customProcess : info.processName; 8075 BatteryStatsImpl.Uid.Proc ps = null; 8076 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 8077 int uid = info.uid; 8078 if (isolated) { 8079 int userId = UserHandle.getUserId(uid); 8080 int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1; 8081 while (true) { 8082 if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID 8083 || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) { 8084 mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID; 8085 } 8086 uid = UserHandle.getUid(userId, mNextIsolatedProcessUid); 8087 mNextIsolatedProcessUid++; 8088 if (mIsolatedProcesses.indexOfKey(uid) < 0) { 8089 // No process for this uid, use it. 8090 break; 8091 } 8092 stepsLeft--; 8093 if (stepsLeft <= 0) { 8094 return null; 8095 } 8096 } 8097 } 8098 return new ProcessRecord(stats, info, proc, uid); 8099 } 8100 8101 final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated) { 8102 ProcessRecord app; 8103 if (!isolated) { 8104 app = getProcessRecordLocked(info.processName, info.uid, true); 8105 } else { 8106 app = null; 8107 } 8108 8109 if (app == null) { 8110 app = newProcessRecordLocked(info, null, isolated); 8111 mProcessNames.put(info.processName, app.uid, app); 8112 if (isolated) { 8113 mIsolatedProcesses.put(app.uid, app); 8114 } 8115 updateLruProcessLocked(app, false, null); 8116 updateOomAdjLocked(); 8117 } 8118 8119 // This package really, really can not be stopped. 8120 try { 8121 AppGlobals.getPackageManager().setPackageStoppedState( 8122 info.packageName, false, UserHandle.getUserId(app.uid)); 8123 } catch (RemoteException e) { 8124 } catch (IllegalArgumentException e) { 8125 Slog.w(TAG, "Failed trying to unstop package " 8126 + info.packageName + ": " + e); 8127 } 8128 8129 if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) 8130 == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) { 8131 app.persistent = true; 8132 app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ; 8133 } 8134 if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) { 8135 mPersistentStartingProcesses.add(app); 8136 startProcessLocked(app, "added application", app.processName); 8137 } 8138 8139 return app; 8140 } 8141 8142 public void unhandledBack() { 8143 enforceCallingPermission(android.Manifest.permission.FORCE_BACK, 8144 "unhandledBack()"); 8145 8146 synchronized(this) { 8147 final long origId = Binder.clearCallingIdentity(); 8148 try { 8149 getFocusedStack().unhandledBackLocked(); 8150 } finally { 8151 Binder.restoreCallingIdentity(origId); 8152 } 8153 } 8154 } 8155 8156 public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException { 8157 enforceNotIsolatedCaller("openContentUri"); 8158 final int userId = UserHandle.getCallingUserId(); 8159 String name = uri.getAuthority(); 8160 ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId); 8161 ParcelFileDescriptor pfd = null; 8162 if (cph != null) { 8163 // We record the binder invoker's uid in thread-local storage before 8164 // going to the content provider to open the file. Later, in the code 8165 // that handles all permissions checks, we look for this uid and use 8166 // that rather than the Activity Manager's own uid. The effect is that 8167 // we do the check against the caller's permissions even though it looks 8168 // to the content provider like the Activity Manager itself is making 8169 // the request. 8170 sCallerIdentity.set(new Identity( 8171 Binder.getCallingPid(), Binder.getCallingUid())); 8172 try { 8173 pfd = cph.provider.openFile(null, uri, "r", null); 8174 } catch (FileNotFoundException e) { 8175 // do nothing; pfd will be returned null 8176 } finally { 8177 // Ensure that whatever happens, we clean up the identity state 8178 sCallerIdentity.remove(); 8179 } 8180 8181 // We've got the fd now, so we're done with the provider. 8182 removeContentProviderExternalUnchecked(name, null, userId); 8183 } else { 8184 Slog.d(TAG, "Failed to get provider for authority '" + name + "'"); 8185 } 8186 return pfd; 8187 } 8188 8189 // Actually is sleeping or shutting down or whatever else in the future 8190 // is an inactive state. 8191 public boolean isSleepingOrShuttingDown() { 8192 return mSleeping || mShuttingDown; 8193 } 8194 8195 void goingToSleep() { 8196 synchronized(this) { 8197 mWentToSleep = true; 8198 updateEventDispatchingLocked(); 8199 8200 if (!mSleeping) { 8201 mSleeping = true; 8202 mStackSupervisor.goingToSleepLocked(); 8203 8204 // Initialize the wake times of all processes. 8205 checkExcessivePowerUsageLocked(false); 8206 mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 8207 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 8208 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 8209 } 8210 } 8211 } 8212 8213 @Override 8214 public boolean shutdown(int timeout) { 8215 if (checkCallingPermission(android.Manifest.permission.SHUTDOWN) 8216 != PackageManager.PERMISSION_GRANTED) { 8217 throw new SecurityException("Requires permission " 8218 + android.Manifest.permission.SHUTDOWN); 8219 } 8220 8221 boolean timedout = false; 8222 8223 synchronized(this) { 8224 mShuttingDown = true; 8225 updateEventDispatchingLocked(); 8226 timedout = mStackSupervisor.shutdownLocked(timeout); 8227 } 8228 8229 mAppOpsService.shutdown(); 8230 mUsageStatsService.shutdown(); 8231 mBatteryStatsService.shutdown(); 8232 synchronized (this) { 8233 mProcessStats.shutdownLocked(); 8234 } 8235 8236 return timedout; 8237 } 8238 8239 public final void activitySlept(IBinder token) { 8240 if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token); 8241 8242 final long origId = Binder.clearCallingIdentity(); 8243 8244 synchronized (this) { 8245 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 8246 if (r != null) { 8247 mStackSupervisor.activitySleptLocked(r); 8248 } 8249 } 8250 8251 Binder.restoreCallingIdentity(origId); 8252 } 8253 8254 void logLockScreen(String msg) { 8255 if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg + 8256 " mLockScreenShown=" + mLockScreenShown + " mWentToSleep=" + 8257 mWentToSleep + " mSleeping=" + mSleeping + " mDismissKeyguardOnNextActivity=" + 8258 mStackSupervisor.mDismissKeyguardOnNextActivity); 8259 } 8260 8261 private void comeOutOfSleepIfNeededLocked() { 8262 if (!mWentToSleep && !mLockScreenShown) { 8263 if (mSleeping) { 8264 mSleeping = false; 8265 mStackSupervisor.comeOutOfSleepIfNeededLocked(); 8266 } 8267 } 8268 } 8269 8270 void wakingUp() { 8271 synchronized(this) { 8272 mWentToSleep = false; 8273 updateEventDispatchingLocked(); 8274 comeOutOfSleepIfNeededLocked(); 8275 } 8276 } 8277 8278 private void updateEventDispatchingLocked() { 8279 mWindowManager.setEventDispatching(mBooted && !mWentToSleep && !mShuttingDown); 8280 } 8281 8282 public void setLockScreenShown(boolean shown) { 8283 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER) 8284 != PackageManager.PERMISSION_GRANTED) { 8285 throw new SecurityException("Requires permission " 8286 + android.Manifest.permission.DEVICE_POWER); 8287 } 8288 8289 synchronized(this) { 8290 long ident = Binder.clearCallingIdentity(); 8291 try { 8292 if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown); 8293 mLockScreenShown = shown; 8294 comeOutOfSleepIfNeededLocked(); 8295 } finally { 8296 Binder.restoreCallingIdentity(ident); 8297 } 8298 } 8299 } 8300 8301 public void stopAppSwitches() { 8302 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 8303 != PackageManager.PERMISSION_GRANTED) { 8304 throw new SecurityException("Requires permission " 8305 + android.Manifest.permission.STOP_APP_SWITCHES); 8306 } 8307 8308 synchronized(this) { 8309 mAppSwitchesAllowedTime = SystemClock.uptimeMillis() 8310 + APP_SWITCH_DELAY_TIME; 8311 mDidAppSwitch = false; 8312 mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 8313 Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 8314 mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME); 8315 } 8316 } 8317 8318 public void resumeAppSwitches() { 8319 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 8320 != PackageManager.PERMISSION_GRANTED) { 8321 throw new SecurityException("Requires permission " 8322 + android.Manifest.permission.STOP_APP_SWITCHES); 8323 } 8324 8325 synchronized(this) { 8326 // Note that we don't execute any pending app switches... we will 8327 // let those wait until either the timeout, or the next start 8328 // activity request. 8329 mAppSwitchesAllowedTime = 0; 8330 } 8331 } 8332 8333 boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid, 8334 String name) { 8335 if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) { 8336 return true; 8337 } 8338 8339 final int perm = checkComponentPermission( 8340 android.Manifest.permission.STOP_APP_SWITCHES, callingPid, 8341 callingUid, -1, true); 8342 if (perm == PackageManager.PERMISSION_GRANTED) { 8343 return true; 8344 } 8345 8346 Slog.w(TAG, name + " request from " + callingUid + " stopped"); 8347 return false; 8348 } 8349 8350 public void setDebugApp(String packageName, boolean waitForDebugger, 8351 boolean persistent) { 8352 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP, 8353 "setDebugApp()"); 8354 8355 long ident = Binder.clearCallingIdentity(); 8356 try { 8357 // Note that this is not really thread safe if there are multiple 8358 // callers into it at the same time, but that's not a situation we 8359 // care about. 8360 if (persistent) { 8361 final ContentResolver resolver = mContext.getContentResolver(); 8362 Settings.Global.putString( 8363 resolver, Settings.Global.DEBUG_APP, 8364 packageName); 8365 Settings.Global.putInt( 8366 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 8367 waitForDebugger ? 1 : 0); 8368 } 8369 8370 synchronized (this) { 8371 if (!persistent) { 8372 mOrigDebugApp = mDebugApp; 8373 mOrigWaitForDebugger = mWaitForDebugger; 8374 } 8375 mDebugApp = packageName; 8376 mWaitForDebugger = waitForDebugger; 8377 mDebugTransient = !persistent; 8378 if (packageName != null) { 8379 forceStopPackageLocked(packageName, -1, false, false, true, true, 8380 UserHandle.USER_ALL, "set debug app"); 8381 } 8382 } 8383 } finally { 8384 Binder.restoreCallingIdentity(ident); 8385 } 8386 } 8387 8388 void setOpenGlTraceApp(ApplicationInfo app, String processName) { 8389 synchronized (this) { 8390 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 8391 if (!isDebuggable) { 8392 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 8393 throw new SecurityException("Process not debuggable: " + app.packageName); 8394 } 8395 } 8396 8397 mOpenGlTraceApp = processName; 8398 } 8399 } 8400 8401 void setProfileApp(ApplicationInfo app, String processName, String profileFile, 8402 ParcelFileDescriptor profileFd, boolean autoStopProfiler) { 8403 synchronized (this) { 8404 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 8405 if (!isDebuggable) { 8406 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 8407 throw new SecurityException("Process not debuggable: " + app.packageName); 8408 } 8409 } 8410 mProfileApp = processName; 8411 mProfileFile = profileFile; 8412 if (mProfileFd != null) { 8413 try { 8414 mProfileFd.close(); 8415 } catch (IOException e) { 8416 } 8417 mProfileFd = null; 8418 } 8419 mProfileFd = profileFd; 8420 mProfileType = 0; 8421 mAutoStopProfiler = autoStopProfiler; 8422 } 8423 } 8424 8425 @Override 8426 public void setAlwaysFinish(boolean enabled) { 8427 enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH, 8428 "setAlwaysFinish()"); 8429 8430 Settings.Global.putInt( 8431 mContext.getContentResolver(), 8432 Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0); 8433 8434 synchronized (this) { 8435 mAlwaysFinishActivities = enabled; 8436 } 8437 } 8438 8439 @Override 8440 public void setActivityController(IActivityController controller) { 8441 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 8442 "setActivityController()"); 8443 synchronized (this) { 8444 mController = controller; 8445 Watchdog.getInstance().setActivityController(controller); 8446 } 8447 } 8448 8449 @Override 8450 public void setUserIsMonkey(boolean userIsMonkey) { 8451 synchronized (this) { 8452 synchronized (mPidsSelfLocked) { 8453 final int callingPid = Binder.getCallingPid(); 8454 ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid); 8455 if (precessRecord == null) { 8456 throw new SecurityException("Unknown process: " + callingPid); 8457 } 8458 if (precessRecord.instrumentationUiAutomationConnection == null) { 8459 throw new SecurityException("Only an instrumentation process " 8460 + "with a UiAutomation can call setUserIsMonkey"); 8461 } 8462 } 8463 mUserIsMonkey = userIsMonkey; 8464 } 8465 } 8466 8467 @Override 8468 public boolean isUserAMonkey() { 8469 synchronized (this) { 8470 // If there is a controller also implies the user is a monkey. 8471 return (mUserIsMonkey || mController != null); 8472 } 8473 } 8474 8475 public void requestBugReport() { 8476 enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport"); 8477 SystemProperties.set("ctl.start", "bugreport"); 8478 } 8479 8480 public static long getInputDispatchingTimeoutLocked(ActivityRecord r) { 8481 return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT; 8482 } 8483 8484 public static long getInputDispatchingTimeoutLocked(ProcessRecord r) { 8485 if (r != null && (r.instrumentationClass != null || r.usingWrapper)) { 8486 return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT; 8487 } 8488 return KEY_DISPATCHING_TIMEOUT; 8489 } 8490 8491 @Override 8492 public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) { 8493 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS) 8494 != PackageManager.PERMISSION_GRANTED) { 8495 throw new SecurityException("Requires permission " 8496 + android.Manifest.permission.FILTER_EVENTS); 8497 } 8498 ProcessRecord proc; 8499 long timeout; 8500 synchronized (this) { 8501 synchronized (mPidsSelfLocked) { 8502 proc = mPidsSelfLocked.get(pid); 8503 } 8504 timeout = getInputDispatchingTimeoutLocked(proc); 8505 } 8506 8507 if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) { 8508 return -1; 8509 } 8510 8511 return timeout; 8512 } 8513 8514 /** 8515 * Handle input dispatching timeouts. 8516 * Returns whether input dispatching should be aborted or not. 8517 */ 8518 public boolean inputDispatchingTimedOut(final ProcessRecord proc, 8519 final ActivityRecord activity, final ActivityRecord parent, 8520 final boolean aboveSystem, String reason) { 8521 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS) 8522 != PackageManager.PERMISSION_GRANTED) { 8523 throw new SecurityException("Requires permission " 8524 + android.Manifest.permission.FILTER_EVENTS); 8525 } 8526 8527 final String annotation; 8528 if (reason == null) { 8529 annotation = "Input dispatching timed out"; 8530 } else { 8531 annotation = "Input dispatching timed out (" + reason + ")"; 8532 } 8533 8534 if (proc != null) { 8535 synchronized (this) { 8536 if (proc.debugging) { 8537 return false; 8538 } 8539 8540 if (mDidDexOpt) { 8541 // Give more time since we were dexopting. 8542 mDidDexOpt = false; 8543 return false; 8544 } 8545 8546 if (proc.instrumentationClass != null) { 8547 Bundle info = new Bundle(); 8548 info.putString("shortMsg", "keyDispatchingTimedOut"); 8549 info.putString("longMsg", annotation); 8550 finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info); 8551 return true; 8552 } 8553 } 8554 mHandler.post(new Runnable() { 8555 @Override 8556 public void run() { 8557 appNotResponding(proc, activity, parent, aboveSystem, annotation); 8558 } 8559 }); 8560 } 8561 8562 return true; 8563 } 8564 8565 public Bundle getAssistContextExtras(int requestType) { 8566 enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO, 8567 "getAssistContextExtras()"); 8568 PendingAssistExtras pae; 8569 Bundle extras = new Bundle(); 8570 synchronized (this) { 8571 ActivityRecord activity = getFocusedStack().mResumedActivity; 8572 if (activity == null) { 8573 Slog.w(TAG, "getAssistContextExtras failed: no resumed activity"); 8574 return null; 8575 } 8576 extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName); 8577 if (activity.app == null || activity.app.thread == null) { 8578 Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity); 8579 return extras; 8580 } 8581 if (activity.app.pid == Binder.getCallingPid()) { 8582 Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity); 8583 return extras; 8584 } 8585 pae = new PendingAssistExtras(activity); 8586 try { 8587 activity.app.thread.requestAssistContextExtras(activity.appToken, pae, 8588 requestType); 8589 mPendingAssistExtras.add(pae); 8590 mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT); 8591 } catch (RemoteException e) { 8592 Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity); 8593 return extras; 8594 } 8595 } 8596 synchronized (pae) { 8597 while (!pae.haveResult) { 8598 try { 8599 pae.wait(); 8600 } catch (InterruptedException e) { 8601 } 8602 } 8603 if (pae.result != null) { 8604 extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result); 8605 } 8606 } 8607 synchronized (this) { 8608 mPendingAssistExtras.remove(pae); 8609 mHandler.removeCallbacks(pae); 8610 } 8611 return extras; 8612 } 8613 8614 public void reportAssistContextExtras(IBinder token, Bundle extras) { 8615 PendingAssistExtras pae = (PendingAssistExtras)token; 8616 synchronized (pae) { 8617 pae.result = extras; 8618 pae.haveResult = true; 8619 pae.notifyAll(); 8620 } 8621 } 8622 8623 public void registerProcessObserver(IProcessObserver observer) { 8624 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 8625 "registerProcessObserver()"); 8626 synchronized (this) { 8627 mProcessObservers.register(observer); 8628 } 8629 } 8630 8631 @Override 8632 public void unregisterProcessObserver(IProcessObserver observer) { 8633 synchronized (this) { 8634 mProcessObservers.unregister(observer); 8635 } 8636 } 8637 8638 @Override 8639 public boolean convertFromTranslucent(IBinder token) { 8640 final long origId = Binder.clearCallingIdentity(); 8641 try { 8642 synchronized (this) { 8643 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 8644 if (r == null) { 8645 return false; 8646 } 8647 if (r.changeWindowTranslucency(true)) { 8648 mWindowManager.setAppFullscreen(token, true); 8649 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 8650 return true; 8651 } 8652 return false; 8653 } 8654 } finally { 8655 Binder.restoreCallingIdentity(origId); 8656 } 8657 } 8658 8659 @Override 8660 public boolean convertToTranslucent(IBinder token) { 8661 final long origId = Binder.clearCallingIdentity(); 8662 try { 8663 synchronized (this) { 8664 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 8665 if (r == null) { 8666 return false; 8667 } 8668 if (r.changeWindowTranslucency(false)) { 8669 r.task.stack.convertToTranslucent(r); 8670 mWindowManager.setAppFullscreen(token, false); 8671 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 8672 return true; 8673 } 8674 return false; 8675 } 8676 } finally { 8677 Binder.restoreCallingIdentity(origId); 8678 } 8679 } 8680 8681 @Override 8682 public void setImmersive(IBinder token, boolean immersive) { 8683 synchronized(this) { 8684 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 8685 if (r == null) { 8686 throw new IllegalArgumentException(); 8687 } 8688 r.immersive = immersive; 8689 8690 // update associated state if we're frontmost 8691 if (r == mFocusedActivity) { 8692 if (DEBUG_IMMERSIVE) { 8693 Slog.d(TAG, "Frontmost changed immersion: "+ r); 8694 } 8695 applyUpdateLockStateLocked(r); 8696 } 8697 } 8698 } 8699 8700 @Override 8701 public boolean isImmersive(IBinder token) { 8702 synchronized (this) { 8703 ActivityRecord r = ActivityRecord.isInStackLocked(token); 8704 if (r == null) { 8705 throw new IllegalArgumentException(); 8706 } 8707 return r.immersive; 8708 } 8709 } 8710 8711 public boolean isTopActivityImmersive() { 8712 enforceNotIsolatedCaller("startActivity"); 8713 synchronized (this) { 8714 ActivityRecord r = getFocusedStack().topRunningActivityLocked(null); 8715 return (r != null) ? r.immersive : false; 8716 } 8717 } 8718 8719 public final void enterSafeMode() { 8720 synchronized(this) { 8721 // It only makes sense to do this before the system is ready 8722 // and started launching other packages. 8723 if (!mSystemReady) { 8724 try { 8725 AppGlobals.getPackageManager().enterSafeMode(); 8726 } catch (RemoteException e) { 8727 } 8728 } 8729 8730 mSafeMode = true; 8731 } 8732 } 8733 8734 public final void showSafeModeOverlay() { 8735 View v = LayoutInflater.from(mContext).inflate( 8736 com.android.internal.R.layout.safe_mode, null); 8737 WindowManager.LayoutParams lp = new WindowManager.LayoutParams(); 8738 lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY; 8739 lp.width = WindowManager.LayoutParams.WRAP_CONTENT; 8740 lp.height = WindowManager.LayoutParams.WRAP_CONTENT; 8741 lp.gravity = Gravity.BOTTOM | Gravity.START; 8742 lp.format = v.getBackground().getOpacity(); 8743 lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE 8744 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE; 8745 lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS; 8746 ((WindowManager)mContext.getSystemService( 8747 Context.WINDOW_SERVICE)).addView(v, lp); 8748 } 8749 8750 public void noteWakeupAlarm(IIntentSender sender) { 8751 if (!(sender instanceof PendingIntentRecord)) { 8752 return; 8753 } 8754 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 8755 synchronized (stats) { 8756 if (mBatteryStatsService.isOnBattery()) { 8757 mBatteryStatsService.enforceCallingPermission(); 8758 PendingIntentRecord rec = (PendingIntentRecord)sender; 8759 int MY_UID = Binder.getCallingUid(); 8760 int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid; 8761 BatteryStatsImpl.Uid.Pkg pkg = 8762 stats.getPackageStatsLocked(uid, rec.key.packageName); 8763 pkg.incWakeupsLocked(); 8764 } 8765 } 8766 } 8767 8768 public boolean killPids(int[] pids, String pReason, boolean secure) { 8769 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 8770 throw new SecurityException("killPids only available to the system"); 8771 } 8772 String reason = (pReason == null) ? "Unknown" : pReason; 8773 // XXX Note: don't acquire main activity lock here, because the window 8774 // manager calls in with its locks held. 8775 8776 boolean killed = false; 8777 synchronized (mPidsSelfLocked) { 8778 int[] types = new int[pids.length]; 8779 int worstType = 0; 8780 for (int i=0; i<pids.length; i++) { 8781 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 8782 if (proc != null) { 8783 int type = proc.setAdj; 8784 types[i] = type; 8785 if (type > worstType) { 8786 worstType = type; 8787 } 8788 } 8789 } 8790 8791 // If the worst oom_adj is somewhere in the cached proc LRU range, 8792 // then constrain it so we will kill all cached procs. 8793 if (worstType < ProcessList.CACHED_APP_MAX_ADJ 8794 && worstType > ProcessList.CACHED_APP_MIN_ADJ) { 8795 worstType = ProcessList.CACHED_APP_MIN_ADJ; 8796 } 8797 8798 // If this is not a secure call, don't let it kill processes that 8799 // are important. 8800 if (!secure && worstType < ProcessList.SERVICE_ADJ) { 8801 worstType = ProcessList.SERVICE_ADJ; 8802 } 8803 8804 Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType); 8805 for (int i=0; i<pids.length; i++) { 8806 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 8807 if (proc == null) { 8808 continue; 8809 } 8810 int adj = proc.setAdj; 8811 if (adj >= worstType && !proc.killedByAm) { 8812 killUnneededProcessLocked(proc, reason); 8813 killed = true; 8814 } 8815 } 8816 } 8817 return killed; 8818 } 8819 8820 @Override 8821 public void killUid(int uid, String reason) { 8822 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 8823 throw new SecurityException("killUid only available to the system"); 8824 } 8825 synchronized (this) { 8826 killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid), 8827 ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false, 8828 reason != null ? reason : "kill uid"); 8829 } 8830 } 8831 8832 @Override 8833 public boolean killProcessesBelowForeground(String reason) { 8834 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 8835 throw new SecurityException("killProcessesBelowForeground() only available to system"); 8836 } 8837 8838 return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason); 8839 } 8840 8841 private boolean killProcessesBelowAdj(int belowAdj, String reason) { 8842 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 8843 throw new SecurityException("killProcessesBelowAdj() only available to system"); 8844 } 8845 8846 boolean killed = false; 8847 synchronized (mPidsSelfLocked) { 8848 final int size = mPidsSelfLocked.size(); 8849 for (int i = 0; i < size; i++) { 8850 final int pid = mPidsSelfLocked.keyAt(i); 8851 final ProcessRecord proc = mPidsSelfLocked.valueAt(i); 8852 if (proc == null) continue; 8853 8854 final int adj = proc.setAdj; 8855 if (adj > belowAdj && !proc.killedByAm) { 8856 killUnneededProcessLocked(proc, reason); 8857 killed = true; 8858 } 8859 } 8860 } 8861 return killed; 8862 } 8863 8864 @Override 8865 public void hang(final IBinder who, boolean allowRestart) { 8866 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 8867 != PackageManager.PERMISSION_GRANTED) { 8868 throw new SecurityException("Requires permission " 8869 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 8870 } 8871 8872 final IBinder.DeathRecipient death = new DeathRecipient() { 8873 @Override 8874 public void binderDied() { 8875 synchronized (this) { 8876 notifyAll(); 8877 } 8878 } 8879 }; 8880 8881 try { 8882 who.linkToDeath(death, 0); 8883 } catch (RemoteException e) { 8884 Slog.w(TAG, "hang: given caller IBinder is already dead."); 8885 return; 8886 } 8887 8888 synchronized (this) { 8889 Watchdog.getInstance().setAllowRestart(allowRestart); 8890 Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid()); 8891 synchronized (death) { 8892 while (who.isBinderAlive()) { 8893 try { 8894 death.wait(); 8895 } catch (InterruptedException e) { 8896 } 8897 } 8898 } 8899 Watchdog.getInstance().setAllowRestart(true); 8900 } 8901 } 8902 8903 @Override 8904 public void restart() { 8905 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 8906 != PackageManager.PERMISSION_GRANTED) { 8907 throw new SecurityException("Requires permission " 8908 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 8909 } 8910 8911 Log.i(TAG, "Sending shutdown broadcast..."); 8912 8913 BroadcastReceiver br = new BroadcastReceiver() { 8914 @Override public void onReceive(Context context, Intent intent) { 8915 // Now the broadcast is done, finish up the low-level shutdown. 8916 Log.i(TAG, "Shutting down activity manager..."); 8917 shutdown(10000); 8918 Log.i(TAG, "Shutdown complete, restarting!"); 8919 Process.killProcess(Process.myPid()); 8920 System.exit(10); 8921 } 8922 }; 8923 8924 // First send the high-level shut down broadcast. 8925 Intent intent = new Intent(Intent.ACTION_SHUTDOWN); 8926 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 8927 intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true); 8928 /* For now we are not doing a clean shutdown, because things seem to get unhappy. 8929 mContext.sendOrderedBroadcastAsUser(intent, 8930 UserHandle.ALL, null, br, mHandler, 0, null, null); 8931 */ 8932 br.onReceive(mContext, intent); 8933 } 8934 8935 private long getLowRamTimeSinceIdle(long now) { 8936 return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0); 8937 } 8938 8939 @Override 8940 public void performIdleMaintenance() { 8941 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 8942 != PackageManager.PERMISSION_GRANTED) { 8943 throw new SecurityException("Requires permission " 8944 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 8945 } 8946 8947 synchronized (this) { 8948 final long now = SystemClock.uptimeMillis(); 8949 final long timeSinceLastIdle = now - mLastIdleTime; 8950 final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now); 8951 mLastIdleTime = now; 8952 mLowRamTimeSinceLastIdle = 0; 8953 if (mLowRamStartTime != 0) { 8954 mLowRamStartTime = now; 8955 } 8956 8957 StringBuilder sb = new StringBuilder(128); 8958 sb.append("Idle maintenance over "); 8959 TimeUtils.formatDuration(timeSinceLastIdle, sb); 8960 sb.append(" low RAM for "); 8961 TimeUtils.formatDuration(lowRamSinceLastIdle, sb); 8962 Slog.i(TAG, sb.toString()); 8963 8964 // If at least 1/3 of our time since the last idle period has been spent 8965 // with RAM low, then we want to kill processes. 8966 boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3); 8967 8968 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 8969 ProcessRecord proc = mLruProcesses.get(i); 8970 if (proc.notCachedSinceIdle) { 8971 if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP 8972 && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) { 8973 if (doKilling && proc.initialIdlePss != 0 8974 && proc.lastPss > ((proc.initialIdlePss*3)/2)) { 8975 killUnneededProcessLocked(proc, "idle maint (pss " + proc.lastPss 8976 + " from " + proc.initialIdlePss + ")"); 8977 } 8978 } 8979 } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) { 8980 proc.notCachedSinceIdle = true; 8981 proc.initialIdlePss = 0; 8982 proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true, 8983 mSleeping, now); 8984 } 8985 } 8986 8987 mHandler.removeMessages(REQUEST_ALL_PSS_MSG); 8988 mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000); 8989 } 8990 } 8991 8992 private void retrieveSettings() { 8993 final ContentResolver resolver = mContext.getContentResolver(); 8994 String debugApp = Settings.Global.getString( 8995 resolver, Settings.Global.DEBUG_APP); 8996 boolean waitForDebugger = Settings.Global.getInt( 8997 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0; 8998 boolean alwaysFinishActivities = Settings.Global.getInt( 8999 resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0; 9000 boolean forceRtl = Settings.Global.getInt( 9001 resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0; 9002 // Transfer any global setting for forcing RTL layout, into a System Property 9003 SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0"); 9004 9005 Configuration configuration = new Configuration(); 9006 Settings.System.getConfiguration(resolver, configuration); 9007 if (forceRtl) { 9008 // This will take care of setting the correct layout direction flags 9009 configuration.setLayoutDirection(configuration.locale); 9010 } 9011 9012 synchronized (this) { 9013 mDebugApp = mOrigDebugApp = debugApp; 9014 mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger; 9015 mAlwaysFinishActivities = alwaysFinishActivities; 9016 // This happens before any activities are started, so we can 9017 // change mConfiguration in-place. 9018 updateConfigurationLocked(configuration, null, false, true); 9019 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration); 9020 } 9021 } 9022 9023 public boolean testIsSystemReady() { 9024 // no need to synchronize(this) just to read & return the value 9025 return mSystemReady; 9026 } 9027 9028 private static File getCalledPreBootReceiversFile() { 9029 File dataDir = Environment.getDataDirectory(); 9030 File systemDir = new File(dataDir, "system"); 9031 File fname = new File(systemDir, "called_pre_boots.dat"); 9032 return fname; 9033 } 9034 9035 static final int LAST_DONE_VERSION = 10000; 9036 9037 private static ArrayList<ComponentName> readLastDonePreBootReceivers() { 9038 ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>(); 9039 File file = getCalledPreBootReceiversFile(); 9040 FileInputStream fis = null; 9041 try { 9042 fis = new FileInputStream(file); 9043 DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048)); 9044 int fvers = dis.readInt(); 9045 if (fvers == LAST_DONE_VERSION) { 9046 String vers = dis.readUTF(); 9047 String codename = dis.readUTF(); 9048 String build = dis.readUTF(); 9049 if (android.os.Build.VERSION.RELEASE.equals(vers) 9050 && android.os.Build.VERSION.CODENAME.equals(codename) 9051 && android.os.Build.VERSION.INCREMENTAL.equals(build)) { 9052 int num = dis.readInt(); 9053 while (num > 0) { 9054 num--; 9055 String pkg = dis.readUTF(); 9056 String cls = dis.readUTF(); 9057 lastDoneReceivers.add(new ComponentName(pkg, cls)); 9058 } 9059 } 9060 } 9061 } catch (FileNotFoundException e) { 9062 } catch (IOException e) { 9063 Slog.w(TAG, "Failure reading last done pre-boot receivers", e); 9064 } finally { 9065 if (fis != null) { 9066 try { 9067 fis.close(); 9068 } catch (IOException e) { 9069 } 9070 } 9071 } 9072 return lastDoneReceivers; 9073 } 9074 9075 private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) { 9076 File file = getCalledPreBootReceiversFile(); 9077 FileOutputStream fos = null; 9078 DataOutputStream dos = null; 9079 try { 9080 Slog.i(TAG, "Writing new set of last done pre-boot receivers..."); 9081 fos = new FileOutputStream(file); 9082 dos = new DataOutputStream(new BufferedOutputStream(fos, 2048)); 9083 dos.writeInt(LAST_DONE_VERSION); 9084 dos.writeUTF(android.os.Build.VERSION.RELEASE); 9085 dos.writeUTF(android.os.Build.VERSION.CODENAME); 9086 dos.writeUTF(android.os.Build.VERSION.INCREMENTAL); 9087 dos.writeInt(list.size()); 9088 for (int i=0; i<list.size(); i++) { 9089 dos.writeUTF(list.get(i).getPackageName()); 9090 dos.writeUTF(list.get(i).getClassName()); 9091 } 9092 } catch (IOException e) { 9093 Slog.w(TAG, "Failure writing last done pre-boot receivers", e); 9094 file.delete(); 9095 } finally { 9096 FileUtils.sync(fos); 9097 if (dos != null) { 9098 try { 9099 dos.close(); 9100 } catch (IOException e) { 9101 // TODO Auto-generated catch block 9102 e.printStackTrace(); 9103 } 9104 } 9105 } 9106 } 9107 9108 public void systemReady(final Runnable goingCallback) { 9109 synchronized(this) { 9110 if (mSystemReady) { 9111 if (goingCallback != null) goingCallback.run(); 9112 return; 9113 } 9114 9115 // Check to see if there are any update receivers to run. 9116 if (!mDidUpdate) { 9117 if (mWaitingUpdate) { 9118 return; 9119 } 9120 Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED); 9121 List<ResolveInfo> ris = null; 9122 try { 9123 ris = AppGlobals.getPackageManager().queryIntentReceivers( 9124 intent, null, 0, 0); 9125 } catch (RemoteException e) { 9126 } 9127 if (ris != null) { 9128 for (int i=ris.size()-1; i>=0; i--) { 9129 if ((ris.get(i).activityInfo.applicationInfo.flags 9130 &ApplicationInfo.FLAG_SYSTEM) == 0) { 9131 ris.remove(i); 9132 } 9133 } 9134 intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE); 9135 9136 ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers(); 9137 9138 final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>(); 9139 for (int i=0; i<ris.size(); i++) { 9140 ActivityInfo ai = ris.get(i).activityInfo; 9141 ComponentName comp = new ComponentName(ai.packageName, ai.name); 9142 if (lastDoneReceivers.contains(comp)) { 9143 // We already did the pre boot receiver for this app with the current 9144 // platform version, so don't do it again... 9145 ris.remove(i); 9146 i--; 9147 // ...however, do keep it as one that has been done, so we don't 9148 // forget about it when rewriting the file of last done receivers. 9149 doneReceivers.add(comp); 9150 } 9151 } 9152 9153 final int[] users = getUsersLocked(); 9154 for (int i=0; i<ris.size(); i++) { 9155 ActivityInfo ai = ris.get(i).activityInfo; 9156 ComponentName comp = new ComponentName(ai.packageName, ai.name); 9157 doneReceivers.add(comp); 9158 intent.setComponent(comp); 9159 for (int j=0; j<users.length; j++) { 9160 IIntentReceiver finisher = null; 9161 if (i == ris.size()-1 && j == users.length-1) { 9162 finisher = new IIntentReceiver.Stub() { 9163 public void performReceive(Intent intent, int resultCode, 9164 String data, Bundle extras, boolean ordered, 9165 boolean sticky, int sendingUser) { 9166 // The raw IIntentReceiver interface is called 9167 // with the AM lock held, so redispatch to 9168 // execute our code without the lock. 9169 mHandler.post(new Runnable() { 9170 public void run() { 9171 synchronized (ActivityManagerService.this) { 9172 mDidUpdate = true; 9173 } 9174 writeLastDonePreBootReceivers(doneReceivers); 9175 showBootMessage(mContext.getText( 9176 R.string.android_upgrading_complete), 9177 false); 9178 systemReady(goingCallback); 9179 } 9180 }); 9181 } 9182 }; 9183 } 9184 Slog.i(TAG, "Sending system update to " + intent.getComponent() 9185 + " for user " + users[j]); 9186 broadcastIntentLocked(null, null, intent, null, finisher, 9187 0, null, null, null, AppOpsManager.OP_NONE, 9188 true, false, MY_PID, Process.SYSTEM_UID, 9189 users[j]); 9190 if (finisher != null) { 9191 mWaitingUpdate = true; 9192 } 9193 } 9194 } 9195 } 9196 if (mWaitingUpdate) { 9197 return; 9198 } 9199 mDidUpdate = true; 9200 } 9201 9202 mAppOpsService.systemReady(); 9203 mSystemReady = true; 9204 } 9205 9206 ArrayList<ProcessRecord> procsToKill = null; 9207 synchronized(mPidsSelfLocked) { 9208 for (int i=mPidsSelfLocked.size()-1; i>=0; i--) { 9209 ProcessRecord proc = mPidsSelfLocked.valueAt(i); 9210 if (!isAllowedWhileBooting(proc.info)){ 9211 if (procsToKill == null) { 9212 procsToKill = new ArrayList<ProcessRecord>(); 9213 } 9214 procsToKill.add(proc); 9215 } 9216 } 9217 } 9218 9219 synchronized(this) { 9220 if (procsToKill != null) { 9221 for (int i=procsToKill.size()-1; i>=0; i--) { 9222 ProcessRecord proc = procsToKill.get(i); 9223 Slog.i(TAG, "Removing system update proc: " + proc); 9224 removeProcessLocked(proc, true, false, "system update done"); 9225 } 9226 } 9227 9228 // Now that we have cleaned up any update processes, we 9229 // are ready to start launching real processes and know that 9230 // we won't trample on them any more. 9231 mProcessesReady = true; 9232 } 9233 9234 Slog.i(TAG, "System now ready"); 9235 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY, 9236 SystemClock.uptimeMillis()); 9237 9238 synchronized(this) { 9239 // Make sure we have no pre-ready processes sitting around. 9240 9241 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) { 9242 ResolveInfo ri = mContext.getPackageManager() 9243 .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST), 9244 STOCK_PM_FLAGS); 9245 CharSequence errorMsg = null; 9246 if (ri != null) { 9247 ActivityInfo ai = ri.activityInfo; 9248 ApplicationInfo app = ai.applicationInfo; 9249 if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) { 9250 mTopAction = Intent.ACTION_FACTORY_TEST; 9251 mTopData = null; 9252 mTopComponent = new ComponentName(app.packageName, 9253 ai.name); 9254 } else { 9255 errorMsg = mContext.getResources().getText( 9256 com.android.internal.R.string.factorytest_not_system); 9257 } 9258 } else { 9259 errorMsg = mContext.getResources().getText( 9260 com.android.internal.R.string.factorytest_no_action); 9261 } 9262 if (errorMsg != null) { 9263 mTopAction = null; 9264 mTopData = null; 9265 mTopComponent = null; 9266 Message msg = Message.obtain(); 9267 msg.what = SHOW_FACTORY_ERROR_MSG; 9268 msg.getData().putCharSequence("msg", errorMsg); 9269 mHandler.sendMessage(msg); 9270 } 9271 } 9272 } 9273 9274 retrieveSettings(); 9275 9276 synchronized (this) { 9277 readGrantedUriPermissionsLocked(); 9278 } 9279 9280 if (goingCallback != null) goingCallback.run(); 9281 9282 synchronized (this) { 9283 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 9284 try { 9285 List apps = AppGlobals.getPackageManager(). 9286 getPersistentApplications(STOCK_PM_FLAGS); 9287 if (apps != null) { 9288 int N = apps.size(); 9289 int i; 9290 for (i=0; i<N; i++) { 9291 ApplicationInfo info 9292 = (ApplicationInfo)apps.get(i); 9293 if (info != null && 9294 !info.packageName.equals("android")) { 9295 addAppLocked(info, false); 9296 } 9297 } 9298 } 9299 } catch (RemoteException ex) { 9300 // pm is in same process, this will never happen. 9301 } 9302 } 9303 9304 // Start up initial activity. 9305 mBooting = true; 9306 9307 try { 9308 if (AppGlobals.getPackageManager().hasSystemUidErrors()) { 9309 Message msg = Message.obtain(); 9310 msg.what = SHOW_UID_ERROR_MSG; 9311 mHandler.sendMessage(msg); 9312 } 9313 } catch (RemoteException e) { 9314 } 9315 9316 long ident = Binder.clearCallingIdentity(); 9317 try { 9318 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 9319 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 9320 | Intent.FLAG_RECEIVER_FOREGROUND); 9321 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); 9322 broadcastIntentLocked(null, null, intent, 9323 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 9324 false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId); 9325 intent = new Intent(Intent.ACTION_USER_STARTING); 9326 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 9327 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); 9328 broadcastIntentLocked(null, null, intent, 9329 null, new IIntentReceiver.Stub() { 9330 @Override 9331 public void performReceive(Intent intent, int resultCode, String data, 9332 Bundle extras, boolean ordered, boolean sticky, int sendingUser) 9333 throws RemoteException { 9334 } 9335 }, 0, null, null, 9336 android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 9337 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 9338 } finally { 9339 Binder.restoreCallingIdentity(ident); 9340 } 9341 mStackSupervisor.resumeTopActivitiesLocked(); 9342 sendUserSwitchBroadcastsLocked(-1, mCurrentUserId); 9343 } 9344 } 9345 9346 private boolean makeAppCrashingLocked(ProcessRecord app, 9347 String shortMsg, String longMsg, String stackTrace) { 9348 app.crashing = true; 9349 app.crashingReport = generateProcessError(app, 9350 ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace); 9351 startAppProblemLocked(app); 9352 app.stopFreezingAllLocked(); 9353 return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace); 9354 } 9355 9356 private void makeAppNotRespondingLocked(ProcessRecord app, 9357 String activity, String shortMsg, String longMsg) { 9358 app.notResponding = true; 9359 app.notRespondingReport = generateProcessError(app, 9360 ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING, 9361 activity, shortMsg, longMsg, null); 9362 startAppProblemLocked(app); 9363 app.stopFreezingAllLocked(); 9364 } 9365 9366 /** 9367 * Generate a process error record, suitable for attachment to a ProcessRecord. 9368 * 9369 * @param app The ProcessRecord in which the error occurred. 9370 * @param condition Crashing, Application Not Responding, etc. Values are defined in 9371 * ActivityManager.AppErrorStateInfo 9372 * @param activity The activity associated with the crash, if known. 9373 * @param shortMsg Short message describing the crash. 9374 * @param longMsg Long message describing the crash. 9375 * @param stackTrace Full crash stack trace, may be null. 9376 * 9377 * @return Returns a fully-formed AppErrorStateInfo record. 9378 */ 9379 private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app, 9380 int condition, String activity, String shortMsg, String longMsg, String stackTrace) { 9381 ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo(); 9382 9383 report.condition = condition; 9384 report.processName = app.processName; 9385 report.pid = app.pid; 9386 report.uid = app.info.uid; 9387 report.tag = activity; 9388 report.shortMsg = shortMsg; 9389 report.longMsg = longMsg; 9390 report.stackTrace = stackTrace; 9391 9392 return report; 9393 } 9394 9395 void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) { 9396 synchronized (this) { 9397 app.crashing = false; 9398 app.crashingReport = null; 9399 app.notResponding = false; 9400 app.notRespondingReport = null; 9401 if (app.anrDialog == fromDialog) { 9402 app.anrDialog = null; 9403 } 9404 if (app.waitDialog == fromDialog) { 9405 app.waitDialog = null; 9406 } 9407 if (app.pid > 0 && app.pid != MY_PID) { 9408 handleAppCrashLocked(app, null, null, null); 9409 killUnneededProcessLocked(app, "user request after error"); 9410 } 9411 } 9412 } 9413 9414 private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg, 9415 String stackTrace) { 9416 long now = SystemClock.uptimeMillis(); 9417 9418 Long crashTime; 9419 if (!app.isolated) { 9420 crashTime = mProcessCrashTimes.get(app.info.processName, app.uid); 9421 } else { 9422 crashTime = null; 9423 } 9424 if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) { 9425 // This process loses! 9426 Slog.w(TAG, "Process " + app.info.processName 9427 + " has crashed too many times: killing!"); 9428 EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH, 9429 app.userId, app.info.processName, app.uid); 9430 mStackSupervisor.handleAppCrashLocked(app); 9431 if (!app.persistent) { 9432 // We don't want to start this process again until the user 9433 // explicitly does so... but for persistent process, we really 9434 // need to keep it running. If a persistent process is actually 9435 // repeatedly crashing, then badness for everyone. 9436 EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid, 9437 app.info.processName); 9438 if (!app.isolated) { 9439 // XXX We don't have a way to mark isolated processes 9440 // as bad, since they don't have a peristent identity. 9441 mBadProcesses.put(app.info.processName, app.uid, 9442 new BadProcessInfo(now, shortMsg, longMsg, stackTrace)); 9443 mProcessCrashTimes.remove(app.info.processName, app.uid); 9444 } 9445 app.bad = true; 9446 app.removed = true; 9447 // Don't let services in this process be restarted and potentially 9448 // annoy the user repeatedly. Unless it is persistent, since those 9449 // processes run critical code. 9450 removeProcessLocked(app, false, false, "crash"); 9451 mStackSupervisor.resumeTopActivitiesLocked(); 9452 return false; 9453 } 9454 mStackSupervisor.resumeTopActivitiesLocked(); 9455 } else { 9456 mStackSupervisor.finishTopRunningActivityLocked(app); 9457 } 9458 9459 // Bump up the crash count of any services currently running in the proc. 9460 for (int i=app.services.size()-1; i>=0; i--) { 9461 // Any services running in the application need to be placed 9462 // back in the pending list. 9463 ServiceRecord sr = app.services.valueAt(i); 9464 sr.crashCount++; 9465 } 9466 9467 // If the crashing process is what we consider to be the "home process" and it has been 9468 // replaced by a third-party app, clear the package preferred activities from packages 9469 // with a home activity running in the process to prevent a repeatedly crashing app 9470 // from blocking the user to manually clear the list. 9471 final ArrayList<ActivityRecord> activities = app.activities; 9472 if (app == mHomeProcess && activities.size() > 0 9473 && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) { 9474 for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) { 9475 final ActivityRecord r = activities.get(activityNdx); 9476 if (r.isHomeActivity()) { 9477 Log.i(TAG, "Clearing package preferred activities from " + r.packageName); 9478 try { 9479 ActivityThread.getPackageManager() 9480 .clearPackagePreferredActivities(r.packageName); 9481 } catch (RemoteException c) { 9482 // pm is in same process, this will never happen. 9483 } 9484 } 9485 } 9486 } 9487 9488 if (!app.isolated) { 9489 // XXX Can't keep track of crash times for isolated processes, 9490 // because they don't have a perisistent identity. 9491 mProcessCrashTimes.put(app.info.processName, app.uid, now); 9492 } 9493 9494 return true; 9495 } 9496 9497 void startAppProblemLocked(ProcessRecord app) { 9498 if (app.userId == mCurrentUserId) { 9499 app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver( 9500 mContext, app.info.packageName, app.info.flags); 9501 } else { 9502 // If this app is not running under the current user, then we 9503 // can't give it a report button because that would require 9504 // launching the report UI under a different user. 9505 app.errorReportReceiver = null; 9506 } 9507 skipCurrentReceiverLocked(app); 9508 } 9509 9510 void skipCurrentReceiverLocked(ProcessRecord app) { 9511 for (BroadcastQueue queue : mBroadcastQueues) { 9512 queue.skipCurrentReceiverLocked(app); 9513 } 9514 } 9515 9516 /** 9517 * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes. 9518 * The application process will exit immediately after this call returns. 9519 * @param app object of the crashing app, null for the system server 9520 * @param crashInfo describing the exception 9521 */ 9522 public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) { 9523 ProcessRecord r = findAppProcess(app, "Crash"); 9524 final String processName = app == null ? "system_server" 9525 : (r == null ? "unknown" : r.processName); 9526 9527 handleApplicationCrashInner("crash", r, processName, crashInfo); 9528 } 9529 9530 /* Native crash reporting uses this inner version because it needs to be somewhat 9531 * decoupled from the AM-managed cleanup lifecycle 9532 */ 9533 void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName, 9534 ApplicationErrorReport.CrashInfo crashInfo) { 9535 EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(), 9536 UserHandle.getUserId(Binder.getCallingUid()), processName, 9537 r == null ? -1 : r.info.flags, 9538 crashInfo.exceptionClassName, 9539 crashInfo.exceptionMessage, 9540 crashInfo.throwFileName, 9541 crashInfo.throwLineNumber); 9542 9543 addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo); 9544 9545 crashApplication(r, crashInfo); 9546 } 9547 9548 public void handleApplicationStrictModeViolation( 9549 IBinder app, 9550 int violationMask, 9551 StrictMode.ViolationInfo info) { 9552 ProcessRecord r = findAppProcess(app, "StrictMode"); 9553 if (r == null) { 9554 return; 9555 } 9556 9557 if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) { 9558 Integer stackFingerprint = info.hashCode(); 9559 boolean logIt = true; 9560 synchronized (mAlreadyLoggedViolatedStacks) { 9561 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) { 9562 logIt = false; 9563 // TODO: sub-sample into EventLog for these, with 9564 // the info.durationMillis? Then we'd get 9565 // the relative pain numbers, without logging all 9566 // the stack traces repeatedly. We'd want to do 9567 // likewise in the client code, which also does 9568 // dup suppression, before the Binder call. 9569 } else { 9570 if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) { 9571 mAlreadyLoggedViolatedStacks.clear(); 9572 } 9573 mAlreadyLoggedViolatedStacks.add(stackFingerprint); 9574 } 9575 } 9576 if (logIt) { 9577 logStrictModeViolationToDropBox(r, info); 9578 } 9579 } 9580 9581 if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) { 9582 AppErrorResult result = new AppErrorResult(); 9583 synchronized (this) { 9584 final long origId = Binder.clearCallingIdentity(); 9585 9586 Message msg = Message.obtain(); 9587 msg.what = SHOW_STRICT_MODE_VIOLATION_MSG; 9588 HashMap<String, Object> data = new HashMap<String, Object>(); 9589 data.put("result", result); 9590 data.put("app", r); 9591 data.put("violationMask", violationMask); 9592 data.put("info", info); 9593 msg.obj = data; 9594 mHandler.sendMessage(msg); 9595 9596 Binder.restoreCallingIdentity(origId); 9597 } 9598 int res = result.get(); 9599 Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res); 9600 } 9601 } 9602 9603 // Depending on the policy in effect, there could be a bunch of 9604 // these in quick succession so we try to batch these together to 9605 // minimize disk writes, number of dropbox entries, and maximize 9606 // compression, by having more fewer, larger records. 9607 private void logStrictModeViolationToDropBox( 9608 ProcessRecord process, 9609 StrictMode.ViolationInfo info) { 9610 if (info == null) { 9611 return; 9612 } 9613 final boolean isSystemApp = process == null || 9614 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM | 9615 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0; 9616 final String processName = process == null ? "unknown" : process.processName; 9617 final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode"; 9618 final DropBoxManager dbox = (DropBoxManager) 9619 mContext.getSystemService(Context.DROPBOX_SERVICE); 9620 9621 // Exit early if the dropbox isn't configured to accept this report type. 9622 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 9623 9624 boolean bufferWasEmpty; 9625 boolean needsFlush; 9626 final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024); 9627 synchronized (sb) { 9628 bufferWasEmpty = sb.length() == 0; 9629 appendDropBoxProcessHeaders(process, processName, sb); 9630 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 9631 sb.append("System-App: ").append(isSystemApp).append("\n"); 9632 sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n"); 9633 if (info.violationNumThisLoop != 0) { 9634 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n"); 9635 } 9636 if (info.numAnimationsRunning != 0) { 9637 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n"); 9638 } 9639 if (info.broadcastIntentAction != null) { 9640 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n"); 9641 } 9642 if (info.durationMillis != -1) { 9643 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n"); 9644 } 9645 if (info.numInstances != -1) { 9646 sb.append("Instance-Count: ").append(info.numInstances).append("\n"); 9647 } 9648 if (info.tags != null) { 9649 for (String tag : info.tags) { 9650 sb.append("Span-Tag: ").append(tag).append("\n"); 9651 } 9652 } 9653 sb.append("\n"); 9654 if (info.crashInfo != null && info.crashInfo.stackTrace != null) { 9655 sb.append(info.crashInfo.stackTrace); 9656 } 9657 sb.append("\n"); 9658 9659 // Only buffer up to ~64k. Various logging bits truncate 9660 // things at 128k. 9661 needsFlush = (sb.length() > 64 * 1024); 9662 } 9663 9664 // Flush immediately if the buffer's grown too large, or this 9665 // is a non-system app. Non-system apps are isolated with a 9666 // different tag & policy and not batched. 9667 // 9668 // Batching is useful during internal testing with 9669 // StrictMode settings turned up high. Without batching, 9670 // thousands of separate files could be created on boot. 9671 if (!isSystemApp || needsFlush) { 9672 new Thread("Error dump: " + dropboxTag) { 9673 @Override 9674 public void run() { 9675 String report; 9676 synchronized (sb) { 9677 report = sb.toString(); 9678 sb.delete(0, sb.length()); 9679 sb.trimToSize(); 9680 } 9681 if (report.length() != 0) { 9682 dbox.addText(dropboxTag, report); 9683 } 9684 } 9685 }.start(); 9686 return; 9687 } 9688 9689 // System app batching: 9690 if (!bufferWasEmpty) { 9691 // An existing dropbox-writing thread is outstanding, so 9692 // we don't need to start it up. The existing thread will 9693 // catch the buffer appends we just did. 9694 return; 9695 } 9696 9697 // Worker thread to both batch writes and to avoid blocking the caller on I/O. 9698 // (After this point, we shouldn't access AMS internal data structures.) 9699 new Thread("Error dump: " + dropboxTag) { 9700 @Override 9701 public void run() { 9702 // 5 second sleep to let stacks arrive and be batched together 9703 try { 9704 Thread.sleep(5000); // 5 seconds 9705 } catch (InterruptedException e) {} 9706 9707 String errorReport; 9708 synchronized (mStrictModeBuffer) { 9709 errorReport = mStrictModeBuffer.toString(); 9710 if (errorReport.length() == 0) { 9711 return; 9712 } 9713 mStrictModeBuffer.delete(0, mStrictModeBuffer.length()); 9714 mStrictModeBuffer.trimToSize(); 9715 } 9716 dbox.addText(dropboxTag, errorReport); 9717 } 9718 }.start(); 9719 } 9720 9721 /** 9722 * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors. 9723 * @param app object of the crashing app, null for the system server 9724 * @param tag reported by the caller 9725 * @param crashInfo describing the context of the error 9726 * @return true if the process should exit immediately (WTF is fatal) 9727 */ 9728 public boolean handleApplicationWtf(IBinder app, String tag, 9729 ApplicationErrorReport.CrashInfo crashInfo) { 9730 ProcessRecord r = findAppProcess(app, "WTF"); 9731 final String processName = app == null ? "system_server" 9732 : (r == null ? "unknown" : r.processName); 9733 9734 EventLog.writeEvent(EventLogTags.AM_WTF, 9735 UserHandle.getUserId(Binder.getCallingUid()), Binder.getCallingPid(), 9736 processName, 9737 r == null ? -1 : r.info.flags, 9738 tag, crashInfo.exceptionMessage); 9739 9740 addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo); 9741 9742 if (r != null && r.pid != Process.myPid() && 9743 Settings.Global.getInt(mContext.getContentResolver(), 9744 Settings.Global.WTF_IS_FATAL, 0) != 0) { 9745 crashApplication(r, crashInfo); 9746 return true; 9747 } else { 9748 return false; 9749 } 9750 } 9751 9752 /** 9753 * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit}) 9754 * @return the corresponding {@link ProcessRecord} object, or null if none could be found 9755 */ 9756 private ProcessRecord findAppProcess(IBinder app, String reason) { 9757 if (app == null) { 9758 return null; 9759 } 9760 9761 synchronized (this) { 9762 final int NP = mProcessNames.getMap().size(); 9763 for (int ip=0; ip<NP; ip++) { 9764 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 9765 final int NA = apps.size(); 9766 for (int ia=0; ia<NA; ia++) { 9767 ProcessRecord p = apps.valueAt(ia); 9768 if (p.thread != null && p.thread.asBinder() == app) { 9769 return p; 9770 } 9771 } 9772 } 9773 9774 Slog.w(TAG, "Can't find mystery application for " + reason 9775 + " from pid=" + Binder.getCallingPid() 9776 + " uid=" + Binder.getCallingUid() + ": " + app); 9777 return null; 9778 } 9779 } 9780 9781 /** 9782 * Utility function for addErrorToDropBox and handleStrictModeViolation's logging 9783 * to append various headers to the dropbox log text. 9784 */ 9785 private void appendDropBoxProcessHeaders(ProcessRecord process, String processName, 9786 StringBuilder sb) { 9787 // Watchdog thread ends up invoking this function (with 9788 // a null ProcessRecord) to add the stack file to dropbox. 9789 // Do not acquire a lock on this (am) in such cases, as it 9790 // could cause a potential deadlock, if and when watchdog 9791 // is invoked due to unavailability of lock on am and it 9792 // would prevent watchdog from killing system_server. 9793 if (process == null) { 9794 sb.append("Process: ").append(processName).append("\n"); 9795 return; 9796 } 9797 // Note: ProcessRecord 'process' is guarded by the service 9798 // instance. (notably process.pkgList, which could otherwise change 9799 // concurrently during execution of this method) 9800 synchronized (this) { 9801 sb.append("Process: ").append(processName).append("\n"); 9802 int flags = process.info.flags; 9803 IPackageManager pm = AppGlobals.getPackageManager(); 9804 sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n"); 9805 for (int ip=0; ip<process.pkgList.size(); ip++) { 9806 String pkg = process.pkgList.keyAt(ip); 9807 sb.append("Package: ").append(pkg); 9808 try { 9809 PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId()); 9810 if (pi != null) { 9811 sb.append(" v").append(pi.versionCode); 9812 if (pi.versionName != null) { 9813 sb.append(" (").append(pi.versionName).append(")"); 9814 } 9815 } 9816 } catch (RemoteException e) { 9817 Slog.e(TAG, "Error getting package info: " + pkg, e); 9818 } 9819 sb.append("\n"); 9820 } 9821 } 9822 } 9823 9824 private static String processClass(ProcessRecord process) { 9825 if (process == null || process.pid == MY_PID) { 9826 return "system_server"; 9827 } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) { 9828 return "system_app"; 9829 } else { 9830 return "data_app"; 9831 } 9832 } 9833 9834 /** 9835 * Write a description of an error (crash, WTF, ANR) to the drop box. 9836 * @param eventType to include in the drop box tag ("crash", "wtf", etc.) 9837 * @param process which caused the error, null means the system server 9838 * @param activity which triggered the error, null if unknown 9839 * @param parent activity related to the error, null if unknown 9840 * @param subject line related to the error, null if absent 9841 * @param report in long form describing the error, null if absent 9842 * @param logFile to include in the report, null if none 9843 * @param crashInfo giving an application stack trace, null if absent 9844 */ 9845 public void addErrorToDropBox(String eventType, 9846 ProcessRecord process, String processName, ActivityRecord activity, 9847 ActivityRecord parent, String subject, 9848 final String report, final File logFile, 9849 final ApplicationErrorReport.CrashInfo crashInfo) { 9850 // NOTE -- this must never acquire the ActivityManagerService lock, 9851 // otherwise the watchdog may be prevented from resetting the system. 9852 9853 final String dropboxTag = processClass(process) + "_" + eventType; 9854 final DropBoxManager dbox = (DropBoxManager) 9855 mContext.getSystemService(Context.DROPBOX_SERVICE); 9856 9857 // Exit early if the dropbox isn't configured to accept this report type. 9858 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 9859 9860 final StringBuilder sb = new StringBuilder(1024); 9861 appendDropBoxProcessHeaders(process, processName, sb); 9862 if (activity != null) { 9863 sb.append("Activity: ").append(activity.shortComponentName).append("\n"); 9864 } 9865 if (parent != null && parent.app != null && parent.app.pid != process.pid) { 9866 sb.append("Parent-Process: ").append(parent.app.processName).append("\n"); 9867 } 9868 if (parent != null && parent != activity) { 9869 sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n"); 9870 } 9871 if (subject != null) { 9872 sb.append("Subject: ").append(subject).append("\n"); 9873 } 9874 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 9875 if (Debug.isDebuggerConnected()) { 9876 sb.append("Debugger: Connected\n"); 9877 } 9878 sb.append("\n"); 9879 9880 // Do the rest in a worker thread to avoid blocking the caller on I/O 9881 // (After this point, we shouldn't access AMS internal data structures.) 9882 Thread worker = new Thread("Error dump: " + dropboxTag) { 9883 @Override 9884 public void run() { 9885 if (report != null) { 9886 sb.append(report); 9887 } 9888 if (logFile != null) { 9889 try { 9890 sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE, 9891 "\n\n[[TRUNCATED]]")); 9892 } catch (IOException e) { 9893 Slog.e(TAG, "Error reading " + logFile, e); 9894 } 9895 } 9896 if (crashInfo != null && crashInfo.stackTrace != null) { 9897 sb.append(crashInfo.stackTrace); 9898 } 9899 9900 String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag; 9901 int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0); 9902 if (lines > 0) { 9903 sb.append("\n"); 9904 9905 // Merge several logcat streams, and take the last N lines 9906 InputStreamReader input = null; 9907 try { 9908 java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat", 9909 "-v", "time", "-b", "events", "-b", "system", "-b", "main", 9910 "-t", String.valueOf(lines)).redirectErrorStream(true).start(); 9911 9912 try { logcat.getOutputStream().close(); } catch (IOException e) {} 9913 try { logcat.getErrorStream().close(); } catch (IOException e) {} 9914 input = new InputStreamReader(logcat.getInputStream()); 9915 9916 int num; 9917 char[] buf = new char[8192]; 9918 while ((num = input.read(buf)) > 0) sb.append(buf, 0, num); 9919 } catch (IOException e) { 9920 Slog.e(TAG, "Error running logcat", e); 9921 } finally { 9922 if (input != null) try { input.close(); } catch (IOException e) {} 9923 } 9924 } 9925 9926 dbox.addText(dropboxTag, sb.toString()); 9927 } 9928 }; 9929 9930 if (process == null) { 9931 // If process is null, we are being called from some internal code 9932 // and may be about to die -- run this synchronously. 9933 worker.run(); 9934 } else { 9935 worker.start(); 9936 } 9937 } 9938 9939 /** 9940 * Bring up the "unexpected error" dialog box for a crashing app. 9941 * Deal with edge cases (intercepts from instrumented applications, 9942 * ActivityController, error intent receivers, that sort of thing). 9943 * @param r the application crashing 9944 * @param crashInfo describing the failure 9945 */ 9946 private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) { 9947 long timeMillis = System.currentTimeMillis(); 9948 String shortMsg = crashInfo.exceptionClassName; 9949 String longMsg = crashInfo.exceptionMessage; 9950 String stackTrace = crashInfo.stackTrace; 9951 if (shortMsg != null && longMsg != null) { 9952 longMsg = shortMsg + ": " + longMsg; 9953 } else if (shortMsg != null) { 9954 longMsg = shortMsg; 9955 } 9956 9957 AppErrorResult result = new AppErrorResult(); 9958 synchronized (this) { 9959 if (mController != null) { 9960 try { 9961 String name = r != null ? r.processName : null; 9962 int pid = r != null ? r.pid : Binder.getCallingPid(); 9963 if (!mController.appCrashed(name, pid, 9964 shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) { 9965 Slog.w(TAG, "Force-killing crashed app " + name 9966 + " at watcher's request"); 9967 Process.killProcess(pid); 9968 return; 9969 } 9970 } catch (RemoteException e) { 9971 mController = null; 9972 Watchdog.getInstance().setActivityController(null); 9973 } 9974 } 9975 9976 final long origId = Binder.clearCallingIdentity(); 9977 9978 // If this process is running instrumentation, finish it. 9979 if (r != null && r.instrumentationClass != null) { 9980 Slog.w(TAG, "Error in app " + r.processName 9981 + " running instrumentation " + r.instrumentationClass + ":"); 9982 if (shortMsg != null) Slog.w(TAG, " " + shortMsg); 9983 if (longMsg != null) Slog.w(TAG, " " + longMsg); 9984 Bundle info = new Bundle(); 9985 info.putString("shortMsg", shortMsg); 9986 info.putString("longMsg", longMsg); 9987 finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info); 9988 Binder.restoreCallingIdentity(origId); 9989 return; 9990 } 9991 9992 // If we can't identify the process or it's already exceeded its crash quota, 9993 // quit right away without showing a crash dialog. 9994 if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) { 9995 Binder.restoreCallingIdentity(origId); 9996 return; 9997 } 9998 9999 Message msg = Message.obtain(); 10000 msg.what = SHOW_ERROR_MSG; 10001 HashMap data = new HashMap(); 10002 data.put("result", result); 10003 data.put("app", r); 10004 msg.obj = data; 10005 mHandler.sendMessage(msg); 10006 10007 Binder.restoreCallingIdentity(origId); 10008 } 10009 10010 int res = result.get(); 10011 10012 Intent appErrorIntent = null; 10013 synchronized (this) { 10014 if (r != null && !r.isolated) { 10015 // XXX Can't keep track of crash time for isolated processes, 10016 // since they don't have a persistent identity. 10017 mProcessCrashTimes.put(r.info.processName, r.uid, 10018 SystemClock.uptimeMillis()); 10019 } 10020 if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) { 10021 appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo); 10022 } 10023 } 10024 10025 if (appErrorIntent != null) { 10026 try { 10027 mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId)); 10028 } catch (ActivityNotFoundException e) { 10029 Slog.w(TAG, "bug report receiver dissappeared", e); 10030 } 10031 } 10032 } 10033 10034 Intent createAppErrorIntentLocked(ProcessRecord r, 10035 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 10036 ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo); 10037 if (report == null) { 10038 return null; 10039 } 10040 Intent result = new Intent(Intent.ACTION_APP_ERROR); 10041 result.setComponent(r.errorReportReceiver); 10042 result.putExtra(Intent.EXTRA_BUG_REPORT, report); 10043 result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 10044 return result; 10045 } 10046 10047 private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r, 10048 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 10049 if (r.errorReportReceiver == null) { 10050 return null; 10051 } 10052 10053 if (!r.crashing && !r.notResponding && !r.forceCrashReport) { 10054 return null; 10055 } 10056 10057 ApplicationErrorReport report = new ApplicationErrorReport(); 10058 report.packageName = r.info.packageName; 10059 report.installerPackageName = r.errorReportReceiver.getPackageName(); 10060 report.processName = r.processName; 10061 report.time = timeMillis; 10062 report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0; 10063 10064 if (r.crashing || r.forceCrashReport) { 10065 report.type = ApplicationErrorReport.TYPE_CRASH; 10066 report.crashInfo = crashInfo; 10067 } else if (r.notResponding) { 10068 report.type = ApplicationErrorReport.TYPE_ANR; 10069 report.anrInfo = new ApplicationErrorReport.AnrInfo(); 10070 10071 report.anrInfo.activity = r.notRespondingReport.tag; 10072 report.anrInfo.cause = r.notRespondingReport.shortMsg; 10073 report.anrInfo.info = r.notRespondingReport.longMsg; 10074 } 10075 10076 return report; 10077 } 10078 10079 public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() { 10080 enforceNotIsolatedCaller("getProcessesInErrorState"); 10081 // assume our apps are happy - lazy create the list 10082 List<ActivityManager.ProcessErrorStateInfo> errList = null; 10083 10084 final boolean allUsers = ActivityManager.checkUidPermission( 10085 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 10086 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 10087 int userId = UserHandle.getUserId(Binder.getCallingUid()); 10088 10089 synchronized (this) { 10090 10091 // iterate across all processes 10092 for (int i=mLruProcesses.size()-1; i>=0; i--) { 10093 ProcessRecord app = mLruProcesses.get(i); 10094 if (!allUsers && app.userId != userId) { 10095 continue; 10096 } 10097 if ((app.thread != null) && (app.crashing || app.notResponding)) { 10098 // This one's in trouble, so we'll generate a report for it 10099 // crashes are higher priority (in case there's a crash *and* an anr) 10100 ActivityManager.ProcessErrorStateInfo report = null; 10101 if (app.crashing) { 10102 report = app.crashingReport; 10103 } else if (app.notResponding) { 10104 report = app.notRespondingReport; 10105 } 10106 10107 if (report != null) { 10108 if (errList == null) { 10109 errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1); 10110 } 10111 errList.add(report); 10112 } else { 10113 Slog.w(TAG, "Missing app error report, app = " + app.processName + 10114 " crashing = " + app.crashing + 10115 " notResponding = " + app.notResponding); 10116 } 10117 } 10118 } 10119 } 10120 10121 return errList; 10122 } 10123 10124 static int oomAdjToImportance(int adj, ActivityManager.RunningAppProcessInfo currApp) { 10125 if (adj >= ProcessList.CACHED_APP_MIN_ADJ) { 10126 if (currApp != null) { 10127 currApp.lru = adj - ProcessList.CACHED_APP_MIN_ADJ + 1; 10128 } 10129 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 10130 } else if (adj >= ProcessList.SERVICE_B_ADJ) { 10131 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 10132 } else if (adj >= ProcessList.HOME_APP_ADJ) { 10133 if (currApp != null) { 10134 currApp.lru = 0; 10135 } 10136 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 10137 } else if (adj >= ProcessList.SERVICE_ADJ) { 10138 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 10139 } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 10140 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE; 10141 } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) { 10142 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE; 10143 } else if (adj >= ProcessList.VISIBLE_APP_ADJ) { 10144 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE; 10145 } else { 10146 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND; 10147 } 10148 } 10149 10150 private void fillInProcMemInfo(ProcessRecord app, 10151 ActivityManager.RunningAppProcessInfo outInfo) { 10152 outInfo.pid = app.pid; 10153 outInfo.uid = app.info.uid; 10154 if (mHeavyWeightProcess == app) { 10155 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE; 10156 } 10157 if (app.persistent) { 10158 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT; 10159 } 10160 if (app.activities.size() > 0) { 10161 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES; 10162 } 10163 outInfo.lastTrimLevel = app.trimMemoryLevel; 10164 int adj = app.curAdj; 10165 outInfo.importance = oomAdjToImportance(adj, outInfo); 10166 outInfo.importanceReasonCode = app.adjTypeCode; 10167 } 10168 10169 public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() { 10170 enforceNotIsolatedCaller("getRunningAppProcesses"); 10171 // Lazy instantiation of list 10172 List<ActivityManager.RunningAppProcessInfo> runList = null; 10173 final boolean allUsers = ActivityManager.checkUidPermission( 10174 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 10175 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 10176 int userId = UserHandle.getUserId(Binder.getCallingUid()); 10177 synchronized (this) { 10178 // Iterate across all processes 10179 for (int i=mLruProcesses.size()-1; i>=0; i--) { 10180 ProcessRecord app = mLruProcesses.get(i); 10181 if (!allUsers && app.userId != userId) { 10182 continue; 10183 } 10184 if ((app.thread != null) && (!app.crashing && !app.notResponding)) { 10185 // Generate process state info for running application 10186 ActivityManager.RunningAppProcessInfo currApp = 10187 new ActivityManager.RunningAppProcessInfo(app.processName, 10188 app.pid, app.getPackageList()); 10189 fillInProcMemInfo(app, currApp); 10190 if (app.adjSource instanceof ProcessRecord) { 10191 currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid; 10192 currApp.importanceReasonImportance = oomAdjToImportance( 10193 app.adjSourceOom, null); 10194 } else if (app.adjSource instanceof ActivityRecord) { 10195 ActivityRecord r = (ActivityRecord)app.adjSource; 10196 if (r.app != null) currApp.importanceReasonPid = r.app.pid; 10197 } 10198 if (app.adjTarget instanceof ComponentName) { 10199 currApp.importanceReasonComponent = (ComponentName)app.adjTarget; 10200 } 10201 //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance 10202 // + " lru=" + currApp.lru); 10203 if (runList == null) { 10204 runList = new ArrayList<ActivityManager.RunningAppProcessInfo>(); 10205 } 10206 runList.add(currApp); 10207 } 10208 } 10209 } 10210 return runList; 10211 } 10212 10213 public List<ApplicationInfo> getRunningExternalApplications() { 10214 enforceNotIsolatedCaller("getRunningExternalApplications"); 10215 List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses(); 10216 List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>(); 10217 if (runningApps != null && runningApps.size() > 0) { 10218 Set<String> extList = new HashSet<String>(); 10219 for (ActivityManager.RunningAppProcessInfo app : runningApps) { 10220 if (app.pkgList != null) { 10221 for (String pkg : app.pkgList) { 10222 extList.add(pkg); 10223 } 10224 } 10225 } 10226 IPackageManager pm = AppGlobals.getPackageManager(); 10227 for (String pkg : extList) { 10228 try { 10229 ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId()); 10230 if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) { 10231 retList.add(info); 10232 } 10233 } catch (RemoteException e) { 10234 } 10235 } 10236 } 10237 return retList; 10238 } 10239 10240 @Override 10241 public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) { 10242 enforceNotIsolatedCaller("getMyMemoryState"); 10243 synchronized (this) { 10244 ProcessRecord proc; 10245 synchronized (mPidsSelfLocked) { 10246 proc = mPidsSelfLocked.get(Binder.getCallingPid()); 10247 } 10248 fillInProcMemInfo(proc, outInfo); 10249 } 10250 } 10251 10252 @Override 10253 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 10254 if (checkCallingPermission(android.Manifest.permission.DUMP) 10255 != PackageManager.PERMISSION_GRANTED) { 10256 pw.println("Permission Denial: can't dump ActivityManager from from pid=" 10257 + Binder.getCallingPid() 10258 + ", uid=" + Binder.getCallingUid() 10259 + " without permission " 10260 + android.Manifest.permission.DUMP); 10261 return; 10262 } 10263 10264 boolean dumpAll = false; 10265 boolean dumpClient = false; 10266 String dumpPackage = null; 10267 10268 int opti = 0; 10269 while (opti < args.length) { 10270 String opt = args[opti]; 10271 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 10272 break; 10273 } 10274 opti++; 10275 if ("-a".equals(opt)) { 10276 dumpAll = true; 10277 } else if ("-c".equals(opt)) { 10278 dumpClient = true; 10279 } else if ("-h".equals(opt)) { 10280 pw.println("Activity manager dump options:"); 10281 pw.println(" [-a] [-c] [-h] [cmd] ..."); 10282 pw.println(" cmd may be one of:"); 10283 pw.println(" a[ctivities]: activity stack state"); 10284 pw.println(" b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state"); 10285 pw.println(" i[ntents] [PACKAGE_NAME]: pending intent state"); 10286 pw.println(" p[rocesses] [PACKAGE_NAME]: process state"); 10287 pw.println(" o[om]: out of memory management"); 10288 pw.println(" prov[iders] [COMP_SPEC ...]: content provider state"); 10289 pw.println(" provider [COMP_SPEC]: provider client-side state"); 10290 pw.println(" s[ervices] [COMP_SPEC ...]: service state"); 10291 pw.println(" service [COMP_SPEC]: service client-side state"); 10292 pw.println(" package [PACKAGE_NAME]: all state related to given package"); 10293 pw.println(" all: dump all activities"); 10294 pw.println(" top: dump the top activity"); 10295 pw.println(" cmd may also be a COMP_SPEC to dump activities."); 10296 pw.println(" COMP_SPEC may be a component name (com.foo/.myApp),"); 10297 pw.println(" a partial substring in a component name, a"); 10298 pw.println(" hex object identifier."); 10299 pw.println(" -a: include all available server state."); 10300 pw.println(" -c: include client state."); 10301 return; 10302 } else { 10303 pw.println("Unknown argument: " + opt + "; use -h for help"); 10304 } 10305 } 10306 10307 long origId = Binder.clearCallingIdentity(); 10308 boolean more = false; 10309 // Is the caller requesting to dump a particular piece of data? 10310 if (opti < args.length) { 10311 String cmd = args[opti]; 10312 opti++; 10313 if ("activities".equals(cmd) || "a".equals(cmd)) { 10314 synchronized (this) { 10315 dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null); 10316 } 10317 } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) { 10318 String[] newArgs; 10319 String name; 10320 if (opti >= args.length) { 10321 name = null; 10322 newArgs = EMPTY_STRING_ARRAY; 10323 } else { 10324 name = args[opti]; 10325 opti++; 10326 newArgs = new String[args.length - opti]; 10327 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 10328 args.length - opti); 10329 } 10330 synchronized (this) { 10331 dumpBroadcastsLocked(fd, pw, args, opti, true, name); 10332 } 10333 } else if ("intents".equals(cmd) || "i".equals(cmd)) { 10334 String[] newArgs; 10335 String name; 10336 if (opti >= args.length) { 10337 name = null; 10338 newArgs = EMPTY_STRING_ARRAY; 10339 } else { 10340 name = args[opti]; 10341 opti++; 10342 newArgs = new String[args.length - opti]; 10343 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 10344 args.length - opti); 10345 } 10346 synchronized (this) { 10347 dumpPendingIntentsLocked(fd, pw, args, opti, true, name); 10348 } 10349 } else if ("processes".equals(cmd) || "p".equals(cmd)) { 10350 String[] newArgs; 10351 String name; 10352 if (opti >= args.length) { 10353 name = null; 10354 newArgs = EMPTY_STRING_ARRAY; 10355 } else { 10356 name = args[opti]; 10357 opti++; 10358 newArgs = new String[args.length - opti]; 10359 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 10360 args.length - opti); 10361 } 10362 synchronized (this) { 10363 dumpProcessesLocked(fd, pw, args, opti, true, name); 10364 } 10365 } else if ("oom".equals(cmd) || "o".equals(cmd)) { 10366 synchronized (this) { 10367 dumpOomLocked(fd, pw, args, opti, true); 10368 } 10369 } else if ("provider".equals(cmd)) { 10370 String[] newArgs; 10371 String name; 10372 if (opti >= args.length) { 10373 name = null; 10374 newArgs = EMPTY_STRING_ARRAY; 10375 } else { 10376 name = args[opti]; 10377 opti++; 10378 newArgs = new String[args.length - opti]; 10379 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti); 10380 } 10381 if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) { 10382 pw.println("No providers match: " + name); 10383 pw.println("Use -h for help."); 10384 } 10385 } else if ("providers".equals(cmd) || "prov".equals(cmd)) { 10386 synchronized (this) { 10387 dumpProvidersLocked(fd, pw, args, opti, true, null); 10388 } 10389 } else if ("service".equals(cmd)) { 10390 String[] newArgs; 10391 String name; 10392 if (opti >= args.length) { 10393 name = null; 10394 newArgs = EMPTY_STRING_ARRAY; 10395 } else { 10396 name = args[opti]; 10397 opti++; 10398 newArgs = new String[args.length - opti]; 10399 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 10400 args.length - opti); 10401 } 10402 if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) { 10403 pw.println("No services match: " + name); 10404 pw.println("Use -h for help."); 10405 } 10406 } else if ("package".equals(cmd)) { 10407 String[] newArgs; 10408 if (opti >= args.length) { 10409 pw.println("package: no package name specified"); 10410 pw.println("Use -h for help."); 10411 } else { 10412 dumpPackage = args[opti]; 10413 opti++; 10414 newArgs = new String[args.length - opti]; 10415 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 10416 args.length - opti); 10417 args = newArgs; 10418 opti = 0; 10419 more = true; 10420 } 10421 } else if ("services".equals(cmd) || "s".equals(cmd)) { 10422 synchronized (this) { 10423 mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null); 10424 } 10425 } else { 10426 // Dumping a single activity? 10427 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) { 10428 pw.println("Bad activity command, or no activities match: " + cmd); 10429 pw.println("Use -h for help."); 10430 } 10431 } 10432 if (!more) { 10433 Binder.restoreCallingIdentity(origId); 10434 return; 10435 } 10436 } 10437 10438 // No piece of data specified, dump everything. 10439 synchronized (this) { 10440 dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 10441 pw.println(); 10442 if (dumpAll) { 10443 pw.println("-------------------------------------------------------------------------------"); 10444 } 10445 dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 10446 pw.println(); 10447 if (dumpAll) { 10448 pw.println("-------------------------------------------------------------------------------"); 10449 } 10450 dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage); 10451 pw.println(); 10452 if (dumpAll) { 10453 pw.println("-------------------------------------------------------------------------------"); 10454 } 10455 mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 10456 pw.println(); 10457 if (dumpAll) { 10458 pw.println("-------------------------------------------------------------------------------"); 10459 } 10460 dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 10461 pw.println(); 10462 if (dumpAll) { 10463 pw.println("-------------------------------------------------------------------------------"); 10464 } 10465 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage); 10466 } 10467 Binder.restoreCallingIdentity(origId); 10468 } 10469 10470 void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 10471 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) { 10472 pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)"); 10473 10474 boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient, 10475 dumpPackage); 10476 boolean needSep = printedAnything; 10477 10478 boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity, 10479 dumpPackage, needSep, " mFocusedActivity: "); 10480 if (printed) { 10481 printedAnything = true; 10482 needSep = false; 10483 } 10484 10485 if (dumpPackage == null) { 10486 if (needSep) { 10487 pw.println(); 10488 } 10489 needSep = true; 10490 printedAnything = true; 10491 mStackSupervisor.dump(pw, " "); 10492 } 10493 10494 if (mRecentTasks.size() > 0) { 10495 boolean printedHeader = false; 10496 10497 final int N = mRecentTasks.size(); 10498 for (int i=0; i<N; i++) { 10499 TaskRecord tr = mRecentTasks.get(i); 10500 if (dumpPackage != null) { 10501 if (tr.realActivity == null || 10502 !dumpPackage.equals(tr.realActivity)) { 10503 continue; 10504 } 10505 } 10506 if (!printedHeader) { 10507 if (needSep) { 10508 pw.println(); 10509 } 10510 pw.println(" Recent tasks:"); 10511 printedHeader = true; 10512 printedAnything = true; 10513 } 10514 pw.print(" * Recent #"); pw.print(i); pw.print(": "); 10515 pw.println(tr); 10516 if (dumpAll) { 10517 mRecentTasks.get(i).dump(pw, " "); 10518 } 10519 } 10520 } 10521 10522 if (!printedAnything) { 10523 pw.println(" (nothing)"); 10524 } 10525 } 10526 10527 void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 10528 int opti, boolean dumpAll, String dumpPackage) { 10529 boolean needSep = false; 10530 boolean printedAnything = false; 10531 int numPers = 0; 10532 10533 pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)"); 10534 10535 if (dumpAll) { 10536 final int NP = mProcessNames.getMap().size(); 10537 for (int ip=0; ip<NP; ip++) { 10538 SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip); 10539 final int NA = procs.size(); 10540 for (int ia=0; ia<NA; ia++) { 10541 ProcessRecord r = procs.valueAt(ia); 10542 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 10543 continue; 10544 } 10545 if (!needSep) { 10546 pw.println(" All known processes:"); 10547 needSep = true; 10548 printedAnything = true; 10549 } 10550 pw.print(r.persistent ? " *PERS*" : " *APP*"); 10551 pw.print(" UID "); pw.print(procs.keyAt(ia)); 10552 pw.print(" "); pw.println(r); 10553 r.dump(pw, " "); 10554 if (r.persistent) { 10555 numPers++; 10556 } 10557 } 10558 } 10559 } 10560 10561 if (mIsolatedProcesses.size() > 0) { 10562 boolean printed = false; 10563 for (int i=0; i<mIsolatedProcesses.size(); i++) { 10564 ProcessRecord r = mIsolatedProcesses.valueAt(i); 10565 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 10566 continue; 10567 } 10568 if (!printed) { 10569 if (needSep) { 10570 pw.println(); 10571 } 10572 pw.println(" Isolated process list (sorted by uid):"); 10573 printedAnything = true; 10574 printed = true; 10575 needSep = true; 10576 } 10577 pw.println(String.format("%sIsolated #%2d: %s", 10578 " ", i, r.toString())); 10579 } 10580 } 10581 10582 if (mLruProcesses.size() > 0) { 10583 if (needSep) { 10584 pw.println(); 10585 } 10586 pw.print(" Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size()); 10587 pw.print(" total, non-act at "); 10588 pw.print(mLruProcesses.size()-mLruProcessActivityStart); 10589 pw.print(", non-svc at "); 10590 pw.print(mLruProcesses.size()-mLruProcessServiceStart); 10591 pw.println("):"); 10592 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", false, dumpPackage); 10593 needSep = true; 10594 printedAnything = true; 10595 } 10596 10597 if (dumpAll || dumpPackage != null) { 10598 synchronized (mPidsSelfLocked) { 10599 boolean printed = false; 10600 for (int i=0; i<mPidsSelfLocked.size(); i++) { 10601 ProcessRecord r = mPidsSelfLocked.valueAt(i); 10602 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 10603 continue; 10604 } 10605 if (!printed) { 10606 if (needSep) pw.println(); 10607 needSep = true; 10608 pw.println(" PID mappings:"); 10609 printed = true; 10610 printedAnything = true; 10611 } 10612 pw.print(" PID #"); pw.print(mPidsSelfLocked.keyAt(i)); 10613 pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i)); 10614 } 10615 } 10616 } 10617 10618 if (mForegroundProcesses.size() > 0) { 10619 synchronized (mPidsSelfLocked) { 10620 boolean printed = false; 10621 for (int i=0; i<mForegroundProcesses.size(); i++) { 10622 ProcessRecord r = mPidsSelfLocked.get( 10623 mForegroundProcesses.valueAt(i).pid); 10624 if (dumpPackage != null && (r == null 10625 || !r.pkgList.containsKey(dumpPackage))) { 10626 continue; 10627 } 10628 if (!printed) { 10629 if (needSep) pw.println(); 10630 needSep = true; 10631 pw.println(" Foreground Processes:"); 10632 printed = true; 10633 printedAnything = true; 10634 } 10635 pw.print(" PID #"); pw.print(mForegroundProcesses.keyAt(i)); 10636 pw.print(": "); pw.println(mForegroundProcesses.valueAt(i)); 10637 } 10638 } 10639 } 10640 10641 if (mPersistentStartingProcesses.size() > 0) { 10642 if (needSep) pw.println(); 10643 needSep = true; 10644 printedAnything = true; 10645 pw.println(" Persisent processes that are starting:"); 10646 dumpProcessList(pw, this, mPersistentStartingProcesses, " ", 10647 "Starting Norm", "Restarting PERS", dumpPackage); 10648 } 10649 10650 if (mRemovedProcesses.size() > 0) { 10651 if (needSep) pw.println(); 10652 needSep = true; 10653 printedAnything = true; 10654 pw.println(" Processes that are being removed:"); 10655 dumpProcessList(pw, this, mRemovedProcesses, " ", 10656 "Removed Norm", "Removed PERS", dumpPackage); 10657 } 10658 10659 if (mProcessesOnHold.size() > 0) { 10660 if (needSep) pw.println(); 10661 needSep = true; 10662 printedAnything = true; 10663 pw.println(" Processes that are on old until the system is ready:"); 10664 dumpProcessList(pw, this, mProcessesOnHold, " ", 10665 "OnHold Norm", "OnHold PERS", dumpPackage); 10666 } 10667 10668 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage); 10669 10670 if (mProcessCrashTimes.getMap().size() > 0) { 10671 boolean printed = false; 10672 long now = SystemClock.uptimeMillis(); 10673 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap(); 10674 final int NP = pmap.size(); 10675 for (int ip=0; ip<NP; ip++) { 10676 String pname = pmap.keyAt(ip); 10677 SparseArray<Long> uids = pmap.valueAt(ip); 10678 final int N = uids.size(); 10679 for (int i=0; i<N; i++) { 10680 int puid = uids.keyAt(i); 10681 ProcessRecord r = mProcessNames.get(pname, puid); 10682 if (dumpPackage != null && (r == null 10683 || !r.pkgList.containsKey(dumpPackage))) { 10684 continue; 10685 } 10686 if (!printed) { 10687 if (needSep) pw.println(); 10688 needSep = true; 10689 pw.println(" Time since processes crashed:"); 10690 printed = true; 10691 printedAnything = true; 10692 } 10693 pw.print(" Process "); pw.print(pname); 10694 pw.print(" uid "); pw.print(puid); 10695 pw.print(": last crashed "); 10696 TimeUtils.formatDuration(now-uids.valueAt(i), pw); 10697 pw.println(" ago"); 10698 } 10699 } 10700 } 10701 10702 if (mBadProcesses.getMap().size() > 0) { 10703 boolean printed = false; 10704 final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap(); 10705 final int NP = pmap.size(); 10706 for (int ip=0; ip<NP; ip++) { 10707 String pname = pmap.keyAt(ip); 10708 SparseArray<BadProcessInfo> uids = pmap.valueAt(ip); 10709 final int N = uids.size(); 10710 for (int i=0; i<N; i++) { 10711 int puid = uids.keyAt(i); 10712 ProcessRecord r = mProcessNames.get(pname, puid); 10713 if (dumpPackage != null && (r == null 10714 || !r.pkgList.containsKey(dumpPackage))) { 10715 continue; 10716 } 10717 if (!printed) { 10718 if (needSep) pw.println(); 10719 needSep = true; 10720 pw.println(" Bad processes:"); 10721 printedAnything = true; 10722 } 10723 BadProcessInfo info = uids.valueAt(i); 10724 pw.print(" Bad process "); pw.print(pname); 10725 pw.print(" uid "); pw.print(puid); 10726 pw.print(": crashed at time "); pw.println(info.time); 10727 if (info.shortMsg != null) { 10728 pw.print(" Short msg: "); pw.println(info.shortMsg); 10729 } 10730 if (info.longMsg != null) { 10731 pw.print(" Long msg: "); pw.println(info.longMsg); 10732 } 10733 if (info.stack != null) { 10734 pw.println(" Stack:"); 10735 int lastPos = 0; 10736 for (int pos=0; pos<info.stack.length(); pos++) { 10737 if (info.stack.charAt(pos) == '\n') { 10738 pw.print(" "); 10739 pw.write(info.stack, lastPos, pos-lastPos); 10740 pw.println(); 10741 lastPos = pos+1; 10742 } 10743 } 10744 if (lastPos < info.stack.length()) { 10745 pw.print(" "); 10746 pw.write(info.stack, lastPos, info.stack.length()-lastPos); 10747 pw.println(); 10748 } 10749 } 10750 } 10751 } 10752 } 10753 10754 if (dumpPackage == null) { 10755 pw.println(); 10756 needSep = false; 10757 pw.println(" mStartedUsers:"); 10758 for (int i=0; i<mStartedUsers.size(); i++) { 10759 UserStartedState uss = mStartedUsers.valueAt(i); 10760 pw.print(" User #"); pw.print(uss.mHandle.getIdentifier()); 10761 pw.print(": "); uss.dump("", pw); 10762 } 10763 pw.print(" mStartedUserArray: ["); 10764 for (int i=0; i<mStartedUserArray.length; i++) { 10765 if (i > 0) pw.print(", "); 10766 pw.print(mStartedUserArray[i]); 10767 } 10768 pw.println("]"); 10769 pw.print(" mUserLru: ["); 10770 for (int i=0; i<mUserLru.size(); i++) { 10771 if (i > 0) pw.print(", "); 10772 pw.print(mUserLru.get(i)); 10773 } 10774 pw.println("]"); 10775 if (dumpAll) { 10776 pw.print(" mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray)); 10777 } 10778 } 10779 if (mHomeProcess != null && (dumpPackage == null 10780 || mHomeProcess.pkgList.containsKey(dumpPackage))) { 10781 if (needSep) { 10782 pw.println(); 10783 needSep = false; 10784 } 10785 pw.println(" mHomeProcess: " + mHomeProcess); 10786 } 10787 if (mPreviousProcess != null && (dumpPackage == null 10788 || mPreviousProcess.pkgList.containsKey(dumpPackage))) { 10789 if (needSep) { 10790 pw.println(); 10791 needSep = false; 10792 } 10793 pw.println(" mPreviousProcess: " + mPreviousProcess); 10794 } 10795 if (dumpAll) { 10796 StringBuilder sb = new StringBuilder(128); 10797 sb.append(" mPreviousProcessVisibleTime: "); 10798 TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb); 10799 pw.println(sb); 10800 } 10801 if (mHeavyWeightProcess != null && (dumpPackage == null 10802 || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) { 10803 if (needSep) { 10804 pw.println(); 10805 needSep = false; 10806 } 10807 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 10808 } 10809 if (dumpPackage == null) { 10810 pw.println(" mConfiguration: " + mConfiguration); 10811 } 10812 if (dumpAll) { 10813 pw.println(" mConfigWillChange: " + getFocusedStack().mConfigWillChange); 10814 if (mCompatModePackages.getPackages().size() > 0) { 10815 boolean printed = false; 10816 for (Map.Entry<String, Integer> entry 10817 : mCompatModePackages.getPackages().entrySet()) { 10818 String pkg = entry.getKey(); 10819 int mode = entry.getValue(); 10820 if (dumpPackage != null && !dumpPackage.equals(pkg)) { 10821 continue; 10822 } 10823 if (!printed) { 10824 pw.println(" mScreenCompatPackages:"); 10825 printed = true; 10826 } 10827 pw.print(" "); pw.print(pkg); pw.print(": "); 10828 pw.print(mode); pw.println(); 10829 } 10830 } 10831 } 10832 if (dumpPackage == null) { 10833 if (mSleeping || mWentToSleep || mLockScreenShown) { 10834 pw.println(" mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep 10835 + " mLockScreenShown " + mLockScreenShown); 10836 } 10837 if (mShuttingDown) { 10838 pw.println(" mShuttingDown=" + mShuttingDown); 10839 } 10840 } 10841 if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient 10842 || mOrigWaitForDebugger) { 10843 if (dumpPackage == null || dumpPackage.equals(mDebugApp) 10844 || dumpPackage.equals(mOrigDebugApp)) { 10845 if (needSep) { 10846 pw.println(); 10847 needSep = false; 10848 } 10849 pw.println(" mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp 10850 + " mDebugTransient=" + mDebugTransient 10851 + " mOrigWaitForDebugger=" + mOrigWaitForDebugger); 10852 } 10853 } 10854 if (mOpenGlTraceApp != null) { 10855 if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) { 10856 if (needSep) { 10857 pw.println(); 10858 needSep = false; 10859 } 10860 pw.println(" mOpenGlTraceApp=" + mOpenGlTraceApp); 10861 } 10862 } 10863 if (mProfileApp != null || mProfileProc != null || mProfileFile != null 10864 || mProfileFd != null) { 10865 if (dumpPackage == null || dumpPackage.equals(mProfileApp)) { 10866 if (needSep) { 10867 pw.println(); 10868 needSep = false; 10869 } 10870 pw.println(" mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc); 10871 pw.println(" mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd); 10872 pw.println(" mProfileType=" + mProfileType + " mAutoStopProfiler=" 10873 + mAutoStopProfiler); 10874 } 10875 } 10876 if (dumpPackage == null) { 10877 if (mAlwaysFinishActivities || mController != null) { 10878 pw.println(" mAlwaysFinishActivities=" + mAlwaysFinishActivities 10879 + " mController=" + mController); 10880 } 10881 if (dumpAll) { 10882 pw.println(" Total persistent processes: " + numPers); 10883 pw.println(" mProcessesReady=" + mProcessesReady 10884 + " mSystemReady=" + mSystemReady); 10885 pw.println(" mBooting=" + mBooting 10886 + " mBooted=" + mBooted 10887 + " mFactoryTest=" + mFactoryTest); 10888 pw.print(" mLastPowerCheckRealtime="); 10889 TimeUtils.formatDuration(mLastPowerCheckRealtime, pw); 10890 pw.println(""); 10891 pw.print(" mLastPowerCheckUptime="); 10892 TimeUtils.formatDuration(mLastPowerCheckUptime, pw); 10893 pw.println(""); 10894 pw.println(" mGoingToSleep=" + mStackSupervisor.mGoingToSleep); 10895 pw.println(" mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity); 10896 pw.println(" mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq); 10897 pw.println(" mNumNonCachedProcs=" + mNumNonCachedProcs 10898 + " (" + mLruProcesses.size() + " total)" 10899 + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs 10900 + " mNumServiceProcs=" + mNumServiceProcs 10901 + " mNewNumServiceProcs=" + mNewNumServiceProcs); 10902 pw.println(" mAllowLowerMemLevel=" + mAllowLowerMemLevel 10903 + " mLastMemoryLevel" + mLastMemoryLevel 10904 + " mLastNumProcesses" + mLastNumProcesses); 10905 long now = SystemClock.uptimeMillis(); 10906 pw.print(" mLastIdleTime="); 10907 TimeUtils.formatDuration(now, mLastIdleTime, pw); 10908 pw.print(" mLowRamSinceLastIdle="); 10909 TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw); 10910 pw.println(); 10911 } 10912 } 10913 10914 if (!printedAnything) { 10915 pw.println(" (nothing)"); 10916 } 10917 } 10918 10919 boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args, 10920 int opti, boolean needSep, boolean dumpAll, String dumpPackage) { 10921 if (mProcessesToGc.size() > 0) { 10922 boolean printed = false; 10923 long now = SystemClock.uptimeMillis(); 10924 for (int i=0; i<mProcessesToGc.size(); i++) { 10925 ProcessRecord proc = mProcessesToGc.get(i); 10926 if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) { 10927 continue; 10928 } 10929 if (!printed) { 10930 if (needSep) pw.println(); 10931 needSep = true; 10932 pw.println(" Processes that are waiting to GC:"); 10933 printed = true; 10934 } 10935 pw.print(" Process "); pw.println(proc); 10936 pw.print(" lowMem="); pw.print(proc.reportLowMemory); 10937 pw.print(", last gced="); 10938 pw.print(now-proc.lastRequestedGc); 10939 pw.print(" ms ago, last lowMem="); 10940 pw.print(now-proc.lastLowMemory); 10941 pw.println(" ms ago"); 10942 10943 } 10944 } 10945 return needSep; 10946 } 10947 10948 void printOomLevel(PrintWriter pw, String name, int adj) { 10949 pw.print(" "); 10950 if (adj >= 0) { 10951 pw.print(' '); 10952 if (adj < 10) pw.print(' '); 10953 } else { 10954 if (adj > -10) pw.print(' '); 10955 } 10956 pw.print(adj); 10957 pw.print(": "); 10958 pw.print(name); 10959 pw.print(" ("); 10960 pw.print(mProcessList.getMemLevel(adj)/1024); 10961 pw.println(" kB)"); 10962 } 10963 10964 boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args, 10965 int opti, boolean dumpAll) { 10966 boolean needSep = false; 10967 10968 if (mLruProcesses.size() > 0) { 10969 if (needSep) pw.println(); 10970 needSep = true; 10971 pw.println(" OOM levels:"); 10972 printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ); 10973 printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ); 10974 printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ); 10975 printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ); 10976 printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ); 10977 printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ); 10978 printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ); 10979 printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ); 10980 printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ); 10981 printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ); 10982 printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ); 10983 printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ); 10984 printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ); 10985 10986 if (needSep) pw.println(); 10987 pw.print(" Process OOM control ("); pw.print(mLruProcesses.size()); 10988 pw.print(" total, non-act at "); 10989 pw.print(mLruProcesses.size()-mLruProcessActivityStart); 10990 pw.print(", non-svc at "); 10991 pw.print(mLruProcesses.size()-mLruProcessServiceStart); 10992 pw.println("):"); 10993 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", true, null); 10994 needSep = true; 10995 } 10996 10997 dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null); 10998 10999 pw.println(); 11000 pw.println(" mHomeProcess: " + mHomeProcess); 11001 pw.println(" mPreviousProcess: " + mPreviousProcess); 11002 if (mHeavyWeightProcess != null) { 11003 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 11004 } 11005 11006 return true; 11007 } 11008 11009 /** 11010 * There are three ways to call this: 11011 * - no provider specified: dump all the providers 11012 * - a flattened component name that matched an existing provider was specified as the 11013 * first arg: dump that one provider 11014 * - the first arg isn't the flattened component name of an existing provider: 11015 * dump all providers whose component contains the first arg as a substring 11016 */ 11017 protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args, 11018 int opti, boolean dumpAll) { 11019 return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll); 11020 } 11021 11022 static class ItemMatcher { 11023 ArrayList<ComponentName> components; 11024 ArrayList<String> strings; 11025 ArrayList<Integer> objects; 11026 boolean all; 11027 11028 ItemMatcher() { 11029 all = true; 11030 } 11031 11032 void build(String name) { 11033 ComponentName componentName = ComponentName.unflattenFromString(name); 11034 if (componentName != null) { 11035 if (components == null) { 11036 components = new ArrayList<ComponentName>(); 11037 } 11038 components.add(componentName); 11039 all = false; 11040 } else { 11041 int objectId = 0; 11042 // Not a '/' separated full component name; maybe an object ID? 11043 try { 11044 objectId = Integer.parseInt(name, 16); 11045 if (objects == null) { 11046 objects = new ArrayList<Integer>(); 11047 } 11048 objects.add(objectId); 11049 all = false; 11050 } catch (RuntimeException e) { 11051 // Not an integer; just do string match. 11052 if (strings == null) { 11053 strings = new ArrayList<String>(); 11054 } 11055 strings.add(name); 11056 all = false; 11057 } 11058 } 11059 } 11060 11061 int build(String[] args, int opti) { 11062 for (; opti<args.length; opti++) { 11063 String name = args[opti]; 11064 if ("--".equals(name)) { 11065 return opti+1; 11066 } 11067 build(name); 11068 } 11069 return opti; 11070 } 11071 11072 boolean match(Object object, ComponentName comp) { 11073 if (all) { 11074 return true; 11075 } 11076 if (components != null) { 11077 for (int i=0; i<components.size(); i++) { 11078 if (components.get(i).equals(comp)) { 11079 return true; 11080 } 11081 } 11082 } 11083 if (objects != null) { 11084 for (int i=0; i<objects.size(); i++) { 11085 if (System.identityHashCode(object) == objects.get(i)) { 11086 return true; 11087 } 11088 } 11089 } 11090 if (strings != null) { 11091 String flat = comp.flattenToString(); 11092 for (int i=0; i<strings.size(); i++) { 11093 if (flat.contains(strings.get(i))) { 11094 return true; 11095 } 11096 } 11097 } 11098 return false; 11099 } 11100 } 11101 11102 /** 11103 * There are three things that cmd can be: 11104 * - a flattened component name that matches an existing activity 11105 * - the cmd arg isn't the flattened component name of an existing activity: 11106 * dump all activity whose component contains the cmd as a substring 11107 * - A hex number of the ActivityRecord object instance. 11108 */ 11109 protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args, 11110 int opti, boolean dumpAll) { 11111 ArrayList<ActivityRecord> activities; 11112 11113 synchronized (this) { 11114 activities = mStackSupervisor.getDumpActivitiesLocked(name); 11115 } 11116 11117 if (activities.size() <= 0) { 11118 return false; 11119 } 11120 11121 String[] newArgs = new String[args.length - opti]; 11122 System.arraycopy(args, opti, newArgs, 0, args.length - opti); 11123 11124 TaskRecord lastTask = null; 11125 boolean needSep = false; 11126 for (int i=activities.size()-1; i>=0; i--) { 11127 ActivityRecord r = activities.get(i); 11128 if (needSep) { 11129 pw.println(); 11130 } 11131 needSep = true; 11132 synchronized (this) { 11133 if (lastTask != r.task) { 11134 lastTask = r.task; 11135 pw.print("TASK "); pw.print(lastTask.affinity); 11136 pw.print(" id="); pw.println(lastTask.taskId); 11137 if (dumpAll) { 11138 lastTask.dump(pw, " "); 11139 } 11140 } 11141 } 11142 dumpActivity(" ", fd, pw, activities.get(i), newArgs, dumpAll); 11143 } 11144 return true; 11145 } 11146 11147 /** 11148 * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if 11149 * there is a thread associated with the activity. 11150 */ 11151 private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw, 11152 final ActivityRecord r, String[] args, boolean dumpAll) { 11153 String innerPrefix = prefix + " "; 11154 synchronized (this) { 11155 pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName); 11156 pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r))); 11157 pw.print(" pid="); 11158 if (r.app != null) pw.println(r.app.pid); 11159 else pw.println("(not running)"); 11160 if (dumpAll) { 11161 r.dump(pw, innerPrefix); 11162 } 11163 } 11164 if (r.app != null && r.app.thread != null) { 11165 // flush anything that is already in the PrintWriter since the thread is going 11166 // to write to the file descriptor directly 11167 pw.flush(); 11168 try { 11169 TransferPipe tp = new TransferPipe(); 11170 try { 11171 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(), 11172 r.appToken, innerPrefix, args); 11173 tp.go(fd); 11174 } finally { 11175 tp.kill(); 11176 } 11177 } catch (IOException e) { 11178 pw.println(innerPrefix + "Failure while dumping the activity: " + e); 11179 } catch (RemoteException e) { 11180 pw.println(innerPrefix + "Got a RemoteException while dumping the activity"); 11181 } 11182 } 11183 } 11184 11185 void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 11186 int opti, boolean dumpAll, String dumpPackage) { 11187 boolean needSep = false; 11188 boolean onlyHistory = false; 11189 boolean printedAnything = false; 11190 11191 if ("history".equals(dumpPackage)) { 11192 if (opti < args.length && "-s".equals(args[opti])) { 11193 dumpAll = false; 11194 } 11195 onlyHistory = true; 11196 dumpPackage = null; 11197 } 11198 11199 pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)"); 11200 if (!onlyHistory && dumpAll) { 11201 if (mRegisteredReceivers.size() > 0) { 11202 boolean printed = false; 11203 Iterator it = mRegisteredReceivers.values().iterator(); 11204 while (it.hasNext()) { 11205 ReceiverList r = (ReceiverList)it.next(); 11206 if (dumpPackage != null && (r.app == null || 11207 !dumpPackage.equals(r.app.info.packageName))) { 11208 continue; 11209 } 11210 if (!printed) { 11211 pw.println(" Registered Receivers:"); 11212 needSep = true; 11213 printed = true; 11214 printedAnything = true; 11215 } 11216 pw.print(" * "); pw.println(r); 11217 r.dump(pw, " "); 11218 } 11219 } 11220 11221 if (mReceiverResolver.dump(pw, needSep ? 11222 "\n Receiver Resolver Table:" : " Receiver Resolver Table:", 11223 " ", dumpPackage, false)) { 11224 needSep = true; 11225 printedAnything = true; 11226 } 11227 } 11228 11229 for (BroadcastQueue q : mBroadcastQueues) { 11230 needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep); 11231 printedAnything |= needSep; 11232 } 11233 11234 needSep = true; 11235 11236 if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) { 11237 for (int user=0; user<mStickyBroadcasts.size(); user++) { 11238 if (needSep) { 11239 pw.println(); 11240 } 11241 needSep = true; 11242 printedAnything = true; 11243 pw.print(" Sticky broadcasts for user "); 11244 pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":"); 11245 StringBuilder sb = new StringBuilder(128); 11246 for (Map.Entry<String, ArrayList<Intent>> ent 11247 : mStickyBroadcasts.valueAt(user).entrySet()) { 11248 pw.print(" * Sticky action "); pw.print(ent.getKey()); 11249 if (dumpAll) { 11250 pw.println(":"); 11251 ArrayList<Intent> intents = ent.getValue(); 11252 final int N = intents.size(); 11253 for (int i=0; i<N; i++) { 11254 sb.setLength(0); 11255 sb.append(" Intent: "); 11256 intents.get(i).toShortString(sb, false, true, false, false); 11257 pw.println(sb.toString()); 11258 Bundle bundle = intents.get(i).getExtras(); 11259 if (bundle != null) { 11260 pw.print(" "); 11261 pw.println(bundle.toString()); 11262 } 11263 } 11264 } else { 11265 pw.println(""); 11266 } 11267 } 11268 } 11269 } 11270 11271 if (!onlyHistory && dumpAll) { 11272 pw.println(); 11273 for (BroadcastQueue queue : mBroadcastQueues) { 11274 pw.println(" mBroadcastsScheduled [" + queue.mQueueName + "]=" 11275 + queue.mBroadcastsScheduled); 11276 } 11277 pw.println(" mHandler:"); 11278 mHandler.dump(new PrintWriterPrinter(pw), " "); 11279 needSep = true; 11280 printedAnything = true; 11281 } 11282 11283 if (!printedAnything) { 11284 pw.println(" (nothing)"); 11285 } 11286 } 11287 11288 void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args, 11289 int opti, boolean dumpAll, String dumpPackage) { 11290 boolean needSep; 11291 boolean printedAnything = false; 11292 11293 ItemMatcher matcher = new ItemMatcher(); 11294 matcher.build(args, opti); 11295 11296 pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)"); 11297 11298 needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage); 11299 printedAnything |= needSep; 11300 11301 if (mLaunchingProviders.size() > 0) { 11302 boolean printed = false; 11303 for (int i=mLaunchingProviders.size()-1; i>=0; i--) { 11304 ContentProviderRecord r = mLaunchingProviders.get(i); 11305 if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) { 11306 continue; 11307 } 11308 if (!printed) { 11309 if (needSep) pw.println(); 11310 needSep = true; 11311 pw.println(" Launching content providers:"); 11312 printed = true; 11313 printedAnything = true; 11314 } 11315 pw.print(" Launching #"); pw.print(i); pw.print(": "); 11316 pw.println(r); 11317 } 11318 } 11319 11320 if (mGrantedUriPermissions.size() > 0) { 11321 boolean printed = false; 11322 int dumpUid = -2; 11323 if (dumpPackage != null) { 11324 try { 11325 dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0); 11326 } catch (NameNotFoundException e) { 11327 dumpUid = -1; 11328 } 11329 } 11330 for (int i=0; i<mGrantedUriPermissions.size(); i++) { 11331 int uid = mGrantedUriPermissions.keyAt(i); 11332 if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) { 11333 continue; 11334 } 11335 ArrayMap<Uri, UriPermission> perms 11336 = mGrantedUriPermissions.valueAt(i); 11337 if (!printed) { 11338 if (needSep) pw.println(); 11339 needSep = true; 11340 pw.println(" Granted Uri Permissions:"); 11341 printed = true; 11342 printedAnything = true; 11343 } 11344 pw.print(" * UID "); pw.print(uid); 11345 pw.println(" holds:"); 11346 for (UriPermission perm : perms.values()) { 11347 pw.print(" "); pw.println(perm); 11348 if (dumpAll) { 11349 perm.dump(pw, " "); 11350 } 11351 } 11352 } 11353 } 11354 11355 if (!printedAnything) { 11356 pw.println(" (nothing)"); 11357 } 11358 } 11359 11360 void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 11361 int opti, boolean dumpAll, String dumpPackage) { 11362 boolean printed = false; 11363 11364 pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)"); 11365 11366 if (mIntentSenderRecords.size() > 0) { 11367 Iterator<WeakReference<PendingIntentRecord>> it 11368 = mIntentSenderRecords.values().iterator(); 11369 while (it.hasNext()) { 11370 WeakReference<PendingIntentRecord> ref = it.next(); 11371 PendingIntentRecord rec = ref != null ? ref.get(): null; 11372 if (dumpPackage != null && (rec == null 11373 || !dumpPackage.equals(rec.key.packageName))) { 11374 continue; 11375 } 11376 printed = true; 11377 if (rec != null) { 11378 pw.print(" * "); pw.println(rec); 11379 if (dumpAll) { 11380 rec.dump(pw, " "); 11381 } 11382 } else { 11383 pw.print(" * "); pw.println(ref); 11384 } 11385 } 11386 } 11387 11388 if (!printed) { 11389 pw.println(" (nothing)"); 11390 } 11391 } 11392 11393 private static final int dumpProcessList(PrintWriter pw, 11394 ActivityManagerService service, List list, 11395 String prefix, String normalLabel, String persistentLabel, 11396 String dumpPackage) { 11397 int numPers = 0; 11398 final int N = list.size()-1; 11399 for (int i=N; i>=0; i--) { 11400 ProcessRecord r = (ProcessRecord)list.get(i); 11401 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 11402 continue; 11403 } 11404 pw.println(String.format("%s%s #%2d: %s", 11405 prefix, (r.persistent ? persistentLabel : normalLabel), 11406 i, r.toString())); 11407 if (r.persistent) { 11408 numPers++; 11409 } 11410 } 11411 return numPers; 11412 } 11413 11414 private static final boolean dumpProcessOomList(PrintWriter pw, 11415 ActivityManagerService service, List<ProcessRecord> origList, 11416 String prefix, String normalLabel, String persistentLabel, 11417 boolean inclDetails, String dumpPackage) { 11418 11419 ArrayList<Pair<ProcessRecord, Integer>> list 11420 = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size()); 11421 for (int i=0; i<origList.size(); i++) { 11422 ProcessRecord r = origList.get(i); 11423 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 11424 continue; 11425 } 11426 list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i)); 11427 } 11428 11429 if (list.size() <= 0) { 11430 return false; 11431 } 11432 11433 Comparator<Pair<ProcessRecord, Integer>> comparator 11434 = new Comparator<Pair<ProcessRecord, Integer>>() { 11435 @Override 11436 public int compare(Pair<ProcessRecord, Integer> object1, 11437 Pair<ProcessRecord, Integer> object2) { 11438 if (object1.first.setAdj != object2.first.setAdj) { 11439 return object1.first.setAdj > object2.first.setAdj ? -1 : 1; 11440 } 11441 if (object1.second.intValue() != object2.second.intValue()) { 11442 return object1.second.intValue() > object2.second.intValue() ? -1 : 1; 11443 } 11444 return 0; 11445 } 11446 }; 11447 11448 Collections.sort(list, comparator); 11449 11450 final long curRealtime = SystemClock.elapsedRealtime(); 11451 final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime; 11452 final long curUptime = SystemClock.uptimeMillis(); 11453 final long uptimeSince = curUptime - service.mLastPowerCheckUptime; 11454 11455 for (int i=list.size()-1; i>=0; i--) { 11456 ProcessRecord r = list.get(i).first; 11457 String oomAdj = ProcessList.makeOomAdjString(r.setAdj); 11458 char schedGroup; 11459 switch (r.setSchedGroup) { 11460 case Process.THREAD_GROUP_BG_NONINTERACTIVE: 11461 schedGroup = 'B'; 11462 break; 11463 case Process.THREAD_GROUP_DEFAULT: 11464 schedGroup = 'F'; 11465 break; 11466 default: 11467 schedGroup = '?'; 11468 break; 11469 } 11470 char foreground; 11471 if (r.foregroundActivities) { 11472 foreground = 'A'; 11473 } else if (r.foregroundServices) { 11474 foreground = 'S'; 11475 } else { 11476 foreground = ' '; 11477 } 11478 String procState = ProcessList.makeProcStateString(r.curProcState); 11479 pw.print(prefix); 11480 pw.print(r.persistent ? persistentLabel : normalLabel); 11481 pw.print(" #"); 11482 int num = (origList.size()-1)-list.get(i).second; 11483 if (num < 10) pw.print(' '); 11484 pw.print(num); 11485 pw.print(": "); 11486 pw.print(oomAdj); 11487 pw.print(' '); 11488 pw.print(schedGroup); 11489 pw.print('/'); 11490 pw.print(foreground); 11491 pw.print('/'); 11492 pw.print(procState); 11493 pw.print(" trm:"); 11494 if (r.trimMemoryLevel < 10) pw.print(' '); 11495 pw.print(r.trimMemoryLevel); 11496 pw.print(' '); 11497 pw.print(r.toShortString()); 11498 pw.print(" ("); 11499 pw.print(r.adjType); 11500 pw.println(')'); 11501 if (r.adjSource != null || r.adjTarget != null) { 11502 pw.print(prefix); 11503 pw.print(" "); 11504 if (r.adjTarget instanceof ComponentName) { 11505 pw.print(((ComponentName)r.adjTarget).flattenToShortString()); 11506 } else if (r.adjTarget != null) { 11507 pw.print(r.adjTarget.toString()); 11508 } else { 11509 pw.print("{null}"); 11510 } 11511 pw.print("<="); 11512 if (r.adjSource instanceof ProcessRecord) { 11513 pw.print("Proc{"); 11514 pw.print(((ProcessRecord)r.adjSource).toShortString()); 11515 pw.println("}"); 11516 } else if (r.adjSource != null) { 11517 pw.println(r.adjSource.toString()); 11518 } else { 11519 pw.println("{null}"); 11520 } 11521 } 11522 if (inclDetails) { 11523 pw.print(prefix); 11524 pw.print(" "); 11525 pw.print("oom: max="); pw.print(r.maxAdj); 11526 pw.print(" curRaw="); pw.print(r.curRawAdj); 11527 pw.print(" setRaw="); pw.print(r.setRawAdj); 11528 pw.print(" cur="); pw.print(r.curAdj); 11529 pw.print(" set="); pw.println(r.setAdj); 11530 pw.print(prefix); 11531 pw.print(" "); 11532 pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState)); 11533 pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState)); 11534 pw.print(" lastPss="); pw.print(r.lastPss); 11535 pw.print(" lastCachedPss="); pw.println(r.lastCachedPss); 11536 pw.print(prefix); 11537 pw.print(" "); 11538 pw.print("keeping="); pw.print(r.keeping); 11539 pw.print(" cached="); pw.print(r.cached); 11540 pw.print(" empty="); pw.print(r.empty); 11541 pw.print(" hasAboveClient="); pw.println(r.hasAboveClient); 11542 11543 if (!r.keeping) { 11544 if (r.lastWakeTime != 0) { 11545 long wtime; 11546 BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics(); 11547 synchronized (stats) { 11548 wtime = stats.getProcessWakeTime(r.info.uid, 11549 r.pid, curRealtime); 11550 } 11551 long timeUsed = wtime - r.lastWakeTime; 11552 pw.print(prefix); 11553 pw.print(" "); 11554 pw.print("keep awake over "); 11555 TimeUtils.formatDuration(realtimeSince, pw); 11556 pw.print(" used "); 11557 TimeUtils.formatDuration(timeUsed, pw); 11558 pw.print(" ("); 11559 pw.print((timeUsed*100)/realtimeSince); 11560 pw.println("%)"); 11561 } 11562 if (r.lastCpuTime != 0) { 11563 long timeUsed = r.curCpuTime - r.lastCpuTime; 11564 pw.print(prefix); 11565 pw.print(" "); 11566 pw.print("run cpu over "); 11567 TimeUtils.formatDuration(uptimeSince, pw); 11568 pw.print(" used "); 11569 TimeUtils.formatDuration(timeUsed, pw); 11570 pw.print(" ("); 11571 pw.print((timeUsed*100)/uptimeSince); 11572 pw.println("%)"); 11573 } 11574 } 11575 } 11576 } 11577 return true; 11578 } 11579 11580 ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) { 11581 ArrayList<ProcessRecord> procs; 11582 synchronized (this) { 11583 if (args != null && args.length > start 11584 && args[start].charAt(0) != '-') { 11585 procs = new ArrayList<ProcessRecord>(); 11586 int pid = -1; 11587 try { 11588 pid = Integer.parseInt(args[start]); 11589 } catch (NumberFormatException e) { 11590 } 11591 for (int i=mLruProcesses.size()-1; i>=0; i--) { 11592 ProcessRecord proc = mLruProcesses.get(i); 11593 if (proc.pid == pid) { 11594 procs.add(proc); 11595 } else if (proc.processName.equals(args[start])) { 11596 procs.add(proc); 11597 } 11598 } 11599 if (procs.size() <= 0) { 11600 return null; 11601 } 11602 } else { 11603 procs = new ArrayList<ProcessRecord>(mLruProcesses); 11604 } 11605 } 11606 return procs; 11607 } 11608 11609 final void dumpGraphicsHardwareUsage(FileDescriptor fd, 11610 PrintWriter pw, String[] args) { 11611 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args); 11612 if (procs == null) { 11613 pw.println("No process found for: " + args[0]); 11614 return; 11615 } 11616 11617 long uptime = SystemClock.uptimeMillis(); 11618 long realtime = SystemClock.elapsedRealtime(); 11619 pw.println("Applications Graphics Acceleration Info:"); 11620 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 11621 11622 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 11623 ProcessRecord r = procs.get(i); 11624 if (r.thread != null) { 11625 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **"); 11626 pw.flush(); 11627 try { 11628 TransferPipe tp = new TransferPipe(); 11629 try { 11630 r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args); 11631 tp.go(fd); 11632 } finally { 11633 tp.kill(); 11634 } 11635 } catch (IOException e) { 11636 pw.println("Failure while dumping the app: " + r); 11637 pw.flush(); 11638 } catch (RemoteException e) { 11639 pw.println("Got a RemoteException while dumping the app " + r); 11640 pw.flush(); 11641 } 11642 } 11643 } 11644 } 11645 11646 final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) { 11647 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args); 11648 if (procs == null) { 11649 pw.println("No process found for: " + args[0]); 11650 return; 11651 } 11652 11653 pw.println("Applications Database Info:"); 11654 11655 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 11656 ProcessRecord r = procs.get(i); 11657 if (r.thread != null) { 11658 pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **"); 11659 pw.flush(); 11660 try { 11661 TransferPipe tp = new TransferPipe(); 11662 try { 11663 r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args); 11664 tp.go(fd); 11665 } finally { 11666 tp.kill(); 11667 } 11668 } catch (IOException e) { 11669 pw.println("Failure while dumping the app: " + r); 11670 pw.flush(); 11671 } catch (RemoteException e) { 11672 pw.println("Got a RemoteException while dumping the app " + r); 11673 pw.flush(); 11674 } 11675 } 11676 } 11677 } 11678 11679 final static class MemItem { 11680 final boolean isProc; 11681 final String label; 11682 final String shortLabel; 11683 final long pss; 11684 final int id; 11685 final boolean hasActivities; 11686 ArrayList<MemItem> subitems; 11687 11688 public MemItem(String _label, String _shortLabel, long _pss, int _id, 11689 boolean _hasActivities) { 11690 isProc = true; 11691 label = _label; 11692 shortLabel = _shortLabel; 11693 pss = _pss; 11694 id = _id; 11695 hasActivities = _hasActivities; 11696 } 11697 11698 public MemItem(String _label, String _shortLabel, long _pss, int _id) { 11699 isProc = false; 11700 label = _label; 11701 shortLabel = _shortLabel; 11702 pss = _pss; 11703 id = _id; 11704 hasActivities = false; 11705 } 11706 } 11707 11708 static final void dumpMemItems(PrintWriter pw, String prefix, String tag, 11709 ArrayList<MemItem> items, boolean sort, boolean isCompact) { 11710 if (sort && !isCompact) { 11711 Collections.sort(items, new Comparator<MemItem>() { 11712 @Override 11713 public int compare(MemItem lhs, MemItem rhs) { 11714 if (lhs.pss < rhs.pss) { 11715 return 1; 11716 } else if (lhs.pss > rhs.pss) { 11717 return -1; 11718 } 11719 return 0; 11720 } 11721 }); 11722 } 11723 11724 for (int i=0; i<items.size(); i++) { 11725 MemItem mi = items.get(i); 11726 if (!isCompact) { 11727 pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label); 11728 } else if (mi.isProc) { 11729 pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel); 11730 pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss); 11731 pw.println(mi.hasActivities ? ",a" : ",e"); 11732 } else { 11733 pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(","); 11734 pw.println(mi.pss); 11735 } 11736 if (mi.subitems != null) { 11737 dumpMemItems(pw, prefix + " ", mi.shortLabel, mi.subitems, 11738 true, isCompact); 11739 } 11740 } 11741 } 11742 11743 // These are in KB. 11744 static final long[] DUMP_MEM_BUCKETS = new long[] { 11745 5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024, 11746 120*1024, 160*1024, 200*1024, 11747 250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024, 11748 1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024 11749 }; 11750 11751 static final void appendMemBucket(StringBuilder out, long memKB, String label, 11752 boolean stackLike) { 11753 int start = label.lastIndexOf('.'); 11754 if (start >= 0) start++; 11755 else start = 0; 11756 int end = label.length(); 11757 for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) { 11758 if (DUMP_MEM_BUCKETS[i] >= memKB) { 11759 long bucket = DUMP_MEM_BUCKETS[i]/1024; 11760 out.append(bucket); 11761 out.append(stackLike ? "MB." : "MB "); 11762 out.append(label, start, end); 11763 return; 11764 } 11765 } 11766 out.append(memKB/1024); 11767 out.append(stackLike ? "MB." : "MB "); 11768 out.append(label, start, end); 11769 } 11770 11771 static final int[] DUMP_MEM_OOM_ADJ = new int[] { 11772 ProcessList.NATIVE_ADJ, 11773 ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ, 11774 ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ, 11775 ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ, 11776 ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ, 11777 ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ 11778 }; 11779 static final String[] DUMP_MEM_OOM_LABEL = new String[] { 11780 "Native", 11781 "System", "Persistent", "Foreground", 11782 "Visible", "Perceptible", 11783 "Heavy Weight", "Backup", 11784 "A Services", "Home", 11785 "Previous", "B Services", "Cached" 11786 }; 11787 static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] { 11788 "native", 11789 "sys", "pers", "fore", 11790 "vis", "percept", 11791 "heavy", "backup", 11792 "servicea", "home", 11793 "prev", "serviceb", "cached" 11794 }; 11795 11796 private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime, 11797 long realtime, boolean isCheckinRequest, boolean isCompact) { 11798 if (isCheckinRequest || isCompact) { 11799 // short checkin version 11800 pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime); 11801 } else { 11802 pw.println("Applications Memory Usage (kB):"); 11803 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 11804 } 11805 } 11806 11807 final void dumpApplicationMemoryUsage(FileDescriptor fd, 11808 PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) { 11809 boolean dumpDetails = false; 11810 boolean dumpFullDetails = false; 11811 boolean dumpDalvik = false; 11812 boolean oomOnly = false; 11813 boolean isCompact = false; 11814 boolean localOnly = false; 11815 11816 int opti = 0; 11817 while (opti < args.length) { 11818 String opt = args[opti]; 11819 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 11820 break; 11821 } 11822 opti++; 11823 if ("-a".equals(opt)) { 11824 dumpDetails = true; 11825 dumpFullDetails = true; 11826 dumpDalvik = true; 11827 } else if ("-d".equals(opt)) { 11828 dumpDalvik = true; 11829 } else if ("-c".equals(opt)) { 11830 isCompact = true; 11831 } else if ("--oom".equals(opt)) { 11832 oomOnly = true; 11833 } else if ("--local".equals(opt)) { 11834 localOnly = true; 11835 } else if ("-h".equals(opt)) { 11836 pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]"); 11837 pw.println(" -a: include all available information for each process."); 11838 pw.println(" -d: include dalvik details when dumping process details."); 11839 pw.println(" -c: dump in a compact machine-parseable representation."); 11840 pw.println(" --oom: only show processes organized by oom adj."); 11841 pw.println(" --local: only collect details locally, don't call process."); 11842 pw.println("If [process] is specified it can be the name or "); 11843 pw.println("pid of a specific process to dump."); 11844 return; 11845 } else { 11846 pw.println("Unknown argument: " + opt + "; use -h for help"); 11847 } 11848 } 11849 11850 final boolean isCheckinRequest = scanArgs(args, "--checkin"); 11851 long uptime = SystemClock.uptimeMillis(); 11852 long realtime = SystemClock.elapsedRealtime(); 11853 final long[] tmpLong = new long[1]; 11854 11855 ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args); 11856 if (procs == null) { 11857 // No Java processes. Maybe they want to print a native process. 11858 if (args != null && args.length > opti 11859 && args[opti].charAt(0) != '-') { 11860 ArrayList<ProcessCpuTracker.Stats> nativeProcs 11861 = new ArrayList<ProcessCpuTracker.Stats>(); 11862 updateCpuStatsNow(); 11863 int findPid = -1; 11864 try { 11865 findPid = Integer.parseInt(args[opti]); 11866 } catch (NumberFormatException e) { 11867 } 11868 synchronized (mProcessCpuThread) { 11869 final int N = mProcessCpuTracker.countStats(); 11870 for (int i=0; i<N; i++) { 11871 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 11872 if (st.pid == findPid || (st.baseName != null 11873 && st.baseName.equals(args[opti]))) { 11874 nativeProcs.add(st); 11875 } 11876 } 11877 } 11878 if (nativeProcs.size() > 0) { 11879 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, 11880 isCompact); 11881 Debug.MemoryInfo mi = null; 11882 for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) { 11883 final ProcessCpuTracker.Stats r = nativeProcs.get(i); 11884 final int pid = r.pid; 11885 if (!isCheckinRequest && dumpDetails) { 11886 pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **"); 11887 } 11888 if (mi == null) { 11889 mi = new Debug.MemoryInfo(); 11890 } 11891 if (dumpDetails || (!brief && !oomOnly)) { 11892 Debug.getMemoryInfo(pid, mi); 11893 } else { 11894 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong); 11895 mi.dalvikPrivateDirty = (int)tmpLong[0]; 11896 } 11897 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails, 11898 dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0); 11899 if (isCheckinRequest) { 11900 pw.println(); 11901 } 11902 } 11903 return; 11904 } 11905 } 11906 pw.println("No process found for: " + args[opti]); 11907 return; 11908 } 11909 11910 if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest)) { 11911 dumpDetails = true; 11912 } 11913 11914 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact); 11915 11916 String[] innerArgs = new String[args.length-opti]; 11917 System.arraycopy(args, opti, innerArgs, 0, args.length-opti); 11918 11919 ArrayList<MemItem> procMems = new ArrayList<MemItem>(); 11920 final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>(); 11921 long nativePss=0, dalvikPss=0, otherPss=0; 11922 long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS]; 11923 11924 long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length]; 11925 ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[]) 11926 new ArrayList[DUMP_MEM_OOM_LABEL.length]; 11927 11928 long totalPss = 0; 11929 long cachedPss = 0; 11930 11931 Debug.MemoryInfo mi = null; 11932 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 11933 final ProcessRecord r = procs.get(i); 11934 final IApplicationThread thread; 11935 final int pid; 11936 final int oomAdj; 11937 final boolean hasActivities; 11938 synchronized (this) { 11939 thread = r.thread; 11940 pid = r.pid; 11941 oomAdj = r.getSetAdjWithServices(); 11942 hasActivities = r.activities.size() > 0; 11943 } 11944 if (thread != null) { 11945 if (!isCheckinRequest && dumpDetails) { 11946 pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **"); 11947 } 11948 if (mi == null) { 11949 mi = new Debug.MemoryInfo(); 11950 } 11951 if (dumpDetails || (!brief && !oomOnly)) { 11952 Debug.getMemoryInfo(pid, mi); 11953 } else { 11954 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong); 11955 mi.dalvikPrivateDirty = (int)tmpLong[0]; 11956 } 11957 if (dumpDetails) { 11958 if (localOnly) { 11959 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails, 11960 dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0); 11961 if (isCheckinRequest) { 11962 pw.println(); 11963 } 11964 } else { 11965 try { 11966 pw.flush(); 11967 thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails, 11968 dumpDalvik, innerArgs); 11969 } catch (RemoteException e) { 11970 if (!isCheckinRequest) { 11971 pw.println("Got RemoteException!"); 11972 pw.flush(); 11973 } 11974 } 11975 } 11976 } 11977 11978 final long myTotalPss = mi.getTotalPss(); 11979 final long myTotalUss = mi.getTotalUss(); 11980 11981 synchronized (this) { 11982 if (r.thread != null && oomAdj == r.getSetAdjWithServices()) { 11983 // Record this for posterity if the process has been stable. 11984 r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList); 11985 } 11986 } 11987 11988 if (!isCheckinRequest && mi != null) { 11989 totalPss += myTotalPss; 11990 MemItem pssItem = new MemItem(r.processName + " (pid " + pid + 11991 (hasActivities ? " / activities)" : ")"), 11992 r.processName, myTotalPss, pid, hasActivities); 11993 procMems.add(pssItem); 11994 procMemsMap.put(pid, 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 12005 if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 12006 cachedPss += myTotalPss; 12007 } 12008 12009 for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) { 12010 if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex] 12011 || oomIndex == (oomPss.length-1)) { 12012 oomPss[oomIndex] += myTotalPss; 12013 if (oomProcs[oomIndex] == null) { 12014 oomProcs[oomIndex] = new ArrayList<MemItem>(); 12015 } 12016 oomProcs[oomIndex].add(pssItem); 12017 break; 12018 } 12019 } 12020 } 12021 } 12022 } 12023 12024 if (!isCheckinRequest && procs.size() > 1) { 12025 // If we are showing aggregations, also look for native processes to 12026 // include so that our aggregations are more accurate. 12027 updateCpuStatsNow(); 12028 synchronized (mProcessCpuThread) { 12029 final int N = mProcessCpuTracker.countStats(); 12030 for (int i=0; i<N; i++) { 12031 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 12032 if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) { 12033 if (mi == null) { 12034 mi = new Debug.MemoryInfo(); 12035 } 12036 if (!brief && !oomOnly) { 12037 Debug.getMemoryInfo(st.pid, mi); 12038 } else { 12039 mi.nativePss = (int)Debug.getPss(st.pid, tmpLong); 12040 mi.nativePrivateDirty = (int)tmpLong[0]; 12041 } 12042 12043 final long myTotalPss = mi.getTotalPss(); 12044 totalPss += myTotalPss; 12045 12046 MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")", 12047 st.name, myTotalPss, st.pid, false); 12048 procMems.add(pssItem); 12049 12050 nativePss += mi.nativePss; 12051 dalvikPss += mi.dalvikPss; 12052 otherPss += mi.otherPss; 12053 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 12054 long mem = mi.getOtherPss(j); 12055 miscPss[j] += mem; 12056 otherPss -= mem; 12057 } 12058 oomPss[0] += myTotalPss; 12059 if (oomProcs[0] == null) { 12060 oomProcs[0] = new ArrayList<MemItem>(); 12061 } 12062 oomProcs[0].add(pssItem); 12063 } 12064 } 12065 } 12066 12067 ArrayList<MemItem> catMems = new ArrayList<MemItem>(); 12068 12069 catMems.add(new MemItem("Native", "Native", nativePss, -1)); 12070 catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2)); 12071 catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3)); 12072 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 12073 String label = Debug.MemoryInfo.getOtherLabel(j); 12074 catMems.add(new MemItem(label, label, miscPss[j], j)); 12075 } 12076 12077 ArrayList<MemItem> oomMems = new ArrayList<MemItem>(); 12078 for (int j=0; j<oomPss.length; j++) { 12079 if (oomPss[j] != 0) { 12080 String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j] 12081 : DUMP_MEM_OOM_LABEL[j]; 12082 MemItem item = new MemItem(label, label, oomPss[j], 12083 DUMP_MEM_OOM_ADJ[j]); 12084 item.subitems = oomProcs[j]; 12085 oomMems.add(item); 12086 } 12087 } 12088 12089 if (!brief && !oomOnly && !isCompact) { 12090 pw.println(); 12091 pw.println("Total PSS by process:"); 12092 dumpMemItems(pw, " ", "proc", procMems, true, isCompact); 12093 pw.println(); 12094 } 12095 if (!isCompact) { 12096 pw.println("Total PSS by OOM adjustment:"); 12097 } 12098 dumpMemItems(pw, " ", "oom", oomMems, false, isCompact); 12099 if (!brief && !oomOnly) { 12100 PrintWriter out = categoryPw != null ? categoryPw : pw; 12101 if (!isCompact) { 12102 out.println(); 12103 out.println("Total PSS by category:"); 12104 } 12105 dumpMemItems(out, " ", "cat", catMems, true, isCompact); 12106 } 12107 if (!isCompact) { 12108 pw.println(); 12109 } 12110 MemInfoReader memInfo = new MemInfoReader(); 12111 memInfo.readMemInfo(); 12112 if (!brief) { 12113 if (!isCompact) { 12114 pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb()); 12115 pw.println(" kB"); 12116 pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb() 12117 + memInfo.getFreeSizeKb()); pw.print(" kB ("); 12118 pw.print(cachedPss); pw.print(" cached pss + "); 12119 pw.print(memInfo.getCachedSizeKb()); pw.print(" cached + "); 12120 pw.print(memInfo.getFreeSizeKb()); pw.println(" free)"); 12121 } else { 12122 pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(","); 12123 pw.print(cachedPss + memInfo.getCachedSizeKb() 12124 + memInfo.getFreeSizeKb()); pw.print(","); 12125 pw.println(totalPss - cachedPss); 12126 } 12127 } 12128 if (!isCompact) { 12129 pw.print(" Used RAM: "); pw.print(totalPss - cachedPss 12130 + memInfo.getBuffersSizeKb() + memInfo.getShmemSizeKb() 12131 + memInfo.getSlabSizeKb()); pw.print(" kB ("); 12132 pw.print(totalPss - cachedPss); pw.print(" used pss + "); 12133 pw.print(memInfo.getBuffersSizeKb()); pw.print(" buffers + "); 12134 pw.print(memInfo.getShmemSizeKb()); pw.print(" shmem + "); 12135 pw.print(memInfo.getSlabSizeKb()); pw.println(" slab)"); 12136 pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb() 12137 - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb() 12138 - memInfo.getBuffersSizeKb() - memInfo.getShmemSizeKb() 12139 - memInfo.getSlabSizeKb()); pw.println(" kB"); 12140 } 12141 if (!brief) { 12142 if (memInfo.getZramTotalSizeKb() != 0) { 12143 if (!isCompact) { 12144 pw.print(" ZRAM: "); pw.print(memInfo.getZramTotalSizeKb()); 12145 pw.print(" kB physical used for "); 12146 pw.print(memInfo.getSwapTotalSizeKb() 12147 - memInfo.getSwapFreeSizeKb()); 12148 pw.print(" kB in swap ("); 12149 pw.print(memInfo.getSwapTotalSizeKb()); 12150 pw.println(" kB total swap)"); 12151 } else { 12152 pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(","); 12153 pw.print(memInfo.getSwapTotalSizeKb()); pw.print(","); 12154 pw.println(memInfo.getSwapFreeSizeKb()); 12155 } 12156 } 12157 final int[] SINGLE_LONG_FORMAT = new int[] { 12158 Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG 12159 }; 12160 long[] longOut = new long[1]; 12161 Process.readProcFile("/sys/kernel/mm/ksm/pages_shared", 12162 SINGLE_LONG_FORMAT, null, longOut, null); 12163 long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024; 12164 longOut[0] = 0; 12165 Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing", 12166 SINGLE_LONG_FORMAT, null, longOut, null); 12167 long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024; 12168 longOut[0] = 0; 12169 Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared", 12170 SINGLE_LONG_FORMAT, null, longOut, null); 12171 long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024; 12172 longOut[0] = 0; 12173 Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile", 12174 SINGLE_LONG_FORMAT, null, longOut, null); 12175 long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024; 12176 if (!isCompact) { 12177 if (sharing != 0 || shared != 0 || unshared != 0 || voltile != 0) { 12178 pw.print(" KSM: "); pw.print(sharing); 12179 pw.print(" kB saved from shared "); 12180 pw.print(shared); pw.println(" kB"); 12181 pw.print(" "); pw.print(unshared); pw.print(" kB unshared; "); 12182 pw.print(voltile); pw.println(" kB volatile"); 12183 } 12184 pw.print(" Tuning: "); 12185 pw.print(ActivityManager.staticGetMemoryClass()); 12186 pw.print(" (large "); 12187 pw.print(ActivityManager.staticGetLargeMemoryClass()); 12188 pw.print("), oom "); 12189 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024); 12190 pw.print(" kB"); 12191 pw.print(", restore limit "); 12192 pw.print(mProcessList.getCachedRestoreThresholdKb()); 12193 pw.print(" kB"); 12194 if (ActivityManager.isLowRamDeviceStatic()) { 12195 pw.print(" (low-ram)"); 12196 } 12197 if (ActivityManager.isHighEndGfx()) { 12198 pw.print(" (high-end-gfx)"); 12199 } 12200 pw.println(); 12201 } else { 12202 pw.print("ksm,"); pw.print(sharing); pw.print(","); 12203 pw.print(shared); pw.print(","); pw.print(unshared); pw.print(","); 12204 pw.println(voltile); 12205 pw.print("tuning,"); 12206 pw.print(ActivityManager.staticGetMemoryClass()); 12207 pw.print(','); 12208 pw.print(ActivityManager.staticGetLargeMemoryClass()); 12209 pw.print(','); 12210 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024); 12211 if (ActivityManager.isLowRamDeviceStatic()) { 12212 pw.print(",low-ram"); 12213 } 12214 if (ActivityManager.isHighEndGfx()) { 12215 pw.print(",high-end-gfx"); 12216 } 12217 pw.println(); 12218 } 12219 } 12220 } 12221 } 12222 12223 /** 12224 * Searches array of arguments for the specified string 12225 * @param args array of argument strings 12226 * @param value value to search for 12227 * @return true if the value is contained in the array 12228 */ 12229 private static boolean scanArgs(String[] args, String value) { 12230 if (args != null) { 12231 for (String arg : args) { 12232 if (value.equals(arg)) { 12233 return true; 12234 } 12235 } 12236 } 12237 return false; 12238 } 12239 12240 private final boolean removeDyingProviderLocked(ProcessRecord proc, 12241 ContentProviderRecord cpr, boolean always) { 12242 final boolean inLaunching = mLaunchingProviders.contains(cpr); 12243 12244 if (!inLaunching || always) { 12245 synchronized (cpr) { 12246 cpr.launchingApp = null; 12247 cpr.notifyAll(); 12248 } 12249 mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid)); 12250 String names[] = cpr.info.authority.split(";"); 12251 for (int j = 0; j < names.length; j++) { 12252 mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid)); 12253 } 12254 } 12255 12256 for (int i=0; i<cpr.connections.size(); i++) { 12257 ContentProviderConnection conn = cpr.connections.get(i); 12258 if (conn.waiting) { 12259 // If this connection is waiting for the provider, then we don't 12260 // need to mess with its process unless we are always removing 12261 // or for some reason the provider is not currently launching. 12262 if (inLaunching && !always) { 12263 continue; 12264 } 12265 } 12266 ProcessRecord capp = conn.client; 12267 conn.dead = true; 12268 if (conn.stableCount > 0) { 12269 if (!capp.persistent && capp.thread != null 12270 && capp.pid != 0 12271 && capp.pid != MY_PID) { 12272 killUnneededProcessLocked(capp, "depends on provider " 12273 + cpr.name.flattenToShortString() 12274 + " in dying proc " + (proc != null ? proc.processName : "??")); 12275 } 12276 } else if (capp.thread != null && conn.provider.provider != null) { 12277 try { 12278 capp.thread.unstableProviderDied(conn.provider.provider.asBinder()); 12279 } catch (RemoteException e) { 12280 } 12281 // In the protocol here, we don't expect the client to correctly 12282 // clean up this connection, we'll just remove it. 12283 cpr.connections.remove(i); 12284 conn.client.conProviders.remove(conn); 12285 } 12286 } 12287 12288 if (inLaunching && always) { 12289 mLaunchingProviders.remove(cpr); 12290 } 12291 return inLaunching; 12292 } 12293 12294 /** 12295 * Main code for cleaning up a process when it has gone away. This is 12296 * called both as a result of the process dying, or directly when stopping 12297 * a process when running in single process mode. 12298 */ 12299 private final void cleanUpApplicationRecordLocked(ProcessRecord app, 12300 boolean restarting, boolean allowRestart, int index) { 12301 if (index >= 0) { 12302 removeLruProcessLocked(app); 12303 ProcessList.remove(app.pid); 12304 } 12305 12306 mProcessesToGc.remove(app); 12307 mPendingPssProcesses.remove(app); 12308 12309 // Dismiss any open dialogs. 12310 if (app.crashDialog != null && !app.forceCrashReport) { 12311 app.crashDialog.dismiss(); 12312 app.crashDialog = null; 12313 } 12314 if (app.anrDialog != null) { 12315 app.anrDialog.dismiss(); 12316 app.anrDialog = null; 12317 } 12318 if (app.waitDialog != null) { 12319 app.waitDialog.dismiss(); 12320 app.waitDialog = null; 12321 } 12322 12323 app.crashing = false; 12324 app.notResponding = false; 12325 12326 app.resetPackageList(mProcessStats); 12327 app.unlinkDeathRecipient(); 12328 app.makeInactive(mProcessStats); 12329 app.forcingToForeground = null; 12330 app.foregroundServices = false; 12331 app.foregroundActivities = false; 12332 app.hasShownUi = false; 12333 app.hasAboveClient = false; 12334 app.hasClientActivities = false; 12335 12336 mServices.killServicesLocked(app, allowRestart); 12337 12338 boolean restart = false; 12339 12340 // Remove published content providers. 12341 for (int i=app.pubProviders.size()-1; i>=0; i--) { 12342 ContentProviderRecord cpr = app.pubProviders.valueAt(i); 12343 final boolean always = app.bad || !allowRestart; 12344 if (removeDyingProviderLocked(app, cpr, always) || always) { 12345 // We left the provider in the launching list, need to 12346 // restart it. 12347 restart = true; 12348 } 12349 12350 cpr.provider = null; 12351 cpr.proc = null; 12352 } 12353 app.pubProviders.clear(); 12354 12355 // Take care of any launching providers waiting for this process. 12356 if (checkAppInLaunchingProvidersLocked(app, false)) { 12357 restart = true; 12358 } 12359 12360 // Unregister from connected content providers. 12361 if (!app.conProviders.isEmpty()) { 12362 for (int i=0; i<app.conProviders.size(); i++) { 12363 ContentProviderConnection conn = app.conProviders.get(i); 12364 conn.provider.connections.remove(conn); 12365 } 12366 app.conProviders.clear(); 12367 } 12368 12369 // At this point there may be remaining entries in mLaunchingProviders 12370 // where we were the only one waiting, so they are no longer of use. 12371 // Look for these and clean up if found. 12372 // XXX Commented out for now. Trying to figure out a way to reproduce 12373 // the actual situation to identify what is actually going on. 12374 if (false) { 12375 for (int i=0; i<mLaunchingProviders.size(); i++) { 12376 ContentProviderRecord cpr = (ContentProviderRecord) 12377 mLaunchingProviders.get(i); 12378 if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) { 12379 synchronized (cpr) { 12380 cpr.launchingApp = null; 12381 cpr.notifyAll(); 12382 } 12383 } 12384 } 12385 } 12386 12387 skipCurrentReceiverLocked(app); 12388 12389 // Unregister any receivers. 12390 for (int i=app.receivers.size()-1; i>=0; i--) { 12391 removeReceiverLocked(app.receivers.valueAt(i)); 12392 } 12393 app.receivers.clear(); 12394 12395 // If the app is undergoing backup, tell the backup manager about it 12396 if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) { 12397 if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App " 12398 + mBackupTarget.appInfo + " died during backup"); 12399 try { 12400 IBackupManager bm = IBackupManager.Stub.asInterface( 12401 ServiceManager.getService(Context.BACKUP_SERVICE)); 12402 bm.agentDisconnected(app.info.packageName); 12403 } catch (RemoteException e) { 12404 // can't happen; backup manager is local 12405 } 12406 } 12407 12408 for (int i = mPendingProcessChanges.size()-1; i>=0; i--) { 12409 ProcessChangeItem item = mPendingProcessChanges.get(i); 12410 if (item.pid == app.pid) { 12411 mPendingProcessChanges.remove(i); 12412 mAvailProcessChanges.add(item); 12413 } 12414 } 12415 mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget(); 12416 12417 // If the caller is restarting this app, then leave it in its 12418 // current lists and let the caller take care of it. 12419 if (restarting) { 12420 return; 12421 } 12422 12423 if (!app.persistent || app.isolated) { 12424 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, 12425 "Removing non-persistent process during cleanup: " + app); 12426 mProcessNames.remove(app.processName, app.uid); 12427 mIsolatedProcesses.remove(app.uid); 12428 if (mHeavyWeightProcess == app) { 12429 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 12430 mHeavyWeightProcess.userId, 0)); 12431 mHeavyWeightProcess = null; 12432 } 12433 } else if (!app.removed) { 12434 // This app is persistent, so we need to keep its record around. 12435 // If it is not already on the pending app list, add it there 12436 // and start a new process for it. 12437 if (mPersistentStartingProcesses.indexOf(app) < 0) { 12438 mPersistentStartingProcesses.add(app); 12439 restart = true; 12440 } 12441 } 12442 if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG, 12443 "Clean-up removing on hold: " + app); 12444 mProcessesOnHold.remove(app); 12445 12446 if (app == mHomeProcess) { 12447 mHomeProcess = null; 12448 } 12449 if (app == mPreviousProcess) { 12450 mPreviousProcess = null; 12451 } 12452 12453 if (restart && !app.isolated) { 12454 // We have components that still need to be running in the 12455 // process, so re-launch it. 12456 mProcessNames.put(app.processName, app.uid, app); 12457 startProcessLocked(app, "restart", app.processName); 12458 } else if (app.pid > 0 && app.pid != MY_PID) { 12459 // Goodbye! 12460 synchronized (mPidsSelfLocked) { 12461 mPidsSelfLocked.remove(app.pid); 12462 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 12463 } 12464 app.setPid(0); 12465 } 12466 } 12467 12468 boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) { 12469 // Look through the content providers we are waiting to have launched, 12470 // and if any run in this process then either schedule a restart of 12471 // the process or kill the client waiting for it if this process has 12472 // gone bad. 12473 int NL = mLaunchingProviders.size(); 12474 boolean restart = false; 12475 for (int i=0; i<NL; i++) { 12476 ContentProviderRecord cpr = mLaunchingProviders.get(i); 12477 if (cpr.launchingApp == app) { 12478 if (!alwaysBad && !app.bad) { 12479 restart = true; 12480 } else { 12481 removeDyingProviderLocked(app, cpr, true); 12482 // cpr should have been removed from mLaunchingProviders 12483 NL = mLaunchingProviders.size(); 12484 i--; 12485 } 12486 } 12487 } 12488 return restart; 12489 } 12490 12491 // ========================================================= 12492 // SERVICES 12493 // ========================================================= 12494 12495 public List<ActivityManager.RunningServiceInfo> getServices(int maxNum, 12496 int flags) { 12497 enforceNotIsolatedCaller("getServices"); 12498 synchronized (this) { 12499 return mServices.getRunningServiceInfoLocked(maxNum, flags); 12500 } 12501 } 12502 12503 public PendingIntent getRunningServiceControlPanel(ComponentName name) { 12504 enforceNotIsolatedCaller("getRunningServiceControlPanel"); 12505 synchronized (this) { 12506 return mServices.getRunningServiceControlPanelLocked(name); 12507 } 12508 } 12509 12510 public ComponentName startService(IApplicationThread caller, Intent service, 12511 String resolvedType, int userId) { 12512 enforceNotIsolatedCaller("startService"); 12513 // Refuse possible leaked file descriptors 12514 if (service != null && service.hasFileDescriptors() == true) { 12515 throw new IllegalArgumentException("File descriptors passed in Intent"); 12516 } 12517 12518 if (DEBUG_SERVICE) 12519 Slog.v(TAG, "startService: " + service + " type=" + resolvedType); 12520 synchronized(this) { 12521 final int callingPid = Binder.getCallingPid(); 12522 final int callingUid = Binder.getCallingUid(); 12523 final long origId = Binder.clearCallingIdentity(); 12524 ComponentName res = mServices.startServiceLocked(caller, service, 12525 resolvedType, callingPid, callingUid, userId); 12526 Binder.restoreCallingIdentity(origId); 12527 return res; 12528 } 12529 } 12530 12531 ComponentName startServiceInPackage(int uid, 12532 Intent service, String resolvedType, int userId) { 12533 synchronized(this) { 12534 if (DEBUG_SERVICE) 12535 Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType); 12536 final long origId = Binder.clearCallingIdentity(); 12537 ComponentName res = mServices.startServiceLocked(null, service, 12538 resolvedType, -1, uid, userId); 12539 Binder.restoreCallingIdentity(origId); 12540 return res; 12541 } 12542 } 12543 12544 public int stopService(IApplicationThread caller, Intent service, 12545 String resolvedType, int userId) { 12546 enforceNotIsolatedCaller("stopService"); 12547 // Refuse possible leaked file descriptors 12548 if (service != null && service.hasFileDescriptors() == true) { 12549 throw new IllegalArgumentException("File descriptors passed in Intent"); 12550 } 12551 12552 synchronized(this) { 12553 return mServices.stopServiceLocked(caller, service, resolvedType, userId); 12554 } 12555 } 12556 12557 public IBinder peekService(Intent service, String resolvedType) { 12558 enforceNotIsolatedCaller("peekService"); 12559 // Refuse possible leaked file descriptors 12560 if (service != null && service.hasFileDescriptors() == true) { 12561 throw new IllegalArgumentException("File descriptors passed in Intent"); 12562 } 12563 synchronized(this) { 12564 return mServices.peekServiceLocked(service, resolvedType); 12565 } 12566 } 12567 12568 public boolean stopServiceToken(ComponentName className, IBinder token, 12569 int startId) { 12570 synchronized(this) { 12571 return mServices.stopServiceTokenLocked(className, token, startId); 12572 } 12573 } 12574 12575 public void setServiceForeground(ComponentName className, IBinder token, 12576 int id, Notification notification, boolean removeNotification) { 12577 synchronized(this) { 12578 mServices.setServiceForegroundLocked(className, token, id, notification, 12579 removeNotification); 12580 } 12581 } 12582 12583 public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll, 12584 boolean requireFull, String name, String callerPackage) { 12585 final int callingUserId = UserHandle.getUserId(callingUid); 12586 if (callingUserId != userId) { 12587 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 12588 if ((requireFull || checkComponentPermission( 12589 android.Manifest.permission.INTERACT_ACROSS_USERS, 12590 callingPid, callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) 12591 && checkComponentPermission( 12592 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 12593 callingPid, callingUid, -1, true) 12594 != PackageManager.PERMISSION_GRANTED) { 12595 if (userId == UserHandle.USER_CURRENT_OR_SELF) { 12596 // In this case, they would like to just execute as their 12597 // owner user instead of failing. 12598 userId = callingUserId; 12599 } else { 12600 StringBuilder builder = new StringBuilder(128); 12601 builder.append("Permission Denial: "); 12602 builder.append(name); 12603 if (callerPackage != null) { 12604 builder.append(" from "); 12605 builder.append(callerPackage); 12606 } 12607 builder.append(" asks to run as user "); 12608 builder.append(userId); 12609 builder.append(" but is calling from user "); 12610 builder.append(UserHandle.getUserId(callingUid)); 12611 builder.append("; this requires "); 12612 builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL); 12613 if (!requireFull) { 12614 builder.append(" or "); 12615 builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS); 12616 } 12617 String msg = builder.toString(); 12618 Slog.w(TAG, msg); 12619 throw new SecurityException(msg); 12620 } 12621 } 12622 } 12623 if (userId == UserHandle.USER_CURRENT 12624 || userId == UserHandle.USER_CURRENT_OR_SELF) { 12625 // Note that we may be accessing this outside of a lock... 12626 // shouldn't be a big deal, if this is being called outside 12627 // of a locked context there is intrinsically a race with 12628 // the value the caller will receive and someone else changing it. 12629 userId = mCurrentUserId; 12630 } 12631 if (!allowAll && userId < 0) { 12632 throw new IllegalArgumentException( 12633 "Call does not support special user #" + userId); 12634 } 12635 } 12636 return userId; 12637 } 12638 12639 boolean isSingleton(String componentProcessName, ApplicationInfo aInfo, 12640 String className, int flags) { 12641 boolean result = false; 12642 if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) { 12643 if ((flags&ServiceInfo.FLAG_SINGLE_USER) != 0) { 12644 if (ActivityManager.checkUidPermission( 12645 android.Manifest.permission.INTERACT_ACROSS_USERS, 12646 aInfo.uid) != PackageManager.PERMISSION_GRANTED) { 12647 ComponentName comp = new ComponentName(aInfo.packageName, className); 12648 String msg = "Permission Denial: Component " + comp.flattenToShortString() 12649 + " requests FLAG_SINGLE_USER, but app does not hold " 12650 + android.Manifest.permission.INTERACT_ACROSS_USERS; 12651 Slog.w(TAG, msg); 12652 throw new SecurityException(msg); 12653 } 12654 result = true; 12655 } 12656 } else if (componentProcessName == aInfo.packageName) { 12657 result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0; 12658 } else if ("system".equals(componentProcessName)) { 12659 result = true; 12660 } 12661 if (DEBUG_MU) { 12662 Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo 12663 + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result); 12664 } 12665 return result; 12666 } 12667 12668 public int bindService(IApplicationThread caller, IBinder token, 12669 Intent service, String resolvedType, 12670 IServiceConnection connection, int flags, int userId) { 12671 enforceNotIsolatedCaller("bindService"); 12672 // Refuse possible leaked file descriptors 12673 if (service != null && service.hasFileDescriptors() == true) { 12674 throw new IllegalArgumentException("File descriptors passed in Intent"); 12675 } 12676 12677 synchronized(this) { 12678 return mServices.bindServiceLocked(caller, token, service, resolvedType, 12679 connection, flags, userId); 12680 } 12681 } 12682 12683 public boolean unbindService(IServiceConnection connection) { 12684 synchronized (this) { 12685 return mServices.unbindServiceLocked(connection); 12686 } 12687 } 12688 12689 public void publishService(IBinder token, Intent intent, IBinder service) { 12690 // Refuse possible leaked file descriptors 12691 if (intent != null && intent.hasFileDescriptors() == true) { 12692 throw new IllegalArgumentException("File descriptors passed in Intent"); 12693 } 12694 12695 synchronized(this) { 12696 if (!(token instanceof ServiceRecord)) { 12697 throw new IllegalArgumentException("Invalid service token"); 12698 } 12699 mServices.publishServiceLocked((ServiceRecord)token, intent, service); 12700 } 12701 } 12702 12703 public void unbindFinished(IBinder token, Intent intent, boolean doRebind) { 12704 // Refuse possible leaked file descriptors 12705 if (intent != null && intent.hasFileDescriptors() == true) { 12706 throw new IllegalArgumentException("File descriptors passed in Intent"); 12707 } 12708 12709 synchronized(this) { 12710 mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind); 12711 } 12712 } 12713 12714 public void serviceDoneExecuting(IBinder token, int type, int startId, int res) { 12715 synchronized(this) { 12716 if (!(token instanceof ServiceRecord)) { 12717 throw new IllegalArgumentException("Invalid service token"); 12718 } 12719 mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res); 12720 } 12721 } 12722 12723 // ========================================================= 12724 // BACKUP AND RESTORE 12725 // ========================================================= 12726 12727 // Cause the target app to be launched if necessary and its backup agent 12728 // instantiated. The backup agent will invoke backupAgentCreated() on the 12729 // activity manager to announce its creation. 12730 public boolean bindBackupAgent(ApplicationInfo app, int backupMode) { 12731 if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode); 12732 enforceCallingPermission("android.permission.BACKUP", "bindBackupAgent"); 12733 12734 synchronized(this) { 12735 // !!! TODO: currently no check here that we're already bound 12736 BatteryStatsImpl.Uid.Pkg.Serv ss = null; 12737 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 12738 synchronized (stats) { 12739 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name); 12740 } 12741 12742 // Backup agent is now in use, its package can't be stopped. 12743 try { 12744 AppGlobals.getPackageManager().setPackageStoppedState( 12745 app.packageName, false, UserHandle.getUserId(app.uid)); 12746 } catch (RemoteException e) { 12747 } catch (IllegalArgumentException e) { 12748 Slog.w(TAG, "Failed trying to unstop package " 12749 + app.packageName + ": " + e); 12750 } 12751 12752 BackupRecord r = new BackupRecord(ss, app, backupMode); 12753 ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL) 12754 ? new ComponentName(app.packageName, app.backupAgentName) 12755 : new ComponentName("android", "FullBackupAgent"); 12756 // startProcessLocked() returns existing proc's record if it's already running 12757 ProcessRecord proc = startProcessLocked(app.processName, app, 12758 false, 0, "backup", hostingName, false, false, false); 12759 if (proc == null) { 12760 Slog.e(TAG, "Unable to start backup agent process " + r); 12761 return false; 12762 } 12763 12764 r.app = proc; 12765 mBackupTarget = r; 12766 mBackupAppName = app.packageName; 12767 12768 // Try not to kill the process during backup 12769 updateOomAdjLocked(proc); 12770 12771 // If the process is already attached, schedule the creation of the backup agent now. 12772 // If it is not yet live, this will be done when it attaches to the framework. 12773 if (proc.thread != null) { 12774 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc); 12775 try { 12776 proc.thread.scheduleCreateBackupAgent(app, 12777 compatibilityInfoForPackageLocked(app), backupMode); 12778 } catch (RemoteException e) { 12779 // Will time out on the backup manager side 12780 } 12781 } else { 12782 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach"); 12783 } 12784 // Invariants: at this point, the target app process exists and the application 12785 // is either already running or in the process of coming up. mBackupTarget and 12786 // mBackupAppName describe the app, so that when it binds back to the AM we 12787 // know that it's scheduled for a backup-agent operation. 12788 } 12789 12790 return true; 12791 } 12792 12793 @Override 12794 public void clearPendingBackup() { 12795 if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup"); 12796 enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup"); 12797 12798 synchronized (this) { 12799 mBackupTarget = null; 12800 mBackupAppName = null; 12801 } 12802 } 12803 12804 // A backup agent has just come up 12805 public void backupAgentCreated(String agentPackageName, IBinder agent) { 12806 if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName 12807 + " = " + agent); 12808 12809 synchronized(this) { 12810 if (!agentPackageName.equals(mBackupAppName)) { 12811 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!"); 12812 return; 12813 } 12814 } 12815 12816 long oldIdent = Binder.clearCallingIdentity(); 12817 try { 12818 IBackupManager bm = IBackupManager.Stub.asInterface( 12819 ServiceManager.getService(Context.BACKUP_SERVICE)); 12820 bm.agentConnected(agentPackageName, agent); 12821 } catch (RemoteException e) { 12822 // can't happen; the backup manager service is local 12823 } catch (Exception e) { 12824 Slog.w(TAG, "Exception trying to deliver BackupAgent binding: "); 12825 e.printStackTrace(); 12826 } finally { 12827 Binder.restoreCallingIdentity(oldIdent); 12828 } 12829 } 12830 12831 // done with this agent 12832 public void unbindBackupAgent(ApplicationInfo appInfo) { 12833 if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo); 12834 if (appInfo == null) { 12835 Slog.w(TAG, "unbind backup agent for null app"); 12836 return; 12837 } 12838 12839 synchronized(this) { 12840 try { 12841 if (mBackupAppName == null) { 12842 Slog.w(TAG, "Unbinding backup agent with no active backup"); 12843 return; 12844 } 12845 12846 if (!mBackupAppName.equals(appInfo.packageName)) { 12847 Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target"); 12848 return; 12849 } 12850 12851 // Not backing this app up any more; reset its OOM adjustment 12852 final ProcessRecord proc = mBackupTarget.app; 12853 updateOomAdjLocked(proc); 12854 12855 // If the app crashed during backup, 'thread' will be null here 12856 if (proc.thread != null) { 12857 try { 12858 proc.thread.scheduleDestroyBackupAgent(appInfo, 12859 compatibilityInfoForPackageLocked(appInfo)); 12860 } catch (Exception e) { 12861 Slog.e(TAG, "Exception when unbinding backup agent:"); 12862 e.printStackTrace(); 12863 } 12864 } 12865 } finally { 12866 mBackupTarget = null; 12867 mBackupAppName = null; 12868 } 12869 } 12870 } 12871 // ========================================================= 12872 // BROADCASTS 12873 // ========================================================= 12874 12875 private final List getStickiesLocked(String action, IntentFilter filter, 12876 List cur, int userId) { 12877 final ContentResolver resolver = mContext.getContentResolver(); 12878 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 12879 if (stickies == null) { 12880 return cur; 12881 } 12882 final ArrayList<Intent> list = stickies.get(action); 12883 if (list == null) { 12884 return cur; 12885 } 12886 int N = list.size(); 12887 for (int i=0; i<N; i++) { 12888 Intent intent = list.get(i); 12889 if (filter.match(resolver, intent, true, TAG) >= 0) { 12890 if (cur == null) { 12891 cur = new ArrayList<Intent>(); 12892 } 12893 cur.add(intent); 12894 } 12895 } 12896 return cur; 12897 } 12898 12899 boolean isPendingBroadcastProcessLocked(int pid) { 12900 return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid) 12901 || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid); 12902 } 12903 12904 void skipPendingBroadcastLocked(int pid) { 12905 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 12906 for (BroadcastQueue queue : mBroadcastQueues) { 12907 queue.skipPendingBroadcastLocked(pid); 12908 } 12909 } 12910 12911 // The app just attached; send any pending broadcasts that it should receive 12912 boolean sendPendingBroadcastsLocked(ProcessRecord app) { 12913 boolean didSomething = false; 12914 for (BroadcastQueue queue : mBroadcastQueues) { 12915 didSomething |= queue.sendPendingBroadcastsLocked(app); 12916 } 12917 return didSomething; 12918 } 12919 12920 public Intent registerReceiver(IApplicationThread caller, String callerPackage, 12921 IIntentReceiver receiver, IntentFilter filter, String permission, int userId) { 12922 enforceNotIsolatedCaller("registerReceiver"); 12923 int callingUid; 12924 int callingPid; 12925 synchronized(this) { 12926 ProcessRecord callerApp = null; 12927 if (caller != null) { 12928 callerApp = getRecordForAppLocked(caller); 12929 if (callerApp == null) { 12930 throw new SecurityException( 12931 "Unable to find app for caller " + caller 12932 + " (pid=" + Binder.getCallingPid() 12933 + ") when registering receiver " + receiver); 12934 } 12935 if (callerApp.info.uid != Process.SYSTEM_UID && 12936 !callerApp.pkgList.containsKey(callerPackage) && 12937 !"android".equals(callerPackage)) { 12938 throw new SecurityException("Given caller package " + callerPackage 12939 + " is not running in process " + callerApp); 12940 } 12941 callingUid = callerApp.info.uid; 12942 callingPid = callerApp.pid; 12943 } else { 12944 callerPackage = null; 12945 callingUid = Binder.getCallingUid(); 12946 callingPid = Binder.getCallingPid(); 12947 } 12948 12949 userId = this.handleIncomingUser(callingPid, callingUid, userId, 12950 true, true, "registerReceiver", callerPackage); 12951 12952 List allSticky = null; 12953 12954 // Look for any matching sticky broadcasts... 12955 Iterator actions = filter.actionsIterator(); 12956 if (actions != null) { 12957 while (actions.hasNext()) { 12958 String action = (String)actions.next(); 12959 allSticky = getStickiesLocked(action, filter, allSticky, 12960 UserHandle.USER_ALL); 12961 allSticky = getStickiesLocked(action, filter, allSticky, 12962 UserHandle.getUserId(callingUid)); 12963 } 12964 } else { 12965 allSticky = getStickiesLocked(null, filter, allSticky, 12966 UserHandle.USER_ALL); 12967 allSticky = getStickiesLocked(null, filter, allSticky, 12968 UserHandle.getUserId(callingUid)); 12969 } 12970 12971 // The first sticky in the list is returned directly back to 12972 // the client. 12973 Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null; 12974 12975 if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter 12976 + ": " + sticky); 12977 12978 if (receiver == null) { 12979 return sticky; 12980 } 12981 12982 ReceiverList rl 12983 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder()); 12984 if (rl == null) { 12985 rl = new ReceiverList(this, callerApp, callingPid, callingUid, 12986 userId, receiver); 12987 if (rl.app != null) { 12988 rl.app.receivers.add(rl); 12989 } else { 12990 try { 12991 receiver.asBinder().linkToDeath(rl, 0); 12992 } catch (RemoteException e) { 12993 return sticky; 12994 } 12995 rl.linkedToDeath = true; 12996 } 12997 mRegisteredReceivers.put(receiver.asBinder(), rl); 12998 } else if (rl.uid != callingUid) { 12999 throw new IllegalArgumentException( 13000 "Receiver requested to register for uid " + callingUid 13001 + " was previously registered for uid " + rl.uid); 13002 } else if (rl.pid != callingPid) { 13003 throw new IllegalArgumentException( 13004 "Receiver requested to register for pid " + callingPid 13005 + " was previously registered for pid " + rl.pid); 13006 } else if (rl.userId != userId) { 13007 throw new IllegalArgumentException( 13008 "Receiver requested to register for user " + userId 13009 + " was previously registered for user " + rl.userId); 13010 } 13011 BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage, 13012 permission, callingUid, userId); 13013 rl.add(bf); 13014 if (!bf.debugCheck()) { 13015 Slog.w(TAG, "==> For Dynamic broadast"); 13016 } 13017 mReceiverResolver.addFilter(bf); 13018 13019 // Enqueue broadcasts for all existing stickies that match 13020 // this filter. 13021 if (allSticky != null) { 13022 ArrayList receivers = new ArrayList(); 13023 receivers.add(bf); 13024 13025 int N = allSticky.size(); 13026 for (int i=0; i<N; i++) { 13027 Intent intent = (Intent)allSticky.get(i); 13028 BroadcastQueue queue = broadcastQueueForIntent(intent); 13029 BroadcastRecord r = new BroadcastRecord(queue, intent, null, 13030 null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0, 13031 null, null, false, true, true, -1); 13032 queue.enqueueParallelBroadcastLocked(r); 13033 queue.scheduleBroadcastsLocked(); 13034 } 13035 } 13036 13037 return sticky; 13038 } 13039 } 13040 13041 public void unregisterReceiver(IIntentReceiver receiver) { 13042 if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver); 13043 13044 final long origId = Binder.clearCallingIdentity(); 13045 try { 13046 boolean doTrim = false; 13047 13048 synchronized(this) { 13049 ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder()); 13050 if (rl != null) { 13051 if (rl.curBroadcast != null) { 13052 BroadcastRecord r = rl.curBroadcast; 13053 final boolean doNext = finishReceiverLocked( 13054 receiver.asBinder(), r.resultCode, r.resultData, 13055 r.resultExtras, r.resultAbort); 13056 if (doNext) { 13057 doTrim = true; 13058 r.queue.processNextBroadcast(false); 13059 } 13060 } 13061 13062 if (rl.app != null) { 13063 rl.app.receivers.remove(rl); 13064 } 13065 removeReceiverLocked(rl); 13066 if (rl.linkedToDeath) { 13067 rl.linkedToDeath = false; 13068 rl.receiver.asBinder().unlinkToDeath(rl, 0); 13069 } 13070 } 13071 } 13072 13073 // If we actually concluded any broadcasts, we might now be able 13074 // to trim the recipients' apps from our working set 13075 if (doTrim) { 13076 trimApplications(); 13077 return; 13078 } 13079 13080 } finally { 13081 Binder.restoreCallingIdentity(origId); 13082 } 13083 } 13084 13085 void removeReceiverLocked(ReceiverList rl) { 13086 mRegisteredReceivers.remove(rl.receiver.asBinder()); 13087 int N = rl.size(); 13088 for (int i=0; i<N; i++) { 13089 mReceiverResolver.removeFilter(rl.get(i)); 13090 } 13091 } 13092 13093 private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) { 13094 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 13095 ProcessRecord r = mLruProcesses.get(i); 13096 if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) { 13097 try { 13098 r.thread.dispatchPackageBroadcast(cmd, packages); 13099 } catch (RemoteException ex) { 13100 } 13101 } 13102 } 13103 } 13104 13105 private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType, 13106 int[] users) { 13107 List<ResolveInfo> receivers = null; 13108 try { 13109 HashSet<ComponentName> singleUserReceivers = null; 13110 boolean scannedFirstReceivers = false; 13111 for (int user : users) { 13112 List<ResolveInfo> newReceivers = AppGlobals.getPackageManager() 13113 .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user); 13114 if (user != 0 && newReceivers != null) { 13115 // If this is not the primary user, we need to check for 13116 // any receivers that should be filtered out. 13117 for (int i=0; i<newReceivers.size(); i++) { 13118 ResolveInfo ri = newReceivers.get(i); 13119 if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) { 13120 newReceivers.remove(i); 13121 i--; 13122 } 13123 } 13124 } 13125 if (newReceivers != null && newReceivers.size() == 0) { 13126 newReceivers = null; 13127 } 13128 if (receivers == null) { 13129 receivers = newReceivers; 13130 } else if (newReceivers != null) { 13131 // We need to concatenate the additional receivers 13132 // found with what we have do far. This would be easy, 13133 // but we also need to de-dup any receivers that are 13134 // singleUser. 13135 if (!scannedFirstReceivers) { 13136 // Collect any single user receivers we had already retrieved. 13137 scannedFirstReceivers = true; 13138 for (int i=0; i<receivers.size(); i++) { 13139 ResolveInfo ri = receivers.get(i); 13140 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 13141 ComponentName cn = new ComponentName( 13142 ri.activityInfo.packageName, ri.activityInfo.name); 13143 if (singleUserReceivers == null) { 13144 singleUserReceivers = new HashSet<ComponentName>(); 13145 } 13146 singleUserReceivers.add(cn); 13147 } 13148 } 13149 } 13150 // Add the new results to the existing results, tracking 13151 // and de-dupping single user receivers. 13152 for (int i=0; i<newReceivers.size(); i++) { 13153 ResolveInfo ri = newReceivers.get(i); 13154 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 13155 ComponentName cn = new ComponentName( 13156 ri.activityInfo.packageName, ri.activityInfo.name); 13157 if (singleUserReceivers == null) { 13158 singleUserReceivers = new HashSet<ComponentName>(); 13159 } 13160 if (!singleUserReceivers.contains(cn)) { 13161 singleUserReceivers.add(cn); 13162 receivers.add(ri); 13163 } 13164 } else { 13165 receivers.add(ri); 13166 } 13167 } 13168 } 13169 } 13170 } catch (RemoteException ex) { 13171 // pm is in same process, this will never happen. 13172 } 13173 return receivers; 13174 } 13175 13176 private final int broadcastIntentLocked(ProcessRecord callerApp, 13177 String callerPackage, Intent intent, String resolvedType, 13178 IIntentReceiver resultTo, int resultCode, String resultData, 13179 Bundle map, String requiredPermission, int appOp, 13180 boolean ordered, boolean sticky, int callingPid, int callingUid, 13181 int userId) { 13182 intent = new Intent(intent); 13183 13184 // By default broadcasts do not go to stopped apps. 13185 intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES); 13186 13187 if (DEBUG_BROADCAST_LIGHT) Slog.v( 13188 TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent 13189 + " ordered=" + ordered + " userid=" + userId); 13190 if ((resultTo != null) && !ordered) { 13191 Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!"); 13192 } 13193 13194 userId = handleIncomingUser(callingPid, callingUid, userId, 13195 true, false, "broadcast", callerPackage); 13196 13197 // Make sure that the user who is receiving this broadcast is started. 13198 // If not, we will just skip it. 13199 if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) { 13200 if (callingUid != Process.SYSTEM_UID || (intent.getFlags() 13201 & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) { 13202 Slog.w(TAG, "Skipping broadcast of " + intent 13203 + ": user " + userId + " is stopped"); 13204 return ActivityManager.BROADCAST_SUCCESS; 13205 } 13206 } 13207 13208 /* 13209 * Prevent non-system code (defined here to be non-persistent 13210 * processes) from sending protected broadcasts. 13211 */ 13212 int callingAppId = UserHandle.getAppId(callingUid); 13213 if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID 13214 || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID || 13215 callingUid == 0) { 13216 // Always okay. 13217 } else if (callerApp == null || !callerApp.persistent) { 13218 try { 13219 if (AppGlobals.getPackageManager().isProtectedBroadcast( 13220 intent.getAction())) { 13221 String msg = "Permission Denial: not allowed to send broadcast " 13222 + intent.getAction() + " from pid=" 13223 + callingPid + ", uid=" + callingUid; 13224 Slog.w(TAG, msg); 13225 throw new SecurityException(msg); 13226 } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) { 13227 // Special case for compatibility: we don't want apps to send this, 13228 // but historically it has not been protected and apps may be using it 13229 // to poke their own app widget. So, instead of making it protected, 13230 // just limit it to the caller. 13231 if (callerApp == null) { 13232 String msg = "Permission Denial: not allowed to send broadcast " 13233 + intent.getAction() + " from unknown caller."; 13234 Slog.w(TAG, msg); 13235 throw new SecurityException(msg); 13236 } else if (intent.getComponent() != null) { 13237 // They are good enough to send to an explicit component... verify 13238 // it is being sent to the calling app. 13239 if (!intent.getComponent().getPackageName().equals( 13240 callerApp.info.packageName)) { 13241 String msg = "Permission Denial: not allowed to send broadcast " 13242 + intent.getAction() + " to " 13243 + intent.getComponent().getPackageName() + " from " 13244 + callerApp.info.packageName; 13245 Slog.w(TAG, msg); 13246 throw new SecurityException(msg); 13247 } 13248 } else { 13249 // Limit broadcast to their own package. 13250 intent.setPackage(callerApp.info.packageName); 13251 } 13252 } 13253 } catch (RemoteException e) { 13254 Slog.w(TAG, "Remote exception", e); 13255 return ActivityManager.BROADCAST_SUCCESS; 13256 } 13257 } 13258 13259 // Handle special intents: if this broadcast is from the package 13260 // manager about a package being removed, we need to remove all of 13261 // its activities from the history stack. 13262 final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals( 13263 intent.getAction()); 13264 if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction()) 13265 || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction()) 13266 || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction()) 13267 || uidRemoved) { 13268 if (checkComponentPermission( 13269 android.Manifest.permission.BROADCAST_PACKAGE_REMOVED, 13270 callingPid, callingUid, -1, true) 13271 == PackageManager.PERMISSION_GRANTED) { 13272 if (uidRemoved) { 13273 final Bundle intentExtras = intent.getExtras(); 13274 final int uid = intentExtras != null 13275 ? intentExtras.getInt(Intent.EXTRA_UID) : -1; 13276 if (uid >= 0) { 13277 BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics(); 13278 synchronized (bs) { 13279 bs.removeUidStatsLocked(uid); 13280 } 13281 mAppOpsService.uidRemoved(uid); 13282 } 13283 } else { 13284 // If resources are unavailable just force stop all 13285 // those packages and flush the attribute cache as well. 13286 if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) { 13287 String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 13288 if (list != null && (list.length > 0)) { 13289 for (String pkg : list) { 13290 forceStopPackageLocked(pkg, -1, false, true, true, false, userId, 13291 "storage unmount"); 13292 } 13293 sendPackageBroadcastLocked( 13294 IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId); 13295 } 13296 } else { 13297 Uri data = intent.getData(); 13298 String ssp; 13299 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 13300 boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals( 13301 intent.getAction()); 13302 if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) { 13303 forceStopPackageLocked(ssp, UserHandle.getAppId( 13304 intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true, 13305 false, userId, removed ? "pkg removed" : "pkg changed"); 13306 } 13307 if (removed) { 13308 sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED, 13309 new String[] {ssp}, userId); 13310 if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) { 13311 mAppOpsService.packageRemoved( 13312 intent.getIntExtra(Intent.EXTRA_UID, -1), ssp); 13313 13314 // Remove all permissions granted from/to this package 13315 removeUriPermissionsForPackageLocked(ssp, userId, true); 13316 } 13317 } 13318 } 13319 } 13320 } 13321 } else { 13322 String msg = "Permission Denial: " + intent.getAction() 13323 + " broadcast from " + callerPackage + " (pid=" + callingPid 13324 + ", uid=" + callingUid + ")" 13325 + " requires " 13326 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED; 13327 Slog.w(TAG, msg); 13328 throw new SecurityException(msg); 13329 } 13330 13331 // Special case for adding a package: by default turn on compatibility 13332 // mode. 13333 } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) { 13334 Uri data = intent.getData(); 13335 String ssp; 13336 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 13337 mCompatModePackages.handlePackageAddedLocked(ssp, 13338 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)); 13339 } 13340 } 13341 13342 /* 13343 * If this is the time zone changed action, queue up a message that will reset the timezone 13344 * of all currently running processes. This message will get queued up before the broadcast 13345 * happens. 13346 */ 13347 if (Intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) { 13348 mHandler.sendEmptyMessage(UPDATE_TIME_ZONE); 13349 } 13350 13351 /* 13352 * If the user set the time, let all running processes know. 13353 */ 13354 if (Intent.ACTION_TIME_CHANGED.equals(intent.getAction())) { 13355 final int is24Hour = intent.getBooleanExtra( 13356 Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1 : 0; 13357 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0)); 13358 } 13359 13360 if (Intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) { 13361 mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG); 13362 } 13363 13364 if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) { 13365 ProxyProperties proxy = intent.getParcelableExtra("proxy"); 13366 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy)); 13367 } 13368 13369 // Add to the sticky list if requested. 13370 if (sticky) { 13371 if (checkPermission(android.Manifest.permission.BROADCAST_STICKY, 13372 callingPid, callingUid) 13373 != PackageManager.PERMISSION_GRANTED) { 13374 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid=" 13375 + callingPid + ", uid=" + callingUid 13376 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 13377 Slog.w(TAG, msg); 13378 throw new SecurityException(msg); 13379 } 13380 if (requiredPermission != null) { 13381 Slog.w(TAG, "Can't broadcast sticky intent " + intent 13382 + " and enforce permission " + requiredPermission); 13383 return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION; 13384 } 13385 if (intent.getComponent() != null) { 13386 throw new SecurityException( 13387 "Sticky broadcasts can't target a specific component"); 13388 } 13389 // We use userId directly here, since the "all" target is maintained 13390 // as a separate set of sticky broadcasts. 13391 if (userId != UserHandle.USER_ALL) { 13392 // But first, if this is not a broadcast to all users, then 13393 // make sure it doesn't conflict with an existing broadcast to 13394 // all users. 13395 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get( 13396 UserHandle.USER_ALL); 13397 if (stickies != null) { 13398 ArrayList<Intent> list = stickies.get(intent.getAction()); 13399 if (list != null) { 13400 int N = list.size(); 13401 int i; 13402 for (i=0; i<N; i++) { 13403 if (intent.filterEquals(list.get(i))) { 13404 throw new IllegalArgumentException( 13405 "Sticky broadcast " + intent + " for user " 13406 + userId + " conflicts with existing global broadcast"); 13407 } 13408 } 13409 } 13410 } 13411 } 13412 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 13413 if (stickies == null) { 13414 stickies = new ArrayMap<String, ArrayList<Intent>>(); 13415 mStickyBroadcasts.put(userId, stickies); 13416 } 13417 ArrayList<Intent> list = stickies.get(intent.getAction()); 13418 if (list == null) { 13419 list = new ArrayList<Intent>(); 13420 stickies.put(intent.getAction(), list); 13421 } 13422 int N = list.size(); 13423 int i; 13424 for (i=0; i<N; i++) { 13425 if (intent.filterEquals(list.get(i))) { 13426 // This sticky already exists, replace it. 13427 list.set(i, new Intent(intent)); 13428 break; 13429 } 13430 } 13431 if (i >= N) { 13432 list.add(new Intent(intent)); 13433 } 13434 } 13435 13436 int[] users; 13437 if (userId == UserHandle.USER_ALL) { 13438 // Caller wants broadcast to go to all started users. 13439 users = mStartedUserArray; 13440 } else { 13441 // Caller wants broadcast to go to one specific user. 13442 users = new int[] {userId}; 13443 } 13444 13445 // Figure out who all will receive this broadcast. 13446 List receivers = null; 13447 List<BroadcastFilter> registeredReceivers = null; 13448 // Need to resolve the intent to interested receivers... 13449 if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) 13450 == 0) { 13451 receivers = collectReceiverComponents(intent, resolvedType, users); 13452 } 13453 if (intent.getComponent() == null) { 13454 registeredReceivers = mReceiverResolver.queryIntent(intent, 13455 resolvedType, false, userId); 13456 } 13457 13458 final boolean replacePending = 13459 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0; 13460 13461 if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction() 13462 + " replacePending=" + replacePending); 13463 13464 int NR = registeredReceivers != null ? registeredReceivers.size() : 0; 13465 if (!ordered && NR > 0) { 13466 // If we are not serializing this broadcast, then send the 13467 // registered receivers separately so they don't wait for the 13468 // components to be launched. 13469 final BroadcastQueue queue = broadcastQueueForIntent(intent); 13470 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 13471 callerPackage, callingPid, callingUid, resolvedType, requiredPermission, 13472 appOp, registeredReceivers, resultTo, resultCode, resultData, map, 13473 ordered, sticky, false, userId); 13474 if (DEBUG_BROADCAST) Slog.v( 13475 TAG, "Enqueueing parallel broadcast " + r); 13476 final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r); 13477 if (!replaced) { 13478 queue.enqueueParallelBroadcastLocked(r); 13479 queue.scheduleBroadcastsLocked(); 13480 } 13481 registeredReceivers = null; 13482 NR = 0; 13483 } 13484 13485 // Merge into one list. 13486 int ir = 0; 13487 if (receivers != null) { 13488 // A special case for PACKAGE_ADDED: do not allow the package 13489 // being added to see this broadcast. This prevents them from 13490 // using this as a back door to get run as soon as they are 13491 // installed. Maybe in the future we want to have a special install 13492 // broadcast or such for apps, but we'd like to deliberately make 13493 // this decision. 13494 String skipPackages[] = null; 13495 if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction()) 13496 || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction()) 13497 || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) { 13498 Uri data = intent.getData(); 13499 if (data != null) { 13500 String pkgName = data.getSchemeSpecificPart(); 13501 if (pkgName != null) { 13502 skipPackages = new String[] { pkgName }; 13503 } 13504 } 13505 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) { 13506 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 13507 } 13508 if (skipPackages != null && (skipPackages.length > 0)) { 13509 for (String skipPackage : skipPackages) { 13510 if (skipPackage != null) { 13511 int NT = receivers.size(); 13512 for (int it=0; it<NT; it++) { 13513 ResolveInfo curt = (ResolveInfo)receivers.get(it); 13514 if (curt.activityInfo.packageName.equals(skipPackage)) { 13515 receivers.remove(it); 13516 it--; 13517 NT--; 13518 } 13519 } 13520 } 13521 } 13522 } 13523 13524 int NT = receivers != null ? receivers.size() : 0; 13525 int it = 0; 13526 ResolveInfo curt = null; 13527 BroadcastFilter curr = null; 13528 while (it < NT && ir < NR) { 13529 if (curt == null) { 13530 curt = (ResolveInfo)receivers.get(it); 13531 } 13532 if (curr == null) { 13533 curr = registeredReceivers.get(ir); 13534 } 13535 if (curr.getPriority() >= curt.priority) { 13536 // Insert this broadcast record into the final list. 13537 receivers.add(it, curr); 13538 ir++; 13539 curr = null; 13540 it++; 13541 NT++; 13542 } else { 13543 // Skip to the next ResolveInfo in the final list. 13544 it++; 13545 curt = null; 13546 } 13547 } 13548 } 13549 while (ir < NR) { 13550 if (receivers == null) { 13551 receivers = new ArrayList(); 13552 } 13553 receivers.add(registeredReceivers.get(ir)); 13554 ir++; 13555 } 13556 13557 if ((receivers != null && receivers.size() > 0) 13558 || resultTo != null) { 13559 BroadcastQueue queue = broadcastQueueForIntent(intent); 13560 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 13561 callerPackage, callingPid, callingUid, resolvedType, 13562 requiredPermission, appOp, receivers, resultTo, resultCode, 13563 resultData, map, ordered, sticky, false, userId); 13564 if (DEBUG_BROADCAST) Slog.v( 13565 TAG, "Enqueueing ordered broadcast " + r 13566 + ": prev had " + queue.mOrderedBroadcasts.size()); 13567 if (DEBUG_BROADCAST) { 13568 int seq = r.intent.getIntExtra("seq", -1); 13569 Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq); 13570 } 13571 boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r); 13572 if (!replaced) { 13573 queue.enqueueOrderedBroadcastLocked(r); 13574 queue.scheduleBroadcastsLocked(); 13575 } 13576 } 13577 13578 return ActivityManager.BROADCAST_SUCCESS; 13579 } 13580 13581 final Intent verifyBroadcastLocked(Intent intent) { 13582 // Refuse possible leaked file descriptors 13583 if (intent != null && intent.hasFileDescriptors() == true) { 13584 throw new IllegalArgumentException("File descriptors passed in Intent"); 13585 } 13586 13587 int flags = intent.getFlags(); 13588 13589 if (!mProcessesReady) { 13590 // if the caller really truly claims to know what they're doing, go 13591 // ahead and allow the broadcast without launching any receivers 13592 if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) { 13593 intent = new Intent(intent); 13594 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 13595 } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) { 13596 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent 13597 + " before boot completion"); 13598 throw new IllegalStateException("Cannot broadcast before boot completed"); 13599 } 13600 } 13601 13602 if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 13603 throw new IllegalArgumentException( 13604 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 13605 } 13606 13607 return intent; 13608 } 13609 13610 public final int broadcastIntent(IApplicationThread caller, 13611 Intent intent, String resolvedType, IIntentReceiver resultTo, 13612 int resultCode, String resultData, Bundle map, 13613 String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) { 13614 enforceNotIsolatedCaller("broadcastIntent"); 13615 synchronized(this) { 13616 intent = verifyBroadcastLocked(intent); 13617 13618 final ProcessRecord callerApp = getRecordForAppLocked(caller); 13619 final int callingPid = Binder.getCallingPid(); 13620 final int callingUid = Binder.getCallingUid(); 13621 final long origId = Binder.clearCallingIdentity(); 13622 int res = broadcastIntentLocked(callerApp, 13623 callerApp != null ? callerApp.info.packageName : null, 13624 intent, resolvedType, resultTo, 13625 resultCode, resultData, map, requiredPermission, appOp, serialized, sticky, 13626 callingPid, callingUid, userId); 13627 Binder.restoreCallingIdentity(origId); 13628 return res; 13629 } 13630 } 13631 13632 int broadcastIntentInPackage(String packageName, int uid, 13633 Intent intent, String resolvedType, IIntentReceiver resultTo, 13634 int resultCode, String resultData, Bundle map, 13635 String requiredPermission, boolean serialized, boolean sticky, int userId) { 13636 synchronized(this) { 13637 intent = verifyBroadcastLocked(intent); 13638 13639 final long origId = Binder.clearCallingIdentity(); 13640 int res = broadcastIntentLocked(null, packageName, intent, resolvedType, 13641 resultTo, resultCode, resultData, map, requiredPermission, 13642 AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId); 13643 Binder.restoreCallingIdentity(origId); 13644 return res; 13645 } 13646 } 13647 13648 public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) { 13649 // Refuse possible leaked file descriptors 13650 if (intent != null && intent.hasFileDescriptors() == true) { 13651 throw new IllegalArgumentException("File descriptors passed in Intent"); 13652 } 13653 13654 userId = handleIncomingUser(Binder.getCallingPid(), 13655 Binder.getCallingUid(), userId, true, false, "removeStickyBroadcast", null); 13656 13657 synchronized(this) { 13658 if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY) 13659 != PackageManager.PERMISSION_GRANTED) { 13660 String msg = "Permission Denial: unbroadcastIntent() from pid=" 13661 + Binder.getCallingPid() 13662 + ", uid=" + Binder.getCallingUid() 13663 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 13664 Slog.w(TAG, msg); 13665 throw new SecurityException(msg); 13666 } 13667 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 13668 if (stickies != null) { 13669 ArrayList<Intent> list = stickies.get(intent.getAction()); 13670 if (list != null) { 13671 int N = list.size(); 13672 int i; 13673 for (i=0; i<N; i++) { 13674 if (intent.filterEquals(list.get(i))) { 13675 list.remove(i); 13676 break; 13677 } 13678 } 13679 if (list.size() <= 0) { 13680 stickies.remove(intent.getAction()); 13681 } 13682 } 13683 if (stickies.size() <= 0) { 13684 mStickyBroadcasts.remove(userId); 13685 } 13686 } 13687 } 13688 } 13689 13690 private final boolean finishReceiverLocked(IBinder receiver, int resultCode, 13691 String resultData, Bundle resultExtras, boolean resultAbort) { 13692 final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver); 13693 if (r == null) { 13694 Slog.w(TAG, "finishReceiver called but not found on queue"); 13695 return false; 13696 } 13697 13698 return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false); 13699 } 13700 13701 void backgroundServicesFinishedLocked(int userId) { 13702 for (BroadcastQueue queue : mBroadcastQueues) { 13703 queue.backgroundServicesFinishedLocked(userId); 13704 } 13705 } 13706 13707 public void finishReceiver(IBinder who, int resultCode, String resultData, 13708 Bundle resultExtras, boolean resultAbort) { 13709 if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who); 13710 13711 // Refuse possible leaked file descriptors 13712 if (resultExtras != null && resultExtras.hasFileDescriptors()) { 13713 throw new IllegalArgumentException("File descriptors passed in Bundle"); 13714 } 13715 13716 final long origId = Binder.clearCallingIdentity(); 13717 try { 13718 boolean doNext = false; 13719 BroadcastRecord r; 13720 13721 synchronized(this) { 13722 r = broadcastRecordForReceiverLocked(who); 13723 if (r != null) { 13724 doNext = r.queue.finishReceiverLocked(r, resultCode, 13725 resultData, resultExtras, resultAbort, true); 13726 } 13727 } 13728 13729 if (doNext) { 13730 r.queue.processNextBroadcast(false); 13731 } 13732 trimApplications(); 13733 } finally { 13734 Binder.restoreCallingIdentity(origId); 13735 } 13736 } 13737 13738 // ========================================================= 13739 // INSTRUMENTATION 13740 // ========================================================= 13741 13742 public boolean startInstrumentation(ComponentName className, 13743 String profileFile, int flags, Bundle arguments, 13744 IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection, 13745 int userId) { 13746 enforceNotIsolatedCaller("startInstrumentation"); 13747 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 13748 userId, false, true, "startInstrumentation", null); 13749 // Refuse possible leaked file descriptors 13750 if (arguments != null && arguments.hasFileDescriptors()) { 13751 throw new IllegalArgumentException("File descriptors passed in Bundle"); 13752 } 13753 13754 synchronized(this) { 13755 InstrumentationInfo ii = null; 13756 ApplicationInfo ai = null; 13757 try { 13758 ii = mContext.getPackageManager().getInstrumentationInfo( 13759 className, STOCK_PM_FLAGS); 13760 ai = AppGlobals.getPackageManager().getApplicationInfo( 13761 ii.targetPackage, STOCK_PM_FLAGS, userId); 13762 } catch (PackageManager.NameNotFoundException e) { 13763 } catch (RemoteException e) { 13764 } 13765 if (ii == null) { 13766 reportStartInstrumentationFailure(watcher, className, 13767 "Unable to find instrumentation info for: " + className); 13768 return false; 13769 } 13770 if (ai == null) { 13771 reportStartInstrumentationFailure(watcher, className, 13772 "Unable to find instrumentation target package: " + ii.targetPackage); 13773 return false; 13774 } 13775 13776 int match = mContext.getPackageManager().checkSignatures( 13777 ii.targetPackage, ii.packageName); 13778 if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) { 13779 String msg = "Permission Denial: starting instrumentation " 13780 + className + " from pid=" 13781 + Binder.getCallingPid() 13782 + ", uid=" + Binder.getCallingPid() 13783 + " not allowed because package " + ii.packageName 13784 + " does not have a signature matching the target " 13785 + ii.targetPackage; 13786 reportStartInstrumentationFailure(watcher, className, msg); 13787 throw new SecurityException(msg); 13788 } 13789 13790 final long origId = Binder.clearCallingIdentity(); 13791 // Instrumentation can kill and relaunch even persistent processes 13792 forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, userId, 13793 "start instr"); 13794 ProcessRecord app = addAppLocked(ai, false); 13795 app.instrumentationClass = className; 13796 app.instrumentationInfo = ai; 13797 app.instrumentationProfileFile = profileFile; 13798 app.instrumentationArguments = arguments; 13799 app.instrumentationWatcher = watcher; 13800 app.instrumentationUiAutomationConnection = uiAutomationConnection; 13801 app.instrumentationResultClass = className; 13802 Binder.restoreCallingIdentity(origId); 13803 } 13804 13805 return true; 13806 } 13807 13808 /** 13809 * Report errors that occur while attempting to start Instrumentation. Always writes the 13810 * error to the logs, but if somebody is watching, send the report there too. This enables 13811 * the "am" command to report errors with more information. 13812 * 13813 * @param watcher The IInstrumentationWatcher. Null if there isn't one. 13814 * @param cn The component name of the instrumentation. 13815 * @param report The error report. 13816 */ 13817 private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher, 13818 ComponentName cn, String report) { 13819 Slog.w(TAG, report); 13820 try { 13821 if (watcher != null) { 13822 Bundle results = new Bundle(); 13823 results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService"); 13824 results.putString("Error", report); 13825 watcher.instrumentationStatus(cn, -1, results); 13826 } 13827 } catch (RemoteException e) { 13828 Slog.w(TAG, e); 13829 } 13830 } 13831 13832 void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) { 13833 if (app.instrumentationWatcher != null) { 13834 try { 13835 // NOTE: IInstrumentationWatcher *must* be oneway here 13836 app.instrumentationWatcher.instrumentationFinished( 13837 app.instrumentationClass, 13838 resultCode, 13839 results); 13840 } catch (RemoteException e) { 13841 } 13842 } 13843 if (app.instrumentationUiAutomationConnection != null) { 13844 try { 13845 app.instrumentationUiAutomationConnection.shutdown(); 13846 } catch (RemoteException re) { 13847 /* ignore */ 13848 } 13849 // Only a UiAutomation can set this flag and now that 13850 // it is finished we make sure it is reset to its default. 13851 mUserIsMonkey = false; 13852 } 13853 app.instrumentationWatcher = null; 13854 app.instrumentationUiAutomationConnection = null; 13855 app.instrumentationClass = null; 13856 app.instrumentationInfo = null; 13857 app.instrumentationProfileFile = null; 13858 app.instrumentationArguments = null; 13859 13860 forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, app.userId, 13861 "finished inst"); 13862 } 13863 13864 public void finishInstrumentation(IApplicationThread target, 13865 int resultCode, Bundle results) { 13866 int userId = UserHandle.getCallingUserId(); 13867 // Refuse possible leaked file descriptors 13868 if (results != null && results.hasFileDescriptors()) { 13869 throw new IllegalArgumentException("File descriptors passed in Intent"); 13870 } 13871 13872 synchronized(this) { 13873 ProcessRecord app = getRecordForAppLocked(target); 13874 if (app == null) { 13875 Slog.w(TAG, "finishInstrumentation: no app for " + target); 13876 return; 13877 } 13878 final long origId = Binder.clearCallingIdentity(); 13879 finishInstrumentationLocked(app, resultCode, results); 13880 Binder.restoreCallingIdentity(origId); 13881 } 13882 } 13883 13884 // ========================================================= 13885 // CONFIGURATION 13886 // ========================================================= 13887 13888 public ConfigurationInfo getDeviceConfigurationInfo() { 13889 ConfigurationInfo config = new ConfigurationInfo(); 13890 synchronized (this) { 13891 config.reqTouchScreen = mConfiguration.touchscreen; 13892 config.reqKeyboardType = mConfiguration.keyboard; 13893 config.reqNavigation = mConfiguration.navigation; 13894 if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD 13895 || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) { 13896 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV; 13897 } 13898 if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED 13899 && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) { 13900 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD; 13901 } 13902 config.reqGlEsVersion = GL_ES_VERSION; 13903 } 13904 return config; 13905 } 13906 13907 ActivityStack getFocusedStack() { 13908 return mStackSupervisor.getFocusedStack(); 13909 } 13910 13911 public Configuration getConfiguration() { 13912 Configuration ci; 13913 synchronized(this) { 13914 ci = new Configuration(mConfiguration); 13915 } 13916 return ci; 13917 } 13918 13919 public void updatePersistentConfiguration(Configuration values) { 13920 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 13921 "updateConfiguration()"); 13922 enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS, 13923 "updateConfiguration()"); 13924 if (values == null) { 13925 throw new NullPointerException("Configuration must not be null"); 13926 } 13927 13928 synchronized(this) { 13929 final long origId = Binder.clearCallingIdentity(); 13930 updateConfigurationLocked(values, null, true, false); 13931 Binder.restoreCallingIdentity(origId); 13932 } 13933 } 13934 13935 public void updateConfiguration(Configuration values) { 13936 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 13937 "updateConfiguration()"); 13938 13939 synchronized(this) { 13940 if (values == null && mWindowManager != null) { 13941 // sentinel: fetch the current configuration from the window manager 13942 values = mWindowManager.computeNewConfiguration(); 13943 } 13944 13945 if (mWindowManager != null) { 13946 mProcessList.applyDisplaySize(mWindowManager); 13947 } 13948 13949 final long origId = Binder.clearCallingIdentity(); 13950 if (values != null) { 13951 Settings.System.clearConfiguration(values); 13952 } 13953 updateConfigurationLocked(values, null, false, false); 13954 Binder.restoreCallingIdentity(origId); 13955 } 13956 } 13957 13958 /** 13959 * Do either or both things: (1) change the current configuration, and (2) 13960 * make sure the given activity is running with the (now) current 13961 * configuration. Returns true if the activity has been left running, or 13962 * false if <var>starting</var> is being destroyed to match the new 13963 * configuration. 13964 * @param persistent TODO 13965 */ 13966 boolean updateConfigurationLocked(Configuration values, 13967 ActivityRecord starting, boolean persistent, boolean initLocale) { 13968 int changes = 0; 13969 13970 if (values != null) { 13971 Configuration newConfig = new Configuration(mConfiguration); 13972 changes = newConfig.updateFrom(values); 13973 if (changes != 0) { 13974 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) { 13975 Slog.i(TAG, "Updating configuration to: " + values); 13976 } 13977 13978 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes); 13979 13980 if (values.locale != null && !initLocale) { 13981 saveLocaleLocked(values.locale, 13982 !values.locale.equals(mConfiguration.locale), 13983 values.userSetLocale); 13984 } 13985 13986 mConfigurationSeq++; 13987 if (mConfigurationSeq <= 0) { 13988 mConfigurationSeq = 1; 13989 } 13990 newConfig.seq = mConfigurationSeq; 13991 mConfiguration = newConfig; 13992 Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig); 13993 13994 final Configuration configCopy = new Configuration(mConfiguration); 13995 13996 // TODO: If our config changes, should we auto dismiss any currently 13997 // showing dialogs? 13998 mShowDialogs = shouldShowDialogs(newConfig); 13999 14000 AttributeCache ac = AttributeCache.instance(); 14001 if (ac != null) { 14002 ac.updateConfiguration(configCopy); 14003 } 14004 14005 // Make sure all resources in our process are updated 14006 // right now, so that anyone who is going to retrieve 14007 // resource values after we return will be sure to get 14008 // the new ones. This is especially important during 14009 // boot, where the first config change needs to guarantee 14010 // all resources have that config before following boot 14011 // code is executed. 14012 mSystemThread.applyConfigurationToResources(configCopy); 14013 14014 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) { 14015 Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG); 14016 msg.obj = new Configuration(configCopy); 14017 mHandler.sendMessage(msg); 14018 } 14019 14020 for (int i=mLruProcesses.size()-1; i>=0; i--) { 14021 ProcessRecord app = mLruProcesses.get(i); 14022 try { 14023 if (app.thread != null) { 14024 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc " 14025 + app.processName + " new config " + mConfiguration); 14026 app.thread.scheduleConfigurationChanged(configCopy); 14027 } 14028 } catch (Exception e) { 14029 } 14030 } 14031 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED); 14032 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 14033 | Intent.FLAG_RECEIVER_REPLACE_PENDING 14034 | Intent.FLAG_RECEIVER_FOREGROUND); 14035 broadcastIntentLocked(null, null, intent, null, null, 0, null, null, 14036 null, AppOpsManager.OP_NONE, false, false, MY_PID, 14037 Process.SYSTEM_UID, UserHandle.USER_ALL); 14038 if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) { 14039 intent = new Intent(Intent.ACTION_LOCALE_CHANGED); 14040 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 14041 broadcastIntentLocked(null, null, intent, 14042 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 14043 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 14044 } 14045 } 14046 } 14047 14048 boolean kept = true; 14049 final ActivityStack mainStack = mStackSupervisor.getFocusedStack(); 14050 // mainStack is null during startup. 14051 if (mainStack != null) { 14052 if (changes != 0 && starting == null) { 14053 // If the configuration changed, and the caller is not already 14054 // in the process of starting an activity, then find the top 14055 // activity to check if its configuration needs to change. 14056 starting = mainStack.topRunningActivityLocked(null); 14057 } 14058 14059 if (starting != null) { 14060 kept = mainStack.ensureActivityConfigurationLocked(starting, changes); 14061 // And we need to make sure at this point that all other activities 14062 // are made visible with the correct configuration. 14063 mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes); 14064 } 14065 } 14066 14067 if (values != null && mWindowManager != null) { 14068 mWindowManager.setNewConfiguration(mConfiguration); 14069 } 14070 14071 return kept; 14072 } 14073 14074 /** 14075 * Decide based on the configuration whether we should shouw the ANR, 14076 * crash, etc dialogs. The idea is that if there is no affordnace to 14077 * press the on-screen buttons, we shouldn't show the dialog. 14078 * 14079 * A thought: SystemUI might also want to get told about this, the Power 14080 * dialog / global actions also might want different behaviors. 14081 */ 14082 private static final boolean shouldShowDialogs(Configuration config) { 14083 return !(config.keyboard == Configuration.KEYBOARD_NOKEYS 14084 && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH); 14085 } 14086 14087 /** 14088 * Save the locale. You must be inside a synchronized (this) block. 14089 */ 14090 private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) { 14091 if(isDiff) { 14092 SystemProperties.set("user.language", l.getLanguage()); 14093 SystemProperties.set("user.region", l.getCountry()); 14094 } 14095 14096 if(isPersist) { 14097 SystemProperties.set("persist.sys.language", l.getLanguage()); 14098 SystemProperties.set("persist.sys.country", l.getCountry()); 14099 SystemProperties.set("persist.sys.localevar", l.getVariant()); 14100 } 14101 } 14102 14103 @Override 14104 public boolean targetTaskAffinityMatchesActivity(IBinder token, String destAffinity) { 14105 ActivityRecord srec = ActivityRecord.forToken(token); 14106 return srec != null && srec.task.affinity != null && 14107 srec.task.affinity.equals(destAffinity); 14108 } 14109 14110 public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode, 14111 Intent resultData) { 14112 14113 synchronized (this) { 14114 final ActivityStack stack = ActivityRecord.getStackLocked(token); 14115 if (stack != null) { 14116 return stack.navigateUpToLocked(token, destIntent, resultCode, resultData); 14117 } 14118 return false; 14119 } 14120 } 14121 14122 public int getLaunchedFromUid(IBinder activityToken) { 14123 ActivityRecord srec = ActivityRecord.forToken(activityToken); 14124 if (srec == null) { 14125 return -1; 14126 } 14127 return srec.launchedFromUid; 14128 } 14129 14130 public String getLaunchedFromPackage(IBinder activityToken) { 14131 ActivityRecord srec = ActivityRecord.forToken(activityToken); 14132 if (srec == null) { 14133 return null; 14134 } 14135 return srec.launchedFromPackage; 14136 } 14137 14138 // ========================================================= 14139 // LIFETIME MANAGEMENT 14140 // ========================================================= 14141 14142 // Returns which broadcast queue the app is the current [or imminent] receiver 14143 // on, or 'null' if the app is not an active broadcast recipient. 14144 private BroadcastQueue isReceivingBroadcast(ProcessRecord app) { 14145 BroadcastRecord r = app.curReceiver; 14146 if (r != null) { 14147 return r.queue; 14148 } 14149 14150 // It's not the current receiver, but it might be starting up to become one 14151 synchronized (this) { 14152 for (BroadcastQueue queue : mBroadcastQueues) { 14153 r = queue.mPendingBroadcast; 14154 if (r != null && r.curApp == app) { 14155 // found it; report which queue it's in 14156 return queue; 14157 } 14158 } 14159 } 14160 14161 return null; 14162 } 14163 14164 private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP, 14165 boolean doingAll, long now) { 14166 if (mAdjSeq == app.adjSeq) { 14167 // This adjustment has already been computed. 14168 return app.curRawAdj; 14169 } 14170 14171 if (app.thread == null) { 14172 app.adjSeq = mAdjSeq; 14173 app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 14174 app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 14175 return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ); 14176 } 14177 14178 app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN; 14179 app.adjSource = null; 14180 app.adjTarget = null; 14181 app.empty = false; 14182 app.cached = false; 14183 14184 final int activitiesSize = app.activities.size(); 14185 14186 if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) { 14187 // The max adjustment doesn't allow this app to be anything 14188 // below foreground, so it is not worth doing work for it. 14189 app.adjType = "fixed"; 14190 app.adjSeq = mAdjSeq; 14191 app.curRawAdj = app.maxAdj; 14192 app.foregroundActivities = false; 14193 app.keeping = true; 14194 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT; 14195 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT; 14196 // System process can do UI, and when they do we want to have 14197 // them trim their memory after the user leaves the UI. To 14198 // facilitate this, here we need to determine whether or not it 14199 // is currently showing UI. 14200 app.systemNoUi = true; 14201 if (app == TOP_APP) { 14202 app.systemNoUi = false; 14203 } else if (activitiesSize > 0) { 14204 for (int j = 0; j < activitiesSize; j++) { 14205 final ActivityRecord r = app.activities.get(j); 14206 if (r.visible) { 14207 app.systemNoUi = false; 14208 } 14209 } 14210 } 14211 if (!app.systemNoUi) { 14212 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI; 14213 } 14214 return (app.curAdj=app.maxAdj); 14215 } 14216 14217 app.keeping = false; 14218 app.systemNoUi = false; 14219 14220 // Determine the importance of the process, starting with most 14221 // important to least, and assign an appropriate OOM adjustment. 14222 int adj; 14223 int schedGroup; 14224 int procState; 14225 boolean foregroundActivities = false; 14226 boolean interesting = false; 14227 BroadcastQueue queue; 14228 if (app == TOP_APP) { 14229 // The last app on the list is the foreground app. 14230 adj = ProcessList.FOREGROUND_APP_ADJ; 14231 schedGroup = Process.THREAD_GROUP_DEFAULT; 14232 app.adjType = "top-activity"; 14233 foregroundActivities = true; 14234 interesting = true; 14235 procState = ActivityManager.PROCESS_STATE_TOP; 14236 } else if (app.instrumentationClass != null) { 14237 // Don't want to kill running instrumentation. 14238 adj = ProcessList.FOREGROUND_APP_ADJ; 14239 schedGroup = Process.THREAD_GROUP_DEFAULT; 14240 app.adjType = "instrumentation"; 14241 interesting = true; 14242 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14243 } else if ((queue = isReceivingBroadcast(app)) != null) { 14244 // An app that is currently receiving a broadcast also 14245 // counts as being in the foreground for OOM killer purposes. 14246 // It's placed in a sched group based on the nature of the 14247 // broadcast as reflected by which queue it's active in. 14248 adj = ProcessList.FOREGROUND_APP_ADJ; 14249 schedGroup = (queue == mFgBroadcastQueue) 14250 ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 14251 app.adjType = "broadcast"; 14252 procState = ActivityManager.PROCESS_STATE_RECEIVER; 14253 } else if (app.executingServices.size() > 0) { 14254 // An app that is currently executing a service callback also 14255 // counts as being in the foreground. 14256 adj = ProcessList.FOREGROUND_APP_ADJ; 14257 schedGroup = app.execServicesFg ? 14258 Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 14259 app.adjType = "exec-service"; 14260 procState = ActivityManager.PROCESS_STATE_SERVICE; 14261 //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app); 14262 } else { 14263 // As far as we know the process is empty. We may change our mind later. 14264 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 14265 // At this point we don't actually know the adjustment. Use the cached adj 14266 // value that the caller wants us to. 14267 adj = cachedAdj; 14268 procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 14269 app.cached = true; 14270 app.empty = true; 14271 app.adjType = "cch-empty"; 14272 } 14273 14274 // Examine all activities if not already foreground. 14275 if (!foregroundActivities && activitiesSize > 0) { 14276 for (int j = 0; j < activitiesSize; j++) { 14277 final ActivityRecord r = app.activities.get(j); 14278 if (r.app != app) { 14279 Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc " 14280 + app + "?!?"); 14281 continue; 14282 } 14283 if (r.visible) { 14284 // App has a visible activity; only upgrade adjustment. 14285 if (adj > ProcessList.VISIBLE_APP_ADJ) { 14286 adj = ProcessList.VISIBLE_APP_ADJ; 14287 app.adjType = "visible"; 14288 } 14289 if (procState > ActivityManager.PROCESS_STATE_TOP) { 14290 procState = ActivityManager.PROCESS_STATE_TOP; 14291 } 14292 schedGroup = Process.THREAD_GROUP_DEFAULT; 14293 app.cached = false; 14294 app.empty = false; 14295 foregroundActivities = true; 14296 break; 14297 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) { 14298 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14299 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 14300 app.adjType = "pausing"; 14301 } 14302 if (procState > ActivityManager.PROCESS_STATE_TOP) { 14303 procState = ActivityManager.PROCESS_STATE_TOP; 14304 } 14305 schedGroup = Process.THREAD_GROUP_DEFAULT; 14306 app.cached = false; 14307 app.empty = false; 14308 foregroundActivities = true; 14309 } else if (r.state == ActivityState.STOPPING) { 14310 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14311 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 14312 app.adjType = "stopping"; 14313 } 14314 // For the process state, we will at this point consider the 14315 // process to be cached. It will be cached either as an activity 14316 // or empty depending on whether the activity is finishing. We do 14317 // this so that we can treat the process as cached for purposes of 14318 // memory trimming (determing current memory level, trim command to 14319 // send to process) since there can be an arbitrary number of stopping 14320 // processes and they should soon all go into the cached state. 14321 if (!r.finishing) { 14322 if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 14323 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 14324 } 14325 } 14326 app.cached = false; 14327 app.empty = false; 14328 foregroundActivities = true; 14329 } else { 14330 if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 14331 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 14332 app.adjType = "cch-act"; 14333 } 14334 } 14335 } 14336 } 14337 14338 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14339 if (app.foregroundServices) { 14340 // The user is aware of this app, so make it visible. 14341 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 14342 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14343 app.cached = false; 14344 app.adjType = "fg-service"; 14345 schedGroup = Process.THREAD_GROUP_DEFAULT; 14346 } else if (app.forcingToForeground != null) { 14347 // The user is aware of this app, so make it visible. 14348 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 14349 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14350 app.cached = false; 14351 app.adjType = "force-fg"; 14352 app.adjSource = app.forcingToForeground; 14353 schedGroup = Process.THREAD_GROUP_DEFAULT; 14354 } 14355 } 14356 14357 if (app.foregroundServices) { 14358 interesting = true; 14359 } 14360 14361 if (app == mHeavyWeightProcess) { 14362 if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) { 14363 // We don't want to kill the current heavy-weight process. 14364 adj = ProcessList.HEAVY_WEIGHT_APP_ADJ; 14365 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 14366 app.cached = false; 14367 app.adjType = "heavy"; 14368 } 14369 if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) { 14370 procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT; 14371 } 14372 } 14373 14374 if (app == mHomeProcess) { 14375 if (adj > ProcessList.HOME_APP_ADJ) { 14376 // This process is hosting what we currently consider to be the 14377 // home app, so we don't want to let it go into the background. 14378 adj = ProcessList.HOME_APP_ADJ; 14379 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 14380 app.cached = false; 14381 app.adjType = "home"; 14382 } 14383 if (procState > ActivityManager.PROCESS_STATE_HOME) { 14384 procState = ActivityManager.PROCESS_STATE_HOME; 14385 } 14386 } 14387 14388 if (app == mPreviousProcess && app.activities.size() > 0) { 14389 if (adj > ProcessList.PREVIOUS_APP_ADJ) { 14390 // This was the previous process that showed UI to the user. 14391 // We want to try to keep it around more aggressively, to give 14392 // a good experience around switching between two apps. 14393 adj = ProcessList.PREVIOUS_APP_ADJ; 14394 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 14395 app.cached = false; 14396 app.adjType = "previous"; 14397 } 14398 if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) { 14399 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY; 14400 } 14401 } 14402 14403 if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj 14404 + " reason=" + app.adjType); 14405 14406 // By default, we use the computed adjustment. It may be changed if 14407 // there are applications dependent on our services or providers, but 14408 // this gives us a baseline and makes sure we don't get into an 14409 // infinite recursion. 14410 app.adjSeq = mAdjSeq; 14411 app.curRawAdj = adj; 14412 app.hasStartedServices = false; 14413 14414 if (mBackupTarget != null && app == mBackupTarget.app) { 14415 // If possible we want to avoid killing apps while they're being backed up 14416 if (adj > ProcessList.BACKUP_APP_ADJ) { 14417 if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app); 14418 adj = ProcessList.BACKUP_APP_ADJ; 14419 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) { 14420 procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND; 14421 } 14422 app.adjType = "backup"; 14423 app.cached = false; 14424 } 14425 if (procState > ActivityManager.PROCESS_STATE_BACKUP) { 14426 procState = ActivityManager.PROCESS_STATE_BACKUP; 14427 } 14428 } 14429 14430 boolean mayBeTop = false; 14431 14432 for (int is = app.services.size()-1; 14433 is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 14434 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 14435 || procState > ActivityManager.PROCESS_STATE_TOP); 14436 is--) { 14437 ServiceRecord s = app.services.valueAt(is); 14438 if (s.startRequested) { 14439 app.hasStartedServices = true; 14440 if (procState > ActivityManager.PROCESS_STATE_SERVICE) { 14441 procState = ActivityManager.PROCESS_STATE_SERVICE; 14442 } 14443 if (app.hasShownUi && app != mHomeProcess) { 14444 // If this process has shown some UI, let it immediately 14445 // go to the LRU list because it may be pretty heavy with 14446 // UI stuff. We'll tag it with a label just to help 14447 // debug and understand what is going on. 14448 if (adj > ProcessList.SERVICE_ADJ) { 14449 app.adjType = "cch-started-ui-services"; 14450 } 14451 } else { 14452 if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) { 14453 // This service has seen some activity within 14454 // recent memory, so we will keep its process ahead 14455 // of the background processes. 14456 if (adj > ProcessList.SERVICE_ADJ) { 14457 adj = ProcessList.SERVICE_ADJ; 14458 app.adjType = "started-services"; 14459 app.cached = false; 14460 } 14461 } 14462 // If we have let the service slide into the background 14463 // state, still have some text describing what it is doing 14464 // even though the service no longer has an impact. 14465 if (adj > ProcessList.SERVICE_ADJ) { 14466 app.adjType = "cch-started-services"; 14467 } 14468 } 14469 // Don't kill this process because it is doing work; it 14470 // has said it is doing work. 14471 app.keeping = true; 14472 } 14473 for (int conni = s.connections.size()-1; 14474 conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 14475 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 14476 || procState > ActivityManager.PROCESS_STATE_TOP); 14477 conni--) { 14478 ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni); 14479 for (int i = 0; 14480 i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ 14481 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 14482 || procState > ActivityManager.PROCESS_STATE_TOP); 14483 i++) { 14484 // XXX should compute this based on the max of 14485 // all connected clients. 14486 ConnectionRecord cr = clist.get(i); 14487 if (cr.binding.client == app) { 14488 // Binding to ourself is not interesting. 14489 continue; 14490 } 14491 if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) { 14492 ProcessRecord client = cr.binding.client; 14493 int clientAdj = computeOomAdjLocked(client, cachedAdj, 14494 TOP_APP, doingAll, now); 14495 int clientProcState = client.curProcState; 14496 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 14497 // If the other app is cached for any reason, for purposes here 14498 // we are going to consider it empty. The specific cached state 14499 // doesn't propagate except under certain conditions. 14500 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 14501 } 14502 String adjType = null; 14503 if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) { 14504 // Not doing bind OOM management, so treat 14505 // this guy more like a started service. 14506 if (app.hasShownUi && app != mHomeProcess) { 14507 // If this process has shown some UI, let it immediately 14508 // go to the LRU list because it may be pretty heavy with 14509 // UI stuff. We'll tag it with a label just to help 14510 // debug and understand what is going on. 14511 if (adj > clientAdj) { 14512 adjType = "cch-bound-ui-services"; 14513 } 14514 app.cached = false; 14515 clientAdj = adj; 14516 clientProcState = procState; 14517 } else { 14518 if (now >= (s.lastActivity 14519 + ActiveServices.MAX_SERVICE_INACTIVITY)) { 14520 // This service has not seen activity within 14521 // recent memory, so allow it to drop to the 14522 // LRU list if there is no other reason to keep 14523 // it around. We'll also tag it with a label just 14524 // to help debug and undertand what is going on. 14525 if (adj > clientAdj) { 14526 adjType = "cch-bound-services"; 14527 } 14528 clientAdj = adj; 14529 } 14530 } 14531 } 14532 if (adj > clientAdj) { 14533 // If this process has recently shown UI, and 14534 // the process that is binding to it is less 14535 // important than being visible, then we don't 14536 // care about the binding as much as we care 14537 // about letting this process get into the LRU 14538 // list to be killed and restarted if needed for 14539 // memory. 14540 if (app.hasShownUi && app != mHomeProcess 14541 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14542 adjType = "cch-bound-ui-services"; 14543 } else { 14544 if ((cr.flags&(Context.BIND_ABOVE_CLIENT 14545 |Context.BIND_IMPORTANT)) != 0) { 14546 adj = clientAdj; 14547 } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0 14548 && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ 14549 && adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14550 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 14551 } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) { 14552 adj = clientAdj; 14553 } else { 14554 if (adj > ProcessList.VISIBLE_APP_ADJ) { 14555 adj = ProcessList.VISIBLE_APP_ADJ; 14556 } 14557 } 14558 if (!client.cached) { 14559 app.cached = false; 14560 } 14561 if (client.keeping) { 14562 app.keeping = true; 14563 } 14564 adjType = "service"; 14565 } 14566 } 14567 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 14568 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 14569 schedGroup = Process.THREAD_GROUP_DEFAULT; 14570 } 14571 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) { 14572 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) { 14573 // Special handling of clients who are in the top state. 14574 // We *may* want to consider this process to be in the 14575 // top state as well, but only if there is not another 14576 // reason for it to be running. Being on the top is a 14577 // special state, meaning you are specifically running 14578 // for the current top app. If the process is already 14579 // running in the background for some other reason, it 14580 // is more important to continue considering it to be 14581 // in the background state. 14582 mayBeTop = true; 14583 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 14584 } else { 14585 // Special handling for above-top states (persistent 14586 // processes). These should not bring the current process 14587 // into the top state, since they are not on top. Instead 14588 // give them the best state after that. 14589 clientProcState = 14590 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14591 } 14592 } 14593 } else { 14594 if (clientProcState < 14595 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) { 14596 clientProcState = 14597 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND; 14598 } 14599 } 14600 if (procState > clientProcState) { 14601 procState = clientProcState; 14602 } 14603 if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 14604 && (cr.flags&Context.BIND_SHOWING_UI) != 0) { 14605 app.pendingUiClean = true; 14606 } 14607 if (adjType != null) { 14608 app.adjType = adjType; 14609 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 14610 .REASON_SERVICE_IN_USE; 14611 app.adjSource = cr.binding.client; 14612 app.adjSourceOom = clientAdj; 14613 app.adjTarget = s.name; 14614 } 14615 } 14616 final ActivityRecord a = cr.activity; 14617 if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) { 14618 if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ && 14619 (a.visible || a.state == ActivityState.RESUMED 14620 || a.state == ActivityState.PAUSING)) { 14621 adj = ProcessList.FOREGROUND_APP_ADJ; 14622 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 14623 schedGroup = Process.THREAD_GROUP_DEFAULT; 14624 } 14625 app.cached = false; 14626 app.adjType = "service"; 14627 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 14628 .REASON_SERVICE_IN_USE; 14629 app.adjSource = a; 14630 app.adjSourceOom = adj; 14631 app.adjTarget = s.name; 14632 } 14633 } 14634 } 14635 } 14636 } 14637 14638 for (int provi = app.pubProviders.size()-1; 14639 provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 14640 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 14641 || procState > ActivityManager.PROCESS_STATE_TOP); 14642 provi--) { 14643 ContentProviderRecord cpr = app.pubProviders.valueAt(provi); 14644 for (int i = cpr.connections.size()-1; 14645 i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 14646 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 14647 || procState > ActivityManager.PROCESS_STATE_TOP); 14648 i--) { 14649 ContentProviderConnection conn = cpr.connections.get(i); 14650 ProcessRecord client = conn.client; 14651 if (client == app) { 14652 // Being our own client is not interesting. 14653 continue; 14654 } 14655 int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now); 14656 int clientProcState = client.curProcState; 14657 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 14658 // If the other app is cached for any reason, for purposes here 14659 // we are going to consider it empty. 14660 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 14661 } 14662 if (adj > clientAdj) { 14663 if (app.hasShownUi && app != mHomeProcess 14664 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14665 app.adjType = "cch-ui-provider"; 14666 } else { 14667 adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ 14668 ? clientAdj : ProcessList.FOREGROUND_APP_ADJ; 14669 app.adjType = "provider"; 14670 } 14671 app.cached &= client.cached; 14672 app.keeping |= client.keeping; 14673 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 14674 .REASON_PROVIDER_IN_USE; 14675 app.adjSource = client; 14676 app.adjSourceOom = clientAdj; 14677 app.adjTarget = cpr.name; 14678 } 14679 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) { 14680 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) { 14681 // Special handling of clients who are in the top state. 14682 // We *may* want to consider this process to be in the 14683 // top state as well, but only if there is not another 14684 // reason for it to be running. Being on the top is a 14685 // special state, meaning you are specifically running 14686 // for the current top app. If the process is already 14687 // running in the background for some other reason, it 14688 // is more important to continue considering it to be 14689 // in the background state. 14690 mayBeTop = true; 14691 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 14692 } else { 14693 // Special handling for above-top states (persistent 14694 // processes). These should not bring the current process 14695 // into the top state, since they are not on top. Instead 14696 // give them the best state after that. 14697 clientProcState = 14698 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14699 } 14700 } 14701 if (procState > clientProcState) { 14702 procState = clientProcState; 14703 } 14704 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 14705 schedGroup = Process.THREAD_GROUP_DEFAULT; 14706 } 14707 } 14708 // If the provider has external (non-framework) process 14709 // dependencies, ensure that its adjustment is at least 14710 // FOREGROUND_APP_ADJ. 14711 if (cpr.hasExternalProcessHandles()) { 14712 if (adj > ProcessList.FOREGROUND_APP_ADJ) { 14713 adj = ProcessList.FOREGROUND_APP_ADJ; 14714 schedGroup = Process.THREAD_GROUP_DEFAULT; 14715 app.cached = false; 14716 app.keeping = true; 14717 app.adjType = "provider"; 14718 app.adjTarget = cpr.name; 14719 } 14720 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) { 14721 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14722 } 14723 } 14724 } 14725 14726 if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) { 14727 // A client of one of our services or providers is in the top state. We 14728 // *may* want to be in the top state, but not if we are already running in 14729 // the background for some other reason. For the decision here, we are going 14730 // to pick out a few specific states that we want to remain in when a client 14731 // is top (states that tend to be longer-term) and otherwise allow it to go 14732 // to the top state. 14733 switch (procState) { 14734 case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND: 14735 case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND: 14736 case ActivityManager.PROCESS_STATE_SERVICE: 14737 // These all are longer-term states, so pull them up to the top 14738 // of the background states, but not all the way to the top state. 14739 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14740 break; 14741 default: 14742 // Otherwise, top is a better choice, so take it. 14743 procState = ActivityManager.PROCESS_STATE_TOP; 14744 break; 14745 } 14746 } 14747 14748 if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY && app.hasClientActivities) { 14749 // This is a cached process, but with client activities. Mark it so. 14750 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT; 14751 app.adjType = "cch-client-act"; 14752 } 14753 14754 if (adj == ProcessList.SERVICE_ADJ) { 14755 if (doingAll) { 14756 app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3); 14757 mNewNumServiceProcs++; 14758 //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb); 14759 if (!app.serviceb) { 14760 // This service isn't far enough down on the LRU list to 14761 // normally be a B service, but if we are low on RAM and it 14762 // is large we want to force it down since we would prefer to 14763 // keep launcher over it. 14764 if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL 14765 && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) { 14766 app.serviceHighRam = true; 14767 app.serviceb = true; 14768 //Slog.i(TAG, "ADJ " + app + " high ram!"); 14769 } else { 14770 mNewNumAServiceProcs++; 14771 //Slog.i(TAG, "ADJ " + app + " not high ram!"); 14772 } 14773 } else { 14774 app.serviceHighRam = false; 14775 } 14776 } 14777 if (app.serviceb) { 14778 adj = ProcessList.SERVICE_B_ADJ; 14779 } 14780 } 14781 14782 app.curRawAdj = adj; 14783 14784 //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid + 14785 // " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj); 14786 if (adj > app.maxAdj) { 14787 adj = app.maxAdj; 14788 if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 14789 schedGroup = Process.THREAD_GROUP_DEFAULT; 14790 } 14791 } 14792 if (adj < ProcessList.CACHED_APP_MIN_ADJ) { 14793 app.keeping = true; 14794 } 14795 14796 // Do final modification to adj. Everything we do between here and applying 14797 // the final setAdj must be done in this function, because we will also use 14798 // it when computing the final cached adj later. Note that we don't need to 14799 // worry about this for max adj above, since max adj will always be used to 14800 // keep it out of the cached vaues. 14801 adj = app.modifyRawOomAdj(adj); 14802 14803 app.curProcState = procState; 14804 14805 int importance = app.memImportance; 14806 if (importance == 0 || adj != app.curAdj || schedGroup != app.curSchedGroup) { 14807 app.curAdj = adj; 14808 app.curSchedGroup = schedGroup; 14809 if (!interesting) { 14810 // For this reporting, if there is not something explicitly 14811 // interesting in this process then we will push it to the 14812 // background importance. 14813 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 14814 } else if (adj >= ProcessList.CACHED_APP_MIN_ADJ) { 14815 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 14816 } else if (adj >= ProcessList.SERVICE_B_ADJ) { 14817 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 14818 } else if (adj >= ProcessList.HOME_APP_ADJ) { 14819 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 14820 } else if (adj >= ProcessList.SERVICE_ADJ) { 14821 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 14822 } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 14823 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE; 14824 } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) { 14825 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE; 14826 } else if (adj >= ProcessList.VISIBLE_APP_ADJ) { 14827 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE; 14828 } else if (adj >= ProcessList.FOREGROUND_APP_ADJ) { 14829 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND; 14830 } else { 14831 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERSISTENT; 14832 } 14833 } 14834 14835 int changes = importance != app.memImportance ? ProcessChangeItem.CHANGE_IMPORTANCE : 0; 14836 if (foregroundActivities != app.foregroundActivities) { 14837 changes |= ProcessChangeItem.CHANGE_ACTIVITIES; 14838 } 14839 if (changes != 0) { 14840 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes); 14841 app.memImportance = importance; 14842 app.foregroundActivities = foregroundActivities; 14843 int i = mPendingProcessChanges.size()-1; 14844 ProcessChangeItem item = null; 14845 while (i >= 0) { 14846 item = mPendingProcessChanges.get(i); 14847 if (item.pid == app.pid) { 14848 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item); 14849 break; 14850 } 14851 i--; 14852 } 14853 if (i < 0) { 14854 // No existing item in pending changes; need a new one. 14855 final int NA = mAvailProcessChanges.size(); 14856 if (NA > 0) { 14857 item = mAvailProcessChanges.remove(NA-1); 14858 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item); 14859 } else { 14860 item = new ProcessChangeItem(); 14861 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item); 14862 } 14863 item.changes = 0; 14864 item.pid = app.pid; 14865 item.uid = app.info.uid; 14866 if (mPendingProcessChanges.size() == 0) { 14867 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, 14868 "*** Enqueueing dispatch processes changed!"); 14869 mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget(); 14870 } 14871 mPendingProcessChanges.add(item); 14872 } 14873 item.changes |= changes; 14874 item.importance = importance; 14875 item.foregroundActivities = foregroundActivities; 14876 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item " 14877 + Integer.toHexString(System.identityHashCode(item)) 14878 + " " + app.toShortString() + ": changes=" + item.changes 14879 + " importance=" + item.importance 14880 + " foreground=" + item.foregroundActivities 14881 + " type=" + app.adjType + " source=" + app.adjSource 14882 + " target=" + app.adjTarget); 14883 } 14884 14885 return app.curRawAdj; 14886 } 14887 14888 /** 14889 * Schedule PSS collection of a process. 14890 */ 14891 void requestPssLocked(ProcessRecord proc, int procState) { 14892 if (mPendingPssProcesses.contains(proc)) { 14893 return; 14894 } 14895 if (mPendingPssProcesses.size() == 0) { 14896 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG); 14897 } 14898 if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc); 14899 proc.pssProcState = procState; 14900 mPendingPssProcesses.add(proc); 14901 } 14902 14903 /** 14904 * Schedule PSS collection of all processes. 14905 */ 14906 void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) { 14907 if (!always) { 14908 if (now < (mLastFullPssTime + 14909 (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) { 14910 return; 14911 } 14912 } 14913 if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs! memLowered=" + memLowered); 14914 mLastFullPssTime = now; 14915 mPendingPssProcesses.ensureCapacity(mLruProcesses.size()); 14916 mPendingPssProcesses.clear(); 14917 for (int i=mLruProcesses.size()-1; i>=0; i--) { 14918 ProcessRecord app = mLruProcesses.get(i); 14919 if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) { 14920 app.pssProcState = app.setProcState; 14921 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true, 14922 mSleeping, now); 14923 mPendingPssProcesses.add(app); 14924 } 14925 } 14926 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG); 14927 } 14928 14929 /** 14930 * Ask a given process to GC right now. 14931 */ 14932 final void performAppGcLocked(ProcessRecord app) { 14933 try { 14934 app.lastRequestedGc = SystemClock.uptimeMillis(); 14935 if (app.thread != null) { 14936 if (app.reportLowMemory) { 14937 app.reportLowMemory = false; 14938 app.thread.scheduleLowMemory(); 14939 } else { 14940 app.thread.processInBackground(); 14941 } 14942 } 14943 } catch (Exception e) { 14944 // whatever. 14945 } 14946 } 14947 14948 /** 14949 * Returns true if things are idle enough to perform GCs. 14950 */ 14951 private final boolean canGcNowLocked() { 14952 boolean processingBroadcasts = false; 14953 for (BroadcastQueue q : mBroadcastQueues) { 14954 if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) { 14955 processingBroadcasts = true; 14956 } 14957 } 14958 return !processingBroadcasts 14959 && (mSleeping || mStackSupervisor.allResumedActivitiesIdle()); 14960 } 14961 14962 /** 14963 * Perform GCs on all processes that are waiting for it, but only 14964 * if things are idle. 14965 */ 14966 final void performAppGcsLocked() { 14967 final int N = mProcessesToGc.size(); 14968 if (N <= 0) { 14969 return; 14970 } 14971 if (canGcNowLocked()) { 14972 while (mProcessesToGc.size() > 0) { 14973 ProcessRecord proc = mProcessesToGc.remove(0); 14974 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) { 14975 if ((proc.lastRequestedGc+GC_MIN_INTERVAL) 14976 <= SystemClock.uptimeMillis()) { 14977 // To avoid spamming the system, we will GC processes one 14978 // at a time, waiting a few seconds between each. 14979 performAppGcLocked(proc); 14980 scheduleAppGcsLocked(); 14981 return; 14982 } else { 14983 // It hasn't been long enough since we last GCed this 14984 // process... put it in the list to wait for its time. 14985 addProcessToGcListLocked(proc); 14986 break; 14987 } 14988 } 14989 } 14990 14991 scheduleAppGcsLocked(); 14992 } 14993 } 14994 14995 /** 14996 * If all looks good, perform GCs on all processes waiting for them. 14997 */ 14998 final void performAppGcsIfAppropriateLocked() { 14999 if (canGcNowLocked()) { 15000 performAppGcsLocked(); 15001 return; 15002 } 15003 // Still not idle, wait some more. 15004 scheduleAppGcsLocked(); 15005 } 15006 15007 /** 15008 * Schedule the execution of all pending app GCs. 15009 */ 15010 final void scheduleAppGcsLocked() { 15011 mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG); 15012 15013 if (mProcessesToGc.size() > 0) { 15014 // Schedule a GC for the time to the next process. 15015 ProcessRecord proc = mProcessesToGc.get(0); 15016 Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG); 15017 15018 long when = proc.lastRequestedGc + GC_MIN_INTERVAL; 15019 long now = SystemClock.uptimeMillis(); 15020 if (when < (now+GC_TIMEOUT)) { 15021 when = now + GC_TIMEOUT; 15022 } 15023 mHandler.sendMessageAtTime(msg, when); 15024 } 15025 } 15026 15027 /** 15028 * Add a process to the array of processes waiting to be GCed. Keeps the 15029 * list in sorted order by the last GC time. The process can't already be 15030 * on the list. 15031 */ 15032 final void addProcessToGcListLocked(ProcessRecord proc) { 15033 boolean added = false; 15034 for (int i=mProcessesToGc.size()-1; i>=0; i--) { 15035 if (mProcessesToGc.get(i).lastRequestedGc < 15036 proc.lastRequestedGc) { 15037 added = true; 15038 mProcessesToGc.add(i+1, proc); 15039 break; 15040 } 15041 } 15042 if (!added) { 15043 mProcessesToGc.add(0, proc); 15044 } 15045 } 15046 15047 /** 15048 * Set up to ask a process to GC itself. This will either do it 15049 * immediately, or put it on the list of processes to gc the next 15050 * time things are idle. 15051 */ 15052 final void scheduleAppGcLocked(ProcessRecord app) { 15053 long now = SystemClock.uptimeMillis(); 15054 if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) { 15055 return; 15056 } 15057 if (!mProcessesToGc.contains(app)) { 15058 addProcessToGcListLocked(app); 15059 scheduleAppGcsLocked(); 15060 } 15061 } 15062 15063 final void checkExcessivePowerUsageLocked(boolean doKills) { 15064 updateCpuStatsNow(); 15065 15066 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 15067 boolean doWakeKills = doKills; 15068 boolean doCpuKills = doKills; 15069 if (mLastPowerCheckRealtime == 0) { 15070 doWakeKills = false; 15071 } 15072 if (mLastPowerCheckUptime == 0) { 15073 doCpuKills = false; 15074 } 15075 if (stats.isScreenOn()) { 15076 doWakeKills = false; 15077 } 15078 final long curRealtime = SystemClock.elapsedRealtime(); 15079 final long realtimeSince = curRealtime - mLastPowerCheckRealtime; 15080 final long curUptime = SystemClock.uptimeMillis(); 15081 final long uptimeSince = curUptime - mLastPowerCheckUptime; 15082 mLastPowerCheckRealtime = curRealtime; 15083 mLastPowerCheckUptime = curUptime; 15084 if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) { 15085 doWakeKills = false; 15086 } 15087 if (uptimeSince < CPU_MIN_CHECK_DURATION) { 15088 doCpuKills = false; 15089 } 15090 int i = mLruProcesses.size(); 15091 while (i > 0) { 15092 i--; 15093 ProcessRecord app = mLruProcesses.get(i); 15094 if (!app.keeping) { 15095 long wtime; 15096 synchronized (stats) { 15097 wtime = stats.getProcessWakeTime(app.info.uid, 15098 app.pid, curRealtime); 15099 } 15100 long wtimeUsed = wtime - app.lastWakeTime; 15101 long cputimeUsed = app.curCpuTime - app.lastCpuTime; 15102 if (DEBUG_POWER) { 15103 StringBuilder sb = new StringBuilder(128); 15104 sb.append("Wake for "); 15105 app.toShortString(sb); 15106 sb.append(": over "); 15107 TimeUtils.formatDuration(realtimeSince, sb); 15108 sb.append(" used "); 15109 TimeUtils.formatDuration(wtimeUsed, sb); 15110 sb.append(" ("); 15111 sb.append((wtimeUsed*100)/realtimeSince); 15112 sb.append("%)"); 15113 Slog.i(TAG, sb.toString()); 15114 sb.setLength(0); 15115 sb.append("CPU for "); 15116 app.toShortString(sb); 15117 sb.append(": over "); 15118 TimeUtils.formatDuration(uptimeSince, sb); 15119 sb.append(" used "); 15120 TimeUtils.formatDuration(cputimeUsed, sb); 15121 sb.append(" ("); 15122 sb.append((cputimeUsed*100)/uptimeSince); 15123 sb.append("%)"); 15124 Slog.i(TAG, sb.toString()); 15125 } 15126 // If a process has held a wake lock for more 15127 // than 50% of the time during this period, 15128 // that sounds bad. Kill! 15129 if (doWakeKills && realtimeSince > 0 15130 && ((wtimeUsed*100)/realtimeSince) >= 50) { 15131 synchronized (stats) { 15132 stats.reportExcessiveWakeLocked(app.info.uid, app.processName, 15133 realtimeSince, wtimeUsed); 15134 } 15135 killUnneededProcessLocked(app, "excessive wake held " + wtimeUsed 15136 + " during " + realtimeSince); 15137 app.baseProcessTracker.reportExcessiveWake(app.pkgList); 15138 } else if (doCpuKills && uptimeSince > 0 15139 && ((cputimeUsed*100)/uptimeSince) >= 50) { 15140 synchronized (stats) { 15141 stats.reportExcessiveCpuLocked(app.info.uid, app.processName, 15142 uptimeSince, cputimeUsed); 15143 } 15144 killUnneededProcessLocked(app, "excessive cpu " + cputimeUsed 15145 + " during " + uptimeSince); 15146 app.baseProcessTracker.reportExcessiveCpu(app.pkgList); 15147 } else { 15148 app.lastWakeTime = wtime; 15149 app.lastCpuTime = app.curCpuTime; 15150 } 15151 } 15152 } 15153 } 15154 15155 private final boolean applyOomAdjLocked(ProcessRecord app, boolean wasKeeping, 15156 ProcessRecord TOP_APP, boolean doingAll, boolean reportingProcessState, long now) { 15157 boolean success = true; 15158 15159 if (app.curRawAdj != app.setRawAdj) { 15160 if (wasKeeping && !app.keeping) { 15161 // This app is no longer something we want to keep. Note 15162 // its current wake lock time to later know to kill it if 15163 // it is not behaving well. 15164 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 15165 synchronized (stats) { 15166 app.lastWakeTime = stats.getProcessWakeTime(app.info.uid, 15167 app.pid, SystemClock.elapsedRealtime()); 15168 } 15169 app.lastCpuTime = app.curCpuTime; 15170 } 15171 15172 app.setRawAdj = app.curRawAdj; 15173 } 15174 15175 if (app.curAdj != app.setAdj) { 15176 ProcessList.setOomAdj(app.pid, app.curAdj); 15177 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v( 15178 TAG, "Set " + app.pid + " " + app.processName + 15179 " adj " + app.curAdj + ": " + app.adjType); 15180 app.setAdj = app.curAdj; 15181 } 15182 15183 if (app.setSchedGroup != app.curSchedGroup) { 15184 app.setSchedGroup = app.curSchedGroup; 15185 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 15186 "Setting process group of " + app.processName 15187 + " to " + app.curSchedGroup); 15188 if (app.waitingToKill != null && 15189 app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 15190 killUnneededProcessLocked(app, app.waitingToKill); 15191 success = false; 15192 } else { 15193 if (true) { 15194 long oldId = Binder.clearCallingIdentity(); 15195 try { 15196 Process.setProcessGroup(app.pid, app.curSchedGroup); 15197 } catch (Exception e) { 15198 Slog.w(TAG, "Failed setting process group of " + app.pid 15199 + " to " + app.curSchedGroup); 15200 e.printStackTrace(); 15201 } finally { 15202 Binder.restoreCallingIdentity(oldId); 15203 } 15204 } else { 15205 if (app.thread != null) { 15206 try { 15207 app.thread.setSchedulingGroup(app.curSchedGroup); 15208 } catch (RemoteException e) { 15209 } 15210 } 15211 } 15212 Process.setSwappiness(app.pid, 15213 app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE); 15214 } 15215 } 15216 if (app.repProcState != app.curProcState) { 15217 app.repProcState = app.curProcState; 15218 if (!reportingProcessState && app.thread != null) { 15219 try { 15220 if (false) { 15221 //RuntimeException h = new RuntimeException("here"); 15222 Slog.i(TAG, "Sending new process state " + app.repProcState 15223 + " to " + app /*, h*/); 15224 } 15225 app.thread.setProcessState(app.repProcState); 15226 } catch (RemoteException e) { 15227 } 15228 } 15229 } 15230 if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState, 15231 app.setProcState)) { 15232 app.lastStateTime = now; 15233 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true, 15234 mSleeping, now); 15235 if (DEBUG_PSS) Slog.d(TAG, "Process state change from " 15236 + ProcessList.makeProcStateString(app.setProcState) + " to " 15237 + ProcessList.makeProcStateString(app.curProcState) + " next pss in " 15238 + (app.nextPssTime-now) + ": " + app); 15239 } else { 15240 if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL) 15241 && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) { 15242 requestPssLocked(app, app.setProcState); 15243 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false, 15244 mSleeping, now); 15245 } else if (false && DEBUG_PSS) { 15246 Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now)); 15247 } 15248 } 15249 if (app.setProcState != app.curProcState) { 15250 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 15251 "Proc state change of " + app.processName 15252 + " to " + app.curProcState); 15253 app.setProcState = app.curProcState; 15254 if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) { 15255 app.notCachedSinceIdle = false; 15256 } 15257 if (!doingAll) { 15258 setProcessTrackerState(app, mProcessStats.getMemFactorLocked(), now); 15259 } else { 15260 app.procStateChanged = true; 15261 } 15262 } 15263 return success; 15264 } 15265 15266 private final void setProcessTrackerState(ProcessRecord proc, int memFactor, long now) { 15267 if (proc.thread != null && proc.baseProcessTracker != null) { 15268 proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList); 15269 } 15270 } 15271 15272 private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj, 15273 ProcessRecord TOP_APP, boolean doingAll, boolean reportingProcessState, long now) { 15274 if (app.thread == null) { 15275 return false; 15276 } 15277 15278 final boolean wasKeeping = app.keeping; 15279 15280 computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now); 15281 15282 return applyOomAdjLocked(app, wasKeeping, TOP_APP, doingAll, 15283 reportingProcessState, now); 15284 } 15285 15286 private final ActivityRecord resumedAppLocked() { 15287 return mStackSupervisor.resumedAppLocked(); 15288 } 15289 15290 final boolean updateOomAdjLocked(ProcessRecord app) { 15291 return updateOomAdjLocked(app, false); 15292 } 15293 15294 final boolean updateOomAdjLocked(ProcessRecord app, boolean doingProcessState) { 15295 final ActivityRecord TOP_ACT = resumedAppLocked(); 15296 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 15297 final boolean wasCached = app.cached; 15298 15299 mAdjSeq++; 15300 15301 // This is the desired cached adjusment we want to tell it to use. 15302 // If our app is currently cached, we know it, and that is it. Otherwise, 15303 // we don't know it yet, and it needs to now be cached we will then 15304 // need to do a complete oom adj. 15305 final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ 15306 ? app.curRawAdj : ProcessList.UNKNOWN_ADJ; 15307 boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false, doingProcessState, 15308 SystemClock.uptimeMillis()); 15309 if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) { 15310 // Changed to/from cached state, so apps after it in the LRU 15311 // list may also be changed. 15312 updateOomAdjLocked(); 15313 } 15314 return success; 15315 } 15316 15317 final void updateOomAdjLocked() { 15318 final ActivityRecord TOP_ACT = resumedAppLocked(); 15319 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 15320 final long now = SystemClock.uptimeMillis(); 15321 final long oldTime = now - ProcessList.MAX_EMPTY_TIME; 15322 final int N = mLruProcesses.size(); 15323 15324 if (false) { 15325 RuntimeException e = new RuntimeException(); 15326 e.fillInStackTrace(); 15327 Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e); 15328 } 15329 15330 mAdjSeq++; 15331 mNewNumServiceProcs = 0; 15332 mNewNumAServiceProcs = 0; 15333 15334 final int emptyProcessLimit; 15335 final int cachedProcessLimit; 15336 if (mProcessLimit <= 0) { 15337 emptyProcessLimit = cachedProcessLimit = 0; 15338 } else if (mProcessLimit == 1) { 15339 emptyProcessLimit = 1; 15340 cachedProcessLimit = 0; 15341 } else { 15342 emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit); 15343 cachedProcessLimit = mProcessLimit - emptyProcessLimit; 15344 } 15345 15346 // Let's determine how many processes we have running vs. 15347 // how many slots we have for background processes; we may want 15348 // to put multiple processes in a slot of there are enough of 15349 // them. 15350 int numSlots = (ProcessList.CACHED_APP_MAX_ADJ 15351 - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2; 15352 int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs; 15353 if (numEmptyProcs > cachedProcessLimit) { 15354 // If there are more empty processes than our limit on cached 15355 // processes, then use the cached process limit for the factor. 15356 // This ensures that the really old empty processes get pushed 15357 // down to the bottom, so if we are running low on memory we will 15358 // have a better chance at keeping around more cached processes 15359 // instead of a gazillion empty processes. 15360 numEmptyProcs = cachedProcessLimit; 15361 } 15362 int emptyFactor = numEmptyProcs/numSlots; 15363 if (emptyFactor < 1) emptyFactor = 1; 15364 int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots; 15365 if (cachedFactor < 1) cachedFactor = 1; 15366 int stepCached = 0; 15367 int stepEmpty = 0; 15368 int numCached = 0; 15369 int numEmpty = 0; 15370 int numTrimming = 0; 15371 15372 mNumNonCachedProcs = 0; 15373 mNumCachedHiddenProcs = 0; 15374 15375 // First update the OOM adjustment for each of the 15376 // application processes based on their current state. 15377 int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ; 15378 int nextCachedAdj = curCachedAdj+1; 15379 int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ; 15380 int nextEmptyAdj = curEmptyAdj+2; 15381 for (int i=N-1; i>=0; i--) { 15382 ProcessRecord app = mLruProcesses.get(i); 15383 if (!app.killedByAm && app.thread != null) { 15384 app.procStateChanged = false; 15385 final boolean wasKeeping = app.keeping; 15386 computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now); 15387 15388 // If we haven't yet assigned the final cached adj 15389 // to the process, do that now. 15390 if (app.curAdj >= ProcessList.UNKNOWN_ADJ) { 15391 switch (app.curProcState) { 15392 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY: 15393 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: 15394 // This process is a cached process holding activities... 15395 // assign it the next cached value for that type, and then 15396 // step that cached level. 15397 app.curRawAdj = curCachedAdj; 15398 app.curAdj = app.modifyRawOomAdj(curCachedAdj); 15399 if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i 15400 + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj 15401 + ")"); 15402 if (curCachedAdj != nextCachedAdj) { 15403 stepCached++; 15404 if (stepCached >= cachedFactor) { 15405 stepCached = 0; 15406 curCachedAdj = nextCachedAdj; 15407 nextCachedAdj += 2; 15408 if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) { 15409 nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ; 15410 } 15411 } 15412 } 15413 break; 15414 default: 15415 // For everything else, assign next empty cached process 15416 // level and bump that up. Note that this means that 15417 // long-running services that have dropped down to the 15418 // cached level will be treated as empty (since their process 15419 // state is still as a service), which is what we want. 15420 app.curRawAdj = curEmptyAdj; 15421 app.curAdj = app.modifyRawOomAdj(curEmptyAdj); 15422 if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i 15423 + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj 15424 + ")"); 15425 if (curEmptyAdj != nextEmptyAdj) { 15426 stepEmpty++; 15427 if (stepEmpty >= emptyFactor) { 15428 stepEmpty = 0; 15429 curEmptyAdj = nextEmptyAdj; 15430 nextEmptyAdj += 2; 15431 if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) { 15432 nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ; 15433 } 15434 } 15435 } 15436 break; 15437 } 15438 } 15439 15440 applyOomAdjLocked(app, wasKeeping, TOP_APP, true, false, now); 15441 15442 // Count the number of process types. 15443 switch (app.curProcState) { 15444 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY: 15445 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: 15446 mNumCachedHiddenProcs++; 15447 numCached++; 15448 if (numCached > cachedProcessLimit) { 15449 killUnneededProcessLocked(app, "cached #" + numCached); 15450 } 15451 break; 15452 case ActivityManager.PROCESS_STATE_CACHED_EMPTY: 15453 if (numEmpty > ProcessList.TRIM_EMPTY_APPS 15454 && app.lastActivityTime < oldTime) { 15455 killUnneededProcessLocked(app, "empty for " 15456 + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime) 15457 / 1000) + "s"); 15458 } else { 15459 numEmpty++; 15460 if (numEmpty > emptyProcessLimit) { 15461 killUnneededProcessLocked(app, "empty #" + numEmpty); 15462 } 15463 } 15464 break; 15465 default: 15466 mNumNonCachedProcs++; 15467 break; 15468 } 15469 15470 if (app.isolated && app.services.size() <= 0) { 15471 // If this is an isolated process, and there are no 15472 // services running in it, then the process is no longer 15473 // needed. We agressively kill these because we can by 15474 // definition not re-use the same process again, and it is 15475 // good to avoid having whatever code was running in them 15476 // left sitting around after no longer needed. 15477 killUnneededProcessLocked(app, "isolated not needed"); 15478 } 15479 15480 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME 15481 && !app.killedByAm) { 15482 numTrimming++; 15483 } 15484 } 15485 } 15486 15487 mNumServiceProcs = mNewNumServiceProcs; 15488 15489 // Now determine the memory trimming level of background processes. 15490 // Unfortunately we need to start at the back of the list to do this 15491 // properly. We only do this if the number of background apps we 15492 // are managing to keep around is less than half the maximum we desire; 15493 // if we are keeping a good number around, we'll let them use whatever 15494 // memory they want. 15495 final int numCachedAndEmpty = numCached + numEmpty; 15496 int memFactor; 15497 if (numCached <= ProcessList.TRIM_CACHED_APPS 15498 && numEmpty <= ProcessList.TRIM_EMPTY_APPS) { 15499 if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) { 15500 memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL; 15501 } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) { 15502 memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW; 15503 } else { 15504 memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE; 15505 } 15506 } else { 15507 memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL; 15508 } 15509 // We always allow the memory level to go up (better). We only allow it to go 15510 // down if we are in a state where that is allowed, *and* the total number of processes 15511 // has gone down since last time. 15512 if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel 15513 + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size() 15514 + " last=" + mLastNumProcesses); 15515 if (memFactor > mLastMemoryLevel) { 15516 if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) { 15517 memFactor = mLastMemoryLevel; 15518 if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!"); 15519 } 15520 } 15521 mLastMemoryLevel = memFactor; 15522 mLastNumProcesses = mLruProcesses.size(); 15523 boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !mSleeping, now); 15524 final int trackerMemFactor = mProcessStats.getMemFactorLocked(); 15525 if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) { 15526 if (mLowRamStartTime == 0) { 15527 mLowRamStartTime = now; 15528 } 15529 int step = 0; 15530 int fgTrimLevel; 15531 switch (memFactor) { 15532 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL: 15533 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL; 15534 break; 15535 case ProcessStats.ADJ_MEM_FACTOR_LOW: 15536 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW; 15537 break; 15538 default: 15539 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE; 15540 break; 15541 } 15542 int factor = numTrimming/3; 15543 int minFactor = 2; 15544 if (mHomeProcess != null) minFactor++; 15545 if (mPreviousProcess != null) minFactor++; 15546 if (factor < minFactor) factor = minFactor; 15547 int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE; 15548 for (int i=N-1; i>=0; i--) { 15549 ProcessRecord app = mLruProcesses.get(i); 15550 if (allChanged || app.procStateChanged) { 15551 setProcessTrackerState(app, trackerMemFactor, now); 15552 app.procStateChanged = false; 15553 } 15554 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME 15555 && !app.killedByAm) { 15556 if (app.trimMemoryLevel < curLevel && app.thread != null) { 15557 try { 15558 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 15559 "Trimming memory of " + app.processName 15560 + " to " + curLevel); 15561 app.thread.scheduleTrimMemory(curLevel); 15562 } catch (RemoteException e) { 15563 } 15564 if (false) { 15565 // For now we won't do this; our memory trimming seems 15566 // to be good enough at this point that destroying 15567 // activities causes more harm than good. 15568 if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE 15569 && app != mHomeProcess && app != mPreviousProcess) { 15570 // Need to do this on its own message because the stack may not 15571 // be in a consistent state at this point. 15572 // For these apps we will also finish their activities 15573 // to help them free memory. 15574 mStackSupervisor.scheduleDestroyAllActivities(app, "trim"); 15575 } 15576 } 15577 } 15578 app.trimMemoryLevel = curLevel; 15579 step++; 15580 if (step >= factor) { 15581 step = 0; 15582 switch (curLevel) { 15583 case ComponentCallbacks2.TRIM_MEMORY_COMPLETE: 15584 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE; 15585 break; 15586 case ComponentCallbacks2.TRIM_MEMORY_MODERATE: 15587 curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 15588 break; 15589 } 15590 } 15591 } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) { 15592 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND 15593 && app.thread != null) { 15594 try { 15595 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 15596 "Trimming memory of heavy-weight " + app.processName 15597 + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 15598 app.thread.scheduleTrimMemory( 15599 ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 15600 } catch (RemoteException e) { 15601 } 15602 } 15603 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 15604 } else { 15605 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 15606 || app.systemNoUi) && app.pendingUiClean) { 15607 // If this application is now in the background and it 15608 // had done UI, then give it the special trim level to 15609 // have it free UI resources. 15610 final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN; 15611 if (app.trimMemoryLevel < level && app.thread != null) { 15612 try { 15613 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 15614 "Trimming memory of bg-ui " + app.processName 15615 + " to " + level); 15616 app.thread.scheduleTrimMemory(level); 15617 } catch (RemoteException e) { 15618 } 15619 } 15620 app.pendingUiClean = false; 15621 } 15622 if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) { 15623 try { 15624 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 15625 "Trimming memory of fg " + app.processName 15626 + " to " + fgTrimLevel); 15627 app.thread.scheduleTrimMemory(fgTrimLevel); 15628 } catch (RemoteException e) { 15629 } 15630 } 15631 app.trimMemoryLevel = fgTrimLevel; 15632 } 15633 } 15634 } else { 15635 if (mLowRamStartTime != 0) { 15636 mLowRamTimeSinceLastIdle += now - mLowRamStartTime; 15637 mLowRamStartTime = 0; 15638 } 15639 for (int i=N-1; i>=0; i--) { 15640 ProcessRecord app = mLruProcesses.get(i); 15641 if (allChanged || app.procStateChanged) { 15642 setProcessTrackerState(app, trackerMemFactor, now); 15643 app.procStateChanged = false; 15644 } 15645 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 15646 || app.systemNoUi) && app.pendingUiClean) { 15647 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN 15648 && app.thread != null) { 15649 try { 15650 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 15651 "Trimming memory of ui hidden " + app.processName 15652 + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 15653 app.thread.scheduleTrimMemory( 15654 ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 15655 } catch (RemoteException e) { 15656 } 15657 } 15658 app.pendingUiClean = false; 15659 } 15660 app.trimMemoryLevel = 0; 15661 } 15662 } 15663 15664 if (mAlwaysFinishActivities) { 15665 // Need to do this on its own message because the stack may not 15666 // be in a consistent state at this point. 15667 mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish"); 15668 } 15669 15670 if (allChanged) { 15671 requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered()); 15672 } 15673 15674 if (mProcessStats.shouldWriteNowLocked(now)) { 15675 mHandler.post(new Runnable() { 15676 @Override public void run() { 15677 synchronized (ActivityManagerService.this) { 15678 mProcessStats.writeStateAsyncLocked(); 15679 } 15680 } 15681 }); 15682 } 15683 15684 if (DEBUG_OOM_ADJ) { 15685 Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms"); 15686 } 15687 } 15688 15689 final void trimApplications() { 15690 synchronized (this) { 15691 int i; 15692 15693 // First remove any unused application processes whose package 15694 // has been removed. 15695 for (i=mRemovedProcesses.size()-1; i>=0; i--) { 15696 final ProcessRecord app = mRemovedProcesses.get(i); 15697 if (app.activities.size() == 0 15698 && app.curReceiver == null && app.services.size() == 0) { 15699 Slog.i( 15700 TAG, "Exiting empty application process " 15701 + app.processName + " (" 15702 + (app.thread != null ? app.thread.asBinder() : null) 15703 + ")\n"); 15704 if (app.pid > 0 && app.pid != MY_PID) { 15705 EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid, 15706 app.processName, app.setAdj, "empty"); 15707 app.killedByAm = true; 15708 Process.killProcessQuiet(app.pid); 15709 } else { 15710 try { 15711 app.thread.scheduleExit(); 15712 } catch (Exception e) { 15713 // Ignore exceptions. 15714 } 15715 } 15716 cleanUpApplicationRecordLocked(app, false, true, -1); 15717 mRemovedProcesses.remove(i); 15718 15719 if (app.persistent) { 15720 if (app.persistent) { 15721 addAppLocked(app.info, false); 15722 } 15723 } 15724 } 15725 } 15726 15727 // Now update the oom adj for all processes. 15728 updateOomAdjLocked(); 15729 } 15730 } 15731 15732 /** This method sends the specified signal to each of the persistent apps */ 15733 public void signalPersistentProcesses(int sig) throws RemoteException { 15734 if (sig != Process.SIGNAL_USR1) { 15735 throw new SecurityException("Only SIGNAL_USR1 is allowed"); 15736 } 15737 15738 synchronized (this) { 15739 if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES) 15740 != PackageManager.PERMISSION_GRANTED) { 15741 throw new SecurityException("Requires permission " 15742 + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES); 15743 } 15744 15745 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 15746 ProcessRecord r = mLruProcesses.get(i); 15747 if (r.thread != null && r.persistent) { 15748 Process.sendSignal(r.pid, sig); 15749 } 15750 } 15751 } 15752 } 15753 15754 private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) { 15755 if (proc == null || proc == mProfileProc) { 15756 proc = mProfileProc; 15757 path = mProfileFile; 15758 profileType = mProfileType; 15759 clearProfilerLocked(); 15760 } 15761 if (proc == null) { 15762 return; 15763 } 15764 try { 15765 proc.thread.profilerControl(false, path, null, profileType); 15766 } catch (RemoteException e) { 15767 throw new IllegalStateException("Process disappeared"); 15768 } 15769 } 15770 15771 private void clearProfilerLocked() { 15772 if (mProfileFd != null) { 15773 try { 15774 mProfileFd.close(); 15775 } catch (IOException e) { 15776 } 15777 } 15778 mProfileApp = null; 15779 mProfileProc = null; 15780 mProfileFile = null; 15781 mProfileType = 0; 15782 mAutoStopProfiler = false; 15783 } 15784 15785 public boolean profileControl(String process, int userId, boolean start, 15786 String path, ParcelFileDescriptor fd, int profileType) throws RemoteException { 15787 15788 try { 15789 synchronized (this) { 15790 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 15791 // its own permission. 15792 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 15793 != PackageManager.PERMISSION_GRANTED) { 15794 throw new SecurityException("Requires permission " 15795 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 15796 } 15797 15798 if (start && fd == null) { 15799 throw new IllegalArgumentException("null fd"); 15800 } 15801 15802 ProcessRecord proc = null; 15803 if (process != null) { 15804 proc = findProcessLocked(process, userId, "profileControl"); 15805 } 15806 15807 if (start && (proc == null || proc.thread == null)) { 15808 throw new IllegalArgumentException("Unknown process: " + process); 15809 } 15810 15811 if (start) { 15812 stopProfilerLocked(null, null, 0); 15813 setProfileApp(proc.info, proc.processName, path, fd, false); 15814 mProfileProc = proc; 15815 mProfileType = profileType; 15816 try { 15817 fd = fd.dup(); 15818 } catch (IOException e) { 15819 fd = null; 15820 } 15821 proc.thread.profilerControl(start, path, fd, profileType); 15822 fd = null; 15823 mProfileFd = null; 15824 } else { 15825 stopProfilerLocked(proc, path, profileType); 15826 if (fd != null) { 15827 try { 15828 fd.close(); 15829 } catch (IOException e) { 15830 } 15831 } 15832 } 15833 15834 return true; 15835 } 15836 } catch (RemoteException e) { 15837 throw new IllegalStateException("Process disappeared"); 15838 } finally { 15839 if (fd != null) { 15840 try { 15841 fd.close(); 15842 } catch (IOException e) { 15843 } 15844 } 15845 } 15846 } 15847 15848 private ProcessRecord findProcessLocked(String process, int userId, String callName) { 15849 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 15850 userId, true, true, callName, null); 15851 ProcessRecord proc = null; 15852 try { 15853 int pid = Integer.parseInt(process); 15854 synchronized (mPidsSelfLocked) { 15855 proc = mPidsSelfLocked.get(pid); 15856 } 15857 } catch (NumberFormatException e) { 15858 } 15859 15860 if (proc == null) { 15861 ArrayMap<String, SparseArray<ProcessRecord>> all 15862 = mProcessNames.getMap(); 15863 SparseArray<ProcessRecord> procs = all.get(process); 15864 if (procs != null && procs.size() > 0) { 15865 proc = procs.valueAt(0); 15866 if (userId != UserHandle.USER_ALL && proc.userId != userId) { 15867 for (int i=1; i<procs.size(); i++) { 15868 ProcessRecord thisProc = procs.valueAt(i); 15869 if (thisProc.userId == userId) { 15870 proc = thisProc; 15871 break; 15872 } 15873 } 15874 } 15875 } 15876 } 15877 15878 return proc; 15879 } 15880 15881 public boolean dumpHeap(String process, int userId, boolean managed, 15882 String path, ParcelFileDescriptor fd) throws RemoteException { 15883 15884 try { 15885 synchronized (this) { 15886 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 15887 // its own permission (same as profileControl). 15888 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 15889 != PackageManager.PERMISSION_GRANTED) { 15890 throw new SecurityException("Requires permission " 15891 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 15892 } 15893 15894 if (fd == null) { 15895 throw new IllegalArgumentException("null fd"); 15896 } 15897 15898 ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap"); 15899 if (proc == null || proc.thread == null) { 15900 throw new IllegalArgumentException("Unknown process: " + process); 15901 } 15902 15903 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 15904 if (!isDebuggable) { 15905 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 15906 throw new SecurityException("Process not debuggable: " + proc); 15907 } 15908 } 15909 15910 proc.thread.dumpHeap(managed, path, fd); 15911 fd = null; 15912 return true; 15913 } 15914 } catch (RemoteException e) { 15915 throw new IllegalStateException("Process disappeared"); 15916 } finally { 15917 if (fd != null) { 15918 try { 15919 fd.close(); 15920 } catch (IOException e) { 15921 } 15922 } 15923 } 15924 } 15925 15926 /** In this method we try to acquire our lock to make sure that we have not deadlocked */ 15927 public void monitor() { 15928 synchronized (this) { } 15929 } 15930 15931 void onCoreSettingsChange(Bundle settings) { 15932 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 15933 ProcessRecord processRecord = mLruProcesses.get(i); 15934 try { 15935 if (processRecord.thread != null) { 15936 processRecord.thread.setCoreSettings(settings); 15937 } 15938 } catch (RemoteException re) { 15939 /* ignore */ 15940 } 15941 } 15942 } 15943 15944 // Multi-user methods 15945 15946 @Override 15947 public boolean switchUser(final int userId) { 15948 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 15949 != PackageManager.PERMISSION_GRANTED) { 15950 String msg = "Permission Denial: switchUser() from pid=" 15951 + Binder.getCallingPid() 15952 + ", uid=" + Binder.getCallingUid() 15953 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 15954 Slog.w(TAG, msg); 15955 throw new SecurityException(msg); 15956 } 15957 15958 final long ident = Binder.clearCallingIdentity(); 15959 try { 15960 synchronized (this) { 15961 final int oldUserId = mCurrentUserId; 15962 if (oldUserId == userId) { 15963 return true; 15964 } 15965 15966 final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId); 15967 if (userInfo == null) { 15968 Slog.w(TAG, "No user info for user #" + userId); 15969 return false; 15970 } 15971 15972 mWindowManager.startFreezingScreen(R.anim.screen_user_exit, 15973 R.anim.screen_user_enter); 15974 15975 boolean needStart = false; 15976 15977 // If the user we are switching to is not currently started, then 15978 // we need to start it now. 15979 if (mStartedUsers.get(userId) == null) { 15980 mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false)); 15981 updateStartedUserArrayLocked(); 15982 needStart = true; 15983 } 15984 15985 mCurrentUserId = userId; 15986 final Integer userIdInt = Integer.valueOf(userId); 15987 mUserLru.remove(userIdInt); 15988 mUserLru.add(userIdInt); 15989 15990 mWindowManager.setCurrentUser(userId); 15991 15992 // Once the internal notion of the active user has switched, we lock the device 15993 // with the option to show the user switcher on the keyguard. 15994 mWindowManager.lockNow(null); 15995 15996 final UserStartedState uss = mStartedUsers.get(userId); 15997 15998 // Make sure user is in the started state. If it is currently 15999 // stopping, we need to knock that off. 16000 if (uss.mState == UserStartedState.STATE_STOPPING) { 16001 // If we are stopping, we haven't sent ACTION_SHUTDOWN, 16002 // so we can just fairly silently bring the user back from 16003 // the almost-dead. 16004 uss.mState = UserStartedState.STATE_RUNNING; 16005 updateStartedUserArrayLocked(); 16006 needStart = true; 16007 } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) { 16008 // This means ACTION_SHUTDOWN has been sent, so we will 16009 // need to treat this as a new boot of the user. 16010 uss.mState = UserStartedState.STATE_BOOTING; 16011 updateStartedUserArrayLocked(); 16012 needStart = true; 16013 } 16014 16015 mHandler.removeMessages(REPORT_USER_SWITCH_MSG); 16016 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 16017 mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG, 16018 oldUserId, userId, uss)); 16019 mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG, 16020 oldUserId, userId, uss), USER_SWITCH_TIMEOUT); 16021 if (needStart) { 16022 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 16023 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16024 | Intent.FLAG_RECEIVER_FOREGROUND); 16025 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 16026 broadcastIntentLocked(null, null, intent, 16027 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 16028 false, false, MY_PID, Process.SYSTEM_UID, userId); 16029 } 16030 16031 if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) { 16032 if (userId != 0) { 16033 Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE); 16034 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 16035 broadcastIntentLocked(null, null, intent, null, 16036 new IIntentReceiver.Stub() { 16037 public void performReceive(Intent intent, int resultCode, 16038 String data, Bundle extras, boolean ordered, 16039 boolean sticky, int sendingUser) { 16040 userInitialized(uss, userId); 16041 } 16042 }, 0, null, null, null, AppOpsManager.OP_NONE, 16043 true, false, MY_PID, Process.SYSTEM_UID, 16044 userId); 16045 uss.initializing = true; 16046 } else { 16047 getUserManagerLocked().makeInitialized(userInfo.id); 16048 } 16049 } 16050 16051 boolean homeInFront = mStackSupervisor.switchUserLocked(userId, uss); 16052 if (homeInFront) { 16053 startHomeActivityLocked(userId); 16054 } else { 16055 mStackSupervisor.resumeTopActivitiesLocked(); 16056 } 16057 16058 EventLogTags.writeAmSwitchUser(userId); 16059 getUserManagerLocked().userForeground(userId); 16060 sendUserSwitchBroadcastsLocked(oldUserId, userId); 16061 if (needStart) { 16062 Intent intent = new Intent(Intent.ACTION_USER_STARTING); 16063 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 16064 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 16065 broadcastIntentLocked(null, null, intent, 16066 null, new IIntentReceiver.Stub() { 16067 @Override 16068 public void performReceive(Intent intent, int resultCode, String data, 16069 Bundle extras, boolean ordered, boolean sticky, int sendingUser) 16070 throws RemoteException { 16071 } 16072 }, 0, null, null, 16073 android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 16074 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 16075 } 16076 } 16077 } finally { 16078 Binder.restoreCallingIdentity(ident); 16079 } 16080 16081 return true; 16082 } 16083 16084 void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) { 16085 long ident = Binder.clearCallingIdentity(); 16086 try { 16087 Intent intent; 16088 if (oldUserId >= 0) { 16089 intent = new Intent(Intent.ACTION_USER_BACKGROUND); 16090 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16091 | Intent.FLAG_RECEIVER_FOREGROUND); 16092 intent.putExtra(Intent.EXTRA_USER_HANDLE, oldUserId); 16093 broadcastIntentLocked(null, null, intent, 16094 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 16095 false, false, MY_PID, Process.SYSTEM_UID, oldUserId); 16096 } 16097 if (newUserId >= 0) { 16098 intent = new Intent(Intent.ACTION_USER_FOREGROUND); 16099 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16100 | Intent.FLAG_RECEIVER_FOREGROUND); 16101 intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId); 16102 broadcastIntentLocked(null, null, intent, 16103 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 16104 false, false, MY_PID, Process.SYSTEM_UID, newUserId); 16105 intent = new Intent(Intent.ACTION_USER_SWITCHED); 16106 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16107 | Intent.FLAG_RECEIVER_FOREGROUND); 16108 intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId); 16109 broadcastIntentLocked(null, null, intent, 16110 null, null, 0, null, null, 16111 android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE, 16112 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 16113 } 16114 } finally { 16115 Binder.restoreCallingIdentity(ident); 16116 } 16117 } 16118 16119 void dispatchUserSwitch(final UserStartedState uss, final int oldUserId, 16120 final int newUserId) { 16121 final int N = mUserSwitchObservers.beginBroadcast(); 16122 if (N > 0) { 16123 final IRemoteCallback callback = new IRemoteCallback.Stub() { 16124 int mCount = 0; 16125 @Override 16126 public void sendResult(Bundle data) throws RemoteException { 16127 synchronized (ActivityManagerService.this) { 16128 if (mCurUserSwitchCallback == this) { 16129 mCount++; 16130 if (mCount == N) { 16131 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 16132 } 16133 } 16134 } 16135 } 16136 }; 16137 synchronized (this) { 16138 uss.switching = true; 16139 mCurUserSwitchCallback = callback; 16140 } 16141 for (int i=0; i<N; i++) { 16142 try { 16143 mUserSwitchObservers.getBroadcastItem(i).onUserSwitching( 16144 newUserId, callback); 16145 } catch (RemoteException e) { 16146 } 16147 } 16148 } else { 16149 synchronized (this) { 16150 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 16151 } 16152 } 16153 mUserSwitchObservers.finishBroadcast(); 16154 } 16155 16156 void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 16157 synchronized (this) { 16158 Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId); 16159 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 16160 } 16161 } 16162 16163 void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) { 16164 mCurUserSwitchCallback = null; 16165 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 16166 mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG, 16167 oldUserId, newUserId, uss)); 16168 } 16169 16170 void userInitialized(UserStartedState uss, int newUserId) { 16171 completeSwitchAndInitalize(uss, newUserId, true, false); 16172 } 16173 16174 void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 16175 completeSwitchAndInitalize(uss, newUserId, false, true); 16176 } 16177 16178 void completeSwitchAndInitalize(UserStartedState uss, int newUserId, 16179 boolean clearInitializing, boolean clearSwitching) { 16180 boolean unfrozen = false; 16181 synchronized (this) { 16182 if (clearInitializing) { 16183 uss.initializing = false; 16184 getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier()); 16185 } 16186 if (clearSwitching) { 16187 uss.switching = false; 16188 } 16189 if (!uss.switching && !uss.initializing) { 16190 mWindowManager.stopFreezingScreen(); 16191 unfrozen = true; 16192 } 16193 } 16194 if (unfrozen) { 16195 final int N = mUserSwitchObservers.beginBroadcast(); 16196 for (int i=0; i<N; i++) { 16197 try { 16198 mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId); 16199 } catch (RemoteException e) { 16200 } 16201 } 16202 mUserSwitchObservers.finishBroadcast(); 16203 } 16204 } 16205 16206 void finishUserSwitch(UserStartedState uss) { 16207 synchronized (this) { 16208 if (uss.mState == UserStartedState.STATE_BOOTING 16209 && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) { 16210 uss.mState = UserStartedState.STATE_RUNNING; 16211 final int userId = uss.mHandle.getIdentifier(); 16212 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 16213 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 16214 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT); 16215 broadcastIntentLocked(null, null, intent, 16216 null, null, 0, null, null, 16217 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE, 16218 true, false, MY_PID, Process.SYSTEM_UID, userId); 16219 } 16220 int num = mUserLru.size(); 16221 int i = 0; 16222 while (num > MAX_RUNNING_USERS && i < mUserLru.size()) { 16223 Integer oldUserId = mUserLru.get(i); 16224 UserStartedState oldUss = mStartedUsers.get(oldUserId); 16225 if (oldUss == null) { 16226 // Shouldn't happen, but be sane if it does. 16227 mUserLru.remove(i); 16228 num--; 16229 continue; 16230 } 16231 if (oldUss.mState == UserStartedState.STATE_STOPPING 16232 || oldUss.mState == UserStartedState.STATE_SHUTDOWN) { 16233 // This user is already stopping, doesn't count. 16234 num--; 16235 i++; 16236 continue; 16237 } 16238 if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) { 16239 // Owner and current can't be stopped, but count as running. 16240 i++; 16241 continue; 16242 } 16243 // This is a user to be stopped. 16244 stopUserLocked(oldUserId, null); 16245 num--; 16246 i++; 16247 } 16248 } 16249 } 16250 16251 @Override 16252 public int stopUser(final int userId, final IStopUserCallback callback) { 16253 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 16254 != PackageManager.PERMISSION_GRANTED) { 16255 String msg = "Permission Denial: switchUser() from pid=" 16256 + Binder.getCallingPid() 16257 + ", uid=" + Binder.getCallingUid() 16258 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 16259 Slog.w(TAG, msg); 16260 throw new SecurityException(msg); 16261 } 16262 if (userId <= 0) { 16263 throw new IllegalArgumentException("Can't stop primary user " + userId); 16264 } 16265 synchronized (this) { 16266 return stopUserLocked(userId, callback); 16267 } 16268 } 16269 16270 private int stopUserLocked(final int userId, final IStopUserCallback callback) { 16271 if (mCurrentUserId == userId) { 16272 return ActivityManager.USER_OP_IS_CURRENT; 16273 } 16274 16275 final UserStartedState uss = mStartedUsers.get(userId); 16276 if (uss == null) { 16277 // User is not started, nothing to do... but we do need to 16278 // callback if requested. 16279 if (callback != null) { 16280 mHandler.post(new Runnable() { 16281 @Override 16282 public void run() { 16283 try { 16284 callback.userStopped(userId); 16285 } catch (RemoteException e) { 16286 } 16287 } 16288 }); 16289 } 16290 return ActivityManager.USER_OP_SUCCESS; 16291 } 16292 16293 if (callback != null) { 16294 uss.mStopCallbacks.add(callback); 16295 } 16296 16297 if (uss.mState != UserStartedState.STATE_STOPPING 16298 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 16299 uss.mState = UserStartedState.STATE_STOPPING; 16300 updateStartedUserArrayLocked(); 16301 16302 long ident = Binder.clearCallingIdentity(); 16303 try { 16304 // We are going to broadcast ACTION_USER_STOPPING and then 16305 // once that is done send a final ACTION_SHUTDOWN and then 16306 // stop the user. 16307 final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING); 16308 stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 16309 stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 16310 stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true); 16311 final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN); 16312 // This is the result receiver for the final shutdown broadcast. 16313 final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() { 16314 @Override 16315 public void performReceive(Intent intent, int resultCode, String data, 16316 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 16317 finishUserStop(uss); 16318 } 16319 }; 16320 // This is the result receiver for the initial stopping broadcast. 16321 final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() { 16322 @Override 16323 public void performReceive(Intent intent, int resultCode, String data, 16324 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 16325 // On to the next. 16326 synchronized (ActivityManagerService.this) { 16327 if (uss.mState != UserStartedState.STATE_STOPPING) { 16328 // Whoops, we are being started back up. Abort, abort! 16329 return; 16330 } 16331 uss.mState = UserStartedState.STATE_SHUTDOWN; 16332 } 16333 broadcastIntentLocked(null, null, shutdownIntent, 16334 null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE, 16335 true, false, MY_PID, Process.SYSTEM_UID, userId); 16336 } 16337 }; 16338 // Kick things off. 16339 broadcastIntentLocked(null, null, stoppingIntent, 16340 null, stoppingReceiver, 0, null, null, 16341 android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 16342 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 16343 } finally { 16344 Binder.restoreCallingIdentity(ident); 16345 } 16346 } 16347 16348 return ActivityManager.USER_OP_SUCCESS; 16349 } 16350 16351 void finishUserStop(UserStartedState uss) { 16352 final int userId = uss.mHandle.getIdentifier(); 16353 boolean stopped; 16354 ArrayList<IStopUserCallback> callbacks; 16355 synchronized (this) { 16356 callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks); 16357 if (mStartedUsers.get(userId) != uss) { 16358 stopped = false; 16359 } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) { 16360 stopped = false; 16361 } else { 16362 stopped = true; 16363 // User can no longer run. 16364 mStartedUsers.remove(userId); 16365 mUserLru.remove(Integer.valueOf(userId)); 16366 updateStartedUserArrayLocked(); 16367 16368 // Clean up all state and processes associated with the user. 16369 // Kill all the processes for the user. 16370 forceStopUserLocked(userId, "finish user"); 16371 } 16372 } 16373 16374 for (int i=0; i<callbacks.size(); i++) { 16375 try { 16376 if (stopped) callbacks.get(i).userStopped(userId); 16377 else callbacks.get(i).userStopAborted(userId); 16378 } catch (RemoteException e) { 16379 } 16380 } 16381 16382 mStackSupervisor.removeUserLocked(userId); 16383 } 16384 16385 @Override 16386 public UserInfo getCurrentUser() { 16387 if ((checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) 16388 != PackageManager.PERMISSION_GRANTED) && ( 16389 checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 16390 != PackageManager.PERMISSION_GRANTED)) { 16391 String msg = "Permission Denial: getCurrentUser() from pid=" 16392 + Binder.getCallingPid() 16393 + ", uid=" + Binder.getCallingUid() 16394 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS; 16395 Slog.w(TAG, msg); 16396 throw new SecurityException(msg); 16397 } 16398 synchronized (this) { 16399 return getUserManagerLocked().getUserInfo(mCurrentUserId); 16400 } 16401 } 16402 16403 int getCurrentUserIdLocked() { 16404 return mCurrentUserId; 16405 } 16406 16407 @Override 16408 public boolean isUserRunning(int userId, boolean orStopped) { 16409 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) 16410 != PackageManager.PERMISSION_GRANTED) { 16411 String msg = "Permission Denial: isUserRunning() from pid=" 16412 + Binder.getCallingPid() 16413 + ", uid=" + Binder.getCallingUid() 16414 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS; 16415 Slog.w(TAG, msg); 16416 throw new SecurityException(msg); 16417 } 16418 synchronized (this) { 16419 return isUserRunningLocked(userId, orStopped); 16420 } 16421 } 16422 16423 boolean isUserRunningLocked(int userId, boolean orStopped) { 16424 UserStartedState state = mStartedUsers.get(userId); 16425 if (state == null) { 16426 return false; 16427 } 16428 if (orStopped) { 16429 return true; 16430 } 16431 return state.mState != UserStartedState.STATE_STOPPING 16432 && state.mState != UserStartedState.STATE_SHUTDOWN; 16433 } 16434 16435 @Override 16436 public int[] getRunningUserIds() { 16437 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) 16438 != PackageManager.PERMISSION_GRANTED) { 16439 String msg = "Permission Denial: isUserRunning() from pid=" 16440 + Binder.getCallingPid() 16441 + ", uid=" + Binder.getCallingUid() 16442 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS; 16443 Slog.w(TAG, msg); 16444 throw new SecurityException(msg); 16445 } 16446 synchronized (this) { 16447 return mStartedUserArray; 16448 } 16449 } 16450 16451 private void updateStartedUserArrayLocked() { 16452 int num = 0; 16453 for (int i=0; i<mStartedUsers.size(); i++) { 16454 UserStartedState uss = mStartedUsers.valueAt(i); 16455 // This list does not include stopping users. 16456 if (uss.mState != UserStartedState.STATE_STOPPING 16457 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 16458 num++; 16459 } 16460 } 16461 mStartedUserArray = new int[num]; 16462 num = 0; 16463 for (int i=0; i<mStartedUsers.size(); i++) { 16464 UserStartedState uss = mStartedUsers.valueAt(i); 16465 if (uss.mState != UserStartedState.STATE_STOPPING 16466 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 16467 mStartedUserArray[num] = mStartedUsers.keyAt(i); 16468 num++; 16469 } 16470 } 16471 } 16472 16473 @Override 16474 public void registerUserSwitchObserver(IUserSwitchObserver observer) { 16475 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 16476 != PackageManager.PERMISSION_GRANTED) { 16477 String msg = "Permission Denial: registerUserSwitchObserver() from pid=" 16478 + Binder.getCallingPid() 16479 + ", uid=" + Binder.getCallingUid() 16480 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 16481 Slog.w(TAG, msg); 16482 throw new SecurityException(msg); 16483 } 16484 16485 mUserSwitchObservers.register(observer); 16486 } 16487 16488 @Override 16489 public void unregisterUserSwitchObserver(IUserSwitchObserver observer) { 16490 mUserSwitchObservers.unregister(observer); 16491 } 16492 16493 private boolean userExists(int userId) { 16494 if (userId == 0) { 16495 return true; 16496 } 16497 UserManagerService ums = getUserManagerLocked(); 16498 return ums != null ? (ums.getUserInfo(userId) != null) : false; 16499 } 16500 16501 int[] getUsersLocked() { 16502 UserManagerService ums = getUserManagerLocked(); 16503 return ums != null ? ums.getUserIds() : new int[] { 0 }; 16504 } 16505 16506 UserManagerService getUserManagerLocked() { 16507 if (mUserManager == null) { 16508 IBinder b = ServiceManager.getService(Context.USER_SERVICE); 16509 mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b); 16510 } 16511 return mUserManager; 16512 } 16513 16514 private int applyUserId(int uid, int userId) { 16515 return UserHandle.getUid(userId, uid); 16516 } 16517 16518 ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) { 16519 if (info == null) return null; 16520 ApplicationInfo newInfo = new ApplicationInfo(info); 16521 newInfo.uid = applyUserId(info.uid, userId); 16522 newInfo.dataDir = USER_DATA_DIR + userId + "/" 16523 + info.packageName; 16524 return newInfo; 16525 } 16526 16527 ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) { 16528 if (aInfo == null 16529 || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) { 16530 return aInfo; 16531 } 16532 16533 ActivityInfo info = new ActivityInfo(aInfo); 16534 info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId); 16535 return info; 16536 } 16537 16538 private final class LocalService extends ActivityManagerInternal { 16539 @Override 16540 public void goingToSleep() { 16541 ActivityManagerService.this.goingToSleep(); 16542 } 16543 16544 @Override 16545 public void wakingUp() { 16546 ActivityManagerService.this.wakingUp(); 16547 } 16548 } 16549} 16550