ActivityManagerService.java revision 099bc627c463d9941e23e480f25a78a154429c55
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; 27 28import static com.android.server.am.ActivityStackSupervisor.HOME_STACK_ID; 29 30import android.app.AppOpsManager; 31import android.app.IActivityContainer; 32import android.app.IActivityContainerCallback; 33import android.appwidget.AppWidgetManager; 34import android.graphics.Rect; 35import android.os.BatteryStats; 36import android.util.ArrayMap; 37import com.android.internal.R; 38import com.android.internal.annotations.GuardedBy; 39import com.android.internal.app.IAppOpsService; 40import com.android.internal.app.ProcessMap; 41import com.android.internal.app.ProcessStats; 42import com.android.internal.os.BackgroundThread; 43import com.android.internal.os.BatteryStatsImpl; 44import com.android.internal.os.ProcessCpuTracker; 45import com.android.internal.os.TransferPipe; 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.ServiceThread; 54import com.android.server.SystemServer; 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 dalvik.system.Zygote; 66 67import libcore.io.IoUtils; 68 69import org.xmlpull.v1.XmlPullParser; 70import org.xmlpull.v1.XmlPullParserException; 71import org.xmlpull.v1.XmlSerializer; 72 73import android.app.Activity; 74import android.app.ActivityManager; 75import android.app.ActivityManager.RunningTaskInfo; 76import android.app.ActivityManager.StackInfo; 77import android.app.ActivityManagerNative; 78import android.app.ActivityOptions; 79import android.app.ActivityThread; 80import android.app.AlertDialog; 81import android.app.AppGlobals; 82import android.app.ApplicationErrorReport; 83import android.app.Dialog; 84import android.app.IActivityController; 85import android.app.IApplicationThread; 86import android.app.IInstrumentationWatcher; 87import android.app.INotificationManager; 88import android.app.IProcessObserver; 89import android.app.IServiceConnection; 90import android.app.IStopUserCallback; 91import android.app.IThumbnailReceiver; 92import android.app.IUiAutomationConnection; 93import android.app.IUserSwitchObserver; 94import android.app.Instrumentation; 95import android.app.Notification; 96import android.app.NotificationManager; 97import android.app.PendingIntent; 98import android.app.backup.IBackupManager; 99import android.content.ActivityNotFoundException; 100import android.content.BroadcastReceiver; 101import android.content.ClipData; 102import android.content.ComponentCallbacks2; 103import android.content.ComponentName; 104import android.content.ContentProvider; 105import android.content.ContentResolver; 106import android.content.Context; 107import android.content.DialogInterface; 108import android.content.IContentProvider; 109import android.content.IIntentReceiver; 110import android.content.IIntentSender; 111import android.content.Intent; 112import android.content.IntentFilter; 113import android.content.IntentSender; 114import android.content.pm.ActivityInfo; 115import android.content.pm.ApplicationInfo; 116import android.content.pm.ConfigurationInfo; 117import android.content.pm.IPackageDataObserver; 118import android.content.pm.IPackageManager; 119import android.content.pm.InstrumentationInfo; 120import android.content.pm.PackageInfo; 121import android.content.pm.PackageManager; 122import android.content.pm.ParceledListSlice; 123import android.content.pm.UserInfo; 124import android.content.pm.PackageManager.NameNotFoundException; 125import android.content.pm.PathPermission; 126import android.content.pm.ProviderInfo; 127import android.content.pm.ResolveInfo; 128import android.content.pm.ServiceInfo; 129import android.content.res.CompatibilityInfo; 130import android.content.res.Configuration; 131import android.graphics.Bitmap; 132import android.net.Proxy; 133import android.net.ProxyProperties; 134import android.net.Uri; 135import android.os.Binder; 136import android.os.Build; 137import android.os.Bundle; 138import android.os.Debug; 139import android.os.DropBoxManager; 140import android.os.Environment; 141import android.os.FactoryTest; 142import android.os.FileObserver; 143import android.os.FileUtils; 144import android.os.Handler; 145import android.os.IBinder; 146import android.os.IPermissionController; 147import android.os.IRemoteCallback; 148import android.os.IUserManager; 149import android.os.Looper; 150import android.os.Message; 151import android.os.Parcel; 152import android.os.ParcelFileDescriptor; 153import android.os.Process; 154import android.os.RemoteCallbackList; 155import android.os.RemoteException; 156import android.os.SELinux; 157import android.os.ServiceManager; 158import android.os.StrictMode; 159import android.os.SystemClock; 160import android.os.SystemProperties; 161import android.os.UpdateLock; 162import android.os.UserHandle; 163import android.provider.Settings; 164import android.text.format.DateUtils; 165import android.text.format.Time; 166import android.util.AtomicFile; 167import android.util.EventLog; 168import android.util.Log; 169import android.util.Pair; 170import android.util.PrintWriterPrinter; 171import android.util.Slog; 172import android.util.SparseArray; 173import android.util.TimeUtils; 174import android.util.Xml; 175import android.view.Gravity; 176import android.view.LayoutInflater; 177import android.view.View; 178import android.view.WindowManager; 179 180import java.io.BufferedInputStream; 181import java.io.BufferedOutputStream; 182import java.io.DataInputStream; 183import java.io.DataOutputStream; 184import java.io.File; 185import java.io.FileDescriptor; 186import java.io.FileInputStream; 187import java.io.FileNotFoundException; 188import java.io.FileOutputStream; 189import java.io.IOException; 190import java.io.InputStreamReader; 191import java.io.PrintWriter; 192import java.io.StringWriter; 193import java.lang.ref.WeakReference; 194import java.util.ArrayList; 195import java.util.Arrays; 196import java.util.Collections; 197import java.util.Comparator; 198import java.util.HashMap; 199import java.util.HashSet; 200import java.util.Iterator; 201import java.util.List; 202import java.util.Locale; 203import java.util.Map; 204import java.util.Set; 205import java.util.concurrent.atomic.AtomicBoolean; 206import java.util.concurrent.atomic.AtomicLong; 207 208public final class ActivityManagerService extends ActivityManagerNative 209 implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback { 210 private static final String USER_DATA_DIR = "/data/user/"; 211 static final String TAG = "ActivityManager"; 212 static final String TAG_MU = "ActivityManagerServiceMU"; 213 static final boolean DEBUG = false; 214 static final boolean localLOGV = DEBUG; 215 static final boolean DEBUG_BACKUP = localLOGV || false; 216 static final boolean DEBUG_BROADCAST = localLOGV || false; 217 static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false; 218 static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false; 219 static final boolean DEBUG_CLEANUP = localLOGV || false; 220 static final boolean DEBUG_CONFIGURATION = localLOGV || false; 221 static final boolean DEBUG_FOCUS = false; 222 static final boolean DEBUG_IMMERSIVE = localLOGV || false; 223 static final boolean DEBUG_MU = localLOGV || false; 224 static final boolean DEBUG_OOM_ADJ = localLOGV || false; 225 static final boolean DEBUG_LRU = localLOGV || false; 226 static final boolean DEBUG_PAUSE = localLOGV || false; 227 static final boolean DEBUG_POWER = localLOGV || false; 228 static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false; 229 static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false; 230 static final boolean DEBUG_PROCESSES = localLOGV || false; 231 static final boolean DEBUG_PROVIDER = localLOGV || false; 232 static final boolean DEBUG_RESULTS = localLOGV || false; 233 static final boolean DEBUG_SERVICE = localLOGV || false; 234 static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false; 235 static final boolean DEBUG_STACK = localLOGV || false; 236 static final boolean DEBUG_SWITCH = localLOGV || false; 237 static final boolean DEBUG_TASKS = localLOGV || false; 238 static final boolean DEBUG_THUMBNAILS = localLOGV || false; 239 static final boolean DEBUG_TRANSITION = localLOGV || false; 240 static final boolean DEBUG_URI_PERMISSION = localLOGV || false; 241 static final boolean DEBUG_USER_LEAVING = localLOGV || false; 242 static final boolean DEBUG_VISBILITY = localLOGV || false; 243 static final boolean DEBUG_PSS = localLOGV || false; 244 static final boolean DEBUG_LOCKSCREEN = localLOGV || false; 245 static final boolean VALIDATE_TOKENS = false; 246 static final boolean SHOW_ACTIVITY_START_TIME = true; 247 248 // Control over CPU and battery monitoring. 249 static final long BATTERY_STATS_TIME = 30*60*1000; // write battery stats every 30 minutes. 250 static final boolean MONITOR_CPU_USAGE = true; 251 static final long MONITOR_CPU_MIN_TIME = 5*1000; // don't sample cpu less than every 5 seconds. 252 static final long MONITOR_CPU_MAX_TIME = 0x0fffffff; // wait possibly forever for next cpu sample. 253 static final boolean MONITOR_THREAD_CPU_USAGE = false; 254 255 // The flags that are set for all calls we make to the package manager. 256 static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES; 257 258 private static final String SYSTEM_DEBUGGABLE = "ro.debuggable"; 259 260 static final boolean IS_USER_BUILD = "user".equals(Build.TYPE); 261 262 // Maximum number of recent tasks that we can remember. 263 static final int MAX_RECENT_TASKS = ActivityManager.isLowRamDeviceStatic() ? 10 : 20; 264 265 // Amount of time after a call to stopAppSwitches() during which we will 266 // prevent further untrusted switches from happening. 267 static final long APP_SWITCH_DELAY_TIME = 5*1000; 268 269 // How long we wait for a launched process to attach to the activity manager 270 // before we decide it's never going to come up for real. 271 static final int PROC_START_TIMEOUT = 10*1000; 272 273 // How long we wait for a launched process to attach to the activity manager 274 // before we decide it's never going to come up for real, when the process was 275 // started with a wrapper for instrumentation (such as Valgrind) because it 276 // could take much longer than usual. 277 static final int PROC_START_TIMEOUT_WITH_WRAPPER = 300*1000; 278 279 // How long to wait after going idle before forcing apps to GC. 280 static final int GC_TIMEOUT = 5*1000; 281 282 // The minimum amount of time between successive GC requests for a process. 283 static final int GC_MIN_INTERVAL = 60*1000; 284 285 // The minimum amount of time between successive PSS requests for a process. 286 static final int FULL_PSS_MIN_INTERVAL = 10*60*1000; 287 288 // The minimum amount of time between successive PSS requests for a process 289 // when the request is due to the memory state being lowered. 290 static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000; 291 292 // The rate at which we check for apps using excessive power -- 15 mins. 293 static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000; 294 295 // The minimum sample duration we will allow before deciding we have 296 // enough data on wake locks to start killing things. 297 static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000; 298 299 // The minimum sample duration we will allow before deciding we have 300 // enough data on CPU usage to start killing things. 301 static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000; 302 303 // How long we allow a receiver to run before giving up on it. 304 static final int BROADCAST_FG_TIMEOUT = 10*1000; 305 static final int BROADCAST_BG_TIMEOUT = 60*1000; 306 307 // How long we wait until we timeout on key dispatching. 308 static final int KEY_DISPATCHING_TIMEOUT = 5*1000; 309 310 // How long we wait until we timeout on key dispatching during instrumentation. 311 static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000; 312 313 // Amount of time we wait for observers to handle a user switch before 314 // giving up on them and unfreezing the screen. 315 static final int USER_SWITCH_TIMEOUT = 2*1000; 316 317 // Maximum number of users we allow to be running at a time. 318 static final int MAX_RUNNING_USERS = 3; 319 320 // How long to wait in getAssistContextExtras for the activity and foreground services 321 // to respond with the result. 322 static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500; 323 324 // Maximum number of persisted Uri grants a package is allowed 325 static final int MAX_PERSISTED_URI_GRANTS = 128; 326 327 static final int MY_PID = Process.myPid(); 328 329 static final String[] EMPTY_STRING_ARRAY = new String[0]; 330 331 // How many bytes to write into the dropbox log before truncating 332 static final int DROPBOX_MAX_SIZE = 256 * 1024; 333 334 /** Run all ActivityStacks through this */ 335 ActivityStackSupervisor mStackSupervisor; 336 337 public IntentFirewall mIntentFirewall; 338 339 // Whether we should show our dialogs (ANR, crash, etc) or just perform their 340 // default actuion automatically. Important for devices without direct input 341 // devices. 342 private boolean mShowDialogs = true; 343 344 /** 345 * Description of a request to start a new activity, which has been held 346 * due to app switches being disabled. 347 */ 348 static class PendingActivityLaunch { 349 final ActivityRecord r; 350 final ActivityRecord sourceRecord; 351 final int startFlags; 352 final ActivityStack stack; 353 354 PendingActivityLaunch(ActivityRecord _r, ActivityRecord _sourceRecord, 355 int _startFlags, ActivityStack _stack) { 356 r = _r; 357 sourceRecord = _sourceRecord; 358 startFlags = _startFlags; 359 stack = _stack; 360 } 361 } 362 363 final ArrayList<PendingActivityLaunch> mPendingActivityLaunches 364 = new ArrayList<PendingActivityLaunch>(); 365 366 BroadcastQueue mFgBroadcastQueue; 367 BroadcastQueue mBgBroadcastQueue; 368 // Convenient for easy iteration over the queues. Foreground is first 369 // so that dispatch of foreground broadcasts gets precedence. 370 final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2]; 371 372 BroadcastQueue broadcastQueueForIntent(Intent intent) { 373 final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0; 374 if (DEBUG_BACKGROUND_BROADCAST) { 375 Slog.i(TAG, "Broadcast intent " + intent + " on " 376 + (isFg ? "foreground" : "background") 377 + " queue"); 378 } 379 return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue; 380 } 381 382 BroadcastRecord broadcastRecordForReceiverLocked(IBinder receiver) { 383 for (BroadcastQueue queue : mBroadcastQueues) { 384 BroadcastRecord r = queue.getMatchingOrderedReceiver(receiver); 385 if (r != null) { 386 return r; 387 } 388 } 389 return null; 390 } 391 392 /** 393 * Activity we have told the window manager to have key focus. 394 */ 395 ActivityRecord mFocusedActivity = null; 396 397 /** 398 * List of intents that were used to start the most recent tasks. 399 */ 400 private final ArrayList<TaskRecord> mRecentTasks = new ArrayList<TaskRecord>(); 401 402 public class PendingAssistExtras extends Binder implements Runnable { 403 public final ActivityRecord activity; 404 public boolean haveResult = false; 405 public Bundle result = null; 406 public PendingAssistExtras(ActivityRecord _activity) { 407 activity = _activity; 408 } 409 @Override 410 public void run() { 411 Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity); 412 synchronized (this) { 413 haveResult = true; 414 notifyAll(); 415 } 416 } 417 } 418 419 final ArrayList<PendingAssistExtras> mPendingAssistExtras 420 = new ArrayList<PendingAssistExtras>(); 421 422 /** 423 * Process management. 424 */ 425 final ProcessList mProcessList = new ProcessList(); 426 427 /** 428 * All of the applications we currently have running organized by name. 429 * The keys are strings of the application package name (as 430 * returned by the package manager), and the keys are ApplicationRecord 431 * objects. 432 */ 433 final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>(); 434 435 /** 436 * Tracking long-term execution of processes to look for abuse and other 437 * bad app behavior. 438 */ 439 final ProcessStatsService mProcessStats; 440 441 /** 442 * The currently running isolated processes. 443 */ 444 final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>(); 445 446 /** 447 * Counter for assigning isolated process uids, to avoid frequently reusing the 448 * same ones. 449 */ 450 int mNextIsolatedProcessUid = 0; 451 452 /** 453 * The currently running heavy-weight process, if any. 454 */ 455 ProcessRecord mHeavyWeightProcess = null; 456 457 /** 458 * The last time that various processes have crashed. 459 */ 460 final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>(); 461 462 /** 463 * Information about a process that is currently marked as bad. 464 */ 465 static final class BadProcessInfo { 466 BadProcessInfo(long time, String shortMsg, String longMsg, String stack) { 467 this.time = time; 468 this.shortMsg = shortMsg; 469 this.longMsg = longMsg; 470 this.stack = stack; 471 } 472 473 final long time; 474 final String shortMsg; 475 final String longMsg; 476 final String stack; 477 } 478 479 /** 480 * Set of applications that we consider to be bad, and will reject 481 * incoming broadcasts from (which the user has no control over). 482 * Processes are added to this set when they have crashed twice within 483 * a minimum amount of time; they are removed from it when they are 484 * later restarted (hopefully due to some user action). The value is the 485 * time it was added to the list. 486 */ 487 final ProcessMap<BadProcessInfo> mBadProcesses = new ProcessMap<BadProcessInfo>(); 488 489 /** 490 * All of the processes we currently have running organized by pid. 491 * The keys are the pid running the application. 492 * 493 * <p>NOTE: This object is protected by its own lock, NOT the global 494 * activity manager lock! 495 */ 496 final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>(); 497 498 /** 499 * All of the processes that have been forced to be foreground. The key 500 * is the pid of the caller who requested it (we hold a death 501 * link on it). 502 */ 503 abstract class ForegroundToken implements IBinder.DeathRecipient { 504 int pid; 505 IBinder token; 506 } 507 final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>(); 508 509 /** 510 * List of records for processes that someone had tried to start before the 511 * system was ready. We don't start them at that point, but ensure they 512 * are started by the time booting is complete. 513 */ 514 final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>(); 515 516 /** 517 * List of persistent applications that are in the process 518 * of being started. 519 */ 520 final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>(); 521 522 /** 523 * Processes that are being forcibly torn down. 524 */ 525 final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>(); 526 527 /** 528 * List of running applications, sorted by recent usage. 529 * The first entry in the list is the least recently used. 530 */ 531 final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>(); 532 533 /** 534 * Where in mLruProcesses that the processes hosting activities start. 535 */ 536 int mLruProcessActivityStart = 0; 537 538 /** 539 * Where in mLruProcesses that the processes hosting services start. 540 * This is after (lower index) than mLruProcessesActivityStart. 541 */ 542 int mLruProcessServiceStart = 0; 543 544 /** 545 * List of processes that should gc as soon as things are idle. 546 */ 547 final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>(); 548 549 /** 550 * Processes we want to collect PSS data from. 551 */ 552 final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>(); 553 554 /** 555 * Last time we requested PSS data of all processes. 556 */ 557 long mLastFullPssTime = SystemClock.uptimeMillis(); 558 559 /** 560 * This is the process holding what we currently consider to be 561 * the "home" activity. 562 */ 563 ProcessRecord mHomeProcess; 564 565 /** 566 * This is the process holding the activity the user last visited that 567 * is in a different process from the one they are currently in. 568 */ 569 ProcessRecord mPreviousProcess; 570 571 /** 572 * The time at which the previous process was last visible. 573 */ 574 long mPreviousProcessVisibleTime; 575 576 /** 577 * Which uses have been started, so are allowed to run code. 578 */ 579 final SparseArray<UserStartedState> mStartedUsers = new SparseArray<UserStartedState>(); 580 581 /** 582 * LRU list of history of current users. Most recently current is at the end. 583 */ 584 final ArrayList<Integer> mUserLru = new ArrayList<Integer>(); 585 586 /** 587 * Constant array of the users that are currently started. 588 */ 589 int[] mStartedUserArray = new int[] { 0 }; 590 591 /** 592 * Registered observers of the user switching mechanics. 593 */ 594 final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers 595 = new RemoteCallbackList<IUserSwitchObserver>(); 596 597 /** 598 * Currently active user switch. 599 */ 600 Object mCurUserSwitchCallback; 601 602 /** 603 * Packages that the user has asked to have run in screen size 604 * compatibility mode instead of filling the screen. 605 */ 606 final CompatModePackages mCompatModePackages; 607 608 /** 609 * Set of IntentSenderRecord objects that are currently active. 610 */ 611 final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords 612 = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>(); 613 614 /** 615 * Fingerprints (hashCode()) of stack traces that we've 616 * already logged DropBox entries for. Guarded by itself. If 617 * something (rogue user app) forces this over 618 * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared. 619 */ 620 private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>(); 621 private static final int MAX_DUP_SUPPRESSED_STACKS = 5000; 622 623 /** 624 * Strict Mode background batched logging state. 625 * 626 * The string buffer is guarded by itself, and its lock is also 627 * used to determine if another batched write is already 628 * in-flight. 629 */ 630 private final StringBuilder mStrictModeBuffer = new StringBuilder(); 631 632 /** 633 * Keeps track of all IIntentReceivers that have been registered for 634 * broadcasts. Hash keys are the receiver IBinder, hash value is 635 * a ReceiverList. 636 */ 637 final HashMap<IBinder, ReceiverList> mRegisteredReceivers = 638 new HashMap<IBinder, ReceiverList>(); 639 640 /** 641 * Resolver for broadcast intents to registered receivers. 642 * Holds BroadcastFilter (subclass of IntentFilter). 643 */ 644 final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver 645 = new IntentResolver<BroadcastFilter, BroadcastFilter>() { 646 @Override 647 protected boolean allowFilterResult( 648 BroadcastFilter filter, List<BroadcastFilter> dest) { 649 IBinder target = filter.receiverList.receiver.asBinder(); 650 for (int i=dest.size()-1; i>=0; i--) { 651 if (dest.get(i).receiverList.receiver.asBinder() == target) { 652 return false; 653 } 654 } 655 return true; 656 } 657 658 @Override 659 protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) { 660 if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL 661 || userId == filter.owningUserId) { 662 return super.newResult(filter, match, userId); 663 } 664 return null; 665 } 666 667 @Override 668 protected BroadcastFilter[] newArray(int size) { 669 return new BroadcastFilter[size]; 670 } 671 672 @Override 673 protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) { 674 return packageName.equals(filter.packageName); 675 } 676 }; 677 678 /** 679 * State of all active sticky broadcasts per user. Keys are the action of the 680 * sticky Intent, values are an ArrayList of all broadcasted intents with 681 * that action (which should usually be one). The SparseArray is keyed 682 * by the user ID the sticky is for, and can include UserHandle.USER_ALL 683 * for stickies that are sent to all users. 684 */ 685 final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts = 686 new SparseArray<ArrayMap<String, ArrayList<Intent>>>(); 687 688 final ActiveServices mServices; 689 690 /** 691 * Backup/restore process management 692 */ 693 String mBackupAppName = null; 694 BackupRecord mBackupTarget = null; 695 696 /** 697 * List of PendingThumbnailsRecord objects of clients who are still 698 * waiting to receive all of the thumbnails for a task. 699 */ 700 final ArrayList<PendingThumbnailsRecord> mPendingThumbnails = 701 new ArrayList<PendingThumbnailsRecord>(); 702 703 final ProviderMap mProviderMap; 704 705 /** 706 * List of content providers who have clients waiting for them. The 707 * application is currently being launched and the provider will be 708 * removed from this list once it is published. 709 */ 710 final ArrayList<ContentProviderRecord> mLaunchingProviders 711 = new ArrayList<ContentProviderRecord>(); 712 713 /** 714 * File storing persisted {@link #mGrantedUriPermissions}. 715 */ 716 private final AtomicFile mGrantFile; 717 718 /** XML constants used in {@link #mGrantFile} */ 719 private static final String TAG_URI_GRANTS = "uri-grants"; 720 private static final String TAG_URI_GRANT = "uri-grant"; 721 private static final String ATTR_USER_HANDLE = "userHandle"; 722 private static final String ATTR_SOURCE_PKG = "sourcePkg"; 723 private static final String ATTR_TARGET_PKG = "targetPkg"; 724 private static final String ATTR_URI = "uri"; 725 private static final String ATTR_MODE_FLAGS = "modeFlags"; 726 private static final String ATTR_CREATED_TIME = "createdTime"; 727 728 /** 729 * Global set of specific {@link Uri} permissions that have been granted. 730 * This optimized lookup structure maps from {@link UriPermission#targetUid} 731 * to {@link UriPermission#uri} to {@link UriPermission}. 732 */ 733 @GuardedBy("this") 734 private final SparseArray<ArrayMap<Uri, UriPermission>> 735 mGrantedUriPermissions = new SparseArray<ArrayMap<Uri, UriPermission>>(); 736 737 CoreSettingsObserver mCoreSettingsObserver; 738 739 /** 740 * Thread-local storage used to carry caller permissions over through 741 * indirect content-provider access. 742 */ 743 private class Identity { 744 public int pid; 745 public int uid; 746 747 Identity(int _pid, int _uid) { 748 pid = _pid; 749 uid = _uid; 750 } 751 } 752 753 private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>(); 754 755 /** 756 * All information we have collected about the runtime performance of 757 * any user id that can impact battery performance. 758 */ 759 final BatteryStatsService mBatteryStatsService; 760 761 /** 762 * Information about component usage 763 */ 764 final UsageStatsService mUsageStatsService; 765 766 /** 767 * Information about and control over application operations 768 */ 769 final AppOpsService mAppOpsService; 770 771 /** 772 * Current configuration information. HistoryRecord objects are given 773 * a reference to this object to indicate which configuration they are 774 * currently running in, so this object must be kept immutable. 775 */ 776 Configuration mConfiguration = new Configuration(); 777 778 /** 779 * Current sequencing integer of the configuration, for skipping old 780 * configurations. 781 */ 782 int mConfigurationSeq = 0; 783 784 /** 785 * Hardware-reported OpenGLES version. 786 */ 787 final int GL_ES_VERSION; 788 789 /** 790 * List of initialization arguments to pass to all processes when binding applications to them. 791 * For example, references to the commonly used services. 792 */ 793 HashMap<String, IBinder> mAppBindArgs; 794 795 /** 796 * Temporary to avoid allocations. Protected by main lock. 797 */ 798 final StringBuilder mStringBuilder = new StringBuilder(256); 799 800 /** 801 * Used to control how we initialize the service. 802 */ 803 boolean mStartRunning = false; 804 ComponentName mTopComponent; 805 String mTopAction; 806 String mTopData; 807 boolean mProcessesReady = false; 808 boolean mSystemReady = false; 809 boolean mBooting = false; 810 boolean mWaitingUpdate = false; 811 boolean mDidUpdate = false; 812 boolean mOnBattery = false; 813 boolean mLaunchWarningShown = false; 814 815 Context mContext; 816 817 int mFactoryTest; 818 819 boolean mCheckedForSetup; 820 821 /** 822 * The time at which we will allow normal application switches again, 823 * after a call to {@link #stopAppSwitches()}. 824 */ 825 long mAppSwitchesAllowedTime; 826 827 /** 828 * This is set to true after the first switch after mAppSwitchesAllowedTime 829 * is set; any switches after that will clear the time. 830 */ 831 boolean mDidAppSwitch; 832 833 /** 834 * Last time (in realtime) at which we checked for power usage. 835 */ 836 long mLastPowerCheckRealtime; 837 838 /** 839 * Last time (in uptime) at which we checked for power usage. 840 */ 841 long mLastPowerCheckUptime; 842 843 /** 844 * Set while we are wanting to sleep, to prevent any 845 * activities from being started/resumed. 846 */ 847 boolean mSleeping = false; 848 849 /** 850 * State of external calls telling us if the device is asleep. 851 */ 852 boolean mWentToSleep = false; 853 854 /** 855 * State of external call telling us if the lock screen is shown. 856 */ 857 boolean mLockScreenShown = false; 858 859 /** 860 * Set if we are shutting down the system, similar to sleeping. 861 */ 862 boolean mShuttingDown = false; 863 864 /** 865 * Current sequence id for oom_adj computation traversal. 866 */ 867 int mAdjSeq = 0; 868 869 /** 870 * Current sequence id for process LRU updating. 871 */ 872 int mLruSeq = 0; 873 874 /** 875 * Keep track of the non-cached/empty process we last found, to help 876 * determine how to distribute cached/empty processes next time. 877 */ 878 int mNumNonCachedProcs = 0; 879 880 /** 881 * Keep track of the number of cached hidden procs, to balance oom adj 882 * distribution between those and empty procs. 883 */ 884 int mNumCachedHiddenProcs = 0; 885 886 /** 887 * Keep track of the number of service processes we last found, to 888 * determine on the next iteration which should be B services. 889 */ 890 int mNumServiceProcs = 0; 891 int mNewNumAServiceProcs = 0; 892 int mNewNumServiceProcs = 0; 893 894 /** 895 * Allow the current computed overall memory level of the system to go down? 896 * This is set to false when we are killing processes for reasons other than 897 * memory management, so that the now smaller process list will not be taken as 898 * an indication that memory is tighter. 899 */ 900 boolean mAllowLowerMemLevel = false; 901 902 /** 903 * The last computed memory level, for holding when we are in a state that 904 * processes are going away for other reasons. 905 */ 906 int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL; 907 908 /** 909 * The last total number of process we have, to determine if changes actually look 910 * like a shrinking number of process due to lower RAM. 911 */ 912 int mLastNumProcesses; 913 914 /** 915 * The uptime of the last time we performed idle maintenance. 916 */ 917 long mLastIdleTime = SystemClock.uptimeMillis(); 918 919 /** 920 * Total time spent with RAM that has been added in the past since the last idle time. 921 */ 922 long mLowRamTimeSinceLastIdle = 0; 923 924 /** 925 * If RAM is currently low, when that horrible situatin started. 926 */ 927 long mLowRamStartTime = 0; 928 929 /** 930 * This is set if we had to do a delayed dexopt of an app before launching 931 * it, to increasing the ANR timeouts in that case. 932 */ 933 boolean mDidDexOpt; 934 935 String mDebugApp = null; 936 boolean mWaitForDebugger = false; 937 boolean mDebugTransient = false; 938 String mOrigDebugApp = null; 939 boolean mOrigWaitForDebugger = false; 940 boolean mAlwaysFinishActivities = false; 941 IActivityController mController = null; 942 String mProfileApp = null; 943 ProcessRecord mProfileProc = null; 944 String mProfileFile; 945 ParcelFileDescriptor mProfileFd; 946 int mProfileType = 0; 947 boolean mAutoStopProfiler = false; 948 String mOpenGlTraceApp = null; 949 950 static class ProcessChangeItem { 951 static final int CHANGE_ACTIVITIES = 1<<0; 952 static final int CHANGE_IMPORTANCE= 1<<1; 953 int changes; 954 int uid; 955 int pid; 956 int importance; 957 boolean foregroundActivities; 958 } 959 960 final RemoteCallbackList<IProcessObserver> mProcessObservers 961 = new RemoteCallbackList<IProcessObserver>(); 962 ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5]; 963 964 final ArrayList<ProcessChangeItem> mPendingProcessChanges 965 = new ArrayList<ProcessChangeItem>(); 966 final ArrayList<ProcessChangeItem> mAvailProcessChanges 967 = new ArrayList<ProcessChangeItem>(); 968 969 /** 970 * Runtime CPU use collection thread. This object's lock is used to 971 * protect all related state. 972 */ 973 final Thread mProcessCpuThread; 974 975 /** 976 * Used to collect process stats when showing not responding dialog. 977 * Protected by mProcessCpuThread. 978 */ 979 final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker( 980 MONITOR_THREAD_CPU_USAGE); 981 final AtomicLong mLastCpuTime = new AtomicLong(0); 982 final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true); 983 984 long mLastWriteTime = 0; 985 986 /** 987 * Used to retain an update lock when the foreground activity is in 988 * immersive mode. 989 */ 990 final UpdateLock mUpdateLock = new UpdateLock("immersive"); 991 992 /** 993 * Set to true after the system has finished booting. 994 */ 995 boolean mBooted = false; 996 997 int mProcessLimit = ProcessList.MAX_CACHED_APPS; 998 int mProcessLimitOverride = -1; 999 1000 WindowManagerService mWindowManager; 1001 1002 static ActivityManagerService sSelf; 1003 static ActivityThread sSystemThread; 1004 1005 int mCurrentUserId = 0; 1006 private UserManagerService mUserManager; 1007 1008 private final class AppDeathRecipient implements IBinder.DeathRecipient { 1009 final ProcessRecord mApp; 1010 final int mPid; 1011 final IApplicationThread mAppThread; 1012 1013 AppDeathRecipient(ProcessRecord app, int pid, 1014 IApplicationThread thread) { 1015 if (localLOGV) Slog.v( 1016 TAG, "New death recipient " + this 1017 + " for thread " + thread.asBinder()); 1018 mApp = app; 1019 mPid = pid; 1020 mAppThread = thread; 1021 } 1022 1023 @Override 1024 public void binderDied() { 1025 if (localLOGV) Slog.v( 1026 TAG, "Death received in " + this 1027 + " for thread " + mAppThread.asBinder()); 1028 synchronized(ActivityManagerService.this) { 1029 appDiedLocked(mApp, mPid, mAppThread); 1030 } 1031 } 1032 } 1033 1034 static final int SHOW_ERROR_MSG = 1; 1035 static final int SHOW_NOT_RESPONDING_MSG = 2; 1036 static final int SHOW_FACTORY_ERROR_MSG = 3; 1037 static final int UPDATE_CONFIGURATION_MSG = 4; 1038 static final int GC_BACKGROUND_PROCESSES_MSG = 5; 1039 static final int WAIT_FOR_DEBUGGER_MSG = 6; 1040 static final int SERVICE_TIMEOUT_MSG = 12; 1041 static final int UPDATE_TIME_ZONE = 13; 1042 static final int SHOW_UID_ERROR_MSG = 14; 1043 static final int IM_FEELING_LUCKY_MSG = 15; 1044 static final int PROC_START_TIMEOUT_MSG = 20; 1045 static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21; 1046 static final int KILL_APPLICATION_MSG = 22; 1047 static final int FINALIZE_PENDING_INTENT_MSG = 23; 1048 static final int POST_HEAVY_NOTIFICATION_MSG = 24; 1049 static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25; 1050 static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26; 1051 static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27; 1052 static final int CLEAR_DNS_CACHE_MSG = 28; 1053 static final int UPDATE_HTTP_PROXY_MSG = 29; 1054 static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30; 1055 static final int DISPATCH_PROCESSES_CHANGED = 31; 1056 static final int DISPATCH_PROCESS_DIED = 32; 1057 static final int REPORT_MEM_USAGE_MSG = 33; 1058 static final int REPORT_USER_SWITCH_MSG = 34; 1059 static final int CONTINUE_USER_SWITCH_MSG = 35; 1060 static final int USER_SWITCH_TIMEOUT_MSG = 36; 1061 static final int IMMERSIVE_MODE_LOCK_MSG = 37; 1062 static final int PERSIST_URI_GRANTS_MSG = 38; 1063 static final int REQUEST_ALL_PSS_MSG = 39; 1064 1065 static final int FIRST_ACTIVITY_STACK_MSG = 100; 1066 static final int FIRST_BROADCAST_QUEUE_MSG = 200; 1067 static final int FIRST_COMPAT_MODE_MSG = 300; 1068 static final int FIRST_SUPERVISOR_STACK_MSG = 100; 1069 1070 AlertDialog mUidAlert; 1071 CompatModeDialog mCompatModeDialog; 1072 long mLastMemUsageReportTime = 0; 1073 1074 /** 1075 * Flag whether the current user is a "monkey", i.e. whether 1076 * the UI is driven by a UI automation tool. 1077 */ 1078 private boolean mUserIsMonkey; 1079 1080 final ServiceThread mHandlerThread; 1081 final MainHandler mHandler; 1082 1083 final class MainHandler extends Handler { 1084 public MainHandler(Looper looper) { 1085 super(looper, null, true); 1086 } 1087 1088 @Override 1089 public void handleMessage(Message msg) { 1090 switch (msg.what) { 1091 case SHOW_ERROR_MSG: { 1092 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1093 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), 1094 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; 1095 synchronized (ActivityManagerService.this) { 1096 ProcessRecord proc = (ProcessRecord)data.get("app"); 1097 AppErrorResult res = (AppErrorResult) data.get("result"); 1098 if (proc != null && proc.crashDialog != null) { 1099 Slog.e(TAG, "App already has crash dialog: " + proc); 1100 if (res != null) { 1101 res.set(0); 1102 } 1103 return; 1104 } 1105 if (!showBackground && UserHandle.getAppId(proc.uid) 1106 >= Process.FIRST_APPLICATION_UID && proc.userId != mCurrentUserId 1107 && proc.pid != MY_PID) { 1108 Slog.w(TAG, "Skipping crash dialog of " + proc + ": background"); 1109 if (res != null) { 1110 res.set(0); 1111 } 1112 return; 1113 } 1114 if (mShowDialogs && !mSleeping && !mShuttingDown) { 1115 Dialog d = new AppErrorDialog(mContext, 1116 ActivityManagerService.this, res, proc); 1117 d.show(); 1118 proc.crashDialog = d; 1119 } else { 1120 // The device is asleep, so just pretend that the user 1121 // saw a crash dialog and hit "force quit". 1122 if (res != null) { 1123 res.set(0); 1124 } 1125 } 1126 } 1127 1128 ensureBootCompleted(); 1129 } break; 1130 case SHOW_NOT_RESPONDING_MSG: { 1131 synchronized (ActivityManagerService.this) { 1132 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1133 ProcessRecord proc = (ProcessRecord)data.get("app"); 1134 if (proc != null && proc.anrDialog != null) { 1135 Slog.e(TAG, "App already has anr dialog: " + proc); 1136 return; 1137 } 1138 1139 Intent intent = new Intent("android.intent.action.ANR"); 1140 if (!mProcessesReady) { 1141 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 1142 | Intent.FLAG_RECEIVER_FOREGROUND); 1143 } 1144 broadcastIntentLocked(null, null, intent, 1145 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 1146 false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */); 1147 1148 if (mShowDialogs) { 1149 Dialog d = new AppNotRespondingDialog(ActivityManagerService.this, 1150 mContext, proc, (ActivityRecord)data.get("activity"), 1151 msg.arg1 != 0); 1152 d.show(); 1153 proc.anrDialog = d; 1154 } else { 1155 // Just kill the app if there is no dialog to be shown. 1156 killAppAtUsersRequest(proc, null); 1157 } 1158 } 1159 1160 ensureBootCompleted(); 1161 } break; 1162 case SHOW_STRICT_MODE_VIOLATION_MSG: { 1163 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1164 synchronized (ActivityManagerService.this) { 1165 ProcessRecord proc = (ProcessRecord) data.get("app"); 1166 if (proc == null) { 1167 Slog.e(TAG, "App not found when showing strict mode dialog."); 1168 break; 1169 } 1170 if (proc.crashDialog != null) { 1171 Slog.e(TAG, "App already has strict mode dialog: " + proc); 1172 return; 1173 } 1174 AppErrorResult res = (AppErrorResult) data.get("result"); 1175 if (mShowDialogs && !mSleeping && !mShuttingDown) { 1176 Dialog d = new StrictModeViolationDialog(mContext, 1177 ActivityManagerService.this, res, proc); 1178 d.show(); 1179 proc.crashDialog = d; 1180 } else { 1181 // The device is asleep, so just pretend that the user 1182 // saw a crash dialog and hit "force quit". 1183 res.set(0); 1184 } 1185 } 1186 ensureBootCompleted(); 1187 } break; 1188 case SHOW_FACTORY_ERROR_MSG: { 1189 Dialog d = new FactoryErrorDialog( 1190 mContext, msg.getData().getCharSequence("msg")); 1191 d.show(); 1192 ensureBootCompleted(); 1193 } break; 1194 case UPDATE_CONFIGURATION_MSG: { 1195 final ContentResolver resolver = mContext.getContentResolver(); 1196 Settings.System.putConfiguration(resolver, (Configuration)msg.obj); 1197 } break; 1198 case GC_BACKGROUND_PROCESSES_MSG: { 1199 synchronized (ActivityManagerService.this) { 1200 performAppGcsIfAppropriateLocked(); 1201 } 1202 } break; 1203 case WAIT_FOR_DEBUGGER_MSG: { 1204 synchronized (ActivityManagerService.this) { 1205 ProcessRecord app = (ProcessRecord)msg.obj; 1206 if (msg.arg1 != 0) { 1207 if (!app.waitedForDebugger) { 1208 Dialog d = new AppWaitingForDebuggerDialog( 1209 ActivityManagerService.this, 1210 mContext, app); 1211 app.waitDialog = d; 1212 app.waitedForDebugger = true; 1213 d.show(); 1214 } 1215 } else { 1216 if (app.waitDialog != null) { 1217 app.waitDialog.dismiss(); 1218 app.waitDialog = null; 1219 } 1220 } 1221 } 1222 } break; 1223 case SERVICE_TIMEOUT_MSG: { 1224 if (mDidDexOpt) { 1225 mDidDexOpt = false; 1226 Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG); 1227 nmsg.obj = msg.obj; 1228 mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT); 1229 return; 1230 } 1231 mServices.serviceTimeout((ProcessRecord)msg.obj); 1232 } break; 1233 case UPDATE_TIME_ZONE: { 1234 synchronized (ActivityManagerService.this) { 1235 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1236 ProcessRecord r = mLruProcesses.get(i); 1237 if (r.thread != null) { 1238 try { 1239 r.thread.updateTimeZone(); 1240 } catch (RemoteException ex) { 1241 Slog.w(TAG, "Failed to update time zone for: " + r.info.processName); 1242 } 1243 } 1244 } 1245 } 1246 } break; 1247 case CLEAR_DNS_CACHE_MSG: { 1248 synchronized (ActivityManagerService.this) { 1249 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1250 ProcessRecord r = mLruProcesses.get(i); 1251 if (r.thread != null) { 1252 try { 1253 r.thread.clearDnsCache(); 1254 } catch (RemoteException ex) { 1255 Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName); 1256 } 1257 } 1258 } 1259 } 1260 } break; 1261 case UPDATE_HTTP_PROXY_MSG: { 1262 ProxyProperties proxy = (ProxyProperties)msg.obj; 1263 String host = ""; 1264 String port = ""; 1265 String exclList = ""; 1266 String pacFileUrl = null; 1267 if (proxy != null) { 1268 host = proxy.getHost(); 1269 port = Integer.toString(proxy.getPort()); 1270 exclList = proxy.getExclusionList(); 1271 pacFileUrl = proxy.getPacFileUrl(); 1272 } 1273 synchronized (ActivityManagerService.this) { 1274 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1275 ProcessRecord r = mLruProcesses.get(i); 1276 if (r.thread != null) { 1277 try { 1278 r.thread.setHttpProxy(host, port, exclList, pacFileUrl); 1279 } catch (RemoteException ex) { 1280 Slog.w(TAG, "Failed to update http proxy for: " + 1281 r.info.processName); 1282 } 1283 } 1284 } 1285 } 1286 } break; 1287 case SHOW_UID_ERROR_MSG: { 1288 String title = "System UIDs Inconsistent"; 1289 String text = "UIDs on the system are inconsistent, you need to wipe your" 1290 + " data partition or your device will be unstable."; 1291 Log.e(TAG, title + ": " + text); 1292 if (mShowDialogs) { 1293 // XXX This is a temporary dialog, no need to localize. 1294 AlertDialog d = new BaseErrorDialog(mContext); 1295 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR); 1296 d.setCancelable(false); 1297 d.setTitle(title); 1298 d.setMessage(text); 1299 d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky", 1300 mHandler.obtainMessage(IM_FEELING_LUCKY_MSG)); 1301 mUidAlert = d; 1302 d.show(); 1303 } 1304 } break; 1305 case IM_FEELING_LUCKY_MSG: { 1306 if (mUidAlert != null) { 1307 mUidAlert.dismiss(); 1308 mUidAlert = null; 1309 } 1310 } break; 1311 case PROC_START_TIMEOUT_MSG: { 1312 if (mDidDexOpt) { 1313 mDidDexOpt = false; 1314 Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 1315 nmsg.obj = msg.obj; 1316 mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT); 1317 return; 1318 } 1319 ProcessRecord app = (ProcessRecord)msg.obj; 1320 synchronized (ActivityManagerService.this) { 1321 processStartTimedOutLocked(app); 1322 } 1323 } break; 1324 case DO_PENDING_ACTIVITY_LAUNCHES_MSG: { 1325 synchronized (ActivityManagerService.this) { 1326 doPendingActivityLaunchesLocked(true); 1327 } 1328 } break; 1329 case KILL_APPLICATION_MSG: { 1330 synchronized (ActivityManagerService.this) { 1331 int appid = msg.arg1; 1332 boolean restart = (msg.arg2 == 1); 1333 Bundle bundle = (Bundle)msg.obj; 1334 String pkg = bundle.getString("pkg"); 1335 String reason = bundle.getString("reason"); 1336 forceStopPackageLocked(pkg, appid, restart, false, true, false, 1337 false, UserHandle.USER_ALL, reason); 1338 } 1339 } break; 1340 case FINALIZE_PENDING_INTENT_MSG: { 1341 ((PendingIntentRecord)msg.obj).completeFinalize(); 1342 } break; 1343 case POST_HEAVY_NOTIFICATION_MSG: { 1344 INotificationManager inm = NotificationManager.getService(); 1345 if (inm == null) { 1346 return; 1347 } 1348 1349 ActivityRecord root = (ActivityRecord)msg.obj; 1350 ProcessRecord process = root.app; 1351 if (process == null) { 1352 return; 1353 } 1354 1355 try { 1356 Context context = mContext.createPackageContext(process.info.packageName, 0); 1357 String text = mContext.getString(R.string.heavy_weight_notification, 1358 context.getApplicationInfo().loadLabel(context.getPackageManager())); 1359 Notification notification = new Notification(); 1360 notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon; 1361 notification.when = 0; 1362 notification.flags = Notification.FLAG_ONGOING_EVENT; 1363 notification.tickerText = text; 1364 notification.defaults = 0; // please be quiet 1365 notification.sound = null; 1366 notification.vibrate = null; 1367 notification.setLatestEventInfo(context, text, 1368 mContext.getText(R.string.heavy_weight_notification_detail), 1369 PendingIntent.getActivityAsUser(mContext, 0, root.intent, 1370 PendingIntent.FLAG_CANCEL_CURRENT, null, 1371 new UserHandle(root.userId))); 1372 1373 try { 1374 int[] outId = new int[1]; 1375 inm.enqueueNotificationWithTag("android", "android", null, 1376 R.string.heavy_weight_notification, 1377 notification, outId, root.userId); 1378 } catch (RuntimeException e) { 1379 Slog.w(ActivityManagerService.TAG, 1380 "Error showing notification for heavy-weight app", e); 1381 } catch (RemoteException e) { 1382 } 1383 } catch (NameNotFoundException e) { 1384 Slog.w(TAG, "Unable to create context for heavy notification", e); 1385 } 1386 } break; 1387 case CANCEL_HEAVY_NOTIFICATION_MSG: { 1388 INotificationManager inm = NotificationManager.getService(); 1389 if (inm == null) { 1390 return; 1391 } 1392 try { 1393 inm.cancelNotificationWithTag("android", null, 1394 R.string.heavy_weight_notification, msg.arg1); 1395 } catch (RuntimeException e) { 1396 Slog.w(ActivityManagerService.TAG, 1397 "Error canceling notification for service", e); 1398 } catch (RemoteException e) { 1399 } 1400 } break; 1401 case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: { 1402 synchronized (ActivityManagerService.this) { 1403 checkExcessivePowerUsageLocked(true); 1404 removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1405 Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1406 sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 1407 } 1408 } break; 1409 case SHOW_COMPAT_MODE_DIALOG_MSG: { 1410 synchronized (ActivityManagerService.this) { 1411 ActivityRecord ar = (ActivityRecord)msg.obj; 1412 if (mCompatModeDialog != null) { 1413 if (mCompatModeDialog.mAppInfo.packageName.equals( 1414 ar.info.applicationInfo.packageName)) { 1415 return; 1416 } 1417 mCompatModeDialog.dismiss(); 1418 mCompatModeDialog = null; 1419 } 1420 if (ar != null && false) { 1421 if (mCompatModePackages.getPackageAskCompatModeLocked( 1422 ar.packageName)) { 1423 int mode = mCompatModePackages.computeCompatModeLocked( 1424 ar.info.applicationInfo); 1425 if (mode == ActivityManager.COMPAT_MODE_DISABLED 1426 || mode == ActivityManager.COMPAT_MODE_ENABLED) { 1427 mCompatModeDialog = new CompatModeDialog( 1428 ActivityManagerService.this, mContext, 1429 ar.info.applicationInfo); 1430 mCompatModeDialog.show(); 1431 } 1432 } 1433 } 1434 } 1435 break; 1436 } 1437 case DISPATCH_PROCESSES_CHANGED: { 1438 dispatchProcessesChanged(); 1439 break; 1440 } 1441 case DISPATCH_PROCESS_DIED: { 1442 final int pid = msg.arg1; 1443 final int uid = msg.arg2; 1444 dispatchProcessDied(pid, uid); 1445 break; 1446 } 1447 case REPORT_MEM_USAGE_MSG: { 1448 final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj; 1449 Thread thread = new Thread() { 1450 @Override public void run() { 1451 final SparseArray<ProcessMemInfo> infoMap 1452 = new SparseArray<ProcessMemInfo>(memInfos.size()); 1453 for (int i=0, N=memInfos.size(); i<N; i++) { 1454 ProcessMemInfo mi = memInfos.get(i); 1455 infoMap.put(mi.pid, mi); 1456 } 1457 updateCpuStatsNow(); 1458 synchronized (mProcessCpuThread) { 1459 final int N = mProcessCpuTracker.countStats(); 1460 for (int i=0; i<N; i++) { 1461 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 1462 if (st.vsize > 0) { 1463 long pss = Debug.getPss(st.pid, null); 1464 if (pss > 0) { 1465 if (infoMap.indexOfKey(st.pid) < 0) { 1466 ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid, 1467 ProcessList.NATIVE_ADJ, -1, "native", null); 1468 mi.pss = pss; 1469 memInfos.add(mi); 1470 } 1471 } 1472 } 1473 } 1474 } 1475 1476 long totalPss = 0; 1477 for (int i=0, N=memInfos.size(); i<N; i++) { 1478 ProcessMemInfo mi = memInfos.get(i); 1479 if (mi.pss == 0) { 1480 mi.pss = Debug.getPss(mi.pid, null); 1481 } 1482 totalPss += mi.pss; 1483 } 1484 Collections.sort(memInfos, new Comparator<ProcessMemInfo>() { 1485 @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) { 1486 if (lhs.oomAdj != rhs.oomAdj) { 1487 return lhs.oomAdj < rhs.oomAdj ? -1 : 1; 1488 } 1489 if (lhs.pss != rhs.pss) { 1490 return lhs.pss < rhs.pss ? 1 : -1; 1491 } 1492 return 0; 1493 } 1494 }); 1495 1496 StringBuilder tag = new StringBuilder(128); 1497 StringBuilder stack = new StringBuilder(128); 1498 tag.append("Low on memory -- "); 1499 appendMemBucket(tag, totalPss, "total", false); 1500 appendMemBucket(stack, totalPss, "total", true); 1501 1502 StringBuilder logBuilder = new StringBuilder(1024); 1503 logBuilder.append("Low on memory:\n"); 1504 1505 boolean firstLine = true; 1506 int lastOomAdj = Integer.MIN_VALUE; 1507 for (int i=0, N=memInfos.size(); i<N; i++) { 1508 ProcessMemInfo mi = memInfos.get(i); 1509 1510 if (mi.oomAdj != ProcessList.NATIVE_ADJ 1511 && (mi.oomAdj < ProcessList.SERVICE_ADJ 1512 || mi.oomAdj == ProcessList.HOME_APP_ADJ 1513 || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) { 1514 if (lastOomAdj != mi.oomAdj) { 1515 lastOomAdj = mi.oomAdj; 1516 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) { 1517 tag.append(" / "); 1518 } 1519 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) { 1520 if (firstLine) { 1521 stack.append(":"); 1522 firstLine = false; 1523 } 1524 stack.append("\n\t at "); 1525 } else { 1526 stack.append("$"); 1527 } 1528 } else { 1529 tag.append(" "); 1530 stack.append("$"); 1531 } 1532 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) { 1533 appendMemBucket(tag, mi.pss, mi.name, false); 1534 } 1535 appendMemBucket(stack, mi.pss, mi.name, true); 1536 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ 1537 && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) { 1538 stack.append("("); 1539 for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) { 1540 if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) { 1541 stack.append(DUMP_MEM_OOM_LABEL[k]); 1542 stack.append(":"); 1543 stack.append(DUMP_MEM_OOM_ADJ[k]); 1544 } 1545 } 1546 stack.append(")"); 1547 } 1548 } 1549 1550 logBuilder.append(" "); 1551 logBuilder.append(ProcessList.makeOomAdjString(mi.oomAdj)); 1552 logBuilder.append(' '); 1553 logBuilder.append(ProcessList.makeProcStateString(mi.procState)); 1554 logBuilder.append(' '); 1555 ProcessList.appendRamKb(logBuilder, mi.pss); 1556 logBuilder.append(" kB: "); 1557 logBuilder.append(mi.name); 1558 logBuilder.append(" ("); 1559 logBuilder.append(mi.pid); 1560 logBuilder.append(") "); 1561 logBuilder.append(mi.adjType); 1562 logBuilder.append('\n'); 1563 if (mi.adjReason != null) { 1564 logBuilder.append(" "); 1565 logBuilder.append(mi.adjReason); 1566 logBuilder.append('\n'); 1567 } 1568 } 1569 1570 logBuilder.append(" "); 1571 ProcessList.appendRamKb(logBuilder, totalPss); 1572 logBuilder.append(" kB: TOTAL\n"); 1573 1574 long[] infos = new long[Debug.MEMINFO_COUNT]; 1575 Debug.getMemInfo(infos); 1576 logBuilder.append(" MemInfo: "); 1577 logBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, "); 1578 logBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, "); 1579 logBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, "); 1580 logBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, "); 1581 logBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n"); 1582 if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) { 1583 logBuilder.append(" ZRAM: "); 1584 logBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]); 1585 logBuilder.append(" kB RAM, "); 1586 logBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]); 1587 logBuilder.append(" kB swap total, "); 1588 logBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]); 1589 logBuilder.append(" kB swap free\n"); 1590 } 1591 Slog.i(TAG, logBuilder.toString()); 1592 1593 StringBuilder dropBuilder = new StringBuilder(1024); 1594 /* 1595 StringWriter oomSw = new StringWriter(); 1596 PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256); 1597 StringWriter catSw = new StringWriter(); 1598 PrintWriter catPw = new FastPrintWriter(catSw, false, 256); 1599 String[] emptyArgs = new String[] { }; 1600 dumpApplicationMemoryUsage(null, oomPw, " ", emptyArgs, true, catPw); 1601 oomPw.flush(); 1602 String oomString = oomSw.toString(); 1603 */ 1604 dropBuilder.append(stack); 1605 dropBuilder.append('\n'); 1606 dropBuilder.append('\n'); 1607 dropBuilder.append(logBuilder); 1608 dropBuilder.append('\n'); 1609 /* 1610 dropBuilder.append(oomString); 1611 dropBuilder.append('\n'); 1612 */ 1613 StringWriter catSw = new StringWriter(); 1614 synchronized (ActivityManagerService.this) { 1615 PrintWriter catPw = new FastPrintWriter(catSw, false, 256); 1616 String[] emptyArgs = new String[] { }; 1617 catPw.println(); 1618 dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null); 1619 catPw.println(); 1620 mServices.dumpServicesLocked(null, catPw, emptyArgs, 0, 1621 false, false, null); 1622 catPw.println(); 1623 dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null); 1624 catPw.flush(); 1625 } 1626 dropBuilder.append(catSw.toString()); 1627 addErrorToDropBox("lowmem", null, "system_server", null, 1628 null, tag.toString(), dropBuilder.toString(), null, null); 1629 //Slog.i(TAG, "Sent to dropbox:"); 1630 //Slog.i(TAG, dropBuilder.toString()); 1631 synchronized (ActivityManagerService.this) { 1632 long now = SystemClock.uptimeMillis(); 1633 if (mLastMemUsageReportTime < now) { 1634 mLastMemUsageReportTime = now; 1635 } 1636 } 1637 } 1638 }; 1639 thread.start(); 1640 break; 1641 } 1642 case REPORT_USER_SWITCH_MSG: { 1643 dispatchUserSwitch((UserStartedState)msg.obj, msg.arg1, msg.arg2); 1644 break; 1645 } 1646 case CONTINUE_USER_SWITCH_MSG: { 1647 continueUserSwitch((UserStartedState)msg.obj, msg.arg1, msg.arg2); 1648 break; 1649 } 1650 case USER_SWITCH_TIMEOUT_MSG: { 1651 timeoutUserSwitch((UserStartedState)msg.obj, msg.arg1, msg.arg2); 1652 break; 1653 } 1654 case IMMERSIVE_MODE_LOCK_MSG: { 1655 final boolean nextState = (msg.arg1 != 0); 1656 if (mUpdateLock.isHeld() != nextState) { 1657 if (DEBUG_IMMERSIVE) { 1658 final ActivityRecord r = (ActivityRecord) msg.obj; 1659 Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r); 1660 } 1661 if (nextState) { 1662 mUpdateLock.acquire(); 1663 } else { 1664 mUpdateLock.release(); 1665 } 1666 } 1667 break; 1668 } 1669 case PERSIST_URI_GRANTS_MSG: { 1670 writeGrantedUriPermissions(); 1671 break; 1672 } 1673 case REQUEST_ALL_PSS_MSG: { 1674 requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false); 1675 break; 1676 } 1677 } 1678 } 1679 }; 1680 1681 static final int COLLECT_PSS_BG_MSG = 1; 1682 1683 final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) { 1684 @Override 1685 public void handleMessage(Message msg) { 1686 switch (msg.what) { 1687 case COLLECT_PSS_BG_MSG: { 1688 int i=0, num=0; 1689 long start = SystemClock.uptimeMillis(); 1690 long[] tmp = new long[1]; 1691 do { 1692 ProcessRecord proc; 1693 int procState; 1694 int pid; 1695 synchronized (ActivityManagerService.this) { 1696 if (i >= mPendingPssProcesses.size()) { 1697 if (DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num + " of " + i 1698 + " processes in " + (SystemClock.uptimeMillis()-start) + "ms"); 1699 mPendingPssProcesses.clear(); 1700 return; 1701 } 1702 proc = mPendingPssProcesses.get(i); 1703 procState = proc.pssProcState; 1704 if (proc.thread != null && procState == proc.setProcState) { 1705 pid = proc.pid; 1706 } else { 1707 proc = null; 1708 pid = 0; 1709 } 1710 i++; 1711 } 1712 if (proc != null) { 1713 long pss = Debug.getPss(pid, tmp); 1714 synchronized (ActivityManagerService.this) { 1715 if (proc.thread != null && proc.setProcState == procState 1716 && proc.pid == pid) { 1717 num++; 1718 proc.lastPssTime = SystemClock.uptimeMillis(); 1719 proc.baseProcessTracker.addPss(pss, tmp[0], true, proc.pkgList); 1720 if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString() 1721 + ": " + pss + " lastPss=" + proc.lastPss 1722 + " state=" + ProcessList.makeProcStateString(procState)); 1723 if (proc.initialIdlePss == 0) { 1724 proc.initialIdlePss = pss; 1725 } 1726 proc.lastPss = pss; 1727 if (procState >= ActivityManager.PROCESS_STATE_HOME) { 1728 proc.lastCachedPss = pss; 1729 } 1730 } 1731 } 1732 } 1733 } while (true); 1734 } 1735 } 1736 } 1737 }; 1738 1739 public static void setSystemProcess() { 1740 try { 1741 ActivityManagerService m = sSelf; 1742 1743 ServiceManager.addService(Context.ACTIVITY_SERVICE, m, true); 1744 ServiceManager.addService(ProcessStats.SERVICE_NAME, m.mProcessStats); 1745 ServiceManager.addService("meminfo", new MemBinder(m)); 1746 ServiceManager.addService("gfxinfo", new GraphicsBinder(m)); 1747 ServiceManager.addService("dbinfo", new DbBinder(m)); 1748 if (MONITOR_CPU_USAGE) { 1749 ServiceManager.addService("cpuinfo", new CpuBinder(m)); 1750 } 1751 ServiceManager.addService("permission", new PermissionController(m)); 1752 1753 ApplicationInfo info = 1754 sSelf.mContext.getPackageManager().getApplicationInfo( 1755 "android", STOCK_PM_FLAGS); 1756 sSystemThread.installSystemApplicationInfo(info); 1757 1758 synchronized (sSelf) { 1759 ProcessRecord app = sSelf.newProcessRecordLocked(info, 1760 info.processName, false); 1761 app.persistent = true; 1762 app.pid = MY_PID; 1763 app.maxAdj = ProcessList.SYSTEM_ADJ; 1764 app.makeActive(sSystemThread.getApplicationThread(), sSelf.mProcessStats); 1765 sSelf.mProcessNames.put(app.processName, app.uid, app); 1766 synchronized (sSelf.mPidsSelfLocked) { 1767 sSelf.mPidsSelfLocked.put(app.pid, app); 1768 } 1769 sSelf.updateLruProcessLocked(app, false, null); 1770 sSelf.updateOomAdjLocked(); 1771 } 1772 } catch (PackageManager.NameNotFoundException e) { 1773 throw new RuntimeException( 1774 "Unable to find android system package", e); 1775 } 1776 } 1777 1778 public void setWindowManager(WindowManagerService wm) { 1779 mWindowManager = wm; 1780 mStackSupervisor.setWindowManager(wm); 1781 } 1782 1783 public void startObservingNativeCrashes() { 1784 final NativeCrashListener ncl = new NativeCrashListener(); 1785 ncl.start(); 1786 } 1787 1788 public static ActivityManagerService self() { 1789 return sSelf; 1790 } 1791 1792 public IAppOpsService getAppOpsService() { 1793 return mAppOpsService; 1794 } 1795 1796 static class MemBinder extends Binder { 1797 ActivityManagerService mActivityManagerService; 1798 MemBinder(ActivityManagerService activityManagerService) { 1799 mActivityManagerService = activityManagerService; 1800 } 1801 1802 @Override 1803 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1804 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1805 != PackageManager.PERMISSION_GRANTED) { 1806 pw.println("Permission Denial: can't dump meminfo from from pid=" 1807 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1808 + " without permission " + android.Manifest.permission.DUMP); 1809 return; 1810 } 1811 1812 mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, " ", args, false, null); 1813 } 1814 } 1815 1816 static class GraphicsBinder extends Binder { 1817 ActivityManagerService mActivityManagerService; 1818 GraphicsBinder(ActivityManagerService activityManagerService) { 1819 mActivityManagerService = activityManagerService; 1820 } 1821 1822 @Override 1823 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1824 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1825 != PackageManager.PERMISSION_GRANTED) { 1826 pw.println("Permission Denial: can't dump gfxinfo from from pid=" 1827 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1828 + " without permission " + android.Manifest.permission.DUMP); 1829 return; 1830 } 1831 1832 mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args); 1833 } 1834 } 1835 1836 static class DbBinder extends Binder { 1837 ActivityManagerService mActivityManagerService; 1838 DbBinder(ActivityManagerService activityManagerService) { 1839 mActivityManagerService = activityManagerService; 1840 } 1841 1842 @Override 1843 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1844 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1845 != PackageManager.PERMISSION_GRANTED) { 1846 pw.println("Permission Denial: can't dump dbinfo from from pid=" 1847 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1848 + " without permission " + android.Manifest.permission.DUMP); 1849 return; 1850 } 1851 1852 mActivityManagerService.dumpDbInfo(fd, pw, args); 1853 } 1854 } 1855 1856 static class CpuBinder extends Binder { 1857 ActivityManagerService mActivityManagerService; 1858 CpuBinder(ActivityManagerService activityManagerService) { 1859 mActivityManagerService = activityManagerService; 1860 } 1861 1862 @Override 1863 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1864 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1865 != PackageManager.PERMISSION_GRANTED) { 1866 pw.println("Permission Denial: can't dump cpuinfo from from pid=" 1867 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1868 + " without permission " + android.Manifest.permission.DUMP); 1869 return; 1870 } 1871 1872 synchronized (mActivityManagerService.mProcessCpuThread) { 1873 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad()); 1874 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState( 1875 SystemClock.uptimeMillis())); 1876 } 1877 } 1878 } 1879 1880 public static class Lifecycle extends SystemService { 1881 private ActivityManagerService mService; 1882 1883 @Override 1884 public void onCreate(Context context) { 1885 mService = new ActivityManagerService(context); 1886 } 1887 1888 @Override 1889 public void onStart() { 1890 mService.start(); 1891 } 1892 } 1893 1894 // Note: This method is invoked on the main thread but may need to attach various 1895 // handlers to other threads. So take care to be explicit about the looper. 1896 public ActivityManagerService(Context systemContext) { 1897 sSelf = this; 1898 sSystemThread = ActivityThread.currentActivityThread(); 1899 1900 mContext = systemContext; 1901 mFactoryTest = FactoryTest.getMode(); 1902 1903 Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass()); 1904 1905 mHandlerThread = new ServiceThread(TAG, android.os.Process.THREAD_PRIORITY_FOREGROUND); 1906 mHandlerThread.start(); 1907 mHandler = new MainHandler(mHandlerThread.getLooper()); 1908 1909 mFgBroadcastQueue = new BroadcastQueue(this, mHandler, 1910 "foreground", BROADCAST_FG_TIMEOUT, false); 1911 mBgBroadcastQueue = new BroadcastQueue(this, mHandler, 1912 "background", BROADCAST_BG_TIMEOUT, true); 1913 mBroadcastQueues[0] = mFgBroadcastQueue; 1914 mBroadcastQueues[1] = mBgBroadcastQueue; 1915 1916 mServices = new ActiveServices(this); 1917 mProviderMap = new ProviderMap(this); 1918 1919 // TODO: Move creation of battery stats service outside of activity manager service. 1920 File dataDir = Environment.getDataDirectory(); 1921 File systemDir = new File(dataDir, "system"); 1922 systemDir.mkdirs(); 1923 mBatteryStatsService = new BatteryStatsService(new File( 1924 systemDir, "batterystats.bin").toString(), mHandler); 1925 mBatteryStatsService.getActiveStatistics().readLocked(); 1926 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 1927 mOnBattery = DEBUG_POWER ? true 1928 : mBatteryStatsService.getActiveStatistics().getIsOnBattery(); 1929 mBatteryStatsService.getActiveStatistics().setCallback(this); 1930 1931 mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats")); 1932 1933 mUsageStatsService = new UsageStatsService(new File(systemDir, "usagestats").toString()); 1934 mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler); 1935 1936 mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml")); 1937 1938 // User 0 is the first and only user that runs at boot. 1939 mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true)); 1940 mUserLru.add(Integer.valueOf(0)); 1941 updateStartedUserArrayLocked(); 1942 1943 GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version", 1944 ConfigurationInfo.GL_ES_VERSION_UNDEFINED); 1945 1946 mConfiguration.setToDefaults(); 1947 mConfiguration.setLocale(Locale.getDefault()); 1948 1949 mConfigurationSeq = mConfiguration.seq = 1; 1950 mProcessCpuTracker.init(); 1951 1952 mCompatModePackages = new CompatModePackages(this, systemDir, mHandler); 1953 mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler); 1954 mStackSupervisor = new ActivityStackSupervisor(this); 1955 1956 mProcessCpuThread = new Thread("CpuTracker") { 1957 @Override 1958 public void run() { 1959 while (true) { 1960 try { 1961 try { 1962 synchronized(this) { 1963 final long now = SystemClock.uptimeMillis(); 1964 long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now; 1965 long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now; 1966 //Slog.i(TAG, "Cpu delay=" + nextCpuDelay 1967 // + ", write delay=" + nextWriteDelay); 1968 if (nextWriteDelay < nextCpuDelay) { 1969 nextCpuDelay = nextWriteDelay; 1970 } 1971 if (nextCpuDelay > 0) { 1972 mProcessCpuMutexFree.set(true); 1973 this.wait(nextCpuDelay); 1974 } 1975 } 1976 } catch (InterruptedException e) { 1977 } 1978 updateCpuStatsNow(); 1979 } catch (Exception e) { 1980 Slog.e(TAG, "Unexpected exception collecting process stats", e); 1981 } 1982 } 1983 } 1984 }; 1985 1986 Watchdog.getInstance().addMonitor(this); 1987 Watchdog.getInstance().addThread(mHandler); 1988 } 1989 1990 private void start() { 1991 mProcessCpuThread.start(); 1992 1993 mBatteryStatsService.publish(mContext); 1994 mUsageStatsService.publish(mContext); 1995 mAppOpsService.publish(mContext); 1996 startRunning(null, null, null, null); 1997 } 1998 1999 @Override 2000 public boolean onTransact(int code, Parcel data, Parcel reply, int flags) 2001 throws RemoteException { 2002 if (code == SYSPROPS_TRANSACTION) { 2003 // We need to tell all apps about the system property change. 2004 ArrayList<IBinder> procs = new ArrayList<IBinder>(); 2005 synchronized(this) { 2006 final int NP = mProcessNames.getMap().size(); 2007 for (int ip=0; ip<NP; ip++) { 2008 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 2009 final int NA = apps.size(); 2010 for (int ia=0; ia<NA; ia++) { 2011 ProcessRecord app = apps.valueAt(ia); 2012 if (app.thread != null) { 2013 procs.add(app.thread.asBinder()); 2014 } 2015 } 2016 } 2017 } 2018 2019 int N = procs.size(); 2020 for (int i=0; i<N; i++) { 2021 Parcel data2 = Parcel.obtain(); 2022 try { 2023 procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0); 2024 } catch (RemoteException e) { 2025 } 2026 data2.recycle(); 2027 } 2028 } 2029 try { 2030 return super.onTransact(code, data, reply, flags); 2031 } catch (RuntimeException e) { 2032 // The activity manager only throws security exceptions, so let's 2033 // log all others. 2034 if (!(e instanceof SecurityException)) { 2035 Slog.wtf(TAG, "Activity Manager Crash", e); 2036 } 2037 throw e; 2038 } 2039 } 2040 2041 void updateCpuStats() { 2042 final long now = SystemClock.uptimeMillis(); 2043 if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) { 2044 return; 2045 } 2046 if (mProcessCpuMutexFree.compareAndSet(true, false)) { 2047 synchronized (mProcessCpuThread) { 2048 mProcessCpuThread.notify(); 2049 } 2050 } 2051 } 2052 2053 void updateCpuStatsNow() { 2054 synchronized (mProcessCpuThread) { 2055 mProcessCpuMutexFree.set(false); 2056 final long now = SystemClock.uptimeMillis(); 2057 boolean haveNewCpuStats = false; 2058 2059 if (MONITOR_CPU_USAGE && 2060 mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) { 2061 mLastCpuTime.set(now); 2062 haveNewCpuStats = true; 2063 mProcessCpuTracker.update(); 2064 //Slog.i(TAG, mProcessCpu.printCurrentState()); 2065 //Slog.i(TAG, "Total CPU usage: " 2066 // + mProcessCpu.getTotalCpuPercent() + "%"); 2067 2068 // Slog the cpu usage if the property is set. 2069 if ("true".equals(SystemProperties.get("events.cpu"))) { 2070 int user = mProcessCpuTracker.getLastUserTime(); 2071 int system = mProcessCpuTracker.getLastSystemTime(); 2072 int iowait = mProcessCpuTracker.getLastIoWaitTime(); 2073 int irq = mProcessCpuTracker.getLastIrqTime(); 2074 int softIrq = mProcessCpuTracker.getLastSoftIrqTime(); 2075 int idle = mProcessCpuTracker.getLastIdleTime(); 2076 2077 int total = user + system + iowait + irq + softIrq + idle; 2078 if (total == 0) total = 1; 2079 2080 EventLog.writeEvent(EventLogTags.CPU, 2081 ((user+system+iowait+irq+softIrq) * 100) / total, 2082 (user * 100) / total, 2083 (system * 100) / total, 2084 (iowait * 100) / total, 2085 (irq * 100) / total, 2086 (softIrq * 100) / total); 2087 } 2088 } 2089 2090 long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes(); 2091 final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics(); 2092 synchronized(bstats) { 2093 synchronized(mPidsSelfLocked) { 2094 if (haveNewCpuStats) { 2095 if (mOnBattery) { 2096 int perc = bstats.startAddingCpuLocked(); 2097 int totalUTime = 0; 2098 int totalSTime = 0; 2099 final int N = mProcessCpuTracker.countStats(); 2100 for (int i=0; i<N; i++) { 2101 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 2102 if (!st.working) { 2103 continue; 2104 } 2105 ProcessRecord pr = mPidsSelfLocked.get(st.pid); 2106 int otherUTime = (st.rel_utime*perc)/100; 2107 int otherSTime = (st.rel_stime*perc)/100; 2108 totalUTime += otherUTime; 2109 totalSTime += otherSTime; 2110 if (pr != null) { 2111 BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats; 2112 if (ps == null || !ps.isActive()) { 2113 pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked( 2114 pr.info.uid, pr.processName); 2115 } 2116 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 2117 st.rel_stime-otherSTime); 2118 ps.addSpeedStepTimes(cpuSpeedTimes); 2119 pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10; 2120 } else { 2121 BatteryStatsImpl.Uid.Proc ps = st.batteryStats; 2122 if (ps == null || !ps.isActive()) { 2123 st.batteryStats = ps = bstats.getProcessStatsLocked( 2124 bstats.mapUid(st.uid), st.name); 2125 } 2126 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 2127 st.rel_stime-otherSTime); 2128 ps.addSpeedStepTimes(cpuSpeedTimes); 2129 } 2130 } 2131 bstats.finishAddingCpuLocked(perc, totalUTime, 2132 totalSTime, cpuSpeedTimes); 2133 } 2134 } 2135 } 2136 2137 if (mLastWriteTime < (now-BATTERY_STATS_TIME)) { 2138 mLastWriteTime = now; 2139 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 2140 } 2141 } 2142 } 2143 } 2144 2145 @Override 2146 public void batteryNeedsCpuUpdate() { 2147 updateCpuStatsNow(); 2148 } 2149 2150 @Override 2151 public void batteryPowerChanged(boolean onBattery) { 2152 // When plugging in, update the CPU stats first before changing 2153 // the plug state. 2154 updateCpuStatsNow(); 2155 synchronized (this) { 2156 synchronized(mPidsSelfLocked) { 2157 mOnBattery = DEBUG_POWER ? true : onBattery; 2158 } 2159 } 2160 } 2161 2162 /** 2163 * Initialize the application bind args. These are passed to each 2164 * process when the bindApplication() IPC is sent to the process. They're 2165 * lazily setup to make sure the services are running when they're asked for. 2166 */ 2167 private HashMap<String, IBinder> getCommonServicesLocked() { 2168 if (mAppBindArgs == null) { 2169 mAppBindArgs = new HashMap<String, IBinder>(); 2170 2171 // Setup the application init args 2172 mAppBindArgs.put("package", ServiceManager.getService("package")); 2173 mAppBindArgs.put("window", ServiceManager.getService("window")); 2174 mAppBindArgs.put(Context.ALARM_SERVICE, 2175 ServiceManager.getService(Context.ALARM_SERVICE)); 2176 } 2177 return mAppBindArgs; 2178 } 2179 2180 final void setFocusedActivityLocked(ActivityRecord r) { 2181 if (mFocusedActivity != r) { 2182 if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r); 2183 mFocusedActivity = r; 2184 mStackSupervisor.setFocusedStack(r); 2185 if (r != null) { 2186 mWindowManager.setFocusedApp(r.appToken, true); 2187 } 2188 applyUpdateLockStateLocked(r); 2189 } 2190 } 2191 2192 @Override 2193 public void setFocusedStack(int stackId) { 2194 if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId); 2195 synchronized (ActivityManagerService.this) { 2196 ActivityStack stack = mStackSupervisor.getStack(stackId); 2197 if (stack != null) { 2198 ActivityRecord r = stack.topRunningActivityLocked(null); 2199 if (r != null) { 2200 setFocusedActivityLocked(r); 2201 } 2202 } 2203 } 2204 } 2205 2206 @Override 2207 public void notifyActivityDrawn(IBinder token) { 2208 if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token); 2209 synchronized (this) { 2210 ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token); 2211 if (r != null) { 2212 r.task.stack.notifyActivityDrawnLocked(r); 2213 } 2214 } 2215 } 2216 2217 final void applyUpdateLockStateLocked(ActivityRecord r) { 2218 // Modifications to the UpdateLock state are done on our handler, outside 2219 // the activity manager's locks. The new state is determined based on the 2220 // state *now* of the relevant activity record. The object is passed to 2221 // the handler solely for logging detail, not to be consulted/modified. 2222 final boolean nextState = r != null && r.immersive; 2223 mHandler.sendMessage( 2224 mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r)); 2225 } 2226 2227 final void showAskCompatModeDialogLocked(ActivityRecord r) { 2228 Message msg = Message.obtain(); 2229 msg.what = SHOW_COMPAT_MODE_DIALOG_MSG; 2230 msg.obj = r.task.askedCompatMode ? null : r; 2231 mHandler.sendMessage(msg); 2232 } 2233 2234 private final int updateLruProcessInternalLocked(ProcessRecord app, long now, int index, 2235 String what, Object obj, ProcessRecord srcApp) { 2236 app.lastActivityTime = now; 2237 2238 if (app.activities.size() > 0) { 2239 // Don't want to touch dependent processes that are hosting activities. 2240 return index; 2241 } 2242 2243 int lrui = mLruProcesses.lastIndexOf(app); 2244 if (lrui < 0) { 2245 Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: " 2246 + what + " " + obj + " from " + srcApp); 2247 return index; 2248 } 2249 2250 if (lrui >= index) { 2251 // Don't want to cause this to move dependent processes *back* in the 2252 // list as if they were less frequently used. 2253 return index; 2254 } 2255 2256 if (lrui >= mLruProcessActivityStart) { 2257 // Don't want to touch dependent processes that are hosting activities. 2258 return index; 2259 } 2260 2261 mLruProcesses.remove(lrui); 2262 if (index > 0) { 2263 index--; 2264 } 2265 if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index 2266 + " in LRU list: " + app); 2267 mLruProcesses.add(index, app); 2268 return index; 2269 } 2270 2271 final void removeLruProcessLocked(ProcessRecord app) { 2272 int lrui = mLruProcesses.lastIndexOf(app); 2273 if (lrui >= 0) { 2274 if (lrui <= mLruProcessActivityStart) { 2275 mLruProcessActivityStart--; 2276 } 2277 if (lrui <= mLruProcessServiceStart) { 2278 mLruProcessServiceStart--; 2279 } 2280 mLruProcesses.remove(lrui); 2281 } 2282 } 2283 2284 final void updateLruProcessLocked(ProcessRecord app, boolean activityChange, 2285 ProcessRecord client) { 2286 final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities; 2287 final boolean hasService = false; // not impl yet. app.services.size() > 0; 2288 if (!activityChange && hasActivity) { 2289 // The process has activties, so we are only going to allow activity-based 2290 // adjustments move it. It should be kept in the front of the list with other 2291 // processes that have activities, and we don't want those to change their 2292 // order except due to activity operations. 2293 return; 2294 } 2295 2296 mLruSeq++; 2297 final long now = SystemClock.uptimeMillis(); 2298 app.lastActivityTime = now; 2299 2300 // First a quick reject: if the app is already at the position we will 2301 // put it, then there is nothing to do. 2302 if (hasActivity) { 2303 final int N = mLruProcesses.size(); 2304 if (N > 0 && mLruProcesses.get(N-1) == app) { 2305 if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app); 2306 return; 2307 } 2308 } else { 2309 if (mLruProcessServiceStart > 0 2310 && mLruProcesses.get(mLruProcessServiceStart-1) == app) { 2311 if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app); 2312 return; 2313 } 2314 } 2315 2316 int lrui = mLruProcesses.lastIndexOf(app); 2317 2318 if (app.persistent && lrui >= 0) { 2319 // We don't care about the position of persistent processes, as long as 2320 // they are in the list. 2321 if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app); 2322 return; 2323 } 2324 2325 /* In progress: compute new position first, so we can avoid doing work 2326 if the process is not actually going to move. Not yet working. 2327 int addIndex; 2328 int nextIndex; 2329 boolean inActivity = false, inService = false; 2330 if (hasActivity) { 2331 // Process has activities, put it at the very tipsy-top. 2332 addIndex = mLruProcesses.size(); 2333 nextIndex = mLruProcessServiceStart; 2334 inActivity = true; 2335 } else if (hasService) { 2336 // Process has services, put it at the top of the service list. 2337 addIndex = mLruProcessActivityStart; 2338 nextIndex = mLruProcessServiceStart; 2339 inActivity = true; 2340 inService = true; 2341 } else { 2342 // Process not otherwise of interest, it goes to the top of the non-service area. 2343 addIndex = mLruProcessServiceStart; 2344 if (client != null) { 2345 int clientIndex = mLruProcesses.lastIndexOf(client); 2346 if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating " 2347 + app); 2348 if (clientIndex >= 0 && addIndex > clientIndex) { 2349 addIndex = clientIndex; 2350 } 2351 } 2352 nextIndex = addIndex > 0 ? addIndex-1 : addIndex; 2353 } 2354 2355 Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act=" 2356 + mLruProcessActivityStart + "): " + app); 2357 */ 2358 2359 if (lrui >= 0) { 2360 if (lrui < mLruProcessActivityStart) { 2361 mLruProcessActivityStart--; 2362 } 2363 if (lrui < mLruProcessServiceStart) { 2364 mLruProcessServiceStart--; 2365 } 2366 /* 2367 if (addIndex > lrui) { 2368 addIndex--; 2369 } 2370 if (nextIndex > lrui) { 2371 nextIndex--; 2372 } 2373 */ 2374 mLruProcesses.remove(lrui); 2375 } 2376 2377 /* 2378 mLruProcesses.add(addIndex, app); 2379 if (inActivity) { 2380 mLruProcessActivityStart++; 2381 } 2382 if (inService) { 2383 mLruProcessActivityStart++; 2384 } 2385 */ 2386 2387 int nextIndex; 2388 if (hasActivity) { 2389 final int N = mLruProcesses.size(); 2390 if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) { 2391 // Process doesn't have activities, but has clients with 2392 // activities... move it up, but one below the top (the top 2393 // should always have a real activity). 2394 if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app); 2395 mLruProcesses.add(N-1, app); 2396 // To keep it from spamming the LRU list (by making a bunch of clients), 2397 // we will push down any other entries owned by the app. 2398 final int uid = app.info.uid; 2399 for (int i=N-2; i>mLruProcessActivityStart; i--) { 2400 ProcessRecord subProc = mLruProcesses.get(i); 2401 if (subProc.info.uid == uid) { 2402 // We want to push this one down the list. If the process after 2403 // it is for the same uid, however, don't do so, because we don't 2404 // want them internally to be re-ordered. 2405 if (mLruProcesses.get(i-1).info.uid != uid) { 2406 if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i 2407 + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1)); 2408 ProcessRecord tmp = mLruProcesses.get(i); 2409 mLruProcesses.set(i, mLruProcesses.get(i-1)); 2410 mLruProcesses.set(i-1, tmp); 2411 i--; 2412 } 2413 } else { 2414 // A gap, we can stop here. 2415 break; 2416 } 2417 } 2418 } else { 2419 // Process has activities, put it at the very tipsy-top. 2420 if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app); 2421 mLruProcesses.add(app); 2422 } 2423 nextIndex = mLruProcessServiceStart; 2424 } else if (hasService) { 2425 // Process has services, put it at the top of the service list. 2426 if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app); 2427 mLruProcesses.add(mLruProcessActivityStart, app); 2428 nextIndex = mLruProcessServiceStart; 2429 mLruProcessActivityStart++; 2430 } else { 2431 // Process not otherwise of interest, it goes to the top of the non-service area. 2432 int index = mLruProcessServiceStart; 2433 if (client != null) { 2434 // If there is a client, don't allow the process to be moved up higher 2435 // in the list than that client. 2436 int clientIndex = mLruProcesses.lastIndexOf(client); 2437 if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client 2438 + " when updating " + app); 2439 if (clientIndex <= lrui) { 2440 // Don't allow the client index restriction to push it down farther in the 2441 // list than it already is. 2442 clientIndex = lrui; 2443 } 2444 if (clientIndex >= 0 && index > clientIndex) { 2445 index = clientIndex; 2446 } 2447 } 2448 if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app); 2449 mLruProcesses.add(index, app); 2450 nextIndex = index-1; 2451 mLruProcessActivityStart++; 2452 mLruProcessServiceStart++; 2453 } 2454 2455 // If the app is currently using a content provider or service, 2456 // bump those processes as well. 2457 for (int j=app.connections.size()-1; j>=0; j--) { 2458 ConnectionRecord cr = app.connections.valueAt(j); 2459 if (cr.binding != null && !cr.serviceDead && cr.binding.service != null 2460 && cr.binding.service.app != null 2461 && cr.binding.service.app.lruSeq != mLruSeq 2462 && !cr.binding.service.app.persistent) { 2463 nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex, 2464 "service connection", cr, app); 2465 } 2466 } 2467 for (int j=app.conProviders.size()-1; j>=0; j--) { 2468 ContentProviderRecord cpr = app.conProviders.get(j).provider; 2469 if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) { 2470 nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex, 2471 "provider reference", cpr, app); 2472 } 2473 } 2474 } 2475 2476 final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) { 2477 if (uid == Process.SYSTEM_UID) { 2478 // The system gets to run in any process. If there are multiple 2479 // processes with the same uid, just pick the first (this 2480 // should never happen). 2481 SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName); 2482 if (procs == null) return null; 2483 final int N = procs.size(); 2484 for (int i = 0; i < N; i++) { 2485 if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i); 2486 } 2487 } 2488 ProcessRecord proc = mProcessNames.get(processName, uid); 2489 if (false && proc != null && !keepIfLarge 2490 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY 2491 && proc.lastCachedPss >= 4000) { 2492 // Turn this condition on to cause killing to happen regularly, for testing. 2493 if (proc.baseProcessTracker != null) { 2494 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss); 2495 } 2496 killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss) 2497 + "k from cached"); 2498 } else if (proc != null && !keepIfLarge 2499 && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL 2500 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) { 2501 if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss); 2502 if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) { 2503 if (proc.baseProcessTracker != null) { 2504 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss); 2505 } 2506 killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss) 2507 + "k from cached"); 2508 } 2509 } 2510 return proc; 2511 } 2512 2513 void ensurePackageDexOpt(String packageName) { 2514 IPackageManager pm = AppGlobals.getPackageManager(); 2515 try { 2516 if (pm.performDexOpt(packageName)) { 2517 mDidDexOpt = true; 2518 } 2519 } catch (RemoteException e) { 2520 } 2521 } 2522 2523 boolean isNextTransitionForward() { 2524 int transit = mWindowManager.getPendingAppTransition(); 2525 return transit == AppTransition.TRANSIT_ACTIVITY_OPEN 2526 || transit == AppTransition.TRANSIT_TASK_OPEN 2527 || transit == AppTransition.TRANSIT_TASK_TO_FRONT; 2528 } 2529 2530 final ProcessRecord startProcessLocked(String processName, 2531 ApplicationInfo info, boolean knownToBeDead, int intentFlags, 2532 String hostingType, ComponentName hostingName, boolean allowWhileBooting, 2533 boolean isolated, boolean keepIfLarge) { 2534 ProcessRecord app; 2535 if (!isolated) { 2536 app = getProcessRecordLocked(processName, info.uid, keepIfLarge); 2537 } else { 2538 // If this is an isolated process, it can't re-use an existing process. 2539 app = null; 2540 } 2541 // We don't have to do anything more if: 2542 // (1) There is an existing application record; and 2543 // (2) The caller doesn't think it is dead, OR there is no thread 2544 // object attached to it so we know it couldn't have crashed; and 2545 // (3) There is a pid assigned to it, so it is either starting or 2546 // already running. 2547 if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName 2548 + " app=" + app + " knownToBeDead=" + knownToBeDead 2549 + " thread=" + (app != null ? app.thread : null) 2550 + " pid=" + (app != null ? app.pid : -1)); 2551 if (app != null && app.pid > 0) { 2552 if (!knownToBeDead || app.thread == null) { 2553 // We already have the app running, or are waiting for it to 2554 // come up (we have a pid but not yet its thread), so keep it. 2555 if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app); 2556 // If this is a new package in the process, add the package to the list 2557 app.addPackage(info.packageName, mProcessStats); 2558 return app; 2559 } 2560 2561 // An application record is attached to a previous process, 2562 // clean it up now. 2563 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app); 2564 handleAppDiedLocked(app, true, true); 2565 } 2566 2567 String hostingNameStr = hostingName != null 2568 ? hostingName.flattenToShortString() : null; 2569 2570 if (!isolated) { 2571 if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) { 2572 // If we are in the background, then check to see if this process 2573 // is bad. If so, we will just silently fail. 2574 if (mBadProcesses.get(info.processName, info.uid) != null) { 2575 if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid 2576 + "/" + info.processName); 2577 return null; 2578 } 2579 } else { 2580 // When the user is explicitly starting a process, then clear its 2581 // crash count so that we won't make it bad until they see at 2582 // least one crash dialog again, and make the process good again 2583 // if it had been bad. 2584 if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid 2585 + "/" + info.processName); 2586 mProcessCrashTimes.remove(info.processName, info.uid); 2587 if (mBadProcesses.get(info.processName, info.uid) != null) { 2588 EventLog.writeEvent(EventLogTags.AM_PROC_GOOD, 2589 UserHandle.getUserId(info.uid), info.uid, 2590 info.processName); 2591 mBadProcesses.remove(info.processName, info.uid); 2592 if (app != null) { 2593 app.bad = false; 2594 } 2595 } 2596 } 2597 } 2598 2599 if (app == null) { 2600 app = newProcessRecordLocked(info, processName, isolated); 2601 if (app == null) { 2602 Slog.w(TAG, "Failed making new process record for " 2603 + processName + "/" + info.uid + " isolated=" + isolated); 2604 return null; 2605 } 2606 mProcessNames.put(processName, app.uid, app); 2607 if (isolated) { 2608 mIsolatedProcesses.put(app.uid, app); 2609 } 2610 } else { 2611 // If this is a new package in the process, add the package to the list 2612 app.addPackage(info.packageName, mProcessStats); 2613 } 2614 2615 // If the system is not ready yet, then hold off on starting this 2616 // process until it is. 2617 if (!mProcessesReady 2618 && !isAllowedWhileBooting(info) 2619 && !allowWhileBooting) { 2620 if (!mProcessesOnHold.contains(app)) { 2621 mProcessesOnHold.add(app); 2622 } 2623 if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app); 2624 return app; 2625 } 2626 2627 startProcessLocked(app, hostingType, hostingNameStr); 2628 return (app.pid != 0) ? app : null; 2629 } 2630 2631 boolean isAllowedWhileBooting(ApplicationInfo ai) { 2632 return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0; 2633 } 2634 2635 private final void startProcessLocked(ProcessRecord app, 2636 String hostingType, String hostingNameStr) { 2637 if (app.pid > 0 && app.pid != MY_PID) { 2638 synchronized (mPidsSelfLocked) { 2639 mPidsSelfLocked.remove(app.pid); 2640 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 2641 } 2642 app.setPid(0); 2643 } 2644 2645 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 2646 "startProcessLocked removing on hold: " + app); 2647 mProcessesOnHold.remove(app); 2648 2649 updateCpuStats(); 2650 2651 try { 2652 int uid = app.uid; 2653 2654 int[] gids = null; 2655 int mountExternal = Zygote.MOUNT_EXTERNAL_NONE; 2656 if (!app.isolated) { 2657 int[] permGids = null; 2658 try { 2659 final PackageManager pm = mContext.getPackageManager(); 2660 permGids = pm.getPackageGids(app.info.packageName); 2661 2662 if (Environment.isExternalStorageEmulated()) { 2663 if (pm.checkPermission( 2664 android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE, 2665 app.info.packageName) == PERMISSION_GRANTED) { 2666 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL; 2667 } else { 2668 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER; 2669 } 2670 } 2671 } catch (PackageManager.NameNotFoundException e) { 2672 Slog.w(TAG, "Unable to retrieve gids", e); 2673 } 2674 2675 /* 2676 * Add shared application GID so applications can share some 2677 * resources like shared libraries 2678 */ 2679 if (permGids == null) { 2680 gids = new int[1]; 2681 } else { 2682 gids = new int[permGids.length + 1]; 2683 System.arraycopy(permGids, 0, gids, 1, permGids.length); 2684 } 2685 gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid)); 2686 } 2687 if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) { 2688 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL 2689 && mTopComponent != null 2690 && app.processName.equals(mTopComponent.getPackageName())) { 2691 uid = 0; 2692 } 2693 if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL 2694 && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) { 2695 uid = 0; 2696 } 2697 } 2698 int debugFlags = 0; 2699 if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) { 2700 debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER; 2701 // Also turn on CheckJNI for debuggable apps. It's quite 2702 // awkward to turn on otherwise. 2703 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 2704 } 2705 // Run the app in safe mode if its manifest requests so or the 2706 // system is booted in safe mode. 2707 if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 || 2708 Zygote.systemInSafeMode == true) { 2709 debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE; 2710 } 2711 if ("1".equals(SystemProperties.get("debug.checkjni"))) { 2712 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 2713 } 2714 if ("1".equals(SystemProperties.get("debug.jni.logging"))) { 2715 debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING; 2716 } 2717 if ("1".equals(SystemProperties.get("debug.assert"))) { 2718 debugFlags |= Zygote.DEBUG_ENABLE_ASSERT; 2719 } 2720 2721 // Start the process. It will either succeed and return a result containing 2722 // the PID of the new process, or else throw a RuntimeException. 2723 Process.ProcessStartResult startResult = Process.start("android.app.ActivityThread", 2724 app.processName, uid, uid, gids, debugFlags, mountExternal, 2725 app.info.targetSdkVersion, app.info.seinfo, null); 2726 2727 BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics(); 2728 synchronized (bs) { 2729 if (bs.isOnBattery()) { 2730 bs.getProcessStatsLocked(app.uid, app.processName).incStartsLocked(); 2731 } 2732 } 2733 2734 EventLog.writeEvent(EventLogTags.AM_PROC_START, 2735 UserHandle.getUserId(uid), startResult.pid, uid, 2736 app.processName, hostingType, 2737 hostingNameStr != null ? hostingNameStr : ""); 2738 2739 if (app.persistent) { 2740 Watchdog.getInstance().processStarted(app.processName, startResult.pid); 2741 } 2742 2743 StringBuilder buf = mStringBuilder; 2744 buf.setLength(0); 2745 buf.append("Start proc "); 2746 buf.append(app.processName); 2747 buf.append(" for "); 2748 buf.append(hostingType); 2749 if (hostingNameStr != null) { 2750 buf.append(" "); 2751 buf.append(hostingNameStr); 2752 } 2753 buf.append(": pid="); 2754 buf.append(startResult.pid); 2755 buf.append(" uid="); 2756 buf.append(uid); 2757 buf.append(" gids={"); 2758 if (gids != null) { 2759 for (int gi=0; gi<gids.length; gi++) { 2760 if (gi != 0) buf.append(", "); 2761 buf.append(gids[gi]); 2762 2763 } 2764 } 2765 buf.append("}"); 2766 Slog.i(TAG, buf.toString()); 2767 app.setPid(startResult.pid); 2768 app.usingWrapper = startResult.usingWrapper; 2769 app.removed = false; 2770 synchronized (mPidsSelfLocked) { 2771 this.mPidsSelfLocked.put(startResult.pid, app); 2772 Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 2773 msg.obj = app; 2774 mHandler.sendMessageDelayed(msg, startResult.usingWrapper 2775 ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT); 2776 } 2777 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_STARTED, 2778 app.processName, app.info.uid); 2779 if (app.isolated) { 2780 mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid); 2781 } 2782 } catch (RuntimeException e) { 2783 // XXX do better error recovery. 2784 app.setPid(0); 2785 Slog.e(TAG, "Failure starting process " + app.processName, e); 2786 } 2787 } 2788 2789 void updateUsageStats(ActivityRecord component, boolean resumed) { 2790 if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed); 2791 final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 2792 if (resumed) { 2793 mUsageStatsService.noteResumeComponent(component.realActivity); 2794 synchronized (stats) { 2795 stats.noteActivityResumedLocked(component.app.uid); 2796 } 2797 } else { 2798 mUsageStatsService.notePauseComponent(component.realActivity); 2799 synchronized (stats) { 2800 stats.noteActivityPausedLocked(component.app.uid); 2801 } 2802 } 2803 } 2804 2805 Intent getHomeIntent() { 2806 Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null); 2807 intent.setComponent(mTopComponent); 2808 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 2809 intent.addCategory(Intent.CATEGORY_HOME); 2810 } 2811 return intent; 2812 } 2813 2814 boolean startHomeActivityLocked(int userId) { 2815 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL 2816 && mTopAction == null) { 2817 // We are running in factory test mode, but unable to find 2818 // the factory test app, so just sit around displaying the 2819 // error message and don't try to start anything. 2820 return false; 2821 } 2822 Intent intent = getHomeIntent(); 2823 ActivityInfo aInfo = 2824 resolveActivityInfo(intent, STOCK_PM_FLAGS, userId); 2825 if (aInfo != null) { 2826 intent.setComponent(new ComponentName( 2827 aInfo.applicationInfo.packageName, aInfo.name)); 2828 // Don't do this if the home app is currently being 2829 // instrumented. 2830 aInfo = new ActivityInfo(aInfo); 2831 aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId); 2832 ProcessRecord app = getProcessRecordLocked(aInfo.processName, 2833 aInfo.applicationInfo.uid, true); 2834 if (app == null || app.instrumentationClass == null) { 2835 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK); 2836 mStackSupervisor.startHomeActivity(intent, aInfo); 2837 } 2838 } 2839 2840 return true; 2841 } 2842 2843 private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) { 2844 ActivityInfo ai = null; 2845 ComponentName comp = intent.getComponent(); 2846 try { 2847 if (comp != null) { 2848 ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId); 2849 } else { 2850 ResolveInfo info = AppGlobals.getPackageManager().resolveIntent( 2851 intent, 2852 intent.resolveTypeIfNeeded(mContext.getContentResolver()), 2853 flags, userId); 2854 2855 if (info != null) { 2856 ai = info.activityInfo; 2857 } 2858 } 2859 } catch (RemoteException e) { 2860 // ignore 2861 } 2862 2863 return ai; 2864 } 2865 2866 /** 2867 * Starts the "new version setup screen" if appropriate. 2868 */ 2869 void startSetupActivityLocked() { 2870 // Only do this once per boot. 2871 if (mCheckedForSetup) { 2872 return; 2873 } 2874 2875 // We will show this screen if the current one is a different 2876 // version than the last one shown, and we are not running in 2877 // low-level factory test mode. 2878 final ContentResolver resolver = mContext.getContentResolver(); 2879 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL && 2880 Settings.Global.getInt(resolver, 2881 Settings.Global.DEVICE_PROVISIONED, 0) != 0) { 2882 mCheckedForSetup = true; 2883 2884 // See if we should be showing the platform update setup UI. 2885 Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP); 2886 List<ResolveInfo> ris = sSelf.mContext.getPackageManager() 2887 .queryIntentActivities(intent, PackageManager.GET_META_DATA); 2888 2889 // We don't allow third party apps to replace this. 2890 ResolveInfo ri = null; 2891 for (int i=0; ris != null && i<ris.size(); i++) { 2892 if ((ris.get(i).activityInfo.applicationInfo.flags 2893 & ApplicationInfo.FLAG_SYSTEM) != 0) { 2894 ri = ris.get(i); 2895 break; 2896 } 2897 } 2898 2899 if (ri != null) { 2900 String vers = ri.activityInfo.metaData != null 2901 ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION) 2902 : null; 2903 if (vers == null && ri.activityInfo.applicationInfo.metaData != null) { 2904 vers = ri.activityInfo.applicationInfo.metaData.getString( 2905 Intent.METADATA_SETUP_VERSION); 2906 } 2907 String lastVers = Settings.Secure.getString( 2908 resolver, Settings.Secure.LAST_SETUP_SHOWN); 2909 if (vers != null && !vers.equals(lastVers)) { 2910 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 2911 intent.setComponent(new ComponentName( 2912 ri.activityInfo.packageName, ri.activityInfo.name)); 2913 mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo, 2914 null, null, 0, 0, 0, null, 0, null, false, null, null); 2915 } 2916 } 2917 } 2918 } 2919 2920 CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) { 2921 return mCompatModePackages.compatibilityInfoForPackageLocked(ai); 2922 } 2923 2924 void enforceNotIsolatedCaller(String caller) { 2925 if (UserHandle.isIsolated(Binder.getCallingUid())) { 2926 throw new SecurityException("Isolated process not allowed to call " + caller); 2927 } 2928 } 2929 2930 @Override 2931 public int getFrontActivityScreenCompatMode() { 2932 enforceNotIsolatedCaller("getFrontActivityScreenCompatMode"); 2933 synchronized (this) { 2934 return mCompatModePackages.getFrontActivityScreenCompatModeLocked(); 2935 } 2936 } 2937 2938 @Override 2939 public void setFrontActivityScreenCompatMode(int mode) { 2940 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 2941 "setFrontActivityScreenCompatMode"); 2942 synchronized (this) { 2943 mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode); 2944 } 2945 } 2946 2947 @Override 2948 public int getPackageScreenCompatMode(String packageName) { 2949 enforceNotIsolatedCaller("getPackageScreenCompatMode"); 2950 synchronized (this) { 2951 return mCompatModePackages.getPackageScreenCompatModeLocked(packageName); 2952 } 2953 } 2954 2955 @Override 2956 public void setPackageScreenCompatMode(String packageName, int mode) { 2957 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 2958 "setPackageScreenCompatMode"); 2959 synchronized (this) { 2960 mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode); 2961 } 2962 } 2963 2964 @Override 2965 public boolean getPackageAskScreenCompat(String packageName) { 2966 enforceNotIsolatedCaller("getPackageAskScreenCompat"); 2967 synchronized (this) { 2968 return mCompatModePackages.getPackageAskCompatModeLocked(packageName); 2969 } 2970 } 2971 2972 @Override 2973 public void setPackageAskScreenCompat(String packageName, boolean ask) { 2974 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 2975 "setPackageAskScreenCompat"); 2976 synchronized (this) { 2977 mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask); 2978 } 2979 } 2980 2981 private void dispatchProcessesChanged() { 2982 int N; 2983 synchronized (this) { 2984 N = mPendingProcessChanges.size(); 2985 if (mActiveProcessChanges.length < N) { 2986 mActiveProcessChanges = new ProcessChangeItem[N]; 2987 } 2988 mPendingProcessChanges.toArray(mActiveProcessChanges); 2989 mAvailProcessChanges.addAll(mPendingProcessChanges); 2990 mPendingProcessChanges.clear(); 2991 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes"); 2992 } 2993 2994 int i = mProcessObservers.beginBroadcast(); 2995 while (i > 0) { 2996 i--; 2997 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 2998 if (observer != null) { 2999 try { 3000 for (int j=0; j<N; j++) { 3001 ProcessChangeItem item = mActiveProcessChanges[j]; 3002 if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) { 3003 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid=" 3004 + item.pid + " uid=" + item.uid + ": " 3005 + item.foregroundActivities); 3006 observer.onForegroundActivitiesChanged(item.pid, item.uid, 3007 item.foregroundActivities); 3008 } 3009 if ((item.changes&ProcessChangeItem.CHANGE_IMPORTANCE) != 0) { 3010 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "IMPORTANCE CHANGED pid=" 3011 + item.pid + " uid=" + item.uid + ": " + item.importance); 3012 observer.onImportanceChanged(item.pid, item.uid, 3013 item.importance); 3014 } 3015 } 3016 } catch (RemoteException e) { 3017 } 3018 } 3019 } 3020 mProcessObservers.finishBroadcast(); 3021 } 3022 3023 private void dispatchProcessDied(int pid, int uid) { 3024 int i = mProcessObservers.beginBroadcast(); 3025 while (i > 0) { 3026 i--; 3027 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 3028 if (observer != null) { 3029 try { 3030 observer.onProcessDied(pid, uid); 3031 } catch (RemoteException e) { 3032 } 3033 } 3034 } 3035 mProcessObservers.finishBroadcast(); 3036 } 3037 3038 final void doPendingActivityLaunchesLocked(boolean doResume) { 3039 final int N = mPendingActivityLaunches.size(); 3040 if (N <= 0) { 3041 return; 3042 } 3043 for (int i=0; i<N; i++) { 3044 PendingActivityLaunch pal = mPendingActivityLaunches.get(i); 3045 mStackSupervisor.startActivityUncheckedLocked(pal.r, pal.sourceRecord, pal.startFlags, 3046 doResume && i == (N-1), null); 3047 } 3048 mPendingActivityLaunches.clear(); 3049 } 3050 3051 @Override 3052 public final int startActivity(IApplicationThread caller, String callingPackage, 3053 Intent intent, String resolvedType, IBinder resultTo, 3054 String resultWho, int requestCode, int startFlags, 3055 String profileFile, ParcelFileDescriptor profileFd, Bundle options) { 3056 return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo, 3057 resultWho, requestCode, 3058 startFlags, profileFile, profileFd, options, UserHandle.getCallingUserId()); 3059 } 3060 3061 @Override 3062 public final int startActivityAsUser(IApplicationThread caller, String callingPackage, 3063 Intent intent, String resolvedType, IBinder resultTo, 3064 String resultWho, int requestCode, int startFlags, 3065 String profileFile, ParcelFileDescriptor profileFd, Bundle options, int userId) { 3066 enforceNotIsolatedCaller("startActivity"); 3067 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3068 false, true, "startActivity", null); 3069 // TODO: Switch to user app stacks here. 3070 return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType, 3071 resultTo, resultWho, requestCode, startFlags, profileFile, profileFd, 3072 null, null, options, userId, null); 3073 } 3074 3075 @Override 3076 public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage, 3077 Intent intent, String resolvedType, IBinder resultTo, 3078 String resultWho, int requestCode, int startFlags, String profileFile, 3079 ParcelFileDescriptor profileFd, Bundle options, int userId) { 3080 enforceNotIsolatedCaller("startActivityAndWait"); 3081 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3082 false, true, "startActivityAndWait", null); 3083 WaitResult res = new WaitResult(); 3084 // TODO: Switch to user app stacks here. 3085 mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType, 3086 resultTo, resultWho, requestCode, startFlags, profileFile, profileFd, 3087 res, null, options, UserHandle.getCallingUserId(), null); 3088 return res; 3089 } 3090 3091 @Override 3092 public final int startActivityWithConfig(IApplicationThread caller, String callingPackage, 3093 Intent intent, String resolvedType, IBinder resultTo, 3094 String resultWho, int requestCode, int startFlags, Configuration config, 3095 Bundle options, int userId) { 3096 enforceNotIsolatedCaller("startActivityWithConfig"); 3097 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3098 false, true, "startActivityWithConfig", null); 3099 // TODO: Switch to user app stacks here. 3100 int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, 3101 resolvedType, resultTo, resultWho, requestCode, startFlags, 3102 null, null, null, config, options, userId, null); 3103 return ret; 3104 } 3105 3106 @Override 3107 public int startActivityIntentSender(IApplicationThread caller, 3108 IntentSender intent, Intent fillInIntent, String resolvedType, 3109 IBinder resultTo, String resultWho, int requestCode, 3110 int flagsMask, int flagsValues, Bundle options) { 3111 enforceNotIsolatedCaller("startActivityIntentSender"); 3112 // Refuse possible leaked file descriptors 3113 if (fillInIntent != null && fillInIntent.hasFileDescriptors()) { 3114 throw new IllegalArgumentException("File descriptors passed in Intent"); 3115 } 3116 3117 IIntentSender sender = intent.getTarget(); 3118 if (!(sender instanceof PendingIntentRecord)) { 3119 throw new IllegalArgumentException("Bad PendingIntent object"); 3120 } 3121 3122 PendingIntentRecord pir = (PendingIntentRecord)sender; 3123 3124 synchronized (this) { 3125 // If this is coming from the currently resumed activity, it is 3126 // effectively saying that app switches are allowed at this point. 3127 final ActivityStack stack = getFocusedStack(); 3128 if (stack.mResumedActivity != null && 3129 stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) { 3130 mAppSwitchesAllowedTime = 0; 3131 } 3132 } 3133 int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null, 3134 resultTo, resultWho, requestCode, flagsMask, flagsValues, options); 3135 return ret; 3136 } 3137 3138 @Override 3139 public boolean startNextMatchingActivity(IBinder callingActivity, 3140 Intent intent, Bundle options) { 3141 // Refuse possible leaked file descriptors 3142 if (intent != null && intent.hasFileDescriptors() == true) { 3143 throw new IllegalArgumentException("File descriptors passed in Intent"); 3144 } 3145 3146 synchronized (this) { 3147 final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity); 3148 if (r == null) { 3149 ActivityOptions.abort(options); 3150 return false; 3151 } 3152 if (r.app == null || r.app.thread == null) { 3153 // The caller is not running... d'oh! 3154 ActivityOptions.abort(options); 3155 return false; 3156 } 3157 intent = new Intent(intent); 3158 // The caller is not allowed to change the data. 3159 intent.setDataAndType(r.intent.getData(), r.intent.getType()); 3160 // And we are resetting to find the next component... 3161 intent.setComponent(null); 3162 3163 final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0); 3164 3165 ActivityInfo aInfo = null; 3166 try { 3167 List<ResolveInfo> resolves = 3168 AppGlobals.getPackageManager().queryIntentActivities( 3169 intent, r.resolvedType, 3170 PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS, 3171 UserHandle.getCallingUserId()); 3172 3173 // Look for the original activity in the list... 3174 final int N = resolves != null ? resolves.size() : 0; 3175 for (int i=0; i<N; i++) { 3176 ResolveInfo rInfo = resolves.get(i); 3177 if (rInfo.activityInfo.packageName.equals(r.packageName) 3178 && rInfo.activityInfo.name.equals(r.info.name)) { 3179 // We found the current one... the next matching is 3180 // after it. 3181 i++; 3182 if (i<N) { 3183 aInfo = resolves.get(i).activityInfo; 3184 } 3185 if (debug) { 3186 Slog.v(TAG, "Next matching activity: found current " + r.packageName 3187 + "/" + r.info.name); 3188 Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName 3189 + "/" + aInfo.name); 3190 } 3191 break; 3192 } 3193 } 3194 } catch (RemoteException e) { 3195 } 3196 3197 if (aInfo == null) { 3198 // Nobody who is next! 3199 ActivityOptions.abort(options); 3200 if (debug) Slog.d(TAG, "Next matching activity: nothing found"); 3201 return false; 3202 } 3203 3204 intent.setComponent(new ComponentName( 3205 aInfo.applicationInfo.packageName, aInfo.name)); 3206 intent.setFlags(intent.getFlags()&~( 3207 Intent.FLAG_ACTIVITY_FORWARD_RESULT| 3208 Intent.FLAG_ACTIVITY_CLEAR_TOP| 3209 Intent.FLAG_ACTIVITY_MULTIPLE_TASK| 3210 Intent.FLAG_ACTIVITY_NEW_TASK)); 3211 3212 // Okay now we need to start the new activity, replacing the 3213 // currently running activity. This is a little tricky because 3214 // we want to start the new one as if the current one is finished, 3215 // but not finish the current one first so that there is no flicker. 3216 // And thus... 3217 final boolean wasFinishing = r.finishing; 3218 r.finishing = true; 3219 3220 // Propagate reply information over to the new activity. 3221 final ActivityRecord resultTo = r.resultTo; 3222 final String resultWho = r.resultWho; 3223 final int requestCode = r.requestCode; 3224 r.resultTo = null; 3225 if (resultTo != null) { 3226 resultTo.removeResultsLocked(r, resultWho, requestCode); 3227 } 3228 3229 final long origId = Binder.clearCallingIdentity(); 3230 int res = mStackSupervisor.startActivityLocked(r.app.thread, intent, 3231 r.resolvedType, aInfo, resultTo != null ? resultTo.appToken : null, 3232 resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage, 0, 3233 options, false, null, null); 3234 Binder.restoreCallingIdentity(origId); 3235 3236 r.finishing = wasFinishing; 3237 if (res != ActivityManager.START_SUCCESS) { 3238 return false; 3239 } 3240 return true; 3241 } 3242 } 3243 3244 final int startActivityInPackage(int uid, String callingPackage, 3245 Intent intent, String resolvedType, IBinder resultTo, 3246 String resultWho, int requestCode, int startFlags, Bundle options, int userId) { 3247 3248 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3249 false, true, "startActivityInPackage", null); 3250 3251 // TODO: Switch to user app stacks here. 3252 int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent, resolvedType, 3253 resultTo, resultWho, requestCode, startFlags, 3254 null, null, null, null, options, userId, null); 3255 return ret; 3256 } 3257 3258 @Override 3259 public final int startActivities(IApplicationThread caller, String callingPackage, 3260 Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options, 3261 int userId) { 3262 enforceNotIsolatedCaller("startActivities"); 3263 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3264 false, true, "startActivity", null); 3265 // TODO: Switch to user app stacks here. 3266 int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents, 3267 resolvedTypes, resultTo, options, userId); 3268 return ret; 3269 } 3270 3271 final int startActivitiesInPackage(int uid, String callingPackage, 3272 Intent[] intents, String[] resolvedTypes, IBinder resultTo, 3273 Bundle options, int userId) { 3274 3275 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3276 false, true, "startActivityInPackage", null); 3277 // TODO: Switch to user app stacks here. 3278 int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes, 3279 resultTo, options, userId); 3280 return ret; 3281 } 3282 3283 final void addRecentTaskLocked(TaskRecord task) { 3284 int N = mRecentTasks.size(); 3285 // Quick case: check if the top-most recent task is the same. 3286 if (N > 0 && mRecentTasks.get(0) == task) { 3287 return; 3288 } 3289 // Remove any existing entries that are the same kind of task. 3290 for (int i=0; i<N; i++) { 3291 TaskRecord tr = mRecentTasks.get(i); 3292 if (task.userId == tr.userId 3293 && ((task.affinity != null && task.affinity.equals(tr.affinity)) 3294 || (task.intent != null && task.intent.filterEquals(tr.intent)))) { 3295 tr.disposeThumbnail(); 3296 mRecentTasks.remove(i); 3297 i--; 3298 N--; 3299 if (task.intent == null) { 3300 // If the new recent task we are adding is not fully 3301 // specified, then replace it with the existing recent task. 3302 task = tr; 3303 } 3304 } 3305 } 3306 if (N >= MAX_RECENT_TASKS) { 3307 mRecentTasks.remove(N-1).disposeThumbnail(); 3308 } 3309 mRecentTasks.add(0, task); 3310 } 3311 3312 @Override 3313 public void reportActivityFullyDrawn(IBinder token) { 3314 synchronized (this) { 3315 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3316 if (r == null) { 3317 return; 3318 } 3319 r.reportFullyDrawnLocked(); 3320 } 3321 } 3322 3323 @Override 3324 public void setRequestedOrientation(IBinder token, int requestedOrientation) { 3325 synchronized (this) { 3326 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3327 if (r == null) { 3328 return; 3329 } 3330 final long origId = Binder.clearCallingIdentity(); 3331 mWindowManager.setAppOrientation(r.appToken, requestedOrientation); 3332 Configuration config = mWindowManager.updateOrientationFromAppTokens( 3333 mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null); 3334 if (config != null) { 3335 r.frozenBeforeDestroy = true; 3336 if (!updateConfigurationLocked(config, r, false, false)) { 3337 mStackSupervisor.resumeTopActivitiesLocked(); 3338 } 3339 } 3340 Binder.restoreCallingIdentity(origId); 3341 } 3342 } 3343 3344 @Override 3345 public int getRequestedOrientation(IBinder token) { 3346 synchronized (this) { 3347 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3348 if (r == null) { 3349 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; 3350 } 3351 return mWindowManager.getAppOrientation(r.appToken); 3352 } 3353 } 3354 3355 /** 3356 * This is the internal entry point for handling Activity.finish(). 3357 * 3358 * @param token The Binder token referencing the Activity we want to finish. 3359 * @param resultCode Result code, if any, from this Activity. 3360 * @param resultData Result data (Intent), if any, from this Activity. 3361 * 3362 * @return Returns true if the activity successfully finished, or false if it is still running. 3363 */ 3364 @Override 3365 public final boolean finishActivity(IBinder token, int resultCode, Intent resultData) { 3366 // Refuse possible leaked file descriptors 3367 if (resultData != null && resultData.hasFileDescriptors() == true) { 3368 throw new IllegalArgumentException("File descriptors passed in Intent"); 3369 } 3370 3371 synchronized(this) { 3372 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3373 if (r == null) { 3374 return true; 3375 } 3376 if (mController != null) { 3377 // Find the first activity that is not finishing. 3378 ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0); 3379 if (next != null) { 3380 // ask watcher if this is allowed 3381 boolean resumeOK = true; 3382 try { 3383 resumeOK = mController.activityResuming(next.packageName); 3384 } catch (RemoteException e) { 3385 mController = null; 3386 Watchdog.getInstance().setActivityController(null); 3387 } 3388 3389 if (!resumeOK) { 3390 return false; 3391 } 3392 } 3393 } 3394 final long origId = Binder.clearCallingIdentity(); 3395 boolean res = r.task.stack.requestFinishActivityLocked(token, resultCode, 3396 resultData, "app-request", true); 3397 Binder.restoreCallingIdentity(origId); 3398 return res; 3399 } 3400 } 3401 3402 @Override 3403 public final void finishHeavyWeightApp() { 3404 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 3405 != PackageManager.PERMISSION_GRANTED) { 3406 String msg = "Permission Denial: finishHeavyWeightApp() from pid=" 3407 + Binder.getCallingPid() 3408 + ", uid=" + Binder.getCallingUid() 3409 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 3410 Slog.w(TAG, msg); 3411 throw new SecurityException(msg); 3412 } 3413 3414 synchronized(this) { 3415 if (mHeavyWeightProcess == null) { 3416 return; 3417 } 3418 3419 ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>( 3420 mHeavyWeightProcess.activities); 3421 for (int i=0; i<activities.size(); i++) { 3422 ActivityRecord r = activities.get(i); 3423 if (!r.finishing) { 3424 r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED, 3425 null, "finish-heavy", true); 3426 } 3427 } 3428 3429 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 3430 mHeavyWeightProcess.userId, 0)); 3431 mHeavyWeightProcess = null; 3432 } 3433 } 3434 3435 @Override 3436 public void crashApplication(int uid, int initialPid, String packageName, 3437 String message) { 3438 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 3439 != PackageManager.PERMISSION_GRANTED) { 3440 String msg = "Permission Denial: crashApplication() from pid=" 3441 + Binder.getCallingPid() 3442 + ", uid=" + Binder.getCallingUid() 3443 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 3444 Slog.w(TAG, msg); 3445 throw new SecurityException(msg); 3446 } 3447 3448 synchronized(this) { 3449 ProcessRecord proc = null; 3450 3451 // Figure out which process to kill. We don't trust that initialPid 3452 // still has any relation to current pids, so must scan through the 3453 // list. 3454 synchronized (mPidsSelfLocked) { 3455 for (int i=0; i<mPidsSelfLocked.size(); i++) { 3456 ProcessRecord p = mPidsSelfLocked.valueAt(i); 3457 if (p.uid != uid) { 3458 continue; 3459 } 3460 if (p.pid == initialPid) { 3461 proc = p; 3462 break; 3463 } 3464 if (p.pkgList.containsKey(packageName)) { 3465 proc = p; 3466 } 3467 } 3468 } 3469 3470 if (proc == null) { 3471 Slog.w(TAG, "crashApplication: nothing for uid=" + uid 3472 + " initialPid=" + initialPid 3473 + " packageName=" + packageName); 3474 return; 3475 } 3476 3477 if (proc.thread != null) { 3478 if (proc.pid == Process.myPid()) { 3479 Log.w(TAG, "crashApplication: trying to crash self!"); 3480 return; 3481 } 3482 long ident = Binder.clearCallingIdentity(); 3483 try { 3484 proc.thread.scheduleCrash(message); 3485 } catch (RemoteException e) { 3486 } 3487 Binder.restoreCallingIdentity(ident); 3488 } 3489 } 3490 } 3491 3492 @Override 3493 public final void finishSubActivity(IBinder token, String resultWho, 3494 int requestCode) { 3495 synchronized(this) { 3496 final long origId = Binder.clearCallingIdentity(); 3497 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3498 if (r != null) { 3499 r.task.stack.finishSubActivityLocked(r, resultWho, requestCode); 3500 } 3501 Binder.restoreCallingIdentity(origId); 3502 } 3503 } 3504 3505 @Override 3506 public boolean finishActivityAffinity(IBinder token) { 3507 synchronized(this) { 3508 final long origId = Binder.clearCallingIdentity(); 3509 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3510 boolean res = false; 3511 if (r != null) { 3512 res = r.task.stack.finishActivityAffinityLocked(r); 3513 } 3514 Binder.restoreCallingIdentity(origId); 3515 return res; 3516 } 3517 } 3518 3519 @Override 3520 public boolean willActivityBeVisible(IBinder token) { 3521 synchronized(this) { 3522 ActivityStack stack = ActivityRecord.getStackLocked(token); 3523 if (stack != null) { 3524 return stack.willActivityBeVisibleLocked(token); 3525 } 3526 return false; 3527 } 3528 } 3529 3530 @Override 3531 public void overridePendingTransition(IBinder token, String packageName, 3532 int enterAnim, int exitAnim) { 3533 synchronized(this) { 3534 ActivityRecord self = ActivityRecord.isInStackLocked(token); 3535 if (self == null) { 3536 return; 3537 } 3538 3539 final long origId = Binder.clearCallingIdentity(); 3540 3541 if (self.state == ActivityState.RESUMED 3542 || self.state == ActivityState.PAUSING) { 3543 mWindowManager.overridePendingAppTransition(packageName, 3544 enterAnim, exitAnim, null); 3545 } 3546 3547 Binder.restoreCallingIdentity(origId); 3548 } 3549 } 3550 3551 /** 3552 * Main function for removing an existing process from the activity manager 3553 * as a result of that process going away. Clears out all connections 3554 * to the process. 3555 */ 3556 private final void handleAppDiedLocked(ProcessRecord app, 3557 boolean restarting, boolean allowRestart) { 3558 int pid = app.pid; 3559 cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1); 3560 if (!restarting) { 3561 removeLruProcessLocked(app); 3562 if (pid > 0) { 3563 ProcessList.remove(pid); 3564 } 3565 } 3566 3567 if (mProfileProc == app) { 3568 clearProfilerLocked(); 3569 } 3570 3571 // Remove this application's activities from active lists. 3572 boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app); 3573 3574 app.activities.clear(); 3575 3576 if (app.instrumentationClass != null) { 3577 Slog.w(TAG, "Crash of app " + app.processName 3578 + " running instrumentation " + app.instrumentationClass); 3579 Bundle info = new Bundle(); 3580 info.putString("shortMsg", "Process crashed."); 3581 finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info); 3582 } 3583 3584 if (!restarting) { 3585 if (!mStackSupervisor.resumeTopActivitiesLocked()) { 3586 // If there was nothing to resume, and we are not already 3587 // restarting this process, but there is a visible activity that 3588 // is hosted by the process... then make sure all visible 3589 // activities are running, taking care of restarting this 3590 // process. 3591 if (hasVisibleActivities) { 3592 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 3593 } 3594 } 3595 } 3596 } 3597 3598 private final int getLRURecordIndexForAppLocked(IApplicationThread thread) { 3599 IBinder threadBinder = thread.asBinder(); 3600 // Find the application record. 3601 for (int i=mLruProcesses.size()-1; i>=0; i--) { 3602 ProcessRecord rec = mLruProcesses.get(i); 3603 if (rec.thread != null && rec.thread.asBinder() == threadBinder) { 3604 return i; 3605 } 3606 } 3607 return -1; 3608 } 3609 3610 final ProcessRecord getRecordForAppLocked( 3611 IApplicationThread thread) { 3612 if (thread == null) { 3613 return null; 3614 } 3615 3616 int appIndex = getLRURecordIndexForAppLocked(thread); 3617 return appIndex >= 0 ? mLruProcesses.get(appIndex) : null; 3618 } 3619 3620 final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) { 3621 // If there are no longer any background processes running, 3622 // and the app that died was not running instrumentation, 3623 // then tell everyone we are now low on memory. 3624 boolean haveBg = false; 3625 for (int i=mLruProcesses.size()-1; i>=0; i--) { 3626 ProcessRecord rec = mLruProcesses.get(i); 3627 if (rec.thread != null 3628 && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 3629 haveBg = true; 3630 break; 3631 } 3632 } 3633 3634 if (!haveBg) { 3635 boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 3636 if (doReport) { 3637 long now = SystemClock.uptimeMillis(); 3638 if (now < (mLastMemUsageReportTime+5*60*1000)) { 3639 doReport = false; 3640 } else { 3641 mLastMemUsageReportTime = now; 3642 } 3643 } 3644 final ArrayList<ProcessMemInfo> memInfos 3645 = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null; 3646 EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size()); 3647 long now = SystemClock.uptimeMillis(); 3648 for (int i=mLruProcesses.size()-1; i>=0; i--) { 3649 ProcessRecord rec = mLruProcesses.get(i); 3650 if (rec == dyingProc || rec.thread == null) { 3651 continue; 3652 } 3653 if (doReport) { 3654 memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj, 3655 rec.setProcState, rec.adjType, rec.makeAdjReason())); 3656 } 3657 if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) { 3658 // The low memory report is overriding any current 3659 // state for a GC request. Make sure to do 3660 // heavy/important/visible/foreground processes first. 3661 if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 3662 rec.lastRequestedGc = 0; 3663 } else { 3664 rec.lastRequestedGc = rec.lastLowMemory; 3665 } 3666 rec.reportLowMemory = true; 3667 rec.lastLowMemory = now; 3668 mProcessesToGc.remove(rec); 3669 addProcessToGcListLocked(rec); 3670 } 3671 } 3672 if (doReport) { 3673 Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos); 3674 mHandler.sendMessage(msg); 3675 } 3676 scheduleAppGcsLocked(); 3677 } 3678 } 3679 3680 final void appDiedLocked(ProcessRecord app, int pid, 3681 IApplicationThread thread) { 3682 3683 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 3684 synchronized (stats) { 3685 stats.noteProcessDiedLocked(app.info.uid, pid); 3686 } 3687 3688 // Clean up already done if the process has been re-started. 3689 if (app.pid == pid && app.thread != null && 3690 app.thread.asBinder() == thread.asBinder()) { 3691 boolean doLowMem = app.instrumentationClass == null; 3692 boolean doOomAdj = doLowMem; 3693 if (!app.killedByAm) { 3694 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 3695 + ") has died."); 3696 mAllowLowerMemLevel = true; 3697 } else { 3698 // Note that we always want to do oom adj to update our state with the 3699 // new number of procs. 3700 mAllowLowerMemLevel = false; 3701 doLowMem = false; 3702 } 3703 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName); 3704 if (DEBUG_CLEANUP) Slog.v( 3705 TAG, "Dying app: " + app + ", pid: " + pid 3706 + ", thread: " + thread.asBinder()); 3707 handleAppDiedLocked(app, false, true); 3708 3709 if (doOomAdj) { 3710 updateOomAdjLocked(); 3711 } 3712 if (doLowMem) { 3713 doLowMemReportIfNeededLocked(app); 3714 } 3715 } else if (app.pid != pid) { 3716 // A new process has already been started. 3717 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 3718 + ") has died and restarted (pid " + app.pid + ")."); 3719 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName); 3720 } else if (DEBUG_PROCESSES) { 3721 Slog.d(TAG, "Received spurious death notification for thread " 3722 + thread.asBinder()); 3723 } 3724 } 3725 3726 /** 3727 * If a stack trace dump file is configured, dump process stack traces. 3728 * @param clearTraces causes the dump file to be erased prior to the new 3729 * traces being written, if true; when false, the new traces will be 3730 * appended to any existing file content. 3731 * @param firstPids of dalvik VM processes to dump stack traces for first 3732 * @param lastPids of dalvik VM processes to dump stack traces for last 3733 * @param nativeProcs optional list of native process names to dump stack crawls 3734 * @return file containing stack traces, or null if no dump file is configured 3735 */ 3736 public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids, 3737 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) { 3738 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 3739 if (tracesPath == null || tracesPath.length() == 0) { 3740 return null; 3741 } 3742 3743 File tracesFile = new File(tracesPath); 3744 try { 3745 File tracesDir = tracesFile.getParentFile(); 3746 if (!tracesDir.exists()) { 3747 tracesFile.mkdirs(); 3748 if (!SELinux.restorecon(tracesDir)) { 3749 return null; 3750 } 3751 } 3752 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 3753 3754 if (clearTraces && tracesFile.exists()) tracesFile.delete(); 3755 tracesFile.createNewFile(); 3756 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 3757 } catch (IOException e) { 3758 Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e); 3759 return null; 3760 } 3761 3762 dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs); 3763 return tracesFile; 3764 } 3765 3766 private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids, 3767 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) { 3768 // Use a FileObserver to detect when traces finish writing. 3769 // The order of traces is considered important to maintain for legibility. 3770 FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) { 3771 @Override 3772 public synchronized void onEvent(int event, String path) { notify(); } 3773 }; 3774 3775 try { 3776 observer.startWatching(); 3777 3778 // First collect all of the stacks of the most important pids. 3779 if (firstPids != null) { 3780 try { 3781 int num = firstPids.size(); 3782 for (int i = 0; i < num; i++) { 3783 synchronized (observer) { 3784 Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT); 3785 observer.wait(200); // Wait for write-close, give up after 200msec 3786 } 3787 } 3788 } catch (InterruptedException e) { 3789 Log.wtf(TAG, e); 3790 } 3791 } 3792 3793 // Next collect the stacks of the native pids 3794 if (nativeProcs != null) { 3795 int[] pids = Process.getPidsForCommands(nativeProcs); 3796 if (pids != null) { 3797 for (int pid : pids) { 3798 Debug.dumpNativeBacktraceToFile(pid, tracesPath); 3799 } 3800 } 3801 } 3802 3803 // Lastly, measure CPU usage. 3804 if (processCpuTracker != null) { 3805 processCpuTracker.init(); 3806 System.gc(); 3807 processCpuTracker.update(); 3808 try { 3809 synchronized (processCpuTracker) { 3810 processCpuTracker.wait(500); // measure over 1/2 second. 3811 } 3812 } catch (InterruptedException e) { 3813 } 3814 processCpuTracker.update(); 3815 3816 // We'll take the stack crawls of just the top apps using CPU. 3817 final int N = processCpuTracker.countWorkingStats(); 3818 int numProcs = 0; 3819 for (int i=0; i<N && numProcs<5; i++) { 3820 ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i); 3821 if (lastPids.indexOfKey(stats.pid) >= 0) { 3822 numProcs++; 3823 try { 3824 synchronized (observer) { 3825 Process.sendSignal(stats.pid, Process.SIGNAL_QUIT); 3826 observer.wait(200); // Wait for write-close, give up after 200msec 3827 } 3828 } catch (InterruptedException e) { 3829 Log.wtf(TAG, e); 3830 } 3831 3832 } 3833 } 3834 } 3835 } finally { 3836 observer.stopWatching(); 3837 } 3838 } 3839 3840 final void logAppTooSlow(ProcessRecord app, long startTime, String msg) { 3841 if (true || IS_USER_BUILD) { 3842 return; 3843 } 3844 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 3845 if (tracesPath == null || tracesPath.length() == 0) { 3846 return; 3847 } 3848 3849 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads(); 3850 StrictMode.allowThreadDiskWrites(); 3851 try { 3852 final File tracesFile = new File(tracesPath); 3853 final File tracesDir = tracesFile.getParentFile(); 3854 final File tracesTmp = new File(tracesDir, "__tmp__"); 3855 try { 3856 if (!tracesDir.exists()) { 3857 tracesFile.mkdirs(); 3858 if (!SELinux.restorecon(tracesDir.getPath())) { 3859 return; 3860 } 3861 } 3862 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 3863 3864 if (tracesFile.exists()) { 3865 tracesTmp.delete(); 3866 tracesFile.renameTo(tracesTmp); 3867 } 3868 StringBuilder sb = new StringBuilder(); 3869 Time tobj = new Time(); 3870 tobj.set(System.currentTimeMillis()); 3871 sb.append(tobj.format("%Y-%m-%d %H:%M:%S")); 3872 sb.append(": "); 3873 TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb); 3874 sb.append(" since "); 3875 sb.append(msg); 3876 FileOutputStream fos = new FileOutputStream(tracesFile); 3877 fos.write(sb.toString().getBytes()); 3878 if (app == null) { 3879 fos.write("\n*** No application process!".getBytes()); 3880 } 3881 fos.close(); 3882 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 3883 } catch (IOException e) { 3884 Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e); 3885 return; 3886 } 3887 3888 if (app != null) { 3889 ArrayList<Integer> firstPids = new ArrayList<Integer>(); 3890 firstPids.add(app.pid); 3891 dumpStackTraces(tracesPath, firstPids, null, null, null); 3892 } 3893 3894 File lastTracesFile = null; 3895 File curTracesFile = null; 3896 for (int i=9; i>=0; i--) { 3897 String name = String.format(Locale.US, "slow%02d.txt", i); 3898 curTracesFile = new File(tracesDir, name); 3899 if (curTracesFile.exists()) { 3900 if (lastTracesFile != null) { 3901 curTracesFile.renameTo(lastTracesFile); 3902 } else { 3903 curTracesFile.delete(); 3904 } 3905 } 3906 lastTracesFile = curTracesFile; 3907 } 3908 tracesFile.renameTo(curTracesFile); 3909 if (tracesTmp.exists()) { 3910 tracesTmp.renameTo(tracesFile); 3911 } 3912 } finally { 3913 StrictMode.setThreadPolicy(oldPolicy); 3914 } 3915 } 3916 3917 final void appNotResponding(ProcessRecord app, ActivityRecord activity, 3918 ActivityRecord parent, boolean aboveSystem, final String annotation) { 3919 ArrayList<Integer> firstPids = new ArrayList<Integer>(5); 3920 SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20); 3921 3922 if (mController != null) { 3923 try { 3924 // 0 == continue, -1 = kill process immediately 3925 int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation); 3926 if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid); 3927 } catch (RemoteException e) { 3928 mController = null; 3929 Watchdog.getInstance().setActivityController(null); 3930 } 3931 } 3932 3933 long anrTime = SystemClock.uptimeMillis(); 3934 if (MONITOR_CPU_USAGE) { 3935 updateCpuStatsNow(); 3936 } 3937 3938 synchronized (this) { 3939 // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down. 3940 if (mShuttingDown) { 3941 Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation); 3942 return; 3943 } else if (app.notResponding) { 3944 Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation); 3945 return; 3946 } else if (app.crashing) { 3947 Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation); 3948 return; 3949 } 3950 3951 // In case we come through here for the same app before completing 3952 // this one, mark as anring now so we will bail out. 3953 app.notResponding = true; 3954 3955 // Log the ANR to the event log. 3956 EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid, 3957 app.processName, app.info.flags, annotation); 3958 3959 // Dump thread traces as quickly as we can, starting with "interesting" processes. 3960 firstPids.add(app.pid); 3961 3962 int parentPid = app.pid; 3963 if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid; 3964 if (parentPid != app.pid) firstPids.add(parentPid); 3965 3966 if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID); 3967 3968 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 3969 ProcessRecord r = mLruProcesses.get(i); 3970 if (r != null && r.thread != null) { 3971 int pid = r.pid; 3972 if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) { 3973 if (r.persistent) { 3974 firstPids.add(pid); 3975 } else { 3976 lastPids.put(pid, Boolean.TRUE); 3977 } 3978 } 3979 } 3980 } 3981 } 3982 3983 // Log the ANR to the main log. 3984 StringBuilder info = new StringBuilder(); 3985 info.setLength(0); 3986 info.append("ANR in ").append(app.processName); 3987 if (activity != null && activity.shortComponentName != null) { 3988 info.append(" (").append(activity.shortComponentName).append(")"); 3989 } 3990 info.append("\n"); 3991 info.append("PID: ").append(app.pid).append("\n"); 3992 if (annotation != null) { 3993 info.append("Reason: ").append(annotation).append("\n"); 3994 } 3995 if (parent != null && parent != activity) { 3996 info.append("Parent: ").append(parent.shortComponentName).append("\n"); 3997 } 3998 3999 final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true); 4000 4001 File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids, 4002 NATIVE_STACKS_OF_INTEREST); 4003 4004 String cpuInfo = null; 4005 if (MONITOR_CPU_USAGE) { 4006 updateCpuStatsNow(); 4007 synchronized (mProcessCpuThread) { 4008 cpuInfo = mProcessCpuTracker.printCurrentState(anrTime); 4009 } 4010 info.append(processCpuTracker.printCurrentLoad()); 4011 info.append(cpuInfo); 4012 } 4013 4014 info.append(processCpuTracker.printCurrentState(anrTime)); 4015 4016 Slog.e(TAG, info.toString()); 4017 if (tracesFile == null) { 4018 // There is no trace file, so dump (only) the alleged culprit's threads to the log 4019 Process.sendSignal(app.pid, Process.SIGNAL_QUIT); 4020 } 4021 4022 addErrorToDropBox("anr", app, app.processName, activity, parent, annotation, 4023 cpuInfo, tracesFile, null); 4024 4025 if (mController != null) { 4026 try { 4027 // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately 4028 int res = mController.appNotResponding(app.processName, app.pid, info.toString()); 4029 if (res != 0) { 4030 if (res < 0 && app.pid != MY_PID) { 4031 Process.killProcess(app.pid); 4032 } else { 4033 synchronized (this) { 4034 mServices.scheduleServiceTimeoutLocked(app); 4035 } 4036 } 4037 return; 4038 } 4039 } catch (RemoteException e) { 4040 mController = null; 4041 Watchdog.getInstance().setActivityController(null); 4042 } 4043 } 4044 4045 // Unless configured otherwise, swallow ANRs in background processes & kill the process. 4046 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), 4047 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; 4048 4049 synchronized (this) { 4050 if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) { 4051 killUnneededProcessLocked(app, "background ANR"); 4052 return; 4053 } 4054 4055 // Set the app's notResponding state, and look up the errorReportReceiver 4056 makeAppNotRespondingLocked(app, 4057 activity != null ? activity.shortComponentName : null, 4058 annotation != null ? "ANR " + annotation : "ANR", 4059 info.toString()); 4060 4061 // Bring up the infamous App Not Responding dialog 4062 Message msg = Message.obtain(); 4063 HashMap<String, Object> map = new HashMap<String, Object>(); 4064 msg.what = SHOW_NOT_RESPONDING_MSG; 4065 msg.obj = map; 4066 msg.arg1 = aboveSystem ? 1 : 0; 4067 map.put("app", app); 4068 if (activity != null) { 4069 map.put("activity", activity); 4070 } 4071 4072 mHandler.sendMessage(msg); 4073 } 4074 } 4075 4076 final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) { 4077 if (!mLaunchWarningShown) { 4078 mLaunchWarningShown = true; 4079 mHandler.post(new Runnable() { 4080 @Override 4081 public void run() { 4082 synchronized (ActivityManagerService.this) { 4083 final Dialog d = new LaunchWarningWindow(mContext, cur, next); 4084 d.show(); 4085 mHandler.postDelayed(new Runnable() { 4086 @Override 4087 public void run() { 4088 synchronized (ActivityManagerService.this) { 4089 d.dismiss(); 4090 mLaunchWarningShown = false; 4091 } 4092 } 4093 }, 4000); 4094 } 4095 } 4096 }); 4097 } 4098 } 4099 4100 @Override 4101 public boolean clearApplicationUserData(final String packageName, 4102 final IPackageDataObserver observer, int userId) { 4103 enforceNotIsolatedCaller("clearApplicationUserData"); 4104 int uid = Binder.getCallingUid(); 4105 int pid = Binder.getCallingPid(); 4106 userId = handleIncomingUser(pid, uid, 4107 userId, false, true, "clearApplicationUserData", null); 4108 long callingId = Binder.clearCallingIdentity(); 4109 try { 4110 IPackageManager pm = AppGlobals.getPackageManager(); 4111 int pkgUid = -1; 4112 synchronized(this) { 4113 try { 4114 pkgUid = pm.getPackageUid(packageName, userId); 4115 } catch (RemoteException e) { 4116 } 4117 if (pkgUid == -1) { 4118 Slog.w(TAG, "Invalid packageName: " + packageName); 4119 if (observer != null) { 4120 try { 4121 observer.onRemoveCompleted(packageName, false); 4122 } catch (RemoteException e) { 4123 Slog.i(TAG, "Observer no longer exists."); 4124 } 4125 } 4126 return false; 4127 } 4128 if (uid == pkgUid || checkComponentPermission( 4129 android.Manifest.permission.CLEAR_APP_USER_DATA, 4130 pid, uid, -1, true) 4131 == PackageManager.PERMISSION_GRANTED) { 4132 forceStopPackageLocked(packageName, pkgUid, "clear data"); 4133 } else { 4134 throw new SecurityException("PID " + pid + " does not have permission " 4135 + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data" 4136 + " of package " + packageName); 4137 } 4138 } 4139 4140 try { 4141 // Clear application user data 4142 pm.clearApplicationUserData(packageName, observer, userId); 4143 4144 // Remove all permissions granted from/to this package 4145 removeUriPermissionsForPackageLocked(packageName, userId, true); 4146 4147 Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED, 4148 Uri.fromParts("package", packageName, null)); 4149 intent.putExtra(Intent.EXTRA_UID, pkgUid); 4150 broadcastIntentInPackage("android", Process.SYSTEM_UID, intent, 4151 null, null, 0, null, null, null, false, false, userId); 4152 } catch (RemoteException e) { 4153 } 4154 } finally { 4155 Binder.restoreCallingIdentity(callingId); 4156 } 4157 return true; 4158 } 4159 4160 @Override 4161 public void killBackgroundProcesses(final String packageName, int userId) { 4162 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 4163 != PackageManager.PERMISSION_GRANTED && 4164 checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES) 4165 != PackageManager.PERMISSION_GRANTED) { 4166 String msg = "Permission Denial: killBackgroundProcesses() from pid=" 4167 + Binder.getCallingPid() 4168 + ", uid=" + Binder.getCallingUid() 4169 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 4170 Slog.w(TAG, msg); 4171 throw new SecurityException(msg); 4172 } 4173 4174 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 4175 userId, true, true, "killBackgroundProcesses", null); 4176 long callingId = Binder.clearCallingIdentity(); 4177 try { 4178 IPackageManager pm = AppGlobals.getPackageManager(); 4179 synchronized(this) { 4180 int appId = -1; 4181 try { 4182 appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0)); 4183 } catch (RemoteException e) { 4184 } 4185 if (appId == -1) { 4186 Slog.w(TAG, "Invalid packageName: " + packageName); 4187 return; 4188 } 4189 killPackageProcessesLocked(packageName, appId, userId, 4190 ProcessList.SERVICE_ADJ, false, true, true, false, "kill background"); 4191 } 4192 } finally { 4193 Binder.restoreCallingIdentity(callingId); 4194 } 4195 } 4196 4197 @Override 4198 public void killAllBackgroundProcesses() { 4199 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 4200 != PackageManager.PERMISSION_GRANTED) { 4201 String msg = "Permission Denial: killAllBackgroundProcesses() from pid=" 4202 + Binder.getCallingPid() 4203 + ", uid=" + Binder.getCallingUid() 4204 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 4205 Slog.w(TAG, msg); 4206 throw new SecurityException(msg); 4207 } 4208 4209 long callingId = Binder.clearCallingIdentity(); 4210 try { 4211 synchronized(this) { 4212 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 4213 final int NP = mProcessNames.getMap().size(); 4214 for (int ip=0; ip<NP; ip++) { 4215 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 4216 final int NA = apps.size(); 4217 for (int ia=0; ia<NA; ia++) { 4218 ProcessRecord app = apps.valueAt(ia); 4219 if (app.persistent) { 4220 // we don't kill persistent processes 4221 continue; 4222 } 4223 if (app.removed) { 4224 procs.add(app); 4225 } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 4226 app.removed = true; 4227 procs.add(app); 4228 } 4229 } 4230 } 4231 4232 int N = procs.size(); 4233 for (int i=0; i<N; i++) { 4234 removeProcessLocked(procs.get(i), false, true, "kill all background"); 4235 } 4236 mAllowLowerMemLevel = true; 4237 updateOomAdjLocked(); 4238 doLowMemReportIfNeededLocked(null); 4239 } 4240 } finally { 4241 Binder.restoreCallingIdentity(callingId); 4242 } 4243 } 4244 4245 @Override 4246 public void forceStopPackage(final String packageName, int userId) { 4247 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 4248 != PackageManager.PERMISSION_GRANTED) { 4249 String msg = "Permission Denial: forceStopPackage() from pid=" 4250 + Binder.getCallingPid() 4251 + ", uid=" + Binder.getCallingUid() 4252 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 4253 Slog.w(TAG, msg); 4254 throw new SecurityException(msg); 4255 } 4256 final int callingPid = Binder.getCallingPid(); 4257 userId = handleIncomingUser(callingPid, Binder.getCallingUid(), 4258 userId, true, true, "forceStopPackage", null); 4259 long callingId = Binder.clearCallingIdentity(); 4260 try { 4261 IPackageManager pm = AppGlobals.getPackageManager(); 4262 synchronized(this) { 4263 int[] users = userId == UserHandle.USER_ALL 4264 ? getUsersLocked() : new int[] { userId }; 4265 for (int user : users) { 4266 int pkgUid = -1; 4267 try { 4268 pkgUid = pm.getPackageUid(packageName, user); 4269 } catch (RemoteException e) { 4270 } 4271 if (pkgUid == -1) { 4272 Slog.w(TAG, "Invalid packageName: " + packageName); 4273 continue; 4274 } 4275 try { 4276 pm.setPackageStoppedState(packageName, true, user); 4277 } catch (RemoteException e) { 4278 } catch (IllegalArgumentException e) { 4279 Slog.w(TAG, "Failed trying to unstop package " 4280 + packageName + ": " + e); 4281 } 4282 if (isUserRunningLocked(user, false)) { 4283 forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid); 4284 } 4285 } 4286 } 4287 } finally { 4288 Binder.restoreCallingIdentity(callingId); 4289 } 4290 } 4291 4292 /* 4293 * The pkg name and app id have to be specified. 4294 */ 4295 @Override 4296 public void killApplicationWithAppId(String pkg, int appid, String reason) { 4297 if (pkg == null) { 4298 return; 4299 } 4300 // Make sure the uid is valid. 4301 if (appid < 0) { 4302 Slog.w(TAG, "Invalid appid specified for pkg : " + pkg); 4303 return; 4304 } 4305 int callerUid = Binder.getCallingUid(); 4306 // Only the system server can kill an application 4307 if (callerUid == Process.SYSTEM_UID) { 4308 // Post an aysnc message to kill the application 4309 Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG); 4310 msg.arg1 = appid; 4311 msg.arg2 = 0; 4312 Bundle bundle = new Bundle(); 4313 bundle.putString("pkg", pkg); 4314 bundle.putString("reason", reason); 4315 msg.obj = bundle; 4316 mHandler.sendMessage(msg); 4317 } else { 4318 throw new SecurityException(callerUid + " cannot kill pkg: " + 4319 pkg); 4320 } 4321 } 4322 4323 @Override 4324 public void closeSystemDialogs(String reason) { 4325 enforceNotIsolatedCaller("closeSystemDialogs"); 4326 4327 final int pid = Binder.getCallingPid(); 4328 final int uid = Binder.getCallingUid(); 4329 final long origId = Binder.clearCallingIdentity(); 4330 try { 4331 synchronized (this) { 4332 // Only allow this from foreground processes, so that background 4333 // applications can't abuse it to prevent system UI from being shown. 4334 if (uid >= Process.FIRST_APPLICATION_UID) { 4335 ProcessRecord proc; 4336 synchronized (mPidsSelfLocked) { 4337 proc = mPidsSelfLocked.get(pid); 4338 } 4339 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 4340 Slog.w(TAG, "Ignoring closeSystemDialogs " + reason 4341 + " from background process " + proc); 4342 return; 4343 } 4344 } 4345 closeSystemDialogsLocked(reason); 4346 } 4347 } finally { 4348 Binder.restoreCallingIdentity(origId); 4349 } 4350 } 4351 4352 void closeSystemDialogsLocked(String reason) { 4353 Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS); 4354 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 4355 | Intent.FLAG_RECEIVER_FOREGROUND); 4356 if (reason != null) { 4357 intent.putExtra("reason", reason); 4358 } 4359 mWindowManager.closeSystemDialogs(reason); 4360 4361 mStackSupervisor.closeSystemDialogsLocked(); 4362 4363 broadcastIntentLocked(null, null, intent, null, 4364 null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1, 4365 Process.SYSTEM_UID, UserHandle.USER_ALL); 4366 } 4367 4368 @Override 4369 public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) { 4370 enforceNotIsolatedCaller("getProcessMemoryInfo"); 4371 Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length]; 4372 for (int i=pids.length-1; i>=0; i--) { 4373 ProcessRecord proc; 4374 int oomAdj; 4375 synchronized (this) { 4376 synchronized (mPidsSelfLocked) { 4377 proc = mPidsSelfLocked.get(pids[i]); 4378 oomAdj = proc != null ? proc.setAdj : 0; 4379 } 4380 } 4381 infos[i] = new Debug.MemoryInfo(); 4382 Debug.getMemoryInfo(pids[i], infos[i]); 4383 if (proc != null) { 4384 synchronized (this) { 4385 if (proc.thread != null && proc.setAdj == oomAdj) { 4386 // Record this for posterity if the process has been stable. 4387 proc.baseProcessTracker.addPss(infos[i].getTotalPss(), 4388 infos[i].getTotalUss(), false, proc.pkgList); 4389 } 4390 } 4391 } 4392 } 4393 return infos; 4394 } 4395 4396 @Override 4397 public long[] getProcessPss(int[] pids) { 4398 enforceNotIsolatedCaller("getProcessPss"); 4399 long[] pss = new long[pids.length]; 4400 for (int i=pids.length-1; i>=0; i--) { 4401 ProcessRecord proc; 4402 int oomAdj; 4403 synchronized (this) { 4404 synchronized (mPidsSelfLocked) { 4405 proc = mPidsSelfLocked.get(pids[i]); 4406 oomAdj = proc != null ? proc.setAdj : 0; 4407 } 4408 } 4409 long[] tmpUss = new long[1]; 4410 pss[i] = Debug.getPss(pids[i], tmpUss); 4411 if (proc != null) { 4412 synchronized (this) { 4413 if (proc.thread != null && proc.setAdj == oomAdj) { 4414 // Record this for posterity if the process has been stable. 4415 proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList); 4416 } 4417 } 4418 } 4419 } 4420 return pss; 4421 } 4422 4423 @Override 4424 public void killApplicationProcess(String processName, int uid) { 4425 if (processName == null) { 4426 return; 4427 } 4428 4429 int callerUid = Binder.getCallingUid(); 4430 // Only the system server can kill an application 4431 if (callerUid == Process.SYSTEM_UID) { 4432 synchronized (this) { 4433 ProcessRecord app = getProcessRecordLocked(processName, uid, true); 4434 if (app != null && app.thread != null) { 4435 try { 4436 app.thread.scheduleSuicide(); 4437 } catch (RemoteException e) { 4438 // If the other end already died, then our work here is done. 4439 } 4440 } else { 4441 Slog.w(TAG, "Process/uid not found attempting kill of " 4442 + processName + " / " + uid); 4443 } 4444 } 4445 } else { 4446 throw new SecurityException(callerUid + " cannot kill app process: " + 4447 processName); 4448 } 4449 } 4450 4451 private void forceStopPackageLocked(final String packageName, int uid, String reason) { 4452 forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false, 4453 false, true, false, false, UserHandle.getUserId(uid), reason); 4454 Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED, 4455 Uri.fromParts("package", packageName, null)); 4456 if (!mProcessesReady) { 4457 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 4458 | Intent.FLAG_RECEIVER_FOREGROUND); 4459 } 4460 intent.putExtra(Intent.EXTRA_UID, uid); 4461 intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid)); 4462 broadcastIntentLocked(null, null, intent, 4463 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 4464 false, false, 4465 MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid)); 4466 } 4467 4468 private void forceStopUserLocked(int userId, String reason) { 4469 forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason); 4470 Intent intent = new Intent(Intent.ACTION_USER_STOPPED); 4471 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 4472 | Intent.FLAG_RECEIVER_FOREGROUND); 4473 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 4474 broadcastIntentLocked(null, null, intent, 4475 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 4476 false, false, 4477 MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 4478 } 4479 4480 private final boolean killPackageProcessesLocked(String packageName, int appId, 4481 int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart, 4482 boolean doit, boolean evenPersistent, String reason) { 4483 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 4484 4485 // Remove all processes this package may have touched: all with the 4486 // same UID (except for the system or root user), and all whose name 4487 // matches the package name. 4488 final String procNamePrefix = packageName != null ? (packageName + ":") : null; 4489 final int NP = mProcessNames.getMap().size(); 4490 for (int ip=0; ip<NP; ip++) { 4491 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 4492 final int NA = apps.size(); 4493 for (int ia=0; ia<NA; ia++) { 4494 ProcessRecord app = apps.valueAt(ia); 4495 if (app.persistent && !evenPersistent) { 4496 // we don't kill persistent processes 4497 continue; 4498 } 4499 if (app.removed) { 4500 if (doit) { 4501 procs.add(app); 4502 } 4503 continue; 4504 } 4505 4506 // Skip process if it doesn't meet our oom adj requirement. 4507 if (app.setAdj < minOomAdj) { 4508 continue; 4509 } 4510 4511 // If no package is specified, we call all processes under the 4512 // give user id. 4513 if (packageName == null) { 4514 if (app.userId != userId) { 4515 continue; 4516 } 4517 if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) { 4518 continue; 4519 } 4520 // Package has been specified, we want to hit all processes 4521 // that match it. We need to qualify this by the processes 4522 // that are running under the specified app and user ID. 4523 } else { 4524 if (UserHandle.getAppId(app.uid) != appId) { 4525 continue; 4526 } 4527 if (userId != UserHandle.USER_ALL && app.userId != userId) { 4528 continue; 4529 } 4530 if (!app.pkgList.containsKey(packageName)) { 4531 continue; 4532 } 4533 } 4534 4535 // Process has passed all conditions, kill it! 4536 if (!doit) { 4537 return true; 4538 } 4539 app.removed = true; 4540 procs.add(app); 4541 } 4542 } 4543 4544 int N = procs.size(); 4545 for (int i=0; i<N; i++) { 4546 removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason); 4547 } 4548 updateOomAdjLocked(); 4549 return N > 0; 4550 } 4551 4552 private final boolean forceStopPackageLocked(String name, int appId, 4553 boolean callerWillRestart, boolean purgeCache, boolean doit, 4554 boolean evenPersistent, boolean uninstalling, int userId, String reason) { 4555 int i; 4556 int N; 4557 4558 if (userId == UserHandle.USER_ALL && name == null) { 4559 Slog.w(TAG, "Can't force stop all processes of all users, that is insane!"); 4560 } 4561 4562 if (appId < 0 && name != null) { 4563 try { 4564 appId = UserHandle.getAppId( 4565 AppGlobals.getPackageManager().getPackageUid(name, 0)); 4566 } catch (RemoteException e) { 4567 } 4568 } 4569 4570 if (doit) { 4571 if (name != null) { 4572 Slog.i(TAG, "Force stopping " + name + " appid=" + appId 4573 + " user=" + userId + ": " + reason); 4574 } else { 4575 Slog.i(TAG, "Force stopping u" + userId + ": " + reason); 4576 } 4577 4578 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap(); 4579 for (int ip=pmap.size()-1; ip>=0; ip--) { 4580 SparseArray<Long> ba = pmap.valueAt(ip); 4581 for (i=ba.size()-1; i>=0; i--) { 4582 boolean remove = false; 4583 final int entUid = ba.keyAt(i); 4584 if (name != null) { 4585 if (userId == UserHandle.USER_ALL) { 4586 if (UserHandle.getAppId(entUid) == appId) { 4587 remove = true; 4588 } 4589 } else { 4590 if (entUid == UserHandle.getUid(userId, appId)) { 4591 remove = true; 4592 } 4593 } 4594 } else if (UserHandle.getUserId(entUid) == userId) { 4595 remove = true; 4596 } 4597 if (remove) { 4598 ba.removeAt(i); 4599 } 4600 } 4601 if (ba.size() == 0) { 4602 pmap.removeAt(ip); 4603 } 4604 } 4605 } 4606 4607 boolean didSomething = killPackageProcessesLocked(name, appId, userId, 4608 -100, callerWillRestart, true, doit, evenPersistent, 4609 name == null ? ("stop user " + userId) : ("stop " + name)); 4610 4611 if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) { 4612 if (!doit) { 4613 return true; 4614 } 4615 didSomething = true; 4616 } 4617 4618 if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) { 4619 if (!doit) { 4620 return true; 4621 } 4622 didSomething = true; 4623 } 4624 4625 if (name == null) { 4626 // Remove all sticky broadcasts from this user. 4627 mStickyBroadcasts.remove(userId); 4628 } 4629 4630 ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>(); 4631 if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent, 4632 userId, providers)) { 4633 if (!doit) { 4634 return true; 4635 } 4636 didSomething = true; 4637 } 4638 N = providers.size(); 4639 for (i=0; i<N; i++) { 4640 removeDyingProviderLocked(null, providers.get(i), true); 4641 } 4642 4643 // Remove transient permissions granted from/to this package/user 4644 removeUriPermissionsForPackageLocked(name, userId, false); 4645 4646 if (name == null || uninstalling) { 4647 // Remove pending intents. For now we only do this when force 4648 // stopping users, because we have some problems when doing this 4649 // for packages -- app widgets are not currently cleaned up for 4650 // such packages, so they can be left with bad pending intents. 4651 if (mIntentSenderRecords.size() > 0) { 4652 Iterator<WeakReference<PendingIntentRecord>> it 4653 = mIntentSenderRecords.values().iterator(); 4654 while (it.hasNext()) { 4655 WeakReference<PendingIntentRecord> wpir = it.next(); 4656 if (wpir == null) { 4657 it.remove(); 4658 continue; 4659 } 4660 PendingIntentRecord pir = wpir.get(); 4661 if (pir == null) { 4662 it.remove(); 4663 continue; 4664 } 4665 if (name == null) { 4666 // Stopping user, remove all objects for the user. 4667 if (pir.key.userId != userId) { 4668 // Not the same user, skip it. 4669 continue; 4670 } 4671 } else { 4672 if (UserHandle.getAppId(pir.uid) != appId) { 4673 // Different app id, skip it. 4674 continue; 4675 } 4676 if (userId != UserHandle.USER_ALL && pir.key.userId != userId) { 4677 // Different user, skip it. 4678 continue; 4679 } 4680 if (!pir.key.packageName.equals(name)) { 4681 // Different package, skip it. 4682 continue; 4683 } 4684 } 4685 if (!doit) { 4686 return true; 4687 } 4688 didSomething = true; 4689 it.remove(); 4690 pir.canceled = true; 4691 if (pir.key.activity != null) { 4692 pir.key.activity.pendingResults.remove(pir.ref); 4693 } 4694 } 4695 } 4696 } 4697 4698 if (doit) { 4699 if (purgeCache && name != null) { 4700 AttributeCache ac = AttributeCache.instance(); 4701 if (ac != null) { 4702 ac.removePackage(name); 4703 } 4704 } 4705 if (mBooted) { 4706 mStackSupervisor.resumeTopActivitiesLocked(); 4707 mStackSupervisor.scheduleIdleLocked(); 4708 } 4709 } 4710 4711 return didSomething; 4712 } 4713 4714 private final boolean removeProcessLocked(ProcessRecord app, 4715 boolean callerWillRestart, boolean allowRestart, String reason) { 4716 final String name = app.processName; 4717 final int uid = app.uid; 4718 if (DEBUG_PROCESSES) Slog.d( 4719 TAG, "Force removing proc " + app.toShortString() + " (" + name 4720 + "/" + uid + ")"); 4721 4722 mProcessNames.remove(name, uid); 4723 mIsolatedProcesses.remove(app.uid); 4724 if (mHeavyWeightProcess == app) { 4725 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 4726 mHeavyWeightProcess.userId, 0)); 4727 mHeavyWeightProcess = null; 4728 } 4729 boolean needRestart = false; 4730 if (app.pid > 0 && app.pid != MY_PID) { 4731 int pid = app.pid; 4732 synchronized (mPidsSelfLocked) { 4733 mPidsSelfLocked.remove(pid); 4734 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 4735 } 4736 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISHED, 4737 app.processName, app.info.uid); 4738 if (app.isolated) { 4739 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 4740 } 4741 killUnneededProcessLocked(app, reason); 4742 handleAppDiedLocked(app, true, allowRestart); 4743 removeLruProcessLocked(app); 4744 4745 if (app.persistent && !app.isolated) { 4746 if (!callerWillRestart) { 4747 addAppLocked(app.info, false); 4748 } else { 4749 needRestart = true; 4750 } 4751 } 4752 } else { 4753 mRemovedProcesses.add(app); 4754 } 4755 4756 return needRestart; 4757 } 4758 4759 private final void processStartTimedOutLocked(ProcessRecord app) { 4760 final int pid = app.pid; 4761 boolean gone = false; 4762 synchronized (mPidsSelfLocked) { 4763 ProcessRecord knownApp = mPidsSelfLocked.get(pid); 4764 if (knownApp != null && knownApp.thread == null) { 4765 mPidsSelfLocked.remove(pid); 4766 gone = true; 4767 } 4768 } 4769 4770 if (gone) { 4771 Slog.w(TAG, "Process " + app + " failed to attach"); 4772 EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId, 4773 pid, app.uid, app.processName); 4774 mProcessNames.remove(app.processName, app.uid); 4775 mIsolatedProcesses.remove(app.uid); 4776 if (mHeavyWeightProcess == app) { 4777 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 4778 mHeavyWeightProcess.userId, 0)); 4779 mHeavyWeightProcess = null; 4780 } 4781 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISHED, 4782 app.processName, app.info.uid); 4783 if (app.isolated) { 4784 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 4785 } 4786 // Take care of any launching providers waiting for this process. 4787 checkAppInLaunchingProvidersLocked(app, true); 4788 // Take care of any services that are waiting for the process. 4789 mServices.processStartTimedOutLocked(app); 4790 killUnneededProcessLocked(app, "start timeout"); 4791 if (mBackupTarget != null && mBackupTarget.app.pid == pid) { 4792 Slog.w(TAG, "Unattached app died before backup, skipping"); 4793 try { 4794 IBackupManager bm = IBackupManager.Stub.asInterface( 4795 ServiceManager.getService(Context.BACKUP_SERVICE)); 4796 bm.agentDisconnected(app.info.packageName); 4797 } catch (RemoteException e) { 4798 // Can't happen; the backup manager is local 4799 } 4800 } 4801 if (isPendingBroadcastProcessLocked(pid)) { 4802 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 4803 skipPendingBroadcastLocked(pid); 4804 } 4805 } else { 4806 Slog.w(TAG, "Spurious process start timeout - pid not known for " + app); 4807 } 4808 } 4809 4810 private final boolean attachApplicationLocked(IApplicationThread thread, 4811 int pid) { 4812 4813 // Find the application record that is being attached... either via 4814 // the pid if we are running in multiple processes, or just pull the 4815 // next app record if we are emulating process with anonymous threads. 4816 ProcessRecord app; 4817 if (pid != MY_PID && pid >= 0) { 4818 synchronized (mPidsSelfLocked) { 4819 app = mPidsSelfLocked.get(pid); 4820 } 4821 } else { 4822 app = null; 4823 } 4824 4825 if (app == null) { 4826 Slog.w(TAG, "No pending application record for pid " + pid 4827 + " (IApplicationThread " + thread + "); dropping process"); 4828 EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid); 4829 if (pid > 0 && pid != MY_PID) { 4830 Process.killProcessQuiet(pid); 4831 } else { 4832 try { 4833 thread.scheduleExit(); 4834 } catch (Exception e) { 4835 // Ignore exceptions. 4836 } 4837 } 4838 return false; 4839 } 4840 4841 // If this application record is still attached to a previous 4842 // process, clean it up now. 4843 if (app.thread != null) { 4844 handleAppDiedLocked(app, true, true); 4845 } 4846 4847 // Tell the process all about itself. 4848 4849 if (localLOGV) Slog.v( 4850 TAG, "Binding process pid " + pid + " to record " + app); 4851 4852 final String processName = app.processName; 4853 try { 4854 AppDeathRecipient adr = new AppDeathRecipient( 4855 app, pid, thread); 4856 thread.asBinder().linkToDeath(adr, 0); 4857 app.deathRecipient = adr; 4858 } catch (RemoteException e) { 4859 app.resetPackageList(mProcessStats); 4860 startProcessLocked(app, "link fail", processName); 4861 return false; 4862 } 4863 4864 EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName); 4865 4866 app.makeActive(thread, mProcessStats); 4867 app.curAdj = app.setAdj = -100; 4868 app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT; 4869 app.forcingToForeground = null; 4870 app.foregroundServices = false; 4871 app.hasShownUi = false; 4872 app.debugging = false; 4873 app.cached = false; 4874 4875 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 4876 4877 boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info); 4878 List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null; 4879 4880 if (!normalMode) { 4881 Slog.i(TAG, "Launching preboot mode app: " + app); 4882 } 4883 4884 if (localLOGV) Slog.v( 4885 TAG, "New app record " + app 4886 + " thread=" + thread.asBinder() + " pid=" + pid); 4887 try { 4888 int testMode = IApplicationThread.DEBUG_OFF; 4889 if (mDebugApp != null && mDebugApp.equals(processName)) { 4890 testMode = mWaitForDebugger 4891 ? IApplicationThread.DEBUG_WAIT 4892 : IApplicationThread.DEBUG_ON; 4893 app.debugging = true; 4894 if (mDebugTransient) { 4895 mDebugApp = mOrigDebugApp; 4896 mWaitForDebugger = mOrigWaitForDebugger; 4897 } 4898 } 4899 String profileFile = app.instrumentationProfileFile; 4900 ParcelFileDescriptor profileFd = null; 4901 boolean profileAutoStop = false; 4902 if (mProfileApp != null && mProfileApp.equals(processName)) { 4903 mProfileProc = app; 4904 profileFile = mProfileFile; 4905 profileFd = mProfileFd; 4906 profileAutoStop = mAutoStopProfiler; 4907 } 4908 boolean enableOpenGlTrace = false; 4909 if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) { 4910 enableOpenGlTrace = true; 4911 mOpenGlTraceApp = null; 4912 } 4913 4914 // If the app is being launched for restore or full backup, set it up specially 4915 boolean isRestrictedBackupMode = false; 4916 if (mBackupTarget != null && mBackupAppName.equals(processName)) { 4917 isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE) 4918 || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL) 4919 || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL); 4920 } 4921 4922 ensurePackageDexOpt(app.instrumentationInfo != null 4923 ? app.instrumentationInfo.packageName 4924 : app.info.packageName); 4925 if (app.instrumentationClass != null) { 4926 ensurePackageDexOpt(app.instrumentationClass.getPackageName()); 4927 } 4928 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc " 4929 + processName + " with config " + mConfiguration); 4930 ApplicationInfo appInfo = app.instrumentationInfo != null 4931 ? app.instrumentationInfo : app.info; 4932 app.compat = compatibilityInfoForPackageLocked(appInfo); 4933 if (profileFd != null) { 4934 profileFd = profileFd.dup(); 4935 } 4936 thread.bindApplication(processName, appInfo, providers, 4937 app.instrumentationClass, profileFile, profileFd, profileAutoStop, 4938 app.instrumentationArguments, app.instrumentationWatcher, 4939 app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace, 4940 isRestrictedBackupMode || !normalMode, app.persistent, 4941 new Configuration(mConfiguration), app.compat, getCommonServicesLocked(), 4942 mCoreSettingsObserver.getCoreSettingsLocked()); 4943 updateLruProcessLocked(app, false, null); 4944 app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis(); 4945 } catch (Exception e) { 4946 // todo: Yikes! What should we do? For now we will try to 4947 // start another process, but that could easily get us in 4948 // an infinite loop of restarting processes... 4949 Slog.w(TAG, "Exception thrown during bind!", e); 4950 4951 app.resetPackageList(mProcessStats); 4952 app.unlinkDeathRecipient(); 4953 startProcessLocked(app, "bind fail", processName); 4954 return false; 4955 } 4956 4957 // Remove this record from the list of starting applications. 4958 mPersistentStartingProcesses.remove(app); 4959 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 4960 "Attach application locked removing on hold: " + app); 4961 mProcessesOnHold.remove(app); 4962 4963 boolean badApp = false; 4964 boolean didSomething = false; 4965 4966 // See if the top visible activity is waiting to run in this process... 4967 if (normalMode) { 4968 try { 4969 if (mStackSupervisor.attachApplicationLocked(app)) { 4970 didSomething = true; 4971 } 4972 } catch (Exception e) { 4973 badApp = true; 4974 } 4975 } 4976 4977 // Find any services that should be running in this process... 4978 if (!badApp) { 4979 try { 4980 didSomething |= mServices.attachApplicationLocked(app, processName); 4981 } catch (Exception e) { 4982 badApp = true; 4983 } 4984 } 4985 4986 // Check if a next-broadcast receiver is in this process... 4987 if (!badApp && isPendingBroadcastProcessLocked(pid)) { 4988 try { 4989 didSomething |= sendPendingBroadcastsLocked(app); 4990 } catch (Exception e) { 4991 // If the app died trying to launch the receiver we declare it 'bad' 4992 badApp = true; 4993 } 4994 } 4995 4996 // Check whether the next backup agent is in this process... 4997 if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) { 4998 if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app); 4999 ensurePackageDexOpt(mBackupTarget.appInfo.packageName); 5000 try { 5001 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo, 5002 compatibilityInfoForPackageLocked(mBackupTarget.appInfo), 5003 mBackupTarget.backupMode); 5004 } catch (Exception e) { 5005 Slog.w(TAG, "Exception scheduling backup agent creation: "); 5006 e.printStackTrace(); 5007 } 5008 } 5009 5010 if (badApp) { 5011 // todo: Also need to kill application to deal with all 5012 // kinds of exceptions. 5013 handleAppDiedLocked(app, false, true); 5014 return false; 5015 } 5016 5017 if (!didSomething) { 5018 updateOomAdjLocked(); 5019 } 5020 5021 return true; 5022 } 5023 5024 @Override 5025 public final void attachApplication(IApplicationThread thread) { 5026 synchronized (this) { 5027 int callingPid = Binder.getCallingPid(); 5028 final long origId = Binder.clearCallingIdentity(); 5029 attachApplicationLocked(thread, callingPid); 5030 Binder.restoreCallingIdentity(origId); 5031 } 5032 } 5033 5034 @Override 5035 public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) { 5036 final long origId = Binder.clearCallingIdentity(); 5037 synchronized (this) { 5038 ActivityStack stack = ActivityRecord.getStackLocked(token); 5039 if (stack != null) { 5040 ActivityRecord r = 5041 mStackSupervisor.activityIdleInternalLocked(token, false, config); 5042 if (stopProfiling) { 5043 if ((mProfileProc == r.app) && (mProfileFd != null)) { 5044 try { 5045 mProfileFd.close(); 5046 } catch (IOException e) { 5047 } 5048 clearProfilerLocked(); 5049 } 5050 } 5051 } 5052 } 5053 Binder.restoreCallingIdentity(origId); 5054 } 5055 5056 void enableScreenAfterBoot() { 5057 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN, 5058 SystemClock.uptimeMillis()); 5059 mWindowManager.enableScreenAfterBoot(); 5060 5061 synchronized (this) { 5062 updateEventDispatchingLocked(); 5063 } 5064 } 5065 5066 @Override 5067 public void showBootMessage(final CharSequence msg, final boolean always) { 5068 enforceNotIsolatedCaller("showBootMessage"); 5069 mWindowManager.showBootMessage(msg, always); 5070 } 5071 5072 @Override 5073 public void dismissKeyguardOnNextActivity() { 5074 enforceNotIsolatedCaller("dismissKeyguardOnNextActivity"); 5075 final long token = Binder.clearCallingIdentity(); 5076 try { 5077 synchronized (this) { 5078 if (DEBUG_LOCKSCREEN) logLockScreen(""); 5079 if (mLockScreenShown) { 5080 mLockScreenShown = false; 5081 comeOutOfSleepIfNeededLocked(); 5082 } 5083 mStackSupervisor.setDismissKeyguard(true); 5084 } 5085 } finally { 5086 Binder.restoreCallingIdentity(token); 5087 } 5088 } 5089 5090 final void finishBooting() { 5091 IntentFilter pkgFilter = new IntentFilter(); 5092 pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART); 5093 pkgFilter.addDataScheme("package"); 5094 mContext.registerReceiver(new BroadcastReceiver() { 5095 @Override 5096 public void onReceive(Context context, Intent intent) { 5097 String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES); 5098 if (pkgs != null) { 5099 for (String pkg : pkgs) { 5100 synchronized (ActivityManagerService.this) { 5101 if (forceStopPackageLocked(pkg, -1, false, false, false, false, false, 0, 5102 "finished booting")) { 5103 setResultCode(Activity.RESULT_OK); 5104 return; 5105 } 5106 } 5107 } 5108 } 5109 } 5110 }, pkgFilter); 5111 5112 synchronized (this) { 5113 // Ensure that any processes we had put on hold are now started 5114 // up. 5115 final int NP = mProcessesOnHold.size(); 5116 if (NP > 0) { 5117 ArrayList<ProcessRecord> procs = 5118 new ArrayList<ProcessRecord>(mProcessesOnHold); 5119 for (int ip=0; ip<NP; ip++) { 5120 if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: " 5121 + procs.get(ip)); 5122 startProcessLocked(procs.get(ip), "on-hold", null); 5123 } 5124 } 5125 5126 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 5127 // Start looking for apps that are abusing wake locks. 5128 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 5129 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 5130 // Tell anyone interested that we are done booting! 5131 SystemProperties.set("sys.boot_completed", "1"); 5132 SystemProperties.set("dev.bootcomplete", "1"); 5133 for (int i=0; i<mStartedUsers.size(); i++) { 5134 UserStartedState uss = mStartedUsers.valueAt(i); 5135 if (uss.mState == UserStartedState.STATE_BOOTING) { 5136 uss.mState = UserStartedState.STATE_RUNNING; 5137 final int userId = mStartedUsers.keyAt(i); 5138 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 5139 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 5140 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT); 5141 broadcastIntentLocked(null, null, intent, null, 5142 new IIntentReceiver.Stub() { 5143 @Override 5144 public void performReceive(Intent intent, int resultCode, 5145 String data, Bundle extras, boolean ordered, 5146 boolean sticky, int sendingUser) { 5147 synchronized (ActivityManagerService.this) { 5148 requestPssAllProcsLocked(SystemClock.uptimeMillis(), 5149 true, false); 5150 } 5151 } 5152 }, 5153 0, null, null, 5154 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, 5155 AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID, 5156 userId); 5157 } 5158 } 5159 } 5160 } 5161 } 5162 5163 final void ensureBootCompleted() { 5164 boolean booting; 5165 boolean enableScreen; 5166 synchronized (this) { 5167 booting = mBooting; 5168 mBooting = false; 5169 enableScreen = !mBooted; 5170 mBooted = true; 5171 } 5172 5173 if (booting) { 5174 finishBooting(); 5175 } 5176 5177 if (enableScreen) { 5178 enableScreenAfterBoot(); 5179 } 5180 } 5181 5182 @Override 5183 public final void activityResumed(IBinder token) { 5184 final long origId = Binder.clearCallingIdentity(); 5185 synchronized(this) { 5186 ActivityStack stack = ActivityRecord.getStackLocked(token); 5187 if (stack != null) { 5188 ActivityRecord.activityResumedLocked(token); 5189 } 5190 } 5191 Binder.restoreCallingIdentity(origId); 5192 } 5193 5194 @Override 5195 public final void activityPaused(IBinder token) { 5196 final long origId = Binder.clearCallingIdentity(); 5197 synchronized(this) { 5198 ActivityStack stack = ActivityRecord.getStackLocked(token); 5199 if (stack != null) { 5200 stack.activityPausedLocked(token, false); 5201 } 5202 } 5203 Binder.restoreCallingIdentity(origId); 5204 } 5205 5206 @Override 5207 public final void activityStopped(IBinder token, Bundle icicle, Bitmap thumbnail, 5208 CharSequence description) { 5209 if (localLOGV) Slog.v( 5210 TAG, "Activity stopped: token=" + token); 5211 5212 // Refuse possible leaked file descriptors 5213 if (icicle != null && icicle.hasFileDescriptors()) { 5214 throw new IllegalArgumentException("File descriptors passed in Bundle"); 5215 } 5216 5217 ActivityRecord r = null; 5218 5219 final long origId = Binder.clearCallingIdentity(); 5220 5221 synchronized (this) { 5222 r = ActivityRecord.isInStackLocked(token); 5223 if (r != null) { 5224 r.task.stack.activityStoppedLocked(r, icicle, thumbnail, description); 5225 } 5226 } 5227 5228 if (r != null) { 5229 sendPendingThumbnail(r, null, null, null, false); 5230 } 5231 5232 trimApplications(); 5233 5234 Binder.restoreCallingIdentity(origId); 5235 } 5236 5237 @Override 5238 public final void activityDestroyed(IBinder token) { 5239 if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token); 5240 synchronized (this) { 5241 ActivityStack stack = ActivityRecord.getStackLocked(token); 5242 if (stack != null) { 5243 stack.activityDestroyedLocked(token); 5244 } 5245 } 5246 } 5247 5248 @Override 5249 public String getCallingPackage(IBinder token) { 5250 synchronized (this) { 5251 ActivityRecord r = getCallingRecordLocked(token); 5252 return r != null ? r.info.packageName : null; 5253 } 5254 } 5255 5256 @Override 5257 public ComponentName getCallingActivity(IBinder token) { 5258 synchronized (this) { 5259 ActivityRecord r = getCallingRecordLocked(token); 5260 return r != null ? r.intent.getComponent() : null; 5261 } 5262 } 5263 5264 private ActivityRecord getCallingRecordLocked(IBinder token) { 5265 ActivityRecord r = ActivityRecord.isInStackLocked(token); 5266 if (r == null) { 5267 return null; 5268 } 5269 return r.resultTo; 5270 } 5271 5272 @Override 5273 public ComponentName getActivityClassForToken(IBinder token) { 5274 synchronized(this) { 5275 ActivityRecord r = ActivityRecord.isInStackLocked(token); 5276 if (r == null) { 5277 return null; 5278 } 5279 return r.intent.getComponent(); 5280 } 5281 } 5282 5283 @Override 5284 public String getPackageForToken(IBinder token) { 5285 synchronized(this) { 5286 ActivityRecord r = ActivityRecord.isInStackLocked(token); 5287 if (r == null) { 5288 return null; 5289 } 5290 return r.packageName; 5291 } 5292 } 5293 5294 @Override 5295 public IIntentSender getIntentSender(int type, 5296 String packageName, IBinder token, String resultWho, 5297 int requestCode, Intent[] intents, String[] resolvedTypes, 5298 int flags, Bundle options, int userId) { 5299 enforceNotIsolatedCaller("getIntentSender"); 5300 // Refuse possible leaked file descriptors 5301 if (intents != null) { 5302 if (intents.length < 1) { 5303 throw new IllegalArgumentException("Intents array length must be >= 1"); 5304 } 5305 for (int i=0; i<intents.length; i++) { 5306 Intent intent = intents[i]; 5307 if (intent != null) { 5308 if (intent.hasFileDescriptors()) { 5309 throw new IllegalArgumentException("File descriptors passed in Intent"); 5310 } 5311 if (type == ActivityManager.INTENT_SENDER_BROADCAST && 5312 (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 5313 throw new IllegalArgumentException( 5314 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 5315 } 5316 intents[i] = new Intent(intent); 5317 } 5318 } 5319 if (resolvedTypes != null && resolvedTypes.length != intents.length) { 5320 throw new IllegalArgumentException( 5321 "Intent array length does not match resolvedTypes length"); 5322 } 5323 } 5324 if (options != null) { 5325 if (options.hasFileDescriptors()) { 5326 throw new IllegalArgumentException("File descriptors passed in options"); 5327 } 5328 } 5329 5330 synchronized(this) { 5331 int callingUid = Binder.getCallingUid(); 5332 int origUserId = userId; 5333 userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId, 5334 type == ActivityManager.INTENT_SENDER_BROADCAST, false, 5335 "getIntentSender", null); 5336 if (origUserId == UserHandle.USER_CURRENT) { 5337 // We don't want to evaluate this until the pending intent is 5338 // actually executed. However, we do want to always do the 5339 // security checking for it above. 5340 userId = UserHandle.USER_CURRENT; 5341 } 5342 try { 5343 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 5344 int uid = AppGlobals.getPackageManager() 5345 .getPackageUid(packageName, UserHandle.getUserId(callingUid)); 5346 if (!UserHandle.isSameApp(callingUid, uid)) { 5347 String msg = "Permission Denial: getIntentSender() from pid=" 5348 + Binder.getCallingPid() 5349 + ", uid=" + Binder.getCallingUid() 5350 + ", (need uid=" + uid + ")" 5351 + " is not allowed to send as package " + packageName; 5352 Slog.w(TAG, msg); 5353 throw new SecurityException(msg); 5354 } 5355 } 5356 5357 return getIntentSenderLocked(type, packageName, callingUid, userId, 5358 token, resultWho, requestCode, intents, resolvedTypes, flags, options); 5359 5360 } catch (RemoteException e) { 5361 throw new SecurityException(e); 5362 } 5363 } 5364 } 5365 5366 IIntentSender getIntentSenderLocked(int type, String packageName, 5367 int callingUid, int userId, IBinder token, String resultWho, 5368 int requestCode, Intent[] intents, String[] resolvedTypes, int flags, 5369 Bundle options) { 5370 if (DEBUG_MU) 5371 Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid); 5372 ActivityRecord activity = null; 5373 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 5374 activity = ActivityRecord.isInStackLocked(token); 5375 if (activity == null) { 5376 return null; 5377 } 5378 if (activity.finishing) { 5379 return null; 5380 } 5381 } 5382 5383 final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0; 5384 final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0; 5385 final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0; 5386 flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT 5387 |PendingIntent.FLAG_UPDATE_CURRENT); 5388 5389 PendingIntentRecord.Key key = new PendingIntentRecord.Key( 5390 type, packageName, activity, resultWho, 5391 requestCode, intents, resolvedTypes, flags, options, userId); 5392 WeakReference<PendingIntentRecord> ref; 5393 ref = mIntentSenderRecords.get(key); 5394 PendingIntentRecord rec = ref != null ? ref.get() : null; 5395 if (rec != null) { 5396 if (!cancelCurrent) { 5397 if (updateCurrent) { 5398 if (rec.key.requestIntent != null) { 5399 rec.key.requestIntent.replaceExtras(intents != null ? 5400 intents[intents.length - 1] : null); 5401 } 5402 if (intents != null) { 5403 intents[intents.length-1] = rec.key.requestIntent; 5404 rec.key.allIntents = intents; 5405 rec.key.allResolvedTypes = resolvedTypes; 5406 } else { 5407 rec.key.allIntents = null; 5408 rec.key.allResolvedTypes = null; 5409 } 5410 } 5411 return rec; 5412 } 5413 rec.canceled = true; 5414 mIntentSenderRecords.remove(key); 5415 } 5416 if (noCreate) { 5417 return rec; 5418 } 5419 rec = new PendingIntentRecord(this, key, callingUid); 5420 mIntentSenderRecords.put(key, rec.ref); 5421 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 5422 if (activity.pendingResults == null) { 5423 activity.pendingResults 5424 = new HashSet<WeakReference<PendingIntentRecord>>(); 5425 } 5426 activity.pendingResults.add(rec.ref); 5427 } 5428 return rec; 5429 } 5430 5431 @Override 5432 public void cancelIntentSender(IIntentSender sender) { 5433 if (!(sender instanceof PendingIntentRecord)) { 5434 return; 5435 } 5436 synchronized(this) { 5437 PendingIntentRecord rec = (PendingIntentRecord)sender; 5438 try { 5439 int uid = AppGlobals.getPackageManager() 5440 .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId()); 5441 if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) { 5442 String msg = "Permission Denial: cancelIntentSender() from pid=" 5443 + Binder.getCallingPid() 5444 + ", uid=" + Binder.getCallingUid() 5445 + " is not allowed to cancel packges " 5446 + rec.key.packageName; 5447 Slog.w(TAG, msg); 5448 throw new SecurityException(msg); 5449 } 5450 } catch (RemoteException e) { 5451 throw new SecurityException(e); 5452 } 5453 cancelIntentSenderLocked(rec, true); 5454 } 5455 } 5456 5457 void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) { 5458 rec.canceled = true; 5459 mIntentSenderRecords.remove(rec.key); 5460 if (cleanActivity && rec.key.activity != null) { 5461 rec.key.activity.pendingResults.remove(rec.ref); 5462 } 5463 } 5464 5465 @Override 5466 public String getPackageForIntentSender(IIntentSender pendingResult) { 5467 if (!(pendingResult instanceof PendingIntentRecord)) { 5468 return null; 5469 } 5470 try { 5471 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5472 return res.key.packageName; 5473 } catch (ClassCastException e) { 5474 } 5475 return null; 5476 } 5477 5478 @Override 5479 public int getUidForIntentSender(IIntentSender sender) { 5480 if (sender instanceof PendingIntentRecord) { 5481 try { 5482 PendingIntentRecord res = (PendingIntentRecord)sender; 5483 return res.uid; 5484 } catch (ClassCastException e) { 5485 } 5486 } 5487 return -1; 5488 } 5489 5490 @Override 5491 public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) { 5492 if (!(pendingResult instanceof PendingIntentRecord)) { 5493 return false; 5494 } 5495 try { 5496 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5497 if (res.key.allIntents == null) { 5498 return false; 5499 } 5500 for (int i=0; i<res.key.allIntents.length; i++) { 5501 Intent intent = res.key.allIntents[i]; 5502 if (intent.getPackage() != null && intent.getComponent() != null) { 5503 return false; 5504 } 5505 } 5506 return true; 5507 } catch (ClassCastException e) { 5508 } 5509 return false; 5510 } 5511 5512 @Override 5513 public boolean isIntentSenderAnActivity(IIntentSender pendingResult) { 5514 if (!(pendingResult instanceof PendingIntentRecord)) { 5515 return false; 5516 } 5517 try { 5518 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5519 if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) { 5520 return true; 5521 } 5522 return false; 5523 } catch (ClassCastException e) { 5524 } 5525 return false; 5526 } 5527 5528 @Override 5529 public Intent getIntentForIntentSender(IIntentSender pendingResult) { 5530 if (!(pendingResult instanceof PendingIntentRecord)) { 5531 return null; 5532 } 5533 try { 5534 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5535 return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null; 5536 } catch (ClassCastException e) { 5537 } 5538 return null; 5539 } 5540 5541 @Override 5542 public void setProcessLimit(int max) { 5543 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 5544 "setProcessLimit()"); 5545 synchronized (this) { 5546 mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max; 5547 mProcessLimitOverride = max; 5548 } 5549 trimApplications(); 5550 } 5551 5552 @Override 5553 public int getProcessLimit() { 5554 synchronized (this) { 5555 return mProcessLimitOverride; 5556 } 5557 } 5558 5559 void foregroundTokenDied(ForegroundToken token) { 5560 synchronized (ActivityManagerService.this) { 5561 synchronized (mPidsSelfLocked) { 5562 ForegroundToken cur 5563 = mForegroundProcesses.get(token.pid); 5564 if (cur != token) { 5565 return; 5566 } 5567 mForegroundProcesses.remove(token.pid); 5568 ProcessRecord pr = mPidsSelfLocked.get(token.pid); 5569 if (pr == null) { 5570 return; 5571 } 5572 pr.forcingToForeground = null; 5573 pr.foregroundServices = false; 5574 } 5575 updateOomAdjLocked(); 5576 } 5577 } 5578 5579 @Override 5580 public void setProcessForeground(IBinder token, int pid, boolean isForeground) { 5581 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 5582 "setProcessForeground()"); 5583 synchronized(this) { 5584 boolean changed = false; 5585 5586 synchronized (mPidsSelfLocked) { 5587 ProcessRecord pr = mPidsSelfLocked.get(pid); 5588 if (pr == null && isForeground) { 5589 Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid); 5590 return; 5591 } 5592 ForegroundToken oldToken = mForegroundProcesses.get(pid); 5593 if (oldToken != null) { 5594 oldToken.token.unlinkToDeath(oldToken, 0); 5595 mForegroundProcesses.remove(pid); 5596 if (pr != null) { 5597 pr.forcingToForeground = null; 5598 } 5599 changed = true; 5600 } 5601 if (isForeground && token != null) { 5602 ForegroundToken newToken = new ForegroundToken() { 5603 @Override 5604 public void binderDied() { 5605 foregroundTokenDied(this); 5606 } 5607 }; 5608 newToken.pid = pid; 5609 newToken.token = token; 5610 try { 5611 token.linkToDeath(newToken, 0); 5612 mForegroundProcesses.put(pid, newToken); 5613 pr.forcingToForeground = token; 5614 changed = true; 5615 } catch (RemoteException e) { 5616 // If the process died while doing this, we will later 5617 // do the cleanup with the process death link. 5618 } 5619 } 5620 } 5621 5622 if (changed) { 5623 updateOomAdjLocked(); 5624 } 5625 } 5626 } 5627 5628 // ========================================================= 5629 // PERMISSIONS 5630 // ========================================================= 5631 5632 static class PermissionController extends IPermissionController.Stub { 5633 ActivityManagerService mActivityManagerService; 5634 PermissionController(ActivityManagerService activityManagerService) { 5635 mActivityManagerService = activityManagerService; 5636 } 5637 5638 @Override 5639 public boolean checkPermission(String permission, int pid, int uid) { 5640 return mActivityManagerService.checkPermission(permission, pid, 5641 uid) == PackageManager.PERMISSION_GRANTED; 5642 } 5643 } 5644 5645 class IntentFirewallInterface implements IntentFirewall.AMSInterface { 5646 @Override 5647 public int checkComponentPermission(String permission, int pid, int uid, 5648 int owningUid, boolean exported) { 5649 return ActivityManagerService.this.checkComponentPermission(permission, pid, uid, 5650 owningUid, exported); 5651 } 5652 5653 @Override 5654 public Object getAMSLock() { 5655 return ActivityManagerService.this; 5656 } 5657 } 5658 5659 /** 5660 * This can be called with or without the global lock held. 5661 */ 5662 int checkComponentPermission(String permission, int pid, int uid, 5663 int owningUid, boolean exported) { 5664 // We might be performing an operation on behalf of an indirect binder 5665 // invocation, e.g. via {@link #openContentUri}. Check and adjust the 5666 // client identity accordingly before proceeding. 5667 Identity tlsIdentity = sCallerIdentity.get(); 5668 if (tlsIdentity != null) { 5669 Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {" 5670 + tlsIdentity.pid + "," + tlsIdentity.uid + "}"); 5671 uid = tlsIdentity.uid; 5672 pid = tlsIdentity.pid; 5673 } 5674 5675 if (pid == MY_PID) { 5676 return PackageManager.PERMISSION_GRANTED; 5677 } 5678 5679 return ActivityManager.checkComponentPermission(permission, uid, 5680 owningUid, exported); 5681 } 5682 5683 /** 5684 * As the only public entry point for permissions checking, this method 5685 * can enforce the semantic that requesting a check on a null global 5686 * permission is automatically denied. (Internally a null permission 5687 * string is used when calling {@link #checkComponentPermission} in cases 5688 * when only uid-based security is needed.) 5689 * 5690 * This can be called with or without the global lock held. 5691 */ 5692 @Override 5693 public int checkPermission(String permission, int pid, int uid) { 5694 if (permission == null) { 5695 return PackageManager.PERMISSION_DENIED; 5696 } 5697 return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true); 5698 } 5699 5700 /** 5701 * Binder IPC calls go through the public entry point. 5702 * This can be called with or without the global lock held. 5703 */ 5704 int checkCallingPermission(String permission) { 5705 return checkPermission(permission, 5706 Binder.getCallingPid(), 5707 UserHandle.getAppId(Binder.getCallingUid())); 5708 } 5709 5710 /** 5711 * This can be called with or without the global lock held. 5712 */ 5713 void enforceCallingPermission(String permission, String func) { 5714 if (checkCallingPermission(permission) 5715 == PackageManager.PERMISSION_GRANTED) { 5716 return; 5717 } 5718 5719 String msg = "Permission Denial: " + func + " from pid=" 5720 + Binder.getCallingPid() 5721 + ", uid=" + Binder.getCallingUid() 5722 + " requires " + permission; 5723 Slog.w(TAG, msg); 5724 throw new SecurityException(msg); 5725 } 5726 5727 /** 5728 * Determine if UID is holding permissions required to access {@link Uri} in 5729 * the given {@link ProviderInfo}. Final permission checking is always done 5730 * in {@link ContentProvider}. 5731 */ 5732 private final boolean checkHoldingPermissionsLocked( 5733 IPackageManager pm, ProviderInfo pi, Uri uri, int uid, int modeFlags) { 5734 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5735 "checkHoldingPermissionsLocked: uri=" + uri + " uid=" + uid); 5736 5737 if (pi.applicationInfo.uid == uid) { 5738 return true; 5739 } else if (!pi.exported) { 5740 return false; 5741 } 5742 5743 boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0; 5744 boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0; 5745 try { 5746 // check if target holds top-level <provider> permissions 5747 if (!readMet && pi.readPermission != null 5748 && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) { 5749 readMet = true; 5750 } 5751 if (!writeMet && pi.writePermission != null 5752 && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) { 5753 writeMet = true; 5754 } 5755 5756 // track if unprotected read/write is allowed; any denied 5757 // <path-permission> below removes this ability 5758 boolean allowDefaultRead = pi.readPermission == null; 5759 boolean allowDefaultWrite = pi.writePermission == null; 5760 5761 // check if target holds any <path-permission> that match uri 5762 final PathPermission[] pps = pi.pathPermissions; 5763 if (pps != null) { 5764 final String path = uri.getPath(); 5765 int i = pps.length; 5766 while (i > 0 && (!readMet || !writeMet)) { 5767 i--; 5768 PathPermission pp = pps[i]; 5769 if (pp.match(path)) { 5770 if (!readMet) { 5771 final String pprperm = pp.getReadPermission(); 5772 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for " 5773 + pprperm + " for " + pp.getPath() 5774 + ": match=" + pp.match(path) 5775 + " check=" + pm.checkUidPermission(pprperm, uid)); 5776 if (pprperm != null) { 5777 if (pm.checkUidPermission(pprperm, uid) == PERMISSION_GRANTED) { 5778 readMet = true; 5779 } else { 5780 allowDefaultRead = false; 5781 } 5782 } 5783 } 5784 if (!writeMet) { 5785 final String ppwperm = pp.getWritePermission(); 5786 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm " 5787 + ppwperm + " for " + pp.getPath() 5788 + ": match=" + pp.match(path) 5789 + " check=" + pm.checkUidPermission(ppwperm, uid)); 5790 if (ppwperm != null) { 5791 if (pm.checkUidPermission(ppwperm, uid) == PERMISSION_GRANTED) { 5792 writeMet = true; 5793 } else { 5794 allowDefaultWrite = false; 5795 } 5796 } 5797 } 5798 } 5799 } 5800 } 5801 5802 // grant unprotected <provider> read/write, if not blocked by 5803 // <path-permission> above 5804 if (allowDefaultRead) readMet = true; 5805 if (allowDefaultWrite) writeMet = true; 5806 5807 } catch (RemoteException e) { 5808 return false; 5809 } 5810 5811 return readMet && writeMet; 5812 } 5813 5814 private ProviderInfo getProviderInfoLocked(String authority, int userHandle) { 5815 ProviderInfo pi = null; 5816 ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle); 5817 if (cpr != null) { 5818 pi = cpr.info; 5819 } else { 5820 try { 5821 pi = AppGlobals.getPackageManager().resolveContentProvider( 5822 authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle); 5823 } catch (RemoteException ex) { 5824 } 5825 } 5826 return pi; 5827 } 5828 5829 private UriPermission findUriPermissionLocked(int targetUid, Uri uri) { 5830 ArrayMap<Uri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid); 5831 if (targetUris != null) { 5832 return targetUris.get(uri); 5833 } else { 5834 return null; 5835 } 5836 } 5837 5838 private UriPermission findOrCreateUriPermissionLocked( 5839 String sourcePkg, String targetPkg, int targetUid, Uri uri) { 5840 ArrayMap<Uri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid); 5841 if (targetUris == null) { 5842 targetUris = Maps.newArrayMap(); 5843 mGrantedUriPermissions.put(targetUid, targetUris); 5844 } 5845 5846 UriPermission perm = targetUris.get(uri); 5847 if (perm == null) { 5848 perm = new UriPermission(sourcePkg, targetPkg, targetUid, uri); 5849 targetUris.put(uri, perm); 5850 } 5851 5852 return perm; 5853 } 5854 5855 private final boolean checkUriPermissionLocked( 5856 Uri uri, int uid, int modeFlags, int minStrength) { 5857 // Root gets to do everything. 5858 if (uid == 0) { 5859 return true; 5860 } 5861 ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(uid); 5862 if (perms == null) return false; 5863 UriPermission perm = perms.get(uri); 5864 if (perm == null) return false; 5865 return perm.getStrength(modeFlags) >= minStrength; 5866 } 5867 5868 @Override 5869 public int checkUriPermission(Uri uri, int pid, int uid, int modeFlags) { 5870 enforceNotIsolatedCaller("checkUriPermission"); 5871 5872 // Another redirected-binder-call permissions check as in 5873 // {@link checkComponentPermission}. 5874 Identity tlsIdentity = sCallerIdentity.get(); 5875 if (tlsIdentity != null) { 5876 uid = tlsIdentity.uid; 5877 pid = tlsIdentity.pid; 5878 } 5879 5880 // Our own process gets to do everything. 5881 if (pid == MY_PID) { 5882 return PackageManager.PERMISSION_GRANTED; 5883 } 5884 synchronized(this) { 5885 return checkUriPermissionLocked(uri, uid, modeFlags, UriPermission.STRENGTH_OWNED) 5886 ? PackageManager.PERMISSION_GRANTED 5887 : PackageManager.PERMISSION_DENIED; 5888 } 5889 } 5890 5891 /** 5892 * Check if the targetPkg can be granted permission to access uri by 5893 * the callingUid using the given modeFlags. Throws a security exception 5894 * if callingUid is not allowed to do this. Returns the uid of the target 5895 * if the URI permission grant should be performed; returns -1 if it is not 5896 * needed (for example targetPkg already has permission to access the URI). 5897 * If you already know the uid of the target, you can supply it in 5898 * lastTargetUid else set that to -1. 5899 */ 5900 int checkGrantUriPermissionLocked(int callingUid, String targetPkg, 5901 Uri uri, int modeFlags, int lastTargetUid) { 5902 final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0; 5903 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION 5904 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 5905 if (modeFlags == 0) { 5906 return -1; 5907 } 5908 5909 if (targetPkg != null) { 5910 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5911 "Checking grant " + targetPkg + " permission to " + uri); 5912 } 5913 5914 final IPackageManager pm = AppGlobals.getPackageManager(); 5915 5916 // If this is not a content: uri, we can't do anything with it. 5917 if (!ContentResolver.SCHEME_CONTENT.equals(uri.getScheme())) { 5918 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5919 "Can't grant URI permission for non-content URI: " + uri); 5920 return -1; 5921 } 5922 5923 final String authority = uri.getAuthority(); 5924 final ProviderInfo pi = getProviderInfoLocked(authority, UserHandle.getUserId(callingUid)); 5925 if (pi == null) { 5926 Slog.w(TAG, "No content provider found for permission check: " + uri.toSafeString()); 5927 return -1; 5928 } 5929 5930 int targetUid = lastTargetUid; 5931 if (targetUid < 0 && targetPkg != null) { 5932 try { 5933 targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid)); 5934 if (targetUid < 0) { 5935 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5936 "Can't grant URI permission no uid for: " + targetPkg); 5937 return -1; 5938 } 5939 } catch (RemoteException ex) { 5940 return -1; 5941 } 5942 } 5943 5944 if (targetUid >= 0) { 5945 // First... does the target actually need this permission? 5946 if (checkHoldingPermissionsLocked(pm, pi, uri, targetUid, modeFlags)) { 5947 // No need to grant the target this permission. 5948 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5949 "Target " + targetPkg + " already has full permission to " + uri); 5950 return -1; 5951 } 5952 } else { 5953 // First... there is no target package, so can anyone access it? 5954 boolean allowed = pi.exported; 5955 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) { 5956 if (pi.readPermission != null) { 5957 allowed = false; 5958 } 5959 } 5960 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) { 5961 if (pi.writePermission != null) { 5962 allowed = false; 5963 } 5964 } 5965 if (allowed) { 5966 return -1; 5967 } 5968 } 5969 5970 // Second... is the provider allowing granting of URI permissions? 5971 if (!pi.grantUriPermissions) { 5972 throw new SecurityException("Provider " + pi.packageName 5973 + "/" + pi.name 5974 + " does not allow granting of Uri permissions (uri " 5975 + uri + ")"); 5976 } 5977 if (pi.uriPermissionPatterns != null) { 5978 final int N = pi.uriPermissionPatterns.length; 5979 boolean allowed = false; 5980 for (int i=0; i<N; i++) { 5981 if (pi.uriPermissionPatterns[i] != null 5982 && pi.uriPermissionPatterns[i].match(uri.getPath())) { 5983 allowed = true; 5984 break; 5985 } 5986 } 5987 if (!allowed) { 5988 throw new SecurityException("Provider " + pi.packageName 5989 + "/" + pi.name 5990 + " does not allow granting of permission to path of Uri " 5991 + uri); 5992 } 5993 } 5994 5995 // Third... does the caller itself have permission to access 5996 // this uri? 5997 if (callingUid != Process.myUid()) { 5998 if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) { 5999 // Require they hold a strong enough Uri permission 6000 final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE 6001 : UriPermission.STRENGTH_OWNED; 6002 if (!checkUriPermissionLocked(uri, callingUid, modeFlags, minStrength)) { 6003 throw new SecurityException("Uid " + callingUid 6004 + " does not have permission to uri " + uri); 6005 } 6006 } 6007 } 6008 6009 return targetUid; 6010 } 6011 6012 @Override 6013 public int checkGrantUriPermission(int callingUid, String targetPkg, 6014 Uri uri, int modeFlags) { 6015 enforceNotIsolatedCaller("checkGrantUriPermission"); 6016 synchronized(this) { 6017 return checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1); 6018 } 6019 } 6020 6021 void grantUriPermissionUncheckedLocked( 6022 int targetUid, String targetPkg, Uri uri, int modeFlags, UriPermissionOwner owner) { 6023 final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0; 6024 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION 6025 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 6026 if (modeFlags == 0) { 6027 return; 6028 } 6029 6030 // So here we are: the caller has the assumed permission 6031 // to the uri, and the target doesn't. Let's now give this to 6032 // the target. 6033 6034 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6035 "Granting " + targetPkg + "/" + targetUid + " permission to " + uri); 6036 6037 final String authority = uri.getAuthority(); 6038 final ProviderInfo pi = getProviderInfoLocked(authority, UserHandle.getUserId(targetUid)); 6039 if (pi == null) { 6040 Slog.w(TAG, "No content provider found for grant: " + uri.toSafeString()); 6041 return; 6042 } 6043 6044 final UriPermission perm = findOrCreateUriPermissionLocked( 6045 pi.packageName, targetPkg, targetUid, uri); 6046 perm.grantModes(modeFlags, persistable, owner); 6047 } 6048 6049 void grantUriPermissionLocked(int callingUid, String targetPkg, Uri uri, 6050 int modeFlags, UriPermissionOwner owner) { 6051 if (targetPkg == null) { 6052 throw new NullPointerException("targetPkg"); 6053 } 6054 6055 int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1); 6056 if (targetUid < 0) { 6057 return; 6058 } 6059 6060 grantUriPermissionUncheckedLocked(targetUid, targetPkg, uri, modeFlags, owner); 6061 } 6062 6063 static class NeededUriGrants extends ArrayList<Uri> { 6064 final String targetPkg; 6065 final int targetUid; 6066 final int flags; 6067 6068 NeededUriGrants(String targetPkg, int targetUid, int flags) { 6069 this.targetPkg = targetPkg; 6070 this.targetUid = targetUid; 6071 this.flags = flags; 6072 } 6073 } 6074 6075 /** 6076 * Like checkGrantUriPermissionLocked, but takes an Intent. 6077 */ 6078 NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid, 6079 String targetPkg, Intent intent, int mode, NeededUriGrants needed) { 6080 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6081 "Checking URI perm to data=" + (intent != null ? intent.getData() : null) 6082 + " clip=" + (intent != null ? intent.getClipData() : null) 6083 + " from " + intent + "; flags=0x" 6084 + Integer.toHexString(intent != null ? intent.getFlags() : 0)); 6085 6086 if (targetPkg == null) { 6087 throw new NullPointerException("targetPkg"); 6088 } 6089 6090 if (intent == null) { 6091 return null; 6092 } 6093 Uri data = intent.getData(); 6094 ClipData clip = intent.getClipData(); 6095 if (data == null && clip == null) { 6096 return null; 6097 } 6098 6099 if (data != null) { 6100 int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, data, 6101 mode, needed != null ? needed.targetUid : -1); 6102 if (targetUid > 0) { 6103 if (needed == null) { 6104 needed = new NeededUriGrants(targetPkg, targetUid, mode); 6105 } 6106 needed.add(data); 6107 } 6108 } 6109 if (clip != null) { 6110 for (int i=0; i<clip.getItemCount(); i++) { 6111 Uri uri = clip.getItemAt(i).getUri(); 6112 if (uri != null) { 6113 int targetUid = -1; 6114 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri, 6115 mode, needed != null ? needed.targetUid : -1); 6116 if (targetUid > 0) { 6117 if (needed == null) { 6118 needed = new NeededUriGrants(targetPkg, targetUid, mode); 6119 } 6120 needed.add(uri); 6121 } 6122 } else { 6123 Intent clipIntent = clip.getItemAt(i).getIntent(); 6124 if (clipIntent != null) { 6125 NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked( 6126 callingUid, targetPkg, clipIntent, mode, needed); 6127 if (newNeeded != null) { 6128 needed = newNeeded; 6129 } 6130 } 6131 } 6132 } 6133 } 6134 6135 return needed; 6136 } 6137 6138 /** 6139 * Like grantUriPermissionUncheckedLocked, but takes an Intent. 6140 */ 6141 void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed, 6142 UriPermissionOwner owner) { 6143 if (needed != null) { 6144 for (int i=0; i<needed.size(); i++) { 6145 grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg, 6146 needed.get(i), needed.flags, owner); 6147 } 6148 } 6149 } 6150 6151 void grantUriPermissionFromIntentLocked(int callingUid, 6152 String targetPkg, Intent intent, UriPermissionOwner owner) { 6153 NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg, 6154 intent, intent != null ? intent.getFlags() : 0, null); 6155 if (needed == null) { 6156 return; 6157 } 6158 6159 grantUriPermissionUncheckedFromIntentLocked(needed, owner); 6160 } 6161 6162 @Override 6163 public void grantUriPermission(IApplicationThread caller, String targetPkg, 6164 Uri uri, int modeFlags) { 6165 enforceNotIsolatedCaller("grantUriPermission"); 6166 synchronized(this) { 6167 final ProcessRecord r = getRecordForAppLocked(caller); 6168 if (r == null) { 6169 throw new SecurityException("Unable to find app for caller " 6170 + caller 6171 + " when granting permission to uri " + uri); 6172 } 6173 if (targetPkg == null) { 6174 throw new IllegalArgumentException("null target"); 6175 } 6176 if (uri == null) { 6177 throw new IllegalArgumentException("null uri"); 6178 } 6179 6180 // Persistable only supported through Intents 6181 Preconditions.checkFlagsArgument(modeFlags, 6182 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 6183 6184 grantUriPermissionLocked(r.uid, targetPkg, uri, modeFlags, 6185 null); 6186 } 6187 } 6188 6189 void removeUriPermissionIfNeededLocked(UriPermission perm) { 6190 if ((perm.modeFlags&(Intent.FLAG_GRANT_READ_URI_PERMISSION 6191 |Intent.FLAG_GRANT_WRITE_URI_PERMISSION)) == 0) { 6192 ArrayMap<Uri, UriPermission> perms 6193 = mGrantedUriPermissions.get(perm.targetUid); 6194 if (perms != null) { 6195 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6196 "Removing " + perm.targetUid + " permission to " + perm.uri); 6197 perms.remove(perm.uri); 6198 if (perms.size() == 0) { 6199 mGrantedUriPermissions.remove(perm.targetUid); 6200 } 6201 } 6202 } 6203 } 6204 6205 private void revokeUriPermissionLocked(int callingUid, Uri uri, int modeFlags) { 6206 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + uri); 6207 6208 final IPackageManager pm = AppGlobals.getPackageManager(); 6209 final String authority = uri.getAuthority(); 6210 final ProviderInfo pi = getProviderInfoLocked(authority, UserHandle.getUserId(callingUid)); 6211 if (pi == null) { 6212 Slog.w(TAG, "No content provider found for permission revoke: " + uri.toSafeString()); 6213 return; 6214 } 6215 6216 // Does the caller have this permission on the URI? 6217 if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) { 6218 // Right now, if you are not the original owner of the permission, 6219 // you are not allowed to revoke it. 6220 //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) { 6221 throw new SecurityException("Uid " + callingUid 6222 + " does not have permission to uri " + uri); 6223 //} 6224 } 6225 6226 boolean persistChanged = false; 6227 6228 // Go through all of the permissions and remove any that match. 6229 final List<String> SEGMENTS = uri.getPathSegments(); 6230 if (SEGMENTS != null) { 6231 final int NS = SEGMENTS.size(); 6232 int N = mGrantedUriPermissions.size(); 6233 for (int i=0; i<N; i++) { 6234 ArrayMap<Uri, UriPermission> perms 6235 = mGrantedUriPermissions.valueAt(i); 6236 Iterator<UriPermission> it = perms.values().iterator(); 6237 toploop: 6238 while (it.hasNext()) { 6239 UriPermission perm = it.next(); 6240 Uri targetUri = perm.uri; 6241 if (!authority.equals(targetUri.getAuthority())) { 6242 continue; 6243 } 6244 List<String> targetSegments = targetUri.getPathSegments(); 6245 if (targetSegments == null) { 6246 continue; 6247 } 6248 if (targetSegments.size() < NS) { 6249 continue; 6250 } 6251 for (int j=0; j<NS; j++) { 6252 if (!SEGMENTS.get(j).equals(targetSegments.get(j))) { 6253 continue toploop; 6254 } 6255 } 6256 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6257 "Revoking " + perm.targetUid + " permission to " + perm.uri); 6258 persistChanged |= perm.clearModes(modeFlags, true); 6259 if (perm.modeFlags == 0) { 6260 it.remove(); 6261 } 6262 } 6263 if (perms.size() == 0) { 6264 mGrantedUriPermissions.remove( 6265 mGrantedUriPermissions.keyAt(i)); 6266 N--; 6267 i--; 6268 } 6269 } 6270 } 6271 6272 if (persistChanged) { 6273 schedulePersistUriGrants(); 6274 } 6275 } 6276 6277 @Override 6278 public void revokeUriPermission(IApplicationThread caller, Uri uri, 6279 int modeFlags) { 6280 enforceNotIsolatedCaller("revokeUriPermission"); 6281 synchronized(this) { 6282 final ProcessRecord r = getRecordForAppLocked(caller); 6283 if (r == null) { 6284 throw new SecurityException("Unable to find app for caller " 6285 + caller 6286 + " when revoking permission to uri " + uri); 6287 } 6288 if (uri == null) { 6289 Slog.w(TAG, "revokeUriPermission: null uri"); 6290 return; 6291 } 6292 6293 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION 6294 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 6295 if (modeFlags == 0) { 6296 return; 6297 } 6298 6299 final IPackageManager pm = AppGlobals.getPackageManager(); 6300 final String authority = uri.getAuthority(); 6301 final ProviderInfo pi = getProviderInfoLocked(authority, r.userId); 6302 if (pi == null) { 6303 Slog.w(TAG, "No content provider found for permission revoke: " 6304 + uri.toSafeString()); 6305 return; 6306 } 6307 6308 revokeUriPermissionLocked(r.uid, uri, modeFlags); 6309 } 6310 } 6311 6312 /** 6313 * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the 6314 * given package. 6315 * 6316 * @param packageName Package name to match, or {@code null} to apply to all 6317 * packages. 6318 * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply 6319 * to all users. 6320 * @param persistable If persistable grants should be removed. 6321 */ 6322 private void removeUriPermissionsForPackageLocked( 6323 String packageName, int userHandle, boolean persistable) { 6324 if (userHandle == UserHandle.USER_ALL && packageName == null) { 6325 throw new IllegalArgumentException("Must narrow by either package or user"); 6326 } 6327 6328 boolean persistChanged = false; 6329 6330 final int size = mGrantedUriPermissions.size(); 6331 for (int i = 0; i < size; i++) { 6332 // Only inspect grants matching user 6333 if (userHandle == UserHandle.USER_ALL 6334 || userHandle == UserHandle.getUserId(mGrantedUriPermissions.keyAt(i))) { 6335 final Iterator<UriPermission> it = mGrantedUriPermissions.valueAt(i) 6336 .values().iterator(); 6337 while (it.hasNext()) { 6338 final UriPermission perm = it.next(); 6339 6340 // Only inspect grants matching package 6341 if (packageName == null || perm.sourcePkg.equals(packageName) 6342 || perm.targetPkg.equals(packageName)) { 6343 persistChanged |= perm.clearModes(~0, persistable); 6344 6345 // Only remove when no modes remain; any persisted grants 6346 // will keep this alive. 6347 if (perm.modeFlags == 0) { 6348 it.remove(); 6349 } 6350 } 6351 } 6352 } 6353 } 6354 6355 if (persistChanged) { 6356 schedulePersistUriGrants(); 6357 } 6358 } 6359 6360 @Override 6361 public IBinder newUriPermissionOwner(String name) { 6362 enforceNotIsolatedCaller("newUriPermissionOwner"); 6363 synchronized(this) { 6364 UriPermissionOwner owner = new UriPermissionOwner(this, name); 6365 return owner.getExternalTokenLocked(); 6366 } 6367 } 6368 6369 @Override 6370 public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, 6371 Uri uri, int modeFlags) { 6372 synchronized(this) { 6373 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 6374 if (owner == null) { 6375 throw new IllegalArgumentException("Unknown owner: " + token); 6376 } 6377 if (fromUid != Binder.getCallingUid()) { 6378 if (Binder.getCallingUid() != Process.myUid()) { 6379 // Only system code can grant URI permissions on behalf 6380 // of other users. 6381 throw new SecurityException("nice try"); 6382 } 6383 } 6384 if (targetPkg == null) { 6385 throw new IllegalArgumentException("null target"); 6386 } 6387 if (uri == null) { 6388 throw new IllegalArgumentException("null uri"); 6389 } 6390 6391 grantUriPermissionLocked(fromUid, targetPkg, uri, modeFlags, owner); 6392 } 6393 } 6394 6395 @Override 6396 public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode) { 6397 synchronized(this) { 6398 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 6399 if (owner == null) { 6400 throw new IllegalArgumentException("Unknown owner: " + token); 6401 } 6402 6403 if (uri == null) { 6404 owner.removeUriPermissionsLocked(mode); 6405 } else { 6406 owner.removeUriPermissionLocked(uri, mode); 6407 } 6408 } 6409 } 6410 6411 private void schedulePersistUriGrants() { 6412 if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) { 6413 mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG), 6414 10 * DateUtils.SECOND_IN_MILLIS); 6415 } 6416 } 6417 6418 private void writeGrantedUriPermissions() { 6419 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()"); 6420 6421 // Snapshot permissions so we can persist without lock 6422 ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList(); 6423 synchronized (this) { 6424 final int size = mGrantedUriPermissions.size(); 6425 for (int i = 0 ; i < size; i++) { 6426 for (UriPermission perm : mGrantedUriPermissions.valueAt(i).values()) { 6427 if (perm.persistedModeFlags != 0) { 6428 persist.add(perm.snapshot()); 6429 } 6430 } 6431 } 6432 } 6433 6434 FileOutputStream fos = null; 6435 try { 6436 fos = mGrantFile.startWrite(); 6437 6438 XmlSerializer out = new FastXmlSerializer(); 6439 out.setOutput(fos, "utf-8"); 6440 out.startDocument(null, true); 6441 out.startTag(null, TAG_URI_GRANTS); 6442 for (UriPermission.Snapshot perm : persist) { 6443 out.startTag(null, TAG_URI_GRANT); 6444 writeIntAttribute(out, ATTR_USER_HANDLE, perm.userHandle); 6445 out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg); 6446 out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg); 6447 out.attribute(null, ATTR_URI, String.valueOf(perm.uri)); 6448 writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags); 6449 writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime); 6450 out.endTag(null, TAG_URI_GRANT); 6451 } 6452 out.endTag(null, TAG_URI_GRANTS); 6453 out.endDocument(); 6454 6455 mGrantFile.finishWrite(fos); 6456 } catch (IOException e) { 6457 if (fos != null) { 6458 mGrantFile.failWrite(fos); 6459 } 6460 } 6461 } 6462 6463 private void readGrantedUriPermissionsLocked() { 6464 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()"); 6465 6466 final long now = System.currentTimeMillis(); 6467 6468 FileInputStream fis = null; 6469 try { 6470 fis = mGrantFile.openRead(); 6471 final XmlPullParser in = Xml.newPullParser(); 6472 in.setInput(fis, null); 6473 6474 int type; 6475 while ((type = in.next()) != END_DOCUMENT) { 6476 final String tag = in.getName(); 6477 if (type == START_TAG) { 6478 if (TAG_URI_GRANT.equals(tag)) { 6479 final int userHandle = readIntAttribute(in, ATTR_USER_HANDLE); 6480 final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG); 6481 final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG); 6482 final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI)); 6483 final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS); 6484 final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now); 6485 6486 // Sanity check that provider still belongs to source package 6487 final ProviderInfo pi = getProviderInfoLocked( 6488 uri.getAuthority(), userHandle); 6489 if (pi != null && sourcePkg.equals(pi.packageName)) { 6490 int targetUid = -1; 6491 try { 6492 targetUid = AppGlobals.getPackageManager() 6493 .getPackageUid(targetPkg, userHandle); 6494 } catch (RemoteException e) { 6495 } 6496 if (targetUid != -1) { 6497 final UriPermission perm = findOrCreateUriPermissionLocked( 6498 sourcePkg, targetPkg, targetUid, uri); 6499 perm.initPersistedModes(modeFlags, createdTime); 6500 } 6501 } else { 6502 Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg 6503 + " but instead found " + pi); 6504 } 6505 } 6506 } 6507 } 6508 } catch (FileNotFoundException e) { 6509 // Missing grants is okay 6510 } catch (IOException e) { 6511 Log.wtf(TAG, "Failed reading Uri grants", e); 6512 } catch (XmlPullParserException e) { 6513 Log.wtf(TAG, "Failed reading Uri grants", e); 6514 } finally { 6515 IoUtils.closeQuietly(fis); 6516 } 6517 } 6518 6519 @Override 6520 public void takePersistableUriPermission(Uri uri, int modeFlags) { 6521 enforceNotIsolatedCaller("takePersistableUriPermission"); 6522 6523 Preconditions.checkFlagsArgument(modeFlags, 6524 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 6525 6526 synchronized (this) { 6527 final int callingUid = Binder.getCallingUid(); 6528 final UriPermission perm = findUriPermissionLocked(callingUid, uri); 6529 if (perm == null) { 6530 throw new SecurityException("No permission grant found for UID " + callingUid 6531 + " and Uri " + uri.toSafeString()); 6532 } 6533 6534 boolean persistChanged = perm.takePersistableModes(modeFlags); 6535 persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid); 6536 6537 if (persistChanged) { 6538 schedulePersistUriGrants(); 6539 } 6540 } 6541 } 6542 6543 @Override 6544 public void releasePersistableUriPermission(Uri uri, int modeFlags) { 6545 enforceNotIsolatedCaller("releasePersistableUriPermission"); 6546 6547 Preconditions.checkFlagsArgument(modeFlags, 6548 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 6549 6550 synchronized (this) { 6551 final int callingUid = Binder.getCallingUid(); 6552 6553 final UriPermission perm = findUriPermissionLocked(callingUid, uri); 6554 if (perm == null) { 6555 Slog.w(TAG, "No permission grant found for UID " + callingUid + " and Uri " 6556 + uri.toSafeString()); 6557 return; 6558 } 6559 6560 final boolean persistChanged = perm.releasePersistableModes(modeFlags); 6561 removeUriPermissionIfNeededLocked(perm); 6562 if (persistChanged) { 6563 schedulePersistUriGrants(); 6564 } 6565 } 6566 } 6567 6568 /** 6569 * Prune any older {@link UriPermission} for the given UID until outstanding 6570 * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}. 6571 * 6572 * @return if any mutations occured that require persisting. 6573 */ 6574 private boolean maybePrunePersistedUriGrantsLocked(int uid) { 6575 final ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(uid); 6576 if (perms == null) return false; 6577 if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false; 6578 6579 final ArrayList<UriPermission> persisted = Lists.newArrayList(); 6580 for (UriPermission perm : perms.values()) { 6581 if (perm.persistedModeFlags != 0) { 6582 persisted.add(perm); 6583 } 6584 } 6585 6586 final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS; 6587 if (trimCount <= 0) return false; 6588 6589 Collections.sort(persisted, new UriPermission.PersistedTimeComparator()); 6590 for (int i = 0; i < trimCount; i++) { 6591 final UriPermission perm = persisted.get(i); 6592 6593 if (DEBUG_URI_PERMISSION) { 6594 Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime); 6595 } 6596 6597 perm.releasePersistableModes(~0); 6598 removeUriPermissionIfNeededLocked(perm); 6599 } 6600 6601 return true; 6602 } 6603 6604 @Override 6605 public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions( 6606 String packageName, boolean incoming) { 6607 enforceNotIsolatedCaller("getPersistedUriPermissions"); 6608 Preconditions.checkNotNull(packageName, "packageName"); 6609 6610 final int callingUid = Binder.getCallingUid(); 6611 final IPackageManager pm = AppGlobals.getPackageManager(); 6612 try { 6613 final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid)); 6614 if (packageUid != callingUid) { 6615 throw new SecurityException( 6616 "Package " + packageName + " does not belong to calling UID " + callingUid); 6617 } 6618 } catch (RemoteException e) { 6619 throw new SecurityException("Failed to verify package name ownership"); 6620 } 6621 6622 final ArrayList<android.content.UriPermission> result = Lists.newArrayList(); 6623 synchronized (this) { 6624 if (incoming) { 6625 final ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(callingUid); 6626 if (perms == null) { 6627 Slog.w(TAG, "No permission grants found for " + packageName); 6628 } else { 6629 final int size = perms.size(); 6630 for (int i = 0; i < size; i++) { 6631 final UriPermission perm = perms.valueAt(i); 6632 if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) { 6633 result.add(perm.buildPersistedPublicApiObject()); 6634 } 6635 } 6636 } 6637 } else { 6638 final int size = mGrantedUriPermissions.size(); 6639 for (int i = 0; i < size; i++) { 6640 final ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 6641 final int permsSize = perms.size(); 6642 for (int j = 0; j < permsSize; j++) { 6643 final UriPermission perm = perms.valueAt(j); 6644 if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) { 6645 result.add(perm.buildPersistedPublicApiObject()); 6646 } 6647 } 6648 } 6649 } 6650 } 6651 return new ParceledListSlice<android.content.UriPermission>(result); 6652 } 6653 6654 @Override 6655 public void showWaitingForDebugger(IApplicationThread who, boolean waiting) { 6656 synchronized (this) { 6657 ProcessRecord app = 6658 who != null ? getRecordForAppLocked(who) : null; 6659 if (app == null) return; 6660 6661 Message msg = Message.obtain(); 6662 msg.what = WAIT_FOR_DEBUGGER_MSG; 6663 msg.obj = app; 6664 msg.arg1 = waiting ? 1 : 0; 6665 mHandler.sendMessage(msg); 6666 } 6667 } 6668 6669 @Override 6670 public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) { 6671 final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ); 6672 final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ); 6673 outInfo.availMem = Process.getFreeMemory(); 6674 outInfo.totalMem = Process.getTotalMemory(); 6675 outInfo.threshold = homeAppMem; 6676 outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2)); 6677 outInfo.hiddenAppThreshold = cachedAppMem; 6678 outInfo.secondaryServerThreshold = mProcessList.getMemLevel( 6679 ProcessList.SERVICE_ADJ); 6680 outInfo.visibleAppThreshold = mProcessList.getMemLevel( 6681 ProcessList.VISIBLE_APP_ADJ); 6682 outInfo.foregroundAppThreshold = mProcessList.getMemLevel( 6683 ProcessList.FOREGROUND_APP_ADJ); 6684 } 6685 6686 // ========================================================= 6687 // TASK MANAGEMENT 6688 // ========================================================= 6689 6690 @Override 6691 public List<RunningTaskInfo> getTasks(int maxNum, int flags, 6692 IThumbnailReceiver receiver) { 6693 ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>(); 6694 6695 PendingThumbnailsRecord pending = new PendingThumbnailsRecord(receiver); 6696 ActivityRecord topRecord = null; 6697 6698 synchronized(this) { 6699 if (localLOGV) Slog.v( 6700 TAG, "getTasks: max=" + maxNum + ", flags=" + flags 6701 + ", receiver=" + receiver); 6702 6703 if (checkCallingPermission(android.Manifest.permission.GET_TASKS) 6704 != PackageManager.PERMISSION_GRANTED) { 6705 if (receiver != null) { 6706 // If the caller wants to wait for pending thumbnails, 6707 // it ain't gonna get them. 6708 try { 6709 receiver.finished(); 6710 } catch (RemoteException ex) { 6711 } 6712 } 6713 String msg = "Permission Denial: getTasks() from pid=" 6714 + Binder.getCallingPid() 6715 + ", uid=" + Binder.getCallingUid() 6716 + " requires " + android.Manifest.permission.GET_TASKS; 6717 Slog.w(TAG, msg); 6718 throw new SecurityException(msg); 6719 } 6720 6721 // TODO: Improve with MRU list from all ActivityStacks. 6722 topRecord = mStackSupervisor.getTasksLocked(maxNum, receiver, pending, list); 6723 6724 if (!pending.pendingRecords.isEmpty()) { 6725 mPendingThumbnails.add(pending); 6726 } 6727 } 6728 6729 if (localLOGV) Slog.v(TAG, "We have pending thumbnails: " + pending); 6730 6731 if (topRecord != null) { 6732 if (localLOGV) Slog.v(TAG, "Requesting top thumbnail"); 6733 try { 6734 IApplicationThread topThumbnail = topRecord.app.thread; 6735 topThumbnail.requestThumbnail(topRecord.appToken); 6736 } catch (Exception e) { 6737 Slog.w(TAG, "Exception thrown when requesting thumbnail", e); 6738 sendPendingThumbnail(null, topRecord.appToken, null, null, true); 6739 } 6740 } 6741 6742 if (pending == null && receiver != null) { 6743 // In this case all thumbnails were available and the client 6744 // is being asked to be told when the remaining ones come in... 6745 // which is unusually, since the top-most currently running 6746 // activity should never have a canned thumbnail! Oh well. 6747 try { 6748 receiver.finished(); 6749 } catch (RemoteException ex) { 6750 } 6751 } 6752 6753 return list; 6754 } 6755 6756 TaskRecord getMostRecentTask() { 6757 return mRecentTasks.get(0); 6758 } 6759 6760 @Override 6761 public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, 6762 int flags, int userId) { 6763 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 6764 false, true, "getRecentTasks", null); 6765 6766 synchronized (this) { 6767 enforceCallingPermission(android.Manifest.permission.GET_TASKS, 6768 "getRecentTasks()"); 6769 final boolean detailed = checkCallingPermission( 6770 android.Manifest.permission.GET_DETAILED_TASKS) 6771 == PackageManager.PERMISSION_GRANTED; 6772 6773 IPackageManager pm = AppGlobals.getPackageManager(); 6774 6775 final int N = mRecentTasks.size(); 6776 ArrayList<ActivityManager.RecentTaskInfo> res 6777 = new ArrayList<ActivityManager.RecentTaskInfo>( 6778 maxNum < N ? maxNum : N); 6779 for (int i=0; i<N && maxNum > 0; i++) { 6780 TaskRecord tr = mRecentTasks.get(i); 6781 // Only add calling user's recent tasks 6782 if (tr.userId != userId) continue; 6783 // Return the entry if desired by the caller. We always return 6784 // the first entry, because callers always expect this to be the 6785 // foreground app. We may filter others if the caller has 6786 // not supplied RECENT_WITH_EXCLUDED and there is some reason 6787 // we should exclude the entry. 6788 6789 if (i == 0 6790 || ((flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0) 6791 || (tr.intent == null) 6792 || ((tr.intent.getFlags() 6793 &Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0)) { 6794 ActivityManager.RecentTaskInfo rti 6795 = new ActivityManager.RecentTaskInfo(); 6796 rti.id = tr.numActivities > 0 ? tr.taskId : -1; 6797 rti.persistentId = tr.taskId; 6798 rti.baseIntent = new Intent( 6799 tr.intent != null ? tr.intent : tr.affinityIntent); 6800 if (!detailed) { 6801 rti.baseIntent.replaceExtras((Bundle)null); 6802 } 6803 rti.origActivity = tr.origActivity; 6804 rti.description = tr.lastDescription; 6805 rti.stackId = tr.stack.mStackId; 6806 6807 if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) { 6808 // Check whether this activity is currently available. 6809 try { 6810 if (rti.origActivity != null) { 6811 if (pm.getActivityInfo(rti.origActivity, 0, userId) 6812 == null) { 6813 continue; 6814 } 6815 } else if (rti.baseIntent != null) { 6816 if (pm.queryIntentActivities(rti.baseIntent, 6817 null, 0, userId) == null) { 6818 continue; 6819 } 6820 } 6821 } catch (RemoteException e) { 6822 // Will never happen. 6823 } 6824 } 6825 6826 res.add(rti); 6827 maxNum--; 6828 } 6829 } 6830 return res; 6831 } 6832 } 6833 6834 private TaskRecord recentTaskForIdLocked(int id) { 6835 final int N = mRecentTasks.size(); 6836 for (int i=0; i<N; i++) { 6837 TaskRecord tr = mRecentTasks.get(i); 6838 if (tr.taskId == id) { 6839 return tr; 6840 } 6841 } 6842 return null; 6843 } 6844 6845 @Override 6846 public ActivityManager.TaskThumbnails getTaskThumbnails(int id) { 6847 synchronized (this) { 6848 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER, 6849 "getTaskThumbnails()"); 6850 TaskRecord tr = recentTaskForIdLocked(id); 6851 if (tr != null) { 6852 return tr.getTaskThumbnailsLocked(); 6853 } 6854 } 6855 return null; 6856 } 6857 6858 @Override 6859 public Bitmap getTaskTopThumbnail(int id) { 6860 synchronized (this) { 6861 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER, 6862 "getTaskTopThumbnail()"); 6863 TaskRecord tr = recentTaskForIdLocked(id); 6864 if (tr != null) { 6865 return tr.getTaskTopThumbnailLocked(); 6866 } 6867 } 6868 return null; 6869 } 6870 6871 @Override 6872 public boolean removeSubTask(int taskId, int subTaskIndex) { 6873 synchronized (this) { 6874 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, 6875 "removeSubTask()"); 6876 long ident = Binder.clearCallingIdentity(); 6877 try { 6878 TaskRecord tr = recentTaskForIdLocked(taskId); 6879 if (tr != null) { 6880 return tr.removeTaskActivitiesLocked(subTaskIndex, true) != null; 6881 } 6882 return false; 6883 } finally { 6884 Binder.restoreCallingIdentity(ident); 6885 } 6886 } 6887 } 6888 6889 private void killUnneededProcessLocked(ProcessRecord pr, String reason) { 6890 if (!pr.killedByAm) { 6891 Slog.i(TAG, "Killing " + pr.toShortString() + " (adj " + pr.setAdj + "): " + reason); 6892 EventLog.writeEvent(EventLogTags.AM_KILL, pr.userId, pr.pid, 6893 pr.processName, pr.setAdj, reason); 6894 pr.killedByAm = true; 6895 Process.killProcessQuiet(pr.pid); 6896 } 6897 } 6898 6899 private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) { 6900 tr.disposeThumbnail(); 6901 mRecentTasks.remove(tr); 6902 final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0; 6903 Intent baseIntent = new Intent( 6904 tr.intent != null ? tr.intent : tr.affinityIntent); 6905 ComponentName component = baseIntent.getComponent(); 6906 if (component == null) { 6907 Slog.w(TAG, "Now component for base intent of task: " + tr); 6908 return; 6909 } 6910 6911 // Find any running services associated with this app. 6912 mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent); 6913 6914 if (killProcesses) { 6915 // Find any running processes associated with this app. 6916 final String pkg = component.getPackageName(); 6917 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 6918 ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap(); 6919 for (int i=0; i<pmap.size(); i++) { 6920 SparseArray<ProcessRecord> uids = pmap.valueAt(i); 6921 for (int j=0; j<uids.size(); j++) { 6922 ProcessRecord proc = uids.valueAt(j); 6923 if (proc.userId != tr.userId) { 6924 continue; 6925 } 6926 if (!proc.pkgList.containsKey(pkg)) { 6927 continue; 6928 } 6929 procs.add(proc); 6930 } 6931 } 6932 6933 // Kill the running processes. 6934 for (int i=0; i<procs.size(); i++) { 6935 ProcessRecord pr = procs.get(i); 6936 if (pr == mHomeProcess) { 6937 // Don't kill the home process along with tasks from the same package. 6938 continue; 6939 } 6940 if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 6941 killUnneededProcessLocked(pr, "remove task"); 6942 } else { 6943 pr.waitingToKill = "remove task"; 6944 } 6945 } 6946 } 6947 } 6948 6949 @Override 6950 public boolean removeTask(int taskId, int flags) { 6951 synchronized (this) { 6952 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, 6953 "removeTask()"); 6954 long ident = Binder.clearCallingIdentity(); 6955 try { 6956 TaskRecord tr = recentTaskForIdLocked(taskId); 6957 if (tr != null) { 6958 ActivityRecord r = tr.removeTaskActivitiesLocked(-1, false); 6959 if (r != null) { 6960 cleanUpRemovedTaskLocked(tr, flags); 6961 return true; 6962 } 6963 if (tr.mActivities.size() == 0) { 6964 // Caller is just removing a recent task that is 6965 // not actively running. That is easy! 6966 cleanUpRemovedTaskLocked(tr, flags); 6967 return true; 6968 } 6969 Slog.w(TAG, "removeTask: task " + taskId 6970 + " does not have activities to remove, " 6971 + " but numActivities=" + tr.numActivities 6972 + ": " + tr); 6973 } 6974 } finally { 6975 Binder.restoreCallingIdentity(ident); 6976 } 6977 } 6978 return false; 6979 } 6980 6981 /** 6982 * TODO: Add mController hook 6983 */ 6984 @Override 6985 public void moveTaskToFront(int task, int flags, Bundle options) { 6986 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 6987 "moveTaskToFront()"); 6988 6989 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving task=" + task); 6990 synchronized(this) { 6991 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 6992 Binder.getCallingUid(), "Task to front")) { 6993 ActivityOptions.abort(options); 6994 return; 6995 } 6996 final long origId = Binder.clearCallingIdentity(); 6997 try { 6998 mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options); 6999 } finally { 7000 Binder.restoreCallingIdentity(origId); 7001 } 7002 ActivityOptions.abort(options); 7003 } 7004 } 7005 7006 @Override 7007 public void moveTaskToBack(int taskId) { 7008 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 7009 "moveTaskToBack()"); 7010 7011 synchronized(this) { 7012 TaskRecord tr = recentTaskForIdLocked(taskId); 7013 if (tr != null) { 7014 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr); 7015 ActivityStack stack = tr.stack; 7016 if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) { 7017 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 7018 Binder.getCallingUid(), "Task to back")) { 7019 return; 7020 } 7021 } 7022 final long origId = Binder.clearCallingIdentity(); 7023 try { 7024 stack.moveTaskToBackLocked(taskId, null); 7025 } finally { 7026 Binder.restoreCallingIdentity(origId); 7027 } 7028 } 7029 } 7030 } 7031 7032 /** 7033 * Moves an activity, and all of the other activities within the same task, to the bottom 7034 * of the history stack. The activity's order within the task is unchanged. 7035 * 7036 * @param token A reference to the activity we wish to move 7037 * @param nonRoot If false then this only works if the activity is the root 7038 * of a task; if true it will work for any activity in a task. 7039 * @return Returns true if the move completed, false if not. 7040 */ 7041 @Override 7042 public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) { 7043 enforceNotIsolatedCaller("moveActivityTaskToBack"); 7044 synchronized(this) { 7045 final long origId = Binder.clearCallingIdentity(); 7046 int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot); 7047 if (taskId >= 0) { 7048 return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null); 7049 } 7050 Binder.restoreCallingIdentity(origId); 7051 } 7052 return false; 7053 } 7054 7055 @Override 7056 public void moveTaskBackwards(int task) { 7057 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 7058 "moveTaskBackwards()"); 7059 7060 synchronized(this) { 7061 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 7062 Binder.getCallingUid(), "Task backwards")) { 7063 return; 7064 } 7065 final long origId = Binder.clearCallingIdentity(); 7066 moveTaskBackwardsLocked(task); 7067 Binder.restoreCallingIdentity(origId); 7068 } 7069 } 7070 7071 private final void moveTaskBackwardsLocked(int task) { 7072 Slog.e(TAG, "moveTaskBackwards not yet implemented!"); 7073 } 7074 7075 @Override 7076 public IBinder getHomeActivityToken() throws RemoteException { 7077 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7078 "getHomeActivityToken()"); 7079 synchronized (this) { 7080 return mStackSupervisor.getHomeActivityToken(); 7081 } 7082 } 7083 7084 @Override 7085 public IActivityContainer createActivityContainer(IBinder parentActivityToken, 7086 IActivityContainerCallback callback) throws RemoteException { 7087 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7088 "createActivityContainer()"); 7089 synchronized (this) { 7090 if (parentActivityToken == null) { 7091 throw new IllegalArgumentException("parent token must not be null"); 7092 } 7093 ActivityRecord r = ActivityRecord.forToken(parentActivityToken); 7094 if (r == null) { 7095 return null; 7096 } 7097 return mStackSupervisor.createActivityContainer(r, callback); 7098 } 7099 } 7100 7101 @Override 7102 public IActivityContainer getEnclosingActivityContainer(IBinder activityToken) 7103 throws RemoteException { 7104 synchronized (this) { 7105 ActivityStack stack = ActivityRecord.getStackLocked(activityToken); 7106 if (stack != null) { 7107 return stack.mActivityContainer; 7108 } 7109 return null; 7110 } 7111 } 7112 7113 @Override 7114 public void moveTaskToStack(int taskId, int stackId, boolean toTop) { 7115 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7116 "moveTaskToStack()"); 7117 if (stackId == HOME_STACK_ID) { 7118 Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack", 7119 new RuntimeException("here").fillInStackTrace()); 7120 } 7121 synchronized (this) { 7122 long ident = Binder.clearCallingIdentity(); 7123 try { 7124 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId=" 7125 + stackId + " toTop=" + toTop); 7126 mStackSupervisor.moveTaskToStack(taskId, stackId, toTop); 7127 } finally { 7128 Binder.restoreCallingIdentity(ident); 7129 } 7130 } 7131 } 7132 7133 @Override 7134 public void resizeStack(int stackBoxId, Rect bounds) { 7135 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7136 "resizeStackBox()"); 7137 long ident = Binder.clearCallingIdentity(); 7138 try { 7139 mWindowManager.resizeStack(stackBoxId, bounds); 7140 } finally { 7141 Binder.restoreCallingIdentity(ident); 7142 } 7143 } 7144 7145 @Override 7146 public List<StackInfo> getAllStackInfos() { 7147 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7148 "getAllStackInfos()"); 7149 long ident = Binder.clearCallingIdentity(); 7150 try { 7151 synchronized (this) { 7152 return mStackSupervisor.getAllStackInfosLocked(); 7153 } 7154 } finally { 7155 Binder.restoreCallingIdentity(ident); 7156 } 7157 } 7158 7159 @Override 7160 public StackInfo getStackInfo(int stackId) { 7161 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7162 "getStackInfo()"); 7163 long ident = Binder.clearCallingIdentity(); 7164 try { 7165 synchronized (this) { 7166 return mStackSupervisor.getStackInfoLocked(stackId); 7167 } 7168 } finally { 7169 Binder.restoreCallingIdentity(ident); 7170 } 7171 } 7172 7173 @Override 7174 public int getTaskForActivity(IBinder token, boolean onlyRoot) { 7175 synchronized(this) { 7176 return ActivityRecord.getTaskForActivityLocked(token, onlyRoot); 7177 } 7178 } 7179 7180 // ========================================================= 7181 // THUMBNAILS 7182 // ========================================================= 7183 7184 public void reportThumbnail(IBinder token, 7185 Bitmap thumbnail, CharSequence description) { 7186 //System.out.println("Report thumbnail for " + token + ": " + thumbnail); 7187 final long origId = Binder.clearCallingIdentity(); 7188 sendPendingThumbnail(null, token, thumbnail, description, true); 7189 Binder.restoreCallingIdentity(origId); 7190 } 7191 7192 final void sendPendingThumbnail(ActivityRecord r, IBinder token, 7193 Bitmap thumbnail, CharSequence description, boolean always) { 7194 TaskRecord task; 7195 ArrayList<PendingThumbnailsRecord> receivers = null; 7196 7197 //System.out.println("Send pending thumbnail: " + r); 7198 7199 synchronized(this) { 7200 if (r == null) { 7201 r = ActivityRecord.isInStackLocked(token); 7202 if (r == null) { 7203 return; 7204 } 7205 } 7206 if (thumbnail == null && r.thumbHolder != null) { 7207 thumbnail = r.thumbHolder.lastThumbnail; 7208 description = r.thumbHolder.lastDescription; 7209 } 7210 if (thumbnail == null && !always) { 7211 // If there is no thumbnail, and this entry is not actually 7212 // going away, then abort for now and pick up the next 7213 // thumbnail we get. 7214 return; 7215 } 7216 task = r.task; 7217 7218 int N = mPendingThumbnails.size(); 7219 int i=0; 7220 while (i<N) { 7221 PendingThumbnailsRecord pr = mPendingThumbnails.get(i); 7222 //System.out.println("Looking in " + pr.pendingRecords); 7223 if (pr.pendingRecords.remove(r)) { 7224 if (receivers == null) { 7225 receivers = new ArrayList<PendingThumbnailsRecord>(); 7226 } 7227 receivers.add(pr); 7228 if (pr.pendingRecords.size() == 0) { 7229 pr.finished = true; 7230 mPendingThumbnails.remove(i); 7231 N--; 7232 continue; 7233 } 7234 } 7235 i++; 7236 } 7237 } 7238 7239 if (receivers != null) { 7240 final int N = receivers.size(); 7241 for (int i=0; i<N; i++) { 7242 try { 7243 PendingThumbnailsRecord pr = receivers.get(i); 7244 pr.receiver.newThumbnail( 7245 task != null ? task.taskId : -1, thumbnail, description); 7246 if (pr.finished) { 7247 pr.receiver.finished(); 7248 } 7249 } catch (Exception e) { 7250 Slog.w(TAG, "Exception thrown when sending thumbnail", e); 7251 } 7252 } 7253 } 7254 } 7255 7256 // ========================================================= 7257 // CONTENT PROVIDERS 7258 // ========================================================= 7259 7260 private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) { 7261 List<ProviderInfo> providers = null; 7262 try { 7263 providers = AppGlobals.getPackageManager(). 7264 queryContentProviders(app.processName, app.uid, 7265 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS); 7266 } catch (RemoteException ex) { 7267 } 7268 if (DEBUG_MU) 7269 Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid); 7270 int userId = app.userId; 7271 if (providers != null) { 7272 int N = providers.size(); 7273 app.pubProviders.ensureCapacity(N + app.pubProviders.size()); 7274 for (int i=0; i<N; i++) { 7275 ProviderInfo cpi = 7276 (ProviderInfo)providers.get(i); 7277 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo, 7278 cpi.name, cpi.flags); 7279 if (singleton && UserHandle.getUserId(app.uid) != 0) { 7280 // This is a singleton provider, but a user besides the 7281 // default user is asking to initialize a process it runs 7282 // in... well, no, it doesn't actually run in this process, 7283 // it runs in the process of the default user. Get rid of it. 7284 providers.remove(i); 7285 N--; 7286 i--; 7287 continue; 7288 } 7289 7290 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 7291 ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId); 7292 if (cpr == null) { 7293 cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton); 7294 mProviderMap.putProviderByClass(comp, cpr); 7295 } 7296 if (DEBUG_MU) 7297 Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid); 7298 app.pubProviders.put(cpi.name, cpr); 7299 if (!cpi.multiprocess || !"android".equals(cpi.packageName)) { 7300 // Don't add this if it is a platform component that is marked 7301 // to run in multiple processes, because this is actually 7302 // part of the framework so doesn't make sense to track as a 7303 // separate apk in the process. 7304 app.addPackage(cpi.applicationInfo.packageName, mProcessStats); 7305 } 7306 ensurePackageDexOpt(cpi.applicationInfo.packageName); 7307 } 7308 } 7309 return providers; 7310 } 7311 7312 /** 7313 * Check if {@link ProcessRecord} has a possible chance at accessing the 7314 * given {@link ProviderInfo}. Final permission checking is always done 7315 * in {@link ContentProvider}. 7316 */ 7317 private final String checkContentProviderPermissionLocked( 7318 ProviderInfo cpi, ProcessRecord r) { 7319 final int callingPid = (r != null) ? r.pid : Binder.getCallingPid(); 7320 final int callingUid = (r != null) ? r.uid : Binder.getCallingUid(); 7321 if (checkComponentPermission(cpi.readPermission, callingPid, callingUid, 7322 cpi.applicationInfo.uid, cpi.exported) 7323 == PackageManager.PERMISSION_GRANTED) { 7324 return null; 7325 } 7326 if (checkComponentPermission(cpi.writePermission, callingPid, callingUid, 7327 cpi.applicationInfo.uid, cpi.exported) 7328 == PackageManager.PERMISSION_GRANTED) { 7329 return null; 7330 } 7331 7332 PathPermission[] pps = cpi.pathPermissions; 7333 if (pps != null) { 7334 int i = pps.length; 7335 while (i > 0) { 7336 i--; 7337 PathPermission pp = pps[i]; 7338 if (checkComponentPermission(pp.getReadPermission(), callingPid, callingUid, 7339 cpi.applicationInfo.uid, cpi.exported) 7340 == PackageManager.PERMISSION_GRANTED) { 7341 return null; 7342 } 7343 if (checkComponentPermission(pp.getWritePermission(), callingPid, callingUid, 7344 cpi.applicationInfo.uid, cpi.exported) 7345 == PackageManager.PERMISSION_GRANTED) { 7346 return null; 7347 } 7348 } 7349 } 7350 7351 ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(callingUid); 7352 if (perms != null) { 7353 for (Map.Entry<Uri, UriPermission> uri : perms.entrySet()) { 7354 if (uri.getKey().getAuthority().equals(cpi.authority)) { 7355 return null; 7356 } 7357 } 7358 } 7359 7360 String msg; 7361 if (!cpi.exported) { 7362 msg = "Permission Denial: opening provider " + cpi.name 7363 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 7364 + ", uid=" + callingUid + ") that is not exported from uid " 7365 + cpi.applicationInfo.uid; 7366 } else { 7367 msg = "Permission Denial: opening provider " + cpi.name 7368 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 7369 + ", uid=" + callingUid + ") requires " 7370 + cpi.readPermission + " or " + cpi.writePermission; 7371 } 7372 Slog.w(TAG, msg); 7373 return msg; 7374 } 7375 7376 ContentProviderConnection incProviderCountLocked(ProcessRecord r, 7377 final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 7378 if (r != null) { 7379 for (int i=0; i<r.conProviders.size(); i++) { 7380 ContentProviderConnection conn = r.conProviders.get(i); 7381 if (conn.provider == cpr) { 7382 if (DEBUG_PROVIDER) Slog.v(TAG, 7383 "Adding provider requested by " 7384 + r.processName + " from process " 7385 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 7386 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 7387 if (stable) { 7388 conn.stableCount++; 7389 conn.numStableIncs++; 7390 } else { 7391 conn.unstableCount++; 7392 conn.numUnstableIncs++; 7393 } 7394 return conn; 7395 } 7396 } 7397 ContentProviderConnection conn = new ContentProviderConnection(cpr, r); 7398 if (stable) { 7399 conn.stableCount = 1; 7400 conn.numStableIncs = 1; 7401 } else { 7402 conn.unstableCount = 1; 7403 conn.numUnstableIncs = 1; 7404 } 7405 cpr.connections.add(conn); 7406 r.conProviders.add(conn); 7407 return conn; 7408 } 7409 cpr.addExternalProcessHandleLocked(externalProcessToken); 7410 return null; 7411 } 7412 7413 boolean decProviderCountLocked(ContentProviderConnection conn, 7414 ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 7415 if (conn != null) { 7416 cpr = conn.provider; 7417 if (DEBUG_PROVIDER) Slog.v(TAG, 7418 "Removing provider requested by " 7419 + conn.client.processName + " from process " 7420 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 7421 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 7422 if (stable) { 7423 conn.stableCount--; 7424 } else { 7425 conn.unstableCount--; 7426 } 7427 if (conn.stableCount == 0 && conn.unstableCount == 0) { 7428 cpr.connections.remove(conn); 7429 conn.client.conProviders.remove(conn); 7430 return true; 7431 } 7432 return false; 7433 } 7434 cpr.removeExternalProcessHandleLocked(externalProcessToken); 7435 return false; 7436 } 7437 7438 private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller, 7439 String name, IBinder token, boolean stable, int userId) { 7440 ContentProviderRecord cpr; 7441 ContentProviderConnection conn = null; 7442 ProviderInfo cpi = null; 7443 7444 synchronized(this) { 7445 ProcessRecord r = null; 7446 if (caller != null) { 7447 r = getRecordForAppLocked(caller); 7448 if (r == null) { 7449 throw new SecurityException( 7450 "Unable to find app for caller " + caller 7451 + " (pid=" + Binder.getCallingPid() 7452 + ") when getting content provider " + name); 7453 } 7454 } 7455 7456 // First check if this content provider has been published... 7457 cpr = mProviderMap.getProviderByName(name, userId); 7458 boolean providerRunning = cpr != null; 7459 if (providerRunning) { 7460 cpi = cpr.info; 7461 String msg; 7462 if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) { 7463 throw new SecurityException(msg); 7464 } 7465 7466 if (r != null && cpr.canRunHere(r)) { 7467 // This provider has been published or is in the process 7468 // of being published... but it is also allowed to run 7469 // in the caller's process, so don't make a connection 7470 // and just let the caller instantiate its own instance. 7471 ContentProviderHolder holder = cpr.newHolder(null); 7472 // don't give caller the provider object, it needs 7473 // to make its own. 7474 holder.provider = null; 7475 return holder; 7476 } 7477 7478 final long origId = Binder.clearCallingIdentity(); 7479 7480 // In this case the provider instance already exists, so we can 7481 // return it right away. 7482 conn = incProviderCountLocked(r, cpr, token, stable); 7483 if (conn != null && (conn.stableCount+conn.unstableCount) == 1) { 7484 if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 7485 // If this is a perceptible app accessing the provider, 7486 // make sure to count it as being accessed and thus 7487 // back up on the LRU list. This is good because 7488 // content providers are often expensive to start. 7489 updateLruProcessLocked(cpr.proc, false, null); 7490 } 7491 } 7492 7493 if (cpr.proc != null) { 7494 if (false) { 7495 if (cpr.name.flattenToShortString().equals( 7496 "com.android.providers.calendar/.CalendarProvider2")) { 7497 Slog.v(TAG, "****************** KILLING " 7498 + cpr.name.flattenToShortString()); 7499 Process.killProcess(cpr.proc.pid); 7500 } 7501 } 7502 boolean success = updateOomAdjLocked(cpr.proc); 7503 if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success); 7504 // NOTE: there is still a race here where a signal could be 7505 // pending on the process even though we managed to update its 7506 // adj level. Not sure what to do about this, but at least 7507 // the race is now smaller. 7508 if (!success) { 7509 // Uh oh... it looks like the provider's process 7510 // has been killed on us. We need to wait for a new 7511 // process to be started, and make sure its death 7512 // doesn't kill our process. 7513 Slog.i(TAG, 7514 "Existing provider " + cpr.name.flattenToShortString() 7515 + " is crashing; detaching " + r); 7516 boolean lastRef = decProviderCountLocked(conn, cpr, token, stable); 7517 appDiedLocked(cpr.proc, cpr.proc.pid, cpr.proc.thread); 7518 if (!lastRef) { 7519 // This wasn't the last ref our process had on 7520 // the provider... we have now been killed, bail. 7521 return null; 7522 } 7523 providerRunning = false; 7524 conn = null; 7525 } 7526 } 7527 7528 Binder.restoreCallingIdentity(origId); 7529 } 7530 7531 boolean singleton; 7532 if (!providerRunning) { 7533 try { 7534 cpi = AppGlobals.getPackageManager(). 7535 resolveContentProvider(name, 7536 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId); 7537 } catch (RemoteException ex) { 7538 } 7539 if (cpi == null) { 7540 return null; 7541 } 7542 singleton = isSingleton(cpi.processName, cpi.applicationInfo, 7543 cpi.name, cpi.flags); 7544 if (singleton) { 7545 userId = 0; 7546 } 7547 cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId); 7548 7549 String msg; 7550 if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) { 7551 throw new SecurityException(msg); 7552 } 7553 7554 if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate 7555 && !cpi.processName.equals("system")) { 7556 // If this content provider does not run in the system 7557 // process, and the system is not yet ready to run other 7558 // processes, then fail fast instead of hanging. 7559 throw new IllegalArgumentException( 7560 "Attempt to launch content provider before system ready"); 7561 } 7562 7563 // Make sure that the user who owns this provider is started. If not, 7564 // we don't want to allow it to run. 7565 if (mStartedUsers.get(userId) == null) { 7566 Slog.w(TAG, "Unable to launch app " 7567 + cpi.applicationInfo.packageName + "/" 7568 + cpi.applicationInfo.uid + " for provider " 7569 + name + ": user " + userId + " is stopped"); 7570 return null; 7571 } 7572 7573 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 7574 cpr = mProviderMap.getProviderByClass(comp, userId); 7575 final boolean firstClass = cpr == null; 7576 if (firstClass) { 7577 try { 7578 ApplicationInfo ai = 7579 AppGlobals.getPackageManager(). 7580 getApplicationInfo( 7581 cpi.applicationInfo.packageName, 7582 STOCK_PM_FLAGS, userId); 7583 if (ai == null) { 7584 Slog.w(TAG, "No package info for content provider " 7585 + cpi.name); 7586 return null; 7587 } 7588 ai = getAppInfoForUser(ai, userId); 7589 cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton); 7590 } catch (RemoteException ex) { 7591 // pm is in same process, this will never happen. 7592 } 7593 } 7594 7595 if (r != null && cpr.canRunHere(r)) { 7596 // If this is a multiprocess provider, then just return its 7597 // info and allow the caller to instantiate it. Only do 7598 // this if the provider is the same user as the caller's 7599 // process, or can run as root (so can be in any process). 7600 return cpr.newHolder(null); 7601 } 7602 7603 if (DEBUG_PROVIDER) { 7604 RuntimeException e = new RuntimeException("here"); 7605 Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null) 7606 + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e); 7607 } 7608 7609 // This is single process, and our app is now connecting to it. 7610 // See if we are already in the process of launching this 7611 // provider. 7612 final int N = mLaunchingProviders.size(); 7613 int i; 7614 for (i=0; i<N; i++) { 7615 if (mLaunchingProviders.get(i) == cpr) { 7616 break; 7617 } 7618 } 7619 7620 // If the provider is not already being launched, then get it 7621 // started. 7622 if (i >= N) { 7623 final long origId = Binder.clearCallingIdentity(); 7624 7625 try { 7626 // Content provider is now in use, its package can't be stopped. 7627 try { 7628 AppGlobals.getPackageManager().setPackageStoppedState( 7629 cpr.appInfo.packageName, false, userId); 7630 } catch (RemoteException e) { 7631 } catch (IllegalArgumentException e) { 7632 Slog.w(TAG, "Failed trying to unstop package " 7633 + cpr.appInfo.packageName + ": " + e); 7634 } 7635 7636 // Use existing process if already started 7637 ProcessRecord proc = getProcessRecordLocked( 7638 cpi.processName, cpr.appInfo.uid, false); 7639 if (proc != null && proc.thread != null) { 7640 if (DEBUG_PROVIDER) { 7641 Slog.d(TAG, "Installing in existing process " + proc); 7642 } 7643 proc.pubProviders.put(cpi.name, cpr); 7644 try { 7645 proc.thread.scheduleInstallProvider(cpi); 7646 } catch (RemoteException e) { 7647 } 7648 } else { 7649 proc = startProcessLocked(cpi.processName, 7650 cpr.appInfo, false, 0, "content provider", 7651 new ComponentName(cpi.applicationInfo.packageName, 7652 cpi.name), false, false, false); 7653 if (proc == null) { 7654 Slog.w(TAG, "Unable to launch app " 7655 + cpi.applicationInfo.packageName + "/" 7656 + cpi.applicationInfo.uid + " for provider " 7657 + name + ": process is bad"); 7658 return null; 7659 } 7660 } 7661 cpr.launchingApp = proc; 7662 mLaunchingProviders.add(cpr); 7663 } finally { 7664 Binder.restoreCallingIdentity(origId); 7665 } 7666 } 7667 7668 // Make sure the provider is published (the same provider class 7669 // may be published under multiple names). 7670 if (firstClass) { 7671 mProviderMap.putProviderByClass(comp, cpr); 7672 } 7673 7674 mProviderMap.putProviderByName(name, cpr); 7675 conn = incProviderCountLocked(r, cpr, token, stable); 7676 if (conn != null) { 7677 conn.waiting = true; 7678 } 7679 } 7680 } 7681 7682 // Wait for the provider to be published... 7683 synchronized (cpr) { 7684 while (cpr.provider == null) { 7685 if (cpr.launchingApp == null) { 7686 Slog.w(TAG, "Unable to launch app " 7687 + cpi.applicationInfo.packageName + "/" 7688 + cpi.applicationInfo.uid + " for provider " 7689 + name + ": launching app became null"); 7690 EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS, 7691 UserHandle.getUserId(cpi.applicationInfo.uid), 7692 cpi.applicationInfo.packageName, 7693 cpi.applicationInfo.uid, name); 7694 return null; 7695 } 7696 try { 7697 if (DEBUG_MU) { 7698 Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp=" 7699 + cpr.launchingApp); 7700 } 7701 if (conn != null) { 7702 conn.waiting = true; 7703 } 7704 cpr.wait(); 7705 } catch (InterruptedException ex) { 7706 } finally { 7707 if (conn != null) { 7708 conn.waiting = false; 7709 } 7710 } 7711 } 7712 } 7713 return cpr != null ? cpr.newHolder(conn) : null; 7714 } 7715 7716 public final ContentProviderHolder getContentProvider( 7717 IApplicationThread caller, String name, int userId, boolean stable) { 7718 enforceNotIsolatedCaller("getContentProvider"); 7719 if (caller == null) { 7720 String msg = "null IApplicationThread when getting content provider " 7721 + name; 7722 Slog.w(TAG, msg); 7723 throw new SecurityException(msg); 7724 } 7725 7726 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 7727 false, true, "getContentProvider", null); 7728 return getContentProviderImpl(caller, name, null, stable, userId); 7729 } 7730 7731 public ContentProviderHolder getContentProviderExternal( 7732 String name, int userId, IBinder token) { 7733 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 7734 "Do not have permission in call getContentProviderExternal()"); 7735 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 7736 false, true, "getContentProvider", null); 7737 return getContentProviderExternalUnchecked(name, token, userId); 7738 } 7739 7740 private ContentProviderHolder getContentProviderExternalUnchecked(String name, 7741 IBinder token, int userId) { 7742 return getContentProviderImpl(null, name, token, true, userId); 7743 } 7744 7745 /** 7746 * Drop a content provider from a ProcessRecord's bookkeeping 7747 */ 7748 public void removeContentProvider(IBinder connection, boolean stable) { 7749 enforceNotIsolatedCaller("removeContentProvider"); 7750 synchronized (this) { 7751 ContentProviderConnection conn; 7752 try { 7753 conn = (ContentProviderConnection)connection; 7754 } catch (ClassCastException e) { 7755 String msg ="removeContentProvider: " + connection 7756 + " not a ContentProviderConnection"; 7757 Slog.w(TAG, msg); 7758 throw new IllegalArgumentException(msg); 7759 } 7760 if (conn == null) { 7761 throw new NullPointerException("connection is null"); 7762 } 7763 if (decProviderCountLocked(conn, null, null, stable)) { 7764 updateOomAdjLocked(); 7765 } 7766 } 7767 } 7768 7769 public void removeContentProviderExternal(String name, IBinder token) { 7770 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 7771 "Do not have permission in call removeContentProviderExternal()"); 7772 removeContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId()); 7773 } 7774 7775 private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) { 7776 synchronized (this) { 7777 ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId); 7778 if(cpr == null) { 7779 //remove from mProvidersByClass 7780 if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list"); 7781 return; 7782 } 7783 7784 //update content provider record entry info 7785 ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name); 7786 ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId); 7787 if (localCpr.hasExternalProcessHandles()) { 7788 if (localCpr.removeExternalProcessHandleLocked(token)) { 7789 updateOomAdjLocked(); 7790 } else { 7791 Slog.e(TAG, "Attmpt to remove content provider " + localCpr 7792 + " with no external reference for token: " 7793 + token + "."); 7794 } 7795 } else { 7796 Slog.e(TAG, "Attmpt to remove content provider: " + localCpr 7797 + " with no external references."); 7798 } 7799 } 7800 } 7801 7802 public final void publishContentProviders(IApplicationThread caller, 7803 List<ContentProviderHolder> providers) { 7804 if (providers == null) { 7805 return; 7806 } 7807 7808 enforceNotIsolatedCaller("publishContentProviders"); 7809 synchronized (this) { 7810 final ProcessRecord r = getRecordForAppLocked(caller); 7811 if (DEBUG_MU) 7812 Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid); 7813 if (r == null) { 7814 throw new SecurityException( 7815 "Unable to find app for caller " + caller 7816 + " (pid=" + Binder.getCallingPid() 7817 + ") when publishing content providers"); 7818 } 7819 7820 final long origId = Binder.clearCallingIdentity(); 7821 7822 final int N = providers.size(); 7823 for (int i=0; i<N; i++) { 7824 ContentProviderHolder src = providers.get(i); 7825 if (src == null || src.info == null || src.provider == null) { 7826 continue; 7827 } 7828 ContentProviderRecord dst = r.pubProviders.get(src.info.name); 7829 if (DEBUG_MU) 7830 Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid); 7831 if (dst != null) { 7832 ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name); 7833 mProviderMap.putProviderByClass(comp, dst); 7834 String names[] = dst.info.authority.split(";"); 7835 for (int j = 0; j < names.length; j++) { 7836 mProviderMap.putProviderByName(names[j], dst); 7837 } 7838 7839 int NL = mLaunchingProviders.size(); 7840 int j; 7841 for (j=0; j<NL; j++) { 7842 if (mLaunchingProviders.get(j) == dst) { 7843 mLaunchingProviders.remove(j); 7844 j--; 7845 NL--; 7846 } 7847 } 7848 synchronized (dst) { 7849 dst.provider = src.provider; 7850 dst.proc = r; 7851 dst.notifyAll(); 7852 } 7853 updateOomAdjLocked(r); 7854 } 7855 } 7856 7857 Binder.restoreCallingIdentity(origId); 7858 } 7859 } 7860 7861 public boolean refContentProvider(IBinder connection, int stable, int unstable) { 7862 ContentProviderConnection conn; 7863 try { 7864 conn = (ContentProviderConnection)connection; 7865 } catch (ClassCastException e) { 7866 String msg ="refContentProvider: " + connection 7867 + " not a ContentProviderConnection"; 7868 Slog.w(TAG, msg); 7869 throw new IllegalArgumentException(msg); 7870 } 7871 if (conn == null) { 7872 throw new NullPointerException("connection is null"); 7873 } 7874 7875 synchronized (this) { 7876 if (stable > 0) { 7877 conn.numStableIncs += stable; 7878 } 7879 stable = conn.stableCount + stable; 7880 if (stable < 0) { 7881 throw new IllegalStateException("stableCount < 0: " + stable); 7882 } 7883 7884 if (unstable > 0) { 7885 conn.numUnstableIncs += unstable; 7886 } 7887 unstable = conn.unstableCount + unstable; 7888 if (unstable < 0) { 7889 throw new IllegalStateException("unstableCount < 0: " + unstable); 7890 } 7891 7892 if ((stable+unstable) <= 0) { 7893 throw new IllegalStateException("ref counts can't go to zero here: stable=" 7894 + stable + " unstable=" + unstable); 7895 } 7896 conn.stableCount = stable; 7897 conn.unstableCount = unstable; 7898 return !conn.dead; 7899 } 7900 } 7901 7902 public void unstableProviderDied(IBinder connection) { 7903 ContentProviderConnection conn; 7904 try { 7905 conn = (ContentProviderConnection)connection; 7906 } catch (ClassCastException e) { 7907 String msg ="refContentProvider: " + connection 7908 + " not a ContentProviderConnection"; 7909 Slog.w(TAG, msg); 7910 throw new IllegalArgumentException(msg); 7911 } 7912 if (conn == null) { 7913 throw new NullPointerException("connection is null"); 7914 } 7915 7916 // Safely retrieve the content provider associated with the connection. 7917 IContentProvider provider; 7918 synchronized (this) { 7919 provider = conn.provider.provider; 7920 } 7921 7922 if (provider == null) { 7923 // Um, yeah, we're way ahead of you. 7924 return; 7925 } 7926 7927 // Make sure the caller is being honest with us. 7928 if (provider.asBinder().pingBinder()) { 7929 // Er, no, still looks good to us. 7930 synchronized (this) { 7931 Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid() 7932 + " says " + conn + " died, but we don't agree"); 7933 return; 7934 } 7935 } 7936 7937 // Well look at that! It's dead! 7938 synchronized (this) { 7939 if (conn.provider.provider != provider) { 7940 // But something changed... good enough. 7941 return; 7942 } 7943 7944 ProcessRecord proc = conn.provider.proc; 7945 if (proc == null || proc.thread == null) { 7946 // Seems like the process is already cleaned up. 7947 return; 7948 } 7949 7950 // As far as we're concerned, this is just like receiving a 7951 // death notification... just a bit prematurely. 7952 Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid 7953 + ") early provider death"); 7954 final long ident = Binder.clearCallingIdentity(); 7955 try { 7956 appDiedLocked(proc, proc.pid, proc.thread); 7957 } finally { 7958 Binder.restoreCallingIdentity(ident); 7959 } 7960 } 7961 } 7962 7963 @Override 7964 public void appNotRespondingViaProvider(IBinder connection) { 7965 enforceCallingPermission( 7966 android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()"); 7967 7968 final ContentProviderConnection conn = (ContentProviderConnection) connection; 7969 if (conn == null) { 7970 Slog.w(TAG, "ContentProviderConnection is null"); 7971 return; 7972 } 7973 7974 final ProcessRecord host = conn.provider.proc; 7975 if (host == null) { 7976 Slog.w(TAG, "Failed to find hosting ProcessRecord"); 7977 return; 7978 } 7979 7980 final long token = Binder.clearCallingIdentity(); 7981 try { 7982 appNotResponding(host, null, null, false, "ContentProvider not responding"); 7983 } finally { 7984 Binder.restoreCallingIdentity(token); 7985 } 7986 } 7987 7988 public static final void installSystemProviders() { 7989 List<ProviderInfo> providers; 7990 synchronized (sSelf) { 7991 ProcessRecord app = sSelf.mProcessNames.get("system", Process.SYSTEM_UID); 7992 providers = sSelf.generateApplicationProvidersLocked(app); 7993 if (providers != null) { 7994 for (int i=providers.size()-1; i>=0; i--) { 7995 ProviderInfo pi = (ProviderInfo)providers.get(i); 7996 if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) { 7997 Slog.w(TAG, "Not installing system proc provider " + pi.name 7998 + ": not system .apk"); 7999 providers.remove(i); 8000 } 8001 } 8002 } 8003 } 8004 if (providers != null) { 8005 sSystemThread.installSystemProviders(providers); 8006 } 8007 8008 sSelf.mCoreSettingsObserver = new CoreSettingsObserver(sSelf); 8009 8010 sSelf.mUsageStatsService.monitorPackages(); 8011 } 8012 8013 /** 8014 * Allows app to retrieve the MIME type of a URI without having permission 8015 * to access its content provider. 8016 * 8017 * CTS tests for this functionality can be run with "runtest cts-appsecurity". 8018 * 8019 * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/ 8020 * src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java 8021 */ 8022 public String getProviderMimeType(Uri uri, int userId) { 8023 enforceNotIsolatedCaller("getProviderMimeType"); 8024 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 8025 userId, false, true, "getProviderMimeType", null); 8026 final String name = uri.getAuthority(); 8027 final long ident = Binder.clearCallingIdentity(); 8028 ContentProviderHolder holder = null; 8029 8030 try { 8031 holder = getContentProviderExternalUnchecked(name, null, userId); 8032 if (holder != null) { 8033 return holder.provider.getType(uri); 8034 } 8035 } catch (RemoteException e) { 8036 Log.w(TAG, "Content provider dead retrieving " + uri, e); 8037 return null; 8038 } finally { 8039 if (holder != null) { 8040 removeContentProviderExternalUnchecked(name, null, userId); 8041 } 8042 Binder.restoreCallingIdentity(ident); 8043 } 8044 8045 return null; 8046 } 8047 8048 // ========================================================= 8049 // GLOBAL MANAGEMENT 8050 // ========================================================= 8051 8052 final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess, 8053 boolean isolated) { 8054 String proc = customProcess != null ? customProcess : info.processName; 8055 BatteryStatsImpl.Uid.Proc ps = null; 8056 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 8057 int uid = info.uid; 8058 if (isolated) { 8059 int userId = UserHandle.getUserId(uid); 8060 int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1; 8061 while (true) { 8062 if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID 8063 || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) { 8064 mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID; 8065 } 8066 uid = UserHandle.getUid(userId, mNextIsolatedProcessUid); 8067 mNextIsolatedProcessUid++; 8068 if (mIsolatedProcesses.indexOfKey(uid) < 0) { 8069 // No process for this uid, use it. 8070 break; 8071 } 8072 stepsLeft--; 8073 if (stepsLeft <= 0) { 8074 return null; 8075 } 8076 } 8077 } 8078 return new ProcessRecord(stats, info, proc, uid); 8079 } 8080 8081 final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated) { 8082 ProcessRecord app; 8083 if (!isolated) { 8084 app = getProcessRecordLocked(info.processName, info.uid, true); 8085 } else { 8086 app = null; 8087 } 8088 8089 if (app == null) { 8090 app = newProcessRecordLocked(info, null, isolated); 8091 mProcessNames.put(info.processName, app.uid, app); 8092 if (isolated) { 8093 mIsolatedProcesses.put(app.uid, app); 8094 } 8095 updateLruProcessLocked(app, false, null); 8096 updateOomAdjLocked(); 8097 } 8098 8099 // This package really, really can not be stopped. 8100 try { 8101 AppGlobals.getPackageManager().setPackageStoppedState( 8102 info.packageName, false, UserHandle.getUserId(app.uid)); 8103 } catch (RemoteException e) { 8104 } catch (IllegalArgumentException e) { 8105 Slog.w(TAG, "Failed trying to unstop package " 8106 + info.packageName + ": " + e); 8107 } 8108 8109 if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) 8110 == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) { 8111 app.persistent = true; 8112 app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ; 8113 } 8114 if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) { 8115 mPersistentStartingProcesses.add(app); 8116 startProcessLocked(app, "added application", app.processName); 8117 } 8118 8119 return app; 8120 } 8121 8122 public void unhandledBack() { 8123 enforceCallingPermission(android.Manifest.permission.FORCE_BACK, 8124 "unhandledBack()"); 8125 8126 synchronized(this) { 8127 final long origId = Binder.clearCallingIdentity(); 8128 try { 8129 getFocusedStack().unhandledBackLocked(); 8130 } finally { 8131 Binder.restoreCallingIdentity(origId); 8132 } 8133 } 8134 } 8135 8136 public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException { 8137 enforceNotIsolatedCaller("openContentUri"); 8138 final int userId = UserHandle.getCallingUserId(); 8139 String name = uri.getAuthority(); 8140 ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId); 8141 ParcelFileDescriptor pfd = null; 8142 if (cph != null) { 8143 // We record the binder invoker's uid in thread-local storage before 8144 // going to the content provider to open the file. Later, in the code 8145 // that handles all permissions checks, we look for this uid and use 8146 // that rather than the Activity Manager's own uid. The effect is that 8147 // we do the check against the caller's permissions even though it looks 8148 // to the content provider like the Activity Manager itself is making 8149 // the request. 8150 sCallerIdentity.set(new Identity( 8151 Binder.getCallingPid(), Binder.getCallingUid())); 8152 try { 8153 pfd = cph.provider.openFile(null, uri, "r", null); 8154 } catch (FileNotFoundException e) { 8155 // do nothing; pfd will be returned null 8156 } finally { 8157 // Ensure that whatever happens, we clean up the identity state 8158 sCallerIdentity.remove(); 8159 } 8160 8161 // We've got the fd now, so we're done with the provider. 8162 removeContentProviderExternalUnchecked(name, null, userId); 8163 } else { 8164 Slog.d(TAG, "Failed to get provider for authority '" + name + "'"); 8165 } 8166 return pfd; 8167 } 8168 8169 // Actually is sleeping or shutting down or whatever else in the future 8170 // is an inactive state. 8171 public boolean isSleepingOrShuttingDown() { 8172 return mSleeping || mShuttingDown; 8173 } 8174 8175 public void goingToSleep() { 8176 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER) 8177 != PackageManager.PERMISSION_GRANTED) { 8178 throw new SecurityException("Requires permission " 8179 + android.Manifest.permission.DEVICE_POWER); 8180 } 8181 8182 synchronized(this) { 8183 mWentToSleep = true; 8184 updateEventDispatchingLocked(); 8185 8186 if (!mSleeping) { 8187 mSleeping = true; 8188 mStackSupervisor.goingToSleepLocked(); 8189 8190 // Initialize the wake times of all processes. 8191 checkExcessivePowerUsageLocked(false); 8192 mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 8193 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 8194 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 8195 } 8196 } 8197 } 8198 8199 @Override 8200 public boolean shutdown(int timeout) { 8201 if (checkCallingPermission(android.Manifest.permission.SHUTDOWN) 8202 != PackageManager.PERMISSION_GRANTED) { 8203 throw new SecurityException("Requires permission " 8204 + android.Manifest.permission.SHUTDOWN); 8205 } 8206 8207 boolean timedout = false; 8208 8209 synchronized(this) { 8210 mShuttingDown = true; 8211 updateEventDispatchingLocked(); 8212 timedout = mStackSupervisor.shutdownLocked(timeout); 8213 } 8214 8215 mAppOpsService.shutdown(); 8216 mUsageStatsService.shutdown(); 8217 mBatteryStatsService.shutdown(); 8218 synchronized (this) { 8219 mProcessStats.shutdownLocked(); 8220 } 8221 8222 return timedout; 8223 } 8224 8225 public final void activitySlept(IBinder token) { 8226 if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token); 8227 8228 final long origId = Binder.clearCallingIdentity(); 8229 8230 synchronized (this) { 8231 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 8232 if (r != null) { 8233 mStackSupervisor.activitySleptLocked(r); 8234 } 8235 } 8236 8237 Binder.restoreCallingIdentity(origId); 8238 } 8239 8240 void logLockScreen(String msg) { 8241 if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg + 8242 " mLockScreenShown=" + mLockScreenShown + " mWentToSleep=" + 8243 mWentToSleep + " mSleeping=" + mSleeping + " mDismissKeyguardOnNextActivity=" + 8244 mStackSupervisor.mDismissKeyguardOnNextActivity); 8245 } 8246 8247 private void comeOutOfSleepIfNeededLocked() { 8248 if (!mWentToSleep && !mLockScreenShown) { 8249 if (mSleeping) { 8250 mSleeping = false; 8251 mStackSupervisor.comeOutOfSleepIfNeededLocked(); 8252 } 8253 } 8254 } 8255 8256 public void wakingUp() { 8257 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER) 8258 != PackageManager.PERMISSION_GRANTED) { 8259 throw new SecurityException("Requires permission " 8260 + android.Manifest.permission.DEVICE_POWER); 8261 } 8262 8263 synchronized(this) { 8264 mWentToSleep = false; 8265 updateEventDispatchingLocked(); 8266 comeOutOfSleepIfNeededLocked(); 8267 } 8268 } 8269 8270 private void updateEventDispatchingLocked() { 8271 mWindowManager.setEventDispatching(mBooted && !mWentToSleep && !mShuttingDown); 8272 } 8273 8274 public void setLockScreenShown(boolean shown) { 8275 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER) 8276 != PackageManager.PERMISSION_GRANTED) { 8277 throw new SecurityException("Requires permission " 8278 + android.Manifest.permission.DEVICE_POWER); 8279 } 8280 8281 synchronized(this) { 8282 long ident = Binder.clearCallingIdentity(); 8283 try { 8284 if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown); 8285 mLockScreenShown = shown; 8286 comeOutOfSleepIfNeededLocked(); 8287 } finally { 8288 Binder.restoreCallingIdentity(ident); 8289 } 8290 } 8291 } 8292 8293 public void stopAppSwitches() { 8294 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 8295 != PackageManager.PERMISSION_GRANTED) { 8296 throw new SecurityException("Requires permission " 8297 + android.Manifest.permission.STOP_APP_SWITCHES); 8298 } 8299 8300 synchronized(this) { 8301 mAppSwitchesAllowedTime = SystemClock.uptimeMillis() 8302 + APP_SWITCH_DELAY_TIME; 8303 mDidAppSwitch = false; 8304 mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 8305 Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 8306 mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME); 8307 } 8308 } 8309 8310 public void resumeAppSwitches() { 8311 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 8312 != PackageManager.PERMISSION_GRANTED) { 8313 throw new SecurityException("Requires permission " 8314 + android.Manifest.permission.STOP_APP_SWITCHES); 8315 } 8316 8317 synchronized(this) { 8318 // Note that we don't execute any pending app switches... we will 8319 // let those wait until either the timeout, or the next start 8320 // activity request. 8321 mAppSwitchesAllowedTime = 0; 8322 } 8323 } 8324 8325 boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid, 8326 String name) { 8327 if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) { 8328 return true; 8329 } 8330 8331 final int perm = checkComponentPermission( 8332 android.Manifest.permission.STOP_APP_SWITCHES, callingPid, 8333 callingUid, -1, true); 8334 if (perm == PackageManager.PERMISSION_GRANTED) { 8335 return true; 8336 } 8337 8338 Slog.w(TAG, name + " request from " + callingUid + " stopped"); 8339 return false; 8340 } 8341 8342 public void setDebugApp(String packageName, boolean waitForDebugger, 8343 boolean persistent) { 8344 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP, 8345 "setDebugApp()"); 8346 8347 long ident = Binder.clearCallingIdentity(); 8348 try { 8349 // Note that this is not really thread safe if there are multiple 8350 // callers into it at the same time, but that's not a situation we 8351 // care about. 8352 if (persistent) { 8353 final ContentResolver resolver = mContext.getContentResolver(); 8354 Settings.Global.putString( 8355 resolver, Settings.Global.DEBUG_APP, 8356 packageName); 8357 Settings.Global.putInt( 8358 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 8359 waitForDebugger ? 1 : 0); 8360 } 8361 8362 synchronized (this) { 8363 if (!persistent) { 8364 mOrigDebugApp = mDebugApp; 8365 mOrigWaitForDebugger = mWaitForDebugger; 8366 } 8367 mDebugApp = packageName; 8368 mWaitForDebugger = waitForDebugger; 8369 mDebugTransient = !persistent; 8370 if (packageName != null) { 8371 forceStopPackageLocked(packageName, -1, false, false, true, true, 8372 false, UserHandle.USER_ALL, "set debug app"); 8373 } 8374 } 8375 } finally { 8376 Binder.restoreCallingIdentity(ident); 8377 } 8378 } 8379 8380 void setOpenGlTraceApp(ApplicationInfo app, String processName) { 8381 synchronized (this) { 8382 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 8383 if (!isDebuggable) { 8384 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 8385 throw new SecurityException("Process not debuggable: " + app.packageName); 8386 } 8387 } 8388 8389 mOpenGlTraceApp = processName; 8390 } 8391 } 8392 8393 void setProfileApp(ApplicationInfo app, String processName, String profileFile, 8394 ParcelFileDescriptor profileFd, boolean autoStopProfiler) { 8395 synchronized (this) { 8396 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 8397 if (!isDebuggable) { 8398 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 8399 throw new SecurityException("Process not debuggable: " + app.packageName); 8400 } 8401 } 8402 mProfileApp = processName; 8403 mProfileFile = profileFile; 8404 if (mProfileFd != null) { 8405 try { 8406 mProfileFd.close(); 8407 } catch (IOException e) { 8408 } 8409 mProfileFd = null; 8410 } 8411 mProfileFd = profileFd; 8412 mProfileType = 0; 8413 mAutoStopProfiler = autoStopProfiler; 8414 } 8415 } 8416 8417 @Override 8418 public void setAlwaysFinish(boolean enabled) { 8419 enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH, 8420 "setAlwaysFinish()"); 8421 8422 Settings.Global.putInt( 8423 mContext.getContentResolver(), 8424 Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0); 8425 8426 synchronized (this) { 8427 mAlwaysFinishActivities = enabled; 8428 } 8429 } 8430 8431 @Override 8432 public void setActivityController(IActivityController controller) { 8433 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 8434 "setActivityController()"); 8435 synchronized (this) { 8436 mController = controller; 8437 Watchdog.getInstance().setActivityController(controller); 8438 } 8439 } 8440 8441 @Override 8442 public void setUserIsMonkey(boolean userIsMonkey) { 8443 synchronized (this) { 8444 synchronized (mPidsSelfLocked) { 8445 final int callingPid = Binder.getCallingPid(); 8446 ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid); 8447 if (precessRecord == null) { 8448 throw new SecurityException("Unknown process: " + callingPid); 8449 } 8450 if (precessRecord.instrumentationUiAutomationConnection == null) { 8451 throw new SecurityException("Only an instrumentation process " 8452 + "with a UiAutomation can call setUserIsMonkey"); 8453 } 8454 } 8455 mUserIsMonkey = userIsMonkey; 8456 } 8457 } 8458 8459 @Override 8460 public boolean isUserAMonkey() { 8461 synchronized (this) { 8462 // If there is a controller also implies the user is a monkey. 8463 return (mUserIsMonkey || mController != null); 8464 } 8465 } 8466 8467 public void requestBugReport() { 8468 enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport"); 8469 SystemProperties.set("ctl.start", "bugreport"); 8470 } 8471 8472 public static long getInputDispatchingTimeoutLocked(ActivityRecord r) { 8473 return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT; 8474 } 8475 8476 public static long getInputDispatchingTimeoutLocked(ProcessRecord r) { 8477 if (r != null && (r.instrumentationClass != null || r.usingWrapper)) { 8478 return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT; 8479 } 8480 return KEY_DISPATCHING_TIMEOUT; 8481 } 8482 8483 @Override 8484 public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) { 8485 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS) 8486 != PackageManager.PERMISSION_GRANTED) { 8487 throw new SecurityException("Requires permission " 8488 + android.Manifest.permission.FILTER_EVENTS); 8489 } 8490 ProcessRecord proc; 8491 long timeout; 8492 synchronized (this) { 8493 synchronized (mPidsSelfLocked) { 8494 proc = mPidsSelfLocked.get(pid); 8495 } 8496 timeout = getInputDispatchingTimeoutLocked(proc); 8497 } 8498 8499 if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) { 8500 return -1; 8501 } 8502 8503 return timeout; 8504 } 8505 8506 /** 8507 * Handle input dispatching timeouts. 8508 * Returns whether input dispatching should be aborted or not. 8509 */ 8510 public boolean inputDispatchingTimedOut(final ProcessRecord proc, 8511 final ActivityRecord activity, final ActivityRecord parent, 8512 final boolean aboveSystem, String reason) { 8513 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS) 8514 != PackageManager.PERMISSION_GRANTED) { 8515 throw new SecurityException("Requires permission " 8516 + android.Manifest.permission.FILTER_EVENTS); 8517 } 8518 8519 final String annotation; 8520 if (reason == null) { 8521 annotation = "Input dispatching timed out"; 8522 } else { 8523 annotation = "Input dispatching timed out (" + reason + ")"; 8524 } 8525 8526 if (proc != null) { 8527 synchronized (this) { 8528 if (proc.debugging) { 8529 return false; 8530 } 8531 8532 if (mDidDexOpt) { 8533 // Give more time since we were dexopting. 8534 mDidDexOpt = false; 8535 return false; 8536 } 8537 8538 if (proc.instrumentationClass != null) { 8539 Bundle info = new Bundle(); 8540 info.putString("shortMsg", "keyDispatchingTimedOut"); 8541 info.putString("longMsg", annotation); 8542 finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info); 8543 return true; 8544 } 8545 } 8546 mHandler.post(new Runnable() { 8547 @Override 8548 public void run() { 8549 appNotResponding(proc, activity, parent, aboveSystem, annotation); 8550 } 8551 }); 8552 } 8553 8554 return true; 8555 } 8556 8557 public Bundle getAssistContextExtras(int requestType) { 8558 enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO, 8559 "getAssistContextExtras()"); 8560 PendingAssistExtras pae; 8561 Bundle extras = new Bundle(); 8562 synchronized (this) { 8563 ActivityRecord activity = getFocusedStack().mResumedActivity; 8564 if (activity == null) { 8565 Slog.w(TAG, "getAssistContextExtras failed: no resumed activity"); 8566 return null; 8567 } 8568 extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName); 8569 if (activity.app == null || activity.app.thread == null) { 8570 Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity); 8571 return extras; 8572 } 8573 if (activity.app.pid == Binder.getCallingPid()) { 8574 Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity); 8575 return extras; 8576 } 8577 pae = new PendingAssistExtras(activity); 8578 try { 8579 activity.app.thread.requestAssistContextExtras(activity.appToken, pae, 8580 requestType); 8581 mPendingAssistExtras.add(pae); 8582 mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT); 8583 } catch (RemoteException e) { 8584 Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity); 8585 return extras; 8586 } 8587 } 8588 synchronized (pae) { 8589 while (!pae.haveResult) { 8590 try { 8591 pae.wait(); 8592 } catch (InterruptedException e) { 8593 } 8594 } 8595 if (pae.result != null) { 8596 extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result); 8597 } 8598 } 8599 synchronized (this) { 8600 mPendingAssistExtras.remove(pae); 8601 mHandler.removeCallbacks(pae); 8602 } 8603 return extras; 8604 } 8605 8606 public void reportAssistContextExtras(IBinder token, Bundle extras) { 8607 PendingAssistExtras pae = (PendingAssistExtras)token; 8608 synchronized (pae) { 8609 pae.result = extras; 8610 pae.haveResult = true; 8611 pae.notifyAll(); 8612 } 8613 } 8614 8615 public void registerProcessObserver(IProcessObserver observer) { 8616 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 8617 "registerProcessObserver()"); 8618 synchronized (this) { 8619 mProcessObservers.register(observer); 8620 } 8621 } 8622 8623 @Override 8624 public void unregisterProcessObserver(IProcessObserver observer) { 8625 synchronized (this) { 8626 mProcessObservers.unregister(observer); 8627 } 8628 } 8629 8630 @Override 8631 public boolean convertFromTranslucent(IBinder token) { 8632 final long origId = Binder.clearCallingIdentity(); 8633 try { 8634 synchronized (this) { 8635 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 8636 if (r == null) { 8637 return false; 8638 } 8639 if (r.changeWindowTranslucency(true)) { 8640 mWindowManager.setAppFullscreen(token, true); 8641 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 8642 return true; 8643 } 8644 return false; 8645 } 8646 } finally { 8647 Binder.restoreCallingIdentity(origId); 8648 } 8649 } 8650 8651 @Override 8652 public boolean convertToTranslucent(IBinder token) { 8653 final long origId = Binder.clearCallingIdentity(); 8654 try { 8655 synchronized (this) { 8656 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 8657 if (r == null) { 8658 return false; 8659 } 8660 if (r.changeWindowTranslucency(false)) { 8661 r.task.stack.convertToTranslucent(r); 8662 mWindowManager.setAppFullscreen(token, false); 8663 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 8664 return true; 8665 } 8666 return false; 8667 } 8668 } finally { 8669 Binder.restoreCallingIdentity(origId); 8670 } 8671 } 8672 8673 @Override 8674 public void setImmersive(IBinder token, boolean immersive) { 8675 synchronized(this) { 8676 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 8677 if (r == null) { 8678 throw new IllegalArgumentException(); 8679 } 8680 r.immersive = immersive; 8681 8682 // update associated state if we're frontmost 8683 if (r == mFocusedActivity) { 8684 if (DEBUG_IMMERSIVE) { 8685 Slog.d(TAG, "Frontmost changed immersion: "+ r); 8686 } 8687 applyUpdateLockStateLocked(r); 8688 } 8689 } 8690 } 8691 8692 @Override 8693 public boolean isImmersive(IBinder token) { 8694 synchronized (this) { 8695 ActivityRecord r = ActivityRecord.isInStackLocked(token); 8696 if (r == null) { 8697 throw new IllegalArgumentException(); 8698 } 8699 return r.immersive; 8700 } 8701 } 8702 8703 public boolean isTopActivityImmersive() { 8704 enforceNotIsolatedCaller("startActivity"); 8705 synchronized (this) { 8706 ActivityRecord r = getFocusedStack().topRunningActivityLocked(null); 8707 return (r != null) ? r.immersive : false; 8708 } 8709 } 8710 8711 public final void enterSafeMode() { 8712 synchronized(this) { 8713 // It only makes sense to do this before the system is ready 8714 // and started launching other packages. 8715 if (!mSystemReady) { 8716 try { 8717 AppGlobals.getPackageManager().enterSafeMode(); 8718 } catch (RemoteException e) { 8719 } 8720 } 8721 } 8722 } 8723 8724 public final void showSafeModeOverlay() { 8725 View v = LayoutInflater.from(mContext).inflate( 8726 com.android.internal.R.layout.safe_mode, null); 8727 WindowManager.LayoutParams lp = new WindowManager.LayoutParams(); 8728 lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY; 8729 lp.width = WindowManager.LayoutParams.WRAP_CONTENT; 8730 lp.height = WindowManager.LayoutParams.WRAP_CONTENT; 8731 lp.gravity = Gravity.BOTTOM | Gravity.START; 8732 lp.format = v.getBackground().getOpacity(); 8733 lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE 8734 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE; 8735 lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS; 8736 ((WindowManager)mContext.getSystemService( 8737 Context.WINDOW_SERVICE)).addView(v, lp); 8738 } 8739 8740 public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) { 8741 if (!(sender instanceof PendingIntentRecord)) { 8742 return; 8743 } 8744 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 8745 synchronized (stats) { 8746 if (mBatteryStatsService.isOnBattery()) { 8747 mBatteryStatsService.enforceCallingPermission(); 8748 PendingIntentRecord rec = (PendingIntentRecord)sender; 8749 int MY_UID = Binder.getCallingUid(); 8750 int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid; 8751 BatteryStatsImpl.Uid.Pkg pkg = 8752 stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid, 8753 sourcePkg != null ? sourcePkg : rec.key.packageName); 8754 pkg.incWakeupsLocked(); 8755 } 8756 } 8757 } 8758 8759 public boolean killPids(int[] pids, String pReason, boolean secure) { 8760 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 8761 throw new SecurityException("killPids only available to the system"); 8762 } 8763 String reason = (pReason == null) ? "Unknown" : pReason; 8764 // XXX Note: don't acquire main activity lock here, because the window 8765 // manager calls in with its locks held. 8766 8767 boolean killed = false; 8768 synchronized (mPidsSelfLocked) { 8769 int[] types = new int[pids.length]; 8770 int worstType = 0; 8771 for (int i=0; i<pids.length; i++) { 8772 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 8773 if (proc != null) { 8774 int type = proc.setAdj; 8775 types[i] = type; 8776 if (type > worstType) { 8777 worstType = type; 8778 } 8779 } 8780 } 8781 8782 // If the worst oom_adj is somewhere in the cached proc LRU range, 8783 // then constrain it so we will kill all cached procs. 8784 if (worstType < ProcessList.CACHED_APP_MAX_ADJ 8785 && worstType > ProcessList.CACHED_APP_MIN_ADJ) { 8786 worstType = ProcessList.CACHED_APP_MIN_ADJ; 8787 } 8788 8789 // If this is not a secure call, don't let it kill processes that 8790 // are important. 8791 if (!secure && worstType < ProcessList.SERVICE_ADJ) { 8792 worstType = ProcessList.SERVICE_ADJ; 8793 } 8794 8795 Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType); 8796 for (int i=0; i<pids.length; i++) { 8797 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 8798 if (proc == null) { 8799 continue; 8800 } 8801 int adj = proc.setAdj; 8802 if (adj >= worstType && !proc.killedByAm) { 8803 killUnneededProcessLocked(proc, reason); 8804 killed = true; 8805 } 8806 } 8807 } 8808 return killed; 8809 } 8810 8811 @Override 8812 public void killUid(int uid, String reason) { 8813 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 8814 throw new SecurityException("killUid only available to the system"); 8815 } 8816 synchronized (this) { 8817 killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid), 8818 ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false, 8819 reason != null ? reason : "kill uid"); 8820 } 8821 } 8822 8823 @Override 8824 public boolean killProcessesBelowForeground(String reason) { 8825 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 8826 throw new SecurityException("killProcessesBelowForeground() only available to system"); 8827 } 8828 8829 return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason); 8830 } 8831 8832 private boolean killProcessesBelowAdj(int belowAdj, String reason) { 8833 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 8834 throw new SecurityException("killProcessesBelowAdj() only available to system"); 8835 } 8836 8837 boolean killed = false; 8838 synchronized (mPidsSelfLocked) { 8839 final int size = mPidsSelfLocked.size(); 8840 for (int i = 0; i < size; i++) { 8841 final int pid = mPidsSelfLocked.keyAt(i); 8842 final ProcessRecord proc = mPidsSelfLocked.valueAt(i); 8843 if (proc == null) continue; 8844 8845 final int adj = proc.setAdj; 8846 if (adj > belowAdj && !proc.killedByAm) { 8847 killUnneededProcessLocked(proc, reason); 8848 killed = true; 8849 } 8850 } 8851 } 8852 return killed; 8853 } 8854 8855 @Override 8856 public void hang(final IBinder who, boolean allowRestart) { 8857 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 8858 != PackageManager.PERMISSION_GRANTED) { 8859 throw new SecurityException("Requires permission " 8860 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 8861 } 8862 8863 final IBinder.DeathRecipient death = new DeathRecipient() { 8864 @Override 8865 public void binderDied() { 8866 synchronized (this) { 8867 notifyAll(); 8868 } 8869 } 8870 }; 8871 8872 try { 8873 who.linkToDeath(death, 0); 8874 } catch (RemoteException e) { 8875 Slog.w(TAG, "hang: given caller IBinder is already dead."); 8876 return; 8877 } 8878 8879 synchronized (this) { 8880 Watchdog.getInstance().setAllowRestart(allowRestart); 8881 Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid()); 8882 synchronized (death) { 8883 while (who.isBinderAlive()) { 8884 try { 8885 death.wait(); 8886 } catch (InterruptedException e) { 8887 } 8888 } 8889 } 8890 Watchdog.getInstance().setAllowRestart(true); 8891 } 8892 } 8893 8894 @Override 8895 public void restart() { 8896 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 8897 != PackageManager.PERMISSION_GRANTED) { 8898 throw new SecurityException("Requires permission " 8899 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 8900 } 8901 8902 Log.i(TAG, "Sending shutdown broadcast..."); 8903 8904 BroadcastReceiver br = new BroadcastReceiver() { 8905 @Override public void onReceive(Context context, Intent intent) { 8906 // Now the broadcast is done, finish up the low-level shutdown. 8907 Log.i(TAG, "Shutting down activity manager..."); 8908 shutdown(10000); 8909 Log.i(TAG, "Shutdown complete, restarting!"); 8910 Process.killProcess(Process.myPid()); 8911 System.exit(10); 8912 } 8913 }; 8914 8915 // First send the high-level shut down broadcast. 8916 Intent intent = new Intent(Intent.ACTION_SHUTDOWN); 8917 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 8918 intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true); 8919 /* For now we are not doing a clean shutdown, because things seem to get unhappy. 8920 mContext.sendOrderedBroadcastAsUser(intent, 8921 UserHandle.ALL, null, br, mHandler, 0, null, null); 8922 */ 8923 br.onReceive(mContext, intent); 8924 } 8925 8926 private long getLowRamTimeSinceIdle(long now) { 8927 return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0); 8928 } 8929 8930 @Override 8931 public void performIdleMaintenance() { 8932 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 8933 != PackageManager.PERMISSION_GRANTED) { 8934 throw new SecurityException("Requires permission " 8935 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 8936 } 8937 8938 synchronized (this) { 8939 final long now = SystemClock.uptimeMillis(); 8940 final long timeSinceLastIdle = now - mLastIdleTime; 8941 final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now); 8942 mLastIdleTime = now; 8943 mLowRamTimeSinceLastIdle = 0; 8944 if (mLowRamStartTime != 0) { 8945 mLowRamStartTime = now; 8946 } 8947 8948 StringBuilder sb = new StringBuilder(128); 8949 sb.append("Idle maintenance over "); 8950 TimeUtils.formatDuration(timeSinceLastIdle, sb); 8951 sb.append(" low RAM for "); 8952 TimeUtils.formatDuration(lowRamSinceLastIdle, sb); 8953 Slog.i(TAG, sb.toString()); 8954 8955 // If at least 1/3 of our time since the last idle period has been spent 8956 // with RAM low, then we want to kill processes. 8957 boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3); 8958 8959 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 8960 ProcessRecord proc = mLruProcesses.get(i); 8961 if (proc.notCachedSinceIdle) { 8962 if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP 8963 && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) { 8964 if (doKilling && proc.initialIdlePss != 0 8965 && proc.lastPss > ((proc.initialIdlePss*3)/2)) { 8966 killUnneededProcessLocked(proc, "idle maint (pss " + proc.lastPss 8967 + " from " + proc.initialIdlePss + ")"); 8968 } 8969 } 8970 } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) { 8971 proc.notCachedSinceIdle = true; 8972 proc.initialIdlePss = 0; 8973 proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true, 8974 mSleeping, now); 8975 } 8976 } 8977 8978 mHandler.removeMessages(REQUEST_ALL_PSS_MSG); 8979 mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000); 8980 } 8981 } 8982 8983 public final void startRunning(String pkg, String cls, String action, 8984 String data) { 8985 synchronized(this) { 8986 if (mStartRunning) { 8987 return; 8988 } 8989 mStartRunning = true; 8990 mTopComponent = pkg != null && cls != null 8991 ? new ComponentName(pkg, cls) : null; 8992 mTopAction = action != null ? action : Intent.ACTION_MAIN; 8993 mTopData = data; 8994 if (!mSystemReady) { 8995 return; 8996 } 8997 } 8998 8999 systemReady(null); 9000 } 9001 9002 private void retrieveSettings() { 9003 final ContentResolver resolver = mContext.getContentResolver(); 9004 String debugApp = Settings.Global.getString( 9005 resolver, Settings.Global.DEBUG_APP); 9006 boolean waitForDebugger = Settings.Global.getInt( 9007 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0; 9008 boolean alwaysFinishActivities = Settings.Global.getInt( 9009 resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0; 9010 boolean forceRtl = Settings.Global.getInt( 9011 resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0; 9012 // Transfer any global setting for forcing RTL layout, into a System Property 9013 SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0"); 9014 9015 Configuration configuration = new Configuration(); 9016 Settings.System.getConfiguration(resolver, configuration); 9017 if (forceRtl) { 9018 // This will take care of setting the correct layout direction flags 9019 configuration.setLayoutDirection(configuration.locale); 9020 } 9021 9022 synchronized (this) { 9023 mDebugApp = mOrigDebugApp = debugApp; 9024 mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger; 9025 mAlwaysFinishActivities = alwaysFinishActivities; 9026 // This happens before any activities are started, so we can 9027 // change mConfiguration in-place. 9028 updateConfigurationLocked(configuration, null, false, true); 9029 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration); 9030 } 9031 } 9032 9033 public boolean testIsSystemReady() { 9034 // no need to synchronize(this) just to read & return the value 9035 return mSystemReady; 9036 } 9037 9038 private static File getCalledPreBootReceiversFile() { 9039 File dataDir = Environment.getDataDirectory(); 9040 File systemDir = new File(dataDir, "system"); 9041 File fname = new File(systemDir, "called_pre_boots.dat"); 9042 return fname; 9043 } 9044 9045 static final int LAST_DONE_VERSION = 10000; 9046 9047 private static ArrayList<ComponentName> readLastDonePreBootReceivers() { 9048 ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>(); 9049 File file = getCalledPreBootReceiversFile(); 9050 FileInputStream fis = null; 9051 try { 9052 fis = new FileInputStream(file); 9053 DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048)); 9054 int fvers = dis.readInt(); 9055 if (fvers == LAST_DONE_VERSION) { 9056 String vers = dis.readUTF(); 9057 String codename = dis.readUTF(); 9058 String build = dis.readUTF(); 9059 if (android.os.Build.VERSION.RELEASE.equals(vers) 9060 && android.os.Build.VERSION.CODENAME.equals(codename) 9061 && android.os.Build.VERSION.INCREMENTAL.equals(build)) { 9062 int num = dis.readInt(); 9063 while (num > 0) { 9064 num--; 9065 String pkg = dis.readUTF(); 9066 String cls = dis.readUTF(); 9067 lastDoneReceivers.add(new ComponentName(pkg, cls)); 9068 } 9069 } 9070 } 9071 } catch (FileNotFoundException e) { 9072 } catch (IOException e) { 9073 Slog.w(TAG, "Failure reading last done pre-boot receivers", e); 9074 } finally { 9075 if (fis != null) { 9076 try { 9077 fis.close(); 9078 } catch (IOException e) { 9079 } 9080 } 9081 } 9082 return lastDoneReceivers; 9083 } 9084 9085 private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) { 9086 File file = getCalledPreBootReceiversFile(); 9087 FileOutputStream fos = null; 9088 DataOutputStream dos = null; 9089 try { 9090 Slog.i(TAG, "Writing new set of last done pre-boot receivers..."); 9091 fos = new FileOutputStream(file); 9092 dos = new DataOutputStream(new BufferedOutputStream(fos, 2048)); 9093 dos.writeInt(LAST_DONE_VERSION); 9094 dos.writeUTF(android.os.Build.VERSION.RELEASE); 9095 dos.writeUTF(android.os.Build.VERSION.CODENAME); 9096 dos.writeUTF(android.os.Build.VERSION.INCREMENTAL); 9097 dos.writeInt(list.size()); 9098 for (int i=0; i<list.size(); i++) { 9099 dos.writeUTF(list.get(i).getPackageName()); 9100 dos.writeUTF(list.get(i).getClassName()); 9101 } 9102 } catch (IOException e) { 9103 Slog.w(TAG, "Failure writing last done pre-boot receivers", e); 9104 file.delete(); 9105 } finally { 9106 FileUtils.sync(fos); 9107 if (dos != null) { 9108 try { 9109 dos.close(); 9110 } catch (IOException e) { 9111 // TODO Auto-generated catch block 9112 e.printStackTrace(); 9113 } 9114 } 9115 } 9116 } 9117 9118 public void systemReady(final Runnable goingCallback) { 9119 synchronized(this) { 9120 if (mSystemReady) { 9121 if (goingCallback != null) goingCallback.run(); 9122 return; 9123 } 9124 9125 // Check to see if there are any update receivers to run. 9126 if (!mDidUpdate) { 9127 if (mWaitingUpdate) { 9128 return; 9129 } 9130 Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED); 9131 List<ResolveInfo> ris = null; 9132 try { 9133 ris = AppGlobals.getPackageManager().queryIntentReceivers( 9134 intent, null, 0, 0); 9135 } catch (RemoteException e) { 9136 } 9137 if (ris != null) { 9138 for (int i=ris.size()-1; i>=0; i--) { 9139 if ((ris.get(i).activityInfo.applicationInfo.flags 9140 &ApplicationInfo.FLAG_SYSTEM) == 0) { 9141 ris.remove(i); 9142 } 9143 } 9144 intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE); 9145 9146 ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers(); 9147 9148 final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>(); 9149 for (int i=0; i<ris.size(); i++) { 9150 ActivityInfo ai = ris.get(i).activityInfo; 9151 ComponentName comp = new ComponentName(ai.packageName, ai.name); 9152 if (lastDoneReceivers.contains(comp)) { 9153 ris.remove(i); 9154 i--; 9155 } 9156 } 9157 9158 final int[] users = getUsersLocked(); 9159 for (int i=0; i<ris.size(); i++) { 9160 ActivityInfo ai = ris.get(i).activityInfo; 9161 ComponentName comp = new ComponentName(ai.packageName, ai.name); 9162 doneReceivers.add(comp); 9163 intent.setComponent(comp); 9164 for (int j=0; j<users.length; j++) { 9165 IIntentReceiver finisher = null; 9166 if (i == ris.size()-1 && j == users.length-1) { 9167 finisher = new IIntentReceiver.Stub() { 9168 public void performReceive(Intent intent, int resultCode, 9169 String data, Bundle extras, boolean ordered, 9170 boolean sticky, int sendingUser) { 9171 // The raw IIntentReceiver interface is called 9172 // with the AM lock held, so redispatch to 9173 // execute our code without the lock. 9174 mHandler.post(new Runnable() { 9175 public void run() { 9176 synchronized (ActivityManagerService.this) { 9177 mDidUpdate = true; 9178 } 9179 writeLastDonePreBootReceivers(doneReceivers); 9180 showBootMessage(mContext.getText( 9181 R.string.android_upgrading_complete), 9182 false); 9183 systemReady(goingCallback); 9184 } 9185 }); 9186 } 9187 }; 9188 } 9189 Slog.i(TAG, "Sending system update to " + intent.getComponent() 9190 + " for user " + users[j]); 9191 broadcastIntentLocked(null, null, intent, null, finisher, 9192 0, null, null, null, AppOpsManager.OP_NONE, 9193 true, false, MY_PID, Process.SYSTEM_UID, 9194 users[j]); 9195 if (finisher != null) { 9196 mWaitingUpdate = true; 9197 } 9198 } 9199 } 9200 } 9201 if (mWaitingUpdate) { 9202 return; 9203 } 9204 mDidUpdate = true; 9205 } 9206 9207 mAppOpsService.systemReady(); 9208 mSystemReady = true; 9209 if (!mStartRunning) { 9210 return; 9211 } 9212 } 9213 9214 ArrayList<ProcessRecord> procsToKill = null; 9215 synchronized(mPidsSelfLocked) { 9216 for (int i=mPidsSelfLocked.size()-1; i>=0; i--) { 9217 ProcessRecord proc = mPidsSelfLocked.valueAt(i); 9218 if (!isAllowedWhileBooting(proc.info)){ 9219 if (procsToKill == null) { 9220 procsToKill = new ArrayList<ProcessRecord>(); 9221 } 9222 procsToKill.add(proc); 9223 } 9224 } 9225 } 9226 9227 synchronized(this) { 9228 if (procsToKill != null) { 9229 for (int i=procsToKill.size()-1; i>=0; i--) { 9230 ProcessRecord proc = procsToKill.get(i); 9231 Slog.i(TAG, "Removing system update proc: " + proc); 9232 removeProcessLocked(proc, true, false, "system update done"); 9233 } 9234 } 9235 9236 // Now that we have cleaned up any update processes, we 9237 // are ready to start launching real processes and know that 9238 // we won't trample on them any more. 9239 mProcessesReady = true; 9240 } 9241 9242 Slog.i(TAG, "System now ready"); 9243 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY, 9244 SystemClock.uptimeMillis()); 9245 9246 synchronized(this) { 9247 // Make sure we have no pre-ready processes sitting around. 9248 9249 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) { 9250 ResolveInfo ri = mContext.getPackageManager() 9251 .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST), 9252 STOCK_PM_FLAGS); 9253 CharSequence errorMsg = null; 9254 if (ri != null) { 9255 ActivityInfo ai = ri.activityInfo; 9256 ApplicationInfo app = ai.applicationInfo; 9257 if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) { 9258 mTopAction = Intent.ACTION_FACTORY_TEST; 9259 mTopData = null; 9260 mTopComponent = new ComponentName(app.packageName, 9261 ai.name); 9262 } else { 9263 errorMsg = mContext.getResources().getText( 9264 com.android.internal.R.string.factorytest_not_system); 9265 } 9266 } else { 9267 errorMsg = mContext.getResources().getText( 9268 com.android.internal.R.string.factorytest_no_action); 9269 } 9270 if (errorMsg != null) { 9271 mTopAction = null; 9272 mTopData = null; 9273 mTopComponent = null; 9274 Message msg = Message.obtain(); 9275 msg.what = SHOW_FACTORY_ERROR_MSG; 9276 msg.getData().putCharSequence("msg", errorMsg); 9277 mHandler.sendMessage(msg); 9278 } 9279 } 9280 } 9281 9282 retrieveSettings(); 9283 9284 synchronized (this) { 9285 readGrantedUriPermissionsLocked(); 9286 } 9287 9288 if (goingCallback != null) goingCallback.run(); 9289 9290 synchronized (this) { 9291 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 9292 try { 9293 List apps = AppGlobals.getPackageManager(). 9294 getPersistentApplications(STOCK_PM_FLAGS); 9295 if (apps != null) { 9296 int N = apps.size(); 9297 int i; 9298 for (i=0; i<N; i++) { 9299 ApplicationInfo info 9300 = (ApplicationInfo)apps.get(i); 9301 if (info != null && 9302 !info.packageName.equals("android")) { 9303 addAppLocked(info, false); 9304 } 9305 } 9306 } 9307 } catch (RemoteException ex) { 9308 // pm is in same process, this will never happen. 9309 } 9310 } 9311 9312 // Start up initial activity. 9313 mBooting = true; 9314 9315 try { 9316 if (AppGlobals.getPackageManager().hasSystemUidErrors()) { 9317 Message msg = Message.obtain(); 9318 msg.what = SHOW_UID_ERROR_MSG; 9319 mHandler.sendMessage(msg); 9320 } 9321 } catch (RemoteException e) { 9322 } 9323 9324 long ident = Binder.clearCallingIdentity(); 9325 try { 9326 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 9327 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 9328 | Intent.FLAG_RECEIVER_FOREGROUND); 9329 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); 9330 broadcastIntentLocked(null, null, intent, 9331 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 9332 false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId); 9333 intent = new Intent(Intent.ACTION_USER_STARTING); 9334 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 9335 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); 9336 broadcastIntentLocked(null, null, intent, 9337 null, new IIntentReceiver.Stub() { 9338 @Override 9339 public void performReceive(Intent intent, int resultCode, String data, 9340 Bundle extras, boolean ordered, boolean sticky, int sendingUser) 9341 throws RemoteException { 9342 } 9343 }, 0, null, null, 9344 android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 9345 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 9346 } finally { 9347 Binder.restoreCallingIdentity(ident); 9348 } 9349 mStackSupervisor.resumeTopActivitiesLocked(); 9350 sendUserSwitchBroadcastsLocked(-1, mCurrentUserId); 9351 } 9352 } 9353 9354 private boolean makeAppCrashingLocked(ProcessRecord app, 9355 String shortMsg, String longMsg, String stackTrace) { 9356 app.crashing = true; 9357 app.crashingReport = generateProcessError(app, 9358 ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace); 9359 startAppProblemLocked(app); 9360 app.stopFreezingAllLocked(); 9361 return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace); 9362 } 9363 9364 private void makeAppNotRespondingLocked(ProcessRecord app, 9365 String activity, String shortMsg, String longMsg) { 9366 app.notResponding = true; 9367 app.notRespondingReport = generateProcessError(app, 9368 ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING, 9369 activity, shortMsg, longMsg, null); 9370 startAppProblemLocked(app); 9371 app.stopFreezingAllLocked(); 9372 } 9373 9374 /** 9375 * Generate a process error record, suitable for attachment to a ProcessRecord. 9376 * 9377 * @param app The ProcessRecord in which the error occurred. 9378 * @param condition Crashing, Application Not Responding, etc. Values are defined in 9379 * ActivityManager.AppErrorStateInfo 9380 * @param activity The activity associated with the crash, if known. 9381 * @param shortMsg Short message describing the crash. 9382 * @param longMsg Long message describing the crash. 9383 * @param stackTrace Full crash stack trace, may be null. 9384 * 9385 * @return Returns a fully-formed AppErrorStateInfo record. 9386 */ 9387 private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app, 9388 int condition, String activity, String shortMsg, String longMsg, String stackTrace) { 9389 ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo(); 9390 9391 report.condition = condition; 9392 report.processName = app.processName; 9393 report.pid = app.pid; 9394 report.uid = app.info.uid; 9395 report.tag = activity; 9396 report.shortMsg = shortMsg; 9397 report.longMsg = longMsg; 9398 report.stackTrace = stackTrace; 9399 9400 return report; 9401 } 9402 9403 void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) { 9404 synchronized (this) { 9405 app.crashing = false; 9406 app.crashingReport = null; 9407 app.notResponding = false; 9408 app.notRespondingReport = null; 9409 if (app.anrDialog == fromDialog) { 9410 app.anrDialog = null; 9411 } 9412 if (app.waitDialog == fromDialog) { 9413 app.waitDialog = null; 9414 } 9415 if (app.pid > 0 && app.pid != MY_PID) { 9416 handleAppCrashLocked(app, null, null, null); 9417 killUnneededProcessLocked(app, "user request after error"); 9418 } 9419 } 9420 } 9421 9422 private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg, 9423 String stackTrace) { 9424 long now = SystemClock.uptimeMillis(); 9425 9426 Long crashTime; 9427 if (!app.isolated) { 9428 crashTime = mProcessCrashTimes.get(app.info.processName, app.uid); 9429 } else { 9430 crashTime = null; 9431 } 9432 if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) { 9433 // This process loses! 9434 Slog.w(TAG, "Process " + app.info.processName 9435 + " has crashed too many times: killing!"); 9436 EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH, 9437 app.userId, app.info.processName, app.uid); 9438 mStackSupervisor.handleAppCrashLocked(app); 9439 if (!app.persistent) { 9440 // We don't want to start this process again until the user 9441 // explicitly does so... but for persistent process, we really 9442 // need to keep it running. If a persistent process is actually 9443 // repeatedly crashing, then badness for everyone. 9444 EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid, 9445 app.info.processName); 9446 if (!app.isolated) { 9447 // XXX We don't have a way to mark isolated processes 9448 // as bad, since they don't have a peristent identity. 9449 mBadProcesses.put(app.info.processName, app.uid, 9450 new BadProcessInfo(now, shortMsg, longMsg, stackTrace)); 9451 mProcessCrashTimes.remove(app.info.processName, app.uid); 9452 } 9453 app.bad = true; 9454 app.removed = true; 9455 // Don't let services in this process be restarted and potentially 9456 // annoy the user repeatedly. Unless it is persistent, since those 9457 // processes run critical code. 9458 removeProcessLocked(app, false, false, "crash"); 9459 mStackSupervisor.resumeTopActivitiesLocked(); 9460 return false; 9461 } 9462 mStackSupervisor.resumeTopActivitiesLocked(); 9463 } else { 9464 mStackSupervisor.finishTopRunningActivityLocked(app); 9465 } 9466 9467 // Bump up the crash count of any services currently running in the proc. 9468 for (int i=app.services.size()-1; i>=0; i--) { 9469 // Any services running in the application need to be placed 9470 // back in the pending list. 9471 ServiceRecord sr = app.services.valueAt(i); 9472 sr.crashCount++; 9473 } 9474 9475 // If the crashing process is what we consider to be the "home process" and it has been 9476 // replaced by a third-party app, clear the package preferred activities from packages 9477 // with a home activity running in the process to prevent a repeatedly crashing app 9478 // from blocking the user to manually clear the list. 9479 final ArrayList<ActivityRecord> activities = app.activities; 9480 if (app == mHomeProcess && activities.size() > 0 9481 && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) { 9482 for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) { 9483 final ActivityRecord r = activities.get(activityNdx); 9484 if (r.isHomeActivity()) { 9485 Log.i(TAG, "Clearing package preferred activities from " + r.packageName); 9486 try { 9487 ActivityThread.getPackageManager() 9488 .clearPackagePreferredActivities(r.packageName); 9489 } catch (RemoteException c) { 9490 // pm is in same process, this will never happen. 9491 } 9492 } 9493 } 9494 } 9495 9496 if (!app.isolated) { 9497 // XXX Can't keep track of crash times for isolated processes, 9498 // because they don't have a perisistent identity. 9499 mProcessCrashTimes.put(app.info.processName, app.uid, now); 9500 } 9501 9502 return true; 9503 } 9504 9505 void startAppProblemLocked(ProcessRecord app) { 9506 if (app.userId == mCurrentUserId) { 9507 app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver( 9508 mContext, app.info.packageName, app.info.flags); 9509 } else { 9510 // If this app is not running under the current user, then we 9511 // can't give it a report button because that would require 9512 // launching the report UI under a different user. 9513 app.errorReportReceiver = null; 9514 } 9515 skipCurrentReceiverLocked(app); 9516 } 9517 9518 void skipCurrentReceiverLocked(ProcessRecord app) { 9519 for (BroadcastQueue queue : mBroadcastQueues) { 9520 queue.skipCurrentReceiverLocked(app); 9521 } 9522 } 9523 9524 /** 9525 * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes. 9526 * The application process will exit immediately after this call returns. 9527 * @param app object of the crashing app, null for the system server 9528 * @param crashInfo describing the exception 9529 */ 9530 public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) { 9531 ProcessRecord r = findAppProcess(app, "Crash"); 9532 final String processName = app == null ? "system_server" 9533 : (r == null ? "unknown" : r.processName); 9534 9535 handleApplicationCrashInner("crash", r, processName, crashInfo); 9536 } 9537 9538 /* Native crash reporting uses this inner version because it needs to be somewhat 9539 * decoupled from the AM-managed cleanup lifecycle 9540 */ 9541 void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName, 9542 ApplicationErrorReport.CrashInfo crashInfo) { 9543 EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(), 9544 UserHandle.getUserId(Binder.getCallingUid()), processName, 9545 r == null ? -1 : r.info.flags, 9546 crashInfo.exceptionClassName, 9547 crashInfo.exceptionMessage, 9548 crashInfo.throwFileName, 9549 crashInfo.throwLineNumber); 9550 9551 addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo); 9552 9553 crashApplication(r, crashInfo); 9554 } 9555 9556 public void handleApplicationStrictModeViolation( 9557 IBinder app, 9558 int violationMask, 9559 StrictMode.ViolationInfo info) { 9560 ProcessRecord r = findAppProcess(app, "StrictMode"); 9561 if (r == null) { 9562 return; 9563 } 9564 9565 if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) { 9566 Integer stackFingerprint = info.hashCode(); 9567 boolean logIt = true; 9568 synchronized (mAlreadyLoggedViolatedStacks) { 9569 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) { 9570 logIt = false; 9571 // TODO: sub-sample into EventLog for these, with 9572 // the info.durationMillis? Then we'd get 9573 // the relative pain numbers, without logging all 9574 // the stack traces repeatedly. We'd want to do 9575 // likewise in the client code, which also does 9576 // dup suppression, before the Binder call. 9577 } else { 9578 if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) { 9579 mAlreadyLoggedViolatedStacks.clear(); 9580 } 9581 mAlreadyLoggedViolatedStacks.add(stackFingerprint); 9582 } 9583 } 9584 if (logIt) { 9585 logStrictModeViolationToDropBox(r, info); 9586 } 9587 } 9588 9589 if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) { 9590 AppErrorResult result = new AppErrorResult(); 9591 synchronized (this) { 9592 final long origId = Binder.clearCallingIdentity(); 9593 9594 Message msg = Message.obtain(); 9595 msg.what = SHOW_STRICT_MODE_VIOLATION_MSG; 9596 HashMap<String, Object> data = new HashMap<String, Object>(); 9597 data.put("result", result); 9598 data.put("app", r); 9599 data.put("violationMask", violationMask); 9600 data.put("info", info); 9601 msg.obj = data; 9602 mHandler.sendMessage(msg); 9603 9604 Binder.restoreCallingIdentity(origId); 9605 } 9606 int res = result.get(); 9607 Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res); 9608 } 9609 } 9610 9611 // Depending on the policy in effect, there could be a bunch of 9612 // these in quick succession so we try to batch these together to 9613 // minimize disk writes, number of dropbox entries, and maximize 9614 // compression, by having more fewer, larger records. 9615 private void logStrictModeViolationToDropBox( 9616 ProcessRecord process, 9617 StrictMode.ViolationInfo info) { 9618 if (info == null) { 9619 return; 9620 } 9621 final boolean isSystemApp = process == null || 9622 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM | 9623 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0; 9624 final String processName = process == null ? "unknown" : process.processName; 9625 final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode"; 9626 final DropBoxManager dbox = (DropBoxManager) 9627 mContext.getSystemService(Context.DROPBOX_SERVICE); 9628 9629 // Exit early if the dropbox isn't configured to accept this report type. 9630 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 9631 9632 boolean bufferWasEmpty; 9633 boolean needsFlush; 9634 final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024); 9635 synchronized (sb) { 9636 bufferWasEmpty = sb.length() == 0; 9637 appendDropBoxProcessHeaders(process, processName, sb); 9638 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 9639 sb.append("System-App: ").append(isSystemApp).append("\n"); 9640 sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n"); 9641 if (info.violationNumThisLoop != 0) { 9642 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n"); 9643 } 9644 if (info.numAnimationsRunning != 0) { 9645 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n"); 9646 } 9647 if (info.broadcastIntentAction != null) { 9648 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n"); 9649 } 9650 if (info.durationMillis != -1) { 9651 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n"); 9652 } 9653 if (info.numInstances != -1) { 9654 sb.append("Instance-Count: ").append(info.numInstances).append("\n"); 9655 } 9656 if (info.tags != null) { 9657 for (String tag : info.tags) { 9658 sb.append("Span-Tag: ").append(tag).append("\n"); 9659 } 9660 } 9661 sb.append("\n"); 9662 if (info.crashInfo != null && info.crashInfo.stackTrace != null) { 9663 sb.append(info.crashInfo.stackTrace); 9664 } 9665 sb.append("\n"); 9666 9667 // Only buffer up to ~64k. Various logging bits truncate 9668 // things at 128k. 9669 needsFlush = (sb.length() > 64 * 1024); 9670 } 9671 9672 // Flush immediately if the buffer's grown too large, or this 9673 // is a non-system app. Non-system apps are isolated with a 9674 // different tag & policy and not batched. 9675 // 9676 // Batching is useful during internal testing with 9677 // StrictMode settings turned up high. Without batching, 9678 // thousands of separate files could be created on boot. 9679 if (!isSystemApp || needsFlush) { 9680 new Thread("Error dump: " + dropboxTag) { 9681 @Override 9682 public void run() { 9683 String report; 9684 synchronized (sb) { 9685 report = sb.toString(); 9686 sb.delete(0, sb.length()); 9687 sb.trimToSize(); 9688 } 9689 if (report.length() != 0) { 9690 dbox.addText(dropboxTag, report); 9691 } 9692 } 9693 }.start(); 9694 return; 9695 } 9696 9697 // System app batching: 9698 if (!bufferWasEmpty) { 9699 // An existing dropbox-writing thread is outstanding, so 9700 // we don't need to start it up. The existing thread will 9701 // catch the buffer appends we just did. 9702 return; 9703 } 9704 9705 // Worker thread to both batch writes and to avoid blocking the caller on I/O. 9706 // (After this point, we shouldn't access AMS internal data structures.) 9707 new Thread("Error dump: " + dropboxTag) { 9708 @Override 9709 public void run() { 9710 // 5 second sleep to let stacks arrive and be batched together 9711 try { 9712 Thread.sleep(5000); // 5 seconds 9713 } catch (InterruptedException e) {} 9714 9715 String errorReport; 9716 synchronized (mStrictModeBuffer) { 9717 errorReport = mStrictModeBuffer.toString(); 9718 if (errorReport.length() == 0) { 9719 return; 9720 } 9721 mStrictModeBuffer.delete(0, mStrictModeBuffer.length()); 9722 mStrictModeBuffer.trimToSize(); 9723 } 9724 dbox.addText(dropboxTag, errorReport); 9725 } 9726 }.start(); 9727 } 9728 9729 /** 9730 * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors. 9731 * @param app object of the crashing app, null for the system server 9732 * @param tag reported by the caller 9733 * @param crashInfo describing the context of the error 9734 * @return true if the process should exit immediately (WTF is fatal) 9735 */ 9736 public boolean handleApplicationWtf(IBinder app, String tag, 9737 ApplicationErrorReport.CrashInfo crashInfo) { 9738 ProcessRecord r = findAppProcess(app, "WTF"); 9739 final String processName = app == null ? "system_server" 9740 : (r == null ? "unknown" : r.processName); 9741 9742 EventLog.writeEvent(EventLogTags.AM_WTF, 9743 UserHandle.getUserId(Binder.getCallingUid()), Binder.getCallingPid(), 9744 processName, 9745 r == null ? -1 : r.info.flags, 9746 tag, crashInfo.exceptionMessage); 9747 9748 addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo); 9749 9750 if (r != null && r.pid != Process.myPid() && 9751 Settings.Global.getInt(mContext.getContentResolver(), 9752 Settings.Global.WTF_IS_FATAL, 0) != 0) { 9753 crashApplication(r, crashInfo); 9754 return true; 9755 } else { 9756 return false; 9757 } 9758 } 9759 9760 /** 9761 * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit}) 9762 * @return the corresponding {@link ProcessRecord} object, or null if none could be found 9763 */ 9764 private ProcessRecord findAppProcess(IBinder app, String reason) { 9765 if (app == null) { 9766 return null; 9767 } 9768 9769 synchronized (this) { 9770 final int NP = mProcessNames.getMap().size(); 9771 for (int ip=0; ip<NP; ip++) { 9772 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 9773 final int NA = apps.size(); 9774 for (int ia=0; ia<NA; ia++) { 9775 ProcessRecord p = apps.valueAt(ia); 9776 if (p.thread != null && p.thread.asBinder() == app) { 9777 return p; 9778 } 9779 } 9780 } 9781 9782 Slog.w(TAG, "Can't find mystery application for " + reason 9783 + " from pid=" + Binder.getCallingPid() 9784 + " uid=" + Binder.getCallingUid() + ": " + app); 9785 return null; 9786 } 9787 } 9788 9789 /** 9790 * Utility function for addErrorToDropBox and handleStrictModeViolation's logging 9791 * to append various headers to the dropbox log text. 9792 */ 9793 private void appendDropBoxProcessHeaders(ProcessRecord process, String processName, 9794 StringBuilder sb) { 9795 // Watchdog thread ends up invoking this function (with 9796 // a null ProcessRecord) to add the stack file to dropbox. 9797 // Do not acquire a lock on this (am) in such cases, as it 9798 // could cause a potential deadlock, if and when watchdog 9799 // is invoked due to unavailability of lock on am and it 9800 // would prevent watchdog from killing system_server. 9801 if (process == null) { 9802 sb.append("Process: ").append(processName).append("\n"); 9803 return; 9804 } 9805 // Note: ProcessRecord 'process' is guarded by the service 9806 // instance. (notably process.pkgList, which could otherwise change 9807 // concurrently during execution of this method) 9808 synchronized (this) { 9809 sb.append("Process: ").append(processName).append("\n"); 9810 int flags = process.info.flags; 9811 IPackageManager pm = AppGlobals.getPackageManager(); 9812 sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n"); 9813 for (int ip=0; ip<process.pkgList.size(); ip++) { 9814 String pkg = process.pkgList.keyAt(ip); 9815 sb.append("Package: ").append(pkg); 9816 try { 9817 PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId()); 9818 if (pi != null) { 9819 sb.append(" v").append(pi.versionCode); 9820 if (pi.versionName != null) { 9821 sb.append(" (").append(pi.versionName).append(")"); 9822 } 9823 } 9824 } catch (RemoteException e) { 9825 Slog.e(TAG, "Error getting package info: " + pkg, e); 9826 } 9827 sb.append("\n"); 9828 } 9829 } 9830 } 9831 9832 private static String processClass(ProcessRecord process) { 9833 if (process == null || process.pid == MY_PID) { 9834 return "system_server"; 9835 } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) { 9836 return "system_app"; 9837 } else { 9838 return "data_app"; 9839 } 9840 } 9841 9842 /** 9843 * Write a description of an error (crash, WTF, ANR) to the drop box. 9844 * @param eventType to include in the drop box tag ("crash", "wtf", etc.) 9845 * @param process which caused the error, null means the system server 9846 * @param activity which triggered the error, null if unknown 9847 * @param parent activity related to the error, null if unknown 9848 * @param subject line related to the error, null if absent 9849 * @param report in long form describing the error, null if absent 9850 * @param logFile to include in the report, null if none 9851 * @param crashInfo giving an application stack trace, null if absent 9852 */ 9853 public void addErrorToDropBox(String eventType, 9854 ProcessRecord process, String processName, ActivityRecord activity, 9855 ActivityRecord parent, String subject, 9856 final String report, final File logFile, 9857 final ApplicationErrorReport.CrashInfo crashInfo) { 9858 // NOTE -- this must never acquire the ActivityManagerService lock, 9859 // otherwise the watchdog may be prevented from resetting the system. 9860 9861 final String dropboxTag = processClass(process) + "_" + eventType; 9862 final DropBoxManager dbox = (DropBoxManager) 9863 mContext.getSystemService(Context.DROPBOX_SERVICE); 9864 9865 // Exit early if the dropbox isn't configured to accept this report type. 9866 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 9867 9868 final StringBuilder sb = new StringBuilder(1024); 9869 appendDropBoxProcessHeaders(process, processName, sb); 9870 if (activity != null) { 9871 sb.append("Activity: ").append(activity.shortComponentName).append("\n"); 9872 } 9873 if (parent != null && parent.app != null && parent.app.pid != process.pid) { 9874 sb.append("Parent-Process: ").append(parent.app.processName).append("\n"); 9875 } 9876 if (parent != null && parent != activity) { 9877 sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n"); 9878 } 9879 if (subject != null) { 9880 sb.append("Subject: ").append(subject).append("\n"); 9881 } 9882 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 9883 if (Debug.isDebuggerConnected()) { 9884 sb.append("Debugger: Connected\n"); 9885 } 9886 sb.append("\n"); 9887 9888 // Do the rest in a worker thread to avoid blocking the caller on I/O 9889 // (After this point, we shouldn't access AMS internal data structures.) 9890 Thread worker = new Thread("Error dump: " + dropboxTag) { 9891 @Override 9892 public void run() { 9893 if (report != null) { 9894 sb.append(report); 9895 } 9896 if (logFile != null) { 9897 try { 9898 sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE, 9899 "\n\n[[TRUNCATED]]")); 9900 } catch (IOException e) { 9901 Slog.e(TAG, "Error reading " + logFile, e); 9902 } 9903 } 9904 if (crashInfo != null && crashInfo.stackTrace != null) { 9905 sb.append(crashInfo.stackTrace); 9906 } 9907 9908 String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag; 9909 int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0); 9910 if (lines > 0) { 9911 sb.append("\n"); 9912 9913 // Merge several logcat streams, and take the last N lines 9914 InputStreamReader input = null; 9915 try { 9916 java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat", 9917 "-v", "time", "-b", "events", "-b", "system", "-b", "main", 9918 "-t", String.valueOf(lines)).redirectErrorStream(true).start(); 9919 9920 try { logcat.getOutputStream().close(); } catch (IOException e) {} 9921 try { logcat.getErrorStream().close(); } catch (IOException e) {} 9922 input = new InputStreamReader(logcat.getInputStream()); 9923 9924 int num; 9925 char[] buf = new char[8192]; 9926 while ((num = input.read(buf)) > 0) sb.append(buf, 0, num); 9927 } catch (IOException e) { 9928 Slog.e(TAG, "Error running logcat", e); 9929 } finally { 9930 if (input != null) try { input.close(); } catch (IOException e) {} 9931 } 9932 } 9933 9934 dbox.addText(dropboxTag, sb.toString()); 9935 } 9936 }; 9937 9938 if (process == null) { 9939 // If process is null, we are being called from some internal code 9940 // and may be about to die -- run this synchronously. 9941 worker.run(); 9942 } else { 9943 worker.start(); 9944 } 9945 } 9946 9947 /** 9948 * Bring up the "unexpected error" dialog box for a crashing app. 9949 * Deal with edge cases (intercepts from instrumented applications, 9950 * ActivityController, error intent receivers, that sort of thing). 9951 * @param r the application crashing 9952 * @param crashInfo describing the failure 9953 */ 9954 private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) { 9955 long timeMillis = System.currentTimeMillis(); 9956 String shortMsg = crashInfo.exceptionClassName; 9957 String longMsg = crashInfo.exceptionMessage; 9958 String stackTrace = crashInfo.stackTrace; 9959 if (shortMsg != null && longMsg != null) { 9960 longMsg = shortMsg + ": " + longMsg; 9961 } else if (shortMsg != null) { 9962 longMsg = shortMsg; 9963 } 9964 9965 AppErrorResult result = new AppErrorResult(); 9966 synchronized (this) { 9967 if (mController != null) { 9968 try { 9969 String name = r != null ? r.processName : null; 9970 int pid = r != null ? r.pid : Binder.getCallingPid(); 9971 if (!mController.appCrashed(name, pid, 9972 shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) { 9973 Slog.w(TAG, "Force-killing crashed app " + name 9974 + " at watcher's request"); 9975 Process.killProcess(pid); 9976 return; 9977 } 9978 } catch (RemoteException e) { 9979 mController = null; 9980 Watchdog.getInstance().setActivityController(null); 9981 } 9982 } 9983 9984 final long origId = Binder.clearCallingIdentity(); 9985 9986 // If this process is running instrumentation, finish it. 9987 if (r != null && r.instrumentationClass != null) { 9988 Slog.w(TAG, "Error in app " + r.processName 9989 + " running instrumentation " + r.instrumentationClass + ":"); 9990 if (shortMsg != null) Slog.w(TAG, " " + shortMsg); 9991 if (longMsg != null) Slog.w(TAG, " " + longMsg); 9992 Bundle info = new Bundle(); 9993 info.putString("shortMsg", shortMsg); 9994 info.putString("longMsg", longMsg); 9995 finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info); 9996 Binder.restoreCallingIdentity(origId); 9997 return; 9998 } 9999 10000 // If we can't identify the process or it's already exceeded its crash quota, 10001 // quit right away without showing a crash dialog. 10002 if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) { 10003 Binder.restoreCallingIdentity(origId); 10004 return; 10005 } 10006 10007 Message msg = Message.obtain(); 10008 msg.what = SHOW_ERROR_MSG; 10009 HashMap data = new HashMap(); 10010 data.put("result", result); 10011 data.put("app", r); 10012 msg.obj = data; 10013 mHandler.sendMessage(msg); 10014 10015 Binder.restoreCallingIdentity(origId); 10016 } 10017 10018 int res = result.get(); 10019 10020 Intent appErrorIntent = null; 10021 synchronized (this) { 10022 if (r != null && !r.isolated) { 10023 // XXX Can't keep track of crash time for isolated processes, 10024 // since they don't have a persistent identity. 10025 mProcessCrashTimes.put(r.info.processName, r.uid, 10026 SystemClock.uptimeMillis()); 10027 } 10028 if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) { 10029 appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo); 10030 } 10031 } 10032 10033 if (appErrorIntent != null) { 10034 try { 10035 mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId)); 10036 } catch (ActivityNotFoundException e) { 10037 Slog.w(TAG, "bug report receiver dissappeared", e); 10038 } 10039 } 10040 } 10041 10042 Intent createAppErrorIntentLocked(ProcessRecord r, 10043 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 10044 ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo); 10045 if (report == null) { 10046 return null; 10047 } 10048 Intent result = new Intent(Intent.ACTION_APP_ERROR); 10049 result.setComponent(r.errorReportReceiver); 10050 result.putExtra(Intent.EXTRA_BUG_REPORT, report); 10051 result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 10052 return result; 10053 } 10054 10055 private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r, 10056 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 10057 if (r.errorReportReceiver == null) { 10058 return null; 10059 } 10060 10061 if (!r.crashing && !r.notResponding && !r.forceCrashReport) { 10062 return null; 10063 } 10064 10065 ApplicationErrorReport report = new ApplicationErrorReport(); 10066 report.packageName = r.info.packageName; 10067 report.installerPackageName = r.errorReportReceiver.getPackageName(); 10068 report.processName = r.processName; 10069 report.time = timeMillis; 10070 report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0; 10071 10072 if (r.crashing || r.forceCrashReport) { 10073 report.type = ApplicationErrorReport.TYPE_CRASH; 10074 report.crashInfo = crashInfo; 10075 } else if (r.notResponding) { 10076 report.type = ApplicationErrorReport.TYPE_ANR; 10077 report.anrInfo = new ApplicationErrorReport.AnrInfo(); 10078 10079 report.anrInfo.activity = r.notRespondingReport.tag; 10080 report.anrInfo.cause = r.notRespondingReport.shortMsg; 10081 report.anrInfo.info = r.notRespondingReport.longMsg; 10082 } 10083 10084 return report; 10085 } 10086 10087 public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() { 10088 enforceNotIsolatedCaller("getProcessesInErrorState"); 10089 // assume our apps are happy - lazy create the list 10090 List<ActivityManager.ProcessErrorStateInfo> errList = null; 10091 10092 final boolean allUsers = ActivityManager.checkUidPermission( 10093 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 10094 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 10095 int userId = UserHandle.getUserId(Binder.getCallingUid()); 10096 10097 synchronized (this) { 10098 10099 // iterate across all processes 10100 for (int i=mLruProcesses.size()-1; i>=0; i--) { 10101 ProcessRecord app = mLruProcesses.get(i); 10102 if (!allUsers && app.userId != userId) { 10103 continue; 10104 } 10105 if ((app.thread != null) && (app.crashing || app.notResponding)) { 10106 // This one's in trouble, so we'll generate a report for it 10107 // crashes are higher priority (in case there's a crash *and* an anr) 10108 ActivityManager.ProcessErrorStateInfo report = null; 10109 if (app.crashing) { 10110 report = app.crashingReport; 10111 } else if (app.notResponding) { 10112 report = app.notRespondingReport; 10113 } 10114 10115 if (report != null) { 10116 if (errList == null) { 10117 errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1); 10118 } 10119 errList.add(report); 10120 } else { 10121 Slog.w(TAG, "Missing app error report, app = " + app.processName + 10122 " crashing = " + app.crashing + 10123 " notResponding = " + app.notResponding); 10124 } 10125 } 10126 } 10127 } 10128 10129 return errList; 10130 } 10131 10132 static int oomAdjToImportance(int adj, ActivityManager.RunningAppProcessInfo currApp) { 10133 if (adj >= ProcessList.CACHED_APP_MIN_ADJ) { 10134 if (currApp != null) { 10135 currApp.lru = adj - ProcessList.CACHED_APP_MIN_ADJ + 1; 10136 } 10137 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 10138 } else if (adj >= ProcessList.SERVICE_B_ADJ) { 10139 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 10140 } else if (adj >= ProcessList.HOME_APP_ADJ) { 10141 if (currApp != null) { 10142 currApp.lru = 0; 10143 } 10144 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 10145 } else if (adj >= ProcessList.SERVICE_ADJ) { 10146 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 10147 } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 10148 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE; 10149 } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) { 10150 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE; 10151 } else if (adj >= ProcessList.VISIBLE_APP_ADJ) { 10152 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE; 10153 } else { 10154 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND; 10155 } 10156 } 10157 10158 private void fillInProcMemInfo(ProcessRecord app, 10159 ActivityManager.RunningAppProcessInfo outInfo) { 10160 outInfo.pid = app.pid; 10161 outInfo.uid = app.info.uid; 10162 if (mHeavyWeightProcess == app) { 10163 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE; 10164 } 10165 if (app.persistent) { 10166 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT; 10167 } 10168 if (app.activities.size() > 0) { 10169 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES; 10170 } 10171 outInfo.lastTrimLevel = app.trimMemoryLevel; 10172 int adj = app.curAdj; 10173 outInfo.importance = oomAdjToImportance(adj, outInfo); 10174 outInfo.importanceReasonCode = app.adjTypeCode; 10175 } 10176 10177 public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() { 10178 enforceNotIsolatedCaller("getRunningAppProcesses"); 10179 // Lazy instantiation of list 10180 List<ActivityManager.RunningAppProcessInfo> runList = null; 10181 final boolean allUsers = ActivityManager.checkUidPermission( 10182 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 10183 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 10184 int userId = UserHandle.getUserId(Binder.getCallingUid()); 10185 synchronized (this) { 10186 // Iterate across all processes 10187 for (int i=mLruProcesses.size()-1; i>=0; i--) { 10188 ProcessRecord app = mLruProcesses.get(i); 10189 if (!allUsers && app.userId != userId) { 10190 continue; 10191 } 10192 if ((app.thread != null) && (!app.crashing && !app.notResponding)) { 10193 // Generate process state info for running application 10194 ActivityManager.RunningAppProcessInfo currApp = 10195 new ActivityManager.RunningAppProcessInfo(app.processName, 10196 app.pid, app.getPackageList()); 10197 fillInProcMemInfo(app, currApp); 10198 if (app.adjSource instanceof ProcessRecord) { 10199 currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid; 10200 currApp.importanceReasonImportance = oomAdjToImportance( 10201 app.adjSourceOom, null); 10202 } else if (app.adjSource instanceof ActivityRecord) { 10203 ActivityRecord r = (ActivityRecord)app.adjSource; 10204 if (r.app != null) currApp.importanceReasonPid = r.app.pid; 10205 } 10206 if (app.adjTarget instanceof ComponentName) { 10207 currApp.importanceReasonComponent = (ComponentName)app.adjTarget; 10208 } 10209 //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance 10210 // + " lru=" + currApp.lru); 10211 if (runList == null) { 10212 runList = new ArrayList<ActivityManager.RunningAppProcessInfo>(); 10213 } 10214 runList.add(currApp); 10215 } 10216 } 10217 } 10218 return runList; 10219 } 10220 10221 public List<ApplicationInfo> getRunningExternalApplications() { 10222 enforceNotIsolatedCaller("getRunningExternalApplications"); 10223 List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses(); 10224 List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>(); 10225 if (runningApps != null && runningApps.size() > 0) { 10226 Set<String> extList = new HashSet<String>(); 10227 for (ActivityManager.RunningAppProcessInfo app : runningApps) { 10228 if (app.pkgList != null) { 10229 for (String pkg : app.pkgList) { 10230 extList.add(pkg); 10231 } 10232 } 10233 } 10234 IPackageManager pm = AppGlobals.getPackageManager(); 10235 for (String pkg : extList) { 10236 try { 10237 ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId()); 10238 if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) { 10239 retList.add(info); 10240 } 10241 } catch (RemoteException e) { 10242 } 10243 } 10244 } 10245 return retList; 10246 } 10247 10248 @Override 10249 public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) { 10250 enforceNotIsolatedCaller("getMyMemoryState"); 10251 synchronized (this) { 10252 ProcessRecord proc; 10253 synchronized (mPidsSelfLocked) { 10254 proc = mPidsSelfLocked.get(Binder.getCallingPid()); 10255 } 10256 fillInProcMemInfo(proc, outInfo); 10257 } 10258 } 10259 10260 @Override 10261 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 10262 if (checkCallingPermission(android.Manifest.permission.DUMP) 10263 != PackageManager.PERMISSION_GRANTED) { 10264 pw.println("Permission Denial: can't dump ActivityManager from from pid=" 10265 + Binder.getCallingPid() 10266 + ", uid=" + Binder.getCallingUid() 10267 + " without permission " 10268 + android.Manifest.permission.DUMP); 10269 return; 10270 } 10271 10272 boolean dumpAll = false; 10273 boolean dumpClient = false; 10274 String dumpPackage = null; 10275 10276 int opti = 0; 10277 while (opti < args.length) { 10278 String opt = args[opti]; 10279 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 10280 break; 10281 } 10282 opti++; 10283 if ("-a".equals(opt)) { 10284 dumpAll = true; 10285 } else if ("-c".equals(opt)) { 10286 dumpClient = true; 10287 } else if ("-h".equals(opt)) { 10288 pw.println("Activity manager dump options:"); 10289 pw.println(" [-a] [-c] [-h] [cmd] ..."); 10290 pw.println(" cmd may be one of:"); 10291 pw.println(" a[ctivities]: activity stack state"); 10292 pw.println(" b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state"); 10293 pw.println(" i[ntents] [PACKAGE_NAME]: pending intent state"); 10294 pw.println(" p[rocesses] [PACKAGE_NAME]: process state"); 10295 pw.println(" o[om]: out of memory management"); 10296 pw.println(" prov[iders] [COMP_SPEC ...]: content provider state"); 10297 pw.println(" provider [COMP_SPEC]: provider client-side state"); 10298 pw.println(" s[ervices] [COMP_SPEC ...]: service state"); 10299 pw.println(" service [COMP_SPEC]: service client-side state"); 10300 pw.println(" package [PACKAGE_NAME]: all state related to given package"); 10301 pw.println(" all: dump all activities"); 10302 pw.println(" top: dump the top activity"); 10303 pw.println(" cmd may also be a COMP_SPEC to dump activities."); 10304 pw.println(" COMP_SPEC may be a component name (com.foo/.myApp),"); 10305 pw.println(" a partial substring in a component name, a"); 10306 pw.println(" hex object identifier."); 10307 pw.println(" -a: include all available server state."); 10308 pw.println(" -c: include client state."); 10309 return; 10310 } else { 10311 pw.println("Unknown argument: " + opt + "; use -h for help"); 10312 } 10313 } 10314 10315 long origId = Binder.clearCallingIdentity(); 10316 boolean more = false; 10317 // Is the caller requesting to dump a particular piece of data? 10318 if (opti < args.length) { 10319 String cmd = args[opti]; 10320 opti++; 10321 if ("activities".equals(cmd) || "a".equals(cmd)) { 10322 synchronized (this) { 10323 dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null); 10324 } 10325 } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) { 10326 String[] newArgs; 10327 String name; 10328 if (opti >= args.length) { 10329 name = null; 10330 newArgs = EMPTY_STRING_ARRAY; 10331 } else { 10332 name = args[opti]; 10333 opti++; 10334 newArgs = new String[args.length - opti]; 10335 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 10336 args.length - opti); 10337 } 10338 synchronized (this) { 10339 dumpBroadcastsLocked(fd, pw, args, opti, true, name); 10340 } 10341 } else if ("intents".equals(cmd) || "i".equals(cmd)) { 10342 String[] newArgs; 10343 String name; 10344 if (opti >= args.length) { 10345 name = null; 10346 newArgs = EMPTY_STRING_ARRAY; 10347 } else { 10348 name = args[opti]; 10349 opti++; 10350 newArgs = new String[args.length - opti]; 10351 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 10352 args.length - opti); 10353 } 10354 synchronized (this) { 10355 dumpPendingIntentsLocked(fd, pw, args, opti, true, name); 10356 } 10357 } else if ("processes".equals(cmd) || "p".equals(cmd)) { 10358 String[] newArgs; 10359 String name; 10360 if (opti >= args.length) { 10361 name = null; 10362 newArgs = EMPTY_STRING_ARRAY; 10363 } else { 10364 name = args[opti]; 10365 opti++; 10366 newArgs = new String[args.length - opti]; 10367 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 10368 args.length - opti); 10369 } 10370 synchronized (this) { 10371 dumpProcessesLocked(fd, pw, args, opti, true, name); 10372 } 10373 } else if ("oom".equals(cmd) || "o".equals(cmd)) { 10374 synchronized (this) { 10375 dumpOomLocked(fd, pw, args, opti, true); 10376 } 10377 } else if ("provider".equals(cmd)) { 10378 String[] newArgs; 10379 String name; 10380 if (opti >= args.length) { 10381 name = null; 10382 newArgs = EMPTY_STRING_ARRAY; 10383 } else { 10384 name = args[opti]; 10385 opti++; 10386 newArgs = new String[args.length - opti]; 10387 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti); 10388 } 10389 if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) { 10390 pw.println("No providers match: " + name); 10391 pw.println("Use -h for help."); 10392 } 10393 } else if ("providers".equals(cmd) || "prov".equals(cmd)) { 10394 synchronized (this) { 10395 dumpProvidersLocked(fd, pw, args, opti, true, null); 10396 } 10397 } else if ("service".equals(cmd)) { 10398 String[] newArgs; 10399 String name; 10400 if (opti >= args.length) { 10401 name = null; 10402 newArgs = EMPTY_STRING_ARRAY; 10403 } else { 10404 name = args[opti]; 10405 opti++; 10406 newArgs = new String[args.length - opti]; 10407 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 10408 args.length - opti); 10409 } 10410 if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) { 10411 pw.println("No services match: " + name); 10412 pw.println("Use -h for help."); 10413 } 10414 } else if ("package".equals(cmd)) { 10415 String[] newArgs; 10416 if (opti >= args.length) { 10417 pw.println("package: no package name specified"); 10418 pw.println("Use -h for help."); 10419 } else { 10420 dumpPackage = args[opti]; 10421 opti++; 10422 newArgs = new String[args.length - opti]; 10423 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 10424 args.length - opti); 10425 args = newArgs; 10426 opti = 0; 10427 more = true; 10428 } 10429 } else if ("services".equals(cmd) || "s".equals(cmd)) { 10430 synchronized (this) { 10431 mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null); 10432 } 10433 } else { 10434 // Dumping a single activity? 10435 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) { 10436 pw.println("Bad activity command, or no activities match: " + cmd); 10437 pw.println("Use -h for help."); 10438 } 10439 } 10440 if (!more) { 10441 Binder.restoreCallingIdentity(origId); 10442 return; 10443 } 10444 } 10445 10446 // No piece of data specified, dump everything. 10447 synchronized (this) { 10448 dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 10449 pw.println(); 10450 if (dumpAll) { 10451 pw.println("-------------------------------------------------------------------------------"); 10452 } 10453 dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 10454 pw.println(); 10455 if (dumpAll) { 10456 pw.println("-------------------------------------------------------------------------------"); 10457 } 10458 dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage); 10459 pw.println(); 10460 if (dumpAll) { 10461 pw.println("-------------------------------------------------------------------------------"); 10462 } 10463 mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 10464 pw.println(); 10465 if (dumpAll) { 10466 pw.println("-------------------------------------------------------------------------------"); 10467 } 10468 dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 10469 pw.println(); 10470 if (dumpAll) { 10471 pw.println("-------------------------------------------------------------------------------"); 10472 } 10473 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage); 10474 } 10475 Binder.restoreCallingIdentity(origId); 10476 } 10477 10478 void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 10479 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) { 10480 pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)"); 10481 10482 boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient, 10483 dumpPackage); 10484 boolean needSep = printedAnything; 10485 10486 boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity, 10487 dumpPackage, needSep, " mFocusedActivity: "); 10488 if (printed) { 10489 printedAnything = true; 10490 needSep = false; 10491 } 10492 10493 if (dumpPackage == null) { 10494 if (needSep) { 10495 pw.println(); 10496 } 10497 needSep = true; 10498 printedAnything = true; 10499 mStackSupervisor.dump(pw, " "); 10500 } 10501 10502 if (mRecentTasks.size() > 0) { 10503 boolean printedHeader = false; 10504 10505 final int N = mRecentTasks.size(); 10506 for (int i=0; i<N; i++) { 10507 TaskRecord tr = mRecentTasks.get(i); 10508 if (dumpPackage != null) { 10509 if (tr.realActivity == null || 10510 !dumpPackage.equals(tr.realActivity)) { 10511 continue; 10512 } 10513 } 10514 if (!printedHeader) { 10515 if (needSep) { 10516 pw.println(); 10517 } 10518 pw.println(" Recent tasks:"); 10519 printedHeader = true; 10520 printedAnything = true; 10521 } 10522 pw.print(" * Recent #"); pw.print(i); pw.print(": "); 10523 pw.println(tr); 10524 if (dumpAll) { 10525 mRecentTasks.get(i).dump(pw, " "); 10526 } 10527 } 10528 } 10529 10530 if (!printedAnything) { 10531 pw.println(" (nothing)"); 10532 } 10533 } 10534 10535 void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 10536 int opti, boolean dumpAll, String dumpPackage) { 10537 boolean needSep = false; 10538 boolean printedAnything = false; 10539 int numPers = 0; 10540 10541 pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)"); 10542 10543 if (dumpAll) { 10544 final int NP = mProcessNames.getMap().size(); 10545 for (int ip=0; ip<NP; ip++) { 10546 SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip); 10547 final int NA = procs.size(); 10548 for (int ia=0; ia<NA; ia++) { 10549 ProcessRecord r = procs.valueAt(ia); 10550 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 10551 continue; 10552 } 10553 if (!needSep) { 10554 pw.println(" All known processes:"); 10555 needSep = true; 10556 printedAnything = true; 10557 } 10558 pw.print(r.persistent ? " *PERS*" : " *APP*"); 10559 pw.print(" UID "); pw.print(procs.keyAt(ia)); 10560 pw.print(" "); pw.println(r); 10561 r.dump(pw, " "); 10562 if (r.persistent) { 10563 numPers++; 10564 } 10565 } 10566 } 10567 } 10568 10569 if (mIsolatedProcesses.size() > 0) { 10570 boolean printed = false; 10571 for (int i=0; i<mIsolatedProcesses.size(); i++) { 10572 ProcessRecord r = mIsolatedProcesses.valueAt(i); 10573 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 10574 continue; 10575 } 10576 if (!printed) { 10577 if (needSep) { 10578 pw.println(); 10579 } 10580 pw.println(" Isolated process list (sorted by uid):"); 10581 printedAnything = true; 10582 printed = true; 10583 needSep = true; 10584 } 10585 pw.println(String.format("%sIsolated #%2d: %s", 10586 " ", i, r.toString())); 10587 } 10588 } 10589 10590 if (mLruProcesses.size() > 0) { 10591 if (needSep) { 10592 pw.println(); 10593 } 10594 pw.print(" Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size()); 10595 pw.print(" total, non-act at "); 10596 pw.print(mLruProcesses.size()-mLruProcessActivityStart); 10597 pw.print(", non-svc at "); 10598 pw.print(mLruProcesses.size()-mLruProcessServiceStart); 10599 pw.println("):"); 10600 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", false, dumpPackage); 10601 needSep = true; 10602 printedAnything = true; 10603 } 10604 10605 if (dumpAll || dumpPackage != null) { 10606 synchronized (mPidsSelfLocked) { 10607 boolean printed = false; 10608 for (int i=0; i<mPidsSelfLocked.size(); i++) { 10609 ProcessRecord r = mPidsSelfLocked.valueAt(i); 10610 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 10611 continue; 10612 } 10613 if (!printed) { 10614 if (needSep) pw.println(); 10615 needSep = true; 10616 pw.println(" PID mappings:"); 10617 printed = true; 10618 printedAnything = true; 10619 } 10620 pw.print(" PID #"); pw.print(mPidsSelfLocked.keyAt(i)); 10621 pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i)); 10622 } 10623 } 10624 } 10625 10626 if (mForegroundProcesses.size() > 0) { 10627 synchronized (mPidsSelfLocked) { 10628 boolean printed = false; 10629 for (int i=0; i<mForegroundProcesses.size(); i++) { 10630 ProcessRecord r = mPidsSelfLocked.get( 10631 mForegroundProcesses.valueAt(i).pid); 10632 if (dumpPackage != null && (r == null 10633 || !r.pkgList.containsKey(dumpPackage))) { 10634 continue; 10635 } 10636 if (!printed) { 10637 if (needSep) pw.println(); 10638 needSep = true; 10639 pw.println(" Foreground Processes:"); 10640 printed = true; 10641 printedAnything = true; 10642 } 10643 pw.print(" PID #"); pw.print(mForegroundProcesses.keyAt(i)); 10644 pw.print(": "); pw.println(mForegroundProcesses.valueAt(i)); 10645 } 10646 } 10647 } 10648 10649 if (mPersistentStartingProcesses.size() > 0) { 10650 if (needSep) pw.println(); 10651 needSep = true; 10652 printedAnything = true; 10653 pw.println(" Persisent processes that are starting:"); 10654 dumpProcessList(pw, this, mPersistentStartingProcesses, " ", 10655 "Starting Norm", "Restarting PERS", dumpPackage); 10656 } 10657 10658 if (mRemovedProcesses.size() > 0) { 10659 if (needSep) pw.println(); 10660 needSep = true; 10661 printedAnything = true; 10662 pw.println(" Processes that are being removed:"); 10663 dumpProcessList(pw, this, mRemovedProcesses, " ", 10664 "Removed Norm", "Removed PERS", dumpPackage); 10665 } 10666 10667 if (mProcessesOnHold.size() > 0) { 10668 if (needSep) pw.println(); 10669 needSep = true; 10670 printedAnything = true; 10671 pw.println(" Processes that are on old until the system is ready:"); 10672 dumpProcessList(pw, this, mProcessesOnHold, " ", 10673 "OnHold Norm", "OnHold PERS", dumpPackage); 10674 } 10675 10676 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage); 10677 10678 if (mProcessCrashTimes.getMap().size() > 0) { 10679 boolean printed = false; 10680 long now = SystemClock.uptimeMillis(); 10681 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap(); 10682 final int NP = pmap.size(); 10683 for (int ip=0; ip<NP; ip++) { 10684 String pname = pmap.keyAt(ip); 10685 SparseArray<Long> uids = pmap.valueAt(ip); 10686 final int N = uids.size(); 10687 for (int i=0; i<N; i++) { 10688 int puid = uids.keyAt(i); 10689 ProcessRecord r = mProcessNames.get(pname, puid); 10690 if (dumpPackage != null && (r == null 10691 || !r.pkgList.containsKey(dumpPackage))) { 10692 continue; 10693 } 10694 if (!printed) { 10695 if (needSep) pw.println(); 10696 needSep = true; 10697 pw.println(" Time since processes crashed:"); 10698 printed = true; 10699 printedAnything = true; 10700 } 10701 pw.print(" Process "); pw.print(pname); 10702 pw.print(" uid "); pw.print(puid); 10703 pw.print(": last crashed "); 10704 TimeUtils.formatDuration(now-uids.valueAt(i), pw); 10705 pw.println(" ago"); 10706 } 10707 } 10708 } 10709 10710 if (mBadProcesses.getMap().size() > 0) { 10711 boolean printed = false; 10712 final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap(); 10713 final int NP = pmap.size(); 10714 for (int ip=0; ip<NP; ip++) { 10715 String pname = pmap.keyAt(ip); 10716 SparseArray<BadProcessInfo> uids = pmap.valueAt(ip); 10717 final int N = uids.size(); 10718 for (int i=0; i<N; i++) { 10719 int puid = uids.keyAt(i); 10720 ProcessRecord r = mProcessNames.get(pname, puid); 10721 if (dumpPackage != null && (r == null 10722 || !r.pkgList.containsKey(dumpPackage))) { 10723 continue; 10724 } 10725 if (!printed) { 10726 if (needSep) pw.println(); 10727 needSep = true; 10728 pw.println(" Bad processes:"); 10729 printedAnything = true; 10730 } 10731 BadProcessInfo info = uids.valueAt(i); 10732 pw.print(" Bad process "); pw.print(pname); 10733 pw.print(" uid "); pw.print(puid); 10734 pw.print(": crashed at time "); pw.println(info.time); 10735 if (info.shortMsg != null) { 10736 pw.print(" Short msg: "); pw.println(info.shortMsg); 10737 } 10738 if (info.longMsg != null) { 10739 pw.print(" Long msg: "); pw.println(info.longMsg); 10740 } 10741 if (info.stack != null) { 10742 pw.println(" Stack:"); 10743 int lastPos = 0; 10744 for (int pos=0; pos<info.stack.length(); pos++) { 10745 if (info.stack.charAt(pos) == '\n') { 10746 pw.print(" "); 10747 pw.write(info.stack, lastPos, pos-lastPos); 10748 pw.println(); 10749 lastPos = pos+1; 10750 } 10751 } 10752 if (lastPos < info.stack.length()) { 10753 pw.print(" "); 10754 pw.write(info.stack, lastPos, info.stack.length()-lastPos); 10755 pw.println(); 10756 } 10757 } 10758 } 10759 } 10760 } 10761 10762 if (dumpPackage == null) { 10763 pw.println(); 10764 needSep = false; 10765 pw.println(" mStartedUsers:"); 10766 for (int i=0; i<mStartedUsers.size(); i++) { 10767 UserStartedState uss = mStartedUsers.valueAt(i); 10768 pw.print(" User #"); pw.print(uss.mHandle.getIdentifier()); 10769 pw.print(": "); uss.dump("", pw); 10770 } 10771 pw.print(" mStartedUserArray: ["); 10772 for (int i=0; i<mStartedUserArray.length; i++) { 10773 if (i > 0) pw.print(", "); 10774 pw.print(mStartedUserArray[i]); 10775 } 10776 pw.println("]"); 10777 pw.print(" mUserLru: ["); 10778 for (int i=0; i<mUserLru.size(); i++) { 10779 if (i > 0) pw.print(", "); 10780 pw.print(mUserLru.get(i)); 10781 } 10782 pw.println("]"); 10783 if (dumpAll) { 10784 pw.print(" mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray)); 10785 } 10786 } 10787 if (mHomeProcess != null && (dumpPackage == null 10788 || mHomeProcess.pkgList.containsKey(dumpPackage))) { 10789 if (needSep) { 10790 pw.println(); 10791 needSep = false; 10792 } 10793 pw.println(" mHomeProcess: " + mHomeProcess); 10794 } 10795 if (mPreviousProcess != null && (dumpPackage == null 10796 || mPreviousProcess.pkgList.containsKey(dumpPackage))) { 10797 if (needSep) { 10798 pw.println(); 10799 needSep = false; 10800 } 10801 pw.println(" mPreviousProcess: " + mPreviousProcess); 10802 } 10803 if (dumpAll) { 10804 StringBuilder sb = new StringBuilder(128); 10805 sb.append(" mPreviousProcessVisibleTime: "); 10806 TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb); 10807 pw.println(sb); 10808 } 10809 if (mHeavyWeightProcess != null && (dumpPackage == null 10810 || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) { 10811 if (needSep) { 10812 pw.println(); 10813 needSep = false; 10814 } 10815 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 10816 } 10817 if (dumpPackage == null) { 10818 pw.println(" mConfiguration: " + mConfiguration); 10819 } 10820 if (dumpAll) { 10821 pw.println(" mConfigWillChange: " + getFocusedStack().mConfigWillChange); 10822 if (mCompatModePackages.getPackages().size() > 0) { 10823 boolean printed = false; 10824 for (Map.Entry<String, Integer> entry 10825 : mCompatModePackages.getPackages().entrySet()) { 10826 String pkg = entry.getKey(); 10827 int mode = entry.getValue(); 10828 if (dumpPackage != null && !dumpPackage.equals(pkg)) { 10829 continue; 10830 } 10831 if (!printed) { 10832 pw.println(" mScreenCompatPackages:"); 10833 printed = true; 10834 } 10835 pw.print(" "); pw.print(pkg); pw.print(": "); 10836 pw.print(mode); pw.println(); 10837 } 10838 } 10839 } 10840 if (dumpPackage == null) { 10841 if (mSleeping || mWentToSleep || mLockScreenShown) { 10842 pw.println(" mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep 10843 + " mLockScreenShown " + mLockScreenShown); 10844 } 10845 if (mShuttingDown) { 10846 pw.println(" mShuttingDown=" + mShuttingDown); 10847 } 10848 } 10849 if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient 10850 || mOrigWaitForDebugger) { 10851 if (dumpPackage == null || dumpPackage.equals(mDebugApp) 10852 || dumpPackage.equals(mOrigDebugApp)) { 10853 if (needSep) { 10854 pw.println(); 10855 needSep = false; 10856 } 10857 pw.println(" mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp 10858 + " mDebugTransient=" + mDebugTransient 10859 + " mOrigWaitForDebugger=" + mOrigWaitForDebugger); 10860 } 10861 } 10862 if (mOpenGlTraceApp != null) { 10863 if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) { 10864 if (needSep) { 10865 pw.println(); 10866 needSep = false; 10867 } 10868 pw.println(" mOpenGlTraceApp=" + mOpenGlTraceApp); 10869 } 10870 } 10871 if (mProfileApp != null || mProfileProc != null || mProfileFile != null 10872 || mProfileFd != null) { 10873 if (dumpPackage == null || dumpPackage.equals(mProfileApp)) { 10874 if (needSep) { 10875 pw.println(); 10876 needSep = false; 10877 } 10878 pw.println(" mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc); 10879 pw.println(" mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd); 10880 pw.println(" mProfileType=" + mProfileType + " mAutoStopProfiler=" 10881 + mAutoStopProfiler); 10882 } 10883 } 10884 if (dumpPackage == null) { 10885 if (mAlwaysFinishActivities || mController != null) { 10886 pw.println(" mAlwaysFinishActivities=" + mAlwaysFinishActivities 10887 + " mController=" + mController); 10888 } 10889 if (dumpAll) { 10890 pw.println(" Total persistent processes: " + numPers); 10891 pw.println(" mStartRunning=" + mStartRunning 10892 + " mProcessesReady=" + mProcessesReady 10893 + " mSystemReady=" + mSystemReady); 10894 pw.println(" mBooting=" + mBooting 10895 + " mBooted=" + mBooted 10896 + " mFactoryTest=" + mFactoryTest); 10897 pw.print(" mLastPowerCheckRealtime="); 10898 TimeUtils.formatDuration(mLastPowerCheckRealtime, pw); 10899 pw.println(""); 10900 pw.print(" mLastPowerCheckUptime="); 10901 TimeUtils.formatDuration(mLastPowerCheckUptime, pw); 10902 pw.println(""); 10903 pw.println(" mGoingToSleep=" + mStackSupervisor.mGoingToSleep); 10904 pw.println(" mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity); 10905 pw.println(" mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq); 10906 pw.println(" mNumNonCachedProcs=" + mNumNonCachedProcs 10907 + " (" + mLruProcesses.size() + " total)" 10908 + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs 10909 + " mNumServiceProcs=" + mNumServiceProcs 10910 + " mNewNumServiceProcs=" + mNewNumServiceProcs); 10911 pw.println(" mAllowLowerMemLevel=" + mAllowLowerMemLevel 10912 + " mLastMemoryLevel" + mLastMemoryLevel 10913 + " mLastNumProcesses" + mLastNumProcesses); 10914 long now = SystemClock.uptimeMillis(); 10915 pw.print(" mLastIdleTime="); 10916 TimeUtils.formatDuration(now, mLastIdleTime, pw); 10917 pw.print(" mLowRamSinceLastIdle="); 10918 TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw); 10919 pw.println(); 10920 } 10921 } 10922 10923 if (!printedAnything) { 10924 pw.println(" (nothing)"); 10925 } 10926 } 10927 10928 boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args, 10929 int opti, boolean needSep, boolean dumpAll, String dumpPackage) { 10930 if (mProcessesToGc.size() > 0) { 10931 boolean printed = false; 10932 long now = SystemClock.uptimeMillis(); 10933 for (int i=0; i<mProcessesToGc.size(); i++) { 10934 ProcessRecord proc = mProcessesToGc.get(i); 10935 if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) { 10936 continue; 10937 } 10938 if (!printed) { 10939 if (needSep) pw.println(); 10940 needSep = true; 10941 pw.println(" Processes that are waiting to GC:"); 10942 printed = true; 10943 } 10944 pw.print(" Process "); pw.println(proc); 10945 pw.print(" lowMem="); pw.print(proc.reportLowMemory); 10946 pw.print(", last gced="); 10947 pw.print(now-proc.lastRequestedGc); 10948 pw.print(" ms ago, last lowMem="); 10949 pw.print(now-proc.lastLowMemory); 10950 pw.println(" ms ago"); 10951 10952 } 10953 } 10954 return needSep; 10955 } 10956 10957 void printOomLevel(PrintWriter pw, String name, int adj) { 10958 pw.print(" "); 10959 if (adj >= 0) { 10960 pw.print(' '); 10961 if (adj < 10) pw.print(' '); 10962 } else { 10963 if (adj > -10) pw.print(' '); 10964 } 10965 pw.print(adj); 10966 pw.print(": "); 10967 pw.print(name); 10968 pw.print(" ("); 10969 pw.print(mProcessList.getMemLevel(adj)/1024); 10970 pw.println(" kB)"); 10971 } 10972 10973 boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args, 10974 int opti, boolean dumpAll) { 10975 boolean needSep = false; 10976 10977 if (mLruProcesses.size() > 0) { 10978 if (needSep) pw.println(); 10979 needSep = true; 10980 pw.println(" OOM levels:"); 10981 printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ); 10982 printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ); 10983 printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ); 10984 printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ); 10985 printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ); 10986 printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ); 10987 printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ); 10988 printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ); 10989 printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ); 10990 printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ); 10991 printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ); 10992 printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ); 10993 printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ); 10994 10995 if (needSep) pw.println(); 10996 pw.print(" Process OOM control ("); pw.print(mLruProcesses.size()); 10997 pw.print(" total, non-act at "); 10998 pw.print(mLruProcesses.size()-mLruProcessActivityStart); 10999 pw.print(", non-svc at "); 11000 pw.print(mLruProcesses.size()-mLruProcessServiceStart); 11001 pw.println("):"); 11002 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", true, null); 11003 needSep = true; 11004 } 11005 11006 dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null); 11007 11008 pw.println(); 11009 pw.println(" mHomeProcess: " + mHomeProcess); 11010 pw.println(" mPreviousProcess: " + mPreviousProcess); 11011 if (mHeavyWeightProcess != null) { 11012 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 11013 } 11014 11015 return true; 11016 } 11017 11018 /** 11019 * There are three ways to call this: 11020 * - no provider specified: dump all the providers 11021 * - a flattened component name that matched an existing provider was specified as the 11022 * first arg: dump that one provider 11023 * - the first arg isn't the flattened component name of an existing provider: 11024 * dump all providers whose component contains the first arg as a substring 11025 */ 11026 protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args, 11027 int opti, boolean dumpAll) { 11028 return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll); 11029 } 11030 11031 static class ItemMatcher { 11032 ArrayList<ComponentName> components; 11033 ArrayList<String> strings; 11034 ArrayList<Integer> objects; 11035 boolean all; 11036 11037 ItemMatcher() { 11038 all = true; 11039 } 11040 11041 void build(String name) { 11042 ComponentName componentName = ComponentName.unflattenFromString(name); 11043 if (componentName != null) { 11044 if (components == null) { 11045 components = new ArrayList<ComponentName>(); 11046 } 11047 components.add(componentName); 11048 all = false; 11049 } else { 11050 int objectId = 0; 11051 // Not a '/' separated full component name; maybe an object ID? 11052 try { 11053 objectId = Integer.parseInt(name, 16); 11054 if (objects == null) { 11055 objects = new ArrayList<Integer>(); 11056 } 11057 objects.add(objectId); 11058 all = false; 11059 } catch (RuntimeException e) { 11060 // Not an integer; just do string match. 11061 if (strings == null) { 11062 strings = new ArrayList<String>(); 11063 } 11064 strings.add(name); 11065 all = false; 11066 } 11067 } 11068 } 11069 11070 int build(String[] args, int opti) { 11071 for (; opti<args.length; opti++) { 11072 String name = args[opti]; 11073 if ("--".equals(name)) { 11074 return opti+1; 11075 } 11076 build(name); 11077 } 11078 return opti; 11079 } 11080 11081 boolean match(Object object, ComponentName comp) { 11082 if (all) { 11083 return true; 11084 } 11085 if (components != null) { 11086 for (int i=0; i<components.size(); i++) { 11087 if (components.get(i).equals(comp)) { 11088 return true; 11089 } 11090 } 11091 } 11092 if (objects != null) { 11093 for (int i=0; i<objects.size(); i++) { 11094 if (System.identityHashCode(object) == objects.get(i)) { 11095 return true; 11096 } 11097 } 11098 } 11099 if (strings != null) { 11100 String flat = comp.flattenToString(); 11101 for (int i=0; i<strings.size(); i++) { 11102 if (flat.contains(strings.get(i))) { 11103 return true; 11104 } 11105 } 11106 } 11107 return false; 11108 } 11109 } 11110 11111 /** 11112 * There are three things that cmd can be: 11113 * - a flattened component name that matches an existing activity 11114 * - the cmd arg isn't the flattened component name of an existing activity: 11115 * dump all activity whose component contains the cmd as a substring 11116 * - A hex number of the ActivityRecord object instance. 11117 */ 11118 protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args, 11119 int opti, boolean dumpAll) { 11120 ArrayList<ActivityRecord> activities; 11121 11122 synchronized (this) { 11123 activities = mStackSupervisor.getDumpActivitiesLocked(name); 11124 } 11125 11126 if (activities.size() <= 0) { 11127 return false; 11128 } 11129 11130 String[] newArgs = new String[args.length - opti]; 11131 System.arraycopy(args, opti, newArgs, 0, args.length - opti); 11132 11133 TaskRecord lastTask = null; 11134 boolean needSep = false; 11135 for (int i=activities.size()-1; i>=0; i--) { 11136 ActivityRecord r = activities.get(i); 11137 if (needSep) { 11138 pw.println(); 11139 } 11140 needSep = true; 11141 synchronized (this) { 11142 if (lastTask != r.task) { 11143 lastTask = r.task; 11144 pw.print("TASK "); pw.print(lastTask.affinity); 11145 pw.print(" id="); pw.println(lastTask.taskId); 11146 if (dumpAll) { 11147 lastTask.dump(pw, " "); 11148 } 11149 } 11150 } 11151 dumpActivity(" ", fd, pw, activities.get(i), newArgs, dumpAll); 11152 } 11153 return true; 11154 } 11155 11156 /** 11157 * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if 11158 * there is a thread associated with the activity. 11159 */ 11160 private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw, 11161 final ActivityRecord r, String[] args, boolean dumpAll) { 11162 String innerPrefix = prefix + " "; 11163 synchronized (this) { 11164 pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName); 11165 pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r))); 11166 pw.print(" pid="); 11167 if (r.app != null) pw.println(r.app.pid); 11168 else pw.println("(not running)"); 11169 if (dumpAll) { 11170 r.dump(pw, innerPrefix); 11171 } 11172 } 11173 if (r.app != null && r.app.thread != null) { 11174 // flush anything that is already in the PrintWriter since the thread is going 11175 // to write to the file descriptor directly 11176 pw.flush(); 11177 try { 11178 TransferPipe tp = new TransferPipe(); 11179 try { 11180 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(), 11181 r.appToken, innerPrefix, args); 11182 tp.go(fd); 11183 } finally { 11184 tp.kill(); 11185 } 11186 } catch (IOException e) { 11187 pw.println(innerPrefix + "Failure while dumping the activity: " + e); 11188 } catch (RemoteException e) { 11189 pw.println(innerPrefix + "Got a RemoteException while dumping the activity"); 11190 } 11191 } 11192 } 11193 11194 void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 11195 int opti, boolean dumpAll, String dumpPackage) { 11196 boolean needSep = false; 11197 boolean onlyHistory = false; 11198 boolean printedAnything = false; 11199 11200 if ("history".equals(dumpPackage)) { 11201 if (opti < args.length && "-s".equals(args[opti])) { 11202 dumpAll = false; 11203 } 11204 onlyHistory = true; 11205 dumpPackage = null; 11206 } 11207 11208 pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)"); 11209 if (!onlyHistory && dumpAll) { 11210 if (mRegisteredReceivers.size() > 0) { 11211 boolean printed = false; 11212 Iterator it = mRegisteredReceivers.values().iterator(); 11213 while (it.hasNext()) { 11214 ReceiverList r = (ReceiverList)it.next(); 11215 if (dumpPackage != null && (r.app == null || 11216 !dumpPackage.equals(r.app.info.packageName))) { 11217 continue; 11218 } 11219 if (!printed) { 11220 pw.println(" Registered Receivers:"); 11221 needSep = true; 11222 printed = true; 11223 printedAnything = true; 11224 } 11225 pw.print(" * "); pw.println(r); 11226 r.dump(pw, " "); 11227 } 11228 } 11229 11230 if (mReceiverResolver.dump(pw, needSep ? 11231 "\n Receiver Resolver Table:" : " Receiver Resolver Table:", 11232 " ", dumpPackage, false)) { 11233 needSep = true; 11234 printedAnything = true; 11235 } 11236 } 11237 11238 for (BroadcastQueue q : mBroadcastQueues) { 11239 needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep); 11240 printedAnything |= needSep; 11241 } 11242 11243 needSep = true; 11244 11245 if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) { 11246 for (int user=0; user<mStickyBroadcasts.size(); user++) { 11247 if (needSep) { 11248 pw.println(); 11249 } 11250 needSep = true; 11251 printedAnything = true; 11252 pw.print(" Sticky broadcasts for user "); 11253 pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":"); 11254 StringBuilder sb = new StringBuilder(128); 11255 for (Map.Entry<String, ArrayList<Intent>> ent 11256 : mStickyBroadcasts.valueAt(user).entrySet()) { 11257 pw.print(" * Sticky action "); pw.print(ent.getKey()); 11258 if (dumpAll) { 11259 pw.println(":"); 11260 ArrayList<Intent> intents = ent.getValue(); 11261 final int N = intents.size(); 11262 for (int i=0; i<N; i++) { 11263 sb.setLength(0); 11264 sb.append(" Intent: "); 11265 intents.get(i).toShortString(sb, false, true, false, false); 11266 pw.println(sb.toString()); 11267 Bundle bundle = intents.get(i).getExtras(); 11268 if (bundle != null) { 11269 pw.print(" "); 11270 pw.println(bundle.toString()); 11271 } 11272 } 11273 } else { 11274 pw.println(""); 11275 } 11276 } 11277 } 11278 } 11279 11280 if (!onlyHistory && dumpAll) { 11281 pw.println(); 11282 for (BroadcastQueue queue : mBroadcastQueues) { 11283 pw.println(" mBroadcastsScheduled [" + queue.mQueueName + "]=" 11284 + queue.mBroadcastsScheduled); 11285 } 11286 pw.println(" mHandler:"); 11287 mHandler.dump(new PrintWriterPrinter(pw), " "); 11288 needSep = true; 11289 printedAnything = true; 11290 } 11291 11292 if (!printedAnything) { 11293 pw.println(" (nothing)"); 11294 } 11295 } 11296 11297 void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args, 11298 int opti, boolean dumpAll, String dumpPackage) { 11299 boolean needSep; 11300 boolean printedAnything = false; 11301 11302 ItemMatcher matcher = new ItemMatcher(); 11303 matcher.build(args, opti); 11304 11305 pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)"); 11306 11307 needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage); 11308 printedAnything |= needSep; 11309 11310 if (mLaunchingProviders.size() > 0) { 11311 boolean printed = false; 11312 for (int i=mLaunchingProviders.size()-1; i>=0; i--) { 11313 ContentProviderRecord r = mLaunchingProviders.get(i); 11314 if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) { 11315 continue; 11316 } 11317 if (!printed) { 11318 if (needSep) pw.println(); 11319 needSep = true; 11320 pw.println(" Launching content providers:"); 11321 printed = true; 11322 printedAnything = true; 11323 } 11324 pw.print(" Launching #"); pw.print(i); pw.print(": "); 11325 pw.println(r); 11326 } 11327 } 11328 11329 if (mGrantedUriPermissions.size() > 0) { 11330 boolean printed = false; 11331 int dumpUid = -2; 11332 if (dumpPackage != null) { 11333 try { 11334 dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0); 11335 } catch (NameNotFoundException e) { 11336 dumpUid = -1; 11337 } 11338 } 11339 for (int i=0; i<mGrantedUriPermissions.size(); i++) { 11340 int uid = mGrantedUriPermissions.keyAt(i); 11341 if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) { 11342 continue; 11343 } 11344 ArrayMap<Uri, UriPermission> perms 11345 = mGrantedUriPermissions.valueAt(i); 11346 if (!printed) { 11347 if (needSep) pw.println(); 11348 needSep = true; 11349 pw.println(" Granted Uri Permissions:"); 11350 printed = true; 11351 printedAnything = true; 11352 } 11353 pw.print(" * UID "); pw.print(uid); 11354 pw.println(" holds:"); 11355 for (UriPermission perm : perms.values()) { 11356 pw.print(" "); pw.println(perm); 11357 if (dumpAll) { 11358 perm.dump(pw, " "); 11359 } 11360 } 11361 } 11362 } 11363 11364 if (!printedAnything) { 11365 pw.println(" (nothing)"); 11366 } 11367 } 11368 11369 void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 11370 int opti, boolean dumpAll, String dumpPackage) { 11371 boolean printed = false; 11372 11373 pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)"); 11374 11375 if (mIntentSenderRecords.size() > 0) { 11376 Iterator<WeakReference<PendingIntentRecord>> it 11377 = mIntentSenderRecords.values().iterator(); 11378 while (it.hasNext()) { 11379 WeakReference<PendingIntentRecord> ref = it.next(); 11380 PendingIntentRecord rec = ref != null ? ref.get(): null; 11381 if (dumpPackage != null && (rec == null 11382 || !dumpPackage.equals(rec.key.packageName))) { 11383 continue; 11384 } 11385 printed = true; 11386 if (rec != null) { 11387 pw.print(" * "); pw.println(rec); 11388 if (dumpAll) { 11389 rec.dump(pw, " "); 11390 } 11391 } else { 11392 pw.print(" * "); pw.println(ref); 11393 } 11394 } 11395 } 11396 11397 if (!printed) { 11398 pw.println(" (nothing)"); 11399 } 11400 } 11401 11402 private static final int dumpProcessList(PrintWriter pw, 11403 ActivityManagerService service, List list, 11404 String prefix, String normalLabel, String persistentLabel, 11405 String dumpPackage) { 11406 int numPers = 0; 11407 final int N = list.size()-1; 11408 for (int i=N; i>=0; i--) { 11409 ProcessRecord r = (ProcessRecord)list.get(i); 11410 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 11411 continue; 11412 } 11413 pw.println(String.format("%s%s #%2d: %s", 11414 prefix, (r.persistent ? persistentLabel : normalLabel), 11415 i, r.toString())); 11416 if (r.persistent) { 11417 numPers++; 11418 } 11419 } 11420 return numPers; 11421 } 11422 11423 private static final boolean dumpProcessOomList(PrintWriter pw, 11424 ActivityManagerService service, List<ProcessRecord> origList, 11425 String prefix, String normalLabel, String persistentLabel, 11426 boolean inclDetails, String dumpPackage) { 11427 11428 ArrayList<Pair<ProcessRecord, Integer>> list 11429 = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size()); 11430 for (int i=0; i<origList.size(); i++) { 11431 ProcessRecord r = origList.get(i); 11432 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 11433 continue; 11434 } 11435 list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i)); 11436 } 11437 11438 if (list.size() <= 0) { 11439 return false; 11440 } 11441 11442 Comparator<Pair<ProcessRecord, Integer>> comparator 11443 = new Comparator<Pair<ProcessRecord, Integer>>() { 11444 @Override 11445 public int compare(Pair<ProcessRecord, Integer> object1, 11446 Pair<ProcessRecord, Integer> object2) { 11447 if (object1.first.setAdj != object2.first.setAdj) { 11448 return object1.first.setAdj > object2.first.setAdj ? -1 : 1; 11449 } 11450 if (object1.second.intValue() != object2.second.intValue()) { 11451 return object1.second.intValue() > object2.second.intValue() ? -1 : 1; 11452 } 11453 return 0; 11454 } 11455 }; 11456 11457 Collections.sort(list, comparator); 11458 11459 final long curRealtime = SystemClock.elapsedRealtime(); 11460 final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime; 11461 final long curUptime = SystemClock.uptimeMillis(); 11462 final long uptimeSince = curUptime - service.mLastPowerCheckUptime; 11463 11464 for (int i=list.size()-1; i>=0; i--) { 11465 ProcessRecord r = list.get(i).first; 11466 String oomAdj = ProcessList.makeOomAdjString(r.setAdj); 11467 char schedGroup; 11468 switch (r.setSchedGroup) { 11469 case Process.THREAD_GROUP_BG_NONINTERACTIVE: 11470 schedGroup = 'B'; 11471 break; 11472 case Process.THREAD_GROUP_DEFAULT: 11473 schedGroup = 'F'; 11474 break; 11475 default: 11476 schedGroup = '?'; 11477 break; 11478 } 11479 char foreground; 11480 if (r.foregroundActivities) { 11481 foreground = 'A'; 11482 } else if (r.foregroundServices) { 11483 foreground = 'S'; 11484 } else { 11485 foreground = ' '; 11486 } 11487 String procState = ProcessList.makeProcStateString(r.curProcState); 11488 pw.print(prefix); 11489 pw.print(r.persistent ? persistentLabel : normalLabel); 11490 pw.print(" #"); 11491 int num = (origList.size()-1)-list.get(i).second; 11492 if (num < 10) pw.print(' '); 11493 pw.print(num); 11494 pw.print(": "); 11495 pw.print(oomAdj); 11496 pw.print(' '); 11497 pw.print(schedGroup); 11498 pw.print('/'); 11499 pw.print(foreground); 11500 pw.print('/'); 11501 pw.print(procState); 11502 pw.print(" trm:"); 11503 if (r.trimMemoryLevel < 10) pw.print(' '); 11504 pw.print(r.trimMemoryLevel); 11505 pw.print(' '); 11506 pw.print(r.toShortString()); 11507 pw.print(" ("); 11508 pw.print(r.adjType); 11509 pw.println(')'); 11510 if (r.adjSource != null || r.adjTarget != null) { 11511 pw.print(prefix); 11512 pw.print(" "); 11513 if (r.adjTarget instanceof ComponentName) { 11514 pw.print(((ComponentName)r.adjTarget).flattenToShortString()); 11515 } else if (r.adjTarget != null) { 11516 pw.print(r.adjTarget.toString()); 11517 } else { 11518 pw.print("{null}"); 11519 } 11520 pw.print("<="); 11521 if (r.adjSource instanceof ProcessRecord) { 11522 pw.print("Proc{"); 11523 pw.print(((ProcessRecord)r.adjSource).toShortString()); 11524 pw.println("}"); 11525 } else if (r.adjSource != null) { 11526 pw.println(r.adjSource.toString()); 11527 } else { 11528 pw.println("{null}"); 11529 } 11530 } 11531 if (inclDetails) { 11532 pw.print(prefix); 11533 pw.print(" "); 11534 pw.print("oom: max="); pw.print(r.maxAdj); 11535 pw.print(" curRaw="); pw.print(r.curRawAdj); 11536 pw.print(" setRaw="); pw.print(r.setRawAdj); 11537 pw.print(" cur="); pw.print(r.curAdj); 11538 pw.print(" set="); pw.println(r.setAdj); 11539 pw.print(prefix); 11540 pw.print(" "); 11541 pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState)); 11542 pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState)); 11543 pw.print(" lastPss="); pw.print(r.lastPss); 11544 pw.print(" lastCachedPss="); pw.println(r.lastCachedPss); 11545 pw.print(prefix); 11546 pw.print(" "); 11547 pw.print("keeping="); pw.print(r.keeping); 11548 pw.print(" cached="); pw.print(r.cached); 11549 pw.print(" empty="); pw.print(r.empty); 11550 pw.print(" hasAboveClient="); pw.println(r.hasAboveClient); 11551 11552 if (!r.keeping) { 11553 if (r.lastWakeTime != 0) { 11554 long wtime; 11555 BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics(); 11556 synchronized (stats) { 11557 wtime = stats.getProcessWakeTime(r.info.uid, 11558 r.pid, curRealtime); 11559 } 11560 long timeUsed = wtime - r.lastWakeTime; 11561 pw.print(prefix); 11562 pw.print(" "); 11563 pw.print("keep awake over "); 11564 TimeUtils.formatDuration(realtimeSince, pw); 11565 pw.print(" used "); 11566 TimeUtils.formatDuration(timeUsed, pw); 11567 pw.print(" ("); 11568 pw.print((timeUsed*100)/realtimeSince); 11569 pw.println("%)"); 11570 } 11571 if (r.lastCpuTime != 0) { 11572 long timeUsed = r.curCpuTime - r.lastCpuTime; 11573 pw.print(prefix); 11574 pw.print(" "); 11575 pw.print("run cpu over "); 11576 TimeUtils.formatDuration(uptimeSince, pw); 11577 pw.print(" used "); 11578 TimeUtils.formatDuration(timeUsed, pw); 11579 pw.print(" ("); 11580 pw.print((timeUsed*100)/uptimeSince); 11581 pw.println("%)"); 11582 } 11583 } 11584 } 11585 } 11586 return true; 11587 } 11588 11589 ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) { 11590 ArrayList<ProcessRecord> procs; 11591 synchronized (this) { 11592 if (args != null && args.length > start 11593 && args[start].charAt(0) != '-') { 11594 procs = new ArrayList<ProcessRecord>(); 11595 int pid = -1; 11596 try { 11597 pid = Integer.parseInt(args[start]); 11598 } catch (NumberFormatException e) { 11599 } 11600 for (int i=mLruProcesses.size()-1; i>=0; i--) { 11601 ProcessRecord proc = mLruProcesses.get(i); 11602 if (proc.pid == pid) { 11603 procs.add(proc); 11604 } else if (proc.processName.equals(args[start])) { 11605 procs.add(proc); 11606 } 11607 } 11608 if (procs.size() <= 0) { 11609 return null; 11610 } 11611 } else { 11612 procs = new ArrayList<ProcessRecord>(mLruProcesses); 11613 } 11614 } 11615 return procs; 11616 } 11617 11618 final void dumpGraphicsHardwareUsage(FileDescriptor fd, 11619 PrintWriter pw, String[] args) { 11620 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args); 11621 if (procs == null) { 11622 pw.println("No process found for: " + args[0]); 11623 return; 11624 } 11625 11626 long uptime = SystemClock.uptimeMillis(); 11627 long realtime = SystemClock.elapsedRealtime(); 11628 pw.println("Applications Graphics Acceleration Info:"); 11629 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 11630 11631 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 11632 ProcessRecord r = procs.get(i); 11633 if (r.thread != null) { 11634 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **"); 11635 pw.flush(); 11636 try { 11637 TransferPipe tp = new TransferPipe(); 11638 try { 11639 r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args); 11640 tp.go(fd); 11641 } finally { 11642 tp.kill(); 11643 } 11644 } catch (IOException e) { 11645 pw.println("Failure while dumping the app: " + r); 11646 pw.flush(); 11647 } catch (RemoteException e) { 11648 pw.println("Got a RemoteException while dumping the app " + r); 11649 pw.flush(); 11650 } 11651 } 11652 } 11653 } 11654 11655 final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) { 11656 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args); 11657 if (procs == null) { 11658 pw.println("No process found for: " + args[0]); 11659 return; 11660 } 11661 11662 pw.println("Applications Database Info:"); 11663 11664 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 11665 ProcessRecord r = procs.get(i); 11666 if (r.thread != null) { 11667 pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **"); 11668 pw.flush(); 11669 try { 11670 TransferPipe tp = new TransferPipe(); 11671 try { 11672 r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args); 11673 tp.go(fd); 11674 } finally { 11675 tp.kill(); 11676 } 11677 } catch (IOException e) { 11678 pw.println("Failure while dumping the app: " + r); 11679 pw.flush(); 11680 } catch (RemoteException e) { 11681 pw.println("Got a RemoteException while dumping the app " + r); 11682 pw.flush(); 11683 } 11684 } 11685 } 11686 } 11687 11688 final static class MemItem { 11689 final boolean isProc; 11690 final String label; 11691 final String shortLabel; 11692 final long pss; 11693 final int id; 11694 final boolean hasActivities; 11695 ArrayList<MemItem> subitems; 11696 11697 public MemItem(String _label, String _shortLabel, long _pss, int _id, 11698 boolean _hasActivities) { 11699 isProc = true; 11700 label = _label; 11701 shortLabel = _shortLabel; 11702 pss = _pss; 11703 id = _id; 11704 hasActivities = _hasActivities; 11705 } 11706 11707 public MemItem(String _label, String _shortLabel, long _pss, int _id) { 11708 isProc = false; 11709 label = _label; 11710 shortLabel = _shortLabel; 11711 pss = _pss; 11712 id = _id; 11713 hasActivities = false; 11714 } 11715 } 11716 11717 static final void dumpMemItems(PrintWriter pw, String prefix, String tag, 11718 ArrayList<MemItem> items, boolean sort, boolean isCompact) { 11719 if (sort && !isCompact) { 11720 Collections.sort(items, new Comparator<MemItem>() { 11721 @Override 11722 public int compare(MemItem lhs, MemItem rhs) { 11723 if (lhs.pss < rhs.pss) { 11724 return 1; 11725 } else if (lhs.pss > rhs.pss) { 11726 return -1; 11727 } 11728 return 0; 11729 } 11730 }); 11731 } 11732 11733 for (int i=0; i<items.size(); i++) { 11734 MemItem mi = items.get(i); 11735 if (!isCompact) { 11736 pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label); 11737 } else if (mi.isProc) { 11738 pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel); 11739 pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss); 11740 pw.println(mi.hasActivities ? ",a" : ",e"); 11741 } else { 11742 pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(","); 11743 pw.println(mi.pss); 11744 } 11745 if (mi.subitems != null) { 11746 dumpMemItems(pw, prefix + " ", mi.shortLabel, mi.subitems, 11747 true, isCompact); 11748 } 11749 } 11750 } 11751 11752 // These are in KB. 11753 static final long[] DUMP_MEM_BUCKETS = new long[] { 11754 5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024, 11755 120*1024, 160*1024, 200*1024, 11756 250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024, 11757 1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024 11758 }; 11759 11760 static final void appendMemBucket(StringBuilder out, long memKB, String label, 11761 boolean stackLike) { 11762 int start = label.lastIndexOf('.'); 11763 if (start >= 0) start++; 11764 else start = 0; 11765 int end = label.length(); 11766 for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) { 11767 if (DUMP_MEM_BUCKETS[i] >= memKB) { 11768 long bucket = DUMP_MEM_BUCKETS[i]/1024; 11769 out.append(bucket); 11770 out.append(stackLike ? "MB." : "MB "); 11771 out.append(label, start, end); 11772 return; 11773 } 11774 } 11775 out.append(memKB/1024); 11776 out.append(stackLike ? "MB." : "MB "); 11777 out.append(label, start, end); 11778 } 11779 11780 static final int[] DUMP_MEM_OOM_ADJ = new int[] { 11781 ProcessList.NATIVE_ADJ, 11782 ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ, 11783 ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ, 11784 ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ, 11785 ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ, 11786 ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ 11787 }; 11788 static final String[] DUMP_MEM_OOM_LABEL = new String[] { 11789 "Native", 11790 "System", "Persistent", "Foreground", 11791 "Visible", "Perceptible", 11792 "Heavy Weight", "Backup", 11793 "A Services", "Home", 11794 "Previous", "B Services", "Cached" 11795 }; 11796 static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] { 11797 "native", 11798 "sys", "pers", "fore", 11799 "vis", "percept", 11800 "heavy", "backup", 11801 "servicea", "home", 11802 "prev", "serviceb", "cached" 11803 }; 11804 11805 private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime, 11806 long realtime, boolean isCheckinRequest, boolean isCompact) { 11807 if (isCheckinRequest || isCompact) { 11808 // short checkin version 11809 pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime); 11810 } else { 11811 pw.println("Applications Memory Usage (kB):"); 11812 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 11813 } 11814 } 11815 11816 final void dumpApplicationMemoryUsage(FileDescriptor fd, 11817 PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) { 11818 boolean dumpDetails = false; 11819 boolean dumpFullDetails = false; 11820 boolean dumpDalvik = false; 11821 boolean oomOnly = false; 11822 boolean isCompact = false; 11823 boolean localOnly = false; 11824 11825 int opti = 0; 11826 while (opti < args.length) { 11827 String opt = args[opti]; 11828 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 11829 break; 11830 } 11831 opti++; 11832 if ("-a".equals(opt)) { 11833 dumpDetails = true; 11834 dumpFullDetails = true; 11835 dumpDalvik = true; 11836 } else if ("-d".equals(opt)) { 11837 dumpDalvik = true; 11838 } else if ("-c".equals(opt)) { 11839 isCompact = true; 11840 } else if ("--oom".equals(opt)) { 11841 oomOnly = true; 11842 } else if ("--local".equals(opt)) { 11843 localOnly = true; 11844 } else if ("-h".equals(opt)) { 11845 pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]"); 11846 pw.println(" -a: include all available information for each process."); 11847 pw.println(" -d: include dalvik details when dumping process details."); 11848 pw.println(" -c: dump in a compact machine-parseable representation."); 11849 pw.println(" --oom: only show processes organized by oom adj."); 11850 pw.println(" --local: only collect details locally, don't call process."); 11851 pw.println("If [process] is specified it can be the name or "); 11852 pw.println("pid of a specific process to dump."); 11853 return; 11854 } else { 11855 pw.println("Unknown argument: " + opt + "; use -h for help"); 11856 } 11857 } 11858 11859 final boolean isCheckinRequest = scanArgs(args, "--checkin"); 11860 long uptime = SystemClock.uptimeMillis(); 11861 long realtime = SystemClock.elapsedRealtime(); 11862 final long[] tmpLong = new long[1]; 11863 11864 ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args); 11865 if (procs == null) { 11866 // No Java processes. Maybe they want to print a native process. 11867 if (args != null && args.length > opti 11868 && args[opti].charAt(0) != '-') { 11869 ArrayList<ProcessCpuTracker.Stats> nativeProcs 11870 = new ArrayList<ProcessCpuTracker.Stats>(); 11871 updateCpuStatsNow(); 11872 int findPid = -1; 11873 try { 11874 findPid = Integer.parseInt(args[opti]); 11875 } catch (NumberFormatException e) { 11876 } 11877 synchronized (mProcessCpuThread) { 11878 final int N = mProcessCpuTracker.countStats(); 11879 for (int i=0; i<N; i++) { 11880 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 11881 if (st.pid == findPid || (st.baseName != null 11882 && st.baseName.equals(args[opti]))) { 11883 nativeProcs.add(st); 11884 } 11885 } 11886 } 11887 if (nativeProcs.size() > 0) { 11888 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, 11889 isCompact); 11890 Debug.MemoryInfo mi = null; 11891 for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) { 11892 final ProcessCpuTracker.Stats r = nativeProcs.get(i); 11893 final int pid = r.pid; 11894 if (!isCheckinRequest && dumpDetails) { 11895 pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **"); 11896 } 11897 if (mi == null) { 11898 mi = new Debug.MemoryInfo(); 11899 } 11900 if (dumpDetails || (!brief && !oomOnly)) { 11901 Debug.getMemoryInfo(pid, mi); 11902 } else { 11903 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong); 11904 mi.dalvikPrivateDirty = (int)tmpLong[0]; 11905 } 11906 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails, 11907 dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0); 11908 if (isCheckinRequest) { 11909 pw.println(); 11910 } 11911 } 11912 return; 11913 } 11914 } 11915 pw.println("No process found for: " + args[opti]); 11916 return; 11917 } 11918 11919 if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest)) { 11920 dumpDetails = true; 11921 } 11922 11923 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact); 11924 11925 String[] innerArgs = new String[args.length-opti]; 11926 System.arraycopy(args, opti, innerArgs, 0, args.length-opti); 11927 11928 ArrayList<MemItem> procMems = new ArrayList<MemItem>(); 11929 final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>(); 11930 long nativePss=0, dalvikPss=0, otherPss=0; 11931 long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS]; 11932 11933 long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length]; 11934 ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[]) 11935 new ArrayList[DUMP_MEM_OOM_LABEL.length]; 11936 11937 long totalPss = 0; 11938 long cachedPss = 0; 11939 11940 Debug.MemoryInfo mi = null; 11941 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 11942 final ProcessRecord r = procs.get(i); 11943 final IApplicationThread thread; 11944 final int pid; 11945 final int oomAdj; 11946 final boolean hasActivities; 11947 synchronized (this) { 11948 thread = r.thread; 11949 pid = r.pid; 11950 oomAdj = r.getSetAdjWithServices(); 11951 hasActivities = r.activities.size() > 0; 11952 } 11953 if (thread != null) { 11954 if (!isCheckinRequest && dumpDetails) { 11955 pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **"); 11956 } 11957 if (mi == null) { 11958 mi = new Debug.MemoryInfo(); 11959 } 11960 if (dumpDetails || (!brief && !oomOnly)) { 11961 Debug.getMemoryInfo(pid, mi); 11962 } else { 11963 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong); 11964 mi.dalvikPrivateDirty = (int)tmpLong[0]; 11965 } 11966 if (dumpDetails) { 11967 if (localOnly) { 11968 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails, 11969 dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0); 11970 if (isCheckinRequest) { 11971 pw.println(); 11972 } 11973 } else { 11974 try { 11975 pw.flush(); 11976 thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails, 11977 dumpDalvik, innerArgs); 11978 } catch (RemoteException e) { 11979 if (!isCheckinRequest) { 11980 pw.println("Got RemoteException!"); 11981 pw.flush(); 11982 } 11983 } 11984 } 11985 } 11986 11987 final long myTotalPss = mi.getTotalPss(); 11988 final long myTotalUss = mi.getTotalUss(); 11989 11990 synchronized (this) { 11991 if (r.thread != null && oomAdj == r.getSetAdjWithServices()) { 11992 // Record this for posterity if the process has been stable. 11993 r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList); 11994 } 11995 } 11996 11997 if (!isCheckinRequest && mi != null) { 11998 totalPss += myTotalPss; 11999 MemItem pssItem = new MemItem(r.processName + " (pid " + pid + 12000 (hasActivities ? " / activities)" : ")"), 12001 r.processName, myTotalPss, pid, hasActivities); 12002 procMems.add(pssItem); 12003 procMemsMap.put(pid, pssItem); 12004 12005 nativePss += mi.nativePss; 12006 dalvikPss += mi.dalvikPss; 12007 otherPss += mi.otherPss; 12008 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 12009 long mem = mi.getOtherPss(j); 12010 miscPss[j] += mem; 12011 otherPss -= mem; 12012 } 12013 12014 if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 12015 cachedPss += myTotalPss; 12016 } 12017 12018 for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) { 12019 if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex] 12020 || oomIndex == (oomPss.length-1)) { 12021 oomPss[oomIndex] += myTotalPss; 12022 if (oomProcs[oomIndex] == null) { 12023 oomProcs[oomIndex] = new ArrayList<MemItem>(); 12024 } 12025 oomProcs[oomIndex].add(pssItem); 12026 break; 12027 } 12028 } 12029 } 12030 } 12031 } 12032 12033 if (!isCheckinRequest && procs.size() > 1) { 12034 // If we are showing aggregations, also look for native processes to 12035 // include so that our aggregations are more accurate. 12036 updateCpuStatsNow(); 12037 synchronized (mProcessCpuThread) { 12038 final int N = mProcessCpuTracker.countStats(); 12039 for (int i=0; i<N; i++) { 12040 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 12041 if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) { 12042 if (mi == null) { 12043 mi = new Debug.MemoryInfo(); 12044 } 12045 if (!brief && !oomOnly) { 12046 Debug.getMemoryInfo(st.pid, mi); 12047 } else { 12048 mi.nativePss = (int)Debug.getPss(st.pid, tmpLong); 12049 mi.nativePrivateDirty = (int)tmpLong[0]; 12050 } 12051 12052 final long myTotalPss = mi.getTotalPss(); 12053 totalPss += myTotalPss; 12054 12055 MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")", 12056 st.name, myTotalPss, st.pid, false); 12057 procMems.add(pssItem); 12058 12059 nativePss += mi.nativePss; 12060 dalvikPss += mi.dalvikPss; 12061 otherPss += mi.otherPss; 12062 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 12063 long mem = mi.getOtherPss(j); 12064 miscPss[j] += mem; 12065 otherPss -= mem; 12066 } 12067 oomPss[0] += myTotalPss; 12068 if (oomProcs[0] == null) { 12069 oomProcs[0] = new ArrayList<MemItem>(); 12070 } 12071 oomProcs[0].add(pssItem); 12072 } 12073 } 12074 } 12075 12076 ArrayList<MemItem> catMems = new ArrayList<MemItem>(); 12077 12078 catMems.add(new MemItem("Native", "Native", nativePss, -1)); 12079 catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2)); 12080 catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3)); 12081 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 12082 String label = Debug.MemoryInfo.getOtherLabel(j); 12083 catMems.add(new MemItem(label, label, miscPss[j], j)); 12084 } 12085 12086 ArrayList<MemItem> oomMems = new ArrayList<MemItem>(); 12087 for (int j=0; j<oomPss.length; j++) { 12088 if (oomPss[j] != 0) { 12089 String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j] 12090 : DUMP_MEM_OOM_LABEL[j]; 12091 MemItem item = new MemItem(label, label, oomPss[j], 12092 DUMP_MEM_OOM_ADJ[j]); 12093 item.subitems = oomProcs[j]; 12094 oomMems.add(item); 12095 } 12096 } 12097 12098 if (!brief && !oomOnly && !isCompact) { 12099 pw.println(); 12100 pw.println("Total PSS by process:"); 12101 dumpMemItems(pw, " ", "proc", procMems, true, isCompact); 12102 pw.println(); 12103 } 12104 if (!isCompact) { 12105 pw.println("Total PSS by OOM adjustment:"); 12106 } 12107 dumpMemItems(pw, " ", "oom", oomMems, false, isCompact); 12108 if (!brief && !oomOnly) { 12109 PrintWriter out = categoryPw != null ? categoryPw : pw; 12110 if (!isCompact) { 12111 out.println(); 12112 out.println("Total PSS by category:"); 12113 } 12114 dumpMemItems(out, " ", "cat", catMems, true, isCompact); 12115 } 12116 if (!isCompact) { 12117 pw.println(); 12118 } 12119 MemInfoReader memInfo = new MemInfoReader(); 12120 memInfo.readMemInfo(); 12121 if (!brief) { 12122 if (!isCompact) { 12123 pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb()); 12124 pw.println(" kB"); 12125 pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb() 12126 + memInfo.getFreeSizeKb()); pw.print(" kB ("); 12127 pw.print(cachedPss); pw.print(" cached pss + "); 12128 pw.print(memInfo.getCachedSizeKb()); pw.print(" cached + "); 12129 pw.print(memInfo.getFreeSizeKb()); pw.println(" free)"); 12130 } else { 12131 pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(","); 12132 pw.print(cachedPss + memInfo.getCachedSizeKb() 12133 + memInfo.getFreeSizeKb()); pw.print(","); 12134 pw.println(totalPss - cachedPss); 12135 } 12136 } 12137 if (!isCompact) { 12138 pw.print(" Used RAM: "); pw.print(totalPss - cachedPss 12139 + memInfo.getBuffersSizeKb() + memInfo.getShmemSizeKb() 12140 + memInfo.getSlabSizeKb()); pw.print(" kB ("); 12141 pw.print(totalPss - cachedPss); pw.print(" used pss + "); 12142 pw.print(memInfo.getBuffersSizeKb()); pw.print(" buffers + "); 12143 pw.print(memInfo.getShmemSizeKb()); pw.print(" shmem + "); 12144 pw.print(memInfo.getSlabSizeKb()); pw.println(" slab)"); 12145 pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb() 12146 - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb() 12147 - memInfo.getBuffersSizeKb() - memInfo.getShmemSizeKb() 12148 - memInfo.getSlabSizeKb()); pw.println(" kB"); 12149 } 12150 if (!brief) { 12151 if (memInfo.getZramTotalSizeKb() != 0) { 12152 if (!isCompact) { 12153 pw.print(" ZRAM: "); pw.print(memInfo.getZramTotalSizeKb()); 12154 pw.print(" kB physical used for "); 12155 pw.print(memInfo.getSwapTotalSizeKb() 12156 - memInfo.getSwapFreeSizeKb()); 12157 pw.print(" kB in swap ("); 12158 pw.print(memInfo.getSwapTotalSizeKb()); 12159 pw.println(" kB total swap)"); 12160 } else { 12161 pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(","); 12162 pw.print(memInfo.getSwapTotalSizeKb()); pw.print(","); 12163 pw.println(memInfo.getSwapFreeSizeKb()); 12164 } 12165 } 12166 final int[] SINGLE_LONG_FORMAT = new int[] { 12167 Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG 12168 }; 12169 long[] longOut = new long[1]; 12170 Process.readProcFile("/sys/kernel/mm/ksm/pages_shared", 12171 SINGLE_LONG_FORMAT, null, longOut, null); 12172 long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024; 12173 longOut[0] = 0; 12174 Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing", 12175 SINGLE_LONG_FORMAT, null, longOut, null); 12176 long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024; 12177 longOut[0] = 0; 12178 Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared", 12179 SINGLE_LONG_FORMAT, null, longOut, null); 12180 long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024; 12181 longOut[0] = 0; 12182 Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile", 12183 SINGLE_LONG_FORMAT, null, longOut, null); 12184 long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024; 12185 if (!isCompact) { 12186 if (sharing != 0 || shared != 0 || unshared != 0 || voltile != 0) { 12187 pw.print(" KSM: "); pw.print(sharing); 12188 pw.print(" kB saved from shared "); 12189 pw.print(shared); pw.println(" kB"); 12190 pw.print(" "); pw.print(unshared); pw.print(" kB unshared; "); 12191 pw.print(voltile); pw.println(" kB volatile"); 12192 } 12193 pw.print(" Tuning: "); 12194 pw.print(ActivityManager.staticGetMemoryClass()); 12195 pw.print(" (large "); 12196 pw.print(ActivityManager.staticGetLargeMemoryClass()); 12197 pw.print("), oom "); 12198 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024); 12199 pw.print(" kB"); 12200 pw.print(", restore limit "); 12201 pw.print(mProcessList.getCachedRestoreThresholdKb()); 12202 pw.print(" kB"); 12203 if (ActivityManager.isLowRamDeviceStatic()) { 12204 pw.print(" (low-ram)"); 12205 } 12206 if (ActivityManager.isHighEndGfx()) { 12207 pw.print(" (high-end-gfx)"); 12208 } 12209 pw.println(); 12210 } else { 12211 pw.print("ksm,"); pw.print(sharing); pw.print(","); 12212 pw.print(shared); pw.print(","); pw.print(unshared); pw.print(","); 12213 pw.println(voltile); 12214 pw.print("tuning,"); 12215 pw.print(ActivityManager.staticGetMemoryClass()); 12216 pw.print(','); 12217 pw.print(ActivityManager.staticGetLargeMemoryClass()); 12218 pw.print(','); 12219 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024); 12220 if (ActivityManager.isLowRamDeviceStatic()) { 12221 pw.print(",low-ram"); 12222 } 12223 if (ActivityManager.isHighEndGfx()) { 12224 pw.print(",high-end-gfx"); 12225 } 12226 pw.println(); 12227 } 12228 } 12229 } 12230 } 12231 12232 /** 12233 * Searches array of arguments for the specified string 12234 * @param args array of argument strings 12235 * @param value value to search for 12236 * @return true if the value is contained in the array 12237 */ 12238 private static boolean scanArgs(String[] args, String value) { 12239 if (args != null) { 12240 for (String arg : args) { 12241 if (value.equals(arg)) { 12242 return true; 12243 } 12244 } 12245 } 12246 return false; 12247 } 12248 12249 private final boolean removeDyingProviderLocked(ProcessRecord proc, 12250 ContentProviderRecord cpr, boolean always) { 12251 final boolean inLaunching = mLaunchingProviders.contains(cpr); 12252 12253 if (!inLaunching || always) { 12254 synchronized (cpr) { 12255 cpr.launchingApp = null; 12256 cpr.notifyAll(); 12257 } 12258 mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid)); 12259 String names[] = cpr.info.authority.split(";"); 12260 for (int j = 0; j < names.length; j++) { 12261 mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid)); 12262 } 12263 } 12264 12265 for (int i=0; i<cpr.connections.size(); i++) { 12266 ContentProviderConnection conn = cpr.connections.get(i); 12267 if (conn.waiting) { 12268 // If this connection is waiting for the provider, then we don't 12269 // need to mess with its process unless we are always removing 12270 // or for some reason the provider is not currently launching. 12271 if (inLaunching && !always) { 12272 continue; 12273 } 12274 } 12275 ProcessRecord capp = conn.client; 12276 conn.dead = true; 12277 if (conn.stableCount > 0) { 12278 if (!capp.persistent && capp.thread != null 12279 && capp.pid != 0 12280 && capp.pid != MY_PID) { 12281 killUnneededProcessLocked(capp, "depends on provider " 12282 + cpr.name.flattenToShortString() 12283 + " in dying proc " + (proc != null ? proc.processName : "??")); 12284 } 12285 } else if (capp.thread != null && conn.provider.provider != null) { 12286 try { 12287 capp.thread.unstableProviderDied(conn.provider.provider.asBinder()); 12288 } catch (RemoteException e) { 12289 } 12290 // In the protocol here, we don't expect the client to correctly 12291 // clean up this connection, we'll just remove it. 12292 cpr.connections.remove(i); 12293 conn.client.conProviders.remove(conn); 12294 } 12295 } 12296 12297 if (inLaunching && always) { 12298 mLaunchingProviders.remove(cpr); 12299 } 12300 return inLaunching; 12301 } 12302 12303 /** 12304 * Main code for cleaning up a process when it has gone away. This is 12305 * called both as a result of the process dying, or directly when stopping 12306 * a process when running in single process mode. 12307 */ 12308 private final void cleanUpApplicationRecordLocked(ProcessRecord app, 12309 boolean restarting, boolean allowRestart, int index) { 12310 if (index >= 0) { 12311 removeLruProcessLocked(app); 12312 ProcessList.remove(app.pid); 12313 } 12314 12315 mProcessesToGc.remove(app); 12316 mPendingPssProcesses.remove(app); 12317 12318 // Dismiss any open dialogs. 12319 if (app.crashDialog != null && !app.forceCrashReport) { 12320 app.crashDialog.dismiss(); 12321 app.crashDialog = null; 12322 } 12323 if (app.anrDialog != null) { 12324 app.anrDialog.dismiss(); 12325 app.anrDialog = null; 12326 } 12327 if (app.waitDialog != null) { 12328 app.waitDialog.dismiss(); 12329 app.waitDialog = null; 12330 } 12331 12332 app.crashing = false; 12333 app.notResponding = false; 12334 12335 app.resetPackageList(mProcessStats); 12336 app.unlinkDeathRecipient(); 12337 app.makeInactive(mProcessStats); 12338 app.forcingToForeground = null; 12339 app.foregroundServices = false; 12340 app.foregroundActivities = false; 12341 app.hasShownUi = false; 12342 app.hasAboveClient = false; 12343 12344 mServices.killServicesLocked(app, allowRestart); 12345 12346 boolean restart = false; 12347 12348 // Remove published content providers. 12349 for (int i=app.pubProviders.size()-1; i>=0; i--) { 12350 ContentProviderRecord cpr = app.pubProviders.valueAt(i); 12351 final boolean always = app.bad || !allowRestart; 12352 if (removeDyingProviderLocked(app, cpr, always) || always) { 12353 // We left the provider in the launching list, need to 12354 // restart it. 12355 restart = true; 12356 } 12357 12358 cpr.provider = null; 12359 cpr.proc = null; 12360 } 12361 app.pubProviders.clear(); 12362 12363 // Take care of any launching providers waiting for this process. 12364 if (checkAppInLaunchingProvidersLocked(app, false)) { 12365 restart = true; 12366 } 12367 12368 // Unregister from connected content providers. 12369 if (!app.conProviders.isEmpty()) { 12370 for (int i=0; i<app.conProviders.size(); i++) { 12371 ContentProviderConnection conn = app.conProviders.get(i); 12372 conn.provider.connections.remove(conn); 12373 } 12374 app.conProviders.clear(); 12375 } 12376 12377 // At this point there may be remaining entries in mLaunchingProviders 12378 // where we were the only one waiting, so they are no longer of use. 12379 // Look for these and clean up if found. 12380 // XXX Commented out for now. Trying to figure out a way to reproduce 12381 // the actual situation to identify what is actually going on. 12382 if (false) { 12383 for (int i=0; i<mLaunchingProviders.size(); i++) { 12384 ContentProviderRecord cpr = (ContentProviderRecord) 12385 mLaunchingProviders.get(i); 12386 if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) { 12387 synchronized (cpr) { 12388 cpr.launchingApp = null; 12389 cpr.notifyAll(); 12390 } 12391 } 12392 } 12393 } 12394 12395 skipCurrentReceiverLocked(app); 12396 12397 // Unregister any receivers. 12398 for (int i=app.receivers.size()-1; i>=0; i--) { 12399 removeReceiverLocked(app.receivers.valueAt(i)); 12400 } 12401 app.receivers.clear(); 12402 12403 // If the app is undergoing backup, tell the backup manager about it 12404 if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) { 12405 if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App " 12406 + mBackupTarget.appInfo + " died during backup"); 12407 try { 12408 IBackupManager bm = IBackupManager.Stub.asInterface( 12409 ServiceManager.getService(Context.BACKUP_SERVICE)); 12410 bm.agentDisconnected(app.info.packageName); 12411 } catch (RemoteException e) { 12412 // can't happen; backup manager is local 12413 } 12414 } 12415 12416 for (int i = mPendingProcessChanges.size()-1; i>=0; i--) { 12417 ProcessChangeItem item = mPendingProcessChanges.get(i); 12418 if (item.pid == app.pid) { 12419 mPendingProcessChanges.remove(i); 12420 mAvailProcessChanges.add(item); 12421 } 12422 } 12423 mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget(); 12424 12425 // If the caller is restarting this app, then leave it in its 12426 // current lists and let the caller take care of it. 12427 if (restarting) { 12428 return; 12429 } 12430 12431 if (!app.persistent || app.isolated) { 12432 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, 12433 "Removing non-persistent process during cleanup: " + app); 12434 mProcessNames.remove(app.processName, app.uid); 12435 mIsolatedProcesses.remove(app.uid); 12436 if (mHeavyWeightProcess == app) { 12437 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 12438 mHeavyWeightProcess.userId, 0)); 12439 mHeavyWeightProcess = null; 12440 } 12441 } else if (!app.removed) { 12442 // This app is persistent, so we need to keep its record around. 12443 // If it is not already on the pending app list, add it there 12444 // and start a new process for it. 12445 if (mPersistentStartingProcesses.indexOf(app) < 0) { 12446 mPersistentStartingProcesses.add(app); 12447 restart = true; 12448 } 12449 } 12450 if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG, 12451 "Clean-up removing on hold: " + app); 12452 mProcessesOnHold.remove(app); 12453 12454 if (app == mHomeProcess) { 12455 mHomeProcess = null; 12456 } 12457 if (app == mPreviousProcess) { 12458 mPreviousProcess = null; 12459 } 12460 12461 if (restart && !app.isolated) { 12462 // We have components that still need to be running in the 12463 // process, so re-launch it. 12464 mProcessNames.put(app.processName, app.uid, app); 12465 startProcessLocked(app, "restart", app.processName); 12466 } else if (app.pid > 0 && app.pid != MY_PID) { 12467 // Goodbye! 12468 boolean removed; 12469 synchronized (mPidsSelfLocked) { 12470 mPidsSelfLocked.remove(app.pid); 12471 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 12472 } 12473 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISHED, 12474 app.processName, app.info.uid); 12475 if (app.isolated) { 12476 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 12477 } 12478 app.setPid(0); 12479 } 12480 } 12481 12482 boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) { 12483 // Look through the content providers we are waiting to have launched, 12484 // and if any run in this process then either schedule a restart of 12485 // the process or kill the client waiting for it if this process has 12486 // gone bad. 12487 int NL = mLaunchingProviders.size(); 12488 boolean restart = false; 12489 for (int i=0; i<NL; i++) { 12490 ContentProviderRecord cpr = mLaunchingProviders.get(i); 12491 if (cpr.launchingApp == app) { 12492 if (!alwaysBad && !app.bad) { 12493 restart = true; 12494 } else { 12495 removeDyingProviderLocked(app, cpr, true); 12496 // cpr should have been removed from mLaunchingProviders 12497 NL = mLaunchingProviders.size(); 12498 i--; 12499 } 12500 } 12501 } 12502 return restart; 12503 } 12504 12505 // ========================================================= 12506 // SERVICES 12507 // ========================================================= 12508 12509 public List<ActivityManager.RunningServiceInfo> getServices(int maxNum, 12510 int flags) { 12511 enforceNotIsolatedCaller("getServices"); 12512 synchronized (this) { 12513 return mServices.getRunningServiceInfoLocked(maxNum, flags); 12514 } 12515 } 12516 12517 public PendingIntent getRunningServiceControlPanel(ComponentName name) { 12518 enforceNotIsolatedCaller("getRunningServiceControlPanel"); 12519 synchronized (this) { 12520 return mServices.getRunningServiceControlPanelLocked(name); 12521 } 12522 } 12523 12524 public ComponentName startService(IApplicationThread caller, Intent service, 12525 String resolvedType, int userId) { 12526 enforceNotIsolatedCaller("startService"); 12527 // Refuse possible leaked file descriptors 12528 if (service != null && service.hasFileDescriptors() == true) { 12529 throw new IllegalArgumentException("File descriptors passed in Intent"); 12530 } 12531 12532 if (DEBUG_SERVICE) 12533 Slog.v(TAG, "startService: " + service + " type=" + resolvedType); 12534 synchronized(this) { 12535 final int callingPid = Binder.getCallingPid(); 12536 final int callingUid = Binder.getCallingUid(); 12537 final long origId = Binder.clearCallingIdentity(); 12538 ComponentName res = mServices.startServiceLocked(caller, service, 12539 resolvedType, callingPid, callingUid, userId); 12540 Binder.restoreCallingIdentity(origId); 12541 return res; 12542 } 12543 } 12544 12545 ComponentName startServiceInPackage(int uid, 12546 Intent service, String resolvedType, int userId) { 12547 synchronized(this) { 12548 if (DEBUG_SERVICE) 12549 Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType); 12550 final long origId = Binder.clearCallingIdentity(); 12551 ComponentName res = mServices.startServiceLocked(null, service, 12552 resolvedType, -1, uid, userId); 12553 Binder.restoreCallingIdentity(origId); 12554 return res; 12555 } 12556 } 12557 12558 public int stopService(IApplicationThread caller, Intent service, 12559 String resolvedType, int userId) { 12560 enforceNotIsolatedCaller("stopService"); 12561 // Refuse possible leaked file descriptors 12562 if (service != null && service.hasFileDescriptors() == true) { 12563 throw new IllegalArgumentException("File descriptors passed in Intent"); 12564 } 12565 12566 synchronized(this) { 12567 return mServices.stopServiceLocked(caller, service, resolvedType, userId); 12568 } 12569 } 12570 12571 public IBinder peekService(Intent service, String resolvedType) { 12572 enforceNotIsolatedCaller("peekService"); 12573 // Refuse possible leaked file descriptors 12574 if (service != null && service.hasFileDescriptors() == true) { 12575 throw new IllegalArgumentException("File descriptors passed in Intent"); 12576 } 12577 synchronized(this) { 12578 return mServices.peekServiceLocked(service, resolvedType); 12579 } 12580 } 12581 12582 public boolean stopServiceToken(ComponentName className, IBinder token, 12583 int startId) { 12584 synchronized(this) { 12585 return mServices.stopServiceTokenLocked(className, token, startId); 12586 } 12587 } 12588 12589 public void setServiceForeground(ComponentName className, IBinder token, 12590 int id, Notification notification, boolean removeNotification) { 12591 synchronized(this) { 12592 mServices.setServiceForegroundLocked(className, token, id, notification, 12593 removeNotification); 12594 } 12595 } 12596 12597 public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll, 12598 boolean requireFull, String name, String callerPackage) { 12599 final int callingUserId = UserHandle.getUserId(callingUid); 12600 if (callingUserId != userId) { 12601 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 12602 if ((requireFull || checkComponentPermission( 12603 android.Manifest.permission.INTERACT_ACROSS_USERS, 12604 callingPid, callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) 12605 && checkComponentPermission( 12606 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 12607 callingPid, callingUid, -1, true) 12608 != PackageManager.PERMISSION_GRANTED) { 12609 if (userId == UserHandle.USER_CURRENT_OR_SELF) { 12610 // In this case, they would like to just execute as their 12611 // owner user instead of failing. 12612 userId = callingUserId; 12613 } else { 12614 StringBuilder builder = new StringBuilder(128); 12615 builder.append("Permission Denial: "); 12616 builder.append(name); 12617 if (callerPackage != null) { 12618 builder.append(" from "); 12619 builder.append(callerPackage); 12620 } 12621 builder.append(" asks to run as user "); 12622 builder.append(userId); 12623 builder.append(" but is calling from user "); 12624 builder.append(UserHandle.getUserId(callingUid)); 12625 builder.append("; this requires "); 12626 builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL); 12627 if (!requireFull) { 12628 builder.append(" or "); 12629 builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS); 12630 } 12631 String msg = builder.toString(); 12632 Slog.w(TAG, msg); 12633 throw new SecurityException(msg); 12634 } 12635 } 12636 } 12637 if (userId == UserHandle.USER_CURRENT 12638 || userId == UserHandle.USER_CURRENT_OR_SELF) { 12639 // Note that we may be accessing this outside of a lock... 12640 // shouldn't be a big deal, if this is being called outside 12641 // of a locked context there is intrinsically a race with 12642 // the value the caller will receive and someone else changing it. 12643 userId = mCurrentUserId; 12644 } 12645 if (!allowAll && userId < 0) { 12646 throw new IllegalArgumentException( 12647 "Call does not support special user #" + userId); 12648 } 12649 } 12650 return userId; 12651 } 12652 12653 boolean isSingleton(String componentProcessName, ApplicationInfo aInfo, 12654 String className, int flags) { 12655 boolean result = false; 12656 if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) { 12657 if ((flags&ServiceInfo.FLAG_SINGLE_USER) != 0) { 12658 if (ActivityManager.checkUidPermission( 12659 android.Manifest.permission.INTERACT_ACROSS_USERS, 12660 aInfo.uid) != PackageManager.PERMISSION_GRANTED) { 12661 ComponentName comp = new ComponentName(aInfo.packageName, className); 12662 String msg = "Permission Denial: Component " + comp.flattenToShortString() 12663 + " requests FLAG_SINGLE_USER, but app does not hold " 12664 + android.Manifest.permission.INTERACT_ACROSS_USERS; 12665 Slog.w(TAG, msg); 12666 throw new SecurityException(msg); 12667 } 12668 result = true; 12669 } 12670 } else if (componentProcessName == aInfo.packageName) { 12671 result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0; 12672 } else if ("system".equals(componentProcessName)) { 12673 result = true; 12674 } 12675 if (DEBUG_MU) { 12676 Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo 12677 + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result); 12678 } 12679 return result; 12680 } 12681 12682 public int bindService(IApplicationThread caller, IBinder token, 12683 Intent service, String resolvedType, 12684 IServiceConnection connection, int flags, int userId) { 12685 enforceNotIsolatedCaller("bindService"); 12686 // Refuse possible leaked file descriptors 12687 if (service != null && service.hasFileDescriptors() == true) { 12688 throw new IllegalArgumentException("File descriptors passed in Intent"); 12689 } 12690 12691 synchronized(this) { 12692 return mServices.bindServiceLocked(caller, token, service, resolvedType, 12693 connection, flags, userId); 12694 } 12695 } 12696 12697 public boolean unbindService(IServiceConnection connection) { 12698 synchronized (this) { 12699 return mServices.unbindServiceLocked(connection); 12700 } 12701 } 12702 12703 public void publishService(IBinder token, Intent intent, IBinder service) { 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 if (!(token instanceof ServiceRecord)) { 12711 throw new IllegalArgumentException("Invalid service token"); 12712 } 12713 mServices.publishServiceLocked((ServiceRecord)token, intent, service); 12714 } 12715 } 12716 12717 public void unbindFinished(IBinder token, Intent intent, boolean doRebind) { 12718 // Refuse possible leaked file descriptors 12719 if (intent != null && intent.hasFileDescriptors() == true) { 12720 throw new IllegalArgumentException("File descriptors passed in Intent"); 12721 } 12722 12723 synchronized(this) { 12724 mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind); 12725 } 12726 } 12727 12728 public void serviceDoneExecuting(IBinder token, int type, int startId, int res) { 12729 synchronized(this) { 12730 if (!(token instanceof ServiceRecord)) { 12731 throw new IllegalArgumentException("Invalid service token"); 12732 } 12733 mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res); 12734 } 12735 } 12736 12737 // ========================================================= 12738 // BACKUP AND RESTORE 12739 // ========================================================= 12740 12741 // Cause the target app to be launched if necessary and its backup agent 12742 // instantiated. The backup agent will invoke backupAgentCreated() on the 12743 // activity manager to announce its creation. 12744 public boolean bindBackupAgent(ApplicationInfo app, int backupMode) { 12745 if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode); 12746 enforceCallingPermission("android.permission.BACKUP", "bindBackupAgent"); 12747 12748 synchronized(this) { 12749 // !!! TODO: currently no check here that we're already bound 12750 BatteryStatsImpl.Uid.Pkg.Serv ss = null; 12751 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 12752 synchronized (stats) { 12753 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name); 12754 } 12755 12756 // Backup agent is now in use, its package can't be stopped. 12757 try { 12758 AppGlobals.getPackageManager().setPackageStoppedState( 12759 app.packageName, false, UserHandle.getUserId(app.uid)); 12760 } catch (RemoteException e) { 12761 } catch (IllegalArgumentException e) { 12762 Slog.w(TAG, "Failed trying to unstop package " 12763 + app.packageName + ": " + e); 12764 } 12765 12766 BackupRecord r = new BackupRecord(ss, app, backupMode); 12767 ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL) 12768 ? new ComponentName(app.packageName, app.backupAgentName) 12769 : new ComponentName("android", "FullBackupAgent"); 12770 // startProcessLocked() returns existing proc's record if it's already running 12771 ProcessRecord proc = startProcessLocked(app.processName, app, 12772 false, 0, "backup", hostingName, false, false, false); 12773 if (proc == null) { 12774 Slog.e(TAG, "Unable to start backup agent process " + r); 12775 return false; 12776 } 12777 12778 r.app = proc; 12779 mBackupTarget = r; 12780 mBackupAppName = app.packageName; 12781 12782 // Try not to kill the process during backup 12783 updateOomAdjLocked(proc); 12784 12785 // If the process is already attached, schedule the creation of the backup agent now. 12786 // If it is not yet live, this will be done when it attaches to the framework. 12787 if (proc.thread != null) { 12788 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc); 12789 try { 12790 proc.thread.scheduleCreateBackupAgent(app, 12791 compatibilityInfoForPackageLocked(app), backupMode); 12792 } catch (RemoteException e) { 12793 // Will time out on the backup manager side 12794 } 12795 } else { 12796 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach"); 12797 } 12798 // Invariants: at this point, the target app process exists and the application 12799 // is either already running or in the process of coming up. mBackupTarget and 12800 // mBackupAppName describe the app, so that when it binds back to the AM we 12801 // know that it's scheduled for a backup-agent operation. 12802 } 12803 12804 return true; 12805 } 12806 12807 @Override 12808 public void clearPendingBackup() { 12809 if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup"); 12810 enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup"); 12811 12812 synchronized (this) { 12813 mBackupTarget = null; 12814 mBackupAppName = null; 12815 } 12816 } 12817 12818 // A backup agent has just come up 12819 public void backupAgentCreated(String agentPackageName, IBinder agent) { 12820 if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName 12821 + " = " + agent); 12822 12823 synchronized(this) { 12824 if (!agentPackageName.equals(mBackupAppName)) { 12825 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!"); 12826 return; 12827 } 12828 } 12829 12830 long oldIdent = Binder.clearCallingIdentity(); 12831 try { 12832 IBackupManager bm = IBackupManager.Stub.asInterface( 12833 ServiceManager.getService(Context.BACKUP_SERVICE)); 12834 bm.agentConnected(agentPackageName, agent); 12835 } catch (RemoteException e) { 12836 // can't happen; the backup manager service is local 12837 } catch (Exception e) { 12838 Slog.w(TAG, "Exception trying to deliver BackupAgent binding: "); 12839 e.printStackTrace(); 12840 } finally { 12841 Binder.restoreCallingIdentity(oldIdent); 12842 } 12843 } 12844 12845 // done with this agent 12846 public void unbindBackupAgent(ApplicationInfo appInfo) { 12847 if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo); 12848 if (appInfo == null) { 12849 Slog.w(TAG, "unbind backup agent for null app"); 12850 return; 12851 } 12852 12853 synchronized(this) { 12854 try { 12855 if (mBackupAppName == null) { 12856 Slog.w(TAG, "Unbinding backup agent with no active backup"); 12857 return; 12858 } 12859 12860 if (!mBackupAppName.equals(appInfo.packageName)) { 12861 Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target"); 12862 return; 12863 } 12864 12865 // Not backing this app up any more; reset its OOM adjustment 12866 final ProcessRecord proc = mBackupTarget.app; 12867 updateOomAdjLocked(proc); 12868 12869 // If the app crashed during backup, 'thread' will be null here 12870 if (proc.thread != null) { 12871 try { 12872 proc.thread.scheduleDestroyBackupAgent(appInfo, 12873 compatibilityInfoForPackageLocked(appInfo)); 12874 } catch (Exception e) { 12875 Slog.e(TAG, "Exception when unbinding backup agent:"); 12876 e.printStackTrace(); 12877 } 12878 } 12879 } finally { 12880 mBackupTarget = null; 12881 mBackupAppName = null; 12882 } 12883 } 12884 } 12885 // ========================================================= 12886 // BROADCASTS 12887 // ========================================================= 12888 12889 private final List getStickiesLocked(String action, IntentFilter filter, 12890 List cur, int userId) { 12891 final ContentResolver resolver = mContext.getContentResolver(); 12892 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 12893 if (stickies == null) { 12894 return cur; 12895 } 12896 final ArrayList<Intent> list = stickies.get(action); 12897 if (list == null) { 12898 return cur; 12899 } 12900 int N = list.size(); 12901 for (int i=0; i<N; i++) { 12902 Intent intent = list.get(i); 12903 if (filter.match(resolver, intent, true, TAG) >= 0) { 12904 if (cur == null) { 12905 cur = new ArrayList<Intent>(); 12906 } 12907 cur.add(intent); 12908 } 12909 } 12910 return cur; 12911 } 12912 12913 boolean isPendingBroadcastProcessLocked(int pid) { 12914 return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid) 12915 || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid); 12916 } 12917 12918 void skipPendingBroadcastLocked(int pid) { 12919 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 12920 for (BroadcastQueue queue : mBroadcastQueues) { 12921 queue.skipPendingBroadcastLocked(pid); 12922 } 12923 } 12924 12925 // The app just attached; send any pending broadcasts that it should receive 12926 boolean sendPendingBroadcastsLocked(ProcessRecord app) { 12927 boolean didSomething = false; 12928 for (BroadcastQueue queue : mBroadcastQueues) { 12929 didSomething |= queue.sendPendingBroadcastsLocked(app); 12930 } 12931 return didSomething; 12932 } 12933 12934 public Intent registerReceiver(IApplicationThread caller, String callerPackage, 12935 IIntentReceiver receiver, IntentFilter filter, String permission, int userId) { 12936 enforceNotIsolatedCaller("registerReceiver"); 12937 int callingUid; 12938 int callingPid; 12939 synchronized(this) { 12940 ProcessRecord callerApp = null; 12941 if (caller != null) { 12942 callerApp = getRecordForAppLocked(caller); 12943 if (callerApp == null) { 12944 throw new SecurityException( 12945 "Unable to find app for caller " + caller 12946 + " (pid=" + Binder.getCallingPid() 12947 + ") when registering receiver " + receiver); 12948 } 12949 if (callerApp.info.uid != Process.SYSTEM_UID && 12950 !callerApp.pkgList.containsKey(callerPackage) && 12951 !"android".equals(callerPackage)) { 12952 throw new SecurityException("Given caller package " + callerPackage 12953 + " is not running in process " + callerApp); 12954 } 12955 callingUid = callerApp.info.uid; 12956 callingPid = callerApp.pid; 12957 } else { 12958 callerPackage = null; 12959 callingUid = Binder.getCallingUid(); 12960 callingPid = Binder.getCallingPid(); 12961 } 12962 12963 userId = this.handleIncomingUser(callingPid, callingUid, userId, 12964 true, true, "registerReceiver", callerPackage); 12965 12966 List allSticky = null; 12967 12968 // Look for any matching sticky broadcasts... 12969 Iterator actions = filter.actionsIterator(); 12970 if (actions != null) { 12971 while (actions.hasNext()) { 12972 String action = (String)actions.next(); 12973 allSticky = getStickiesLocked(action, filter, allSticky, 12974 UserHandle.USER_ALL); 12975 allSticky = getStickiesLocked(action, filter, allSticky, 12976 UserHandle.getUserId(callingUid)); 12977 } 12978 } else { 12979 allSticky = getStickiesLocked(null, filter, allSticky, 12980 UserHandle.USER_ALL); 12981 allSticky = getStickiesLocked(null, filter, allSticky, 12982 UserHandle.getUserId(callingUid)); 12983 } 12984 12985 // The first sticky in the list is returned directly back to 12986 // the client. 12987 Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null; 12988 12989 if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter 12990 + ": " + sticky); 12991 12992 if (receiver == null) { 12993 return sticky; 12994 } 12995 12996 ReceiverList rl 12997 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder()); 12998 if (rl == null) { 12999 rl = new ReceiverList(this, callerApp, callingPid, callingUid, 13000 userId, receiver); 13001 if (rl.app != null) { 13002 rl.app.receivers.add(rl); 13003 } else { 13004 try { 13005 receiver.asBinder().linkToDeath(rl, 0); 13006 } catch (RemoteException e) { 13007 return sticky; 13008 } 13009 rl.linkedToDeath = true; 13010 } 13011 mRegisteredReceivers.put(receiver.asBinder(), rl); 13012 } else if (rl.uid != callingUid) { 13013 throw new IllegalArgumentException( 13014 "Receiver requested to register for uid " + callingUid 13015 + " was previously registered for uid " + rl.uid); 13016 } else if (rl.pid != callingPid) { 13017 throw new IllegalArgumentException( 13018 "Receiver requested to register for pid " + callingPid 13019 + " was previously registered for pid " + rl.pid); 13020 } else if (rl.userId != userId) { 13021 throw new IllegalArgumentException( 13022 "Receiver requested to register for user " + userId 13023 + " was previously registered for user " + rl.userId); 13024 } 13025 BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage, 13026 permission, callingUid, userId); 13027 rl.add(bf); 13028 if (!bf.debugCheck()) { 13029 Slog.w(TAG, "==> For Dynamic broadast"); 13030 } 13031 mReceiverResolver.addFilter(bf); 13032 13033 // Enqueue broadcasts for all existing stickies that match 13034 // this filter. 13035 if (allSticky != null) { 13036 ArrayList receivers = new ArrayList(); 13037 receivers.add(bf); 13038 13039 int N = allSticky.size(); 13040 for (int i=0; i<N; i++) { 13041 Intent intent = (Intent)allSticky.get(i); 13042 BroadcastQueue queue = broadcastQueueForIntent(intent); 13043 BroadcastRecord r = new BroadcastRecord(queue, intent, null, 13044 null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0, 13045 null, null, false, true, true, -1); 13046 queue.enqueueParallelBroadcastLocked(r); 13047 queue.scheduleBroadcastsLocked(); 13048 } 13049 } 13050 13051 return sticky; 13052 } 13053 } 13054 13055 public void unregisterReceiver(IIntentReceiver receiver) { 13056 if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver); 13057 13058 final long origId = Binder.clearCallingIdentity(); 13059 try { 13060 boolean doTrim = false; 13061 13062 synchronized(this) { 13063 ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder()); 13064 if (rl != null) { 13065 if (rl.curBroadcast != null) { 13066 BroadcastRecord r = rl.curBroadcast; 13067 final boolean doNext = finishReceiverLocked( 13068 receiver.asBinder(), r.resultCode, r.resultData, 13069 r.resultExtras, r.resultAbort); 13070 if (doNext) { 13071 doTrim = true; 13072 r.queue.processNextBroadcast(false); 13073 } 13074 } 13075 13076 if (rl.app != null) { 13077 rl.app.receivers.remove(rl); 13078 } 13079 removeReceiverLocked(rl); 13080 if (rl.linkedToDeath) { 13081 rl.linkedToDeath = false; 13082 rl.receiver.asBinder().unlinkToDeath(rl, 0); 13083 } 13084 } 13085 } 13086 13087 // If we actually concluded any broadcasts, we might now be able 13088 // to trim the recipients' apps from our working set 13089 if (doTrim) { 13090 trimApplications(); 13091 return; 13092 } 13093 13094 } finally { 13095 Binder.restoreCallingIdentity(origId); 13096 } 13097 } 13098 13099 void removeReceiverLocked(ReceiverList rl) { 13100 mRegisteredReceivers.remove(rl.receiver.asBinder()); 13101 int N = rl.size(); 13102 for (int i=0; i<N; i++) { 13103 mReceiverResolver.removeFilter(rl.get(i)); 13104 } 13105 } 13106 13107 private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) { 13108 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 13109 ProcessRecord r = mLruProcesses.get(i); 13110 if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) { 13111 try { 13112 r.thread.dispatchPackageBroadcast(cmd, packages); 13113 } catch (RemoteException ex) { 13114 } 13115 } 13116 } 13117 } 13118 13119 private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType, 13120 int[] users) { 13121 List<ResolveInfo> receivers = null; 13122 try { 13123 HashSet<ComponentName> singleUserReceivers = null; 13124 boolean scannedFirstReceivers = false; 13125 for (int user : users) { 13126 List<ResolveInfo> newReceivers = AppGlobals.getPackageManager() 13127 .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user); 13128 if (user != 0 && newReceivers != null) { 13129 // If this is not the primary user, we need to check for 13130 // any receivers that should be filtered out. 13131 for (int i=0; i<newReceivers.size(); i++) { 13132 ResolveInfo ri = newReceivers.get(i); 13133 if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) { 13134 newReceivers.remove(i); 13135 i--; 13136 } 13137 } 13138 } 13139 if (newReceivers != null && newReceivers.size() == 0) { 13140 newReceivers = null; 13141 } 13142 if (receivers == null) { 13143 receivers = newReceivers; 13144 } else if (newReceivers != null) { 13145 // We need to concatenate the additional receivers 13146 // found with what we have do far. This would be easy, 13147 // but we also need to de-dup any receivers that are 13148 // singleUser. 13149 if (!scannedFirstReceivers) { 13150 // Collect any single user receivers we had already retrieved. 13151 scannedFirstReceivers = true; 13152 for (int i=0; i<receivers.size(); i++) { 13153 ResolveInfo ri = receivers.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 singleUserReceivers.add(cn); 13161 } 13162 } 13163 } 13164 // Add the new results to the existing results, tracking 13165 // and de-dupping single user receivers. 13166 for (int i=0; i<newReceivers.size(); i++) { 13167 ResolveInfo ri = newReceivers.get(i); 13168 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 13169 ComponentName cn = new ComponentName( 13170 ri.activityInfo.packageName, ri.activityInfo.name); 13171 if (singleUserReceivers == null) { 13172 singleUserReceivers = new HashSet<ComponentName>(); 13173 } 13174 if (!singleUserReceivers.contains(cn)) { 13175 singleUserReceivers.add(cn); 13176 receivers.add(ri); 13177 } 13178 } else { 13179 receivers.add(ri); 13180 } 13181 } 13182 } 13183 } 13184 } catch (RemoteException ex) { 13185 // pm is in same process, this will never happen. 13186 } 13187 return receivers; 13188 } 13189 13190 private final int broadcastIntentLocked(ProcessRecord callerApp, 13191 String callerPackage, Intent intent, String resolvedType, 13192 IIntentReceiver resultTo, int resultCode, String resultData, 13193 Bundle map, String requiredPermission, int appOp, 13194 boolean ordered, boolean sticky, int callingPid, int callingUid, 13195 int userId) { 13196 intent = new Intent(intent); 13197 13198 // By default broadcasts do not go to stopped apps. 13199 intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES); 13200 13201 if (DEBUG_BROADCAST_LIGHT) Slog.v( 13202 TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent 13203 + " ordered=" + ordered + " userid=" + userId); 13204 if ((resultTo != null) && !ordered) { 13205 Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!"); 13206 } 13207 13208 userId = handleIncomingUser(callingPid, callingUid, userId, 13209 true, false, "broadcast", callerPackage); 13210 13211 // Make sure that the user who is receiving this broadcast is started. 13212 // If not, we will just skip it. 13213 if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) { 13214 if (callingUid != Process.SYSTEM_UID || (intent.getFlags() 13215 & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) { 13216 Slog.w(TAG, "Skipping broadcast of " + intent 13217 + ": user " + userId + " is stopped"); 13218 return ActivityManager.BROADCAST_SUCCESS; 13219 } 13220 } 13221 13222 /* 13223 * Prevent non-system code (defined here to be non-persistent 13224 * processes) from sending protected broadcasts. 13225 */ 13226 int callingAppId = UserHandle.getAppId(callingUid); 13227 if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID 13228 || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID || 13229 callingUid == 0) { 13230 // Always okay. 13231 } else if (callerApp == null || !callerApp.persistent) { 13232 try { 13233 if (AppGlobals.getPackageManager().isProtectedBroadcast( 13234 intent.getAction())) { 13235 String msg = "Permission Denial: not allowed to send broadcast " 13236 + intent.getAction() + " from pid=" 13237 + callingPid + ", uid=" + callingUid; 13238 Slog.w(TAG, msg); 13239 throw new SecurityException(msg); 13240 } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) { 13241 // Special case for compatibility: we don't want apps to send this, 13242 // but historically it has not been protected and apps may be using it 13243 // to poke their own app widget. So, instead of making it protected, 13244 // just limit it to the caller. 13245 if (callerApp == null) { 13246 String msg = "Permission Denial: not allowed to send broadcast " 13247 + intent.getAction() + " from unknown caller."; 13248 Slog.w(TAG, msg); 13249 throw new SecurityException(msg); 13250 } else if (intent.getComponent() != null) { 13251 // They are good enough to send to an explicit component... verify 13252 // it is being sent to the calling app. 13253 if (!intent.getComponent().getPackageName().equals( 13254 callerApp.info.packageName)) { 13255 String msg = "Permission Denial: not allowed to send broadcast " 13256 + intent.getAction() + " to " 13257 + intent.getComponent().getPackageName() + " from " 13258 + callerApp.info.packageName; 13259 Slog.w(TAG, msg); 13260 throw new SecurityException(msg); 13261 } 13262 } else { 13263 // Limit broadcast to their own package. 13264 intent.setPackage(callerApp.info.packageName); 13265 } 13266 } 13267 } catch (RemoteException e) { 13268 Slog.w(TAG, "Remote exception", e); 13269 return ActivityManager.BROADCAST_SUCCESS; 13270 } 13271 } 13272 13273 // Handle special intents: if this broadcast is from the package 13274 // manager about a package being removed, we need to remove all of 13275 // its activities from the history stack. 13276 final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals( 13277 intent.getAction()); 13278 if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction()) 13279 || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction()) 13280 || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction()) 13281 || uidRemoved) { 13282 if (checkComponentPermission( 13283 android.Manifest.permission.BROADCAST_PACKAGE_REMOVED, 13284 callingPid, callingUid, -1, true) 13285 == PackageManager.PERMISSION_GRANTED) { 13286 if (uidRemoved) { 13287 final Bundle intentExtras = intent.getExtras(); 13288 final int uid = intentExtras != null 13289 ? intentExtras.getInt(Intent.EXTRA_UID) : -1; 13290 if (uid >= 0) { 13291 BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics(); 13292 synchronized (bs) { 13293 bs.removeUidStatsLocked(uid); 13294 } 13295 mAppOpsService.uidRemoved(uid); 13296 } 13297 } else { 13298 // If resources are unavailable just force stop all 13299 // those packages and flush the attribute cache as well. 13300 if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) { 13301 String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 13302 if (list != null && (list.length > 0)) { 13303 for (String pkg : list) { 13304 forceStopPackageLocked(pkg, -1, false, true, true, false, false, userId, 13305 "storage unmount"); 13306 } 13307 sendPackageBroadcastLocked( 13308 IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId); 13309 } 13310 } else { 13311 Uri data = intent.getData(); 13312 String ssp; 13313 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 13314 boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals( 13315 intent.getAction()); 13316 boolean fullUninstall = removed && 13317 !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false); 13318 if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) { 13319 forceStopPackageLocked(ssp, UserHandle.getAppId( 13320 intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true, 13321 false, fullUninstall, userId, 13322 removed ? "pkg removed" : "pkg changed"); 13323 } 13324 if (removed) { 13325 sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED, 13326 new String[] {ssp}, userId); 13327 if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) { 13328 mAppOpsService.packageRemoved( 13329 intent.getIntExtra(Intent.EXTRA_UID, -1), ssp); 13330 13331 // Remove all permissions granted from/to this package 13332 removeUriPermissionsForPackageLocked(ssp, userId, true); 13333 } 13334 } 13335 } 13336 } 13337 } 13338 } else { 13339 String msg = "Permission Denial: " + intent.getAction() 13340 + " broadcast from " + callerPackage + " (pid=" + callingPid 13341 + ", uid=" + callingUid + ")" 13342 + " requires " 13343 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED; 13344 Slog.w(TAG, msg); 13345 throw new SecurityException(msg); 13346 } 13347 13348 // Special case for adding a package: by default turn on compatibility 13349 // mode. 13350 } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) { 13351 Uri data = intent.getData(); 13352 String ssp; 13353 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 13354 mCompatModePackages.handlePackageAddedLocked(ssp, 13355 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)); 13356 } 13357 } 13358 13359 /* 13360 * If this is the time zone changed action, queue up a message that will reset the timezone 13361 * of all currently running processes. This message will get queued up before the broadcast 13362 * happens. 13363 */ 13364 if (intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) { 13365 mHandler.sendEmptyMessage(UPDATE_TIME_ZONE); 13366 } 13367 13368 if (intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) { 13369 mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG); 13370 } 13371 13372 if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) { 13373 ProxyProperties proxy = intent.getParcelableExtra("proxy"); 13374 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy)); 13375 } 13376 13377 // Add to the sticky list if requested. 13378 if (sticky) { 13379 if (checkPermission(android.Manifest.permission.BROADCAST_STICKY, 13380 callingPid, callingUid) 13381 != PackageManager.PERMISSION_GRANTED) { 13382 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid=" 13383 + callingPid + ", uid=" + callingUid 13384 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 13385 Slog.w(TAG, msg); 13386 throw new SecurityException(msg); 13387 } 13388 if (requiredPermission != null) { 13389 Slog.w(TAG, "Can't broadcast sticky intent " + intent 13390 + " and enforce permission " + requiredPermission); 13391 return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION; 13392 } 13393 if (intent.getComponent() != null) { 13394 throw new SecurityException( 13395 "Sticky broadcasts can't target a specific component"); 13396 } 13397 // We use userId directly here, since the "all" target is maintained 13398 // as a separate set of sticky broadcasts. 13399 if (userId != UserHandle.USER_ALL) { 13400 // But first, if this is not a broadcast to all users, then 13401 // make sure it doesn't conflict with an existing broadcast to 13402 // all users. 13403 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get( 13404 UserHandle.USER_ALL); 13405 if (stickies != null) { 13406 ArrayList<Intent> list = stickies.get(intent.getAction()); 13407 if (list != null) { 13408 int N = list.size(); 13409 int i; 13410 for (i=0; i<N; i++) { 13411 if (intent.filterEquals(list.get(i))) { 13412 throw new IllegalArgumentException( 13413 "Sticky broadcast " + intent + " for user " 13414 + userId + " conflicts with existing global broadcast"); 13415 } 13416 } 13417 } 13418 } 13419 } 13420 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 13421 if (stickies == null) { 13422 stickies = new ArrayMap<String, ArrayList<Intent>>(); 13423 mStickyBroadcasts.put(userId, stickies); 13424 } 13425 ArrayList<Intent> list = stickies.get(intent.getAction()); 13426 if (list == null) { 13427 list = new ArrayList<Intent>(); 13428 stickies.put(intent.getAction(), list); 13429 } 13430 int N = list.size(); 13431 int i; 13432 for (i=0; i<N; i++) { 13433 if (intent.filterEquals(list.get(i))) { 13434 // This sticky already exists, replace it. 13435 list.set(i, new Intent(intent)); 13436 break; 13437 } 13438 } 13439 if (i >= N) { 13440 list.add(new Intent(intent)); 13441 } 13442 } 13443 13444 int[] users; 13445 if (userId == UserHandle.USER_ALL) { 13446 // Caller wants broadcast to go to all started users. 13447 users = mStartedUserArray; 13448 } else { 13449 // Caller wants broadcast to go to one specific user. 13450 users = new int[] {userId}; 13451 } 13452 13453 // Figure out who all will receive this broadcast. 13454 List receivers = null; 13455 List<BroadcastFilter> registeredReceivers = null; 13456 // Need to resolve the intent to interested receivers... 13457 if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) 13458 == 0) { 13459 receivers = collectReceiverComponents(intent, resolvedType, users); 13460 } 13461 if (intent.getComponent() == null) { 13462 registeredReceivers = mReceiverResolver.queryIntent(intent, 13463 resolvedType, false, userId); 13464 } 13465 13466 final boolean replacePending = 13467 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0; 13468 13469 if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction() 13470 + " replacePending=" + replacePending); 13471 13472 int NR = registeredReceivers != null ? registeredReceivers.size() : 0; 13473 if (!ordered && NR > 0) { 13474 // If we are not serializing this broadcast, then send the 13475 // registered receivers separately so they don't wait for the 13476 // components to be launched. 13477 final BroadcastQueue queue = broadcastQueueForIntent(intent); 13478 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 13479 callerPackage, callingPid, callingUid, resolvedType, requiredPermission, 13480 appOp, registeredReceivers, resultTo, resultCode, resultData, map, 13481 ordered, sticky, false, userId); 13482 if (DEBUG_BROADCAST) Slog.v( 13483 TAG, "Enqueueing parallel broadcast " + r); 13484 final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r); 13485 if (!replaced) { 13486 queue.enqueueParallelBroadcastLocked(r); 13487 queue.scheduleBroadcastsLocked(); 13488 } 13489 registeredReceivers = null; 13490 NR = 0; 13491 } 13492 13493 // Merge into one list. 13494 int ir = 0; 13495 if (receivers != null) { 13496 // A special case for PACKAGE_ADDED: do not allow the package 13497 // being added to see this broadcast. This prevents them from 13498 // using this as a back door to get run as soon as they are 13499 // installed. Maybe in the future we want to have a special install 13500 // broadcast or such for apps, but we'd like to deliberately make 13501 // this decision. 13502 String skipPackages[] = null; 13503 if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction()) 13504 || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction()) 13505 || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) { 13506 Uri data = intent.getData(); 13507 if (data != null) { 13508 String pkgName = data.getSchemeSpecificPart(); 13509 if (pkgName != null) { 13510 skipPackages = new String[] { pkgName }; 13511 } 13512 } 13513 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) { 13514 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 13515 } 13516 if (skipPackages != null && (skipPackages.length > 0)) { 13517 for (String skipPackage : skipPackages) { 13518 if (skipPackage != null) { 13519 int NT = receivers.size(); 13520 for (int it=0; it<NT; it++) { 13521 ResolveInfo curt = (ResolveInfo)receivers.get(it); 13522 if (curt.activityInfo.packageName.equals(skipPackage)) { 13523 receivers.remove(it); 13524 it--; 13525 NT--; 13526 } 13527 } 13528 } 13529 } 13530 } 13531 13532 int NT = receivers != null ? receivers.size() : 0; 13533 int it = 0; 13534 ResolveInfo curt = null; 13535 BroadcastFilter curr = null; 13536 while (it < NT && ir < NR) { 13537 if (curt == null) { 13538 curt = (ResolveInfo)receivers.get(it); 13539 } 13540 if (curr == null) { 13541 curr = registeredReceivers.get(ir); 13542 } 13543 if (curr.getPriority() >= curt.priority) { 13544 // Insert this broadcast record into the final list. 13545 receivers.add(it, curr); 13546 ir++; 13547 curr = null; 13548 it++; 13549 NT++; 13550 } else { 13551 // Skip to the next ResolveInfo in the final list. 13552 it++; 13553 curt = null; 13554 } 13555 } 13556 } 13557 while (ir < NR) { 13558 if (receivers == null) { 13559 receivers = new ArrayList(); 13560 } 13561 receivers.add(registeredReceivers.get(ir)); 13562 ir++; 13563 } 13564 13565 if ((receivers != null && receivers.size() > 0) 13566 || resultTo != null) { 13567 BroadcastQueue queue = broadcastQueueForIntent(intent); 13568 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 13569 callerPackage, callingPid, callingUid, resolvedType, 13570 requiredPermission, appOp, receivers, resultTo, resultCode, 13571 resultData, map, ordered, sticky, false, userId); 13572 if (DEBUG_BROADCAST) Slog.v( 13573 TAG, "Enqueueing ordered broadcast " + r 13574 + ": prev had " + queue.mOrderedBroadcasts.size()); 13575 if (DEBUG_BROADCAST) { 13576 int seq = r.intent.getIntExtra("seq", -1); 13577 Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq); 13578 } 13579 boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r); 13580 if (!replaced) { 13581 queue.enqueueOrderedBroadcastLocked(r); 13582 queue.scheduleBroadcastsLocked(); 13583 } 13584 } 13585 13586 return ActivityManager.BROADCAST_SUCCESS; 13587 } 13588 13589 final Intent verifyBroadcastLocked(Intent intent) { 13590 // Refuse possible leaked file descriptors 13591 if (intent != null && intent.hasFileDescriptors() == true) { 13592 throw new IllegalArgumentException("File descriptors passed in Intent"); 13593 } 13594 13595 int flags = intent.getFlags(); 13596 13597 if (!mProcessesReady) { 13598 // if the caller really truly claims to know what they're doing, go 13599 // ahead and allow the broadcast without launching any receivers 13600 if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) { 13601 intent = new Intent(intent); 13602 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 13603 } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) { 13604 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent 13605 + " before boot completion"); 13606 throw new IllegalStateException("Cannot broadcast before boot completed"); 13607 } 13608 } 13609 13610 if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 13611 throw new IllegalArgumentException( 13612 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 13613 } 13614 13615 return intent; 13616 } 13617 13618 public final int broadcastIntent(IApplicationThread caller, 13619 Intent intent, String resolvedType, IIntentReceiver resultTo, 13620 int resultCode, String resultData, Bundle map, 13621 String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) { 13622 enforceNotIsolatedCaller("broadcastIntent"); 13623 synchronized(this) { 13624 intent = verifyBroadcastLocked(intent); 13625 13626 final ProcessRecord callerApp = getRecordForAppLocked(caller); 13627 final int callingPid = Binder.getCallingPid(); 13628 final int callingUid = Binder.getCallingUid(); 13629 final long origId = Binder.clearCallingIdentity(); 13630 int res = broadcastIntentLocked(callerApp, 13631 callerApp != null ? callerApp.info.packageName : null, 13632 intent, resolvedType, resultTo, 13633 resultCode, resultData, map, requiredPermission, appOp, serialized, sticky, 13634 callingPid, callingUid, userId); 13635 Binder.restoreCallingIdentity(origId); 13636 return res; 13637 } 13638 } 13639 13640 int broadcastIntentInPackage(String packageName, int uid, 13641 Intent intent, String resolvedType, IIntentReceiver resultTo, 13642 int resultCode, String resultData, Bundle map, 13643 String requiredPermission, boolean serialized, boolean sticky, int userId) { 13644 synchronized(this) { 13645 intent = verifyBroadcastLocked(intent); 13646 13647 final long origId = Binder.clearCallingIdentity(); 13648 int res = broadcastIntentLocked(null, packageName, intent, resolvedType, 13649 resultTo, resultCode, resultData, map, requiredPermission, 13650 AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId); 13651 Binder.restoreCallingIdentity(origId); 13652 return res; 13653 } 13654 } 13655 13656 public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) { 13657 // Refuse possible leaked file descriptors 13658 if (intent != null && intent.hasFileDescriptors() == true) { 13659 throw new IllegalArgumentException("File descriptors passed in Intent"); 13660 } 13661 13662 userId = handleIncomingUser(Binder.getCallingPid(), 13663 Binder.getCallingUid(), userId, true, false, "removeStickyBroadcast", null); 13664 13665 synchronized(this) { 13666 if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY) 13667 != PackageManager.PERMISSION_GRANTED) { 13668 String msg = "Permission Denial: unbroadcastIntent() from pid=" 13669 + Binder.getCallingPid() 13670 + ", uid=" + Binder.getCallingUid() 13671 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 13672 Slog.w(TAG, msg); 13673 throw new SecurityException(msg); 13674 } 13675 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 13676 if (stickies != null) { 13677 ArrayList<Intent> list = stickies.get(intent.getAction()); 13678 if (list != null) { 13679 int N = list.size(); 13680 int i; 13681 for (i=0; i<N; i++) { 13682 if (intent.filterEquals(list.get(i))) { 13683 list.remove(i); 13684 break; 13685 } 13686 } 13687 if (list.size() <= 0) { 13688 stickies.remove(intent.getAction()); 13689 } 13690 } 13691 if (stickies.size() <= 0) { 13692 mStickyBroadcasts.remove(userId); 13693 } 13694 } 13695 } 13696 } 13697 13698 private final boolean finishReceiverLocked(IBinder receiver, int resultCode, 13699 String resultData, Bundle resultExtras, boolean resultAbort) { 13700 final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver); 13701 if (r == null) { 13702 Slog.w(TAG, "finishReceiver called but not found on queue"); 13703 return false; 13704 } 13705 13706 return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false); 13707 } 13708 13709 void backgroundServicesFinishedLocked(int userId) { 13710 for (BroadcastQueue queue : mBroadcastQueues) { 13711 queue.backgroundServicesFinishedLocked(userId); 13712 } 13713 } 13714 13715 public void finishReceiver(IBinder who, int resultCode, String resultData, 13716 Bundle resultExtras, boolean resultAbort) { 13717 if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who); 13718 13719 // Refuse possible leaked file descriptors 13720 if (resultExtras != null && resultExtras.hasFileDescriptors()) { 13721 throw new IllegalArgumentException("File descriptors passed in Bundle"); 13722 } 13723 13724 final long origId = Binder.clearCallingIdentity(); 13725 try { 13726 boolean doNext = false; 13727 BroadcastRecord r; 13728 13729 synchronized(this) { 13730 r = broadcastRecordForReceiverLocked(who); 13731 if (r != null) { 13732 doNext = r.queue.finishReceiverLocked(r, resultCode, 13733 resultData, resultExtras, resultAbort, true); 13734 } 13735 } 13736 13737 if (doNext) { 13738 r.queue.processNextBroadcast(false); 13739 } 13740 trimApplications(); 13741 } finally { 13742 Binder.restoreCallingIdentity(origId); 13743 } 13744 } 13745 13746 // ========================================================= 13747 // INSTRUMENTATION 13748 // ========================================================= 13749 13750 public boolean startInstrumentation(ComponentName className, 13751 String profileFile, int flags, Bundle arguments, 13752 IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection, 13753 int userId) { 13754 enforceNotIsolatedCaller("startInstrumentation"); 13755 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 13756 userId, false, true, "startInstrumentation", null); 13757 // Refuse possible leaked file descriptors 13758 if (arguments != null && arguments.hasFileDescriptors()) { 13759 throw new IllegalArgumentException("File descriptors passed in Bundle"); 13760 } 13761 13762 synchronized(this) { 13763 InstrumentationInfo ii = null; 13764 ApplicationInfo ai = null; 13765 try { 13766 ii = mContext.getPackageManager().getInstrumentationInfo( 13767 className, STOCK_PM_FLAGS); 13768 ai = AppGlobals.getPackageManager().getApplicationInfo( 13769 ii.targetPackage, STOCK_PM_FLAGS, userId); 13770 } catch (PackageManager.NameNotFoundException e) { 13771 } catch (RemoteException e) { 13772 } 13773 if (ii == null) { 13774 reportStartInstrumentationFailure(watcher, className, 13775 "Unable to find instrumentation info for: " + className); 13776 return false; 13777 } 13778 if (ai == null) { 13779 reportStartInstrumentationFailure(watcher, className, 13780 "Unable to find instrumentation target package: " + ii.targetPackage); 13781 return false; 13782 } 13783 13784 int match = mContext.getPackageManager().checkSignatures( 13785 ii.targetPackage, ii.packageName); 13786 if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) { 13787 String msg = "Permission Denial: starting instrumentation " 13788 + className + " from pid=" 13789 + Binder.getCallingPid() 13790 + ", uid=" + Binder.getCallingPid() 13791 + " not allowed because package " + ii.packageName 13792 + " does not have a signature matching the target " 13793 + ii.targetPackage; 13794 reportStartInstrumentationFailure(watcher, className, msg); 13795 throw new SecurityException(msg); 13796 } 13797 13798 final long origId = Binder.clearCallingIdentity(); 13799 // Instrumentation can kill and relaunch even persistent processes 13800 forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId, 13801 "start instr"); 13802 ProcessRecord app = addAppLocked(ai, false); 13803 app.instrumentationClass = className; 13804 app.instrumentationInfo = ai; 13805 app.instrumentationProfileFile = profileFile; 13806 app.instrumentationArguments = arguments; 13807 app.instrumentationWatcher = watcher; 13808 app.instrumentationUiAutomationConnection = uiAutomationConnection; 13809 app.instrumentationResultClass = className; 13810 Binder.restoreCallingIdentity(origId); 13811 } 13812 13813 return true; 13814 } 13815 13816 /** 13817 * Report errors that occur while attempting to start Instrumentation. Always writes the 13818 * error to the logs, but if somebody is watching, send the report there too. This enables 13819 * the "am" command to report errors with more information. 13820 * 13821 * @param watcher The IInstrumentationWatcher. Null if there isn't one. 13822 * @param cn The component name of the instrumentation. 13823 * @param report The error report. 13824 */ 13825 private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher, 13826 ComponentName cn, String report) { 13827 Slog.w(TAG, report); 13828 try { 13829 if (watcher != null) { 13830 Bundle results = new Bundle(); 13831 results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService"); 13832 results.putString("Error", report); 13833 watcher.instrumentationStatus(cn, -1, results); 13834 } 13835 } catch (RemoteException e) { 13836 Slog.w(TAG, e); 13837 } 13838 } 13839 13840 void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) { 13841 if (app.instrumentationWatcher != null) { 13842 try { 13843 // NOTE: IInstrumentationWatcher *must* be oneway here 13844 app.instrumentationWatcher.instrumentationFinished( 13845 app.instrumentationClass, 13846 resultCode, 13847 results); 13848 } catch (RemoteException e) { 13849 } 13850 } 13851 if (app.instrumentationUiAutomationConnection != null) { 13852 try { 13853 app.instrumentationUiAutomationConnection.shutdown(); 13854 } catch (RemoteException re) { 13855 /* ignore */ 13856 } 13857 // Only a UiAutomation can set this flag and now that 13858 // it is finished we make sure it is reset to its default. 13859 mUserIsMonkey = false; 13860 } 13861 app.instrumentationWatcher = null; 13862 app.instrumentationUiAutomationConnection = null; 13863 app.instrumentationClass = null; 13864 app.instrumentationInfo = null; 13865 app.instrumentationProfileFile = null; 13866 app.instrumentationArguments = null; 13867 13868 forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId, 13869 "finished inst"); 13870 } 13871 13872 public void finishInstrumentation(IApplicationThread target, 13873 int resultCode, Bundle results) { 13874 int userId = UserHandle.getCallingUserId(); 13875 // Refuse possible leaked file descriptors 13876 if (results != null && results.hasFileDescriptors()) { 13877 throw new IllegalArgumentException("File descriptors passed in Intent"); 13878 } 13879 13880 synchronized(this) { 13881 ProcessRecord app = getRecordForAppLocked(target); 13882 if (app == null) { 13883 Slog.w(TAG, "finishInstrumentation: no app for " + target); 13884 return; 13885 } 13886 final long origId = Binder.clearCallingIdentity(); 13887 finishInstrumentationLocked(app, resultCode, results); 13888 Binder.restoreCallingIdentity(origId); 13889 } 13890 } 13891 13892 // ========================================================= 13893 // CONFIGURATION 13894 // ========================================================= 13895 13896 public ConfigurationInfo getDeviceConfigurationInfo() { 13897 ConfigurationInfo config = new ConfigurationInfo(); 13898 synchronized (this) { 13899 config.reqTouchScreen = mConfiguration.touchscreen; 13900 config.reqKeyboardType = mConfiguration.keyboard; 13901 config.reqNavigation = mConfiguration.navigation; 13902 if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD 13903 || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) { 13904 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV; 13905 } 13906 if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED 13907 && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) { 13908 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD; 13909 } 13910 config.reqGlEsVersion = GL_ES_VERSION; 13911 } 13912 return config; 13913 } 13914 13915 ActivityStack getFocusedStack() { 13916 return mStackSupervisor.getFocusedStack(); 13917 } 13918 13919 public Configuration getConfiguration() { 13920 Configuration ci; 13921 synchronized(this) { 13922 ci = new Configuration(mConfiguration); 13923 } 13924 return ci; 13925 } 13926 13927 public void updatePersistentConfiguration(Configuration values) { 13928 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 13929 "updateConfiguration()"); 13930 enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS, 13931 "updateConfiguration()"); 13932 if (values == null) { 13933 throw new NullPointerException("Configuration must not be null"); 13934 } 13935 13936 synchronized(this) { 13937 final long origId = Binder.clearCallingIdentity(); 13938 updateConfigurationLocked(values, null, true, false); 13939 Binder.restoreCallingIdentity(origId); 13940 } 13941 } 13942 13943 public void updateConfiguration(Configuration values) { 13944 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 13945 "updateConfiguration()"); 13946 13947 synchronized(this) { 13948 if (values == null && mWindowManager != null) { 13949 // sentinel: fetch the current configuration from the window manager 13950 values = mWindowManager.computeNewConfiguration(); 13951 } 13952 13953 if (mWindowManager != null) { 13954 mProcessList.applyDisplaySize(mWindowManager); 13955 } 13956 13957 final long origId = Binder.clearCallingIdentity(); 13958 if (values != null) { 13959 Settings.System.clearConfiguration(values); 13960 } 13961 updateConfigurationLocked(values, null, false, false); 13962 Binder.restoreCallingIdentity(origId); 13963 } 13964 } 13965 13966 /** 13967 * Do either or both things: (1) change the current configuration, and (2) 13968 * make sure the given activity is running with the (now) current 13969 * configuration. Returns true if the activity has been left running, or 13970 * false if <var>starting</var> is being destroyed to match the new 13971 * configuration. 13972 * @param persistent TODO 13973 */ 13974 boolean updateConfigurationLocked(Configuration values, 13975 ActivityRecord starting, boolean persistent, boolean initLocale) { 13976 int changes = 0; 13977 13978 if (values != null) { 13979 Configuration newConfig = new Configuration(mConfiguration); 13980 changes = newConfig.updateFrom(values); 13981 if (changes != 0) { 13982 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) { 13983 Slog.i(TAG, "Updating configuration to: " + values); 13984 } 13985 13986 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes); 13987 13988 if (values.locale != null && !initLocale) { 13989 saveLocaleLocked(values.locale, 13990 !values.locale.equals(mConfiguration.locale), 13991 values.userSetLocale); 13992 } 13993 13994 mConfigurationSeq++; 13995 if (mConfigurationSeq <= 0) { 13996 mConfigurationSeq = 1; 13997 } 13998 newConfig.seq = mConfigurationSeq; 13999 mConfiguration = newConfig; 14000 Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig); 14001 14002 final Configuration configCopy = new Configuration(mConfiguration); 14003 14004 // TODO: If our config changes, should we auto dismiss any currently 14005 // showing dialogs? 14006 mShowDialogs = shouldShowDialogs(newConfig); 14007 14008 AttributeCache ac = AttributeCache.instance(); 14009 if (ac != null) { 14010 ac.updateConfiguration(configCopy); 14011 } 14012 14013 // Make sure all resources in our process are updated 14014 // right now, so that anyone who is going to retrieve 14015 // resource values after we return will be sure to get 14016 // the new ones. This is especially important during 14017 // boot, where the first config change needs to guarantee 14018 // all resources have that config before following boot 14019 // code is executed. 14020 sSystemThread.applyConfigurationToResources(configCopy); 14021 14022 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) { 14023 Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG); 14024 msg.obj = new Configuration(configCopy); 14025 mHandler.sendMessage(msg); 14026 } 14027 14028 for (int i=mLruProcesses.size()-1; i>=0; i--) { 14029 ProcessRecord app = mLruProcesses.get(i); 14030 try { 14031 if (app.thread != null) { 14032 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc " 14033 + app.processName + " new config " + mConfiguration); 14034 app.thread.scheduleConfigurationChanged(configCopy); 14035 } 14036 } catch (Exception e) { 14037 } 14038 } 14039 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED); 14040 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 14041 | Intent.FLAG_RECEIVER_REPLACE_PENDING 14042 | Intent.FLAG_RECEIVER_FOREGROUND); 14043 broadcastIntentLocked(null, null, intent, null, null, 0, null, null, 14044 null, AppOpsManager.OP_NONE, false, false, MY_PID, 14045 Process.SYSTEM_UID, UserHandle.USER_ALL); 14046 if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) { 14047 intent = new Intent(Intent.ACTION_LOCALE_CHANGED); 14048 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 14049 broadcastIntentLocked(null, null, intent, 14050 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 14051 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 14052 } 14053 } 14054 } 14055 14056 boolean kept = true; 14057 final ActivityStack mainStack = mStackSupervisor.getFocusedStack(); 14058 // mainStack is null during startup. 14059 if (mainStack != null) { 14060 if (changes != 0 && starting == null) { 14061 // If the configuration changed, and the caller is not already 14062 // in the process of starting an activity, then find the top 14063 // activity to check if its configuration needs to change. 14064 starting = mainStack.topRunningActivityLocked(null); 14065 } 14066 14067 if (starting != null) { 14068 kept = mainStack.ensureActivityConfigurationLocked(starting, changes); 14069 // And we need to make sure at this point that all other activities 14070 // are made visible with the correct configuration. 14071 mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes); 14072 } 14073 } 14074 14075 if (values != null && mWindowManager != null) { 14076 mWindowManager.setNewConfiguration(mConfiguration); 14077 } 14078 14079 return kept; 14080 } 14081 14082 /** 14083 * Decide based on the configuration whether we should shouw the ANR, 14084 * crash, etc dialogs. The idea is that if there is no affordnace to 14085 * press the on-screen buttons, we shouldn't show the dialog. 14086 * 14087 * A thought: SystemUI might also want to get told about this, the Power 14088 * dialog / global actions also might want different behaviors. 14089 */ 14090 private static final boolean shouldShowDialogs(Configuration config) { 14091 return !(config.keyboard == Configuration.KEYBOARD_NOKEYS 14092 && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH); 14093 } 14094 14095 /** 14096 * Save the locale. You must be inside a synchronized (this) block. 14097 */ 14098 private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) { 14099 if(isDiff) { 14100 SystemProperties.set("user.language", l.getLanguage()); 14101 SystemProperties.set("user.region", l.getCountry()); 14102 } 14103 14104 if(isPersist) { 14105 SystemProperties.set("persist.sys.language", l.getLanguage()); 14106 SystemProperties.set("persist.sys.country", l.getCountry()); 14107 SystemProperties.set("persist.sys.localevar", l.getVariant()); 14108 } 14109 } 14110 14111 @Override 14112 public boolean targetTaskAffinityMatchesActivity(IBinder token, String destAffinity) { 14113 ActivityRecord srec = ActivityRecord.forToken(token); 14114 return srec != null && srec.task.affinity != null && 14115 srec.task.affinity.equals(destAffinity); 14116 } 14117 14118 public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode, 14119 Intent resultData) { 14120 14121 synchronized (this) { 14122 final ActivityStack stack = ActivityRecord.getStackLocked(token); 14123 if (stack != null) { 14124 return stack.navigateUpToLocked(token, destIntent, resultCode, resultData); 14125 } 14126 return false; 14127 } 14128 } 14129 14130 public int getLaunchedFromUid(IBinder activityToken) { 14131 ActivityRecord srec = ActivityRecord.forToken(activityToken); 14132 if (srec == null) { 14133 return -1; 14134 } 14135 return srec.launchedFromUid; 14136 } 14137 14138 public String getLaunchedFromPackage(IBinder activityToken) { 14139 ActivityRecord srec = ActivityRecord.forToken(activityToken); 14140 if (srec == null) { 14141 return null; 14142 } 14143 return srec.launchedFromPackage; 14144 } 14145 14146 // ========================================================= 14147 // LIFETIME MANAGEMENT 14148 // ========================================================= 14149 14150 // Returns which broadcast queue the app is the current [or imminent] receiver 14151 // on, or 'null' if the app is not an active broadcast recipient. 14152 private BroadcastQueue isReceivingBroadcast(ProcessRecord app) { 14153 BroadcastRecord r = app.curReceiver; 14154 if (r != null) { 14155 return r.queue; 14156 } 14157 14158 // It's not the current receiver, but it might be starting up to become one 14159 synchronized (this) { 14160 for (BroadcastQueue queue : mBroadcastQueues) { 14161 r = queue.mPendingBroadcast; 14162 if (r != null && r.curApp == app) { 14163 // found it; report which queue it's in 14164 return queue; 14165 } 14166 } 14167 } 14168 14169 return null; 14170 } 14171 14172 private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP, 14173 boolean doingAll, long now) { 14174 if (mAdjSeq == app.adjSeq) { 14175 // This adjustment has already been computed. 14176 return app.curRawAdj; 14177 } 14178 14179 if (app.thread == null) { 14180 app.adjSeq = mAdjSeq; 14181 app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 14182 app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 14183 return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ); 14184 } 14185 14186 app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN; 14187 app.adjSource = null; 14188 app.adjTarget = null; 14189 app.empty = false; 14190 app.cached = false; 14191 14192 final int activitiesSize = app.activities.size(); 14193 14194 if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) { 14195 // The max adjustment doesn't allow this app to be anything 14196 // below foreground, so it is not worth doing work for it. 14197 app.adjType = "fixed"; 14198 app.adjSeq = mAdjSeq; 14199 app.curRawAdj = app.maxAdj; 14200 app.foregroundActivities = false; 14201 app.keeping = true; 14202 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT; 14203 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT; 14204 // System process can do UI, and when they do we want to have 14205 // them trim their memory after the user leaves the UI. To 14206 // facilitate this, here we need to determine whether or not it 14207 // is currently showing UI. 14208 app.systemNoUi = true; 14209 if (app == TOP_APP) { 14210 app.systemNoUi = false; 14211 } else if (activitiesSize > 0) { 14212 for (int j = 0; j < activitiesSize; j++) { 14213 final ActivityRecord r = app.activities.get(j); 14214 if (r.visible) { 14215 app.systemNoUi = false; 14216 } 14217 } 14218 } 14219 if (!app.systemNoUi) { 14220 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI; 14221 } 14222 return (app.curAdj=app.maxAdj); 14223 } 14224 14225 app.keeping = false; 14226 app.systemNoUi = false; 14227 14228 // Determine the importance of the process, starting with most 14229 // important to least, and assign an appropriate OOM adjustment. 14230 int adj; 14231 int schedGroup; 14232 int procState; 14233 boolean foregroundActivities = false; 14234 boolean interesting = false; 14235 BroadcastQueue queue; 14236 if (app == TOP_APP) { 14237 // The last app on the list is the foreground app. 14238 adj = ProcessList.FOREGROUND_APP_ADJ; 14239 schedGroup = Process.THREAD_GROUP_DEFAULT; 14240 app.adjType = "top-activity"; 14241 foregroundActivities = true; 14242 interesting = true; 14243 procState = ActivityManager.PROCESS_STATE_TOP; 14244 } else if (app.instrumentationClass != null) { 14245 // Don't want to kill running instrumentation. 14246 adj = ProcessList.FOREGROUND_APP_ADJ; 14247 schedGroup = Process.THREAD_GROUP_DEFAULT; 14248 app.adjType = "instrumentation"; 14249 interesting = true; 14250 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14251 } else if ((queue = isReceivingBroadcast(app)) != null) { 14252 // An app that is currently receiving a broadcast also 14253 // counts as being in the foreground for OOM killer purposes. 14254 // It's placed in a sched group based on the nature of the 14255 // broadcast as reflected by which queue it's active in. 14256 adj = ProcessList.FOREGROUND_APP_ADJ; 14257 schedGroup = (queue == mFgBroadcastQueue) 14258 ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 14259 app.adjType = "broadcast"; 14260 procState = ActivityManager.PROCESS_STATE_RECEIVER; 14261 } else if (app.executingServices.size() > 0) { 14262 // An app that is currently executing a service callback also 14263 // counts as being in the foreground. 14264 adj = ProcessList.FOREGROUND_APP_ADJ; 14265 schedGroup = app.execServicesFg ? 14266 Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 14267 app.adjType = "exec-service"; 14268 procState = ActivityManager.PROCESS_STATE_SERVICE; 14269 //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app); 14270 } else { 14271 // As far as we know the process is empty. We may change our mind later. 14272 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 14273 // At this point we don't actually know the adjustment. Use the cached adj 14274 // value that the caller wants us to. 14275 adj = cachedAdj; 14276 procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 14277 app.cached = true; 14278 app.empty = true; 14279 app.adjType = "cch-empty"; 14280 } 14281 14282 // Examine all activities if not already foreground. 14283 if (!foregroundActivities && activitiesSize > 0) { 14284 for (int j = 0; j < activitiesSize; j++) { 14285 final ActivityRecord r = app.activities.get(j); 14286 if (r.app != app) { 14287 Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc " 14288 + app + "?!?"); 14289 continue; 14290 } 14291 if (r.visible) { 14292 // App has a visible activity; only upgrade adjustment. 14293 if (adj > ProcessList.VISIBLE_APP_ADJ) { 14294 adj = ProcessList.VISIBLE_APP_ADJ; 14295 app.adjType = "visible"; 14296 } 14297 if (procState > ActivityManager.PROCESS_STATE_TOP) { 14298 procState = ActivityManager.PROCESS_STATE_TOP; 14299 } 14300 schedGroup = Process.THREAD_GROUP_DEFAULT; 14301 app.cached = false; 14302 app.empty = false; 14303 foregroundActivities = true; 14304 break; 14305 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) { 14306 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14307 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 14308 app.adjType = "pausing"; 14309 } 14310 if (procState > ActivityManager.PROCESS_STATE_TOP) { 14311 procState = ActivityManager.PROCESS_STATE_TOP; 14312 } 14313 schedGroup = Process.THREAD_GROUP_DEFAULT; 14314 app.cached = false; 14315 app.empty = false; 14316 foregroundActivities = true; 14317 } else if (r.state == ActivityState.STOPPING) { 14318 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14319 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 14320 app.adjType = "stopping"; 14321 } 14322 // For the process state, we will at this point consider the 14323 // process to be cached. It will be cached either as an activity 14324 // or empty depending on whether the activity is finishing. We do 14325 // this so that we can treat the process as cached for purposes of 14326 // memory trimming (determing current memory level, trim command to 14327 // send to process) since there can be an arbitrary number of stopping 14328 // processes and they should soon all go into the cached state. 14329 if (!r.finishing) { 14330 if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 14331 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 14332 } 14333 } 14334 app.cached = false; 14335 app.empty = false; 14336 foregroundActivities = true; 14337 } else { 14338 if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 14339 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 14340 app.adjType = "cch-act"; 14341 } 14342 } 14343 } 14344 } 14345 14346 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14347 if (app.foregroundServices) { 14348 // The user is aware of this app, so make it visible. 14349 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 14350 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14351 app.cached = false; 14352 app.adjType = "fg-service"; 14353 schedGroup = Process.THREAD_GROUP_DEFAULT; 14354 } else if (app.forcingToForeground != null) { 14355 // The user is aware of this app, so make it visible. 14356 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 14357 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14358 app.cached = false; 14359 app.adjType = "force-fg"; 14360 app.adjSource = app.forcingToForeground; 14361 schedGroup = Process.THREAD_GROUP_DEFAULT; 14362 } 14363 } 14364 14365 if (app.foregroundServices) { 14366 interesting = true; 14367 } 14368 14369 if (app == mHeavyWeightProcess) { 14370 if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) { 14371 // We don't want to kill the current heavy-weight process. 14372 adj = ProcessList.HEAVY_WEIGHT_APP_ADJ; 14373 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 14374 app.cached = false; 14375 app.adjType = "heavy"; 14376 } 14377 if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) { 14378 procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT; 14379 } 14380 } 14381 14382 if (app == mHomeProcess) { 14383 if (adj > ProcessList.HOME_APP_ADJ) { 14384 // This process is hosting what we currently consider to be the 14385 // home app, so we don't want to let it go into the background. 14386 adj = ProcessList.HOME_APP_ADJ; 14387 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 14388 app.cached = false; 14389 app.adjType = "home"; 14390 } 14391 if (procState > ActivityManager.PROCESS_STATE_HOME) { 14392 procState = ActivityManager.PROCESS_STATE_HOME; 14393 } 14394 } 14395 14396 if (app == mPreviousProcess && app.activities.size() > 0) { 14397 if (adj > ProcessList.PREVIOUS_APP_ADJ) { 14398 // This was the previous process that showed UI to the user. 14399 // We want to try to keep it around more aggressively, to give 14400 // a good experience around switching between two apps. 14401 adj = ProcessList.PREVIOUS_APP_ADJ; 14402 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 14403 app.cached = false; 14404 app.adjType = "previous"; 14405 } 14406 if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) { 14407 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY; 14408 } 14409 } 14410 14411 if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj 14412 + " reason=" + app.adjType); 14413 14414 // By default, we use the computed adjustment. It may be changed if 14415 // there are applications dependent on our services or providers, but 14416 // this gives us a baseline and makes sure we don't get into an 14417 // infinite recursion. 14418 app.adjSeq = mAdjSeq; 14419 app.curRawAdj = adj; 14420 app.hasStartedServices = false; 14421 14422 if (mBackupTarget != null && app == mBackupTarget.app) { 14423 // If possible we want to avoid killing apps while they're being backed up 14424 if (adj > ProcessList.BACKUP_APP_ADJ) { 14425 if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app); 14426 adj = ProcessList.BACKUP_APP_ADJ; 14427 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) { 14428 procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND; 14429 } 14430 app.adjType = "backup"; 14431 app.cached = false; 14432 } 14433 if (procState > ActivityManager.PROCESS_STATE_BACKUP) { 14434 procState = ActivityManager.PROCESS_STATE_BACKUP; 14435 } 14436 } 14437 14438 boolean mayBeTop = false; 14439 14440 for (int is = app.services.size()-1; 14441 is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 14442 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 14443 || procState > ActivityManager.PROCESS_STATE_TOP); 14444 is--) { 14445 ServiceRecord s = app.services.valueAt(is); 14446 if (s.startRequested) { 14447 app.hasStartedServices = true; 14448 if (procState > ActivityManager.PROCESS_STATE_SERVICE) { 14449 procState = ActivityManager.PROCESS_STATE_SERVICE; 14450 } 14451 if (app.hasShownUi && app != mHomeProcess) { 14452 // If this process has shown some UI, let it immediately 14453 // go to the LRU list because it may be pretty heavy with 14454 // UI stuff. We'll tag it with a label just to help 14455 // debug and understand what is going on. 14456 if (adj > ProcessList.SERVICE_ADJ) { 14457 app.adjType = "cch-started-ui-services"; 14458 } 14459 } else { 14460 if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) { 14461 // This service has seen some activity within 14462 // recent memory, so we will keep its process ahead 14463 // of the background processes. 14464 if (adj > ProcessList.SERVICE_ADJ) { 14465 adj = ProcessList.SERVICE_ADJ; 14466 app.adjType = "started-services"; 14467 app.cached = false; 14468 } 14469 } 14470 // If we have let the service slide into the background 14471 // state, still have some text describing what it is doing 14472 // even though the service no longer has an impact. 14473 if (adj > ProcessList.SERVICE_ADJ) { 14474 app.adjType = "cch-started-services"; 14475 } 14476 } 14477 // Don't kill this process because it is doing work; it 14478 // has said it is doing work. 14479 app.keeping = true; 14480 } 14481 for (int conni = s.connections.size()-1; 14482 conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 14483 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 14484 || procState > ActivityManager.PROCESS_STATE_TOP); 14485 conni--) { 14486 ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni); 14487 for (int i = 0; 14488 i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ 14489 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 14490 || procState > ActivityManager.PROCESS_STATE_TOP); 14491 i++) { 14492 // XXX should compute this based on the max of 14493 // all connected clients. 14494 ConnectionRecord cr = clist.get(i); 14495 if (cr.binding.client == app) { 14496 // Binding to ourself is not interesting. 14497 continue; 14498 } 14499 if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) { 14500 ProcessRecord client = cr.binding.client; 14501 int clientAdj = computeOomAdjLocked(client, cachedAdj, 14502 TOP_APP, doingAll, now); 14503 int clientProcState = client.curProcState; 14504 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 14505 // If the other app is cached for any reason, for purposes here 14506 // we are going to consider it empty. The specific cached state 14507 // doesn't propagate except under certain conditions. 14508 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 14509 } 14510 String adjType = null; 14511 if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) { 14512 // Not doing bind OOM management, so treat 14513 // this guy more like a started service. 14514 if (app.hasShownUi && app != mHomeProcess) { 14515 // If this process has shown some UI, let it immediately 14516 // go to the LRU list because it may be pretty heavy with 14517 // UI stuff. We'll tag it with a label just to help 14518 // debug and understand what is going on. 14519 if (adj > clientAdj) { 14520 adjType = "cch-bound-ui-services"; 14521 } 14522 app.cached = false; 14523 clientAdj = adj; 14524 clientProcState = procState; 14525 } else { 14526 if (now >= (s.lastActivity 14527 + ActiveServices.MAX_SERVICE_INACTIVITY)) { 14528 // This service has not seen activity within 14529 // recent memory, so allow it to drop to the 14530 // LRU list if there is no other reason to keep 14531 // it around. We'll also tag it with a label just 14532 // to help debug and undertand what is going on. 14533 if (adj > clientAdj) { 14534 adjType = "cch-bound-services"; 14535 } 14536 clientAdj = adj; 14537 } 14538 } 14539 } 14540 if (adj > clientAdj) { 14541 // If this process has recently shown UI, and 14542 // the process that is binding to it is less 14543 // important than being visible, then we don't 14544 // care about the binding as much as we care 14545 // about letting this process get into the LRU 14546 // list to be killed and restarted if needed for 14547 // memory. 14548 if (app.hasShownUi && app != mHomeProcess 14549 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14550 adjType = "cch-bound-ui-services"; 14551 } else { 14552 if ((cr.flags&(Context.BIND_ABOVE_CLIENT 14553 |Context.BIND_IMPORTANT)) != 0) { 14554 adj = clientAdj; 14555 } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0 14556 && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ 14557 && adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14558 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 14559 } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) { 14560 adj = clientAdj; 14561 } else { 14562 if (adj > ProcessList.VISIBLE_APP_ADJ) { 14563 adj = ProcessList.VISIBLE_APP_ADJ; 14564 } 14565 } 14566 if (!client.cached) { 14567 app.cached = false; 14568 } 14569 if (client.keeping) { 14570 app.keeping = true; 14571 } 14572 adjType = "service"; 14573 } 14574 } 14575 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 14576 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 14577 schedGroup = Process.THREAD_GROUP_DEFAULT; 14578 } 14579 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) { 14580 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) { 14581 // Special handling of clients who are in the top state. 14582 // We *may* want to consider this process to be in the 14583 // top state as well, but only if there is not another 14584 // reason for it to be running. Being on the top is a 14585 // special state, meaning you are specifically running 14586 // for the current top app. If the process is already 14587 // running in the background for some other reason, it 14588 // is more important to continue considering it to be 14589 // in the background state. 14590 mayBeTop = true; 14591 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 14592 } else { 14593 // Special handling for above-top states (persistent 14594 // processes). These should not bring the current process 14595 // into the top state, since they are not on top. Instead 14596 // give them the best state after that. 14597 clientProcState = 14598 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14599 } 14600 } 14601 } else { 14602 if (clientProcState < 14603 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) { 14604 clientProcState = 14605 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND; 14606 } 14607 } 14608 if (procState > clientProcState) { 14609 procState = clientProcState; 14610 } 14611 if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 14612 && (cr.flags&Context.BIND_SHOWING_UI) != 0) { 14613 app.pendingUiClean = true; 14614 } 14615 if (adjType != null) { 14616 app.adjType = adjType; 14617 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 14618 .REASON_SERVICE_IN_USE; 14619 app.adjSource = cr.binding.client; 14620 app.adjSourceOom = clientAdj; 14621 app.adjTarget = s.name; 14622 } 14623 } 14624 final ActivityRecord a = cr.activity; 14625 if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) { 14626 if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ && 14627 (a.visible || a.state == ActivityState.RESUMED 14628 || a.state == ActivityState.PAUSING)) { 14629 adj = ProcessList.FOREGROUND_APP_ADJ; 14630 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 14631 schedGroup = Process.THREAD_GROUP_DEFAULT; 14632 } 14633 app.cached = false; 14634 app.adjType = "service"; 14635 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 14636 .REASON_SERVICE_IN_USE; 14637 app.adjSource = a; 14638 app.adjSourceOom = adj; 14639 app.adjTarget = s.name; 14640 } 14641 } 14642 } 14643 } 14644 } 14645 14646 for (int provi = app.pubProviders.size()-1; 14647 provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 14648 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 14649 || procState > ActivityManager.PROCESS_STATE_TOP); 14650 provi--) { 14651 ContentProviderRecord cpr = app.pubProviders.valueAt(provi); 14652 for (int i = cpr.connections.size()-1; 14653 i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 14654 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 14655 || procState > ActivityManager.PROCESS_STATE_TOP); 14656 i--) { 14657 ContentProviderConnection conn = cpr.connections.get(i); 14658 ProcessRecord client = conn.client; 14659 if (client == app) { 14660 // Being our own client is not interesting. 14661 continue; 14662 } 14663 int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now); 14664 int clientProcState = client.curProcState; 14665 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 14666 // If the other app is cached for any reason, for purposes here 14667 // we are going to consider it empty. 14668 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 14669 } 14670 if (adj > clientAdj) { 14671 if (app.hasShownUi && app != mHomeProcess 14672 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14673 app.adjType = "cch-ui-provider"; 14674 } else { 14675 adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ 14676 ? clientAdj : ProcessList.FOREGROUND_APP_ADJ; 14677 app.adjType = "provider"; 14678 } 14679 app.cached &= client.cached; 14680 app.keeping |= client.keeping; 14681 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 14682 .REASON_PROVIDER_IN_USE; 14683 app.adjSource = client; 14684 app.adjSourceOom = clientAdj; 14685 app.adjTarget = cpr.name; 14686 } 14687 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) { 14688 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) { 14689 // Special handling of clients who are in the top state. 14690 // We *may* want to consider this process to be in the 14691 // top state as well, but only if there is not another 14692 // reason for it to be running. Being on the top is a 14693 // special state, meaning you are specifically running 14694 // for the current top app. If the process is already 14695 // running in the background for some other reason, it 14696 // is more important to continue considering it to be 14697 // in the background state. 14698 mayBeTop = true; 14699 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 14700 } else { 14701 // Special handling for above-top states (persistent 14702 // processes). These should not bring the current process 14703 // into the top state, since they are not on top. Instead 14704 // give them the best state after that. 14705 clientProcState = 14706 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14707 } 14708 } 14709 if (procState > clientProcState) { 14710 procState = clientProcState; 14711 } 14712 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 14713 schedGroup = Process.THREAD_GROUP_DEFAULT; 14714 } 14715 } 14716 // If the provider has external (non-framework) process 14717 // dependencies, ensure that its adjustment is at least 14718 // FOREGROUND_APP_ADJ. 14719 if (cpr.hasExternalProcessHandles()) { 14720 if (adj > ProcessList.FOREGROUND_APP_ADJ) { 14721 adj = ProcessList.FOREGROUND_APP_ADJ; 14722 schedGroup = Process.THREAD_GROUP_DEFAULT; 14723 app.cached = false; 14724 app.keeping = true; 14725 app.adjType = "provider"; 14726 app.adjTarget = cpr.name; 14727 } 14728 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) { 14729 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14730 } 14731 } 14732 } 14733 14734 if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) { 14735 // A client of one of our services or providers is in the top state. We 14736 // *may* want to be in the top state, but not if we are already running in 14737 // the background for some other reason. For the decision here, we are going 14738 // to pick out a few specific states that we want to remain in when a client 14739 // is top (states that tend to be longer-term) and otherwise allow it to go 14740 // to the top state. 14741 switch (procState) { 14742 case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND: 14743 case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND: 14744 case ActivityManager.PROCESS_STATE_SERVICE: 14745 // These all are longer-term states, so pull them up to the top 14746 // of the background states, but not all the way to the top state. 14747 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14748 break; 14749 default: 14750 // Otherwise, top is a better choice, so take it. 14751 procState = ActivityManager.PROCESS_STATE_TOP; 14752 break; 14753 } 14754 } 14755 14756 if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY && app.hasClientActivities) { 14757 // This is a cached process, but with client activities. Mark it so. 14758 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT; 14759 app.adjType = "cch-client-act"; 14760 } 14761 14762 if (adj == ProcessList.SERVICE_ADJ) { 14763 if (doingAll) { 14764 app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3); 14765 mNewNumServiceProcs++; 14766 //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb); 14767 if (!app.serviceb) { 14768 // This service isn't far enough down on the LRU list to 14769 // normally be a B service, but if we are low on RAM and it 14770 // is large we want to force it down since we would prefer to 14771 // keep launcher over it. 14772 if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL 14773 && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) { 14774 app.serviceHighRam = true; 14775 app.serviceb = true; 14776 //Slog.i(TAG, "ADJ " + app + " high ram!"); 14777 } else { 14778 mNewNumAServiceProcs++; 14779 //Slog.i(TAG, "ADJ " + app + " not high ram!"); 14780 } 14781 } else { 14782 app.serviceHighRam = false; 14783 } 14784 } 14785 if (app.serviceb) { 14786 adj = ProcessList.SERVICE_B_ADJ; 14787 } 14788 } 14789 14790 app.curRawAdj = adj; 14791 14792 //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid + 14793 // " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj); 14794 if (adj > app.maxAdj) { 14795 adj = app.maxAdj; 14796 if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 14797 schedGroup = Process.THREAD_GROUP_DEFAULT; 14798 } 14799 } 14800 if (adj < ProcessList.CACHED_APP_MIN_ADJ) { 14801 app.keeping = true; 14802 } 14803 14804 // Do final modification to adj. Everything we do between here and applying 14805 // the final setAdj must be done in this function, because we will also use 14806 // it when computing the final cached adj later. Note that we don't need to 14807 // worry about this for max adj above, since max adj will always be used to 14808 // keep it out of the cached vaues. 14809 adj = app.modifyRawOomAdj(adj); 14810 14811 app.curProcState = procState; 14812 14813 int importance = app.memImportance; 14814 if (importance == 0 || adj != app.curAdj || schedGroup != app.curSchedGroup) { 14815 app.curAdj = adj; 14816 app.curSchedGroup = schedGroup; 14817 if (!interesting) { 14818 // For this reporting, if there is not something explicitly 14819 // interesting in this process then we will push it to the 14820 // background importance. 14821 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 14822 } else if (adj >= ProcessList.CACHED_APP_MIN_ADJ) { 14823 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 14824 } else if (adj >= ProcessList.SERVICE_B_ADJ) { 14825 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 14826 } else if (adj >= ProcessList.HOME_APP_ADJ) { 14827 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 14828 } else if (adj >= ProcessList.SERVICE_ADJ) { 14829 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 14830 } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 14831 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE; 14832 } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) { 14833 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE; 14834 } else if (adj >= ProcessList.VISIBLE_APP_ADJ) { 14835 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE; 14836 } else if (adj >= ProcessList.FOREGROUND_APP_ADJ) { 14837 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND; 14838 } else { 14839 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERSISTENT; 14840 } 14841 } 14842 14843 int changes = importance != app.memImportance ? ProcessChangeItem.CHANGE_IMPORTANCE : 0; 14844 if (foregroundActivities != app.foregroundActivities) { 14845 changes |= ProcessChangeItem.CHANGE_ACTIVITIES; 14846 } 14847 if (changes != 0) { 14848 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes); 14849 app.memImportance = importance; 14850 app.foregroundActivities = foregroundActivities; 14851 int i = mPendingProcessChanges.size()-1; 14852 ProcessChangeItem item = null; 14853 while (i >= 0) { 14854 item = mPendingProcessChanges.get(i); 14855 if (item.pid == app.pid) { 14856 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item); 14857 break; 14858 } 14859 i--; 14860 } 14861 if (i < 0) { 14862 // No existing item in pending changes; need a new one. 14863 final int NA = mAvailProcessChanges.size(); 14864 if (NA > 0) { 14865 item = mAvailProcessChanges.remove(NA-1); 14866 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item); 14867 } else { 14868 item = new ProcessChangeItem(); 14869 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item); 14870 } 14871 item.changes = 0; 14872 item.pid = app.pid; 14873 item.uid = app.info.uid; 14874 if (mPendingProcessChanges.size() == 0) { 14875 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, 14876 "*** Enqueueing dispatch processes changed!"); 14877 mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget(); 14878 } 14879 mPendingProcessChanges.add(item); 14880 } 14881 item.changes |= changes; 14882 item.importance = importance; 14883 item.foregroundActivities = foregroundActivities; 14884 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item " 14885 + Integer.toHexString(System.identityHashCode(item)) 14886 + " " + app.toShortString() + ": changes=" + item.changes 14887 + " importance=" + item.importance 14888 + " foreground=" + item.foregroundActivities 14889 + " type=" + app.adjType + " source=" + app.adjSource 14890 + " target=" + app.adjTarget); 14891 } 14892 14893 return app.curRawAdj; 14894 } 14895 14896 /** 14897 * Schedule PSS collection of a process. 14898 */ 14899 void requestPssLocked(ProcessRecord proc, int procState) { 14900 if (mPendingPssProcesses.contains(proc)) { 14901 return; 14902 } 14903 if (mPendingPssProcesses.size() == 0) { 14904 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG); 14905 } 14906 if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc); 14907 proc.pssProcState = procState; 14908 mPendingPssProcesses.add(proc); 14909 } 14910 14911 /** 14912 * Schedule PSS collection of all processes. 14913 */ 14914 void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) { 14915 if (!always) { 14916 if (now < (mLastFullPssTime + 14917 (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) { 14918 return; 14919 } 14920 } 14921 if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs! memLowered=" + memLowered); 14922 mLastFullPssTime = now; 14923 mPendingPssProcesses.ensureCapacity(mLruProcesses.size()); 14924 mPendingPssProcesses.clear(); 14925 for (int i=mLruProcesses.size()-1; i>=0; i--) { 14926 ProcessRecord app = mLruProcesses.get(i); 14927 if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) { 14928 app.pssProcState = app.setProcState; 14929 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true, 14930 mSleeping, now); 14931 mPendingPssProcesses.add(app); 14932 } 14933 } 14934 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG); 14935 } 14936 14937 /** 14938 * Ask a given process to GC right now. 14939 */ 14940 final void performAppGcLocked(ProcessRecord app) { 14941 try { 14942 app.lastRequestedGc = SystemClock.uptimeMillis(); 14943 if (app.thread != null) { 14944 if (app.reportLowMemory) { 14945 app.reportLowMemory = false; 14946 app.thread.scheduleLowMemory(); 14947 } else { 14948 app.thread.processInBackground(); 14949 } 14950 } 14951 } catch (Exception e) { 14952 // whatever. 14953 } 14954 } 14955 14956 /** 14957 * Returns true if things are idle enough to perform GCs. 14958 */ 14959 private final boolean canGcNowLocked() { 14960 boolean processingBroadcasts = false; 14961 for (BroadcastQueue q : mBroadcastQueues) { 14962 if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) { 14963 processingBroadcasts = true; 14964 } 14965 } 14966 return !processingBroadcasts 14967 && (mSleeping || mStackSupervisor.allResumedActivitiesIdle()); 14968 } 14969 14970 /** 14971 * Perform GCs on all processes that are waiting for it, but only 14972 * if things are idle. 14973 */ 14974 final void performAppGcsLocked() { 14975 final int N = mProcessesToGc.size(); 14976 if (N <= 0) { 14977 return; 14978 } 14979 if (canGcNowLocked()) { 14980 while (mProcessesToGc.size() > 0) { 14981 ProcessRecord proc = mProcessesToGc.remove(0); 14982 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) { 14983 if ((proc.lastRequestedGc+GC_MIN_INTERVAL) 14984 <= SystemClock.uptimeMillis()) { 14985 // To avoid spamming the system, we will GC processes one 14986 // at a time, waiting a few seconds between each. 14987 performAppGcLocked(proc); 14988 scheduleAppGcsLocked(); 14989 return; 14990 } else { 14991 // It hasn't been long enough since we last GCed this 14992 // process... put it in the list to wait for its time. 14993 addProcessToGcListLocked(proc); 14994 break; 14995 } 14996 } 14997 } 14998 14999 scheduleAppGcsLocked(); 15000 } 15001 } 15002 15003 /** 15004 * If all looks good, perform GCs on all processes waiting for them. 15005 */ 15006 final void performAppGcsIfAppropriateLocked() { 15007 if (canGcNowLocked()) { 15008 performAppGcsLocked(); 15009 return; 15010 } 15011 // Still not idle, wait some more. 15012 scheduleAppGcsLocked(); 15013 } 15014 15015 /** 15016 * Schedule the execution of all pending app GCs. 15017 */ 15018 final void scheduleAppGcsLocked() { 15019 mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG); 15020 15021 if (mProcessesToGc.size() > 0) { 15022 // Schedule a GC for the time to the next process. 15023 ProcessRecord proc = mProcessesToGc.get(0); 15024 Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG); 15025 15026 long when = proc.lastRequestedGc + GC_MIN_INTERVAL; 15027 long now = SystemClock.uptimeMillis(); 15028 if (when < (now+GC_TIMEOUT)) { 15029 when = now + GC_TIMEOUT; 15030 } 15031 mHandler.sendMessageAtTime(msg, when); 15032 } 15033 } 15034 15035 /** 15036 * Add a process to the array of processes waiting to be GCed. Keeps the 15037 * list in sorted order by the last GC time. The process can't already be 15038 * on the list. 15039 */ 15040 final void addProcessToGcListLocked(ProcessRecord proc) { 15041 boolean added = false; 15042 for (int i=mProcessesToGc.size()-1; i>=0; i--) { 15043 if (mProcessesToGc.get(i).lastRequestedGc < 15044 proc.lastRequestedGc) { 15045 added = true; 15046 mProcessesToGc.add(i+1, proc); 15047 break; 15048 } 15049 } 15050 if (!added) { 15051 mProcessesToGc.add(0, proc); 15052 } 15053 } 15054 15055 /** 15056 * Set up to ask a process to GC itself. This will either do it 15057 * immediately, or put it on the list of processes to gc the next 15058 * time things are idle. 15059 */ 15060 final void scheduleAppGcLocked(ProcessRecord app) { 15061 long now = SystemClock.uptimeMillis(); 15062 if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) { 15063 return; 15064 } 15065 if (!mProcessesToGc.contains(app)) { 15066 addProcessToGcListLocked(app); 15067 scheduleAppGcsLocked(); 15068 } 15069 } 15070 15071 final void checkExcessivePowerUsageLocked(boolean doKills) { 15072 updateCpuStatsNow(); 15073 15074 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 15075 boolean doWakeKills = doKills; 15076 boolean doCpuKills = doKills; 15077 if (mLastPowerCheckRealtime == 0) { 15078 doWakeKills = false; 15079 } 15080 if (mLastPowerCheckUptime == 0) { 15081 doCpuKills = false; 15082 } 15083 if (stats.isScreenOn()) { 15084 doWakeKills = false; 15085 } 15086 final long curRealtime = SystemClock.elapsedRealtime(); 15087 final long realtimeSince = curRealtime - mLastPowerCheckRealtime; 15088 final long curUptime = SystemClock.uptimeMillis(); 15089 final long uptimeSince = curUptime - mLastPowerCheckUptime; 15090 mLastPowerCheckRealtime = curRealtime; 15091 mLastPowerCheckUptime = curUptime; 15092 if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) { 15093 doWakeKills = false; 15094 } 15095 if (uptimeSince < CPU_MIN_CHECK_DURATION) { 15096 doCpuKills = false; 15097 } 15098 int i = mLruProcesses.size(); 15099 while (i > 0) { 15100 i--; 15101 ProcessRecord app = mLruProcesses.get(i); 15102 if (!app.keeping) { 15103 long wtime; 15104 synchronized (stats) { 15105 wtime = stats.getProcessWakeTime(app.info.uid, 15106 app.pid, curRealtime); 15107 } 15108 long wtimeUsed = wtime - app.lastWakeTime; 15109 long cputimeUsed = app.curCpuTime - app.lastCpuTime; 15110 if (DEBUG_POWER) { 15111 StringBuilder sb = new StringBuilder(128); 15112 sb.append("Wake for "); 15113 app.toShortString(sb); 15114 sb.append(": over "); 15115 TimeUtils.formatDuration(realtimeSince, sb); 15116 sb.append(" used "); 15117 TimeUtils.formatDuration(wtimeUsed, sb); 15118 sb.append(" ("); 15119 sb.append((wtimeUsed*100)/realtimeSince); 15120 sb.append("%)"); 15121 Slog.i(TAG, sb.toString()); 15122 sb.setLength(0); 15123 sb.append("CPU for "); 15124 app.toShortString(sb); 15125 sb.append(": over "); 15126 TimeUtils.formatDuration(uptimeSince, sb); 15127 sb.append(" used "); 15128 TimeUtils.formatDuration(cputimeUsed, sb); 15129 sb.append(" ("); 15130 sb.append((cputimeUsed*100)/uptimeSince); 15131 sb.append("%)"); 15132 Slog.i(TAG, sb.toString()); 15133 } 15134 // If a process has held a wake lock for more 15135 // than 50% of the time during this period, 15136 // that sounds bad. Kill! 15137 if (doWakeKills && realtimeSince > 0 15138 && ((wtimeUsed*100)/realtimeSince) >= 50) { 15139 synchronized (stats) { 15140 stats.reportExcessiveWakeLocked(app.info.uid, app.processName, 15141 realtimeSince, wtimeUsed); 15142 } 15143 killUnneededProcessLocked(app, "excessive wake held " + wtimeUsed 15144 + " during " + realtimeSince); 15145 app.baseProcessTracker.reportExcessiveWake(app.pkgList); 15146 } else if (doCpuKills && uptimeSince > 0 15147 && ((cputimeUsed*100)/uptimeSince) >= 50) { 15148 synchronized (stats) { 15149 stats.reportExcessiveCpuLocked(app.info.uid, app.processName, 15150 uptimeSince, cputimeUsed); 15151 } 15152 killUnneededProcessLocked(app, "excessive cpu " + cputimeUsed 15153 + " during " + uptimeSince); 15154 app.baseProcessTracker.reportExcessiveCpu(app.pkgList); 15155 } else { 15156 app.lastWakeTime = wtime; 15157 app.lastCpuTime = app.curCpuTime; 15158 } 15159 } 15160 } 15161 } 15162 15163 private final boolean applyOomAdjLocked(ProcessRecord app, boolean wasKeeping, 15164 ProcessRecord TOP_APP, boolean doingAll, boolean reportingProcessState, long now) { 15165 boolean success = true; 15166 15167 if (app.curRawAdj != app.setRawAdj) { 15168 if (wasKeeping && !app.keeping) { 15169 // This app is no longer something we want to keep. Note 15170 // its current wake lock time to later know to kill it if 15171 // it is not behaving well. 15172 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 15173 synchronized (stats) { 15174 app.lastWakeTime = stats.getProcessWakeTime(app.info.uid, 15175 app.pid, SystemClock.elapsedRealtime()); 15176 } 15177 app.lastCpuTime = app.curCpuTime; 15178 } 15179 15180 app.setRawAdj = app.curRawAdj; 15181 } 15182 15183 if (app.curAdj != app.setAdj) { 15184 ProcessList.setOomAdj(app.pid, app.curAdj); 15185 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v( 15186 TAG, "Set " + app.pid + " " + app.processName + 15187 " adj " + app.curAdj + ": " + app.adjType); 15188 app.setAdj = app.curAdj; 15189 } 15190 15191 if (app.setSchedGroup != app.curSchedGroup) { 15192 app.setSchedGroup = app.curSchedGroup; 15193 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 15194 "Setting process group of " + app.processName 15195 + " to " + app.curSchedGroup); 15196 if (app.waitingToKill != null && 15197 app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 15198 killUnneededProcessLocked(app, app.waitingToKill); 15199 success = false; 15200 } else { 15201 if (true) { 15202 long oldId = Binder.clearCallingIdentity(); 15203 try { 15204 Process.setProcessGroup(app.pid, app.curSchedGroup); 15205 } catch (Exception e) { 15206 Slog.w(TAG, "Failed setting process group of " + app.pid 15207 + " to " + app.curSchedGroup); 15208 e.printStackTrace(); 15209 } finally { 15210 Binder.restoreCallingIdentity(oldId); 15211 } 15212 } else { 15213 if (app.thread != null) { 15214 try { 15215 app.thread.setSchedulingGroup(app.curSchedGroup); 15216 } catch (RemoteException e) { 15217 } 15218 } 15219 } 15220 Process.setSwappiness(app.pid, 15221 app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE); 15222 } 15223 } 15224 if (app.repProcState != app.curProcState) { 15225 app.repProcState = app.curProcState; 15226 if (!reportingProcessState && app.thread != null) { 15227 try { 15228 if (false) { 15229 //RuntimeException h = new RuntimeException("here"); 15230 Slog.i(TAG, "Sending new process state " + app.repProcState 15231 + " to " + app /*, h*/); 15232 } 15233 app.thread.setProcessState(app.repProcState); 15234 } catch (RemoteException e) { 15235 } 15236 } 15237 } 15238 if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState, 15239 app.setProcState)) { 15240 app.lastStateTime = now; 15241 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true, 15242 mSleeping, now); 15243 if (DEBUG_PSS) Slog.d(TAG, "Process state change from " 15244 + ProcessList.makeProcStateString(app.setProcState) + " to " 15245 + ProcessList.makeProcStateString(app.curProcState) + " next pss in " 15246 + (app.nextPssTime-now) + ": " + app); 15247 } else { 15248 if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL) 15249 && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) { 15250 requestPssLocked(app, app.setProcState); 15251 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false, 15252 mSleeping, now); 15253 } else if (false && DEBUG_PSS) { 15254 Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now)); 15255 } 15256 } 15257 if (app.setProcState != app.curProcState) { 15258 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 15259 "Proc state change of " + app.processName 15260 + " to " + app.curProcState); 15261 app.setProcState = app.curProcState; 15262 if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) { 15263 app.notCachedSinceIdle = false; 15264 } 15265 if (!doingAll) { 15266 setProcessTrackerState(app, mProcessStats.getMemFactorLocked(), now); 15267 } else { 15268 app.procStateChanged = true; 15269 } 15270 } 15271 return success; 15272 } 15273 15274 private final void setProcessTrackerState(ProcessRecord proc, int memFactor, long now) { 15275 if (proc.thread != null && proc.baseProcessTracker != null) { 15276 proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList); 15277 } 15278 } 15279 15280 private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj, 15281 ProcessRecord TOP_APP, boolean doingAll, boolean reportingProcessState, long now) { 15282 if (app.thread == null) { 15283 return false; 15284 } 15285 15286 final boolean wasKeeping = app.keeping; 15287 15288 computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now); 15289 15290 return applyOomAdjLocked(app, wasKeeping, TOP_APP, doingAll, 15291 reportingProcessState, now); 15292 } 15293 15294 private final ActivityRecord resumedAppLocked() { 15295 return mStackSupervisor.resumedAppLocked(); 15296 } 15297 15298 final boolean updateOomAdjLocked(ProcessRecord app) { 15299 return updateOomAdjLocked(app, false); 15300 } 15301 15302 final boolean updateOomAdjLocked(ProcessRecord app, boolean doingProcessState) { 15303 final ActivityRecord TOP_ACT = resumedAppLocked(); 15304 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 15305 final boolean wasCached = app.cached; 15306 15307 mAdjSeq++; 15308 15309 // This is the desired cached adjusment we want to tell it to use. 15310 // If our app is currently cached, we know it, and that is it. Otherwise, 15311 // we don't know it yet, and it needs to now be cached we will then 15312 // need to do a complete oom adj. 15313 final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ 15314 ? app.curRawAdj : ProcessList.UNKNOWN_ADJ; 15315 boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false, doingProcessState, 15316 SystemClock.uptimeMillis()); 15317 if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) { 15318 // Changed to/from cached state, so apps after it in the LRU 15319 // list may also be changed. 15320 updateOomAdjLocked(); 15321 } 15322 return success; 15323 } 15324 15325 final void updateOomAdjLocked() { 15326 final ActivityRecord TOP_ACT = resumedAppLocked(); 15327 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 15328 final long now = SystemClock.uptimeMillis(); 15329 final long oldTime = now - ProcessList.MAX_EMPTY_TIME; 15330 final int N = mLruProcesses.size(); 15331 15332 if (false) { 15333 RuntimeException e = new RuntimeException(); 15334 e.fillInStackTrace(); 15335 Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e); 15336 } 15337 15338 mAdjSeq++; 15339 mNewNumServiceProcs = 0; 15340 mNewNumAServiceProcs = 0; 15341 15342 final int emptyProcessLimit; 15343 final int cachedProcessLimit; 15344 if (mProcessLimit <= 0) { 15345 emptyProcessLimit = cachedProcessLimit = 0; 15346 } else if (mProcessLimit == 1) { 15347 emptyProcessLimit = 1; 15348 cachedProcessLimit = 0; 15349 } else { 15350 emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit); 15351 cachedProcessLimit = mProcessLimit - emptyProcessLimit; 15352 } 15353 15354 // Let's determine how many processes we have running vs. 15355 // how many slots we have for background processes; we may want 15356 // to put multiple processes in a slot of there are enough of 15357 // them. 15358 int numSlots = (ProcessList.CACHED_APP_MAX_ADJ 15359 - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2; 15360 int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs; 15361 if (numEmptyProcs > cachedProcessLimit) { 15362 // If there are more empty processes than our limit on cached 15363 // processes, then use the cached process limit for the factor. 15364 // This ensures that the really old empty processes get pushed 15365 // down to the bottom, so if we are running low on memory we will 15366 // have a better chance at keeping around more cached processes 15367 // instead of a gazillion empty processes. 15368 numEmptyProcs = cachedProcessLimit; 15369 } 15370 int emptyFactor = numEmptyProcs/numSlots; 15371 if (emptyFactor < 1) emptyFactor = 1; 15372 int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots; 15373 if (cachedFactor < 1) cachedFactor = 1; 15374 int stepCached = 0; 15375 int stepEmpty = 0; 15376 int numCached = 0; 15377 int numEmpty = 0; 15378 int numTrimming = 0; 15379 15380 mNumNonCachedProcs = 0; 15381 mNumCachedHiddenProcs = 0; 15382 15383 // First update the OOM adjustment for each of the 15384 // application processes based on their current state. 15385 int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ; 15386 int nextCachedAdj = curCachedAdj+1; 15387 int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ; 15388 int nextEmptyAdj = curEmptyAdj+2; 15389 for (int i=N-1; i>=0; i--) { 15390 ProcessRecord app = mLruProcesses.get(i); 15391 if (!app.killedByAm && app.thread != null) { 15392 app.procStateChanged = false; 15393 final boolean wasKeeping = app.keeping; 15394 computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now); 15395 15396 // If we haven't yet assigned the final cached adj 15397 // to the process, do that now. 15398 if (app.curAdj >= ProcessList.UNKNOWN_ADJ) { 15399 switch (app.curProcState) { 15400 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY: 15401 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: 15402 // This process is a cached process holding activities... 15403 // assign it the next cached value for that type, and then 15404 // step that cached level. 15405 app.curRawAdj = curCachedAdj; 15406 app.curAdj = app.modifyRawOomAdj(curCachedAdj); 15407 if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i 15408 + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj 15409 + ")"); 15410 if (curCachedAdj != nextCachedAdj) { 15411 stepCached++; 15412 if (stepCached >= cachedFactor) { 15413 stepCached = 0; 15414 curCachedAdj = nextCachedAdj; 15415 nextCachedAdj += 2; 15416 if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) { 15417 nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ; 15418 } 15419 } 15420 } 15421 break; 15422 default: 15423 // For everything else, assign next empty cached process 15424 // level and bump that up. Note that this means that 15425 // long-running services that have dropped down to the 15426 // cached level will be treated as empty (since their process 15427 // state is still as a service), which is what we want. 15428 app.curRawAdj = curEmptyAdj; 15429 app.curAdj = app.modifyRawOomAdj(curEmptyAdj); 15430 if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i 15431 + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj 15432 + ")"); 15433 if (curEmptyAdj != nextEmptyAdj) { 15434 stepEmpty++; 15435 if (stepEmpty >= emptyFactor) { 15436 stepEmpty = 0; 15437 curEmptyAdj = nextEmptyAdj; 15438 nextEmptyAdj += 2; 15439 if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) { 15440 nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ; 15441 } 15442 } 15443 } 15444 break; 15445 } 15446 } 15447 15448 applyOomAdjLocked(app, wasKeeping, TOP_APP, true, false, now); 15449 15450 // Count the number of process types. 15451 switch (app.curProcState) { 15452 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY: 15453 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: 15454 mNumCachedHiddenProcs++; 15455 numCached++; 15456 if (numCached > cachedProcessLimit) { 15457 killUnneededProcessLocked(app, "cached #" + numCached); 15458 } 15459 break; 15460 case ActivityManager.PROCESS_STATE_CACHED_EMPTY: 15461 if (numEmpty > ProcessList.TRIM_EMPTY_APPS 15462 && app.lastActivityTime < oldTime) { 15463 killUnneededProcessLocked(app, "empty for " 15464 + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime) 15465 / 1000) + "s"); 15466 } else { 15467 numEmpty++; 15468 if (numEmpty > emptyProcessLimit) { 15469 killUnneededProcessLocked(app, "empty #" + numEmpty); 15470 } 15471 } 15472 break; 15473 default: 15474 mNumNonCachedProcs++; 15475 break; 15476 } 15477 15478 if (app.isolated && app.services.size() <= 0) { 15479 // If this is an isolated process, and there are no 15480 // services running in it, then the process is no longer 15481 // needed. We agressively kill these because we can by 15482 // definition not re-use the same process again, and it is 15483 // good to avoid having whatever code was running in them 15484 // left sitting around after no longer needed. 15485 killUnneededProcessLocked(app, "isolated not needed"); 15486 } 15487 15488 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME 15489 && !app.killedByAm) { 15490 numTrimming++; 15491 } 15492 } 15493 } 15494 15495 mNumServiceProcs = mNewNumServiceProcs; 15496 15497 // Now determine the memory trimming level of background processes. 15498 // Unfortunately we need to start at the back of the list to do this 15499 // properly. We only do this if the number of background apps we 15500 // are managing to keep around is less than half the maximum we desire; 15501 // if we are keeping a good number around, we'll let them use whatever 15502 // memory they want. 15503 final int numCachedAndEmpty = numCached + numEmpty; 15504 int memFactor; 15505 if (numCached <= ProcessList.TRIM_CACHED_APPS 15506 && numEmpty <= ProcessList.TRIM_EMPTY_APPS) { 15507 if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) { 15508 memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL; 15509 } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) { 15510 memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW; 15511 } else { 15512 memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE; 15513 } 15514 } else { 15515 memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL; 15516 } 15517 // We always allow the memory level to go up (better). We only allow it to go 15518 // down if we are in a state where that is allowed, *and* the total number of processes 15519 // has gone down since last time. 15520 if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel 15521 + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size() 15522 + " last=" + mLastNumProcesses); 15523 if (memFactor > mLastMemoryLevel) { 15524 if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) { 15525 memFactor = mLastMemoryLevel; 15526 if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!"); 15527 } 15528 } 15529 mLastMemoryLevel = memFactor; 15530 mLastNumProcesses = mLruProcesses.size(); 15531 boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !mSleeping, now); 15532 final int trackerMemFactor = mProcessStats.getMemFactorLocked(); 15533 if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) { 15534 if (mLowRamStartTime == 0) { 15535 mLowRamStartTime = now; 15536 } 15537 int step = 0; 15538 int fgTrimLevel; 15539 switch (memFactor) { 15540 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL: 15541 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL; 15542 break; 15543 case ProcessStats.ADJ_MEM_FACTOR_LOW: 15544 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW; 15545 break; 15546 default: 15547 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE; 15548 break; 15549 } 15550 int factor = numTrimming/3; 15551 int minFactor = 2; 15552 if (mHomeProcess != null) minFactor++; 15553 if (mPreviousProcess != null) minFactor++; 15554 if (factor < minFactor) factor = minFactor; 15555 int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE; 15556 for (int i=N-1; i>=0; i--) { 15557 ProcessRecord app = mLruProcesses.get(i); 15558 if (allChanged || app.procStateChanged) { 15559 setProcessTrackerState(app, trackerMemFactor, now); 15560 app.procStateChanged = false; 15561 } 15562 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME 15563 && !app.killedByAm) { 15564 if (app.trimMemoryLevel < curLevel && app.thread != null) { 15565 try { 15566 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 15567 "Trimming memory of " + app.processName 15568 + " to " + curLevel); 15569 app.thread.scheduleTrimMemory(curLevel); 15570 } catch (RemoteException e) { 15571 } 15572 if (false) { 15573 // For now we won't do this; our memory trimming seems 15574 // to be good enough at this point that destroying 15575 // activities causes more harm than good. 15576 if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE 15577 && app != mHomeProcess && app != mPreviousProcess) { 15578 // Need to do this on its own message because the stack may not 15579 // be in a consistent state at this point. 15580 // For these apps we will also finish their activities 15581 // to help them free memory. 15582 mStackSupervisor.scheduleDestroyAllActivities(app, "trim"); 15583 } 15584 } 15585 } 15586 app.trimMemoryLevel = curLevel; 15587 step++; 15588 if (step >= factor) { 15589 step = 0; 15590 switch (curLevel) { 15591 case ComponentCallbacks2.TRIM_MEMORY_COMPLETE: 15592 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE; 15593 break; 15594 case ComponentCallbacks2.TRIM_MEMORY_MODERATE: 15595 curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 15596 break; 15597 } 15598 } 15599 } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) { 15600 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND 15601 && app.thread != null) { 15602 try { 15603 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 15604 "Trimming memory of heavy-weight " + app.processName 15605 + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 15606 app.thread.scheduleTrimMemory( 15607 ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 15608 } catch (RemoteException e) { 15609 } 15610 } 15611 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 15612 } else { 15613 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 15614 || app.systemNoUi) && app.pendingUiClean) { 15615 // If this application is now in the background and it 15616 // had done UI, then give it the special trim level to 15617 // have it free UI resources. 15618 final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN; 15619 if (app.trimMemoryLevel < level && app.thread != null) { 15620 try { 15621 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 15622 "Trimming memory of bg-ui " + app.processName 15623 + " to " + level); 15624 app.thread.scheduleTrimMemory(level); 15625 } catch (RemoteException e) { 15626 } 15627 } 15628 app.pendingUiClean = false; 15629 } 15630 if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) { 15631 try { 15632 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 15633 "Trimming memory of fg " + app.processName 15634 + " to " + fgTrimLevel); 15635 app.thread.scheduleTrimMemory(fgTrimLevel); 15636 } catch (RemoteException e) { 15637 } 15638 } 15639 app.trimMemoryLevel = fgTrimLevel; 15640 } 15641 } 15642 } else { 15643 if (mLowRamStartTime != 0) { 15644 mLowRamTimeSinceLastIdle += now - mLowRamStartTime; 15645 mLowRamStartTime = 0; 15646 } 15647 for (int i=N-1; i>=0; i--) { 15648 ProcessRecord app = mLruProcesses.get(i); 15649 if (allChanged || app.procStateChanged) { 15650 setProcessTrackerState(app, trackerMemFactor, now); 15651 app.procStateChanged = false; 15652 } 15653 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 15654 || app.systemNoUi) && app.pendingUiClean) { 15655 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN 15656 && app.thread != null) { 15657 try { 15658 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 15659 "Trimming memory of ui hidden " + app.processName 15660 + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 15661 app.thread.scheduleTrimMemory( 15662 ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 15663 } catch (RemoteException e) { 15664 } 15665 } 15666 app.pendingUiClean = false; 15667 } 15668 app.trimMemoryLevel = 0; 15669 } 15670 } 15671 15672 if (mAlwaysFinishActivities) { 15673 // Need to do this on its own message because the stack may not 15674 // be in a consistent state at this point. 15675 mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish"); 15676 } 15677 15678 if (allChanged) { 15679 requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered()); 15680 } 15681 15682 if (mProcessStats.shouldWriteNowLocked(now)) { 15683 mHandler.post(new Runnable() { 15684 @Override public void run() { 15685 synchronized (ActivityManagerService.this) { 15686 mProcessStats.writeStateAsyncLocked(); 15687 } 15688 } 15689 }); 15690 } 15691 15692 if (DEBUG_OOM_ADJ) { 15693 Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms"); 15694 } 15695 } 15696 15697 final void trimApplications() { 15698 synchronized (this) { 15699 int i; 15700 15701 // First remove any unused application processes whose package 15702 // has been removed. 15703 for (i=mRemovedProcesses.size()-1; i>=0; i--) { 15704 final ProcessRecord app = mRemovedProcesses.get(i); 15705 if (app.activities.size() == 0 15706 && app.curReceiver == null && app.services.size() == 0) { 15707 Slog.i( 15708 TAG, "Exiting empty application process " 15709 + app.processName + " (" 15710 + (app.thread != null ? app.thread.asBinder() : null) 15711 + ")\n"); 15712 if (app.pid > 0 && app.pid != MY_PID) { 15713 EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid, 15714 app.processName, app.setAdj, "empty"); 15715 app.killedByAm = true; 15716 Process.killProcessQuiet(app.pid); 15717 } else { 15718 try { 15719 app.thread.scheduleExit(); 15720 } catch (Exception e) { 15721 // Ignore exceptions. 15722 } 15723 } 15724 cleanUpApplicationRecordLocked(app, false, true, -1); 15725 mRemovedProcesses.remove(i); 15726 15727 if (app.persistent) { 15728 if (app.persistent) { 15729 addAppLocked(app.info, false); 15730 } 15731 } 15732 } 15733 } 15734 15735 // Now update the oom adj for all processes. 15736 updateOomAdjLocked(); 15737 } 15738 } 15739 15740 /** This method sends the specified signal to each of the persistent apps */ 15741 public void signalPersistentProcesses(int sig) throws RemoteException { 15742 if (sig != Process.SIGNAL_USR1) { 15743 throw new SecurityException("Only SIGNAL_USR1 is allowed"); 15744 } 15745 15746 synchronized (this) { 15747 if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES) 15748 != PackageManager.PERMISSION_GRANTED) { 15749 throw new SecurityException("Requires permission " 15750 + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES); 15751 } 15752 15753 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 15754 ProcessRecord r = mLruProcesses.get(i); 15755 if (r.thread != null && r.persistent) { 15756 Process.sendSignal(r.pid, sig); 15757 } 15758 } 15759 } 15760 } 15761 15762 private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) { 15763 if (proc == null || proc == mProfileProc) { 15764 proc = mProfileProc; 15765 path = mProfileFile; 15766 profileType = mProfileType; 15767 clearProfilerLocked(); 15768 } 15769 if (proc == null) { 15770 return; 15771 } 15772 try { 15773 proc.thread.profilerControl(false, path, null, profileType); 15774 } catch (RemoteException e) { 15775 throw new IllegalStateException("Process disappeared"); 15776 } 15777 } 15778 15779 private void clearProfilerLocked() { 15780 if (mProfileFd != null) { 15781 try { 15782 mProfileFd.close(); 15783 } catch (IOException e) { 15784 } 15785 } 15786 mProfileApp = null; 15787 mProfileProc = null; 15788 mProfileFile = null; 15789 mProfileType = 0; 15790 mAutoStopProfiler = false; 15791 } 15792 15793 public boolean profileControl(String process, int userId, boolean start, 15794 String path, ParcelFileDescriptor fd, int profileType) throws RemoteException { 15795 15796 try { 15797 synchronized (this) { 15798 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 15799 // its own permission. 15800 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 15801 != PackageManager.PERMISSION_GRANTED) { 15802 throw new SecurityException("Requires permission " 15803 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 15804 } 15805 15806 if (start && fd == null) { 15807 throw new IllegalArgumentException("null fd"); 15808 } 15809 15810 ProcessRecord proc = null; 15811 if (process != null) { 15812 proc = findProcessLocked(process, userId, "profileControl"); 15813 } 15814 15815 if (start && (proc == null || proc.thread == null)) { 15816 throw new IllegalArgumentException("Unknown process: " + process); 15817 } 15818 15819 if (start) { 15820 stopProfilerLocked(null, null, 0); 15821 setProfileApp(proc.info, proc.processName, path, fd, false); 15822 mProfileProc = proc; 15823 mProfileType = profileType; 15824 try { 15825 fd = fd.dup(); 15826 } catch (IOException e) { 15827 fd = null; 15828 } 15829 proc.thread.profilerControl(start, path, fd, profileType); 15830 fd = null; 15831 mProfileFd = null; 15832 } else { 15833 stopProfilerLocked(proc, path, profileType); 15834 if (fd != null) { 15835 try { 15836 fd.close(); 15837 } catch (IOException e) { 15838 } 15839 } 15840 } 15841 15842 return true; 15843 } 15844 } catch (RemoteException e) { 15845 throw new IllegalStateException("Process disappeared"); 15846 } finally { 15847 if (fd != null) { 15848 try { 15849 fd.close(); 15850 } catch (IOException e) { 15851 } 15852 } 15853 } 15854 } 15855 15856 private ProcessRecord findProcessLocked(String process, int userId, String callName) { 15857 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 15858 userId, true, true, callName, null); 15859 ProcessRecord proc = null; 15860 try { 15861 int pid = Integer.parseInt(process); 15862 synchronized (mPidsSelfLocked) { 15863 proc = mPidsSelfLocked.get(pid); 15864 } 15865 } catch (NumberFormatException e) { 15866 } 15867 15868 if (proc == null) { 15869 ArrayMap<String, SparseArray<ProcessRecord>> all 15870 = mProcessNames.getMap(); 15871 SparseArray<ProcessRecord> procs = all.get(process); 15872 if (procs != null && procs.size() > 0) { 15873 proc = procs.valueAt(0); 15874 if (userId != UserHandle.USER_ALL && proc.userId != userId) { 15875 for (int i=1; i<procs.size(); i++) { 15876 ProcessRecord thisProc = procs.valueAt(i); 15877 if (thisProc.userId == userId) { 15878 proc = thisProc; 15879 break; 15880 } 15881 } 15882 } 15883 } 15884 } 15885 15886 return proc; 15887 } 15888 15889 public boolean dumpHeap(String process, int userId, boolean managed, 15890 String path, ParcelFileDescriptor fd) throws RemoteException { 15891 15892 try { 15893 synchronized (this) { 15894 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 15895 // its own permission (same as profileControl). 15896 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 15897 != PackageManager.PERMISSION_GRANTED) { 15898 throw new SecurityException("Requires permission " 15899 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 15900 } 15901 15902 if (fd == null) { 15903 throw new IllegalArgumentException("null fd"); 15904 } 15905 15906 ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap"); 15907 if (proc == null || proc.thread == null) { 15908 throw new IllegalArgumentException("Unknown process: " + process); 15909 } 15910 15911 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 15912 if (!isDebuggable) { 15913 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 15914 throw new SecurityException("Process not debuggable: " + proc); 15915 } 15916 } 15917 15918 proc.thread.dumpHeap(managed, path, fd); 15919 fd = null; 15920 return true; 15921 } 15922 } catch (RemoteException e) { 15923 throw new IllegalStateException("Process disappeared"); 15924 } finally { 15925 if (fd != null) { 15926 try { 15927 fd.close(); 15928 } catch (IOException e) { 15929 } 15930 } 15931 } 15932 } 15933 15934 /** In this method we try to acquire our lock to make sure that we have not deadlocked */ 15935 public void monitor() { 15936 synchronized (this) { } 15937 } 15938 15939 void onCoreSettingsChange(Bundle settings) { 15940 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 15941 ProcessRecord processRecord = mLruProcesses.get(i); 15942 try { 15943 if (processRecord.thread != null) { 15944 processRecord.thread.setCoreSettings(settings); 15945 } 15946 } catch (RemoteException re) { 15947 /* ignore */ 15948 } 15949 } 15950 } 15951 15952 // Multi-user methods 15953 15954 @Override 15955 public boolean switchUser(final int userId) { 15956 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 15957 != PackageManager.PERMISSION_GRANTED) { 15958 String msg = "Permission Denial: switchUser() from pid=" 15959 + Binder.getCallingPid() 15960 + ", uid=" + Binder.getCallingUid() 15961 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 15962 Slog.w(TAG, msg); 15963 throw new SecurityException(msg); 15964 } 15965 15966 final long ident = Binder.clearCallingIdentity(); 15967 try { 15968 synchronized (this) { 15969 final int oldUserId = mCurrentUserId; 15970 if (oldUserId == userId) { 15971 return true; 15972 } 15973 15974 final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId); 15975 if (userInfo == null) { 15976 Slog.w(TAG, "No user info for user #" + userId); 15977 return false; 15978 } 15979 15980 mWindowManager.startFreezingScreen(R.anim.screen_user_exit, 15981 R.anim.screen_user_enter); 15982 15983 boolean needStart = false; 15984 15985 // If the user we are switching to is not currently started, then 15986 // we need to start it now. 15987 if (mStartedUsers.get(userId) == null) { 15988 mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false)); 15989 updateStartedUserArrayLocked(); 15990 needStart = true; 15991 } 15992 15993 mCurrentUserId = userId; 15994 final Integer userIdInt = Integer.valueOf(userId); 15995 mUserLru.remove(userIdInt); 15996 mUserLru.add(userIdInt); 15997 15998 mWindowManager.setCurrentUser(userId); 15999 16000 // Once the internal notion of the active user has switched, we lock the device 16001 // with the option to show the user switcher on the keyguard. 16002 mWindowManager.lockNow(null); 16003 16004 final UserStartedState uss = mStartedUsers.get(userId); 16005 16006 // Make sure user is in the started state. If it is currently 16007 // stopping, we need to knock that off. 16008 if (uss.mState == UserStartedState.STATE_STOPPING) { 16009 // If we are stopping, we haven't sent ACTION_SHUTDOWN, 16010 // so we can just fairly silently bring the user back from 16011 // the almost-dead. 16012 uss.mState = UserStartedState.STATE_RUNNING; 16013 updateStartedUserArrayLocked(); 16014 needStart = true; 16015 } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) { 16016 // This means ACTION_SHUTDOWN has been sent, so we will 16017 // need to treat this as a new boot of the user. 16018 uss.mState = UserStartedState.STATE_BOOTING; 16019 updateStartedUserArrayLocked(); 16020 needStart = true; 16021 } 16022 16023 mHandler.removeMessages(REPORT_USER_SWITCH_MSG); 16024 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 16025 mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG, 16026 oldUserId, userId, uss)); 16027 mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG, 16028 oldUserId, userId, uss), USER_SWITCH_TIMEOUT); 16029 if (needStart) { 16030 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 16031 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16032 | Intent.FLAG_RECEIVER_FOREGROUND); 16033 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 16034 broadcastIntentLocked(null, null, intent, 16035 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 16036 false, false, MY_PID, Process.SYSTEM_UID, userId); 16037 } 16038 16039 if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) { 16040 if (userId != 0) { 16041 Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE); 16042 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 16043 broadcastIntentLocked(null, null, intent, null, 16044 new IIntentReceiver.Stub() { 16045 public void performReceive(Intent intent, int resultCode, 16046 String data, Bundle extras, boolean ordered, 16047 boolean sticky, int sendingUser) { 16048 userInitialized(uss, userId); 16049 } 16050 }, 0, null, null, null, AppOpsManager.OP_NONE, 16051 true, false, MY_PID, Process.SYSTEM_UID, 16052 userId); 16053 uss.initializing = true; 16054 } else { 16055 getUserManagerLocked().makeInitialized(userInfo.id); 16056 } 16057 } 16058 16059 boolean homeInFront = mStackSupervisor.switchUserLocked(userId, uss); 16060 if (homeInFront) { 16061 startHomeActivityLocked(userId); 16062 } else { 16063 mStackSupervisor.resumeTopActivitiesLocked(); 16064 } 16065 16066 EventLogTags.writeAmSwitchUser(userId); 16067 getUserManagerLocked().userForeground(userId); 16068 sendUserSwitchBroadcastsLocked(oldUserId, userId); 16069 if (needStart) { 16070 Intent intent = new Intent(Intent.ACTION_USER_STARTING); 16071 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 16072 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 16073 broadcastIntentLocked(null, null, intent, 16074 null, new IIntentReceiver.Stub() { 16075 @Override 16076 public void performReceive(Intent intent, int resultCode, String data, 16077 Bundle extras, boolean ordered, boolean sticky, int sendingUser) 16078 throws RemoteException { 16079 } 16080 }, 0, null, null, 16081 android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 16082 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 16083 } 16084 } 16085 } finally { 16086 Binder.restoreCallingIdentity(ident); 16087 } 16088 16089 return true; 16090 } 16091 16092 void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) { 16093 long ident = Binder.clearCallingIdentity(); 16094 try { 16095 Intent intent; 16096 if (oldUserId >= 0) { 16097 intent = new Intent(Intent.ACTION_USER_BACKGROUND); 16098 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16099 | Intent.FLAG_RECEIVER_FOREGROUND); 16100 intent.putExtra(Intent.EXTRA_USER_HANDLE, oldUserId); 16101 broadcastIntentLocked(null, null, intent, 16102 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 16103 false, false, MY_PID, Process.SYSTEM_UID, oldUserId); 16104 } 16105 if (newUserId >= 0) { 16106 intent = new Intent(Intent.ACTION_USER_FOREGROUND); 16107 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16108 | Intent.FLAG_RECEIVER_FOREGROUND); 16109 intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId); 16110 broadcastIntentLocked(null, null, intent, 16111 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 16112 false, false, MY_PID, Process.SYSTEM_UID, newUserId); 16113 intent = new Intent(Intent.ACTION_USER_SWITCHED); 16114 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16115 | Intent.FLAG_RECEIVER_FOREGROUND); 16116 intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId); 16117 broadcastIntentLocked(null, null, intent, 16118 null, null, 0, null, null, 16119 android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE, 16120 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 16121 } 16122 } finally { 16123 Binder.restoreCallingIdentity(ident); 16124 } 16125 } 16126 16127 void dispatchUserSwitch(final UserStartedState uss, final int oldUserId, 16128 final int newUserId) { 16129 final int N = mUserSwitchObservers.beginBroadcast(); 16130 if (N > 0) { 16131 final IRemoteCallback callback = new IRemoteCallback.Stub() { 16132 int mCount = 0; 16133 @Override 16134 public void sendResult(Bundle data) throws RemoteException { 16135 synchronized (ActivityManagerService.this) { 16136 if (mCurUserSwitchCallback == this) { 16137 mCount++; 16138 if (mCount == N) { 16139 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 16140 } 16141 } 16142 } 16143 } 16144 }; 16145 synchronized (this) { 16146 uss.switching = true; 16147 mCurUserSwitchCallback = callback; 16148 } 16149 for (int i=0; i<N; i++) { 16150 try { 16151 mUserSwitchObservers.getBroadcastItem(i).onUserSwitching( 16152 newUserId, callback); 16153 } catch (RemoteException e) { 16154 } 16155 } 16156 } else { 16157 synchronized (this) { 16158 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 16159 } 16160 } 16161 mUserSwitchObservers.finishBroadcast(); 16162 } 16163 16164 void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 16165 synchronized (this) { 16166 Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId); 16167 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 16168 } 16169 } 16170 16171 void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) { 16172 mCurUserSwitchCallback = null; 16173 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 16174 mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG, 16175 oldUserId, newUserId, uss)); 16176 } 16177 16178 void userInitialized(UserStartedState uss, int newUserId) { 16179 completeSwitchAndInitalize(uss, newUserId, true, false); 16180 } 16181 16182 void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 16183 completeSwitchAndInitalize(uss, newUserId, false, true); 16184 } 16185 16186 void completeSwitchAndInitalize(UserStartedState uss, int newUserId, 16187 boolean clearInitializing, boolean clearSwitching) { 16188 boolean unfrozen = false; 16189 synchronized (this) { 16190 if (clearInitializing) { 16191 uss.initializing = false; 16192 getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier()); 16193 } 16194 if (clearSwitching) { 16195 uss.switching = false; 16196 } 16197 if (!uss.switching && !uss.initializing) { 16198 mWindowManager.stopFreezingScreen(); 16199 unfrozen = true; 16200 } 16201 } 16202 if (unfrozen) { 16203 final int N = mUserSwitchObservers.beginBroadcast(); 16204 for (int i=0; i<N; i++) { 16205 try { 16206 mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId); 16207 } catch (RemoteException e) { 16208 } 16209 } 16210 mUserSwitchObservers.finishBroadcast(); 16211 } 16212 } 16213 16214 void finishUserSwitch(UserStartedState uss) { 16215 synchronized (this) { 16216 if (uss.mState == UserStartedState.STATE_BOOTING 16217 && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) { 16218 uss.mState = UserStartedState.STATE_RUNNING; 16219 final int userId = uss.mHandle.getIdentifier(); 16220 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 16221 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 16222 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT); 16223 broadcastIntentLocked(null, null, intent, 16224 null, null, 0, null, null, 16225 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE, 16226 true, false, MY_PID, Process.SYSTEM_UID, userId); 16227 } 16228 int num = mUserLru.size(); 16229 int i = 0; 16230 while (num > MAX_RUNNING_USERS && i < mUserLru.size()) { 16231 Integer oldUserId = mUserLru.get(i); 16232 UserStartedState oldUss = mStartedUsers.get(oldUserId); 16233 if (oldUss == null) { 16234 // Shouldn't happen, but be sane if it does. 16235 mUserLru.remove(i); 16236 num--; 16237 continue; 16238 } 16239 if (oldUss.mState == UserStartedState.STATE_STOPPING 16240 || oldUss.mState == UserStartedState.STATE_SHUTDOWN) { 16241 // This user is already stopping, doesn't count. 16242 num--; 16243 i++; 16244 continue; 16245 } 16246 if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) { 16247 // Owner and current can't be stopped, but count as running. 16248 i++; 16249 continue; 16250 } 16251 // This is a user to be stopped. 16252 stopUserLocked(oldUserId, null); 16253 num--; 16254 i++; 16255 } 16256 } 16257 } 16258 16259 @Override 16260 public int stopUser(final int userId, final IStopUserCallback callback) { 16261 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 16262 != PackageManager.PERMISSION_GRANTED) { 16263 String msg = "Permission Denial: switchUser() from pid=" 16264 + Binder.getCallingPid() 16265 + ", uid=" + Binder.getCallingUid() 16266 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 16267 Slog.w(TAG, msg); 16268 throw new SecurityException(msg); 16269 } 16270 if (userId <= 0) { 16271 throw new IllegalArgumentException("Can't stop primary user " + userId); 16272 } 16273 synchronized (this) { 16274 return stopUserLocked(userId, callback); 16275 } 16276 } 16277 16278 private int stopUserLocked(final int userId, final IStopUserCallback callback) { 16279 if (mCurrentUserId == userId) { 16280 return ActivityManager.USER_OP_IS_CURRENT; 16281 } 16282 16283 final UserStartedState uss = mStartedUsers.get(userId); 16284 if (uss == null) { 16285 // User is not started, nothing to do... but we do need to 16286 // callback if requested. 16287 if (callback != null) { 16288 mHandler.post(new Runnable() { 16289 @Override 16290 public void run() { 16291 try { 16292 callback.userStopped(userId); 16293 } catch (RemoteException e) { 16294 } 16295 } 16296 }); 16297 } 16298 return ActivityManager.USER_OP_SUCCESS; 16299 } 16300 16301 if (callback != null) { 16302 uss.mStopCallbacks.add(callback); 16303 } 16304 16305 if (uss.mState != UserStartedState.STATE_STOPPING 16306 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 16307 uss.mState = UserStartedState.STATE_STOPPING; 16308 updateStartedUserArrayLocked(); 16309 16310 long ident = Binder.clearCallingIdentity(); 16311 try { 16312 // We are going to broadcast ACTION_USER_STOPPING and then 16313 // once that is done send a final ACTION_SHUTDOWN and then 16314 // stop the user. 16315 final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING); 16316 stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 16317 stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 16318 stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true); 16319 final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN); 16320 // This is the result receiver for the final shutdown broadcast. 16321 final IIntentReceiver shutdownReceiver = 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 finishUserStop(uss); 16326 } 16327 }; 16328 // This is the result receiver for the initial stopping broadcast. 16329 final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() { 16330 @Override 16331 public void performReceive(Intent intent, int resultCode, String data, 16332 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 16333 // On to the next. 16334 synchronized (ActivityManagerService.this) { 16335 if (uss.mState != UserStartedState.STATE_STOPPING) { 16336 // Whoops, we are being started back up. Abort, abort! 16337 return; 16338 } 16339 uss.mState = UserStartedState.STATE_SHUTDOWN; 16340 } 16341 broadcastIntentLocked(null, null, shutdownIntent, 16342 null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE, 16343 true, false, MY_PID, Process.SYSTEM_UID, userId); 16344 } 16345 }; 16346 // Kick things off. 16347 broadcastIntentLocked(null, null, stoppingIntent, 16348 null, stoppingReceiver, 0, null, null, 16349 android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 16350 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 16351 } finally { 16352 Binder.restoreCallingIdentity(ident); 16353 } 16354 } 16355 16356 return ActivityManager.USER_OP_SUCCESS; 16357 } 16358 16359 void finishUserStop(UserStartedState uss) { 16360 final int userId = uss.mHandle.getIdentifier(); 16361 boolean stopped; 16362 ArrayList<IStopUserCallback> callbacks; 16363 synchronized (this) { 16364 callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks); 16365 if (mStartedUsers.get(userId) != uss) { 16366 stopped = false; 16367 } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) { 16368 stopped = false; 16369 } else { 16370 stopped = true; 16371 // User can no longer run. 16372 mStartedUsers.remove(userId); 16373 mUserLru.remove(Integer.valueOf(userId)); 16374 updateStartedUserArrayLocked(); 16375 16376 // Clean up all state and processes associated with the user. 16377 // Kill all the processes for the user. 16378 forceStopUserLocked(userId, "finish user"); 16379 } 16380 } 16381 16382 for (int i=0; i<callbacks.size(); i++) { 16383 try { 16384 if (stopped) callbacks.get(i).userStopped(userId); 16385 else callbacks.get(i).userStopAborted(userId); 16386 } catch (RemoteException e) { 16387 } 16388 } 16389 16390 mStackSupervisor.removeUserLocked(userId); 16391 } 16392 16393 @Override 16394 public UserInfo getCurrentUser() { 16395 if ((checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) 16396 != PackageManager.PERMISSION_GRANTED) && ( 16397 checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 16398 != PackageManager.PERMISSION_GRANTED)) { 16399 String msg = "Permission Denial: getCurrentUser() from pid=" 16400 + Binder.getCallingPid() 16401 + ", uid=" + Binder.getCallingUid() 16402 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS; 16403 Slog.w(TAG, msg); 16404 throw new SecurityException(msg); 16405 } 16406 synchronized (this) { 16407 return getUserManagerLocked().getUserInfo(mCurrentUserId); 16408 } 16409 } 16410 16411 int getCurrentUserIdLocked() { 16412 return mCurrentUserId; 16413 } 16414 16415 @Override 16416 public boolean isUserRunning(int userId, boolean orStopped) { 16417 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) 16418 != PackageManager.PERMISSION_GRANTED) { 16419 String msg = "Permission Denial: isUserRunning() from pid=" 16420 + Binder.getCallingPid() 16421 + ", uid=" + Binder.getCallingUid() 16422 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS; 16423 Slog.w(TAG, msg); 16424 throw new SecurityException(msg); 16425 } 16426 synchronized (this) { 16427 return isUserRunningLocked(userId, orStopped); 16428 } 16429 } 16430 16431 boolean isUserRunningLocked(int userId, boolean orStopped) { 16432 UserStartedState state = mStartedUsers.get(userId); 16433 if (state == null) { 16434 return false; 16435 } 16436 if (orStopped) { 16437 return true; 16438 } 16439 return state.mState != UserStartedState.STATE_STOPPING 16440 && state.mState != UserStartedState.STATE_SHUTDOWN; 16441 } 16442 16443 @Override 16444 public int[] getRunningUserIds() { 16445 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) 16446 != PackageManager.PERMISSION_GRANTED) { 16447 String msg = "Permission Denial: isUserRunning() from pid=" 16448 + Binder.getCallingPid() 16449 + ", uid=" + Binder.getCallingUid() 16450 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS; 16451 Slog.w(TAG, msg); 16452 throw new SecurityException(msg); 16453 } 16454 synchronized (this) { 16455 return mStartedUserArray; 16456 } 16457 } 16458 16459 private void updateStartedUserArrayLocked() { 16460 int num = 0; 16461 for (int i=0; i<mStartedUsers.size(); i++) { 16462 UserStartedState uss = mStartedUsers.valueAt(i); 16463 // This list does not include stopping users. 16464 if (uss.mState != UserStartedState.STATE_STOPPING 16465 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 16466 num++; 16467 } 16468 } 16469 mStartedUserArray = new int[num]; 16470 num = 0; 16471 for (int i=0; i<mStartedUsers.size(); i++) { 16472 UserStartedState uss = mStartedUsers.valueAt(i); 16473 if (uss.mState != UserStartedState.STATE_STOPPING 16474 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 16475 mStartedUserArray[num] = mStartedUsers.keyAt(i); 16476 num++; 16477 } 16478 } 16479 } 16480 16481 @Override 16482 public void registerUserSwitchObserver(IUserSwitchObserver observer) { 16483 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 16484 != PackageManager.PERMISSION_GRANTED) { 16485 String msg = "Permission Denial: registerUserSwitchObserver() from pid=" 16486 + Binder.getCallingPid() 16487 + ", uid=" + Binder.getCallingUid() 16488 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 16489 Slog.w(TAG, msg); 16490 throw new SecurityException(msg); 16491 } 16492 16493 mUserSwitchObservers.register(observer); 16494 } 16495 16496 @Override 16497 public void unregisterUserSwitchObserver(IUserSwitchObserver observer) { 16498 mUserSwitchObservers.unregister(observer); 16499 } 16500 16501 private boolean userExists(int userId) { 16502 if (userId == 0) { 16503 return true; 16504 } 16505 UserManagerService ums = getUserManagerLocked(); 16506 return ums != null ? (ums.getUserInfo(userId) != null) : false; 16507 } 16508 16509 int[] getUsersLocked() { 16510 UserManagerService ums = getUserManagerLocked(); 16511 return ums != null ? ums.getUserIds() : new int[] { 0 }; 16512 } 16513 16514 UserManagerService getUserManagerLocked() { 16515 if (mUserManager == null) { 16516 IBinder b = ServiceManager.getService(Context.USER_SERVICE); 16517 mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b); 16518 } 16519 return mUserManager; 16520 } 16521 16522 private int applyUserId(int uid, int userId) { 16523 return UserHandle.getUid(userId, uid); 16524 } 16525 16526 ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) { 16527 if (info == null) return null; 16528 ApplicationInfo newInfo = new ApplicationInfo(info); 16529 newInfo.uid = applyUserId(info.uid, userId); 16530 newInfo.dataDir = USER_DATA_DIR + userId + "/" 16531 + info.packageName; 16532 return newInfo; 16533 } 16534 16535 ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) { 16536 if (aInfo == null 16537 || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) { 16538 return aInfo; 16539 } 16540 16541 ActivityInfo info = new ActivityInfo(aInfo); 16542 info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId); 16543 return info; 16544 } 16545} 16546