ActivityManagerService.java revision e0a3884cb627efc650e19fbe76b1b3343468cf57
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.util.ArrayMap; 36import com.android.internal.R; 37import com.android.internal.annotations.GuardedBy; 38import com.android.internal.app.IAppOpsService; 39import com.android.internal.app.ProcessMap; 40import com.android.internal.app.ProcessStats; 41import com.android.internal.os.BackgroundThread; 42import com.android.internal.os.BatteryStatsImpl; 43import com.android.internal.os.ProcessCpuTracker; 44import com.android.internal.os.TransferPipe; 45import com.android.internal.util.FastPrintWriter; 46import com.android.internal.util.FastXmlSerializer; 47import com.android.internal.util.MemInfoReader; 48import com.android.internal.util.Preconditions; 49import com.android.server.AppOpsService; 50import com.android.server.AttributeCache; 51import com.android.server.IntentResolver; 52import com.android.server.SystemServer; 53import com.android.server.Watchdog; 54import com.android.server.am.ActivityStack.ActivityState; 55import com.android.server.firewall.IntentFirewall; 56import com.android.server.pm.UserManagerService; 57import com.android.server.wm.AppTransition; 58import com.android.server.wm.WindowManagerService; 59import com.google.android.collect.Lists; 60import com.google.android.collect.Maps; 61 62import dalvik.system.Zygote; 63 64import libcore.io.IoUtils; 65 66import org.xmlpull.v1.XmlPullParser; 67import org.xmlpull.v1.XmlPullParserException; 68import org.xmlpull.v1.XmlSerializer; 69 70import android.app.Activity; 71import android.app.ActivityManager; 72import android.app.ActivityManager.RunningTaskInfo; 73import android.app.ActivityManager.StackInfo; 74import android.app.ActivityManagerNative; 75import android.app.ActivityOptions; 76import android.app.ActivityThread; 77import android.app.AlertDialog; 78import android.app.AppGlobals; 79import android.app.ApplicationErrorReport; 80import android.app.Dialog; 81import android.app.IActivityController; 82import android.app.IApplicationThread; 83import android.app.IInstrumentationWatcher; 84import android.app.INotificationManager; 85import android.app.IProcessObserver; 86import android.app.IServiceConnection; 87import android.app.IStopUserCallback; 88import android.app.IThumbnailReceiver; 89import android.app.IUiAutomationConnection; 90import android.app.IUserSwitchObserver; 91import android.app.Instrumentation; 92import android.app.Notification; 93import android.app.NotificationManager; 94import android.app.PendingIntent; 95import android.app.backup.IBackupManager; 96import android.content.ActivityNotFoundException; 97import android.content.BroadcastReceiver; 98import android.content.ClipData; 99import android.content.ComponentCallbacks2; 100import android.content.ComponentName; 101import android.content.ContentProvider; 102import android.content.ContentResolver; 103import android.content.Context; 104import android.content.DialogInterface; 105import android.content.IContentProvider; 106import android.content.IIntentReceiver; 107import android.content.IIntentSender; 108import android.content.Intent; 109import android.content.IntentFilter; 110import android.content.IntentSender; 111import android.content.pm.ActivityInfo; 112import android.content.pm.ApplicationInfo; 113import android.content.pm.ConfigurationInfo; 114import android.content.pm.IPackageDataObserver; 115import android.content.pm.IPackageManager; 116import android.content.pm.InstrumentationInfo; 117import android.content.pm.PackageInfo; 118import android.content.pm.PackageManager; 119import android.content.pm.ParceledListSlice; 120import android.content.pm.UserInfo; 121import android.content.pm.PackageManager.NameNotFoundException; 122import android.content.pm.PathPermission; 123import android.content.pm.ProviderInfo; 124import android.content.pm.ResolveInfo; 125import android.content.pm.ServiceInfo; 126import android.content.res.CompatibilityInfo; 127import android.content.res.Configuration; 128import android.graphics.Bitmap; 129import android.net.Proxy; 130import android.net.ProxyProperties; 131import android.net.Uri; 132import android.os.Binder; 133import android.os.Build; 134import android.os.Bundle; 135import android.os.Debug; 136import android.os.DropBoxManager; 137import android.os.Environment; 138import android.os.FileObserver; 139import android.os.FileUtils; 140import android.os.Handler; 141import android.os.IBinder; 142import android.os.IPermissionController; 143import android.os.IRemoteCallback; 144import android.os.IUserManager; 145import android.os.Looper; 146import android.os.Message; 147import android.os.Parcel; 148import android.os.ParcelFileDescriptor; 149import android.os.Process; 150import android.os.RemoteCallbackList; 151import android.os.RemoteException; 152import android.os.SELinux; 153import android.os.ServiceManager; 154import android.os.StrictMode; 155import android.os.SystemClock; 156import android.os.SystemProperties; 157import android.os.UpdateLock; 158import android.os.UserHandle; 159import android.provider.Settings; 160import android.text.format.DateUtils; 161import android.text.format.Time; 162import android.util.AtomicFile; 163import android.util.EventLog; 164import android.util.Log; 165import android.util.Pair; 166import android.util.PrintWriterPrinter; 167import android.util.Slog; 168import android.util.SparseArray; 169import android.util.TimeUtils; 170import android.util.Xml; 171import android.view.Gravity; 172import android.view.LayoutInflater; 173import android.view.View; 174import android.view.WindowManager; 175 176import java.io.BufferedInputStream; 177import java.io.BufferedOutputStream; 178import java.io.DataInputStream; 179import java.io.DataOutputStream; 180import java.io.File; 181import java.io.FileDescriptor; 182import java.io.FileInputStream; 183import java.io.FileNotFoundException; 184import java.io.FileOutputStream; 185import java.io.IOException; 186import java.io.InputStreamReader; 187import java.io.PrintWriter; 188import java.io.StringWriter; 189import java.lang.ref.WeakReference; 190import java.util.ArrayList; 191import java.util.Arrays; 192import java.util.Collections; 193import java.util.Comparator; 194import java.util.HashMap; 195import java.util.HashSet; 196import java.util.Iterator; 197import java.util.List; 198import java.util.Locale; 199import java.util.Map; 200import java.util.Set; 201import java.util.concurrent.atomic.AtomicBoolean; 202import java.util.concurrent.atomic.AtomicLong; 203 204public final class ActivityManagerService extends ActivityManagerNative 205 implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback { 206 private static final String USER_DATA_DIR = "/data/user/"; 207 static final String TAG = "ActivityManager"; 208 static final String TAG_MU = "ActivityManagerServiceMU"; 209 static final boolean DEBUG = false; 210 static final boolean localLOGV = DEBUG; 211 static final boolean DEBUG_BACKUP = localLOGV || false; 212 static final boolean DEBUG_BROADCAST = localLOGV || false; 213 static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false; 214 static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false; 215 static final boolean DEBUG_CLEANUP = localLOGV || false; 216 static final boolean DEBUG_CONFIGURATION = localLOGV || false; 217 static final boolean DEBUG_FOCUS = false; 218 static final boolean DEBUG_IMMERSIVE = localLOGV || false; 219 static final boolean DEBUG_MU = localLOGV || false; 220 static final boolean DEBUG_OOM_ADJ = localLOGV || false; 221 static final boolean DEBUG_LRU = localLOGV || false; 222 static final boolean DEBUG_PAUSE = localLOGV || false; 223 static final boolean DEBUG_POWER = localLOGV || false; 224 static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false; 225 static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false; 226 static final boolean DEBUG_PROCESSES = localLOGV || false; 227 static final boolean DEBUG_PROVIDER = localLOGV || false; 228 static final boolean DEBUG_RESULTS = localLOGV || false; 229 static final boolean DEBUG_SERVICE = localLOGV || false; 230 static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false; 231 static final boolean DEBUG_STACK = localLOGV || false; 232 static final boolean DEBUG_SWITCH = localLOGV || false; 233 static final boolean DEBUG_TASKS = localLOGV || false; 234 static final boolean DEBUG_THUMBNAILS = localLOGV || false; 235 static final boolean DEBUG_TRANSITION = localLOGV || false; 236 static final boolean DEBUG_URI_PERMISSION = localLOGV || false; 237 static final boolean DEBUG_USER_LEAVING = localLOGV || false; 238 static final boolean DEBUG_VISBILITY = localLOGV || false; 239 static final boolean DEBUG_PSS = localLOGV || false; 240 static final boolean DEBUG_LOCKSCREEN = localLOGV || false; 241 static final boolean VALIDATE_TOKENS = false; 242 static final boolean SHOW_ACTIVITY_START_TIME = true; 243 244 // Control over CPU and battery monitoring. 245 static final long BATTERY_STATS_TIME = 30*60*1000; // write battery stats every 30 minutes. 246 static final boolean MONITOR_CPU_USAGE = true; 247 static final long MONITOR_CPU_MIN_TIME = 5*1000; // don't sample cpu less than every 5 seconds. 248 static final long MONITOR_CPU_MAX_TIME = 0x0fffffff; // wait possibly forever for next cpu sample. 249 static final boolean MONITOR_THREAD_CPU_USAGE = false; 250 251 // The flags that are set for all calls we make to the package manager. 252 static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES; 253 254 private static final String SYSTEM_DEBUGGABLE = "ro.debuggable"; 255 256 static final boolean IS_USER_BUILD = "user".equals(Build.TYPE); 257 258 // Maximum number of recent tasks that we can remember. 259 static final int MAX_RECENT_TASKS = ActivityManager.isLowRamDeviceStatic() ? 10 : 20; 260 261 // Amount of time after a call to stopAppSwitches() during which we will 262 // prevent further untrusted switches from happening. 263 static final long APP_SWITCH_DELAY_TIME = 5*1000; 264 265 // How long we wait for a launched process to attach to the activity manager 266 // before we decide it's never going to come up for real. 267 static final int PROC_START_TIMEOUT = 10*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, when the process was 271 // started with a wrapper for instrumentation (such as Valgrind) because it 272 // could take much longer than usual. 273 static final int PROC_START_TIMEOUT_WITH_WRAPPER = 300*1000; 274 275 // How long to wait after going idle before forcing apps to GC. 276 static final int GC_TIMEOUT = 5*1000; 277 278 // The minimum amount of time between successive GC requests for a process. 279 static final int GC_MIN_INTERVAL = 60*1000; 280 281 // The minimum amount of time between successive PSS requests for a process. 282 static final int FULL_PSS_MIN_INTERVAL = 10*60*1000; 283 284 // The minimum amount of time between successive PSS requests for a process 285 // when the request is due to the memory state being lowered. 286 static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000; 287 288 // The rate at which we check for apps using excessive power -- 15 mins. 289 static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000; 290 291 // The minimum sample duration we will allow before deciding we have 292 // enough data on wake locks to start killing things. 293 static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000; 294 295 // The minimum sample duration we will allow before deciding we have 296 // enough data on CPU usage to start killing things. 297 static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000; 298 299 // How long we allow a receiver to run before giving up on it. 300 static final int BROADCAST_FG_TIMEOUT = 10*1000; 301 static final int BROADCAST_BG_TIMEOUT = 60*1000; 302 303 // How long we wait until we timeout on key dispatching. 304 static final int KEY_DISPATCHING_TIMEOUT = 5*1000; 305 306 // How long we wait until we timeout on key dispatching during instrumentation. 307 static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000; 308 309 // Amount of time we wait for observers to handle a user switch before 310 // giving up on them and unfreezing the screen. 311 static final int USER_SWITCH_TIMEOUT = 2*1000; 312 313 // Maximum number of users we allow to be running at a time. 314 static final int MAX_RUNNING_USERS = 3; 315 316 // How long to wait in getAssistContextExtras for the activity and foreground services 317 // to respond with the result. 318 static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500; 319 320 // Maximum number of persisted Uri grants a package is allowed 321 static final int MAX_PERSISTED_URI_GRANTS = 128; 322 323 static final int MY_PID = Process.myPid(); 324 325 static final String[] EMPTY_STRING_ARRAY = new String[0]; 326 327 // How many bytes to write into the dropbox log before truncating 328 static final int DROPBOX_MAX_SIZE = 256 * 1024; 329 330 /** Run all ActivityStacks through this */ 331 ActivityStackSupervisor mStackSupervisor; 332 333 public IntentFirewall mIntentFirewall; 334 335 // Whether we should show our dialogs (ANR, crash, etc) or just perform their 336 // default actuion automatically. Important for devices without direct input 337 // devices. 338 private boolean mShowDialogs = true; 339 340 /** 341 * Description of a request to start a new activity, which has been held 342 * due to app switches being disabled. 343 */ 344 static class PendingActivityLaunch { 345 final ActivityRecord r; 346 final ActivityRecord sourceRecord; 347 final int startFlags; 348 final ActivityStack stack; 349 350 PendingActivityLaunch(ActivityRecord _r, ActivityRecord _sourceRecord, 351 int _startFlags, ActivityStack _stack) { 352 r = _r; 353 sourceRecord = _sourceRecord; 354 startFlags = _startFlags; 355 stack = _stack; 356 } 357 } 358 359 final ArrayList<PendingActivityLaunch> mPendingActivityLaunches 360 = new ArrayList<PendingActivityLaunch>(); 361 362 BroadcastQueue mFgBroadcastQueue; 363 BroadcastQueue mBgBroadcastQueue; 364 // Convenient for easy iteration over the queues. Foreground is first 365 // so that dispatch of foreground broadcasts gets precedence. 366 final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2]; 367 368 BroadcastQueue broadcastQueueForIntent(Intent intent) { 369 final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0; 370 if (DEBUG_BACKGROUND_BROADCAST) { 371 Slog.i(TAG, "Broadcast intent " + intent + " on " 372 + (isFg ? "foreground" : "background") 373 + " queue"); 374 } 375 return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue; 376 } 377 378 BroadcastRecord broadcastRecordForReceiverLocked(IBinder receiver) { 379 for (BroadcastQueue queue : mBroadcastQueues) { 380 BroadcastRecord r = queue.getMatchingOrderedReceiver(receiver); 381 if (r != null) { 382 return r; 383 } 384 } 385 return null; 386 } 387 388 /** 389 * Activity we have told the window manager to have key focus. 390 */ 391 ActivityRecord mFocusedActivity = null; 392 393 /** 394 * List of intents that were used to start the most recent tasks. 395 */ 396 private final ArrayList<TaskRecord> mRecentTasks = new ArrayList<TaskRecord>(); 397 398 public class PendingAssistExtras extends Binder implements Runnable { 399 public final ActivityRecord activity; 400 public boolean haveResult = false; 401 public Bundle result = null; 402 public PendingAssistExtras(ActivityRecord _activity) { 403 activity = _activity; 404 } 405 @Override 406 public void run() { 407 Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity); 408 synchronized (this) { 409 haveResult = true; 410 notifyAll(); 411 } 412 } 413 } 414 415 final ArrayList<PendingAssistExtras> mPendingAssistExtras 416 = new ArrayList<PendingAssistExtras>(); 417 418 /** 419 * Process management. 420 */ 421 final ProcessList mProcessList = new ProcessList(); 422 423 /** 424 * All of the applications we currently have running organized by name. 425 * The keys are strings of the application package name (as 426 * returned by the package manager), and the keys are ApplicationRecord 427 * objects. 428 */ 429 final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>(); 430 431 /** 432 * Tracking long-term execution of processes to look for abuse and other 433 * bad app behavior. 434 */ 435 final ProcessStatsService mProcessStats; 436 437 /** 438 * The currently running isolated processes. 439 */ 440 final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>(); 441 442 /** 443 * Counter for assigning isolated process uids, to avoid frequently reusing the 444 * same ones. 445 */ 446 int mNextIsolatedProcessUid = 0; 447 448 /** 449 * The currently running heavy-weight process, if any. 450 */ 451 ProcessRecord mHeavyWeightProcess = null; 452 453 /** 454 * The last time that various processes have crashed. 455 */ 456 final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>(); 457 458 /** 459 * Information about a process that is currently marked as bad. 460 */ 461 static final class BadProcessInfo { 462 BadProcessInfo(long time, String shortMsg, String longMsg, String stack) { 463 this.time = time; 464 this.shortMsg = shortMsg; 465 this.longMsg = longMsg; 466 this.stack = stack; 467 } 468 469 final long time; 470 final String shortMsg; 471 final String longMsg; 472 final String stack; 473 } 474 475 /** 476 * Set of applications that we consider to be bad, and will reject 477 * incoming broadcasts from (which the user has no control over). 478 * Processes are added to this set when they have crashed twice within 479 * a minimum amount of time; they are removed from it when they are 480 * later restarted (hopefully due to some user action). The value is the 481 * time it was added to the list. 482 */ 483 final ProcessMap<BadProcessInfo> mBadProcesses = new ProcessMap<BadProcessInfo>(); 484 485 /** 486 * All of the processes we currently have running organized by pid. 487 * The keys are the pid running the application. 488 * 489 * <p>NOTE: This object is protected by its own lock, NOT the global 490 * activity manager lock! 491 */ 492 final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>(); 493 494 /** 495 * All of the processes that have been forced to be foreground. The key 496 * is the pid of the caller who requested it (we hold a death 497 * link on it). 498 */ 499 abstract class ForegroundToken implements IBinder.DeathRecipient { 500 int pid; 501 IBinder token; 502 } 503 final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>(); 504 505 /** 506 * List of records for processes that someone had tried to start before the 507 * system was ready. We don't start them at that point, but ensure they 508 * are started by the time booting is complete. 509 */ 510 final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>(); 511 512 /** 513 * List of persistent applications that are in the process 514 * of being started. 515 */ 516 final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>(); 517 518 /** 519 * Processes that are being forcibly torn down. 520 */ 521 final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>(); 522 523 /** 524 * List of running applications, sorted by recent usage. 525 * The first entry in the list is the least recently used. 526 */ 527 final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>(); 528 529 /** 530 * Where in mLruProcesses that the processes hosting activities start. 531 */ 532 int mLruProcessActivityStart = 0; 533 534 /** 535 * Where in mLruProcesses that the processes hosting services start. 536 * This is after (lower index) than mLruProcessesActivityStart. 537 */ 538 int mLruProcessServiceStart = 0; 539 540 /** 541 * List of processes that should gc as soon as things are idle. 542 */ 543 final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>(); 544 545 /** 546 * Processes we want to collect PSS data from. 547 */ 548 final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>(); 549 550 /** 551 * Last time we requested PSS data of all processes. 552 */ 553 long mLastFullPssTime = SystemClock.uptimeMillis(); 554 555 /** 556 * This is the process holding what we currently consider to be 557 * the "home" activity. 558 */ 559 ProcessRecord mHomeProcess; 560 561 /** 562 * This is the process holding the activity the user last visited that 563 * is in a different process from the one they are currently in. 564 */ 565 ProcessRecord mPreviousProcess; 566 567 /** 568 * The time at which the previous process was last visible. 569 */ 570 long mPreviousProcessVisibleTime; 571 572 /** 573 * Which uses have been started, so are allowed to run code. 574 */ 575 final SparseArray<UserStartedState> mStartedUsers = new SparseArray<UserStartedState>(); 576 577 /** 578 * LRU list of history of current users. Most recently current is at the end. 579 */ 580 final ArrayList<Integer> mUserLru = new ArrayList<Integer>(); 581 582 /** 583 * Constant array of the users that are currently started. 584 */ 585 int[] mStartedUserArray = new int[] { 0 }; 586 587 /** 588 * Registered observers of the user switching mechanics. 589 */ 590 final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers 591 = new RemoteCallbackList<IUserSwitchObserver>(); 592 593 /** 594 * Currently active user switch. 595 */ 596 Object mCurUserSwitchCallback; 597 598 /** 599 * Packages that the user has asked to have run in screen size 600 * compatibility mode instead of filling the screen. 601 */ 602 final CompatModePackages mCompatModePackages; 603 604 /** 605 * Set of IntentSenderRecord objects that are currently active. 606 */ 607 final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords 608 = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>(); 609 610 /** 611 * Fingerprints (hashCode()) of stack traces that we've 612 * already logged DropBox entries for. Guarded by itself. If 613 * something (rogue user app) forces this over 614 * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared. 615 */ 616 private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>(); 617 private static final int MAX_DUP_SUPPRESSED_STACKS = 5000; 618 619 /** 620 * Strict Mode background batched logging state. 621 * 622 * The string buffer is guarded by itself, and its lock is also 623 * used to determine if another batched write is already 624 * in-flight. 625 */ 626 private final StringBuilder mStrictModeBuffer = new StringBuilder(); 627 628 /** 629 * Keeps track of all IIntentReceivers that have been registered for 630 * broadcasts. Hash keys are the receiver IBinder, hash value is 631 * a ReceiverList. 632 */ 633 final HashMap<IBinder, ReceiverList> mRegisteredReceivers = 634 new HashMap<IBinder, ReceiverList>(); 635 636 /** 637 * Resolver for broadcast intents to registered receivers. 638 * Holds BroadcastFilter (subclass of IntentFilter). 639 */ 640 final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver 641 = new IntentResolver<BroadcastFilter, BroadcastFilter>() { 642 @Override 643 protected boolean allowFilterResult( 644 BroadcastFilter filter, List<BroadcastFilter> dest) { 645 IBinder target = filter.receiverList.receiver.asBinder(); 646 for (int i=dest.size()-1; i>=0; i--) { 647 if (dest.get(i).receiverList.receiver.asBinder() == target) { 648 return false; 649 } 650 } 651 return true; 652 } 653 654 @Override 655 protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) { 656 if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL 657 || userId == filter.owningUserId) { 658 return super.newResult(filter, match, userId); 659 } 660 return null; 661 } 662 663 @Override 664 protected BroadcastFilter[] newArray(int size) { 665 return new BroadcastFilter[size]; 666 } 667 668 @Override 669 protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) { 670 return packageName.equals(filter.packageName); 671 } 672 }; 673 674 /** 675 * State of all active sticky broadcasts per user. Keys are the action of the 676 * sticky Intent, values are an ArrayList of all broadcasted intents with 677 * that action (which should usually be one). The SparseArray is keyed 678 * by the user ID the sticky is for, and can include UserHandle.USER_ALL 679 * for stickies that are sent to all users. 680 */ 681 final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts = 682 new SparseArray<ArrayMap<String, ArrayList<Intent>>>(); 683 684 final ActiveServices mServices; 685 686 /** 687 * Backup/restore process management 688 */ 689 String mBackupAppName = null; 690 BackupRecord mBackupTarget = null; 691 692 /** 693 * List of PendingThumbnailsRecord objects of clients who are still 694 * waiting to receive all of the thumbnails for a task. 695 */ 696 final ArrayList<PendingThumbnailsRecord> mPendingThumbnails = 697 new ArrayList<PendingThumbnailsRecord>(); 698 699 final ProviderMap mProviderMap; 700 701 /** 702 * List of content providers who have clients waiting for them. The 703 * application is currently being launched and the provider will be 704 * removed from this list once it is published. 705 */ 706 final ArrayList<ContentProviderRecord> mLaunchingProviders 707 = new ArrayList<ContentProviderRecord>(); 708 709 /** 710 * File storing persisted {@link #mGrantedUriPermissions}. 711 */ 712 private final AtomicFile mGrantFile; 713 714 /** XML constants used in {@link #mGrantFile} */ 715 private static final String TAG_URI_GRANTS = "uri-grants"; 716 private static final String TAG_URI_GRANT = "uri-grant"; 717 private static final String ATTR_USER_HANDLE = "userHandle"; 718 private static final String ATTR_SOURCE_PKG = "sourcePkg"; 719 private static final String ATTR_TARGET_PKG = "targetPkg"; 720 private static final String ATTR_URI = "uri"; 721 private static final String ATTR_MODE_FLAGS = "modeFlags"; 722 private static final String ATTR_CREATED_TIME = "createdTime"; 723 724 /** 725 * Global set of specific {@link Uri} permissions that have been granted. 726 * This optimized lookup structure maps from {@link UriPermission#targetUid} 727 * to {@link UriPermission#uri} to {@link UriPermission}. 728 */ 729 @GuardedBy("this") 730 private final SparseArray<ArrayMap<Uri, UriPermission>> 731 mGrantedUriPermissions = new SparseArray<ArrayMap<Uri, UriPermission>>(); 732 733 CoreSettingsObserver mCoreSettingsObserver; 734 735 /** 736 * Thread-local storage used to carry caller permissions over through 737 * indirect content-provider access. 738 */ 739 private class Identity { 740 public int pid; 741 public int uid; 742 743 Identity(int _pid, int _uid) { 744 pid = _pid; 745 uid = _uid; 746 } 747 } 748 749 private static ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>(); 750 751 /** 752 * All information we have collected about the runtime performance of 753 * any user id that can impact battery performance. 754 */ 755 final BatteryStatsService mBatteryStatsService; 756 757 /** 758 * Information about component usage 759 */ 760 final UsageStatsService mUsageStatsService; 761 762 /** 763 * Information about and control over application operations 764 */ 765 final AppOpsService mAppOpsService; 766 767 /** 768 * Current configuration information. HistoryRecord objects are given 769 * a reference to this object to indicate which configuration they are 770 * currently running in, so this object must be kept immutable. 771 */ 772 Configuration mConfiguration = new Configuration(); 773 774 /** 775 * Current sequencing integer of the configuration, for skipping old 776 * configurations. 777 */ 778 int mConfigurationSeq = 0; 779 780 /** 781 * Hardware-reported OpenGLES version. 782 */ 783 final int GL_ES_VERSION; 784 785 /** 786 * List of initialization arguments to pass to all processes when binding applications to them. 787 * For example, references to the commonly used services. 788 */ 789 HashMap<String, IBinder> mAppBindArgs; 790 791 /** 792 * Temporary to avoid allocations. Protected by main lock. 793 */ 794 final StringBuilder mStringBuilder = new StringBuilder(256); 795 796 /** 797 * Used to control how we initialize the service. 798 */ 799 boolean mStartRunning = false; 800 ComponentName mTopComponent; 801 String mTopAction; 802 String mTopData; 803 boolean mProcessesReady = false; 804 boolean mSystemReady = false; 805 boolean mBooting = false; 806 boolean mWaitingUpdate = false; 807 boolean mDidUpdate = false; 808 boolean mOnBattery = false; 809 boolean mLaunchWarningShown = false; 810 811 Context mContext; 812 813 int mFactoryTest; 814 815 boolean mCheckedForSetup; 816 817 /** 818 * The time at which we will allow normal application switches again, 819 * after a call to {@link #stopAppSwitches()}. 820 */ 821 long mAppSwitchesAllowedTime; 822 823 /** 824 * This is set to true after the first switch after mAppSwitchesAllowedTime 825 * is set; any switches after that will clear the time. 826 */ 827 boolean mDidAppSwitch; 828 829 /** 830 * Last time (in realtime) at which we checked for power usage. 831 */ 832 long mLastPowerCheckRealtime; 833 834 /** 835 * Last time (in uptime) at which we checked for power usage. 836 */ 837 long mLastPowerCheckUptime; 838 839 /** 840 * Set while we are wanting to sleep, to prevent any 841 * activities from being started/resumed. 842 */ 843 boolean mSleeping = false; 844 845 /** 846 * State of external calls telling us if the device is asleep. 847 */ 848 boolean mWentToSleep = false; 849 850 /** 851 * State of external call telling us if the lock screen is shown. 852 */ 853 boolean mLockScreenShown = false; 854 855 /** 856 * Set if we are shutting down the system, similar to sleeping. 857 */ 858 boolean mShuttingDown = false; 859 860 /** 861 * Current sequence id for oom_adj computation traversal. 862 */ 863 int mAdjSeq = 0; 864 865 /** 866 * Current sequence id for process LRU updating. 867 */ 868 int mLruSeq = 0; 869 870 /** 871 * Keep track of the non-cached/empty process we last found, to help 872 * determine how to distribute cached/empty processes next time. 873 */ 874 int mNumNonCachedProcs = 0; 875 876 /** 877 * Keep track of the number of cached hidden procs, to balance oom adj 878 * distribution between those and empty procs. 879 */ 880 int mNumCachedHiddenProcs = 0; 881 882 /** 883 * Keep track of the number of service processes we last found, to 884 * determine on the next iteration which should be B services. 885 */ 886 int mNumServiceProcs = 0; 887 int mNewNumAServiceProcs = 0; 888 int mNewNumServiceProcs = 0; 889 890 /** 891 * Allow the current computed overall memory level of the system to go down? 892 * This is set to false when we are killing processes for reasons other than 893 * memory management, so that the now smaller process list will not be taken as 894 * an indication that memory is tighter. 895 */ 896 boolean mAllowLowerMemLevel = false; 897 898 /** 899 * The last computed memory level, for holding when we are in a state that 900 * processes are going away for other reasons. 901 */ 902 int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL; 903 904 /** 905 * The last total number of process we have, to determine if changes actually look 906 * like a shrinking number of process due to lower RAM. 907 */ 908 int mLastNumProcesses; 909 910 /** 911 * The uptime of the last time we performed idle maintenance. 912 */ 913 long mLastIdleTime = SystemClock.uptimeMillis(); 914 915 /** 916 * Total time spent with RAM that has been added in the past since the last idle time. 917 */ 918 long mLowRamTimeSinceLastIdle = 0; 919 920 /** 921 * If RAM is currently low, when that horrible situatin started. 922 */ 923 long mLowRamStartTime = 0; 924 925 /** 926 * This is set if we had to do a delayed dexopt of an app before launching 927 * it, to increasing the ANR timeouts in that case. 928 */ 929 boolean mDidDexOpt; 930 931 String mDebugApp = null; 932 boolean mWaitForDebugger = false; 933 boolean mDebugTransient = false; 934 String mOrigDebugApp = null; 935 boolean mOrigWaitForDebugger = false; 936 boolean mAlwaysFinishActivities = false; 937 IActivityController mController = null; 938 String mProfileApp = null; 939 ProcessRecord mProfileProc = null; 940 String mProfileFile; 941 ParcelFileDescriptor mProfileFd; 942 int mProfileType = 0; 943 boolean mAutoStopProfiler = false; 944 String mOpenGlTraceApp = null; 945 946 static class ProcessChangeItem { 947 static final int CHANGE_ACTIVITIES = 1<<0; 948 static final int CHANGE_IMPORTANCE= 1<<1; 949 int changes; 950 int uid; 951 int pid; 952 int importance; 953 boolean foregroundActivities; 954 } 955 956 final RemoteCallbackList<IProcessObserver> mProcessObservers 957 = new RemoteCallbackList<IProcessObserver>(); 958 ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5]; 959 960 final ArrayList<ProcessChangeItem> mPendingProcessChanges 961 = new ArrayList<ProcessChangeItem>(); 962 final ArrayList<ProcessChangeItem> mAvailProcessChanges 963 = new ArrayList<ProcessChangeItem>(); 964 965 /** 966 * Runtime CPU use collection thread. This object's lock is used to 967 * protect all related state. 968 */ 969 final Thread mProcessCpuThread; 970 971 /** 972 * Used to collect process stats when showing not responding dialog. 973 * Protected by mProcessCpuThread. 974 */ 975 final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker( 976 MONITOR_THREAD_CPU_USAGE); 977 final AtomicLong mLastCpuTime = new AtomicLong(0); 978 final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true); 979 980 long mLastWriteTime = 0; 981 982 /** 983 * Used to retain an update lock when the foreground activity is in 984 * immersive mode. 985 */ 986 final UpdateLock mUpdateLock = new UpdateLock("immersive"); 987 988 /** 989 * Set to true after the system has finished booting. 990 */ 991 boolean mBooted = false; 992 993 int mProcessLimit = ProcessList.MAX_CACHED_APPS; 994 int mProcessLimitOverride = -1; 995 996 WindowManagerService mWindowManager; 997 998 static ActivityManagerService mSelf; 999 static ActivityThread mSystemThread; 1000 1001 int mCurrentUserId = 0; 1002 private UserManagerService mUserManager; 1003 1004 private final class AppDeathRecipient implements IBinder.DeathRecipient { 1005 final ProcessRecord mApp; 1006 final int mPid; 1007 final IApplicationThread mAppThread; 1008 1009 AppDeathRecipient(ProcessRecord app, int pid, 1010 IApplicationThread thread) { 1011 if (localLOGV) Slog.v( 1012 TAG, "New death recipient " + this 1013 + " for thread " + thread.asBinder()); 1014 mApp = app; 1015 mPid = pid; 1016 mAppThread = thread; 1017 } 1018 1019 @Override 1020 public void binderDied() { 1021 if (localLOGV) Slog.v( 1022 TAG, "Death received in " + this 1023 + " for thread " + mAppThread.asBinder()); 1024 synchronized(ActivityManagerService.this) { 1025 appDiedLocked(mApp, mPid, mAppThread); 1026 } 1027 } 1028 } 1029 1030 static final int SHOW_ERROR_MSG = 1; 1031 static final int SHOW_NOT_RESPONDING_MSG = 2; 1032 static final int SHOW_FACTORY_ERROR_MSG = 3; 1033 static final int UPDATE_CONFIGURATION_MSG = 4; 1034 static final int GC_BACKGROUND_PROCESSES_MSG = 5; 1035 static final int WAIT_FOR_DEBUGGER_MSG = 6; 1036 static final int SERVICE_TIMEOUT_MSG = 12; 1037 static final int UPDATE_TIME_ZONE = 13; 1038 static final int SHOW_UID_ERROR_MSG = 14; 1039 static final int IM_FEELING_LUCKY_MSG = 15; 1040 static final int PROC_START_TIMEOUT_MSG = 20; 1041 static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21; 1042 static final int KILL_APPLICATION_MSG = 22; 1043 static final int FINALIZE_PENDING_INTENT_MSG = 23; 1044 static final int POST_HEAVY_NOTIFICATION_MSG = 24; 1045 static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25; 1046 static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26; 1047 static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27; 1048 static final int CLEAR_DNS_CACHE_MSG = 28; 1049 static final int UPDATE_HTTP_PROXY_MSG = 29; 1050 static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30; 1051 static final int DISPATCH_PROCESSES_CHANGED = 31; 1052 static final int DISPATCH_PROCESS_DIED = 32; 1053 static final int REPORT_MEM_USAGE_MSG = 33; 1054 static final int REPORT_USER_SWITCH_MSG = 34; 1055 static final int CONTINUE_USER_SWITCH_MSG = 35; 1056 static final int USER_SWITCH_TIMEOUT_MSG = 36; 1057 static final int IMMERSIVE_MODE_LOCK_MSG = 37; 1058 static final int PERSIST_URI_GRANTS_MSG = 38; 1059 static final int REQUEST_ALL_PSS_MSG = 39; 1060 1061 static final int FIRST_ACTIVITY_STACK_MSG = 100; 1062 static final int FIRST_BROADCAST_QUEUE_MSG = 200; 1063 static final int FIRST_COMPAT_MODE_MSG = 300; 1064 static final int FIRST_SUPERVISOR_STACK_MSG = 100; 1065 1066 AlertDialog mUidAlert; 1067 CompatModeDialog mCompatModeDialog; 1068 long mLastMemUsageReportTime = 0; 1069 1070 /** 1071 * Flag whether the current user is a "monkey", i.e. whether 1072 * the UI is driven by a UI automation tool. 1073 */ 1074 private boolean mUserIsMonkey; 1075 1076 final Handler mHandler = new Handler() { 1077 //public Handler() { 1078 // if (localLOGV) Slog.v(TAG, "Handler started!"); 1079 //} 1080 1081 @Override 1082 public void handleMessage(Message msg) { 1083 switch (msg.what) { 1084 case SHOW_ERROR_MSG: { 1085 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1086 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), 1087 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; 1088 synchronized (ActivityManagerService.this) { 1089 ProcessRecord proc = (ProcessRecord)data.get("app"); 1090 AppErrorResult res = (AppErrorResult) data.get("result"); 1091 if (proc != null && proc.crashDialog != null) { 1092 Slog.e(TAG, "App already has crash dialog: " + proc); 1093 if (res != null) { 1094 res.set(0); 1095 } 1096 return; 1097 } 1098 if (!showBackground && UserHandle.getAppId(proc.uid) 1099 >= Process.FIRST_APPLICATION_UID && proc.userId != mCurrentUserId 1100 && proc.pid != MY_PID) { 1101 Slog.w(TAG, "Skipping crash dialog of " + proc + ": background"); 1102 if (res != null) { 1103 res.set(0); 1104 } 1105 return; 1106 } 1107 if (mShowDialogs && !mSleeping && !mShuttingDown) { 1108 Dialog d = new AppErrorDialog(mContext, 1109 ActivityManagerService.this, res, proc); 1110 d.show(); 1111 proc.crashDialog = d; 1112 } else { 1113 // The device is asleep, so just pretend that the user 1114 // saw a crash dialog and hit "force quit". 1115 if (res != null) { 1116 res.set(0); 1117 } 1118 } 1119 } 1120 1121 ensureBootCompleted(); 1122 } break; 1123 case SHOW_NOT_RESPONDING_MSG: { 1124 synchronized (ActivityManagerService.this) { 1125 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1126 ProcessRecord proc = (ProcessRecord)data.get("app"); 1127 if (proc != null && proc.anrDialog != null) { 1128 Slog.e(TAG, "App already has anr dialog: " + proc); 1129 return; 1130 } 1131 1132 Intent intent = new Intent("android.intent.action.ANR"); 1133 if (!mProcessesReady) { 1134 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 1135 | Intent.FLAG_RECEIVER_FOREGROUND); 1136 } 1137 broadcastIntentLocked(null, null, intent, 1138 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 1139 false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */); 1140 1141 if (mShowDialogs) { 1142 Dialog d = new AppNotRespondingDialog(ActivityManagerService.this, 1143 mContext, proc, (ActivityRecord)data.get("activity"), 1144 msg.arg1 != 0); 1145 d.show(); 1146 proc.anrDialog = d; 1147 } else { 1148 // Just kill the app if there is no dialog to be shown. 1149 killAppAtUsersRequest(proc, null); 1150 } 1151 } 1152 1153 ensureBootCompleted(); 1154 } break; 1155 case SHOW_STRICT_MODE_VIOLATION_MSG: { 1156 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1157 synchronized (ActivityManagerService.this) { 1158 ProcessRecord proc = (ProcessRecord) data.get("app"); 1159 if (proc == null) { 1160 Slog.e(TAG, "App not found when showing strict mode dialog."); 1161 break; 1162 } 1163 if (proc.crashDialog != null) { 1164 Slog.e(TAG, "App already has strict mode dialog: " + proc); 1165 return; 1166 } 1167 AppErrorResult res = (AppErrorResult) data.get("result"); 1168 if (mShowDialogs && !mSleeping && !mShuttingDown) { 1169 Dialog d = new StrictModeViolationDialog(mContext, 1170 ActivityManagerService.this, res, proc); 1171 d.show(); 1172 proc.crashDialog = d; 1173 } else { 1174 // The device is asleep, so just pretend that the user 1175 // saw a crash dialog and hit "force quit". 1176 res.set(0); 1177 } 1178 } 1179 ensureBootCompleted(); 1180 } break; 1181 case SHOW_FACTORY_ERROR_MSG: { 1182 Dialog d = new FactoryErrorDialog( 1183 mContext, msg.getData().getCharSequence("msg")); 1184 d.show(); 1185 ensureBootCompleted(); 1186 } break; 1187 case UPDATE_CONFIGURATION_MSG: { 1188 final ContentResolver resolver = mContext.getContentResolver(); 1189 Settings.System.putConfiguration(resolver, (Configuration)msg.obj); 1190 } break; 1191 case GC_BACKGROUND_PROCESSES_MSG: { 1192 synchronized (ActivityManagerService.this) { 1193 performAppGcsIfAppropriateLocked(); 1194 } 1195 } break; 1196 case WAIT_FOR_DEBUGGER_MSG: { 1197 synchronized (ActivityManagerService.this) { 1198 ProcessRecord app = (ProcessRecord)msg.obj; 1199 if (msg.arg1 != 0) { 1200 if (!app.waitedForDebugger) { 1201 Dialog d = new AppWaitingForDebuggerDialog( 1202 ActivityManagerService.this, 1203 mContext, app); 1204 app.waitDialog = d; 1205 app.waitedForDebugger = true; 1206 d.show(); 1207 } 1208 } else { 1209 if (app.waitDialog != null) { 1210 app.waitDialog.dismiss(); 1211 app.waitDialog = null; 1212 } 1213 } 1214 } 1215 } break; 1216 case SERVICE_TIMEOUT_MSG: { 1217 if (mDidDexOpt) { 1218 mDidDexOpt = false; 1219 Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG); 1220 nmsg.obj = msg.obj; 1221 mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT); 1222 return; 1223 } 1224 mServices.serviceTimeout((ProcessRecord)msg.obj); 1225 } break; 1226 case UPDATE_TIME_ZONE: { 1227 synchronized (ActivityManagerService.this) { 1228 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1229 ProcessRecord r = mLruProcesses.get(i); 1230 if (r.thread != null) { 1231 try { 1232 r.thread.updateTimeZone(); 1233 } catch (RemoteException ex) { 1234 Slog.w(TAG, "Failed to update time zone for: " + r.info.processName); 1235 } 1236 } 1237 } 1238 } 1239 } break; 1240 case CLEAR_DNS_CACHE_MSG: { 1241 synchronized (ActivityManagerService.this) { 1242 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1243 ProcessRecord r = mLruProcesses.get(i); 1244 if (r.thread != null) { 1245 try { 1246 r.thread.clearDnsCache(); 1247 } catch (RemoteException ex) { 1248 Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName); 1249 } 1250 } 1251 } 1252 } 1253 } break; 1254 case UPDATE_HTTP_PROXY_MSG: { 1255 ProxyProperties proxy = (ProxyProperties)msg.obj; 1256 String host = ""; 1257 String port = ""; 1258 String exclList = ""; 1259 String pacFileUrl = null; 1260 if (proxy != null) { 1261 host = proxy.getHost(); 1262 port = Integer.toString(proxy.getPort()); 1263 exclList = proxy.getExclusionList(); 1264 pacFileUrl = proxy.getPacFileUrl(); 1265 } 1266 synchronized (ActivityManagerService.this) { 1267 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1268 ProcessRecord r = mLruProcesses.get(i); 1269 if (r.thread != null) { 1270 try { 1271 r.thread.setHttpProxy(host, port, exclList, pacFileUrl); 1272 } catch (RemoteException ex) { 1273 Slog.w(TAG, "Failed to update http proxy for: " + 1274 r.info.processName); 1275 } 1276 } 1277 } 1278 } 1279 } break; 1280 case SHOW_UID_ERROR_MSG: { 1281 String title = "System UIDs Inconsistent"; 1282 String text = "UIDs on the system are inconsistent, you need to wipe your" 1283 + " data partition or your device will be unstable."; 1284 Log.e(TAG, title + ": " + text); 1285 if (mShowDialogs) { 1286 // XXX This is a temporary dialog, no need to localize. 1287 AlertDialog d = new BaseErrorDialog(mContext); 1288 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR); 1289 d.setCancelable(false); 1290 d.setTitle(title); 1291 d.setMessage(text); 1292 d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky", 1293 mHandler.obtainMessage(IM_FEELING_LUCKY_MSG)); 1294 mUidAlert = d; 1295 d.show(); 1296 } 1297 } break; 1298 case IM_FEELING_LUCKY_MSG: { 1299 if (mUidAlert != null) { 1300 mUidAlert.dismiss(); 1301 mUidAlert = null; 1302 } 1303 } break; 1304 case PROC_START_TIMEOUT_MSG: { 1305 if (mDidDexOpt) { 1306 mDidDexOpt = false; 1307 Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 1308 nmsg.obj = msg.obj; 1309 mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT); 1310 return; 1311 } 1312 ProcessRecord app = (ProcessRecord)msg.obj; 1313 synchronized (ActivityManagerService.this) { 1314 processStartTimedOutLocked(app); 1315 } 1316 } break; 1317 case DO_PENDING_ACTIVITY_LAUNCHES_MSG: { 1318 synchronized (ActivityManagerService.this) { 1319 doPendingActivityLaunchesLocked(true); 1320 } 1321 } break; 1322 case KILL_APPLICATION_MSG: { 1323 synchronized (ActivityManagerService.this) { 1324 int appid = msg.arg1; 1325 boolean restart = (msg.arg2 == 1); 1326 Bundle bundle = (Bundle)msg.obj; 1327 String pkg = bundle.getString("pkg"); 1328 String reason = bundle.getString("reason"); 1329 forceStopPackageLocked(pkg, appid, restart, false, true, false, 1330 UserHandle.USER_ALL, reason); 1331 } 1332 } break; 1333 case FINALIZE_PENDING_INTENT_MSG: { 1334 ((PendingIntentRecord)msg.obj).completeFinalize(); 1335 } break; 1336 case POST_HEAVY_NOTIFICATION_MSG: { 1337 INotificationManager inm = NotificationManager.getService(); 1338 if (inm == null) { 1339 return; 1340 } 1341 1342 ActivityRecord root = (ActivityRecord)msg.obj; 1343 ProcessRecord process = root.app; 1344 if (process == null) { 1345 return; 1346 } 1347 1348 try { 1349 Context context = mContext.createPackageContext(process.info.packageName, 0); 1350 String text = mContext.getString(R.string.heavy_weight_notification, 1351 context.getApplicationInfo().loadLabel(context.getPackageManager())); 1352 Notification notification = new Notification(); 1353 notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon; 1354 notification.when = 0; 1355 notification.flags = Notification.FLAG_ONGOING_EVENT; 1356 notification.tickerText = text; 1357 notification.defaults = 0; // please be quiet 1358 notification.sound = null; 1359 notification.vibrate = null; 1360 notification.setLatestEventInfo(context, text, 1361 mContext.getText(R.string.heavy_weight_notification_detail), 1362 PendingIntent.getActivityAsUser(mContext, 0, root.intent, 1363 PendingIntent.FLAG_CANCEL_CURRENT, null, 1364 new UserHandle(root.userId))); 1365 1366 try { 1367 int[] outId = new int[1]; 1368 inm.enqueueNotificationWithTag("android", "android", null, 1369 R.string.heavy_weight_notification, 1370 notification, outId, root.userId); 1371 } catch (RuntimeException e) { 1372 Slog.w(ActivityManagerService.TAG, 1373 "Error showing notification for heavy-weight app", e); 1374 } catch (RemoteException e) { 1375 } 1376 } catch (NameNotFoundException e) { 1377 Slog.w(TAG, "Unable to create context for heavy notification", e); 1378 } 1379 } break; 1380 case CANCEL_HEAVY_NOTIFICATION_MSG: { 1381 INotificationManager inm = NotificationManager.getService(); 1382 if (inm == null) { 1383 return; 1384 } 1385 try { 1386 inm.cancelNotificationWithTag("android", null, 1387 R.string.heavy_weight_notification, msg.arg1); 1388 } catch (RuntimeException e) { 1389 Slog.w(ActivityManagerService.TAG, 1390 "Error canceling notification for service", e); 1391 } catch (RemoteException e) { 1392 } 1393 } break; 1394 case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: { 1395 synchronized (ActivityManagerService.this) { 1396 checkExcessivePowerUsageLocked(true); 1397 removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1398 Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1399 sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 1400 } 1401 } break; 1402 case SHOW_COMPAT_MODE_DIALOG_MSG: { 1403 synchronized (ActivityManagerService.this) { 1404 ActivityRecord ar = (ActivityRecord)msg.obj; 1405 if (mCompatModeDialog != null) { 1406 if (mCompatModeDialog.mAppInfo.packageName.equals( 1407 ar.info.applicationInfo.packageName)) { 1408 return; 1409 } 1410 mCompatModeDialog.dismiss(); 1411 mCompatModeDialog = null; 1412 } 1413 if (ar != null && false) { 1414 if (mCompatModePackages.getPackageAskCompatModeLocked( 1415 ar.packageName)) { 1416 int mode = mCompatModePackages.computeCompatModeLocked( 1417 ar.info.applicationInfo); 1418 if (mode == ActivityManager.COMPAT_MODE_DISABLED 1419 || mode == ActivityManager.COMPAT_MODE_ENABLED) { 1420 mCompatModeDialog = new CompatModeDialog( 1421 ActivityManagerService.this, mContext, 1422 ar.info.applicationInfo); 1423 mCompatModeDialog.show(); 1424 } 1425 } 1426 } 1427 } 1428 break; 1429 } 1430 case DISPATCH_PROCESSES_CHANGED: { 1431 dispatchProcessesChanged(); 1432 break; 1433 } 1434 case DISPATCH_PROCESS_DIED: { 1435 final int pid = msg.arg1; 1436 final int uid = msg.arg2; 1437 dispatchProcessDied(pid, uid); 1438 break; 1439 } 1440 case REPORT_MEM_USAGE_MSG: { 1441 final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj; 1442 Thread thread = new Thread() { 1443 @Override public void run() { 1444 final SparseArray<ProcessMemInfo> infoMap 1445 = new SparseArray<ProcessMemInfo>(memInfos.size()); 1446 for (int i=0, N=memInfos.size(); i<N; i++) { 1447 ProcessMemInfo mi = memInfos.get(i); 1448 infoMap.put(mi.pid, mi); 1449 } 1450 updateCpuStatsNow(); 1451 synchronized (mProcessCpuThread) { 1452 final int N = mProcessCpuTracker.countStats(); 1453 for (int i=0; i<N; i++) { 1454 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 1455 if (st.vsize > 0) { 1456 long pss = Debug.getPss(st.pid, null); 1457 if (pss > 0) { 1458 if (infoMap.indexOfKey(st.pid) < 0) { 1459 ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid, 1460 ProcessList.NATIVE_ADJ, -1, "native", null); 1461 mi.pss = pss; 1462 memInfos.add(mi); 1463 } 1464 } 1465 } 1466 } 1467 } 1468 1469 long totalPss = 0; 1470 for (int i=0, N=memInfos.size(); i<N; i++) { 1471 ProcessMemInfo mi = memInfos.get(i); 1472 if (mi.pss == 0) { 1473 mi.pss = Debug.getPss(mi.pid, null); 1474 } 1475 totalPss += mi.pss; 1476 } 1477 Collections.sort(memInfos, new Comparator<ProcessMemInfo>() { 1478 @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) { 1479 if (lhs.oomAdj != rhs.oomAdj) { 1480 return lhs.oomAdj < rhs.oomAdj ? -1 : 1; 1481 } 1482 if (lhs.pss != rhs.pss) { 1483 return lhs.pss < rhs.pss ? 1 : -1; 1484 } 1485 return 0; 1486 } 1487 }); 1488 1489 StringBuilder tag = new StringBuilder(128); 1490 StringBuilder stack = new StringBuilder(128); 1491 tag.append("Low on memory -- "); 1492 appendMemBucket(tag, totalPss, "total", false); 1493 appendMemBucket(stack, totalPss, "total", true); 1494 1495 StringBuilder logBuilder = new StringBuilder(1024); 1496 logBuilder.append("Low on memory:\n"); 1497 1498 boolean firstLine = true; 1499 int lastOomAdj = Integer.MIN_VALUE; 1500 for (int i=0, N=memInfos.size(); i<N; i++) { 1501 ProcessMemInfo mi = memInfos.get(i); 1502 1503 if (mi.oomAdj != ProcessList.NATIVE_ADJ 1504 && (mi.oomAdj < ProcessList.SERVICE_ADJ 1505 || mi.oomAdj == ProcessList.HOME_APP_ADJ 1506 || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) { 1507 if (lastOomAdj != mi.oomAdj) { 1508 lastOomAdj = mi.oomAdj; 1509 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) { 1510 tag.append(" / "); 1511 } 1512 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) { 1513 if (firstLine) { 1514 stack.append(":"); 1515 firstLine = false; 1516 } 1517 stack.append("\n\t at "); 1518 } else { 1519 stack.append("$"); 1520 } 1521 } else { 1522 tag.append(" "); 1523 stack.append("$"); 1524 } 1525 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) { 1526 appendMemBucket(tag, mi.pss, mi.name, false); 1527 } 1528 appendMemBucket(stack, mi.pss, mi.name, true); 1529 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ 1530 && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) { 1531 stack.append("("); 1532 for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) { 1533 if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) { 1534 stack.append(DUMP_MEM_OOM_LABEL[k]); 1535 stack.append(":"); 1536 stack.append(DUMP_MEM_OOM_ADJ[k]); 1537 } 1538 } 1539 stack.append(")"); 1540 } 1541 } 1542 1543 logBuilder.append(" "); 1544 logBuilder.append(ProcessList.makeOomAdjString(mi.oomAdj)); 1545 logBuilder.append(' '); 1546 logBuilder.append(ProcessList.makeProcStateString(mi.procState)); 1547 logBuilder.append(' '); 1548 ProcessList.appendRamKb(logBuilder, mi.pss); 1549 logBuilder.append(" kB: "); 1550 logBuilder.append(mi.name); 1551 logBuilder.append(" ("); 1552 logBuilder.append(mi.pid); 1553 logBuilder.append(") "); 1554 logBuilder.append(mi.adjType); 1555 logBuilder.append('\n'); 1556 if (mi.adjReason != null) { 1557 logBuilder.append(" "); 1558 logBuilder.append(mi.adjReason); 1559 logBuilder.append('\n'); 1560 } 1561 } 1562 1563 logBuilder.append(" "); 1564 ProcessList.appendRamKb(logBuilder, totalPss); 1565 logBuilder.append(" kB: TOTAL\n"); 1566 1567 long[] infos = new long[Debug.MEMINFO_COUNT]; 1568 Debug.getMemInfo(infos); 1569 logBuilder.append(" MemInfo: "); 1570 logBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, "); 1571 logBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, "); 1572 logBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, "); 1573 logBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, "); 1574 logBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n"); 1575 if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) { 1576 logBuilder.append(" ZRAM: "); 1577 logBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]); 1578 logBuilder.append(" kB RAM, "); 1579 logBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]); 1580 logBuilder.append(" kB swap total, "); 1581 logBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]); 1582 logBuilder.append(" kB swap free\n"); 1583 } 1584 Slog.i(TAG, logBuilder.toString()); 1585 1586 StringBuilder dropBuilder = new StringBuilder(1024); 1587 /* 1588 StringWriter oomSw = new StringWriter(); 1589 PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256); 1590 StringWriter catSw = new StringWriter(); 1591 PrintWriter catPw = new FastPrintWriter(catSw, false, 256); 1592 String[] emptyArgs = new String[] { }; 1593 dumpApplicationMemoryUsage(null, oomPw, " ", emptyArgs, true, catPw); 1594 oomPw.flush(); 1595 String oomString = oomSw.toString(); 1596 */ 1597 dropBuilder.append(stack); 1598 dropBuilder.append('\n'); 1599 dropBuilder.append('\n'); 1600 dropBuilder.append(logBuilder); 1601 dropBuilder.append('\n'); 1602 /* 1603 dropBuilder.append(oomString); 1604 dropBuilder.append('\n'); 1605 */ 1606 StringWriter catSw = new StringWriter(); 1607 synchronized (ActivityManagerService.this) { 1608 PrintWriter catPw = new FastPrintWriter(catSw, false, 256); 1609 String[] emptyArgs = new String[] { }; 1610 catPw.println(); 1611 dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null); 1612 catPw.println(); 1613 mServices.dumpServicesLocked(null, catPw, emptyArgs, 0, 1614 false, false, null); 1615 catPw.println(); 1616 dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null); 1617 catPw.flush(); 1618 } 1619 dropBuilder.append(catSw.toString()); 1620 addErrorToDropBox("lowmem", null, "system_server", null, 1621 null, tag.toString(), dropBuilder.toString(), null, null); 1622 //Slog.i(TAG, "Sent to dropbox:"); 1623 //Slog.i(TAG, dropBuilder.toString()); 1624 synchronized (ActivityManagerService.this) { 1625 long now = SystemClock.uptimeMillis(); 1626 if (mLastMemUsageReportTime < now) { 1627 mLastMemUsageReportTime = now; 1628 } 1629 } 1630 } 1631 }; 1632 thread.start(); 1633 break; 1634 } 1635 case REPORT_USER_SWITCH_MSG: { 1636 dispatchUserSwitch((UserStartedState)msg.obj, msg.arg1, msg.arg2); 1637 break; 1638 } 1639 case CONTINUE_USER_SWITCH_MSG: { 1640 continueUserSwitch((UserStartedState)msg.obj, msg.arg1, msg.arg2); 1641 break; 1642 } 1643 case USER_SWITCH_TIMEOUT_MSG: { 1644 timeoutUserSwitch((UserStartedState)msg.obj, msg.arg1, msg.arg2); 1645 break; 1646 } 1647 case IMMERSIVE_MODE_LOCK_MSG: { 1648 final boolean nextState = (msg.arg1 != 0); 1649 if (mUpdateLock.isHeld() != nextState) { 1650 if (DEBUG_IMMERSIVE) { 1651 final ActivityRecord r = (ActivityRecord) msg.obj; 1652 Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r); 1653 } 1654 if (nextState) { 1655 mUpdateLock.acquire(); 1656 } else { 1657 mUpdateLock.release(); 1658 } 1659 } 1660 break; 1661 } 1662 case PERSIST_URI_GRANTS_MSG: { 1663 writeGrantedUriPermissions(); 1664 break; 1665 } 1666 case REQUEST_ALL_PSS_MSG: { 1667 requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false); 1668 break; 1669 } 1670 } 1671 } 1672 }; 1673 1674 static final int COLLECT_PSS_BG_MSG = 1; 1675 1676 final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) { 1677 @Override 1678 public void handleMessage(Message msg) { 1679 switch (msg.what) { 1680 case COLLECT_PSS_BG_MSG: { 1681 int i=0, num=0; 1682 long start = SystemClock.uptimeMillis(); 1683 long[] tmp = new long[1]; 1684 do { 1685 ProcessRecord proc; 1686 int procState; 1687 int pid; 1688 synchronized (ActivityManagerService.this) { 1689 if (i >= mPendingPssProcesses.size()) { 1690 if (DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num + " of " + i 1691 + " processes in " + (SystemClock.uptimeMillis()-start) + "ms"); 1692 mPendingPssProcesses.clear(); 1693 return; 1694 } 1695 proc = mPendingPssProcesses.get(i); 1696 procState = proc.pssProcState; 1697 if (proc.thread != null && procState == proc.setProcState) { 1698 pid = proc.pid; 1699 } else { 1700 proc = null; 1701 pid = 0; 1702 } 1703 i++; 1704 } 1705 if (proc != null) { 1706 long pss = Debug.getPss(pid, tmp); 1707 synchronized (ActivityManagerService.this) { 1708 if (proc.thread != null && proc.setProcState == procState 1709 && proc.pid == pid) { 1710 num++; 1711 proc.lastPssTime = SystemClock.uptimeMillis(); 1712 proc.baseProcessTracker.addPss(pss, tmp[0], true, proc.pkgList); 1713 if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString() 1714 + ": " + pss + " lastPss=" + proc.lastPss 1715 + " state=" + ProcessList.makeProcStateString(procState)); 1716 if (proc.initialIdlePss == 0) { 1717 proc.initialIdlePss = pss; 1718 } 1719 proc.lastPss = pss; 1720 if (procState >= ActivityManager.PROCESS_STATE_HOME) { 1721 proc.lastCachedPss = pss; 1722 } 1723 } 1724 } 1725 } 1726 } while (true); 1727 } 1728 } 1729 } 1730 }; 1731 1732 public static void setSystemProcess() { 1733 try { 1734 ActivityManagerService m = mSelf; 1735 1736 ServiceManager.addService(Context.ACTIVITY_SERVICE, m, true); 1737 ServiceManager.addService(ProcessStats.SERVICE_NAME, m.mProcessStats); 1738 ServiceManager.addService("meminfo", new MemBinder(m)); 1739 ServiceManager.addService("gfxinfo", new GraphicsBinder(m)); 1740 ServiceManager.addService("dbinfo", new DbBinder(m)); 1741 if (MONITOR_CPU_USAGE) { 1742 ServiceManager.addService("cpuinfo", new CpuBinder(m)); 1743 } 1744 ServiceManager.addService("permission", new PermissionController(m)); 1745 1746 ApplicationInfo info = 1747 mSelf.mContext.getPackageManager().getApplicationInfo( 1748 "android", STOCK_PM_FLAGS); 1749 mSystemThread.installSystemApplicationInfo(info); 1750 1751 synchronized (mSelf) { 1752 ProcessRecord app = mSelf.newProcessRecordLocked(info, 1753 info.processName, false); 1754 app.persistent = true; 1755 app.pid = MY_PID; 1756 app.maxAdj = ProcessList.SYSTEM_ADJ; 1757 app.makeActive(mSystemThread.getApplicationThread(), mSelf.mProcessStats); 1758 mSelf.mProcessNames.put(app.processName, app.uid, app); 1759 synchronized (mSelf.mPidsSelfLocked) { 1760 mSelf.mPidsSelfLocked.put(app.pid, app); 1761 } 1762 mSelf.updateLruProcessLocked(app, false, null); 1763 mSelf.updateOomAdjLocked(); 1764 } 1765 } catch (PackageManager.NameNotFoundException e) { 1766 throw new RuntimeException( 1767 "Unable to find android system package", e); 1768 } 1769 } 1770 1771 public void setWindowManager(WindowManagerService wm) { 1772 mWindowManager = wm; 1773 mStackSupervisor.setWindowManager(wm); 1774 } 1775 1776 public void startObservingNativeCrashes() { 1777 final NativeCrashListener ncl = new NativeCrashListener(); 1778 ncl.start(); 1779 } 1780 1781 public static final Context main(int factoryTest) { 1782 AThread thr = new AThread(); 1783 thr.start(); 1784 1785 synchronized (thr) { 1786 while (thr.mService == null) { 1787 try { 1788 thr.wait(); 1789 } catch (InterruptedException e) { 1790 } 1791 } 1792 } 1793 1794 ActivityManagerService m = thr.mService; 1795 mSelf = m; 1796 ActivityThread at = ActivityThread.systemMain(); 1797 mSystemThread = at; 1798 Context context = at.getSystemContext(); 1799 context.setTheme(android.R.style.Theme_Holo); 1800 m.mContext = context; 1801 m.mFactoryTest = factoryTest; 1802 m.mIntentFirewall = new IntentFirewall(m.new IntentFirewallInterface()); 1803 1804 m.mStackSupervisor = new ActivityStackSupervisor(m); 1805 1806 m.mBatteryStatsService.publish(context); 1807 m.mUsageStatsService.publish(context); 1808 m.mAppOpsService.publish(context); 1809 1810 synchronized (thr) { 1811 thr.mReady = true; 1812 thr.notifyAll(); 1813 } 1814 1815 m.startRunning(null, null, null, null); 1816 1817 return context; 1818 } 1819 1820 public static ActivityManagerService self() { 1821 return mSelf; 1822 } 1823 1824 public IAppOpsService getAppOpsService() { 1825 return mAppOpsService; 1826 } 1827 1828 static class AThread extends Thread { 1829 ActivityManagerService mService; 1830 Looper mLooper; 1831 boolean mReady = false; 1832 1833 public AThread() { 1834 super("ActivityManager"); 1835 } 1836 1837 @Override 1838 public void run() { 1839 Looper.prepare(); 1840 1841 android.os.Process.setThreadPriority( 1842 android.os.Process.THREAD_PRIORITY_FOREGROUND); 1843 android.os.Process.setCanSelfBackground(false); 1844 1845 ActivityManagerService m = new ActivityManagerService(); 1846 1847 synchronized (this) { 1848 mService = m; 1849 mLooper = Looper.myLooper(); 1850 Watchdog.getInstance().addThread(new Handler(mLooper), getName()); 1851 notifyAll(); 1852 } 1853 1854 synchronized (this) { 1855 while (!mReady) { 1856 try { 1857 wait(); 1858 } catch (InterruptedException e) { 1859 } 1860 } 1861 } 1862 1863 // For debug builds, log event loop stalls to dropbox for analysis. 1864 if (StrictMode.conditionallyEnableDebugLogging()) { 1865 Slog.i(TAG, "Enabled StrictMode logging for AThread's Looper"); 1866 } 1867 1868 Looper.loop(); 1869 } 1870 } 1871 1872 static class MemBinder extends Binder { 1873 ActivityManagerService mActivityManagerService; 1874 MemBinder(ActivityManagerService activityManagerService) { 1875 mActivityManagerService = activityManagerService; 1876 } 1877 1878 @Override 1879 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1880 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1881 != PackageManager.PERMISSION_GRANTED) { 1882 pw.println("Permission Denial: can't dump meminfo from from pid=" 1883 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1884 + " without permission " + android.Manifest.permission.DUMP); 1885 return; 1886 } 1887 1888 mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, " ", args, false, null); 1889 } 1890 } 1891 1892 static class GraphicsBinder extends Binder { 1893 ActivityManagerService mActivityManagerService; 1894 GraphicsBinder(ActivityManagerService activityManagerService) { 1895 mActivityManagerService = activityManagerService; 1896 } 1897 1898 @Override 1899 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1900 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1901 != PackageManager.PERMISSION_GRANTED) { 1902 pw.println("Permission Denial: can't dump gfxinfo from from pid=" 1903 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1904 + " without permission " + android.Manifest.permission.DUMP); 1905 return; 1906 } 1907 1908 mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args); 1909 } 1910 } 1911 1912 static class DbBinder extends Binder { 1913 ActivityManagerService mActivityManagerService; 1914 DbBinder(ActivityManagerService activityManagerService) { 1915 mActivityManagerService = activityManagerService; 1916 } 1917 1918 @Override 1919 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1920 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1921 != PackageManager.PERMISSION_GRANTED) { 1922 pw.println("Permission Denial: can't dump dbinfo from from pid=" 1923 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1924 + " without permission " + android.Manifest.permission.DUMP); 1925 return; 1926 } 1927 1928 mActivityManagerService.dumpDbInfo(fd, pw, args); 1929 } 1930 } 1931 1932 static class CpuBinder extends Binder { 1933 ActivityManagerService mActivityManagerService; 1934 CpuBinder(ActivityManagerService activityManagerService) { 1935 mActivityManagerService = activityManagerService; 1936 } 1937 1938 @Override 1939 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1940 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1941 != PackageManager.PERMISSION_GRANTED) { 1942 pw.println("Permission Denial: can't dump cpuinfo from from pid=" 1943 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1944 + " without permission " + android.Manifest.permission.DUMP); 1945 return; 1946 } 1947 1948 synchronized (mActivityManagerService.mProcessCpuThread) { 1949 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad()); 1950 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState( 1951 SystemClock.uptimeMillis())); 1952 } 1953 } 1954 } 1955 1956 private ActivityManagerService() { 1957 Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass()); 1958 1959 mFgBroadcastQueue = new BroadcastQueue(this, "foreground", BROADCAST_FG_TIMEOUT, false); 1960 mBgBroadcastQueue = new BroadcastQueue(this, "background", BROADCAST_BG_TIMEOUT, true); 1961 mBroadcastQueues[0] = mFgBroadcastQueue; 1962 mBroadcastQueues[1] = mBgBroadcastQueue; 1963 1964 mServices = new ActiveServices(this); 1965 mProviderMap = new ProviderMap(this); 1966 1967 File dataDir = Environment.getDataDirectory(); 1968 File systemDir = new File(dataDir, "system"); 1969 systemDir.mkdirs(); 1970 mBatteryStatsService = new BatteryStatsService(new File( 1971 systemDir, "batterystats.bin").toString()); 1972 mBatteryStatsService.getActiveStatistics().readLocked(); 1973 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 1974 mOnBattery = DEBUG_POWER ? true 1975 : mBatteryStatsService.getActiveStatistics().getIsOnBattery(); 1976 mBatteryStatsService.getActiveStatistics().setCallback(this); 1977 1978 mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats")); 1979 1980 mUsageStatsService = new UsageStatsService(new File(systemDir, "usagestats").toString()); 1981 mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml")); 1982 1983 mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml")); 1984 1985 // User 0 is the first and only user that runs at boot. 1986 mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true)); 1987 mUserLru.add(Integer.valueOf(0)); 1988 updateStartedUserArrayLocked(); 1989 1990 GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version", 1991 ConfigurationInfo.GL_ES_VERSION_UNDEFINED); 1992 1993 mConfiguration.setToDefaults(); 1994 mConfiguration.setLocale(Locale.getDefault()); 1995 1996 mConfigurationSeq = mConfiguration.seq = 1; 1997 mProcessCpuTracker.init(); 1998 1999 mCompatModePackages = new CompatModePackages(this, systemDir); 2000 2001 // Add ourself to the Watchdog monitors. 2002 Watchdog.getInstance().addMonitor(this); 2003 2004 mProcessCpuThread = new Thread("CpuTracker") { 2005 @Override 2006 public void run() { 2007 while (true) { 2008 try { 2009 try { 2010 synchronized(this) { 2011 final long now = SystemClock.uptimeMillis(); 2012 long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now; 2013 long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now; 2014 //Slog.i(TAG, "Cpu delay=" + nextCpuDelay 2015 // + ", write delay=" + nextWriteDelay); 2016 if (nextWriteDelay < nextCpuDelay) { 2017 nextCpuDelay = nextWriteDelay; 2018 } 2019 if (nextCpuDelay > 0) { 2020 mProcessCpuMutexFree.set(true); 2021 this.wait(nextCpuDelay); 2022 } 2023 } 2024 } catch (InterruptedException e) { 2025 } 2026 updateCpuStatsNow(); 2027 } catch (Exception e) { 2028 Slog.e(TAG, "Unexpected exception collecting process stats", e); 2029 } 2030 } 2031 } 2032 }; 2033 mProcessCpuThread.start(); 2034 } 2035 2036 @Override 2037 public boolean onTransact(int code, Parcel data, Parcel reply, int flags) 2038 throws RemoteException { 2039 if (code == SYSPROPS_TRANSACTION) { 2040 // We need to tell all apps about the system property change. 2041 ArrayList<IBinder> procs = new ArrayList<IBinder>(); 2042 synchronized(this) { 2043 final int NP = mProcessNames.getMap().size(); 2044 for (int ip=0; ip<NP; ip++) { 2045 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 2046 final int NA = apps.size(); 2047 for (int ia=0; ia<NA; ia++) { 2048 ProcessRecord app = apps.valueAt(ia); 2049 if (app.thread != null) { 2050 procs.add(app.thread.asBinder()); 2051 } 2052 } 2053 } 2054 } 2055 2056 int N = procs.size(); 2057 for (int i=0; i<N; i++) { 2058 Parcel data2 = Parcel.obtain(); 2059 try { 2060 procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0); 2061 } catch (RemoteException e) { 2062 } 2063 data2.recycle(); 2064 } 2065 } 2066 try { 2067 return super.onTransact(code, data, reply, flags); 2068 } catch (RuntimeException e) { 2069 // The activity manager only throws security exceptions, so let's 2070 // log all others. 2071 if (!(e instanceof SecurityException)) { 2072 Slog.wtf(TAG, "Activity Manager Crash", e); 2073 } 2074 throw e; 2075 } 2076 } 2077 2078 void updateCpuStats() { 2079 final long now = SystemClock.uptimeMillis(); 2080 if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) { 2081 return; 2082 } 2083 if (mProcessCpuMutexFree.compareAndSet(true, false)) { 2084 synchronized (mProcessCpuThread) { 2085 mProcessCpuThread.notify(); 2086 } 2087 } 2088 } 2089 2090 void updateCpuStatsNow() { 2091 synchronized (mProcessCpuThread) { 2092 mProcessCpuMutexFree.set(false); 2093 final long now = SystemClock.uptimeMillis(); 2094 boolean haveNewCpuStats = false; 2095 2096 if (MONITOR_CPU_USAGE && 2097 mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) { 2098 mLastCpuTime.set(now); 2099 haveNewCpuStats = true; 2100 mProcessCpuTracker.update(); 2101 //Slog.i(TAG, mProcessCpu.printCurrentState()); 2102 //Slog.i(TAG, "Total CPU usage: " 2103 // + mProcessCpu.getTotalCpuPercent() + "%"); 2104 2105 // Slog the cpu usage if the property is set. 2106 if ("true".equals(SystemProperties.get("events.cpu"))) { 2107 int user = mProcessCpuTracker.getLastUserTime(); 2108 int system = mProcessCpuTracker.getLastSystemTime(); 2109 int iowait = mProcessCpuTracker.getLastIoWaitTime(); 2110 int irq = mProcessCpuTracker.getLastIrqTime(); 2111 int softIrq = mProcessCpuTracker.getLastSoftIrqTime(); 2112 int idle = mProcessCpuTracker.getLastIdleTime(); 2113 2114 int total = user + system + iowait + irq + softIrq + idle; 2115 if (total == 0) total = 1; 2116 2117 EventLog.writeEvent(EventLogTags.CPU, 2118 ((user+system+iowait+irq+softIrq) * 100) / total, 2119 (user * 100) / total, 2120 (system * 100) / total, 2121 (iowait * 100) / total, 2122 (irq * 100) / total, 2123 (softIrq * 100) / total); 2124 } 2125 } 2126 2127 long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes(); 2128 final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics(); 2129 synchronized(bstats) { 2130 synchronized(mPidsSelfLocked) { 2131 if (haveNewCpuStats) { 2132 if (mOnBattery) { 2133 int perc = bstats.startAddingCpuLocked(); 2134 int totalUTime = 0; 2135 int totalSTime = 0; 2136 final int N = mProcessCpuTracker.countStats(); 2137 for (int i=0; i<N; i++) { 2138 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 2139 if (!st.working) { 2140 continue; 2141 } 2142 ProcessRecord pr = mPidsSelfLocked.get(st.pid); 2143 int otherUTime = (st.rel_utime*perc)/100; 2144 int otherSTime = (st.rel_stime*perc)/100; 2145 totalUTime += otherUTime; 2146 totalSTime += otherSTime; 2147 if (pr != null) { 2148 BatteryStatsImpl.Uid.Proc ps = bstats.getProcessStatsLocked( 2149 st.name, st.pid); 2150 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 2151 st.rel_stime-otherSTime); 2152 ps.addSpeedStepTimes(cpuSpeedTimes); 2153 pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10; 2154 } else if (st.uid >= Process.FIRST_APPLICATION_UID) { 2155 BatteryStatsImpl.Uid.Proc ps = st.batteryStats; 2156 if (ps == null) { 2157 st.batteryStats = ps = bstats.getProcessStatsLocked(st.uid, 2158 "(Unknown)"); 2159 } 2160 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 2161 st.rel_stime-otherSTime); 2162 ps.addSpeedStepTimes(cpuSpeedTimes); 2163 } else { 2164 BatteryStatsImpl.Uid.Proc ps = 2165 bstats.getProcessStatsLocked(st.name, st.pid); 2166 if (ps != null) { 2167 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 2168 st.rel_stime-otherSTime); 2169 ps.addSpeedStepTimes(cpuSpeedTimes); 2170 } 2171 } 2172 } 2173 bstats.finishAddingCpuLocked(perc, totalUTime, 2174 totalSTime, cpuSpeedTimes); 2175 } 2176 } 2177 } 2178 2179 if (mLastWriteTime < (now-BATTERY_STATS_TIME)) { 2180 mLastWriteTime = now; 2181 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 2182 } 2183 } 2184 } 2185 } 2186 2187 @Override 2188 public void batteryNeedsCpuUpdate() { 2189 updateCpuStatsNow(); 2190 } 2191 2192 @Override 2193 public void batteryPowerChanged(boolean onBattery) { 2194 // When plugging in, update the CPU stats first before changing 2195 // the plug state. 2196 updateCpuStatsNow(); 2197 synchronized (this) { 2198 synchronized(mPidsSelfLocked) { 2199 mOnBattery = DEBUG_POWER ? true : onBattery; 2200 } 2201 } 2202 } 2203 2204 /** 2205 * Initialize the application bind args. These are passed to each 2206 * process when the bindApplication() IPC is sent to the process. They're 2207 * lazily setup to make sure the services are running when they're asked for. 2208 */ 2209 private HashMap<String, IBinder> getCommonServicesLocked() { 2210 if (mAppBindArgs == null) { 2211 mAppBindArgs = new HashMap<String, IBinder>(); 2212 2213 // Setup the application init args 2214 mAppBindArgs.put("package", ServiceManager.getService("package")); 2215 mAppBindArgs.put("window", ServiceManager.getService("window")); 2216 mAppBindArgs.put(Context.ALARM_SERVICE, 2217 ServiceManager.getService(Context.ALARM_SERVICE)); 2218 } 2219 return mAppBindArgs; 2220 } 2221 2222 final void setFocusedActivityLocked(ActivityRecord r) { 2223 if (mFocusedActivity != r) { 2224 if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r); 2225 mFocusedActivity = r; 2226 mStackSupervisor.setFocusedStack(r); 2227 if (r != null) { 2228 mWindowManager.setFocusedApp(r.appToken, true); 2229 } 2230 applyUpdateLockStateLocked(r); 2231 } 2232 } 2233 2234 @Override 2235 public void setFocusedStack(int stackId) { 2236 if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId); 2237 synchronized (ActivityManagerService.this) { 2238 ActivityStack stack = mStackSupervisor.getStack(stackId); 2239 if (stack != null) { 2240 ActivityRecord r = stack.topRunningActivityLocked(null); 2241 if (r != null) { 2242 setFocusedActivityLocked(r); 2243 } 2244 } 2245 } 2246 } 2247 2248 @Override 2249 public void notifyActivityDrawn(IBinder token) { 2250 if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token); 2251 synchronized (this) { 2252 ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token); 2253 if (r != null) { 2254 r.task.stack.notifyActivityDrawnLocked(r); 2255 } 2256 } 2257 } 2258 2259 final void applyUpdateLockStateLocked(ActivityRecord r) { 2260 // Modifications to the UpdateLock state are done on our handler, outside 2261 // the activity manager's locks. The new state is determined based on the 2262 // state *now* of the relevant activity record. The object is passed to 2263 // the handler solely for logging detail, not to be consulted/modified. 2264 final boolean nextState = r != null && r.immersive; 2265 mHandler.sendMessage( 2266 mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r)); 2267 } 2268 2269 final void showAskCompatModeDialogLocked(ActivityRecord r) { 2270 Message msg = Message.obtain(); 2271 msg.what = SHOW_COMPAT_MODE_DIALOG_MSG; 2272 msg.obj = r.task.askedCompatMode ? null : r; 2273 mHandler.sendMessage(msg); 2274 } 2275 2276 private final int updateLruProcessInternalLocked(ProcessRecord app, long now, int index, 2277 String what, Object obj, ProcessRecord srcApp) { 2278 app.lastActivityTime = now; 2279 2280 if (app.activities.size() > 0) { 2281 // Don't want to touch dependent processes that are hosting activities. 2282 return index; 2283 } 2284 2285 int lrui = mLruProcesses.lastIndexOf(app); 2286 if (lrui < 0) { 2287 Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: " 2288 + what + " " + obj + " from " + srcApp); 2289 return index; 2290 } 2291 2292 if (lrui >= index) { 2293 // Don't want to cause this to move dependent processes *back* in the 2294 // list as if they were less frequently used. 2295 return index; 2296 } 2297 2298 if (lrui >= mLruProcessActivityStart) { 2299 // Don't want to touch dependent processes that are hosting activities. 2300 return index; 2301 } 2302 2303 mLruProcesses.remove(lrui); 2304 if (index > 0) { 2305 index--; 2306 } 2307 if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index 2308 + " in LRU list: " + app); 2309 mLruProcesses.add(index, app); 2310 return index; 2311 } 2312 2313 final void removeLruProcessLocked(ProcessRecord app) { 2314 int lrui = mLruProcesses.lastIndexOf(app); 2315 if (lrui >= 0) { 2316 if (lrui <= mLruProcessActivityStart) { 2317 mLruProcessActivityStart--; 2318 } 2319 if (lrui <= mLruProcessServiceStart) { 2320 mLruProcessServiceStart--; 2321 } 2322 mLruProcesses.remove(lrui); 2323 } 2324 } 2325 2326 final void updateLruProcessLocked(ProcessRecord app, boolean activityChange, 2327 ProcessRecord client) { 2328 final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities; 2329 final boolean hasService = false; // not impl yet. app.services.size() > 0; 2330 if (!activityChange && hasActivity) { 2331 // The process has activties, so we are only going to allow activity-based 2332 // adjustments move it. It should be kept in the front of the list with other 2333 // processes that have activities, and we don't want those to change their 2334 // order except due to activity operations. 2335 return; 2336 } 2337 2338 mLruSeq++; 2339 final long now = SystemClock.uptimeMillis(); 2340 app.lastActivityTime = now; 2341 2342 // First a quick reject: if the app is already at the position we will 2343 // put it, then there is nothing to do. 2344 if (hasActivity) { 2345 final int N = mLruProcesses.size(); 2346 if (N > 0 && mLruProcesses.get(N-1) == app) { 2347 if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app); 2348 return; 2349 } 2350 } else { 2351 if (mLruProcessServiceStart > 0 2352 && mLruProcesses.get(mLruProcessServiceStart-1) == app) { 2353 if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app); 2354 return; 2355 } 2356 } 2357 2358 int lrui = mLruProcesses.lastIndexOf(app); 2359 2360 if (app.persistent && lrui >= 0) { 2361 // We don't care about the position of persistent processes, as long as 2362 // they are in the list. 2363 if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app); 2364 return; 2365 } 2366 2367 /* In progress: compute new position first, so we can avoid doing work 2368 if the process is not actually going to move. Not yet working. 2369 int addIndex; 2370 int nextIndex; 2371 boolean inActivity = false, inService = false; 2372 if (hasActivity) { 2373 // Process has activities, put it at the very tipsy-top. 2374 addIndex = mLruProcesses.size(); 2375 nextIndex = mLruProcessServiceStart; 2376 inActivity = true; 2377 } else if (hasService) { 2378 // Process has services, put it at the top of the service list. 2379 addIndex = mLruProcessActivityStart; 2380 nextIndex = mLruProcessServiceStart; 2381 inActivity = true; 2382 inService = true; 2383 } else { 2384 // Process not otherwise of interest, it goes to the top of the non-service area. 2385 addIndex = mLruProcessServiceStart; 2386 if (client != null) { 2387 int clientIndex = mLruProcesses.lastIndexOf(client); 2388 if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating " 2389 + app); 2390 if (clientIndex >= 0 && addIndex > clientIndex) { 2391 addIndex = clientIndex; 2392 } 2393 } 2394 nextIndex = addIndex > 0 ? addIndex-1 : addIndex; 2395 } 2396 2397 Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act=" 2398 + mLruProcessActivityStart + "): " + app); 2399 */ 2400 2401 if (lrui >= 0) { 2402 if (lrui < mLruProcessActivityStart) { 2403 mLruProcessActivityStart--; 2404 } 2405 if (lrui < mLruProcessServiceStart) { 2406 mLruProcessServiceStart--; 2407 } 2408 /* 2409 if (addIndex > lrui) { 2410 addIndex--; 2411 } 2412 if (nextIndex > lrui) { 2413 nextIndex--; 2414 } 2415 */ 2416 mLruProcesses.remove(lrui); 2417 } 2418 2419 /* 2420 mLruProcesses.add(addIndex, app); 2421 if (inActivity) { 2422 mLruProcessActivityStart++; 2423 } 2424 if (inService) { 2425 mLruProcessActivityStart++; 2426 } 2427 */ 2428 2429 int nextIndex; 2430 if (hasActivity) { 2431 final int N = mLruProcesses.size(); 2432 if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) { 2433 // Process doesn't have activities, but has clients with 2434 // activities... move it up, but one below the top (the top 2435 // should always have a real activity). 2436 if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app); 2437 mLruProcesses.add(N-1, app); 2438 // To keep it from spamming the LRU list (by making a bunch of clients), 2439 // we will push down any other entries owned by the app. 2440 final int uid = app.info.uid; 2441 for (int i=N-2; i>mLruProcessActivityStart; i--) { 2442 ProcessRecord subProc = mLruProcesses.get(i); 2443 if (subProc.info.uid == uid) { 2444 // We want to push this one down the list. If the process after 2445 // it is for the same uid, however, don't do so, because we don't 2446 // want them internally to be re-ordered. 2447 if (mLruProcesses.get(i-1).info.uid != uid) { 2448 if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i 2449 + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1)); 2450 ProcessRecord tmp = mLruProcesses.get(i); 2451 mLruProcesses.set(i, mLruProcesses.get(i-1)); 2452 mLruProcesses.set(i-1, tmp); 2453 i--; 2454 } 2455 } else { 2456 // A gap, we can stop here. 2457 break; 2458 } 2459 } 2460 } else { 2461 // Process has activities, put it at the very tipsy-top. 2462 if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app); 2463 mLruProcesses.add(app); 2464 } 2465 nextIndex = mLruProcessServiceStart; 2466 } else if (hasService) { 2467 // Process has services, put it at the top of the service list. 2468 if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app); 2469 mLruProcesses.add(mLruProcessActivityStart, app); 2470 nextIndex = mLruProcessServiceStart; 2471 mLruProcessActivityStart++; 2472 } else { 2473 // Process not otherwise of interest, it goes to the top of the non-service area. 2474 int index = mLruProcessServiceStart; 2475 if (client != null) { 2476 // If there is a client, don't allow the process to be moved up higher 2477 // in the list than that client. 2478 int clientIndex = mLruProcesses.lastIndexOf(client); 2479 if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client 2480 + " when updating " + app); 2481 if (clientIndex <= lrui) { 2482 // Don't allow the client index restriction to push it down farther in the 2483 // list than it already is. 2484 clientIndex = lrui; 2485 } 2486 if (clientIndex >= 0 && index > clientIndex) { 2487 index = clientIndex; 2488 } 2489 } 2490 if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app); 2491 mLruProcesses.add(index, app); 2492 nextIndex = index-1; 2493 mLruProcessActivityStart++; 2494 mLruProcessServiceStart++; 2495 } 2496 2497 // If the app is currently using a content provider or service, 2498 // bump those processes as well. 2499 for (int j=app.connections.size()-1; j>=0; j--) { 2500 ConnectionRecord cr = app.connections.valueAt(j); 2501 if (cr.binding != null && !cr.serviceDead && cr.binding.service != null 2502 && cr.binding.service.app != null 2503 && cr.binding.service.app.lruSeq != mLruSeq 2504 && !cr.binding.service.app.persistent) { 2505 nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex, 2506 "service connection", cr, app); 2507 } 2508 } 2509 for (int j=app.conProviders.size()-1; j>=0; j--) { 2510 ContentProviderRecord cpr = app.conProviders.get(j).provider; 2511 if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) { 2512 nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex, 2513 "provider reference", cpr, app); 2514 } 2515 } 2516 } 2517 2518 final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) { 2519 if (uid == Process.SYSTEM_UID) { 2520 // The system gets to run in any process. If there are multiple 2521 // processes with the same uid, just pick the first (this 2522 // should never happen). 2523 SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName); 2524 if (procs == null) return null; 2525 final int N = procs.size(); 2526 for (int i = 0; i < N; i++) { 2527 if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i); 2528 } 2529 } 2530 ProcessRecord proc = mProcessNames.get(processName, uid); 2531 if (false && proc != null && !keepIfLarge 2532 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY 2533 && proc.lastCachedPss >= 4000) { 2534 // Turn this condition on to cause killing to happen regularly, for testing. 2535 if (proc.baseProcessTracker != null) { 2536 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss); 2537 } 2538 killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss) 2539 + "k from cached"); 2540 } else if (proc != null && !keepIfLarge 2541 && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL 2542 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) { 2543 if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss); 2544 if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) { 2545 if (proc.baseProcessTracker != null) { 2546 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss); 2547 } 2548 killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss) 2549 + "k from cached"); 2550 } 2551 } 2552 return proc; 2553 } 2554 2555 void ensurePackageDexOpt(String packageName) { 2556 IPackageManager pm = AppGlobals.getPackageManager(); 2557 try { 2558 if (pm.performDexOpt(packageName)) { 2559 mDidDexOpt = true; 2560 } 2561 } catch (RemoteException e) { 2562 } 2563 } 2564 2565 boolean isNextTransitionForward() { 2566 int transit = mWindowManager.getPendingAppTransition(); 2567 return transit == AppTransition.TRANSIT_ACTIVITY_OPEN 2568 || transit == AppTransition.TRANSIT_TASK_OPEN 2569 || transit == AppTransition.TRANSIT_TASK_TO_FRONT; 2570 } 2571 2572 final ProcessRecord startProcessLocked(String processName, 2573 ApplicationInfo info, boolean knownToBeDead, int intentFlags, 2574 String hostingType, ComponentName hostingName, boolean allowWhileBooting, 2575 boolean isolated, boolean keepIfLarge) { 2576 ProcessRecord app; 2577 if (!isolated) { 2578 app = getProcessRecordLocked(processName, info.uid, keepIfLarge); 2579 } else { 2580 // If this is an isolated process, it can't re-use an existing process. 2581 app = null; 2582 } 2583 // We don't have to do anything more if: 2584 // (1) There is an existing application record; and 2585 // (2) The caller doesn't think it is dead, OR there is no thread 2586 // object attached to it so we know it couldn't have crashed; and 2587 // (3) There is a pid assigned to it, so it is either starting or 2588 // already running. 2589 if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName 2590 + " app=" + app + " knownToBeDead=" + knownToBeDead 2591 + " thread=" + (app != null ? app.thread : null) 2592 + " pid=" + (app != null ? app.pid : -1)); 2593 if (app != null && app.pid > 0) { 2594 if (!knownToBeDead || app.thread == null) { 2595 // We already have the app running, or are waiting for it to 2596 // come up (we have a pid but not yet its thread), so keep it. 2597 if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app); 2598 // If this is a new package in the process, add the package to the list 2599 app.addPackage(info.packageName, mProcessStats); 2600 return app; 2601 } 2602 2603 // An application record is attached to a previous process, 2604 // clean it up now. 2605 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app); 2606 handleAppDiedLocked(app, true, true); 2607 } 2608 2609 String hostingNameStr = hostingName != null 2610 ? hostingName.flattenToShortString() : null; 2611 2612 if (!isolated) { 2613 if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) { 2614 // If we are in the background, then check to see if this process 2615 // is bad. If so, we will just silently fail. 2616 if (mBadProcesses.get(info.processName, info.uid) != null) { 2617 if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid 2618 + "/" + info.processName); 2619 return null; 2620 } 2621 } else { 2622 // When the user is explicitly starting a process, then clear its 2623 // crash count so that we won't make it bad until they see at 2624 // least one crash dialog again, and make the process good again 2625 // if it had been bad. 2626 if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid 2627 + "/" + info.processName); 2628 mProcessCrashTimes.remove(info.processName, info.uid); 2629 if (mBadProcesses.get(info.processName, info.uid) != null) { 2630 EventLog.writeEvent(EventLogTags.AM_PROC_GOOD, 2631 UserHandle.getUserId(info.uid), info.uid, 2632 info.processName); 2633 mBadProcesses.remove(info.processName, info.uid); 2634 if (app != null) { 2635 app.bad = false; 2636 } 2637 } 2638 } 2639 } 2640 2641 if (app == null) { 2642 app = newProcessRecordLocked(info, processName, isolated); 2643 if (app == null) { 2644 Slog.w(TAG, "Failed making new process record for " 2645 + processName + "/" + info.uid + " isolated=" + isolated); 2646 return null; 2647 } 2648 mProcessNames.put(processName, app.uid, app); 2649 if (isolated) { 2650 mIsolatedProcesses.put(app.uid, app); 2651 } 2652 } else { 2653 // If this is a new package in the process, add the package to the list 2654 app.addPackage(info.packageName, mProcessStats); 2655 } 2656 2657 // If the system is not ready yet, then hold off on starting this 2658 // process until it is. 2659 if (!mProcessesReady 2660 && !isAllowedWhileBooting(info) 2661 && !allowWhileBooting) { 2662 if (!mProcessesOnHold.contains(app)) { 2663 mProcessesOnHold.add(app); 2664 } 2665 if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app); 2666 return app; 2667 } 2668 2669 startProcessLocked(app, hostingType, hostingNameStr); 2670 return (app.pid != 0) ? app : null; 2671 } 2672 2673 boolean isAllowedWhileBooting(ApplicationInfo ai) { 2674 return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0; 2675 } 2676 2677 private final void startProcessLocked(ProcessRecord app, 2678 String hostingType, String hostingNameStr) { 2679 if (app.pid > 0 && app.pid != MY_PID) { 2680 synchronized (mPidsSelfLocked) { 2681 mPidsSelfLocked.remove(app.pid); 2682 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 2683 } 2684 app.setPid(0); 2685 } 2686 2687 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 2688 "startProcessLocked removing on hold: " + app); 2689 mProcessesOnHold.remove(app); 2690 2691 updateCpuStats(); 2692 2693 try { 2694 int uid = app.uid; 2695 2696 int[] gids = null; 2697 int mountExternal = Zygote.MOUNT_EXTERNAL_NONE; 2698 if (!app.isolated) { 2699 int[] permGids = null; 2700 try { 2701 final PackageManager pm = mContext.getPackageManager(); 2702 permGids = pm.getPackageGids(app.info.packageName); 2703 2704 if (Environment.isExternalStorageEmulated()) { 2705 if (pm.checkPermission( 2706 android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE, 2707 app.info.packageName) == PERMISSION_GRANTED) { 2708 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL; 2709 } else { 2710 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER; 2711 } 2712 } 2713 } catch (PackageManager.NameNotFoundException e) { 2714 Slog.w(TAG, "Unable to retrieve gids", e); 2715 } 2716 2717 /* 2718 * Add shared application GID so applications can share some 2719 * resources like shared libraries 2720 */ 2721 if (permGids == null) { 2722 gids = new int[1]; 2723 } else { 2724 gids = new int[permGids.length + 1]; 2725 System.arraycopy(permGids, 0, gids, 1, permGids.length); 2726 } 2727 gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid)); 2728 } 2729 if (mFactoryTest != SystemServer.FACTORY_TEST_OFF) { 2730 if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL 2731 && mTopComponent != null 2732 && app.processName.equals(mTopComponent.getPackageName())) { 2733 uid = 0; 2734 } 2735 if (mFactoryTest == SystemServer.FACTORY_TEST_HIGH_LEVEL 2736 && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) { 2737 uid = 0; 2738 } 2739 } 2740 int debugFlags = 0; 2741 if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) { 2742 debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER; 2743 // Also turn on CheckJNI for debuggable apps. It's quite 2744 // awkward to turn on otherwise. 2745 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 2746 } 2747 // Run the app in safe mode if its manifest requests so or the 2748 // system is booted in safe mode. 2749 if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 || 2750 Zygote.systemInSafeMode == true) { 2751 debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE; 2752 } 2753 if ("1".equals(SystemProperties.get("debug.checkjni"))) { 2754 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 2755 } 2756 if ("1".equals(SystemProperties.get("debug.jni.logging"))) { 2757 debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING; 2758 } 2759 if ("1".equals(SystemProperties.get("debug.assert"))) { 2760 debugFlags |= Zygote.DEBUG_ENABLE_ASSERT; 2761 } 2762 2763 // Start the process. It will either succeed and return a result containing 2764 // the PID of the new process, or else throw a RuntimeException. 2765 Process.ProcessStartResult startResult = Process.start("android.app.ActivityThread", 2766 app.processName, uid, uid, gids, debugFlags, mountExternal, 2767 app.info.targetSdkVersion, app.info.seinfo, null); 2768 2769 BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics(); 2770 synchronized (bs) { 2771 if (bs.isOnBattery()) { 2772 bs.getProcessStatsLocked(app.uid, app.processName).incStartsLocked(); 2773 } 2774 } 2775 2776 EventLog.writeEvent(EventLogTags.AM_PROC_START, 2777 UserHandle.getUserId(uid), startResult.pid, uid, 2778 app.processName, hostingType, 2779 hostingNameStr != null ? hostingNameStr : ""); 2780 2781 if (app.persistent) { 2782 Watchdog.getInstance().processStarted(app.processName, startResult.pid); 2783 } 2784 2785 StringBuilder buf = mStringBuilder; 2786 buf.setLength(0); 2787 buf.append("Start proc "); 2788 buf.append(app.processName); 2789 buf.append(" for "); 2790 buf.append(hostingType); 2791 if (hostingNameStr != null) { 2792 buf.append(" "); 2793 buf.append(hostingNameStr); 2794 } 2795 buf.append(": pid="); 2796 buf.append(startResult.pid); 2797 buf.append(" uid="); 2798 buf.append(uid); 2799 buf.append(" gids={"); 2800 if (gids != null) { 2801 for (int gi=0; gi<gids.length; gi++) { 2802 if (gi != 0) buf.append(", "); 2803 buf.append(gids[gi]); 2804 2805 } 2806 } 2807 buf.append("}"); 2808 Slog.i(TAG, buf.toString()); 2809 app.setPid(startResult.pid); 2810 app.usingWrapper = startResult.usingWrapper; 2811 app.removed = false; 2812 synchronized (mPidsSelfLocked) { 2813 this.mPidsSelfLocked.put(startResult.pid, app); 2814 Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 2815 msg.obj = app; 2816 mHandler.sendMessageDelayed(msg, startResult.usingWrapper 2817 ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT); 2818 } 2819 } catch (RuntimeException e) { 2820 // XXX do better error recovery. 2821 app.setPid(0); 2822 Slog.e(TAG, "Failure starting process " + app.processName, e); 2823 } 2824 } 2825 2826 void updateUsageStats(ActivityRecord component, boolean resumed) { 2827 if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed); 2828 final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 2829 if (resumed) { 2830 mUsageStatsService.noteResumeComponent(component.realActivity); 2831 synchronized (stats) { 2832 stats.noteActivityResumedLocked(component.app.uid); 2833 } 2834 } else { 2835 mUsageStatsService.notePauseComponent(component.realActivity); 2836 synchronized (stats) { 2837 stats.noteActivityPausedLocked(component.app.uid); 2838 } 2839 } 2840 } 2841 2842 Intent getHomeIntent() { 2843 Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null); 2844 intent.setComponent(mTopComponent); 2845 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) { 2846 intent.addCategory(Intent.CATEGORY_HOME); 2847 } 2848 return intent; 2849 } 2850 2851 boolean startHomeActivityLocked(int userId) { 2852 if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL 2853 && mTopAction == null) { 2854 // We are running in factory test mode, but unable to find 2855 // the factory test app, so just sit around displaying the 2856 // error message and don't try to start anything. 2857 return false; 2858 } 2859 Intent intent = getHomeIntent(); 2860 ActivityInfo aInfo = 2861 resolveActivityInfo(intent, STOCK_PM_FLAGS, userId); 2862 if (aInfo != null) { 2863 intent.setComponent(new ComponentName( 2864 aInfo.applicationInfo.packageName, aInfo.name)); 2865 // Don't do this if the home app is currently being 2866 // instrumented. 2867 aInfo = new ActivityInfo(aInfo); 2868 aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId); 2869 ProcessRecord app = getProcessRecordLocked(aInfo.processName, 2870 aInfo.applicationInfo.uid, true); 2871 if (app == null || app.instrumentationClass == null) { 2872 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK); 2873 mStackSupervisor.startHomeActivity(intent, aInfo); 2874 } 2875 } 2876 2877 return true; 2878 } 2879 2880 private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) { 2881 ActivityInfo ai = null; 2882 ComponentName comp = intent.getComponent(); 2883 try { 2884 if (comp != null) { 2885 ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId); 2886 } else { 2887 ResolveInfo info = AppGlobals.getPackageManager().resolveIntent( 2888 intent, 2889 intent.resolveTypeIfNeeded(mContext.getContentResolver()), 2890 flags, userId); 2891 2892 if (info != null) { 2893 ai = info.activityInfo; 2894 } 2895 } 2896 } catch (RemoteException e) { 2897 // ignore 2898 } 2899 2900 return ai; 2901 } 2902 2903 /** 2904 * Starts the "new version setup screen" if appropriate. 2905 */ 2906 void startSetupActivityLocked() { 2907 // Only do this once per boot. 2908 if (mCheckedForSetup) { 2909 return; 2910 } 2911 2912 // We will show this screen if the current one is a different 2913 // version than the last one shown, and we are not running in 2914 // low-level factory test mode. 2915 final ContentResolver resolver = mContext.getContentResolver(); 2916 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL && 2917 Settings.Global.getInt(resolver, 2918 Settings.Global.DEVICE_PROVISIONED, 0) != 0) { 2919 mCheckedForSetup = true; 2920 2921 // See if we should be showing the platform update setup UI. 2922 Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP); 2923 List<ResolveInfo> ris = mSelf.mContext.getPackageManager() 2924 .queryIntentActivities(intent, PackageManager.GET_META_DATA); 2925 2926 // We don't allow third party apps to replace this. 2927 ResolveInfo ri = null; 2928 for (int i=0; ris != null && i<ris.size(); i++) { 2929 if ((ris.get(i).activityInfo.applicationInfo.flags 2930 & ApplicationInfo.FLAG_SYSTEM) != 0) { 2931 ri = ris.get(i); 2932 break; 2933 } 2934 } 2935 2936 if (ri != null) { 2937 String vers = ri.activityInfo.metaData != null 2938 ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION) 2939 : null; 2940 if (vers == null && ri.activityInfo.applicationInfo.metaData != null) { 2941 vers = ri.activityInfo.applicationInfo.metaData.getString( 2942 Intent.METADATA_SETUP_VERSION); 2943 } 2944 String lastVers = Settings.Secure.getString( 2945 resolver, Settings.Secure.LAST_SETUP_SHOWN); 2946 if (vers != null && !vers.equals(lastVers)) { 2947 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 2948 intent.setComponent(new ComponentName( 2949 ri.activityInfo.packageName, ri.activityInfo.name)); 2950 mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo, 2951 null, null, 0, 0, 0, null, 0, null, false, null, null); 2952 } 2953 } 2954 } 2955 } 2956 2957 CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) { 2958 return mCompatModePackages.compatibilityInfoForPackageLocked(ai); 2959 } 2960 2961 void enforceNotIsolatedCaller(String caller) { 2962 if (UserHandle.isIsolated(Binder.getCallingUid())) { 2963 throw new SecurityException("Isolated process not allowed to call " + caller); 2964 } 2965 } 2966 2967 @Override 2968 public int getFrontActivityScreenCompatMode() { 2969 enforceNotIsolatedCaller("getFrontActivityScreenCompatMode"); 2970 synchronized (this) { 2971 return mCompatModePackages.getFrontActivityScreenCompatModeLocked(); 2972 } 2973 } 2974 2975 @Override 2976 public void setFrontActivityScreenCompatMode(int mode) { 2977 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 2978 "setFrontActivityScreenCompatMode"); 2979 synchronized (this) { 2980 mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode); 2981 } 2982 } 2983 2984 @Override 2985 public int getPackageScreenCompatMode(String packageName) { 2986 enforceNotIsolatedCaller("getPackageScreenCompatMode"); 2987 synchronized (this) { 2988 return mCompatModePackages.getPackageScreenCompatModeLocked(packageName); 2989 } 2990 } 2991 2992 @Override 2993 public void setPackageScreenCompatMode(String packageName, int mode) { 2994 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 2995 "setPackageScreenCompatMode"); 2996 synchronized (this) { 2997 mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode); 2998 } 2999 } 3000 3001 @Override 3002 public boolean getPackageAskScreenCompat(String packageName) { 3003 enforceNotIsolatedCaller("getPackageAskScreenCompat"); 3004 synchronized (this) { 3005 return mCompatModePackages.getPackageAskCompatModeLocked(packageName); 3006 } 3007 } 3008 3009 @Override 3010 public void setPackageAskScreenCompat(String packageName, boolean ask) { 3011 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3012 "setPackageAskScreenCompat"); 3013 synchronized (this) { 3014 mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask); 3015 } 3016 } 3017 3018 private void dispatchProcessesChanged() { 3019 int N; 3020 synchronized (this) { 3021 N = mPendingProcessChanges.size(); 3022 if (mActiveProcessChanges.length < N) { 3023 mActiveProcessChanges = new ProcessChangeItem[N]; 3024 } 3025 mPendingProcessChanges.toArray(mActiveProcessChanges); 3026 mAvailProcessChanges.addAll(mPendingProcessChanges); 3027 mPendingProcessChanges.clear(); 3028 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes"); 3029 } 3030 3031 int i = mProcessObservers.beginBroadcast(); 3032 while (i > 0) { 3033 i--; 3034 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 3035 if (observer != null) { 3036 try { 3037 for (int j=0; j<N; j++) { 3038 ProcessChangeItem item = mActiveProcessChanges[j]; 3039 if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) { 3040 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid=" 3041 + item.pid + " uid=" + item.uid + ": " 3042 + item.foregroundActivities); 3043 observer.onForegroundActivitiesChanged(item.pid, item.uid, 3044 item.foregroundActivities); 3045 } 3046 if ((item.changes&ProcessChangeItem.CHANGE_IMPORTANCE) != 0) { 3047 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "IMPORTANCE CHANGED pid=" 3048 + item.pid + " uid=" + item.uid + ": " + item.importance); 3049 observer.onImportanceChanged(item.pid, item.uid, 3050 item.importance); 3051 } 3052 } 3053 } catch (RemoteException e) { 3054 } 3055 } 3056 } 3057 mProcessObservers.finishBroadcast(); 3058 } 3059 3060 private void dispatchProcessDied(int pid, int uid) { 3061 int i = mProcessObservers.beginBroadcast(); 3062 while (i > 0) { 3063 i--; 3064 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 3065 if (observer != null) { 3066 try { 3067 observer.onProcessDied(pid, uid); 3068 } catch (RemoteException e) { 3069 } 3070 } 3071 } 3072 mProcessObservers.finishBroadcast(); 3073 } 3074 3075 final void doPendingActivityLaunchesLocked(boolean doResume) { 3076 final int N = mPendingActivityLaunches.size(); 3077 if (N <= 0) { 3078 return; 3079 } 3080 for (int i=0; i<N; i++) { 3081 PendingActivityLaunch pal = mPendingActivityLaunches.get(i); 3082 mStackSupervisor.startActivityUncheckedLocked(pal.r, pal.sourceRecord, pal.startFlags, 3083 doResume && i == (N-1), null); 3084 } 3085 mPendingActivityLaunches.clear(); 3086 } 3087 3088 @Override 3089 public final int startActivity(IApplicationThread caller, String callingPackage, 3090 Intent intent, String resolvedType, IBinder resultTo, 3091 String resultWho, int requestCode, int startFlags, 3092 String profileFile, ParcelFileDescriptor profileFd, Bundle options) { 3093 return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo, 3094 resultWho, requestCode, 3095 startFlags, profileFile, profileFd, options, UserHandle.getCallingUserId()); 3096 } 3097 3098 @Override 3099 public final int startActivityAsUser(IApplicationThread caller, String callingPackage, 3100 Intent intent, String resolvedType, IBinder resultTo, 3101 String resultWho, int requestCode, int startFlags, 3102 String profileFile, ParcelFileDescriptor profileFd, Bundle options, int userId) { 3103 enforceNotIsolatedCaller("startActivity"); 3104 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3105 false, true, "startActivity", null); 3106 // TODO: Switch to user app stacks here. 3107 return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType, 3108 resultTo, resultWho, requestCode, startFlags, profileFile, profileFd, 3109 null, null, options, userId, null); 3110 } 3111 3112 @Override 3113 public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage, 3114 Intent intent, String resolvedType, IBinder resultTo, 3115 String resultWho, int requestCode, int startFlags, String profileFile, 3116 ParcelFileDescriptor profileFd, Bundle options, int userId) { 3117 enforceNotIsolatedCaller("startActivityAndWait"); 3118 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3119 false, true, "startActivityAndWait", null); 3120 WaitResult res = new WaitResult(); 3121 // TODO: Switch to user app stacks here. 3122 mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType, 3123 resultTo, resultWho, requestCode, startFlags, profileFile, profileFd, 3124 res, null, options, UserHandle.getCallingUserId(), null); 3125 return res; 3126 } 3127 3128 @Override 3129 public final int startActivityWithConfig(IApplicationThread caller, String callingPackage, 3130 Intent intent, String resolvedType, IBinder resultTo, 3131 String resultWho, int requestCode, int startFlags, Configuration config, 3132 Bundle options, int userId) { 3133 enforceNotIsolatedCaller("startActivityWithConfig"); 3134 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3135 false, true, "startActivityWithConfig", null); 3136 // TODO: Switch to user app stacks here. 3137 int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, 3138 resolvedType, resultTo, resultWho, requestCode, startFlags, 3139 null, null, null, config, options, userId, null); 3140 return ret; 3141 } 3142 3143 @Override 3144 public int startActivityIntentSender(IApplicationThread caller, 3145 IntentSender intent, Intent fillInIntent, String resolvedType, 3146 IBinder resultTo, String resultWho, int requestCode, 3147 int flagsMask, int flagsValues, Bundle options) { 3148 enforceNotIsolatedCaller("startActivityIntentSender"); 3149 // Refuse possible leaked file descriptors 3150 if (fillInIntent != null && fillInIntent.hasFileDescriptors()) { 3151 throw new IllegalArgumentException("File descriptors passed in Intent"); 3152 } 3153 3154 IIntentSender sender = intent.getTarget(); 3155 if (!(sender instanceof PendingIntentRecord)) { 3156 throw new IllegalArgumentException("Bad PendingIntent object"); 3157 } 3158 3159 PendingIntentRecord pir = (PendingIntentRecord)sender; 3160 3161 synchronized (this) { 3162 // If this is coming from the currently resumed activity, it is 3163 // effectively saying that app switches are allowed at this point. 3164 final ActivityStack stack = getFocusedStack(); 3165 if (stack.mResumedActivity != null && 3166 stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) { 3167 mAppSwitchesAllowedTime = 0; 3168 } 3169 } 3170 int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null, 3171 resultTo, resultWho, requestCode, flagsMask, flagsValues, options); 3172 return ret; 3173 } 3174 3175 @Override 3176 public boolean startNextMatchingActivity(IBinder callingActivity, 3177 Intent intent, Bundle options) { 3178 // Refuse possible leaked file descriptors 3179 if (intent != null && intent.hasFileDescriptors() == true) { 3180 throw new IllegalArgumentException("File descriptors passed in Intent"); 3181 } 3182 3183 synchronized (this) { 3184 final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity); 3185 if (r == null) { 3186 ActivityOptions.abort(options); 3187 return false; 3188 } 3189 if (r.app == null || r.app.thread == null) { 3190 // The caller is not running... d'oh! 3191 ActivityOptions.abort(options); 3192 return false; 3193 } 3194 intent = new Intent(intent); 3195 // The caller is not allowed to change the data. 3196 intent.setDataAndType(r.intent.getData(), r.intent.getType()); 3197 // And we are resetting to find the next component... 3198 intent.setComponent(null); 3199 3200 final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0); 3201 3202 ActivityInfo aInfo = null; 3203 try { 3204 List<ResolveInfo> resolves = 3205 AppGlobals.getPackageManager().queryIntentActivities( 3206 intent, r.resolvedType, 3207 PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS, 3208 UserHandle.getCallingUserId()); 3209 3210 // Look for the original activity in the list... 3211 final int N = resolves != null ? resolves.size() : 0; 3212 for (int i=0; i<N; i++) { 3213 ResolveInfo rInfo = resolves.get(i); 3214 if (rInfo.activityInfo.packageName.equals(r.packageName) 3215 && rInfo.activityInfo.name.equals(r.info.name)) { 3216 // We found the current one... the next matching is 3217 // after it. 3218 i++; 3219 if (i<N) { 3220 aInfo = resolves.get(i).activityInfo; 3221 } 3222 if (debug) { 3223 Slog.v(TAG, "Next matching activity: found current " + r.packageName 3224 + "/" + r.info.name); 3225 Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName 3226 + "/" + aInfo.name); 3227 } 3228 break; 3229 } 3230 } 3231 } catch (RemoteException e) { 3232 } 3233 3234 if (aInfo == null) { 3235 // Nobody who is next! 3236 ActivityOptions.abort(options); 3237 if (debug) Slog.d(TAG, "Next matching activity: nothing found"); 3238 return false; 3239 } 3240 3241 intent.setComponent(new ComponentName( 3242 aInfo.applicationInfo.packageName, aInfo.name)); 3243 intent.setFlags(intent.getFlags()&~( 3244 Intent.FLAG_ACTIVITY_FORWARD_RESULT| 3245 Intent.FLAG_ACTIVITY_CLEAR_TOP| 3246 Intent.FLAG_ACTIVITY_MULTIPLE_TASK| 3247 Intent.FLAG_ACTIVITY_NEW_TASK)); 3248 3249 // Okay now we need to start the new activity, replacing the 3250 // currently running activity. This is a little tricky because 3251 // we want to start the new one as if the current one is finished, 3252 // but not finish the current one first so that there is no flicker. 3253 // And thus... 3254 final boolean wasFinishing = r.finishing; 3255 r.finishing = true; 3256 3257 // Propagate reply information over to the new activity. 3258 final ActivityRecord resultTo = r.resultTo; 3259 final String resultWho = r.resultWho; 3260 final int requestCode = r.requestCode; 3261 r.resultTo = null; 3262 if (resultTo != null) { 3263 resultTo.removeResultsLocked(r, resultWho, requestCode); 3264 } 3265 3266 final long origId = Binder.clearCallingIdentity(); 3267 int res = mStackSupervisor.startActivityLocked(r.app.thread, intent, 3268 r.resolvedType, aInfo, resultTo != null ? resultTo.appToken : null, 3269 resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage, 0, 3270 options, false, null, null); 3271 Binder.restoreCallingIdentity(origId); 3272 3273 r.finishing = wasFinishing; 3274 if (res != ActivityManager.START_SUCCESS) { 3275 return false; 3276 } 3277 return true; 3278 } 3279 } 3280 3281 final int startActivityInPackage(int uid, String callingPackage, 3282 Intent intent, String resolvedType, IBinder resultTo, 3283 String resultWho, int requestCode, int startFlags, Bundle options, int userId) { 3284 3285 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3286 false, true, "startActivityInPackage", null); 3287 3288 // TODO: Switch to user app stacks here. 3289 int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent, resolvedType, 3290 resultTo, resultWho, requestCode, startFlags, 3291 null, null, null, null, options, userId, null); 3292 return ret; 3293 } 3294 3295 @Override 3296 public final int startActivities(IApplicationThread caller, String callingPackage, 3297 Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options, 3298 int userId) { 3299 enforceNotIsolatedCaller("startActivities"); 3300 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3301 false, true, "startActivity", null); 3302 // TODO: Switch to user app stacks here. 3303 int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents, 3304 resolvedTypes, resultTo, options, userId); 3305 return ret; 3306 } 3307 3308 final int startActivitiesInPackage(int uid, String callingPackage, 3309 Intent[] intents, String[] resolvedTypes, IBinder resultTo, 3310 Bundle options, int userId) { 3311 3312 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3313 false, true, "startActivityInPackage", null); 3314 // TODO: Switch to user app stacks here. 3315 int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes, 3316 resultTo, options, userId); 3317 return ret; 3318 } 3319 3320 final void addRecentTaskLocked(TaskRecord task) { 3321 int N = mRecentTasks.size(); 3322 // Quick case: check if the top-most recent task is the same. 3323 if (N > 0 && mRecentTasks.get(0) == task) { 3324 return; 3325 } 3326 // Remove any existing entries that are the same kind of task. 3327 for (int i=0; i<N; i++) { 3328 TaskRecord tr = mRecentTasks.get(i); 3329 if (task.userId == tr.userId 3330 && ((task.affinity != null && task.affinity.equals(tr.affinity)) 3331 || (task.intent != null && task.intent.filterEquals(tr.intent)))) { 3332 tr.disposeThumbnail(); 3333 mRecentTasks.remove(i); 3334 i--; 3335 N--; 3336 if (task.intent == null) { 3337 // If the new recent task we are adding is not fully 3338 // specified, then replace it with the existing recent task. 3339 task = tr; 3340 } 3341 } 3342 } 3343 if (N >= MAX_RECENT_TASKS) { 3344 mRecentTasks.remove(N-1).disposeThumbnail(); 3345 } 3346 mRecentTasks.add(0, task); 3347 } 3348 3349 @Override 3350 public void reportActivityFullyDrawn(IBinder token) { 3351 synchronized (this) { 3352 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3353 if (r == null) { 3354 return; 3355 } 3356 r.reportFullyDrawnLocked(); 3357 } 3358 } 3359 3360 @Override 3361 public void setRequestedOrientation(IBinder token, int requestedOrientation) { 3362 synchronized (this) { 3363 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3364 if (r == null) { 3365 return; 3366 } 3367 final long origId = Binder.clearCallingIdentity(); 3368 mWindowManager.setAppOrientation(r.appToken, requestedOrientation); 3369 Configuration config = mWindowManager.updateOrientationFromAppTokens( 3370 mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null); 3371 if (config != null) { 3372 r.frozenBeforeDestroy = true; 3373 if (!updateConfigurationLocked(config, r, false, false)) { 3374 mStackSupervisor.resumeTopActivitiesLocked(); 3375 } 3376 } 3377 Binder.restoreCallingIdentity(origId); 3378 } 3379 } 3380 3381 @Override 3382 public int getRequestedOrientation(IBinder token) { 3383 synchronized (this) { 3384 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3385 if (r == null) { 3386 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; 3387 } 3388 return mWindowManager.getAppOrientation(r.appToken); 3389 } 3390 } 3391 3392 /** 3393 * This is the internal entry point for handling Activity.finish(). 3394 * 3395 * @param token The Binder token referencing the Activity we want to finish. 3396 * @param resultCode Result code, if any, from this Activity. 3397 * @param resultData Result data (Intent), if any, from this Activity. 3398 * 3399 * @return Returns true if the activity successfully finished, or false if it is still running. 3400 */ 3401 @Override 3402 public final boolean finishActivity(IBinder token, int resultCode, Intent resultData) { 3403 // Refuse possible leaked file descriptors 3404 if (resultData != null && resultData.hasFileDescriptors() == true) { 3405 throw new IllegalArgumentException("File descriptors passed in Intent"); 3406 } 3407 3408 synchronized(this) { 3409 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3410 if (r == null) { 3411 return true; 3412 } 3413 if (mController != null) { 3414 // Find the first activity that is not finishing. 3415 ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0); 3416 if (next != null) { 3417 // ask watcher if this is allowed 3418 boolean resumeOK = true; 3419 try { 3420 resumeOK = mController.activityResuming(next.packageName); 3421 } catch (RemoteException e) { 3422 mController = null; 3423 Watchdog.getInstance().setActivityController(null); 3424 } 3425 3426 if (!resumeOK) { 3427 return false; 3428 } 3429 } 3430 } 3431 final long origId = Binder.clearCallingIdentity(); 3432 boolean res = r.task.stack.requestFinishActivityLocked(token, resultCode, 3433 resultData, "app-request", true); 3434 Binder.restoreCallingIdentity(origId); 3435 return res; 3436 } 3437 } 3438 3439 @Override 3440 public final void finishHeavyWeightApp() { 3441 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 3442 != PackageManager.PERMISSION_GRANTED) { 3443 String msg = "Permission Denial: finishHeavyWeightApp() from pid=" 3444 + Binder.getCallingPid() 3445 + ", uid=" + Binder.getCallingUid() 3446 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 3447 Slog.w(TAG, msg); 3448 throw new SecurityException(msg); 3449 } 3450 3451 synchronized(this) { 3452 if (mHeavyWeightProcess == null) { 3453 return; 3454 } 3455 3456 ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>( 3457 mHeavyWeightProcess.activities); 3458 for (int i=0; i<activities.size(); i++) { 3459 ActivityRecord r = activities.get(i); 3460 if (!r.finishing) { 3461 r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED, 3462 null, "finish-heavy", true); 3463 } 3464 } 3465 3466 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 3467 mHeavyWeightProcess.userId, 0)); 3468 mHeavyWeightProcess = null; 3469 } 3470 } 3471 3472 @Override 3473 public void crashApplication(int uid, int initialPid, String packageName, 3474 String message) { 3475 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 3476 != PackageManager.PERMISSION_GRANTED) { 3477 String msg = "Permission Denial: crashApplication() from pid=" 3478 + Binder.getCallingPid() 3479 + ", uid=" + Binder.getCallingUid() 3480 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 3481 Slog.w(TAG, msg); 3482 throw new SecurityException(msg); 3483 } 3484 3485 synchronized(this) { 3486 ProcessRecord proc = null; 3487 3488 // Figure out which process to kill. We don't trust that initialPid 3489 // still has any relation to current pids, so must scan through the 3490 // list. 3491 synchronized (mPidsSelfLocked) { 3492 for (int i=0; i<mPidsSelfLocked.size(); i++) { 3493 ProcessRecord p = mPidsSelfLocked.valueAt(i); 3494 if (p.uid != uid) { 3495 continue; 3496 } 3497 if (p.pid == initialPid) { 3498 proc = p; 3499 break; 3500 } 3501 if (p.pkgList.containsKey(packageName)) { 3502 proc = p; 3503 } 3504 } 3505 } 3506 3507 if (proc == null) { 3508 Slog.w(TAG, "crashApplication: nothing for uid=" + uid 3509 + " initialPid=" + initialPid 3510 + " packageName=" + packageName); 3511 return; 3512 } 3513 3514 if (proc.thread != null) { 3515 if (proc.pid == Process.myPid()) { 3516 Log.w(TAG, "crashApplication: trying to crash self!"); 3517 return; 3518 } 3519 long ident = Binder.clearCallingIdentity(); 3520 try { 3521 proc.thread.scheduleCrash(message); 3522 } catch (RemoteException e) { 3523 } 3524 Binder.restoreCallingIdentity(ident); 3525 } 3526 } 3527 } 3528 3529 @Override 3530 public final void finishSubActivity(IBinder token, String resultWho, 3531 int requestCode) { 3532 synchronized(this) { 3533 final long origId = Binder.clearCallingIdentity(); 3534 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3535 if (r != null) { 3536 r.task.stack.finishSubActivityLocked(r, resultWho, requestCode); 3537 } 3538 Binder.restoreCallingIdentity(origId); 3539 } 3540 } 3541 3542 @Override 3543 public boolean finishActivityAffinity(IBinder token) { 3544 synchronized(this) { 3545 final long origId = Binder.clearCallingIdentity(); 3546 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3547 boolean res = false; 3548 if (r != null) { 3549 res = r.task.stack.finishActivityAffinityLocked(r); 3550 } 3551 Binder.restoreCallingIdentity(origId); 3552 return res; 3553 } 3554 } 3555 3556 @Override 3557 public boolean willActivityBeVisible(IBinder token) { 3558 synchronized(this) { 3559 ActivityStack stack = ActivityRecord.getStackLocked(token); 3560 if (stack != null) { 3561 return stack.willActivityBeVisibleLocked(token); 3562 } 3563 return false; 3564 } 3565 } 3566 3567 @Override 3568 public void overridePendingTransition(IBinder token, String packageName, 3569 int enterAnim, int exitAnim) { 3570 synchronized(this) { 3571 ActivityRecord self = ActivityRecord.isInStackLocked(token); 3572 if (self == null) { 3573 return; 3574 } 3575 3576 final long origId = Binder.clearCallingIdentity(); 3577 3578 if (self.state == ActivityState.RESUMED 3579 || self.state == ActivityState.PAUSING) { 3580 mWindowManager.overridePendingAppTransition(packageName, 3581 enterAnim, exitAnim, null); 3582 } 3583 3584 Binder.restoreCallingIdentity(origId); 3585 } 3586 } 3587 3588 /** 3589 * Main function for removing an existing process from the activity manager 3590 * as a result of that process going away. Clears out all connections 3591 * to the process. 3592 */ 3593 private final void handleAppDiedLocked(ProcessRecord app, 3594 boolean restarting, boolean allowRestart) { 3595 cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1); 3596 if (!restarting) { 3597 removeLruProcessLocked(app); 3598 } 3599 3600 if (mProfileProc == app) { 3601 clearProfilerLocked(); 3602 } 3603 3604 // Remove this application's activities from active lists. 3605 boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app); 3606 3607 app.activities.clear(); 3608 3609 if (app.instrumentationClass != null) { 3610 Slog.w(TAG, "Crash of app " + app.processName 3611 + " running instrumentation " + app.instrumentationClass); 3612 Bundle info = new Bundle(); 3613 info.putString("shortMsg", "Process crashed."); 3614 finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info); 3615 } 3616 3617 if (!restarting) { 3618 if (!mStackSupervisor.resumeTopActivitiesLocked()) { 3619 // If there was nothing to resume, and we are not already 3620 // restarting this process, but there is a visible activity that 3621 // is hosted by the process... then make sure all visible 3622 // activities are running, taking care of restarting this 3623 // process. 3624 if (hasVisibleActivities) { 3625 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 3626 } 3627 } 3628 } 3629 } 3630 3631 private final int getLRURecordIndexForAppLocked(IApplicationThread thread) { 3632 IBinder threadBinder = thread.asBinder(); 3633 // Find the application record. 3634 for (int i=mLruProcesses.size()-1; i>=0; i--) { 3635 ProcessRecord rec = mLruProcesses.get(i); 3636 if (rec.thread != null && rec.thread.asBinder() == threadBinder) { 3637 return i; 3638 } 3639 } 3640 return -1; 3641 } 3642 3643 final ProcessRecord getRecordForAppLocked( 3644 IApplicationThread thread) { 3645 if (thread == null) { 3646 return null; 3647 } 3648 3649 int appIndex = getLRURecordIndexForAppLocked(thread); 3650 return appIndex >= 0 ? mLruProcesses.get(appIndex) : null; 3651 } 3652 3653 final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) { 3654 // If there are no longer any background processes running, 3655 // and the app that died was not running instrumentation, 3656 // then tell everyone we are now low on memory. 3657 boolean haveBg = false; 3658 for (int i=mLruProcesses.size()-1; i>=0; i--) { 3659 ProcessRecord rec = mLruProcesses.get(i); 3660 if (rec.thread != null 3661 && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 3662 haveBg = true; 3663 break; 3664 } 3665 } 3666 3667 if (!haveBg) { 3668 boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 3669 if (doReport) { 3670 long now = SystemClock.uptimeMillis(); 3671 if (now < (mLastMemUsageReportTime+5*60*1000)) { 3672 doReport = false; 3673 } else { 3674 mLastMemUsageReportTime = now; 3675 } 3676 } 3677 final ArrayList<ProcessMemInfo> memInfos 3678 = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null; 3679 EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size()); 3680 long now = SystemClock.uptimeMillis(); 3681 for (int i=mLruProcesses.size()-1; i>=0; i--) { 3682 ProcessRecord rec = mLruProcesses.get(i); 3683 if (rec == dyingProc || rec.thread == null) { 3684 continue; 3685 } 3686 if (doReport) { 3687 memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj, 3688 rec.setProcState, rec.adjType, rec.makeAdjReason())); 3689 } 3690 if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) { 3691 // The low memory report is overriding any current 3692 // state for a GC request. Make sure to do 3693 // heavy/important/visible/foreground processes first. 3694 if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 3695 rec.lastRequestedGc = 0; 3696 } else { 3697 rec.lastRequestedGc = rec.lastLowMemory; 3698 } 3699 rec.reportLowMemory = true; 3700 rec.lastLowMemory = now; 3701 mProcessesToGc.remove(rec); 3702 addProcessToGcListLocked(rec); 3703 } 3704 } 3705 if (doReport) { 3706 Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos); 3707 mHandler.sendMessage(msg); 3708 } 3709 scheduleAppGcsLocked(); 3710 } 3711 } 3712 3713 final void appDiedLocked(ProcessRecord app, int pid, 3714 IApplicationThread thread) { 3715 3716 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 3717 synchronized (stats) { 3718 stats.noteProcessDiedLocked(app.info.uid, pid); 3719 } 3720 3721 // Clean up already done if the process has been re-started. 3722 if (app.pid == pid && app.thread != null && 3723 app.thread.asBinder() == thread.asBinder()) { 3724 boolean doLowMem = app.instrumentationClass == null; 3725 boolean doOomAdj = doLowMem; 3726 if (!app.killedByAm) { 3727 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 3728 + ") has died."); 3729 mAllowLowerMemLevel = true; 3730 } else { 3731 // Note that we always want to do oom adj to update our state with the 3732 // new number of procs. 3733 mAllowLowerMemLevel = false; 3734 doLowMem = false; 3735 } 3736 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName); 3737 if (DEBUG_CLEANUP) Slog.v( 3738 TAG, "Dying app: " + app + ", pid: " + pid 3739 + ", thread: " + thread.asBinder()); 3740 handleAppDiedLocked(app, false, true); 3741 3742 if (doOomAdj) { 3743 updateOomAdjLocked(); 3744 } 3745 if (doLowMem) { 3746 doLowMemReportIfNeededLocked(app); 3747 } 3748 } else if (app.pid != pid) { 3749 // A new process has already been started. 3750 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 3751 + ") has died and restarted (pid " + app.pid + ")."); 3752 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName); 3753 } else if (DEBUG_PROCESSES) { 3754 Slog.d(TAG, "Received spurious death notification for thread " 3755 + thread.asBinder()); 3756 } 3757 } 3758 3759 /** 3760 * If a stack trace dump file is configured, dump process stack traces. 3761 * @param clearTraces causes the dump file to be erased prior to the new 3762 * traces being written, if true; when false, the new traces will be 3763 * appended to any existing file content. 3764 * @param firstPids of dalvik VM processes to dump stack traces for first 3765 * @param lastPids of dalvik VM processes to dump stack traces for last 3766 * @param nativeProcs optional list of native process names to dump stack crawls 3767 * @return file containing stack traces, or null if no dump file is configured 3768 */ 3769 public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids, 3770 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) { 3771 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 3772 if (tracesPath == null || tracesPath.length() == 0) { 3773 return null; 3774 } 3775 3776 File tracesFile = new File(tracesPath); 3777 try { 3778 File tracesDir = tracesFile.getParentFile(); 3779 if (!tracesDir.exists()) { 3780 tracesFile.mkdirs(); 3781 if (!SELinux.restorecon(tracesDir)) { 3782 return null; 3783 } 3784 } 3785 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 3786 3787 if (clearTraces && tracesFile.exists()) tracesFile.delete(); 3788 tracesFile.createNewFile(); 3789 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 3790 } catch (IOException e) { 3791 Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e); 3792 return null; 3793 } 3794 3795 dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs); 3796 return tracesFile; 3797 } 3798 3799 private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids, 3800 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) { 3801 // Use a FileObserver to detect when traces finish writing. 3802 // The order of traces is considered important to maintain for legibility. 3803 FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) { 3804 @Override 3805 public synchronized void onEvent(int event, String path) { notify(); } 3806 }; 3807 3808 try { 3809 observer.startWatching(); 3810 3811 // First collect all of the stacks of the most important pids. 3812 if (firstPids != null) { 3813 try { 3814 int num = firstPids.size(); 3815 for (int i = 0; i < num; i++) { 3816 synchronized (observer) { 3817 Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT); 3818 observer.wait(200); // Wait for write-close, give up after 200msec 3819 } 3820 } 3821 } catch (InterruptedException e) { 3822 Log.wtf(TAG, e); 3823 } 3824 } 3825 3826 // Next collect the stacks of the native pids 3827 if (nativeProcs != null) { 3828 int[] pids = Process.getPidsForCommands(nativeProcs); 3829 if (pids != null) { 3830 for (int pid : pids) { 3831 Debug.dumpNativeBacktraceToFile(pid, tracesPath); 3832 } 3833 } 3834 } 3835 3836 // Lastly, measure CPU usage. 3837 if (processCpuTracker != null) { 3838 processCpuTracker.init(); 3839 System.gc(); 3840 processCpuTracker.update(); 3841 try { 3842 synchronized (processCpuTracker) { 3843 processCpuTracker.wait(500); // measure over 1/2 second. 3844 } 3845 } catch (InterruptedException e) { 3846 } 3847 processCpuTracker.update(); 3848 3849 // We'll take the stack crawls of just the top apps using CPU. 3850 final int N = processCpuTracker.countWorkingStats(); 3851 int numProcs = 0; 3852 for (int i=0; i<N && numProcs<5; i++) { 3853 ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i); 3854 if (lastPids.indexOfKey(stats.pid) >= 0) { 3855 numProcs++; 3856 try { 3857 synchronized (observer) { 3858 Process.sendSignal(stats.pid, Process.SIGNAL_QUIT); 3859 observer.wait(200); // Wait for write-close, give up after 200msec 3860 } 3861 } catch (InterruptedException e) { 3862 Log.wtf(TAG, e); 3863 } 3864 3865 } 3866 } 3867 } 3868 } finally { 3869 observer.stopWatching(); 3870 } 3871 } 3872 3873 final void logAppTooSlow(ProcessRecord app, long startTime, String msg) { 3874 if (true || IS_USER_BUILD) { 3875 return; 3876 } 3877 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 3878 if (tracesPath == null || tracesPath.length() == 0) { 3879 return; 3880 } 3881 3882 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads(); 3883 StrictMode.allowThreadDiskWrites(); 3884 try { 3885 final File tracesFile = new File(tracesPath); 3886 final File tracesDir = tracesFile.getParentFile(); 3887 final File tracesTmp = new File(tracesDir, "__tmp__"); 3888 try { 3889 if (!tracesDir.exists()) { 3890 tracesFile.mkdirs(); 3891 if (!SELinux.restorecon(tracesDir.getPath())) { 3892 return; 3893 } 3894 } 3895 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 3896 3897 if (tracesFile.exists()) { 3898 tracesTmp.delete(); 3899 tracesFile.renameTo(tracesTmp); 3900 } 3901 StringBuilder sb = new StringBuilder(); 3902 Time tobj = new Time(); 3903 tobj.set(System.currentTimeMillis()); 3904 sb.append(tobj.format("%Y-%m-%d %H:%M:%S")); 3905 sb.append(": "); 3906 TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb); 3907 sb.append(" since "); 3908 sb.append(msg); 3909 FileOutputStream fos = new FileOutputStream(tracesFile); 3910 fos.write(sb.toString().getBytes()); 3911 if (app == null) { 3912 fos.write("\n*** No application process!".getBytes()); 3913 } 3914 fos.close(); 3915 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 3916 } catch (IOException e) { 3917 Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e); 3918 return; 3919 } 3920 3921 if (app != null) { 3922 ArrayList<Integer> firstPids = new ArrayList<Integer>(); 3923 firstPids.add(app.pid); 3924 dumpStackTraces(tracesPath, firstPids, null, null, null); 3925 } 3926 3927 File lastTracesFile = null; 3928 File curTracesFile = null; 3929 for (int i=9; i>=0; i--) { 3930 String name = String.format(Locale.US, "slow%02d.txt", i); 3931 curTracesFile = new File(tracesDir, name); 3932 if (curTracesFile.exists()) { 3933 if (lastTracesFile != null) { 3934 curTracesFile.renameTo(lastTracesFile); 3935 } else { 3936 curTracesFile.delete(); 3937 } 3938 } 3939 lastTracesFile = curTracesFile; 3940 } 3941 tracesFile.renameTo(curTracesFile); 3942 if (tracesTmp.exists()) { 3943 tracesTmp.renameTo(tracesFile); 3944 } 3945 } finally { 3946 StrictMode.setThreadPolicy(oldPolicy); 3947 } 3948 } 3949 3950 final void appNotResponding(ProcessRecord app, ActivityRecord activity, 3951 ActivityRecord parent, boolean aboveSystem, final String annotation) { 3952 ArrayList<Integer> firstPids = new ArrayList<Integer>(5); 3953 SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20); 3954 3955 if (mController != null) { 3956 try { 3957 // 0 == continue, -1 = kill process immediately 3958 int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation); 3959 if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid); 3960 } catch (RemoteException e) { 3961 mController = null; 3962 Watchdog.getInstance().setActivityController(null); 3963 } 3964 } 3965 3966 long anrTime = SystemClock.uptimeMillis(); 3967 if (MONITOR_CPU_USAGE) { 3968 updateCpuStatsNow(); 3969 } 3970 3971 synchronized (this) { 3972 // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down. 3973 if (mShuttingDown) { 3974 Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation); 3975 return; 3976 } else if (app.notResponding) { 3977 Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation); 3978 return; 3979 } else if (app.crashing) { 3980 Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation); 3981 return; 3982 } 3983 3984 // In case we come through here for the same app before completing 3985 // this one, mark as anring now so we will bail out. 3986 app.notResponding = true; 3987 3988 // Log the ANR to the event log. 3989 EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid, 3990 app.processName, app.info.flags, annotation); 3991 3992 // Dump thread traces as quickly as we can, starting with "interesting" processes. 3993 firstPids.add(app.pid); 3994 3995 int parentPid = app.pid; 3996 if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid; 3997 if (parentPid != app.pid) firstPids.add(parentPid); 3998 3999 if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID); 4000 4001 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 4002 ProcessRecord r = mLruProcesses.get(i); 4003 if (r != null && r.thread != null) { 4004 int pid = r.pid; 4005 if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) { 4006 if (r.persistent) { 4007 firstPids.add(pid); 4008 } else { 4009 lastPids.put(pid, Boolean.TRUE); 4010 } 4011 } 4012 } 4013 } 4014 } 4015 4016 // Log the ANR to the main log. 4017 StringBuilder info = new StringBuilder(); 4018 info.setLength(0); 4019 info.append("ANR in ").append(app.processName); 4020 if (activity != null && activity.shortComponentName != null) { 4021 info.append(" (").append(activity.shortComponentName).append(")"); 4022 } 4023 info.append("\n"); 4024 info.append("PID: ").append(app.pid).append("\n"); 4025 if (annotation != null) { 4026 info.append("Reason: ").append(annotation).append("\n"); 4027 } 4028 if (parent != null && parent != activity) { 4029 info.append("Parent: ").append(parent.shortComponentName).append("\n"); 4030 } 4031 4032 final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true); 4033 4034 File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids, 4035 NATIVE_STACKS_OF_INTEREST); 4036 4037 String cpuInfo = null; 4038 if (MONITOR_CPU_USAGE) { 4039 updateCpuStatsNow(); 4040 synchronized (mProcessCpuThread) { 4041 cpuInfo = mProcessCpuTracker.printCurrentState(anrTime); 4042 } 4043 info.append(processCpuTracker.printCurrentLoad()); 4044 info.append(cpuInfo); 4045 } 4046 4047 info.append(processCpuTracker.printCurrentState(anrTime)); 4048 4049 Slog.e(TAG, info.toString()); 4050 if (tracesFile == null) { 4051 // There is no trace file, so dump (only) the alleged culprit's threads to the log 4052 Process.sendSignal(app.pid, Process.SIGNAL_QUIT); 4053 } 4054 4055 addErrorToDropBox("anr", app, app.processName, activity, parent, annotation, 4056 cpuInfo, tracesFile, null); 4057 4058 if (mController != null) { 4059 try { 4060 // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately 4061 int res = mController.appNotResponding(app.processName, app.pid, info.toString()); 4062 if (res != 0) { 4063 if (res < 0 && app.pid != MY_PID) { 4064 Process.killProcess(app.pid); 4065 } else { 4066 synchronized (this) { 4067 mServices.scheduleServiceTimeoutLocked(app); 4068 } 4069 } 4070 return; 4071 } 4072 } catch (RemoteException e) { 4073 mController = null; 4074 Watchdog.getInstance().setActivityController(null); 4075 } 4076 } 4077 4078 // Unless configured otherwise, swallow ANRs in background processes & kill the process. 4079 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), 4080 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; 4081 4082 synchronized (this) { 4083 if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) { 4084 killUnneededProcessLocked(app, "background ANR"); 4085 return; 4086 } 4087 4088 // Set the app's notResponding state, and look up the errorReportReceiver 4089 makeAppNotRespondingLocked(app, 4090 activity != null ? activity.shortComponentName : null, 4091 annotation != null ? "ANR " + annotation : "ANR", 4092 info.toString()); 4093 4094 // Bring up the infamous App Not Responding dialog 4095 Message msg = Message.obtain(); 4096 HashMap<String, Object> map = new HashMap<String, Object>(); 4097 msg.what = SHOW_NOT_RESPONDING_MSG; 4098 msg.obj = map; 4099 msg.arg1 = aboveSystem ? 1 : 0; 4100 map.put("app", app); 4101 if (activity != null) { 4102 map.put("activity", activity); 4103 } 4104 4105 mHandler.sendMessage(msg); 4106 } 4107 } 4108 4109 final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) { 4110 if (!mLaunchWarningShown) { 4111 mLaunchWarningShown = true; 4112 mHandler.post(new Runnable() { 4113 @Override 4114 public void run() { 4115 synchronized (ActivityManagerService.this) { 4116 final Dialog d = new LaunchWarningWindow(mContext, cur, next); 4117 d.show(); 4118 mHandler.postDelayed(new Runnable() { 4119 @Override 4120 public void run() { 4121 synchronized (ActivityManagerService.this) { 4122 d.dismiss(); 4123 mLaunchWarningShown = false; 4124 } 4125 } 4126 }, 4000); 4127 } 4128 } 4129 }); 4130 } 4131 } 4132 4133 @Override 4134 public boolean clearApplicationUserData(final String packageName, 4135 final IPackageDataObserver observer, int userId) { 4136 enforceNotIsolatedCaller("clearApplicationUserData"); 4137 int uid = Binder.getCallingUid(); 4138 int pid = Binder.getCallingPid(); 4139 userId = handleIncomingUser(pid, uid, 4140 userId, false, true, "clearApplicationUserData", null); 4141 long callingId = Binder.clearCallingIdentity(); 4142 try { 4143 IPackageManager pm = AppGlobals.getPackageManager(); 4144 int pkgUid = -1; 4145 synchronized(this) { 4146 try { 4147 pkgUid = pm.getPackageUid(packageName, userId); 4148 } catch (RemoteException e) { 4149 } 4150 if (pkgUid == -1) { 4151 Slog.w(TAG, "Invalid packageName: " + packageName); 4152 if (observer != null) { 4153 try { 4154 observer.onRemoveCompleted(packageName, false); 4155 } catch (RemoteException e) { 4156 Slog.i(TAG, "Observer no longer exists."); 4157 } 4158 } 4159 return false; 4160 } 4161 if (uid == pkgUid || checkComponentPermission( 4162 android.Manifest.permission.CLEAR_APP_USER_DATA, 4163 pid, uid, -1, true) 4164 == PackageManager.PERMISSION_GRANTED) { 4165 forceStopPackageLocked(packageName, pkgUid, "clear data"); 4166 } else { 4167 throw new SecurityException("PID " + pid + " does not have permission " 4168 + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data" 4169 + " of package " + packageName); 4170 } 4171 } 4172 4173 try { 4174 // Clear application user data 4175 pm.clearApplicationUserData(packageName, observer, userId); 4176 4177 // Remove all permissions granted from/to this package 4178 removeUriPermissionsForPackageLocked(packageName, userId, true); 4179 4180 Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED, 4181 Uri.fromParts("package", packageName, null)); 4182 intent.putExtra(Intent.EXTRA_UID, pkgUid); 4183 broadcastIntentInPackage("android", Process.SYSTEM_UID, intent, 4184 null, null, 0, null, null, null, false, false, userId); 4185 } catch (RemoteException e) { 4186 } 4187 } finally { 4188 Binder.restoreCallingIdentity(callingId); 4189 } 4190 return true; 4191 } 4192 4193 @Override 4194 public void killBackgroundProcesses(final String packageName, int userId) { 4195 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 4196 != PackageManager.PERMISSION_GRANTED && 4197 checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES) 4198 != PackageManager.PERMISSION_GRANTED) { 4199 String msg = "Permission Denial: killBackgroundProcesses() from pid=" 4200 + Binder.getCallingPid() 4201 + ", uid=" + Binder.getCallingUid() 4202 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 4203 Slog.w(TAG, msg); 4204 throw new SecurityException(msg); 4205 } 4206 4207 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 4208 userId, true, true, "killBackgroundProcesses", null); 4209 long callingId = Binder.clearCallingIdentity(); 4210 try { 4211 IPackageManager pm = AppGlobals.getPackageManager(); 4212 synchronized(this) { 4213 int appId = -1; 4214 try { 4215 appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0)); 4216 } catch (RemoteException e) { 4217 } 4218 if (appId == -1) { 4219 Slog.w(TAG, "Invalid packageName: " + packageName); 4220 return; 4221 } 4222 killPackageProcessesLocked(packageName, appId, userId, 4223 ProcessList.SERVICE_ADJ, false, true, true, false, "kill background"); 4224 } 4225 } finally { 4226 Binder.restoreCallingIdentity(callingId); 4227 } 4228 } 4229 4230 @Override 4231 public void killAllBackgroundProcesses() { 4232 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 4233 != PackageManager.PERMISSION_GRANTED) { 4234 String msg = "Permission Denial: killAllBackgroundProcesses() from pid=" 4235 + Binder.getCallingPid() 4236 + ", uid=" + Binder.getCallingUid() 4237 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 4238 Slog.w(TAG, msg); 4239 throw new SecurityException(msg); 4240 } 4241 4242 long callingId = Binder.clearCallingIdentity(); 4243 try { 4244 synchronized(this) { 4245 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 4246 final int NP = mProcessNames.getMap().size(); 4247 for (int ip=0; ip<NP; ip++) { 4248 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 4249 final int NA = apps.size(); 4250 for (int ia=0; ia<NA; ia++) { 4251 ProcessRecord app = apps.valueAt(ia); 4252 if (app.persistent) { 4253 // we don't kill persistent processes 4254 continue; 4255 } 4256 if (app.removed) { 4257 procs.add(app); 4258 } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 4259 app.removed = true; 4260 procs.add(app); 4261 } 4262 } 4263 } 4264 4265 int N = procs.size(); 4266 for (int i=0; i<N; i++) { 4267 removeProcessLocked(procs.get(i), false, true, "kill all background"); 4268 } 4269 mAllowLowerMemLevel = true; 4270 updateOomAdjLocked(); 4271 doLowMemReportIfNeededLocked(null); 4272 } 4273 } finally { 4274 Binder.restoreCallingIdentity(callingId); 4275 } 4276 } 4277 4278 @Override 4279 public void forceStopPackage(final String packageName, int userId) { 4280 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 4281 != PackageManager.PERMISSION_GRANTED) { 4282 String msg = "Permission Denial: forceStopPackage() from pid=" 4283 + Binder.getCallingPid() 4284 + ", uid=" + Binder.getCallingUid() 4285 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 4286 Slog.w(TAG, msg); 4287 throw new SecurityException(msg); 4288 } 4289 final int callingPid = Binder.getCallingPid(); 4290 userId = handleIncomingUser(callingPid, Binder.getCallingUid(), 4291 userId, true, true, "forceStopPackage", null); 4292 long callingId = Binder.clearCallingIdentity(); 4293 try { 4294 IPackageManager pm = AppGlobals.getPackageManager(); 4295 synchronized(this) { 4296 int[] users = userId == UserHandle.USER_ALL 4297 ? getUsersLocked() : new int[] { userId }; 4298 for (int user : users) { 4299 int pkgUid = -1; 4300 try { 4301 pkgUid = pm.getPackageUid(packageName, user); 4302 } catch (RemoteException e) { 4303 } 4304 if (pkgUid == -1) { 4305 Slog.w(TAG, "Invalid packageName: " + packageName); 4306 continue; 4307 } 4308 try { 4309 pm.setPackageStoppedState(packageName, true, user); 4310 } catch (RemoteException e) { 4311 } catch (IllegalArgumentException e) { 4312 Slog.w(TAG, "Failed trying to unstop package " 4313 + packageName + ": " + e); 4314 } 4315 if (isUserRunningLocked(user, false)) { 4316 forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid); 4317 } 4318 } 4319 } 4320 } finally { 4321 Binder.restoreCallingIdentity(callingId); 4322 } 4323 } 4324 4325 /* 4326 * The pkg name and app id have to be specified. 4327 */ 4328 @Override 4329 public void killApplicationWithAppId(String pkg, int appid, String reason) { 4330 if (pkg == null) { 4331 return; 4332 } 4333 // Make sure the uid is valid. 4334 if (appid < 0) { 4335 Slog.w(TAG, "Invalid appid specified for pkg : " + pkg); 4336 return; 4337 } 4338 int callerUid = Binder.getCallingUid(); 4339 // Only the system server can kill an application 4340 if (callerUid == Process.SYSTEM_UID) { 4341 // Post an aysnc message to kill the application 4342 Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG); 4343 msg.arg1 = appid; 4344 msg.arg2 = 0; 4345 Bundle bundle = new Bundle(); 4346 bundle.putString("pkg", pkg); 4347 bundle.putString("reason", reason); 4348 msg.obj = bundle; 4349 mHandler.sendMessage(msg); 4350 } else { 4351 throw new SecurityException(callerUid + " cannot kill pkg: " + 4352 pkg); 4353 } 4354 } 4355 4356 @Override 4357 public void closeSystemDialogs(String reason) { 4358 enforceNotIsolatedCaller("closeSystemDialogs"); 4359 4360 final int pid = Binder.getCallingPid(); 4361 final int uid = Binder.getCallingUid(); 4362 final long origId = Binder.clearCallingIdentity(); 4363 try { 4364 synchronized (this) { 4365 // Only allow this from foreground processes, so that background 4366 // applications can't abuse it to prevent system UI from being shown. 4367 if (uid >= Process.FIRST_APPLICATION_UID) { 4368 ProcessRecord proc; 4369 synchronized (mPidsSelfLocked) { 4370 proc = mPidsSelfLocked.get(pid); 4371 } 4372 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 4373 Slog.w(TAG, "Ignoring closeSystemDialogs " + reason 4374 + " from background process " + proc); 4375 return; 4376 } 4377 } 4378 closeSystemDialogsLocked(reason); 4379 } 4380 } finally { 4381 Binder.restoreCallingIdentity(origId); 4382 } 4383 } 4384 4385 void closeSystemDialogsLocked(String reason) { 4386 Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS); 4387 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 4388 | Intent.FLAG_RECEIVER_FOREGROUND); 4389 if (reason != null) { 4390 intent.putExtra("reason", reason); 4391 } 4392 mWindowManager.closeSystemDialogs(reason); 4393 4394 mStackSupervisor.closeSystemDialogsLocked(); 4395 4396 broadcastIntentLocked(null, null, intent, null, 4397 null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1, 4398 Process.SYSTEM_UID, UserHandle.USER_ALL); 4399 } 4400 4401 @Override 4402 public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) { 4403 enforceNotIsolatedCaller("getProcessMemoryInfo"); 4404 Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length]; 4405 for (int i=pids.length-1; i>=0; i--) { 4406 ProcessRecord proc; 4407 int oomAdj; 4408 synchronized (this) { 4409 synchronized (mPidsSelfLocked) { 4410 proc = mPidsSelfLocked.get(pids[i]); 4411 oomAdj = proc != null ? proc.setAdj : 0; 4412 } 4413 } 4414 infos[i] = new Debug.MemoryInfo(); 4415 Debug.getMemoryInfo(pids[i], infos[i]); 4416 if (proc != null) { 4417 synchronized (this) { 4418 if (proc.thread != null && proc.setAdj == oomAdj) { 4419 // Record this for posterity if the process has been stable. 4420 proc.baseProcessTracker.addPss(infos[i].getTotalPss(), 4421 infos[i].getTotalUss(), false, proc.pkgList); 4422 } 4423 } 4424 } 4425 } 4426 return infos; 4427 } 4428 4429 @Override 4430 public long[] getProcessPss(int[] pids) { 4431 enforceNotIsolatedCaller("getProcessPss"); 4432 long[] pss = new long[pids.length]; 4433 for (int i=pids.length-1; i>=0; i--) { 4434 ProcessRecord proc; 4435 int oomAdj; 4436 synchronized (this) { 4437 synchronized (mPidsSelfLocked) { 4438 proc = mPidsSelfLocked.get(pids[i]); 4439 oomAdj = proc != null ? proc.setAdj : 0; 4440 } 4441 } 4442 long[] tmpUss = new long[1]; 4443 pss[i] = Debug.getPss(pids[i], tmpUss); 4444 if (proc != null) { 4445 synchronized (this) { 4446 if (proc.thread != null && proc.setAdj == oomAdj) { 4447 // Record this for posterity if the process has been stable. 4448 proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList); 4449 } 4450 } 4451 } 4452 } 4453 return pss; 4454 } 4455 4456 @Override 4457 public void killApplicationProcess(String processName, int uid) { 4458 if (processName == null) { 4459 return; 4460 } 4461 4462 int callerUid = Binder.getCallingUid(); 4463 // Only the system server can kill an application 4464 if (callerUid == Process.SYSTEM_UID) { 4465 synchronized (this) { 4466 ProcessRecord app = getProcessRecordLocked(processName, uid, true); 4467 if (app != null && app.thread != null) { 4468 try { 4469 app.thread.scheduleSuicide(); 4470 } catch (RemoteException e) { 4471 // If the other end already died, then our work here is done. 4472 } 4473 } else { 4474 Slog.w(TAG, "Process/uid not found attempting kill of " 4475 + processName + " / " + uid); 4476 } 4477 } 4478 } else { 4479 throw new SecurityException(callerUid + " cannot kill app process: " + 4480 processName); 4481 } 4482 } 4483 4484 private void forceStopPackageLocked(final String packageName, int uid, String reason) { 4485 forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false, 4486 false, true, false, UserHandle.getUserId(uid), reason); 4487 Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED, 4488 Uri.fromParts("package", packageName, null)); 4489 if (!mProcessesReady) { 4490 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 4491 | Intent.FLAG_RECEIVER_FOREGROUND); 4492 } 4493 intent.putExtra(Intent.EXTRA_UID, uid); 4494 intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid)); 4495 broadcastIntentLocked(null, null, intent, 4496 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 4497 false, false, 4498 MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid)); 4499 } 4500 4501 private void forceStopUserLocked(int userId, String reason) { 4502 forceStopPackageLocked(null, -1, false, false, true, false, userId, reason); 4503 Intent intent = new Intent(Intent.ACTION_USER_STOPPED); 4504 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 4505 | Intent.FLAG_RECEIVER_FOREGROUND); 4506 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 4507 broadcastIntentLocked(null, null, intent, 4508 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 4509 false, false, 4510 MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 4511 } 4512 4513 private final boolean killPackageProcessesLocked(String packageName, int appId, 4514 int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart, 4515 boolean doit, boolean evenPersistent, String reason) { 4516 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 4517 4518 // Remove all processes this package may have touched: all with the 4519 // same UID (except for the system or root user), and all whose name 4520 // matches the package name. 4521 final String procNamePrefix = packageName != null ? (packageName + ":") : null; 4522 final int NP = mProcessNames.getMap().size(); 4523 for (int ip=0; ip<NP; ip++) { 4524 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 4525 final int NA = apps.size(); 4526 for (int ia=0; ia<NA; ia++) { 4527 ProcessRecord app = apps.valueAt(ia); 4528 if (app.persistent && !evenPersistent) { 4529 // we don't kill persistent processes 4530 continue; 4531 } 4532 if (app.removed) { 4533 if (doit) { 4534 procs.add(app); 4535 } 4536 continue; 4537 } 4538 4539 // Skip process if it doesn't meet our oom adj requirement. 4540 if (app.setAdj < minOomAdj) { 4541 continue; 4542 } 4543 4544 // If no package is specified, we call all processes under the 4545 // give user id. 4546 if (packageName == null) { 4547 if (app.userId != userId) { 4548 continue; 4549 } 4550 if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) { 4551 continue; 4552 } 4553 // Package has been specified, we want to hit all processes 4554 // that match it. We need to qualify this by the processes 4555 // that are running under the specified app and user ID. 4556 } else { 4557 if (UserHandle.getAppId(app.uid) != appId) { 4558 continue; 4559 } 4560 if (userId != UserHandle.USER_ALL && app.userId != userId) { 4561 continue; 4562 } 4563 if (!app.pkgList.containsKey(packageName)) { 4564 continue; 4565 } 4566 } 4567 4568 // Process has passed all conditions, kill it! 4569 if (!doit) { 4570 return true; 4571 } 4572 app.removed = true; 4573 procs.add(app); 4574 } 4575 } 4576 4577 int N = procs.size(); 4578 for (int i=0; i<N; i++) { 4579 removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason); 4580 } 4581 updateOomAdjLocked(); 4582 return N > 0; 4583 } 4584 4585 private final boolean forceStopPackageLocked(String name, int appId, 4586 boolean callerWillRestart, boolean purgeCache, boolean doit, 4587 boolean evenPersistent, int userId, String reason) { 4588 int i; 4589 int N; 4590 4591 if (userId == UserHandle.USER_ALL && name == null) { 4592 Slog.w(TAG, "Can't force stop all processes of all users, that is insane!"); 4593 } 4594 4595 if (appId < 0 && name != null) { 4596 try { 4597 appId = UserHandle.getAppId( 4598 AppGlobals.getPackageManager().getPackageUid(name, 0)); 4599 } catch (RemoteException e) { 4600 } 4601 } 4602 4603 if (doit) { 4604 if (name != null) { 4605 Slog.i(TAG, "Force stopping " + name + " appid=" + appId 4606 + " user=" + userId + ": " + reason); 4607 } else { 4608 Slog.i(TAG, "Force stopping u" + userId + ": " + reason); 4609 } 4610 4611 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap(); 4612 for (int ip=pmap.size()-1; ip>=0; ip--) { 4613 SparseArray<Long> ba = pmap.valueAt(ip); 4614 for (i=ba.size()-1; i>=0; i--) { 4615 boolean remove = false; 4616 final int entUid = ba.keyAt(i); 4617 if (name != null) { 4618 if (userId == UserHandle.USER_ALL) { 4619 if (UserHandle.getAppId(entUid) == appId) { 4620 remove = true; 4621 } 4622 } else { 4623 if (entUid == UserHandle.getUid(userId, appId)) { 4624 remove = true; 4625 } 4626 } 4627 } else if (UserHandle.getUserId(entUid) == userId) { 4628 remove = true; 4629 } 4630 if (remove) { 4631 ba.removeAt(i); 4632 } 4633 } 4634 if (ba.size() == 0) { 4635 pmap.removeAt(ip); 4636 } 4637 } 4638 } 4639 4640 boolean didSomething = killPackageProcessesLocked(name, appId, userId, 4641 -100, callerWillRestart, true, doit, evenPersistent, 4642 name == null ? ("stop user " + userId) : ("stop " + name)); 4643 4644 if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) { 4645 if (!doit) { 4646 return true; 4647 } 4648 didSomething = true; 4649 } 4650 4651 if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) { 4652 if (!doit) { 4653 return true; 4654 } 4655 didSomething = true; 4656 } 4657 4658 if (name == null) { 4659 // Remove all sticky broadcasts from this user. 4660 mStickyBroadcasts.remove(userId); 4661 } 4662 4663 ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>(); 4664 if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent, 4665 userId, providers)) { 4666 if (!doit) { 4667 return true; 4668 } 4669 didSomething = true; 4670 } 4671 N = providers.size(); 4672 for (i=0; i<N; i++) { 4673 removeDyingProviderLocked(null, providers.get(i), true); 4674 } 4675 4676 // Remove transient permissions granted from/to this package/user 4677 removeUriPermissionsForPackageLocked(name, userId, false); 4678 4679 if (name == null) { 4680 // Remove pending intents. For now we only do this when force 4681 // stopping users, because we have some problems when doing this 4682 // for packages -- app widgets are not currently cleaned up for 4683 // such packages, so they can be left with bad pending intents. 4684 if (mIntentSenderRecords.size() > 0) { 4685 Iterator<WeakReference<PendingIntentRecord>> it 4686 = mIntentSenderRecords.values().iterator(); 4687 while (it.hasNext()) { 4688 WeakReference<PendingIntentRecord> wpir = it.next(); 4689 if (wpir == null) { 4690 it.remove(); 4691 continue; 4692 } 4693 PendingIntentRecord pir = wpir.get(); 4694 if (pir == null) { 4695 it.remove(); 4696 continue; 4697 } 4698 if (name == null) { 4699 // Stopping user, remove all objects for the user. 4700 if (pir.key.userId != userId) { 4701 // Not the same user, skip it. 4702 continue; 4703 } 4704 } else { 4705 if (UserHandle.getAppId(pir.uid) != appId) { 4706 // Different app id, skip it. 4707 continue; 4708 } 4709 if (userId != UserHandle.USER_ALL && pir.key.userId != userId) { 4710 // Different user, skip it. 4711 continue; 4712 } 4713 if (!pir.key.packageName.equals(name)) { 4714 // Different package, skip it. 4715 continue; 4716 } 4717 } 4718 if (!doit) { 4719 return true; 4720 } 4721 didSomething = true; 4722 it.remove(); 4723 pir.canceled = true; 4724 if (pir.key.activity != null) { 4725 pir.key.activity.pendingResults.remove(pir.ref); 4726 } 4727 } 4728 } 4729 } 4730 4731 if (doit) { 4732 if (purgeCache && name != null) { 4733 AttributeCache ac = AttributeCache.instance(); 4734 if (ac != null) { 4735 ac.removePackage(name); 4736 } 4737 } 4738 if (mBooted) { 4739 mStackSupervisor.resumeTopActivitiesLocked(); 4740 mStackSupervisor.scheduleIdleLocked(); 4741 } 4742 } 4743 4744 return didSomething; 4745 } 4746 4747 private final boolean removeProcessLocked(ProcessRecord app, 4748 boolean callerWillRestart, boolean allowRestart, String reason) { 4749 final String name = app.processName; 4750 final int uid = app.uid; 4751 if (DEBUG_PROCESSES) Slog.d( 4752 TAG, "Force removing proc " + app.toShortString() + " (" + name 4753 + "/" + uid + ")"); 4754 4755 mProcessNames.remove(name, uid); 4756 mIsolatedProcesses.remove(app.uid); 4757 if (mHeavyWeightProcess == app) { 4758 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 4759 mHeavyWeightProcess.userId, 0)); 4760 mHeavyWeightProcess = null; 4761 } 4762 boolean needRestart = false; 4763 if (app.pid > 0 && app.pid != MY_PID) { 4764 int pid = app.pid; 4765 synchronized (mPidsSelfLocked) { 4766 mPidsSelfLocked.remove(pid); 4767 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 4768 } 4769 killUnneededProcessLocked(app, reason); 4770 handleAppDiedLocked(app, true, allowRestart); 4771 removeLruProcessLocked(app); 4772 4773 if (app.persistent && !app.isolated) { 4774 if (!callerWillRestart) { 4775 addAppLocked(app.info, false); 4776 } else { 4777 needRestart = true; 4778 } 4779 } 4780 } else { 4781 mRemovedProcesses.add(app); 4782 } 4783 4784 return needRestart; 4785 } 4786 4787 private final void processStartTimedOutLocked(ProcessRecord app) { 4788 final int pid = app.pid; 4789 boolean gone = false; 4790 synchronized (mPidsSelfLocked) { 4791 ProcessRecord knownApp = mPidsSelfLocked.get(pid); 4792 if (knownApp != null && knownApp.thread == null) { 4793 mPidsSelfLocked.remove(pid); 4794 gone = true; 4795 } 4796 } 4797 4798 if (gone) { 4799 Slog.w(TAG, "Process " + app + " failed to attach"); 4800 EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId, 4801 pid, app.uid, app.processName); 4802 mProcessNames.remove(app.processName, app.uid); 4803 mIsolatedProcesses.remove(app.uid); 4804 if (mHeavyWeightProcess == app) { 4805 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 4806 mHeavyWeightProcess.userId, 0)); 4807 mHeavyWeightProcess = null; 4808 } 4809 // Take care of any launching providers waiting for this process. 4810 checkAppInLaunchingProvidersLocked(app, true); 4811 // Take care of any services that are waiting for the process. 4812 mServices.processStartTimedOutLocked(app); 4813 killUnneededProcessLocked(app, "start timeout"); 4814 if (mBackupTarget != null && mBackupTarget.app.pid == pid) { 4815 Slog.w(TAG, "Unattached app died before backup, skipping"); 4816 try { 4817 IBackupManager bm = IBackupManager.Stub.asInterface( 4818 ServiceManager.getService(Context.BACKUP_SERVICE)); 4819 bm.agentDisconnected(app.info.packageName); 4820 } catch (RemoteException e) { 4821 // Can't happen; the backup manager is local 4822 } 4823 } 4824 if (isPendingBroadcastProcessLocked(pid)) { 4825 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 4826 skipPendingBroadcastLocked(pid); 4827 } 4828 } else { 4829 Slog.w(TAG, "Spurious process start timeout - pid not known for " + app); 4830 } 4831 } 4832 4833 private final boolean attachApplicationLocked(IApplicationThread thread, 4834 int pid) { 4835 4836 // Find the application record that is being attached... either via 4837 // the pid if we are running in multiple processes, or just pull the 4838 // next app record if we are emulating process with anonymous threads. 4839 ProcessRecord app; 4840 if (pid != MY_PID && pid >= 0) { 4841 synchronized (mPidsSelfLocked) { 4842 app = mPidsSelfLocked.get(pid); 4843 } 4844 } else { 4845 app = null; 4846 } 4847 4848 if (app == null) { 4849 Slog.w(TAG, "No pending application record for pid " + pid 4850 + " (IApplicationThread " + thread + "); dropping process"); 4851 EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid); 4852 if (pid > 0 && pid != MY_PID) { 4853 Process.killProcessQuiet(pid); 4854 } else { 4855 try { 4856 thread.scheduleExit(); 4857 } catch (Exception e) { 4858 // Ignore exceptions. 4859 } 4860 } 4861 return false; 4862 } 4863 4864 // If this application record is still attached to a previous 4865 // process, clean it up now. 4866 if (app.thread != null) { 4867 handleAppDiedLocked(app, true, true); 4868 } 4869 4870 // Tell the process all about itself. 4871 4872 if (localLOGV) Slog.v( 4873 TAG, "Binding process pid " + pid + " to record " + app); 4874 4875 final String processName = app.processName; 4876 try { 4877 AppDeathRecipient adr = new AppDeathRecipient( 4878 app, pid, thread); 4879 thread.asBinder().linkToDeath(adr, 0); 4880 app.deathRecipient = adr; 4881 } catch (RemoteException e) { 4882 app.resetPackageList(mProcessStats); 4883 startProcessLocked(app, "link fail", processName); 4884 return false; 4885 } 4886 4887 EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName); 4888 4889 app.makeActive(thread, mProcessStats); 4890 app.curAdj = app.setAdj = -100; 4891 app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT; 4892 app.forcingToForeground = null; 4893 app.foregroundServices = false; 4894 app.hasShownUi = false; 4895 app.debugging = false; 4896 app.cached = false; 4897 4898 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 4899 4900 boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info); 4901 List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null; 4902 4903 if (!normalMode) { 4904 Slog.i(TAG, "Launching preboot mode app: " + app); 4905 } 4906 4907 if (localLOGV) Slog.v( 4908 TAG, "New app record " + app 4909 + " thread=" + thread.asBinder() + " pid=" + pid); 4910 try { 4911 int testMode = IApplicationThread.DEBUG_OFF; 4912 if (mDebugApp != null && mDebugApp.equals(processName)) { 4913 testMode = mWaitForDebugger 4914 ? IApplicationThread.DEBUG_WAIT 4915 : IApplicationThread.DEBUG_ON; 4916 app.debugging = true; 4917 if (mDebugTransient) { 4918 mDebugApp = mOrigDebugApp; 4919 mWaitForDebugger = mOrigWaitForDebugger; 4920 } 4921 } 4922 String profileFile = app.instrumentationProfileFile; 4923 ParcelFileDescriptor profileFd = null; 4924 boolean profileAutoStop = false; 4925 if (mProfileApp != null && mProfileApp.equals(processName)) { 4926 mProfileProc = app; 4927 profileFile = mProfileFile; 4928 profileFd = mProfileFd; 4929 profileAutoStop = mAutoStopProfiler; 4930 } 4931 boolean enableOpenGlTrace = false; 4932 if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) { 4933 enableOpenGlTrace = true; 4934 mOpenGlTraceApp = null; 4935 } 4936 4937 // If the app is being launched for restore or full backup, set it up specially 4938 boolean isRestrictedBackupMode = false; 4939 if (mBackupTarget != null && mBackupAppName.equals(processName)) { 4940 isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE) 4941 || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL) 4942 || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL); 4943 } 4944 4945 ensurePackageDexOpt(app.instrumentationInfo != null 4946 ? app.instrumentationInfo.packageName 4947 : app.info.packageName); 4948 if (app.instrumentationClass != null) { 4949 ensurePackageDexOpt(app.instrumentationClass.getPackageName()); 4950 } 4951 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc " 4952 + processName + " with config " + mConfiguration); 4953 ApplicationInfo appInfo = app.instrumentationInfo != null 4954 ? app.instrumentationInfo : app.info; 4955 app.compat = compatibilityInfoForPackageLocked(appInfo); 4956 if (profileFd != null) { 4957 profileFd = profileFd.dup(); 4958 } 4959 thread.bindApplication(processName, appInfo, providers, 4960 app.instrumentationClass, profileFile, profileFd, profileAutoStop, 4961 app.instrumentationArguments, app.instrumentationWatcher, 4962 app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace, 4963 isRestrictedBackupMode || !normalMode, app.persistent, 4964 new Configuration(mConfiguration), app.compat, getCommonServicesLocked(), 4965 mCoreSettingsObserver.getCoreSettingsLocked()); 4966 updateLruProcessLocked(app, false, null); 4967 app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis(); 4968 } catch (Exception e) { 4969 // todo: Yikes! What should we do? For now we will try to 4970 // start another process, but that could easily get us in 4971 // an infinite loop of restarting processes... 4972 Slog.w(TAG, "Exception thrown during bind!", e); 4973 4974 app.resetPackageList(mProcessStats); 4975 app.unlinkDeathRecipient(); 4976 startProcessLocked(app, "bind fail", processName); 4977 return false; 4978 } 4979 4980 // Remove this record from the list of starting applications. 4981 mPersistentStartingProcesses.remove(app); 4982 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 4983 "Attach application locked removing on hold: " + app); 4984 mProcessesOnHold.remove(app); 4985 4986 boolean badApp = false; 4987 boolean didSomething = false; 4988 4989 // See if the top visible activity is waiting to run in this process... 4990 if (normalMode) { 4991 try { 4992 if (mStackSupervisor.attachApplicationLocked(app)) { 4993 didSomething = true; 4994 } 4995 } catch (Exception e) { 4996 badApp = true; 4997 } 4998 } 4999 5000 // Find any services that should be running in this process... 5001 if (!badApp) { 5002 try { 5003 didSomething |= mServices.attachApplicationLocked(app, processName); 5004 } catch (Exception e) { 5005 badApp = true; 5006 } 5007 } 5008 5009 // Check if a next-broadcast receiver is in this process... 5010 if (!badApp && isPendingBroadcastProcessLocked(pid)) { 5011 try { 5012 didSomething |= sendPendingBroadcastsLocked(app); 5013 } catch (Exception e) { 5014 // If the app died trying to launch the receiver we declare it 'bad' 5015 badApp = true; 5016 } 5017 } 5018 5019 // Check whether the next backup agent is in this process... 5020 if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) { 5021 if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app); 5022 ensurePackageDexOpt(mBackupTarget.appInfo.packageName); 5023 try { 5024 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo, 5025 compatibilityInfoForPackageLocked(mBackupTarget.appInfo), 5026 mBackupTarget.backupMode); 5027 } catch (Exception e) { 5028 Slog.w(TAG, "Exception scheduling backup agent creation: "); 5029 e.printStackTrace(); 5030 } 5031 } 5032 5033 if (badApp) { 5034 // todo: Also need to kill application to deal with all 5035 // kinds of exceptions. 5036 handleAppDiedLocked(app, false, true); 5037 return false; 5038 } 5039 5040 if (!didSomething) { 5041 updateOomAdjLocked(); 5042 } 5043 5044 return true; 5045 } 5046 5047 @Override 5048 public final void attachApplication(IApplicationThread thread) { 5049 synchronized (this) { 5050 int callingPid = Binder.getCallingPid(); 5051 final long origId = Binder.clearCallingIdentity(); 5052 attachApplicationLocked(thread, callingPid); 5053 Binder.restoreCallingIdentity(origId); 5054 } 5055 } 5056 5057 @Override 5058 public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) { 5059 final long origId = Binder.clearCallingIdentity(); 5060 synchronized (this) { 5061 ActivityStack stack = ActivityRecord.getStackLocked(token); 5062 if (stack != null) { 5063 ActivityRecord r = 5064 mStackSupervisor.activityIdleInternalLocked(token, false, config); 5065 if (stopProfiling) { 5066 if ((mProfileProc == r.app) && (mProfileFd != null)) { 5067 try { 5068 mProfileFd.close(); 5069 } catch (IOException e) { 5070 } 5071 clearProfilerLocked(); 5072 } 5073 } 5074 } 5075 } 5076 Binder.restoreCallingIdentity(origId); 5077 } 5078 5079 void enableScreenAfterBoot() { 5080 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN, 5081 SystemClock.uptimeMillis()); 5082 mWindowManager.enableScreenAfterBoot(); 5083 5084 synchronized (this) { 5085 updateEventDispatchingLocked(); 5086 } 5087 } 5088 5089 @Override 5090 public void showBootMessage(final CharSequence msg, final boolean always) { 5091 enforceNotIsolatedCaller("showBootMessage"); 5092 mWindowManager.showBootMessage(msg, always); 5093 } 5094 5095 @Override 5096 public void dismissKeyguardOnNextActivity() { 5097 enforceNotIsolatedCaller("dismissKeyguardOnNextActivity"); 5098 final long token = Binder.clearCallingIdentity(); 5099 try { 5100 synchronized (this) { 5101 if (DEBUG_LOCKSCREEN) logLockScreen(""); 5102 if (mLockScreenShown) { 5103 mLockScreenShown = false; 5104 comeOutOfSleepIfNeededLocked(); 5105 } 5106 mStackSupervisor.setDismissKeyguard(true); 5107 } 5108 } finally { 5109 Binder.restoreCallingIdentity(token); 5110 } 5111 } 5112 5113 final void finishBooting() { 5114 IntentFilter pkgFilter = new IntentFilter(); 5115 pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART); 5116 pkgFilter.addDataScheme("package"); 5117 mContext.registerReceiver(new BroadcastReceiver() { 5118 @Override 5119 public void onReceive(Context context, Intent intent) { 5120 String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES); 5121 if (pkgs != null) { 5122 for (String pkg : pkgs) { 5123 synchronized (ActivityManagerService.this) { 5124 if (forceStopPackageLocked(pkg, -1, false, false, false, false, 0, 5125 "finished booting")) { 5126 setResultCode(Activity.RESULT_OK); 5127 return; 5128 } 5129 } 5130 } 5131 } 5132 } 5133 }, pkgFilter); 5134 5135 synchronized (this) { 5136 // Ensure that any processes we had put on hold are now started 5137 // up. 5138 final int NP = mProcessesOnHold.size(); 5139 if (NP > 0) { 5140 ArrayList<ProcessRecord> procs = 5141 new ArrayList<ProcessRecord>(mProcessesOnHold); 5142 for (int ip=0; ip<NP; ip++) { 5143 if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: " 5144 + procs.get(ip)); 5145 startProcessLocked(procs.get(ip), "on-hold", null); 5146 } 5147 } 5148 5149 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) { 5150 // Start looking for apps that are abusing wake locks. 5151 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 5152 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 5153 // Tell anyone interested that we are done booting! 5154 SystemProperties.set("sys.boot_completed", "1"); 5155 SystemProperties.set("dev.bootcomplete", "1"); 5156 for (int i=0; i<mStartedUsers.size(); i++) { 5157 UserStartedState uss = mStartedUsers.valueAt(i); 5158 if (uss.mState == UserStartedState.STATE_BOOTING) { 5159 uss.mState = UserStartedState.STATE_RUNNING; 5160 final int userId = mStartedUsers.keyAt(i); 5161 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 5162 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 5163 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT); 5164 broadcastIntentLocked(null, null, intent, null, 5165 new IIntentReceiver.Stub() { 5166 @Override 5167 public void performReceive(Intent intent, int resultCode, 5168 String data, Bundle extras, boolean ordered, 5169 boolean sticky, int sendingUser) { 5170 synchronized (ActivityManagerService.this) { 5171 requestPssAllProcsLocked(SystemClock.uptimeMillis(), 5172 true, false); 5173 } 5174 } 5175 }, 5176 0, null, null, 5177 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, 5178 AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID, 5179 userId); 5180 } 5181 } 5182 } 5183 } 5184 } 5185 5186 final void ensureBootCompleted() { 5187 boolean booting; 5188 boolean enableScreen; 5189 synchronized (this) { 5190 booting = mBooting; 5191 mBooting = false; 5192 enableScreen = !mBooted; 5193 mBooted = true; 5194 } 5195 5196 if (booting) { 5197 finishBooting(); 5198 } 5199 5200 if (enableScreen) { 5201 enableScreenAfterBoot(); 5202 } 5203 } 5204 5205 @Override 5206 public final void activityResumed(IBinder token) { 5207 final long origId = Binder.clearCallingIdentity(); 5208 synchronized(this) { 5209 ActivityStack stack = ActivityRecord.getStackLocked(token); 5210 if (stack != null) { 5211 ActivityRecord.activityResumedLocked(token); 5212 } 5213 } 5214 Binder.restoreCallingIdentity(origId); 5215 } 5216 5217 @Override 5218 public final void activityPaused(IBinder token) { 5219 final long origId = Binder.clearCallingIdentity(); 5220 synchronized(this) { 5221 ActivityStack stack = ActivityRecord.getStackLocked(token); 5222 if (stack != null) { 5223 stack.activityPausedLocked(token, false); 5224 } 5225 } 5226 Binder.restoreCallingIdentity(origId); 5227 } 5228 5229 @Override 5230 public final void activityStopped(IBinder token, Bundle icicle, Bitmap thumbnail, 5231 CharSequence description) { 5232 if (localLOGV) Slog.v( 5233 TAG, "Activity stopped: token=" + token); 5234 5235 // Refuse possible leaked file descriptors 5236 if (icicle != null && icicle.hasFileDescriptors()) { 5237 throw new IllegalArgumentException("File descriptors passed in Bundle"); 5238 } 5239 5240 ActivityRecord r = null; 5241 5242 final long origId = Binder.clearCallingIdentity(); 5243 5244 synchronized (this) { 5245 r = ActivityRecord.isInStackLocked(token); 5246 if (r != null) { 5247 r.task.stack.activityStoppedLocked(r, icicle, thumbnail, description); 5248 } 5249 } 5250 5251 if (r != null) { 5252 sendPendingThumbnail(r, null, null, null, false); 5253 } 5254 5255 trimApplications(); 5256 5257 Binder.restoreCallingIdentity(origId); 5258 } 5259 5260 @Override 5261 public final void activityDestroyed(IBinder token) { 5262 if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token); 5263 synchronized (this) { 5264 ActivityStack stack = ActivityRecord.getStackLocked(token); 5265 if (stack != null) { 5266 stack.activityDestroyedLocked(token); 5267 } 5268 } 5269 } 5270 5271 @Override 5272 public String getCallingPackage(IBinder token) { 5273 synchronized (this) { 5274 ActivityRecord r = getCallingRecordLocked(token); 5275 return r != null ? r.info.packageName : null; 5276 } 5277 } 5278 5279 @Override 5280 public ComponentName getCallingActivity(IBinder token) { 5281 synchronized (this) { 5282 ActivityRecord r = getCallingRecordLocked(token); 5283 return r != null ? r.intent.getComponent() : null; 5284 } 5285 } 5286 5287 private ActivityRecord getCallingRecordLocked(IBinder token) { 5288 ActivityRecord r = ActivityRecord.isInStackLocked(token); 5289 if (r == null) { 5290 return null; 5291 } 5292 return r.resultTo; 5293 } 5294 5295 @Override 5296 public ComponentName getActivityClassForToken(IBinder token) { 5297 synchronized(this) { 5298 ActivityRecord r = ActivityRecord.isInStackLocked(token); 5299 if (r == null) { 5300 return null; 5301 } 5302 return r.intent.getComponent(); 5303 } 5304 } 5305 5306 @Override 5307 public String getPackageForToken(IBinder token) { 5308 synchronized(this) { 5309 ActivityRecord r = ActivityRecord.isInStackLocked(token); 5310 if (r == null) { 5311 return null; 5312 } 5313 return r.packageName; 5314 } 5315 } 5316 5317 @Override 5318 public IIntentSender getIntentSender(int type, 5319 String packageName, IBinder token, String resultWho, 5320 int requestCode, Intent[] intents, String[] resolvedTypes, 5321 int flags, Bundle options, int userId) { 5322 enforceNotIsolatedCaller("getIntentSender"); 5323 // Refuse possible leaked file descriptors 5324 if (intents != null) { 5325 if (intents.length < 1) { 5326 throw new IllegalArgumentException("Intents array length must be >= 1"); 5327 } 5328 for (int i=0; i<intents.length; i++) { 5329 Intent intent = intents[i]; 5330 if (intent != null) { 5331 if (intent.hasFileDescriptors()) { 5332 throw new IllegalArgumentException("File descriptors passed in Intent"); 5333 } 5334 if (type == ActivityManager.INTENT_SENDER_BROADCAST && 5335 (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 5336 throw new IllegalArgumentException( 5337 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 5338 } 5339 intents[i] = new Intent(intent); 5340 } 5341 } 5342 if (resolvedTypes != null && resolvedTypes.length != intents.length) { 5343 throw new IllegalArgumentException( 5344 "Intent array length does not match resolvedTypes length"); 5345 } 5346 } 5347 if (options != null) { 5348 if (options.hasFileDescriptors()) { 5349 throw new IllegalArgumentException("File descriptors passed in options"); 5350 } 5351 } 5352 5353 synchronized(this) { 5354 int callingUid = Binder.getCallingUid(); 5355 int origUserId = userId; 5356 userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId, 5357 type == ActivityManager.INTENT_SENDER_BROADCAST, false, 5358 "getIntentSender", null); 5359 if (origUserId == UserHandle.USER_CURRENT) { 5360 // We don't want to evaluate this until the pending intent is 5361 // actually executed. However, we do want to always do the 5362 // security checking for it above. 5363 userId = UserHandle.USER_CURRENT; 5364 } 5365 try { 5366 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 5367 int uid = AppGlobals.getPackageManager() 5368 .getPackageUid(packageName, UserHandle.getUserId(callingUid)); 5369 if (!UserHandle.isSameApp(callingUid, uid)) { 5370 String msg = "Permission Denial: getIntentSender() from pid=" 5371 + Binder.getCallingPid() 5372 + ", uid=" + Binder.getCallingUid() 5373 + ", (need uid=" + uid + ")" 5374 + " is not allowed to send as package " + packageName; 5375 Slog.w(TAG, msg); 5376 throw new SecurityException(msg); 5377 } 5378 } 5379 5380 return getIntentSenderLocked(type, packageName, callingUid, userId, 5381 token, resultWho, requestCode, intents, resolvedTypes, flags, options); 5382 5383 } catch (RemoteException e) { 5384 throw new SecurityException(e); 5385 } 5386 } 5387 } 5388 5389 IIntentSender getIntentSenderLocked(int type, String packageName, 5390 int callingUid, int userId, IBinder token, String resultWho, 5391 int requestCode, Intent[] intents, String[] resolvedTypes, int flags, 5392 Bundle options) { 5393 if (DEBUG_MU) 5394 Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid); 5395 ActivityRecord activity = null; 5396 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 5397 activity = ActivityRecord.isInStackLocked(token); 5398 if (activity == null) { 5399 return null; 5400 } 5401 if (activity.finishing) { 5402 return null; 5403 } 5404 } 5405 5406 final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0; 5407 final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0; 5408 final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0; 5409 flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT 5410 |PendingIntent.FLAG_UPDATE_CURRENT); 5411 5412 PendingIntentRecord.Key key = new PendingIntentRecord.Key( 5413 type, packageName, activity, resultWho, 5414 requestCode, intents, resolvedTypes, flags, options, userId); 5415 WeakReference<PendingIntentRecord> ref; 5416 ref = mIntentSenderRecords.get(key); 5417 PendingIntentRecord rec = ref != null ? ref.get() : null; 5418 if (rec != null) { 5419 if (!cancelCurrent) { 5420 if (updateCurrent) { 5421 if (rec.key.requestIntent != null) { 5422 rec.key.requestIntent.replaceExtras(intents != null ? 5423 intents[intents.length - 1] : null); 5424 } 5425 if (intents != null) { 5426 intents[intents.length-1] = rec.key.requestIntent; 5427 rec.key.allIntents = intents; 5428 rec.key.allResolvedTypes = resolvedTypes; 5429 } else { 5430 rec.key.allIntents = null; 5431 rec.key.allResolvedTypes = null; 5432 } 5433 } 5434 return rec; 5435 } 5436 rec.canceled = true; 5437 mIntentSenderRecords.remove(key); 5438 } 5439 if (noCreate) { 5440 return rec; 5441 } 5442 rec = new PendingIntentRecord(this, key, callingUid); 5443 mIntentSenderRecords.put(key, rec.ref); 5444 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 5445 if (activity.pendingResults == null) { 5446 activity.pendingResults 5447 = new HashSet<WeakReference<PendingIntentRecord>>(); 5448 } 5449 activity.pendingResults.add(rec.ref); 5450 } 5451 return rec; 5452 } 5453 5454 @Override 5455 public void cancelIntentSender(IIntentSender sender) { 5456 if (!(sender instanceof PendingIntentRecord)) { 5457 return; 5458 } 5459 synchronized(this) { 5460 PendingIntentRecord rec = (PendingIntentRecord)sender; 5461 try { 5462 int uid = AppGlobals.getPackageManager() 5463 .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId()); 5464 if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) { 5465 String msg = "Permission Denial: cancelIntentSender() from pid=" 5466 + Binder.getCallingPid() 5467 + ", uid=" + Binder.getCallingUid() 5468 + " is not allowed to cancel packges " 5469 + rec.key.packageName; 5470 Slog.w(TAG, msg); 5471 throw new SecurityException(msg); 5472 } 5473 } catch (RemoteException e) { 5474 throw new SecurityException(e); 5475 } 5476 cancelIntentSenderLocked(rec, true); 5477 } 5478 } 5479 5480 void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) { 5481 rec.canceled = true; 5482 mIntentSenderRecords.remove(rec.key); 5483 if (cleanActivity && rec.key.activity != null) { 5484 rec.key.activity.pendingResults.remove(rec.ref); 5485 } 5486 } 5487 5488 @Override 5489 public String getPackageForIntentSender(IIntentSender pendingResult) { 5490 if (!(pendingResult instanceof PendingIntentRecord)) { 5491 return null; 5492 } 5493 try { 5494 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5495 return res.key.packageName; 5496 } catch (ClassCastException e) { 5497 } 5498 return null; 5499 } 5500 5501 @Override 5502 public int getUidForIntentSender(IIntentSender sender) { 5503 if (sender instanceof PendingIntentRecord) { 5504 try { 5505 PendingIntentRecord res = (PendingIntentRecord)sender; 5506 return res.uid; 5507 } catch (ClassCastException e) { 5508 } 5509 } 5510 return -1; 5511 } 5512 5513 @Override 5514 public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) { 5515 if (!(pendingResult instanceof PendingIntentRecord)) { 5516 return false; 5517 } 5518 try { 5519 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5520 if (res.key.allIntents == null) { 5521 return false; 5522 } 5523 for (int i=0; i<res.key.allIntents.length; i++) { 5524 Intent intent = res.key.allIntents[i]; 5525 if (intent.getPackage() != null && intent.getComponent() != null) { 5526 return false; 5527 } 5528 } 5529 return true; 5530 } catch (ClassCastException e) { 5531 } 5532 return false; 5533 } 5534 5535 @Override 5536 public boolean isIntentSenderAnActivity(IIntentSender pendingResult) { 5537 if (!(pendingResult instanceof PendingIntentRecord)) { 5538 return false; 5539 } 5540 try { 5541 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5542 if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) { 5543 return true; 5544 } 5545 return false; 5546 } catch (ClassCastException e) { 5547 } 5548 return false; 5549 } 5550 5551 @Override 5552 public Intent getIntentForIntentSender(IIntentSender pendingResult) { 5553 if (!(pendingResult instanceof PendingIntentRecord)) { 5554 return null; 5555 } 5556 try { 5557 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5558 return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null; 5559 } catch (ClassCastException e) { 5560 } 5561 return null; 5562 } 5563 5564 @Override 5565 public void setProcessLimit(int max) { 5566 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 5567 "setProcessLimit()"); 5568 synchronized (this) { 5569 mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max; 5570 mProcessLimitOverride = max; 5571 } 5572 trimApplications(); 5573 } 5574 5575 @Override 5576 public int getProcessLimit() { 5577 synchronized (this) { 5578 return mProcessLimitOverride; 5579 } 5580 } 5581 5582 void foregroundTokenDied(ForegroundToken token) { 5583 synchronized (ActivityManagerService.this) { 5584 synchronized (mPidsSelfLocked) { 5585 ForegroundToken cur 5586 = mForegroundProcesses.get(token.pid); 5587 if (cur != token) { 5588 return; 5589 } 5590 mForegroundProcesses.remove(token.pid); 5591 ProcessRecord pr = mPidsSelfLocked.get(token.pid); 5592 if (pr == null) { 5593 return; 5594 } 5595 pr.forcingToForeground = null; 5596 pr.foregroundServices = false; 5597 } 5598 updateOomAdjLocked(); 5599 } 5600 } 5601 5602 @Override 5603 public void setProcessForeground(IBinder token, int pid, boolean isForeground) { 5604 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 5605 "setProcessForeground()"); 5606 synchronized(this) { 5607 boolean changed = false; 5608 5609 synchronized (mPidsSelfLocked) { 5610 ProcessRecord pr = mPidsSelfLocked.get(pid); 5611 if (pr == null && isForeground) { 5612 Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid); 5613 return; 5614 } 5615 ForegroundToken oldToken = mForegroundProcesses.get(pid); 5616 if (oldToken != null) { 5617 oldToken.token.unlinkToDeath(oldToken, 0); 5618 mForegroundProcesses.remove(pid); 5619 if (pr != null) { 5620 pr.forcingToForeground = null; 5621 } 5622 changed = true; 5623 } 5624 if (isForeground && token != null) { 5625 ForegroundToken newToken = new ForegroundToken() { 5626 @Override 5627 public void binderDied() { 5628 foregroundTokenDied(this); 5629 } 5630 }; 5631 newToken.pid = pid; 5632 newToken.token = token; 5633 try { 5634 token.linkToDeath(newToken, 0); 5635 mForegroundProcesses.put(pid, newToken); 5636 pr.forcingToForeground = token; 5637 changed = true; 5638 } catch (RemoteException e) { 5639 // If the process died while doing this, we will later 5640 // do the cleanup with the process death link. 5641 } 5642 } 5643 } 5644 5645 if (changed) { 5646 updateOomAdjLocked(); 5647 } 5648 } 5649 } 5650 5651 // ========================================================= 5652 // PERMISSIONS 5653 // ========================================================= 5654 5655 static class PermissionController extends IPermissionController.Stub { 5656 ActivityManagerService mActivityManagerService; 5657 PermissionController(ActivityManagerService activityManagerService) { 5658 mActivityManagerService = activityManagerService; 5659 } 5660 5661 @Override 5662 public boolean checkPermission(String permission, int pid, int uid) { 5663 return mActivityManagerService.checkPermission(permission, pid, 5664 uid) == PackageManager.PERMISSION_GRANTED; 5665 } 5666 } 5667 5668 class IntentFirewallInterface implements IntentFirewall.AMSInterface { 5669 @Override 5670 public int checkComponentPermission(String permission, int pid, int uid, 5671 int owningUid, boolean exported) { 5672 return ActivityManagerService.this.checkComponentPermission(permission, pid, uid, 5673 owningUid, exported); 5674 } 5675 5676 @Override 5677 public Object getAMSLock() { 5678 return ActivityManagerService.this; 5679 } 5680 } 5681 5682 /** 5683 * This can be called with or without the global lock held. 5684 */ 5685 int checkComponentPermission(String permission, int pid, int uid, 5686 int owningUid, boolean exported) { 5687 // We might be performing an operation on behalf of an indirect binder 5688 // invocation, e.g. via {@link #openContentUri}. Check and adjust the 5689 // client identity accordingly before proceeding. 5690 Identity tlsIdentity = sCallerIdentity.get(); 5691 if (tlsIdentity != null) { 5692 Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {" 5693 + tlsIdentity.pid + "," + tlsIdentity.uid + "}"); 5694 uid = tlsIdentity.uid; 5695 pid = tlsIdentity.pid; 5696 } 5697 5698 if (pid == MY_PID) { 5699 return PackageManager.PERMISSION_GRANTED; 5700 } 5701 5702 return ActivityManager.checkComponentPermission(permission, uid, 5703 owningUid, exported); 5704 } 5705 5706 /** 5707 * As the only public entry point for permissions checking, this method 5708 * can enforce the semantic that requesting a check on a null global 5709 * permission is automatically denied. (Internally a null permission 5710 * string is used when calling {@link #checkComponentPermission} in cases 5711 * when only uid-based security is needed.) 5712 * 5713 * This can be called with or without the global lock held. 5714 */ 5715 @Override 5716 public int checkPermission(String permission, int pid, int uid) { 5717 if (permission == null) { 5718 return PackageManager.PERMISSION_DENIED; 5719 } 5720 return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true); 5721 } 5722 5723 /** 5724 * Binder IPC calls go through the public entry point. 5725 * This can be called with or without the global lock held. 5726 */ 5727 int checkCallingPermission(String permission) { 5728 return checkPermission(permission, 5729 Binder.getCallingPid(), 5730 UserHandle.getAppId(Binder.getCallingUid())); 5731 } 5732 5733 /** 5734 * This can be called with or without the global lock held. 5735 */ 5736 void enforceCallingPermission(String permission, String func) { 5737 if (checkCallingPermission(permission) 5738 == PackageManager.PERMISSION_GRANTED) { 5739 return; 5740 } 5741 5742 String msg = "Permission Denial: " + func + " from pid=" 5743 + Binder.getCallingPid() 5744 + ", uid=" + Binder.getCallingUid() 5745 + " requires " + permission; 5746 Slog.w(TAG, msg); 5747 throw new SecurityException(msg); 5748 } 5749 5750 /** 5751 * Determine if UID is holding permissions required to access {@link Uri} in 5752 * the given {@link ProviderInfo}. Final permission checking is always done 5753 * in {@link ContentProvider}. 5754 */ 5755 private final boolean checkHoldingPermissionsLocked( 5756 IPackageManager pm, ProviderInfo pi, Uri uri, int uid, int modeFlags) { 5757 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5758 "checkHoldingPermissionsLocked: uri=" + uri + " uid=" + uid); 5759 5760 if (pi.applicationInfo.uid == uid) { 5761 return true; 5762 } else if (!pi.exported) { 5763 return false; 5764 } 5765 5766 boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0; 5767 boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0; 5768 try { 5769 // check if target holds top-level <provider> permissions 5770 if (!readMet && pi.readPermission != null 5771 && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) { 5772 readMet = true; 5773 } 5774 if (!writeMet && pi.writePermission != null 5775 && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) { 5776 writeMet = true; 5777 } 5778 5779 // track if unprotected read/write is allowed; any denied 5780 // <path-permission> below removes this ability 5781 boolean allowDefaultRead = pi.readPermission == null; 5782 boolean allowDefaultWrite = pi.writePermission == null; 5783 5784 // check if target holds any <path-permission> that match uri 5785 final PathPermission[] pps = pi.pathPermissions; 5786 if (pps != null) { 5787 final String path = uri.getPath(); 5788 int i = pps.length; 5789 while (i > 0 && (!readMet || !writeMet)) { 5790 i--; 5791 PathPermission pp = pps[i]; 5792 if (pp.match(path)) { 5793 if (!readMet) { 5794 final String pprperm = pp.getReadPermission(); 5795 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for " 5796 + pprperm + " for " + pp.getPath() 5797 + ": match=" + pp.match(path) 5798 + " check=" + pm.checkUidPermission(pprperm, uid)); 5799 if (pprperm != null) { 5800 if (pm.checkUidPermission(pprperm, uid) == PERMISSION_GRANTED) { 5801 readMet = true; 5802 } else { 5803 allowDefaultRead = false; 5804 } 5805 } 5806 } 5807 if (!writeMet) { 5808 final String ppwperm = pp.getWritePermission(); 5809 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm " 5810 + ppwperm + " for " + pp.getPath() 5811 + ": match=" + pp.match(path) 5812 + " check=" + pm.checkUidPermission(ppwperm, uid)); 5813 if (ppwperm != null) { 5814 if (pm.checkUidPermission(ppwperm, uid) == PERMISSION_GRANTED) { 5815 writeMet = true; 5816 } else { 5817 allowDefaultWrite = false; 5818 } 5819 } 5820 } 5821 } 5822 } 5823 } 5824 5825 // grant unprotected <provider> read/write, if not blocked by 5826 // <path-permission> above 5827 if (allowDefaultRead) readMet = true; 5828 if (allowDefaultWrite) writeMet = true; 5829 5830 } catch (RemoteException e) { 5831 return false; 5832 } 5833 5834 return readMet && writeMet; 5835 } 5836 5837 private ProviderInfo getProviderInfoLocked(String authority, int userHandle) { 5838 ProviderInfo pi = null; 5839 ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle); 5840 if (cpr != null) { 5841 pi = cpr.info; 5842 } else { 5843 try { 5844 pi = AppGlobals.getPackageManager().resolveContentProvider( 5845 authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle); 5846 } catch (RemoteException ex) { 5847 } 5848 } 5849 return pi; 5850 } 5851 5852 private UriPermission findUriPermissionLocked(int targetUid, Uri uri) { 5853 ArrayMap<Uri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid); 5854 if (targetUris != null) { 5855 return targetUris.get(uri); 5856 } else { 5857 return null; 5858 } 5859 } 5860 5861 private UriPermission findOrCreateUriPermissionLocked( 5862 String sourcePkg, String targetPkg, int targetUid, Uri uri) { 5863 ArrayMap<Uri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid); 5864 if (targetUris == null) { 5865 targetUris = Maps.newArrayMap(); 5866 mGrantedUriPermissions.put(targetUid, targetUris); 5867 } 5868 5869 UriPermission perm = targetUris.get(uri); 5870 if (perm == null) { 5871 perm = new UriPermission(sourcePkg, targetPkg, targetUid, uri); 5872 targetUris.put(uri, perm); 5873 } 5874 5875 return perm; 5876 } 5877 5878 private final boolean checkUriPermissionLocked( 5879 Uri uri, int uid, int modeFlags, int minStrength) { 5880 // Root gets to do everything. 5881 if (uid == 0) { 5882 return true; 5883 } 5884 ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(uid); 5885 if (perms == null) return false; 5886 UriPermission perm = perms.get(uri); 5887 if (perm == null) return false; 5888 return perm.getStrength(modeFlags) >= minStrength; 5889 } 5890 5891 @Override 5892 public int checkUriPermission(Uri uri, int pid, int uid, int modeFlags) { 5893 enforceNotIsolatedCaller("checkUriPermission"); 5894 5895 // Another redirected-binder-call permissions check as in 5896 // {@link checkComponentPermission}. 5897 Identity tlsIdentity = sCallerIdentity.get(); 5898 if (tlsIdentity != null) { 5899 uid = tlsIdentity.uid; 5900 pid = tlsIdentity.pid; 5901 } 5902 5903 // Our own process gets to do everything. 5904 if (pid == MY_PID) { 5905 return PackageManager.PERMISSION_GRANTED; 5906 } 5907 synchronized(this) { 5908 return checkUriPermissionLocked(uri, uid, modeFlags, UriPermission.STRENGTH_OWNED) 5909 ? PackageManager.PERMISSION_GRANTED 5910 : PackageManager.PERMISSION_DENIED; 5911 } 5912 } 5913 5914 /** 5915 * Check if the targetPkg can be granted permission to access uri by 5916 * the callingUid using the given modeFlags. Throws a security exception 5917 * if callingUid is not allowed to do this. Returns the uid of the target 5918 * if the URI permission grant should be performed; returns -1 if it is not 5919 * needed (for example targetPkg already has permission to access the URI). 5920 * If you already know the uid of the target, you can supply it in 5921 * lastTargetUid else set that to -1. 5922 */ 5923 int checkGrantUriPermissionLocked(int callingUid, String targetPkg, 5924 Uri uri, int modeFlags, int lastTargetUid) { 5925 final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0; 5926 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION 5927 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 5928 if (modeFlags == 0) { 5929 return -1; 5930 } 5931 5932 if (targetPkg != null) { 5933 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5934 "Checking grant " + targetPkg + " permission to " + uri); 5935 } 5936 5937 final IPackageManager pm = AppGlobals.getPackageManager(); 5938 5939 // If this is not a content: uri, we can't do anything with it. 5940 if (!ContentResolver.SCHEME_CONTENT.equals(uri.getScheme())) { 5941 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5942 "Can't grant URI permission for non-content URI: " + uri); 5943 return -1; 5944 } 5945 5946 final String authority = uri.getAuthority(); 5947 final ProviderInfo pi = getProviderInfoLocked(authority, UserHandle.getUserId(callingUid)); 5948 if (pi == null) { 5949 Slog.w(TAG, "No content provider found for permission check: " + uri.toSafeString()); 5950 return -1; 5951 } 5952 5953 int targetUid = lastTargetUid; 5954 if (targetUid < 0 && targetPkg != null) { 5955 try { 5956 targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid)); 5957 if (targetUid < 0) { 5958 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5959 "Can't grant URI permission no uid for: " + targetPkg); 5960 return -1; 5961 } 5962 } catch (RemoteException ex) { 5963 return -1; 5964 } 5965 } 5966 5967 if (targetUid >= 0) { 5968 // First... does the target actually need this permission? 5969 if (checkHoldingPermissionsLocked(pm, pi, uri, targetUid, modeFlags)) { 5970 // No need to grant the target this permission. 5971 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5972 "Target " + targetPkg + " already has full permission to " + uri); 5973 return -1; 5974 } 5975 } else { 5976 // First... there is no target package, so can anyone access it? 5977 boolean allowed = pi.exported; 5978 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) { 5979 if (pi.readPermission != null) { 5980 allowed = false; 5981 } 5982 } 5983 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) { 5984 if (pi.writePermission != null) { 5985 allowed = false; 5986 } 5987 } 5988 if (allowed) { 5989 return -1; 5990 } 5991 } 5992 5993 // Second... is the provider allowing granting of URI permissions? 5994 if (!pi.grantUriPermissions) { 5995 throw new SecurityException("Provider " + pi.packageName 5996 + "/" + pi.name 5997 + " does not allow granting of Uri permissions (uri " 5998 + uri + ")"); 5999 } 6000 if (pi.uriPermissionPatterns != null) { 6001 final int N = pi.uriPermissionPatterns.length; 6002 boolean allowed = false; 6003 for (int i=0; i<N; i++) { 6004 if (pi.uriPermissionPatterns[i] != null 6005 && pi.uriPermissionPatterns[i].match(uri.getPath())) { 6006 allowed = true; 6007 break; 6008 } 6009 } 6010 if (!allowed) { 6011 throw new SecurityException("Provider " + pi.packageName 6012 + "/" + pi.name 6013 + " does not allow granting of permission to path of Uri " 6014 + uri); 6015 } 6016 } 6017 6018 // Third... does the caller itself have permission to access 6019 // this uri? 6020 if (callingUid != Process.myUid()) { 6021 if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) { 6022 // Require they hold a strong enough Uri permission 6023 final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE 6024 : UriPermission.STRENGTH_OWNED; 6025 if (!checkUriPermissionLocked(uri, callingUid, modeFlags, minStrength)) { 6026 throw new SecurityException("Uid " + callingUid 6027 + " does not have permission to uri " + uri); 6028 } 6029 } 6030 } 6031 6032 return targetUid; 6033 } 6034 6035 @Override 6036 public int checkGrantUriPermission(int callingUid, String targetPkg, 6037 Uri uri, int modeFlags) { 6038 enforceNotIsolatedCaller("checkGrantUriPermission"); 6039 synchronized(this) { 6040 return checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1); 6041 } 6042 } 6043 6044 void grantUriPermissionUncheckedLocked( 6045 int targetUid, String targetPkg, Uri uri, int modeFlags, UriPermissionOwner owner) { 6046 final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0; 6047 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION 6048 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 6049 if (modeFlags == 0) { 6050 return; 6051 } 6052 6053 // So here we are: the caller has the assumed permission 6054 // to the uri, and the target doesn't. Let's now give this to 6055 // the target. 6056 6057 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6058 "Granting " + targetPkg + "/" + targetUid + " permission to " + uri); 6059 6060 final String authority = uri.getAuthority(); 6061 final ProviderInfo pi = getProviderInfoLocked(authority, UserHandle.getUserId(targetUid)); 6062 if (pi == null) { 6063 Slog.w(TAG, "No content provider found for grant: " + uri.toSafeString()); 6064 return; 6065 } 6066 6067 final UriPermission perm = findOrCreateUriPermissionLocked( 6068 pi.packageName, targetPkg, targetUid, uri); 6069 perm.grantModes(modeFlags, persistable, owner); 6070 } 6071 6072 void grantUriPermissionLocked(int callingUid, String targetPkg, Uri uri, 6073 int modeFlags, UriPermissionOwner owner) { 6074 if (targetPkg == null) { 6075 throw new NullPointerException("targetPkg"); 6076 } 6077 6078 int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1); 6079 if (targetUid < 0) { 6080 return; 6081 } 6082 6083 grantUriPermissionUncheckedLocked(targetUid, targetPkg, uri, modeFlags, owner); 6084 } 6085 6086 static class NeededUriGrants extends ArrayList<Uri> { 6087 final String targetPkg; 6088 final int targetUid; 6089 final int flags; 6090 6091 NeededUriGrants(String targetPkg, int targetUid, int flags) { 6092 this.targetPkg = targetPkg; 6093 this.targetUid = targetUid; 6094 this.flags = flags; 6095 } 6096 } 6097 6098 /** 6099 * Like checkGrantUriPermissionLocked, but takes an Intent. 6100 */ 6101 NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid, 6102 String targetPkg, Intent intent, int mode, NeededUriGrants needed) { 6103 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6104 "Checking URI perm to data=" + (intent != null ? intent.getData() : null) 6105 + " clip=" + (intent != null ? intent.getClipData() : null) 6106 + " from " + intent + "; flags=0x" 6107 + Integer.toHexString(intent != null ? intent.getFlags() : 0)); 6108 6109 if (targetPkg == null) { 6110 throw new NullPointerException("targetPkg"); 6111 } 6112 6113 if (intent == null) { 6114 return null; 6115 } 6116 Uri data = intent.getData(); 6117 ClipData clip = intent.getClipData(); 6118 if (data == null && clip == null) { 6119 return null; 6120 } 6121 6122 if (data != null) { 6123 int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, data, 6124 mode, needed != null ? needed.targetUid : -1); 6125 if (targetUid > 0) { 6126 if (needed == null) { 6127 needed = new NeededUriGrants(targetPkg, targetUid, mode); 6128 } 6129 needed.add(data); 6130 } 6131 } 6132 if (clip != null) { 6133 for (int i=0; i<clip.getItemCount(); i++) { 6134 Uri uri = clip.getItemAt(i).getUri(); 6135 if (uri != null) { 6136 int targetUid = -1; 6137 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri, 6138 mode, needed != null ? needed.targetUid : -1); 6139 if (targetUid > 0) { 6140 if (needed == null) { 6141 needed = new NeededUriGrants(targetPkg, targetUid, mode); 6142 } 6143 needed.add(uri); 6144 } 6145 } else { 6146 Intent clipIntent = clip.getItemAt(i).getIntent(); 6147 if (clipIntent != null) { 6148 NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked( 6149 callingUid, targetPkg, clipIntent, mode, needed); 6150 if (newNeeded != null) { 6151 needed = newNeeded; 6152 } 6153 } 6154 } 6155 } 6156 } 6157 6158 return needed; 6159 } 6160 6161 /** 6162 * Like grantUriPermissionUncheckedLocked, but takes an Intent. 6163 */ 6164 void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed, 6165 UriPermissionOwner owner) { 6166 if (needed != null) { 6167 for (int i=0; i<needed.size(); i++) { 6168 grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg, 6169 needed.get(i), needed.flags, owner); 6170 } 6171 } 6172 } 6173 6174 void grantUriPermissionFromIntentLocked(int callingUid, 6175 String targetPkg, Intent intent, UriPermissionOwner owner) { 6176 NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg, 6177 intent, intent != null ? intent.getFlags() : 0, null); 6178 if (needed == null) { 6179 return; 6180 } 6181 6182 grantUriPermissionUncheckedFromIntentLocked(needed, owner); 6183 } 6184 6185 @Override 6186 public void grantUriPermission(IApplicationThread caller, String targetPkg, 6187 Uri uri, int modeFlags) { 6188 enforceNotIsolatedCaller("grantUriPermission"); 6189 synchronized(this) { 6190 final ProcessRecord r = getRecordForAppLocked(caller); 6191 if (r == null) { 6192 throw new SecurityException("Unable to find app for caller " 6193 + caller 6194 + " when granting permission to uri " + uri); 6195 } 6196 if (targetPkg == null) { 6197 throw new IllegalArgumentException("null target"); 6198 } 6199 if (uri == null) { 6200 throw new IllegalArgumentException("null uri"); 6201 } 6202 6203 // Persistable only supported through Intents 6204 Preconditions.checkFlagsArgument(modeFlags, 6205 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 6206 6207 grantUriPermissionLocked(r.uid, targetPkg, uri, modeFlags, 6208 null); 6209 } 6210 } 6211 6212 void removeUriPermissionIfNeededLocked(UriPermission perm) { 6213 if ((perm.modeFlags&(Intent.FLAG_GRANT_READ_URI_PERMISSION 6214 |Intent.FLAG_GRANT_WRITE_URI_PERMISSION)) == 0) { 6215 ArrayMap<Uri, UriPermission> perms 6216 = mGrantedUriPermissions.get(perm.targetUid); 6217 if (perms != null) { 6218 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6219 "Removing " + perm.targetUid + " permission to " + perm.uri); 6220 perms.remove(perm.uri); 6221 if (perms.size() == 0) { 6222 mGrantedUriPermissions.remove(perm.targetUid); 6223 } 6224 } 6225 } 6226 } 6227 6228 private void revokeUriPermissionLocked(int callingUid, Uri uri, int modeFlags) { 6229 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + uri); 6230 6231 final IPackageManager pm = AppGlobals.getPackageManager(); 6232 final String authority = uri.getAuthority(); 6233 final ProviderInfo pi = getProviderInfoLocked(authority, UserHandle.getUserId(callingUid)); 6234 if (pi == null) { 6235 Slog.w(TAG, "No content provider found for permission revoke: " + uri.toSafeString()); 6236 return; 6237 } 6238 6239 // Does the caller have this permission on the URI? 6240 if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) { 6241 // Right now, if you are not the original owner of the permission, 6242 // you are not allowed to revoke it. 6243 //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) { 6244 throw new SecurityException("Uid " + callingUid 6245 + " does not have permission to uri " + uri); 6246 //} 6247 } 6248 6249 boolean persistChanged = false; 6250 6251 // Go through all of the permissions and remove any that match. 6252 final List<String> SEGMENTS = uri.getPathSegments(); 6253 if (SEGMENTS != null) { 6254 final int NS = SEGMENTS.size(); 6255 int N = mGrantedUriPermissions.size(); 6256 for (int i=0; i<N; i++) { 6257 ArrayMap<Uri, UriPermission> perms 6258 = mGrantedUriPermissions.valueAt(i); 6259 Iterator<UriPermission> it = perms.values().iterator(); 6260 toploop: 6261 while (it.hasNext()) { 6262 UriPermission perm = it.next(); 6263 Uri targetUri = perm.uri; 6264 if (!authority.equals(targetUri.getAuthority())) { 6265 continue; 6266 } 6267 List<String> targetSegments = targetUri.getPathSegments(); 6268 if (targetSegments == null) { 6269 continue; 6270 } 6271 if (targetSegments.size() < NS) { 6272 continue; 6273 } 6274 for (int j=0; j<NS; j++) { 6275 if (!SEGMENTS.get(j).equals(targetSegments.get(j))) { 6276 continue toploop; 6277 } 6278 } 6279 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6280 "Revoking " + perm.targetUid + " permission to " + perm.uri); 6281 persistChanged |= perm.clearModes(modeFlags, true); 6282 if (perm.modeFlags == 0) { 6283 it.remove(); 6284 } 6285 } 6286 if (perms.size() == 0) { 6287 mGrantedUriPermissions.remove( 6288 mGrantedUriPermissions.keyAt(i)); 6289 N--; 6290 i--; 6291 } 6292 } 6293 } 6294 6295 if (persistChanged) { 6296 schedulePersistUriGrants(); 6297 } 6298 } 6299 6300 @Override 6301 public void revokeUriPermission(IApplicationThread caller, Uri uri, 6302 int modeFlags) { 6303 enforceNotIsolatedCaller("revokeUriPermission"); 6304 synchronized(this) { 6305 final ProcessRecord r = getRecordForAppLocked(caller); 6306 if (r == null) { 6307 throw new SecurityException("Unable to find app for caller " 6308 + caller 6309 + " when revoking permission to uri " + uri); 6310 } 6311 if (uri == null) { 6312 Slog.w(TAG, "revokeUriPermission: null uri"); 6313 return; 6314 } 6315 6316 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION 6317 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 6318 if (modeFlags == 0) { 6319 return; 6320 } 6321 6322 final IPackageManager pm = AppGlobals.getPackageManager(); 6323 final String authority = uri.getAuthority(); 6324 final ProviderInfo pi = getProviderInfoLocked(authority, r.userId); 6325 if (pi == null) { 6326 Slog.w(TAG, "No content provider found for permission revoke: " 6327 + uri.toSafeString()); 6328 return; 6329 } 6330 6331 revokeUriPermissionLocked(r.uid, uri, modeFlags); 6332 } 6333 } 6334 6335 /** 6336 * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the 6337 * given package. 6338 * 6339 * @param packageName Package name to match, or {@code null} to apply to all 6340 * packages. 6341 * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply 6342 * to all users. 6343 * @param persistable If persistable grants should be removed. 6344 */ 6345 private void removeUriPermissionsForPackageLocked( 6346 String packageName, int userHandle, boolean persistable) { 6347 if (userHandle == UserHandle.USER_ALL && packageName == null) { 6348 throw new IllegalArgumentException("Must narrow by either package or user"); 6349 } 6350 6351 boolean persistChanged = false; 6352 6353 final int size = mGrantedUriPermissions.size(); 6354 for (int i = 0; i < size; i++) { 6355 // Only inspect grants matching user 6356 if (userHandle == UserHandle.USER_ALL 6357 || userHandle == UserHandle.getUserId(mGrantedUriPermissions.keyAt(i))) { 6358 final Iterator<UriPermission> it = mGrantedUriPermissions.valueAt(i) 6359 .values().iterator(); 6360 while (it.hasNext()) { 6361 final UriPermission perm = it.next(); 6362 6363 // Only inspect grants matching package 6364 if (packageName == null || perm.sourcePkg.equals(packageName) 6365 || perm.targetPkg.equals(packageName)) { 6366 persistChanged |= perm.clearModes(~0, persistable); 6367 6368 // Only remove when no modes remain; any persisted grants 6369 // will keep this alive. 6370 if (perm.modeFlags == 0) { 6371 it.remove(); 6372 } 6373 } 6374 } 6375 } 6376 } 6377 6378 if (persistChanged) { 6379 schedulePersistUriGrants(); 6380 } 6381 } 6382 6383 @Override 6384 public IBinder newUriPermissionOwner(String name) { 6385 enforceNotIsolatedCaller("newUriPermissionOwner"); 6386 synchronized(this) { 6387 UriPermissionOwner owner = new UriPermissionOwner(this, name); 6388 return owner.getExternalTokenLocked(); 6389 } 6390 } 6391 6392 @Override 6393 public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, 6394 Uri uri, int modeFlags) { 6395 synchronized(this) { 6396 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 6397 if (owner == null) { 6398 throw new IllegalArgumentException("Unknown owner: " + token); 6399 } 6400 if (fromUid != Binder.getCallingUid()) { 6401 if (Binder.getCallingUid() != Process.myUid()) { 6402 // Only system code can grant URI permissions on behalf 6403 // of other users. 6404 throw new SecurityException("nice try"); 6405 } 6406 } 6407 if (targetPkg == null) { 6408 throw new IllegalArgumentException("null target"); 6409 } 6410 if (uri == null) { 6411 throw new IllegalArgumentException("null uri"); 6412 } 6413 6414 grantUriPermissionLocked(fromUid, targetPkg, uri, modeFlags, owner); 6415 } 6416 } 6417 6418 @Override 6419 public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode) { 6420 synchronized(this) { 6421 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 6422 if (owner == null) { 6423 throw new IllegalArgumentException("Unknown owner: " + token); 6424 } 6425 6426 if (uri == null) { 6427 owner.removeUriPermissionsLocked(mode); 6428 } else { 6429 owner.removeUriPermissionLocked(uri, mode); 6430 } 6431 } 6432 } 6433 6434 private void schedulePersistUriGrants() { 6435 if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) { 6436 mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG), 6437 10 * DateUtils.SECOND_IN_MILLIS); 6438 } 6439 } 6440 6441 private void writeGrantedUriPermissions() { 6442 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()"); 6443 6444 // Snapshot permissions so we can persist without lock 6445 ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList(); 6446 synchronized (this) { 6447 final int size = mGrantedUriPermissions.size(); 6448 for (int i = 0 ; i < size; i++) { 6449 for (UriPermission perm : mGrantedUriPermissions.valueAt(i).values()) { 6450 if (perm.persistedModeFlags != 0) { 6451 persist.add(perm.snapshot()); 6452 } 6453 } 6454 } 6455 } 6456 6457 FileOutputStream fos = null; 6458 try { 6459 fos = mGrantFile.startWrite(); 6460 6461 XmlSerializer out = new FastXmlSerializer(); 6462 out.setOutput(fos, "utf-8"); 6463 out.startDocument(null, true); 6464 out.startTag(null, TAG_URI_GRANTS); 6465 for (UriPermission.Snapshot perm : persist) { 6466 out.startTag(null, TAG_URI_GRANT); 6467 writeIntAttribute(out, ATTR_USER_HANDLE, perm.userHandle); 6468 out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg); 6469 out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg); 6470 out.attribute(null, ATTR_URI, String.valueOf(perm.uri)); 6471 writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags); 6472 writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime); 6473 out.endTag(null, TAG_URI_GRANT); 6474 } 6475 out.endTag(null, TAG_URI_GRANTS); 6476 out.endDocument(); 6477 6478 mGrantFile.finishWrite(fos); 6479 } catch (IOException e) { 6480 if (fos != null) { 6481 mGrantFile.failWrite(fos); 6482 } 6483 } 6484 } 6485 6486 private void readGrantedUriPermissionsLocked() { 6487 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()"); 6488 6489 final long now = System.currentTimeMillis(); 6490 6491 FileInputStream fis = null; 6492 try { 6493 fis = mGrantFile.openRead(); 6494 final XmlPullParser in = Xml.newPullParser(); 6495 in.setInput(fis, null); 6496 6497 int type; 6498 while ((type = in.next()) != END_DOCUMENT) { 6499 final String tag = in.getName(); 6500 if (type == START_TAG) { 6501 if (TAG_URI_GRANT.equals(tag)) { 6502 final int userHandle = readIntAttribute(in, ATTR_USER_HANDLE); 6503 final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG); 6504 final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG); 6505 final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI)); 6506 final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS); 6507 final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now); 6508 6509 // Sanity check that provider still belongs to source package 6510 final ProviderInfo pi = getProviderInfoLocked( 6511 uri.getAuthority(), userHandle); 6512 if (pi != null && sourcePkg.equals(pi.packageName)) { 6513 int targetUid = -1; 6514 try { 6515 targetUid = AppGlobals.getPackageManager() 6516 .getPackageUid(targetPkg, userHandle); 6517 } catch (RemoteException e) { 6518 } 6519 if (targetUid != -1) { 6520 final UriPermission perm = findOrCreateUriPermissionLocked( 6521 sourcePkg, targetPkg, targetUid, uri); 6522 perm.initPersistedModes(modeFlags, createdTime); 6523 } 6524 } else { 6525 Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg 6526 + " but instead found " + pi); 6527 } 6528 } 6529 } 6530 } 6531 } catch (FileNotFoundException e) { 6532 // Missing grants is okay 6533 } catch (IOException e) { 6534 Log.wtf(TAG, "Failed reading Uri grants", e); 6535 } catch (XmlPullParserException e) { 6536 Log.wtf(TAG, "Failed reading Uri grants", e); 6537 } finally { 6538 IoUtils.closeQuietly(fis); 6539 } 6540 } 6541 6542 @Override 6543 public void takePersistableUriPermission(Uri uri, int modeFlags) { 6544 enforceNotIsolatedCaller("takePersistableUriPermission"); 6545 6546 Preconditions.checkFlagsArgument(modeFlags, 6547 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 6548 6549 synchronized (this) { 6550 final int callingUid = Binder.getCallingUid(); 6551 final UriPermission perm = findUriPermissionLocked(callingUid, uri); 6552 if (perm == null) { 6553 throw new SecurityException("No permission grant found for UID " + callingUid 6554 + " and Uri " + uri.toSafeString()); 6555 } 6556 6557 boolean persistChanged = perm.takePersistableModes(modeFlags); 6558 persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid); 6559 6560 if (persistChanged) { 6561 schedulePersistUriGrants(); 6562 } 6563 } 6564 } 6565 6566 @Override 6567 public void releasePersistableUriPermission(Uri uri, int modeFlags) { 6568 enforceNotIsolatedCaller("releasePersistableUriPermission"); 6569 6570 Preconditions.checkFlagsArgument(modeFlags, 6571 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 6572 6573 synchronized (this) { 6574 final int callingUid = Binder.getCallingUid(); 6575 6576 final UriPermission perm = findUriPermissionLocked(callingUid, uri); 6577 if (perm == null) { 6578 Slog.w(TAG, "No permission grant found for UID " + callingUid + " and Uri " 6579 + uri.toSafeString()); 6580 return; 6581 } 6582 6583 final boolean persistChanged = perm.releasePersistableModes(modeFlags); 6584 removeUriPermissionIfNeededLocked(perm); 6585 if (persistChanged) { 6586 schedulePersistUriGrants(); 6587 } 6588 } 6589 } 6590 6591 /** 6592 * Prune any older {@link UriPermission} for the given UID until outstanding 6593 * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}. 6594 * 6595 * @return if any mutations occured that require persisting. 6596 */ 6597 private boolean maybePrunePersistedUriGrantsLocked(int uid) { 6598 final ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(uid); 6599 if (perms == null) return false; 6600 if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false; 6601 6602 final ArrayList<UriPermission> persisted = Lists.newArrayList(); 6603 for (UriPermission perm : perms.values()) { 6604 if (perm.persistedModeFlags != 0) { 6605 persisted.add(perm); 6606 } 6607 } 6608 6609 final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS; 6610 if (trimCount <= 0) return false; 6611 6612 Collections.sort(persisted, new UriPermission.PersistedTimeComparator()); 6613 for (int i = 0; i < trimCount; i++) { 6614 final UriPermission perm = persisted.get(i); 6615 6616 if (DEBUG_URI_PERMISSION) { 6617 Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime); 6618 } 6619 6620 perm.releasePersistableModes(~0); 6621 removeUriPermissionIfNeededLocked(perm); 6622 } 6623 6624 return true; 6625 } 6626 6627 @Override 6628 public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions( 6629 String packageName, boolean incoming) { 6630 enforceNotIsolatedCaller("getPersistedUriPermissions"); 6631 Preconditions.checkNotNull(packageName, "packageName"); 6632 6633 final int callingUid = Binder.getCallingUid(); 6634 final IPackageManager pm = AppGlobals.getPackageManager(); 6635 try { 6636 final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid)); 6637 if (packageUid != callingUid) { 6638 throw new SecurityException( 6639 "Package " + packageName + " does not belong to calling UID " + callingUid); 6640 } 6641 } catch (RemoteException e) { 6642 throw new SecurityException("Failed to verify package name ownership"); 6643 } 6644 6645 final ArrayList<android.content.UriPermission> result = Lists.newArrayList(); 6646 synchronized (this) { 6647 if (incoming) { 6648 final ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(callingUid); 6649 if (perms == null) { 6650 Slog.w(TAG, "No permission grants found for " + packageName); 6651 } else { 6652 final int size = perms.size(); 6653 for (int i = 0; i < size; i++) { 6654 final UriPermission perm = perms.valueAt(i); 6655 if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) { 6656 result.add(perm.buildPersistedPublicApiObject()); 6657 } 6658 } 6659 } 6660 } else { 6661 final int size = mGrantedUriPermissions.size(); 6662 for (int i = 0; i < size; i++) { 6663 final ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 6664 final int permsSize = perms.size(); 6665 for (int j = 0; j < permsSize; j++) { 6666 final UriPermission perm = perms.valueAt(j); 6667 if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) { 6668 result.add(perm.buildPersistedPublicApiObject()); 6669 } 6670 } 6671 } 6672 } 6673 } 6674 return new ParceledListSlice<android.content.UriPermission>(result); 6675 } 6676 6677 @Override 6678 public void showWaitingForDebugger(IApplicationThread who, boolean waiting) { 6679 synchronized (this) { 6680 ProcessRecord app = 6681 who != null ? getRecordForAppLocked(who) : null; 6682 if (app == null) return; 6683 6684 Message msg = Message.obtain(); 6685 msg.what = WAIT_FOR_DEBUGGER_MSG; 6686 msg.obj = app; 6687 msg.arg1 = waiting ? 1 : 0; 6688 mHandler.sendMessage(msg); 6689 } 6690 } 6691 6692 @Override 6693 public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) { 6694 final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ); 6695 final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ); 6696 outInfo.availMem = Process.getFreeMemory(); 6697 outInfo.totalMem = Process.getTotalMemory(); 6698 outInfo.threshold = homeAppMem; 6699 outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2)); 6700 outInfo.hiddenAppThreshold = cachedAppMem; 6701 outInfo.secondaryServerThreshold = mProcessList.getMemLevel( 6702 ProcessList.SERVICE_ADJ); 6703 outInfo.visibleAppThreshold = mProcessList.getMemLevel( 6704 ProcessList.VISIBLE_APP_ADJ); 6705 outInfo.foregroundAppThreshold = mProcessList.getMemLevel( 6706 ProcessList.FOREGROUND_APP_ADJ); 6707 } 6708 6709 // ========================================================= 6710 // TASK MANAGEMENT 6711 // ========================================================= 6712 6713 @Override 6714 public List<RunningTaskInfo> getTasks(int maxNum, int flags, 6715 IThumbnailReceiver receiver) { 6716 ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>(); 6717 6718 PendingThumbnailsRecord pending = new PendingThumbnailsRecord(receiver); 6719 ActivityRecord topRecord = null; 6720 6721 synchronized(this) { 6722 if (localLOGV) Slog.v( 6723 TAG, "getTasks: max=" + maxNum + ", flags=" + flags 6724 + ", receiver=" + receiver); 6725 6726 if (checkCallingPermission(android.Manifest.permission.GET_TASKS) 6727 != PackageManager.PERMISSION_GRANTED) { 6728 if (receiver != null) { 6729 // If the caller wants to wait for pending thumbnails, 6730 // it ain't gonna get them. 6731 try { 6732 receiver.finished(); 6733 } catch (RemoteException ex) { 6734 } 6735 } 6736 String msg = "Permission Denial: getTasks() from pid=" 6737 + Binder.getCallingPid() 6738 + ", uid=" + Binder.getCallingUid() 6739 + " requires " + android.Manifest.permission.GET_TASKS; 6740 Slog.w(TAG, msg); 6741 throw new SecurityException(msg); 6742 } 6743 6744 // TODO: Improve with MRU list from all ActivityStacks. 6745 topRecord = mStackSupervisor.getTasksLocked(maxNum, receiver, pending, list); 6746 6747 if (!pending.pendingRecords.isEmpty()) { 6748 mPendingThumbnails.add(pending); 6749 } 6750 } 6751 6752 if (localLOGV) Slog.v(TAG, "We have pending thumbnails: " + pending); 6753 6754 if (topRecord != null) { 6755 if (localLOGV) Slog.v(TAG, "Requesting top thumbnail"); 6756 try { 6757 IApplicationThread topThumbnail = topRecord.app.thread; 6758 topThumbnail.requestThumbnail(topRecord.appToken); 6759 } catch (Exception e) { 6760 Slog.w(TAG, "Exception thrown when requesting thumbnail", e); 6761 sendPendingThumbnail(null, topRecord.appToken, null, null, true); 6762 } 6763 } 6764 6765 if (pending == null && receiver != null) { 6766 // In this case all thumbnails were available and the client 6767 // is being asked to be told when the remaining ones come in... 6768 // which is unusually, since the top-most currently running 6769 // activity should never have a canned thumbnail! Oh well. 6770 try { 6771 receiver.finished(); 6772 } catch (RemoteException ex) { 6773 } 6774 } 6775 6776 return list; 6777 } 6778 6779 TaskRecord getMostRecentTask() { 6780 return mRecentTasks.get(0); 6781 } 6782 6783 @Override 6784 public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, 6785 int flags, int userId) { 6786 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 6787 false, true, "getRecentTasks", null); 6788 6789 synchronized (this) { 6790 enforceCallingPermission(android.Manifest.permission.GET_TASKS, 6791 "getRecentTasks()"); 6792 final boolean detailed = checkCallingPermission( 6793 android.Manifest.permission.GET_DETAILED_TASKS) 6794 == PackageManager.PERMISSION_GRANTED; 6795 6796 IPackageManager pm = AppGlobals.getPackageManager(); 6797 6798 final int N = mRecentTasks.size(); 6799 ArrayList<ActivityManager.RecentTaskInfo> res 6800 = new ArrayList<ActivityManager.RecentTaskInfo>( 6801 maxNum < N ? maxNum : N); 6802 for (int i=0; i<N && maxNum > 0; i++) { 6803 TaskRecord tr = mRecentTasks.get(i); 6804 // Only add calling user's recent tasks 6805 if (tr.userId != userId) continue; 6806 // Return the entry if desired by the caller. We always return 6807 // the first entry, because callers always expect this to be the 6808 // foreground app. We may filter others if the caller has 6809 // not supplied RECENT_WITH_EXCLUDED and there is some reason 6810 // we should exclude the entry. 6811 6812 if (i == 0 6813 || ((flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0) 6814 || (tr.intent == null) 6815 || ((tr.intent.getFlags() 6816 &Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0)) { 6817 ActivityManager.RecentTaskInfo rti 6818 = new ActivityManager.RecentTaskInfo(); 6819 rti.id = tr.numActivities > 0 ? tr.taskId : -1; 6820 rti.persistentId = tr.taskId; 6821 rti.baseIntent = new Intent( 6822 tr.intent != null ? tr.intent : tr.affinityIntent); 6823 if (!detailed) { 6824 rti.baseIntent.replaceExtras((Bundle)null); 6825 } 6826 rti.origActivity = tr.origActivity; 6827 rti.description = tr.lastDescription; 6828 rti.stackId = tr.stack.mStackId; 6829 6830 if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) { 6831 // Check whether this activity is currently available. 6832 try { 6833 if (rti.origActivity != null) { 6834 if (pm.getActivityInfo(rti.origActivity, 0, userId) 6835 == null) { 6836 continue; 6837 } 6838 } else if (rti.baseIntent != null) { 6839 if (pm.queryIntentActivities(rti.baseIntent, 6840 null, 0, userId) == null) { 6841 continue; 6842 } 6843 } 6844 } catch (RemoteException e) { 6845 // Will never happen. 6846 } 6847 } 6848 6849 res.add(rti); 6850 maxNum--; 6851 } 6852 } 6853 return res; 6854 } 6855 } 6856 6857 private TaskRecord recentTaskForIdLocked(int id) { 6858 final int N = mRecentTasks.size(); 6859 for (int i=0; i<N; i++) { 6860 TaskRecord tr = mRecentTasks.get(i); 6861 if (tr.taskId == id) { 6862 return tr; 6863 } 6864 } 6865 return null; 6866 } 6867 6868 @Override 6869 public ActivityManager.TaskThumbnails getTaskThumbnails(int id) { 6870 synchronized (this) { 6871 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER, 6872 "getTaskThumbnails()"); 6873 TaskRecord tr = recentTaskForIdLocked(id); 6874 if (tr != null) { 6875 return tr.getTaskThumbnailsLocked(); 6876 } 6877 } 6878 return null; 6879 } 6880 6881 @Override 6882 public Bitmap getTaskTopThumbnail(int id) { 6883 synchronized (this) { 6884 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER, 6885 "getTaskTopThumbnail()"); 6886 TaskRecord tr = recentTaskForIdLocked(id); 6887 if (tr != null) { 6888 return tr.getTaskTopThumbnailLocked(); 6889 } 6890 } 6891 return null; 6892 } 6893 6894 @Override 6895 public boolean removeSubTask(int taskId, int subTaskIndex) { 6896 synchronized (this) { 6897 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, 6898 "removeSubTask()"); 6899 long ident = Binder.clearCallingIdentity(); 6900 try { 6901 TaskRecord tr = recentTaskForIdLocked(taskId); 6902 if (tr != null) { 6903 return tr.removeTaskActivitiesLocked(subTaskIndex, true) != null; 6904 } 6905 return false; 6906 } finally { 6907 Binder.restoreCallingIdentity(ident); 6908 } 6909 } 6910 } 6911 6912 private void killUnneededProcessLocked(ProcessRecord pr, String reason) { 6913 if (!pr.killedByAm) { 6914 Slog.i(TAG, "Killing " + pr.toShortString() + " (adj " + pr.setAdj + "): " + reason); 6915 EventLog.writeEvent(EventLogTags.AM_KILL, pr.userId, pr.pid, 6916 pr.processName, pr.setAdj, reason); 6917 pr.killedByAm = true; 6918 Process.killProcessQuiet(pr.pid); 6919 } 6920 } 6921 6922 private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) { 6923 tr.disposeThumbnail(); 6924 mRecentTasks.remove(tr); 6925 final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0; 6926 Intent baseIntent = new Intent( 6927 tr.intent != null ? tr.intent : tr.affinityIntent); 6928 ComponentName component = baseIntent.getComponent(); 6929 if (component == null) { 6930 Slog.w(TAG, "Now component for base intent of task: " + tr); 6931 return; 6932 } 6933 6934 // Find any running services associated with this app. 6935 mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent); 6936 6937 if (killProcesses) { 6938 // Find any running processes associated with this app. 6939 final String pkg = component.getPackageName(); 6940 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 6941 ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap(); 6942 for (int i=0; i<pmap.size(); i++) { 6943 SparseArray<ProcessRecord> uids = pmap.valueAt(i); 6944 for (int j=0; j<uids.size(); j++) { 6945 ProcessRecord proc = uids.valueAt(j); 6946 if (proc.userId != tr.userId) { 6947 continue; 6948 } 6949 if (!proc.pkgList.containsKey(pkg)) { 6950 continue; 6951 } 6952 procs.add(proc); 6953 } 6954 } 6955 6956 // Kill the running processes. 6957 for (int i=0; i<procs.size(); i++) { 6958 ProcessRecord pr = procs.get(i); 6959 if (pr == mHomeProcess) { 6960 // Don't kill the home process along with tasks from the same package. 6961 continue; 6962 } 6963 if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 6964 killUnneededProcessLocked(pr, "remove task"); 6965 } else { 6966 pr.waitingToKill = "remove task"; 6967 } 6968 } 6969 } 6970 } 6971 6972 @Override 6973 public boolean removeTask(int taskId, int flags) { 6974 synchronized (this) { 6975 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, 6976 "removeTask()"); 6977 long ident = Binder.clearCallingIdentity(); 6978 try { 6979 TaskRecord tr = recentTaskForIdLocked(taskId); 6980 if (tr != null) { 6981 ActivityRecord r = tr.removeTaskActivitiesLocked(-1, false); 6982 if (r != null) { 6983 cleanUpRemovedTaskLocked(tr, flags); 6984 return true; 6985 } 6986 if (tr.mActivities.size() == 0) { 6987 // Caller is just removing a recent task that is 6988 // not actively running. That is easy! 6989 cleanUpRemovedTaskLocked(tr, flags); 6990 return true; 6991 } 6992 Slog.w(TAG, "removeTask: task " + taskId 6993 + " does not have activities to remove, " 6994 + " but numActivities=" + tr.numActivities 6995 + ": " + tr); 6996 } 6997 } finally { 6998 Binder.restoreCallingIdentity(ident); 6999 } 7000 } 7001 return false; 7002 } 7003 7004 /** 7005 * TODO: Add mController hook 7006 */ 7007 @Override 7008 public void moveTaskToFront(int task, int flags, Bundle options) { 7009 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 7010 "moveTaskToFront()"); 7011 7012 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving task=" + task); 7013 synchronized(this) { 7014 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 7015 Binder.getCallingUid(), "Task to front")) { 7016 ActivityOptions.abort(options); 7017 return; 7018 } 7019 final long origId = Binder.clearCallingIdentity(); 7020 try { 7021 mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options); 7022 } finally { 7023 Binder.restoreCallingIdentity(origId); 7024 } 7025 ActivityOptions.abort(options); 7026 } 7027 } 7028 7029 @Override 7030 public void moveTaskToBack(int taskId) { 7031 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 7032 "moveTaskToBack()"); 7033 7034 synchronized(this) { 7035 TaskRecord tr = recentTaskForIdLocked(taskId); 7036 if (tr != null) { 7037 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr); 7038 ActivityStack stack = tr.stack; 7039 if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) { 7040 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 7041 Binder.getCallingUid(), "Task to back")) { 7042 return; 7043 } 7044 } 7045 final long origId = Binder.clearCallingIdentity(); 7046 try { 7047 stack.moveTaskToBackLocked(taskId, null); 7048 } finally { 7049 Binder.restoreCallingIdentity(origId); 7050 } 7051 } 7052 } 7053 } 7054 7055 /** 7056 * Moves an activity, and all of the other activities within the same task, to the bottom 7057 * of the history stack. The activity's order within the task is unchanged. 7058 * 7059 * @param token A reference to the activity we wish to move 7060 * @param nonRoot If false then this only works if the activity is the root 7061 * of a task; if true it will work for any activity in a task. 7062 * @return Returns true if the move completed, false if not. 7063 */ 7064 @Override 7065 public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) { 7066 enforceNotIsolatedCaller("moveActivityTaskToBack"); 7067 synchronized(this) { 7068 final long origId = Binder.clearCallingIdentity(); 7069 int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot); 7070 if (taskId >= 0) { 7071 return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null); 7072 } 7073 Binder.restoreCallingIdentity(origId); 7074 } 7075 return false; 7076 } 7077 7078 @Override 7079 public void moveTaskBackwards(int task) { 7080 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 7081 "moveTaskBackwards()"); 7082 7083 synchronized(this) { 7084 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 7085 Binder.getCallingUid(), "Task backwards")) { 7086 return; 7087 } 7088 final long origId = Binder.clearCallingIdentity(); 7089 moveTaskBackwardsLocked(task); 7090 Binder.restoreCallingIdentity(origId); 7091 } 7092 } 7093 7094 private final void moveTaskBackwardsLocked(int task) { 7095 Slog.e(TAG, "moveTaskBackwards not yet implemented!"); 7096 } 7097 7098 @Override 7099 public IBinder getHomeActivityToken() throws RemoteException { 7100 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7101 "getHomeActivityToken()"); 7102 synchronized (this) { 7103 return mStackSupervisor.getHomeActivityToken(); 7104 } 7105 } 7106 7107 @Override 7108 public IActivityContainer createActivityContainer(IBinder parentActivityToken, 7109 IActivityContainerCallback callback) throws RemoteException { 7110 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7111 "createActivityContainer()"); 7112 synchronized (this) { 7113 if (parentActivityToken == null) { 7114 throw new IllegalArgumentException("parent token must not be null"); 7115 } 7116 ActivityRecord r = ActivityRecord.forToken(parentActivityToken); 7117 if (r == null) { 7118 return null; 7119 } 7120 return mStackSupervisor.createActivityContainer(r, callback); 7121 } 7122 } 7123 7124 @Override 7125 public IActivityContainer getEnclosingActivityContainer(IBinder activityToken) 7126 throws RemoteException { 7127 synchronized (this) { 7128 ActivityStack stack = ActivityRecord.getStackLocked(activityToken); 7129 if (stack != null) { 7130 return stack.mActivityContainer; 7131 } 7132 return null; 7133 } 7134 } 7135 7136 @Override 7137 public void moveTaskToStack(int taskId, int stackId, boolean toTop) { 7138 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7139 "moveTaskToStack()"); 7140 if (stackId == HOME_STACK_ID) { 7141 Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack", 7142 new RuntimeException("here").fillInStackTrace()); 7143 } 7144 synchronized (this) { 7145 long ident = Binder.clearCallingIdentity(); 7146 try { 7147 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId=" 7148 + stackId + " toTop=" + toTop); 7149 mStackSupervisor.moveTaskToStack(taskId, stackId, toTop); 7150 } finally { 7151 Binder.restoreCallingIdentity(ident); 7152 } 7153 } 7154 } 7155 7156 @Override 7157 public void resizeStack(int stackBoxId, Rect bounds) { 7158 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7159 "resizeStackBox()"); 7160 long ident = Binder.clearCallingIdentity(); 7161 try { 7162 mWindowManager.resizeStack(stackBoxId, bounds); 7163 } finally { 7164 Binder.restoreCallingIdentity(ident); 7165 } 7166 } 7167 7168 @Override 7169 public List<StackInfo> getAllStackInfos() { 7170 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7171 "getAllStackInfos()"); 7172 long ident = Binder.clearCallingIdentity(); 7173 try { 7174 synchronized (this) { 7175 return mStackSupervisor.getAllStackInfosLocked(); 7176 } 7177 } finally { 7178 Binder.restoreCallingIdentity(ident); 7179 } 7180 } 7181 7182 @Override 7183 public StackInfo getStackInfo(int stackId) { 7184 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7185 "getStackInfo()"); 7186 long ident = Binder.clearCallingIdentity(); 7187 try { 7188 synchronized (this) { 7189 return mStackSupervisor.getStackInfoLocked(stackId); 7190 } 7191 } finally { 7192 Binder.restoreCallingIdentity(ident); 7193 } 7194 } 7195 7196 @Override 7197 public int getTaskForActivity(IBinder token, boolean onlyRoot) { 7198 synchronized(this) { 7199 return ActivityRecord.getTaskForActivityLocked(token, onlyRoot); 7200 } 7201 } 7202 7203 // ========================================================= 7204 // THUMBNAILS 7205 // ========================================================= 7206 7207 public void reportThumbnail(IBinder token, 7208 Bitmap thumbnail, CharSequence description) { 7209 //System.out.println("Report thumbnail for " + token + ": " + thumbnail); 7210 final long origId = Binder.clearCallingIdentity(); 7211 sendPendingThumbnail(null, token, thumbnail, description, true); 7212 Binder.restoreCallingIdentity(origId); 7213 } 7214 7215 final void sendPendingThumbnail(ActivityRecord r, IBinder token, 7216 Bitmap thumbnail, CharSequence description, boolean always) { 7217 TaskRecord task; 7218 ArrayList<PendingThumbnailsRecord> receivers = null; 7219 7220 //System.out.println("Send pending thumbnail: " + r); 7221 7222 synchronized(this) { 7223 if (r == null) { 7224 r = ActivityRecord.isInStackLocked(token); 7225 if (r == null) { 7226 return; 7227 } 7228 } 7229 if (thumbnail == null && r.thumbHolder != null) { 7230 thumbnail = r.thumbHolder.lastThumbnail; 7231 description = r.thumbHolder.lastDescription; 7232 } 7233 if (thumbnail == null && !always) { 7234 // If there is no thumbnail, and this entry is not actually 7235 // going away, then abort for now and pick up the next 7236 // thumbnail we get. 7237 return; 7238 } 7239 task = r.task; 7240 7241 int N = mPendingThumbnails.size(); 7242 int i=0; 7243 while (i<N) { 7244 PendingThumbnailsRecord pr = mPendingThumbnails.get(i); 7245 //System.out.println("Looking in " + pr.pendingRecords); 7246 if (pr.pendingRecords.remove(r)) { 7247 if (receivers == null) { 7248 receivers = new ArrayList<PendingThumbnailsRecord>(); 7249 } 7250 receivers.add(pr); 7251 if (pr.pendingRecords.size() == 0) { 7252 pr.finished = true; 7253 mPendingThumbnails.remove(i); 7254 N--; 7255 continue; 7256 } 7257 } 7258 i++; 7259 } 7260 } 7261 7262 if (receivers != null) { 7263 final int N = receivers.size(); 7264 for (int i=0; i<N; i++) { 7265 try { 7266 PendingThumbnailsRecord pr = receivers.get(i); 7267 pr.receiver.newThumbnail( 7268 task != null ? task.taskId : -1, thumbnail, description); 7269 if (pr.finished) { 7270 pr.receiver.finished(); 7271 } 7272 } catch (Exception e) { 7273 Slog.w(TAG, "Exception thrown when sending thumbnail", e); 7274 } 7275 } 7276 } 7277 } 7278 7279 // ========================================================= 7280 // CONTENT PROVIDERS 7281 // ========================================================= 7282 7283 private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) { 7284 List<ProviderInfo> providers = null; 7285 try { 7286 providers = AppGlobals.getPackageManager(). 7287 queryContentProviders(app.processName, app.uid, 7288 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS); 7289 } catch (RemoteException ex) { 7290 } 7291 if (DEBUG_MU) 7292 Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid); 7293 int userId = app.userId; 7294 if (providers != null) { 7295 int N = providers.size(); 7296 app.pubProviders.ensureCapacity(N + app.pubProviders.size()); 7297 for (int i=0; i<N; i++) { 7298 ProviderInfo cpi = 7299 (ProviderInfo)providers.get(i); 7300 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo, 7301 cpi.name, cpi.flags); 7302 if (singleton && UserHandle.getUserId(app.uid) != 0) { 7303 // This is a singleton provider, but a user besides the 7304 // default user is asking to initialize a process it runs 7305 // in... well, no, it doesn't actually run in this process, 7306 // it runs in the process of the default user. Get rid of it. 7307 providers.remove(i); 7308 N--; 7309 i--; 7310 continue; 7311 } 7312 7313 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 7314 ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId); 7315 if (cpr == null) { 7316 cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton); 7317 mProviderMap.putProviderByClass(comp, cpr); 7318 } 7319 if (DEBUG_MU) 7320 Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid); 7321 app.pubProviders.put(cpi.name, cpr); 7322 if (!cpi.multiprocess || !"android".equals(cpi.packageName)) { 7323 // Don't add this if it is a platform component that is marked 7324 // to run in multiple processes, because this is actually 7325 // part of the framework so doesn't make sense to track as a 7326 // separate apk in the process. 7327 app.addPackage(cpi.applicationInfo.packageName, mProcessStats); 7328 } 7329 ensurePackageDexOpt(cpi.applicationInfo.packageName); 7330 } 7331 } 7332 return providers; 7333 } 7334 7335 /** 7336 * Check if {@link ProcessRecord} has a possible chance at accessing the 7337 * given {@link ProviderInfo}. Final permission checking is always done 7338 * in {@link ContentProvider}. 7339 */ 7340 private final String checkContentProviderPermissionLocked( 7341 ProviderInfo cpi, ProcessRecord r) { 7342 final int callingPid = (r != null) ? r.pid : Binder.getCallingPid(); 7343 final int callingUid = (r != null) ? r.uid : Binder.getCallingUid(); 7344 if (checkComponentPermission(cpi.readPermission, callingPid, callingUid, 7345 cpi.applicationInfo.uid, cpi.exported) 7346 == PackageManager.PERMISSION_GRANTED) { 7347 return null; 7348 } 7349 if (checkComponentPermission(cpi.writePermission, callingPid, callingUid, 7350 cpi.applicationInfo.uid, cpi.exported) 7351 == PackageManager.PERMISSION_GRANTED) { 7352 return null; 7353 } 7354 7355 PathPermission[] pps = cpi.pathPermissions; 7356 if (pps != null) { 7357 int i = pps.length; 7358 while (i > 0) { 7359 i--; 7360 PathPermission pp = pps[i]; 7361 if (checkComponentPermission(pp.getReadPermission(), callingPid, callingUid, 7362 cpi.applicationInfo.uid, cpi.exported) 7363 == PackageManager.PERMISSION_GRANTED) { 7364 return null; 7365 } 7366 if (checkComponentPermission(pp.getWritePermission(), callingPid, callingUid, 7367 cpi.applicationInfo.uid, cpi.exported) 7368 == PackageManager.PERMISSION_GRANTED) { 7369 return null; 7370 } 7371 } 7372 } 7373 7374 ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(callingUid); 7375 if (perms != null) { 7376 for (Map.Entry<Uri, UriPermission> uri : perms.entrySet()) { 7377 if (uri.getKey().getAuthority().equals(cpi.authority)) { 7378 return null; 7379 } 7380 } 7381 } 7382 7383 String msg; 7384 if (!cpi.exported) { 7385 msg = "Permission Denial: opening provider " + cpi.name 7386 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 7387 + ", uid=" + callingUid + ") that is not exported from uid " 7388 + cpi.applicationInfo.uid; 7389 } else { 7390 msg = "Permission Denial: opening provider " + cpi.name 7391 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 7392 + ", uid=" + callingUid + ") requires " 7393 + cpi.readPermission + " or " + cpi.writePermission; 7394 } 7395 Slog.w(TAG, msg); 7396 return msg; 7397 } 7398 7399 ContentProviderConnection incProviderCountLocked(ProcessRecord r, 7400 final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 7401 if (r != null) { 7402 for (int i=0; i<r.conProviders.size(); i++) { 7403 ContentProviderConnection conn = r.conProviders.get(i); 7404 if (conn.provider == cpr) { 7405 if (DEBUG_PROVIDER) Slog.v(TAG, 7406 "Adding provider requested by " 7407 + r.processName + " from process " 7408 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 7409 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 7410 if (stable) { 7411 conn.stableCount++; 7412 conn.numStableIncs++; 7413 } else { 7414 conn.unstableCount++; 7415 conn.numUnstableIncs++; 7416 } 7417 return conn; 7418 } 7419 } 7420 ContentProviderConnection conn = new ContentProviderConnection(cpr, r); 7421 if (stable) { 7422 conn.stableCount = 1; 7423 conn.numStableIncs = 1; 7424 } else { 7425 conn.unstableCount = 1; 7426 conn.numUnstableIncs = 1; 7427 } 7428 cpr.connections.add(conn); 7429 r.conProviders.add(conn); 7430 return conn; 7431 } 7432 cpr.addExternalProcessHandleLocked(externalProcessToken); 7433 return null; 7434 } 7435 7436 boolean decProviderCountLocked(ContentProviderConnection conn, 7437 ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 7438 if (conn != null) { 7439 cpr = conn.provider; 7440 if (DEBUG_PROVIDER) Slog.v(TAG, 7441 "Removing provider requested by " 7442 + conn.client.processName + " from process " 7443 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 7444 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 7445 if (stable) { 7446 conn.stableCount--; 7447 } else { 7448 conn.unstableCount--; 7449 } 7450 if (conn.stableCount == 0 && conn.unstableCount == 0) { 7451 cpr.connections.remove(conn); 7452 conn.client.conProviders.remove(conn); 7453 return true; 7454 } 7455 return false; 7456 } 7457 cpr.removeExternalProcessHandleLocked(externalProcessToken); 7458 return false; 7459 } 7460 7461 private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller, 7462 String name, IBinder token, boolean stable, int userId) { 7463 ContentProviderRecord cpr; 7464 ContentProviderConnection conn = null; 7465 ProviderInfo cpi = null; 7466 7467 synchronized(this) { 7468 ProcessRecord r = null; 7469 if (caller != null) { 7470 r = getRecordForAppLocked(caller); 7471 if (r == null) { 7472 throw new SecurityException( 7473 "Unable to find app for caller " + caller 7474 + " (pid=" + Binder.getCallingPid() 7475 + ") when getting content provider " + name); 7476 } 7477 } 7478 7479 // First check if this content provider has been published... 7480 cpr = mProviderMap.getProviderByName(name, userId); 7481 boolean providerRunning = cpr != null; 7482 if (providerRunning) { 7483 cpi = cpr.info; 7484 String msg; 7485 if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) { 7486 throw new SecurityException(msg); 7487 } 7488 7489 if (r != null && cpr.canRunHere(r)) { 7490 // This provider has been published or is in the process 7491 // of being published... but it is also allowed to run 7492 // in the caller's process, so don't make a connection 7493 // and just let the caller instantiate its own instance. 7494 ContentProviderHolder holder = cpr.newHolder(null); 7495 // don't give caller the provider object, it needs 7496 // to make its own. 7497 holder.provider = null; 7498 return holder; 7499 } 7500 7501 final long origId = Binder.clearCallingIdentity(); 7502 7503 // In this case the provider instance already exists, so we can 7504 // return it right away. 7505 conn = incProviderCountLocked(r, cpr, token, stable); 7506 if (conn != null && (conn.stableCount+conn.unstableCount) == 1) { 7507 if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 7508 // If this is a perceptible app accessing the provider, 7509 // make sure to count it as being accessed and thus 7510 // back up on the LRU list. This is good because 7511 // content providers are often expensive to start. 7512 updateLruProcessLocked(cpr.proc, false, null); 7513 } 7514 } 7515 7516 if (cpr.proc != null) { 7517 if (false) { 7518 if (cpr.name.flattenToShortString().equals( 7519 "com.android.providers.calendar/.CalendarProvider2")) { 7520 Slog.v(TAG, "****************** KILLING " 7521 + cpr.name.flattenToShortString()); 7522 Process.killProcess(cpr.proc.pid); 7523 } 7524 } 7525 boolean success = updateOomAdjLocked(cpr.proc); 7526 if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success); 7527 // NOTE: there is still a race here where a signal could be 7528 // pending on the process even though we managed to update its 7529 // adj level. Not sure what to do about this, but at least 7530 // the race is now smaller. 7531 if (!success) { 7532 // Uh oh... it looks like the provider's process 7533 // has been killed on us. We need to wait for a new 7534 // process to be started, and make sure its death 7535 // doesn't kill our process. 7536 Slog.i(TAG, 7537 "Existing provider " + cpr.name.flattenToShortString() 7538 + " is crashing; detaching " + r); 7539 boolean lastRef = decProviderCountLocked(conn, cpr, token, stable); 7540 appDiedLocked(cpr.proc, cpr.proc.pid, cpr.proc.thread); 7541 if (!lastRef) { 7542 // This wasn't the last ref our process had on 7543 // the provider... we have now been killed, bail. 7544 return null; 7545 } 7546 providerRunning = false; 7547 conn = null; 7548 } 7549 } 7550 7551 Binder.restoreCallingIdentity(origId); 7552 } 7553 7554 boolean singleton; 7555 if (!providerRunning) { 7556 try { 7557 cpi = AppGlobals.getPackageManager(). 7558 resolveContentProvider(name, 7559 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId); 7560 } catch (RemoteException ex) { 7561 } 7562 if (cpi == null) { 7563 return null; 7564 } 7565 singleton = isSingleton(cpi.processName, cpi.applicationInfo, 7566 cpi.name, cpi.flags); 7567 if (singleton) { 7568 userId = 0; 7569 } 7570 cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId); 7571 7572 String msg; 7573 if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) { 7574 throw new SecurityException(msg); 7575 } 7576 7577 if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate 7578 && !cpi.processName.equals("system")) { 7579 // If this content provider does not run in the system 7580 // process, and the system is not yet ready to run other 7581 // processes, then fail fast instead of hanging. 7582 throw new IllegalArgumentException( 7583 "Attempt to launch content provider before system ready"); 7584 } 7585 7586 // Make sure that the user who owns this provider is started. If not, 7587 // we don't want to allow it to run. 7588 if (mStartedUsers.get(userId) == null) { 7589 Slog.w(TAG, "Unable to launch app " 7590 + cpi.applicationInfo.packageName + "/" 7591 + cpi.applicationInfo.uid + " for provider " 7592 + name + ": user " + userId + " is stopped"); 7593 return null; 7594 } 7595 7596 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 7597 cpr = mProviderMap.getProviderByClass(comp, userId); 7598 final boolean firstClass = cpr == null; 7599 if (firstClass) { 7600 try { 7601 ApplicationInfo ai = 7602 AppGlobals.getPackageManager(). 7603 getApplicationInfo( 7604 cpi.applicationInfo.packageName, 7605 STOCK_PM_FLAGS, userId); 7606 if (ai == null) { 7607 Slog.w(TAG, "No package info for content provider " 7608 + cpi.name); 7609 return null; 7610 } 7611 ai = getAppInfoForUser(ai, userId); 7612 cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton); 7613 } catch (RemoteException ex) { 7614 // pm is in same process, this will never happen. 7615 } 7616 } 7617 7618 if (r != null && cpr.canRunHere(r)) { 7619 // If this is a multiprocess provider, then just return its 7620 // info and allow the caller to instantiate it. Only do 7621 // this if the provider is the same user as the caller's 7622 // process, or can run as root (so can be in any process). 7623 return cpr.newHolder(null); 7624 } 7625 7626 if (DEBUG_PROVIDER) { 7627 RuntimeException e = new RuntimeException("here"); 7628 Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null) 7629 + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e); 7630 } 7631 7632 // This is single process, and our app is now connecting to it. 7633 // See if we are already in the process of launching this 7634 // provider. 7635 final int N = mLaunchingProviders.size(); 7636 int i; 7637 for (i=0; i<N; i++) { 7638 if (mLaunchingProviders.get(i) == cpr) { 7639 break; 7640 } 7641 } 7642 7643 // If the provider is not already being launched, then get it 7644 // started. 7645 if (i >= N) { 7646 final long origId = Binder.clearCallingIdentity(); 7647 7648 try { 7649 // Content provider is now in use, its package can't be stopped. 7650 try { 7651 AppGlobals.getPackageManager().setPackageStoppedState( 7652 cpr.appInfo.packageName, false, userId); 7653 } catch (RemoteException e) { 7654 } catch (IllegalArgumentException e) { 7655 Slog.w(TAG, "Failed trying to unstop package " 7656 + cpr.appInfo.packageName + ": " + e); 7657 } 7658 7659 // Use existing process if already started 7660 ProcessRecord proc = getProcessRecordLocked( 7661 cpi.processName, cpr.appInfo.uid, false); 7662 if (proc != null && proc.thread != null) { 7663 if (DEBUG_PROVIDER) { 7664 Slog.d(TAG, "Installing in existing process " + proc); 7665 } 7666 proc.pubProviders.put(cpi.name, cpr); 7667 try { 7668 proc.thread.scheduleInstallProvider(cpi); 7669 } catch (RemoteException e) { 7670 } 7671 } else { 7672 proc = startProcessLocked(cpi.processName, 7673 cpr.appInfo, false, 0, "content provider", 7674 new ComponentName(cpi.applicationInfo.packageName, 7675 cpi.name), false, false, false); 7676 if (proc == null) { 7677 Slog.w(TAG, "Unable to launch app " 7678 + cpi.applicationInfo.packageName + "/" 7679 + cpi.applicationInfo.uid + " for provider " 7680 + name + ": process is bad"); 7681 return null; 7682 } 7683 } 7684 cpr.launchingApp = proc; 7685 mLaunchingProviders.add(cpr); 7686 } finally { 7687 Binder.restoreCallingIdentity(origId); 7688 } 7689 } 7690 7691 // Make sure the provider is published (the same provider class 7692 // may be published under multiple names). 7693 if (firstClass) { 7694 mProviderMap.putProviderByClass(comp, cpr); 7695 } 7696 7697 mProviderMap.putProviderByName(name, cpr); 7698 conn = incProviderCountLocked(r, cpr, token, stable); 7699 if (conn != null) { 7700 conn.waiting = true; 7701 } 7702 } 7703 } 7704 7705 // Wait for the provider to be published... 7706 synchronized (cpr) { 7707 while (cpr.provider == null) { 7708 if (cpr.launchingApp == null) { 7709 Slog.w(TAG, "Unable to launch app " 7710 + cpi.applicationInfo.packageName + "/" 7711 + cpi.applicationInfo.uid + " for provider " 7712 + name + ": launching app became null"); 7713 EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS, 7714 UserHandle.getUserId(cpi.applicationInfo.uid), 7715 cpi.applicationInfo.packageName, 7716 cpi.applicationInfo.uid, name); 7717 return null; 7718 } 7719 try { 7720 if (DEBUG_MU) { 7721 Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp=" 7722 + cpr.launchingApp); 7723 } 7724 if (conn != null) { 7725 conn.waiting = true; 7726 } 7727 cpr.wait(); 7728 } catch (InterruptedException ex) { 7729 } finally { 7730 if (conn != null) { 7731 conn.waiting = false; 7732 } 7733 } 7734 } 7735 } 7736 return cpr != null ? cpr.newHolder(conn) : null; 7737 } 7738 7739 public final ContentProviderHolder getContentProvider( 7740 IApplicationThread caller, String name, int userId, boolean stable) { 7741 enforceNotIsolatedCaller("getContentProvider"); 7742 if (caller == null) { 7743 String msg = "null IApplicationThread when getting content provider " 7744 + name; 7745 Slog.w(TAG, msg); 7746 throw new SecurityException(msg); 7747 } 7748 7749 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 7750 false, true, "getContentProvider", null); 7751 return getContentProviderImpl(caller, name, null, stable, userId); 7752 } 7753 7754 public ContentProviderHolder getContentProviderExternal( 7755 String name, int userId, IBinder token) { 7756 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 7757 "Do not have permission in call getContentProviderExternal()"); 7758 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 7759 false, true, "getContentProvider", null); 7760 return getContentProviderExternalUnchecked(name, token, userId); 7761 } 7762 7763 private ContentProviderHolder getContentProviderExternalUnchecked(String name, 7764 IBinder token, int userId) { 7765 return getContentProviderImpl(null, name, token, true, userId); 7766 } 7767 7768 /** 7769 * Drop a content provider from a ProcessRecord's bookkeeping 7770 */ 7771 public void removeContentProvider(IBinder connection, boolean stable) { 7772 enforceNotIsolatedCaller("removeContentProvider"); 7773 synchronized (this) { 7774 ContentProviderConnection conn; 7775 try { 7776 conn = (ContentProviderConnection)connection; 7777 } catch (ClassCastException e) { 7778 String msg ="removeContentProvider: " + connection 7779 + " not a ContentProviderConnection"; 7780 Slog.w(TAG, msg); 7781 throw new IllegalArgumentException(msg); 7782 } 7783 if (conn == null) { 7784 throw new NullPointerException("connection is null"); 7785 } 7786 if (decProviderCountLocked(conn, null, null, stable)) { 7787 updateOomAdjLocked(); 7788 } 7789 } 7790 } 7791 7792 public void removeContentProviderExternal(String name, IBinder token) { 7793 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 7794 "Do not have permission in call removeContentProviderExternal()"); 7795 removeContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId()); 7796 } 7797 7798 private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) { 7799 synchronized (this) { 7800 ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId); 7801 if(cpr == null) { 7802 //remove from mProvidersByClass 7803 if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list"); 7804 return; 7805 } 7806 7807 //update content provider record entry info 7808 ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name); 7809 ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId); 7810 if (localCpr.hasExternalProcessHandles()) { 7811 if (localCpr.removeExternalProcessHandleLocked(token)) { 7812 updateOomAdjLocked(); 7813 } else { 7814 Slog.e(TAG, "Attmpt to remove content provider " + localCpr 7815 + " with no external reference for token: " 7816 + token + "."); 7817 } 7818 } else { 7819 Slog.e(TAG, "Attmpt to remove content provider: " + localCpr 7820 + " with no external references."); 7821 } 7822 } 7823 } 7824 7825 public final void publishContentProviders(IApplicationThread caller, 7826 List<ContentProviderHolder> providers) { 7827 if (providers == null) { 7828 return; 7829 } 7830 7831 enforceNotIsolatedCaller("publishContentProviders"); 7832 synchronized (this) { 7833 final ProcessRecord r = getRecordForAppLocked(caller); 7834 if (DEBUG_MU) 7835 Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid); 7836 if (r == null) { 7837 throw new SecurityException( 7838 "Unable to find app for caller " + caller 7839 + " (pid=" + Binder.getCallingPid() 7840 + ") when publishing content providers"); 7841 } 7842 7843 final long origId = Binder.clearCallingIdentity(); 7844 7845 final int N = providers.size(); 7846 for (int i=0; i<N; i++) { 7847 ContentProviderHolder src = providers.get(i); 7848 if (src == null || src.info == null || src.provider == null) { 7849 continue; 7850 } 7851 ContentProviderRecord dst = r.pubProviders.get(src.info.name); 7852 if (DEBUG_MU) 7853 Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid); 7854 if (dst != null) { 7855 ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name); 7856 mProviderMap.putProviderByClass(comp, dst); 7857 String names[] = dst.info.authority.split(";"); 7858 for (int j = 0; j < names.length; j++) { 7859 mProviderMap.putProviderByName(names[j], dst); 7860 } 7861 7862 int NL = mLaunchingProviders.size(); 7863 int j; 7864 for (j=0; j<NL; j++) { 7865 if (mLaunchingProviders.get(j) == dst) { 7866 mLaunchingProviders.remove(j); 7867 j--; 7868 NL--; 7869 } 7870 } 7871 synchronized (dst) { 7872 dst.provider = src.provider; 7873 dst.proc = r; 7874 dst.notifyAll(); 7875 } 7876 updateOomAdjLocked(r); 7877 } 7878 } 7879 7880 Binder.restoreCallingIdentity(origId); 7881 } 7882 } 7883 7884 public boolean refContentProvider(IBinder connection, int stable, int unstable) { 7885 ContentProviderConnection conn; 7886 try { 7887 conn = (ContentProviderConnection)connection; 7888 } catch (ClassCastException e) { 7889 String msg ="refContentProvider: " + connection 7890 + " not a ContentProviderConnection"; 7891 Slog.w(TAG, msg); 7892 throw new IllegalArgumentException(msg); 7893 } 7894 if (conn == null) { 7895 throw new NullPointerException("connection is null"); 7896 } 7897 7898 synchronized (this) { 7899 if (stable > 0) { 7900 conn.numStableIncs += stable; 7901 } 7902 stable = conn.stableCount + stable; 7903 if (stable < 0) { 7904 throw new IllegalStateException("stableCount < 0: " + stable); 7905 } 7906 7907 if (unstable > 0) { 7908 conn.numUnstableIncs += unstable; 7909 } 7910 unstable = conn.unstableCount + unstable; 7911 if (unstable < 0) { 7912 throw new IllegalStateException("unstableCount < 0: " + unstable); 7913 } 7914 7915 if ((stable+unstable) <= 0) { 7916 throw new IllegalStateException("ref counts can't go to zero here: stable=" 7917 + stable + " unstable=" + unstable); 7918 } 7919 conn.stableCount = stable; 7920 conn.unstableCount = unstable; 7921 return !conn.dead; 7922 } 7923 } 7924 7925 public void unstableProviderDied(IBinder connection) { 7926 ContentProviderConnection conn; 7927 try { 7928 conn = (ContentProviderConnection)connection; 7929 } catch (ClassCastException e) { 7930 String msg ="refContentProvider: " + connection 7931 + " not a ContentProviderConnection"; 7932 Slog.w(TAG, msg); 7933 throw new IllegalArgumentException(msg); 7934 } 7935 if (conn == null) { 7936 throw new NullPointerException("connection is null"); 7937 } 7938 7939 // Safely retrieve the content provider associated with the connection. 7940 IContentProvider provider; 7941 synchronized (this) { 7942 provider = conn.provider.provider; 7943 } 7944 7945 if (provider == null) { 7946 // Um, yeah, we're way ahead of you. 7947 return; 7948 } 7949 7950 // Make sure the caller is being honest with us. 7951 if (provider.asBinder().pingBinder()) { 7952 // Er, no, still looks good to us. 7953 synchronized (this) { 7954 Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid() 7955 + " says " + conn + " died, but we don't agree"); 7956 return; 7957 } 7958 } 7959 7960 // Well look at that! It's dead! 7961 synchronized (this) { 7962 if (conn.provider.provider != provider) { 7963 // But something changed... good enough. 7964 return; 7965 } 7966 7967 ProcessRecord proc = conn.provider.proc; 7968 if (proc == null || proc.thread == null) { 7969 // Seems like the process is already cleaned up. 7970 return; 7971 } 7972 7973 // As far as we're concerned, this is just like receiving a 7974 // death notification... just a bit prematurely. 7975 Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid 7976 + ") early provider death"); 7977 final long ident = Binder.clearCallingIdentity(); 7978 try { 7979 appDiedLocked(proc, proc.pid, proc.thread); 7980 } finally { 7981 Binder.restoreCallingIdentity(ident); 7982 } 7983 } 7984 } 7985 7986 @Override 7987 public void appNotRespondingViaProvider(IBinder connection) { 7988 enforceCallingPermission( 7989 android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()"); 7990 7991 final ContentProviderConnection conn = (ContentProviderConnection) connection; 7992 if (conn == null) { 7993 Slog.w(TAG, "ContentProviderConnection is null"); 7994 return; 7995 } 7996 7997 final ProcessRecord host = conn.provider.proc; 7998 if (host == null) { 7999 Slog.w(TAG, "Failed to find hosting ProcessRecord"); 8000 return; 8001 } 8002 8003 final long token = Binder.clearCallingIdentity(); 8004 try { 8005 appNotResponding(host, null, null, false, "ContentProvider not responding"); 8006 } finally { 8007 Binder.restoreCallingIdentity(token); 8008 } 8009 } 8010 8011 public static final void installSystemProviders() { 8012 List<ProviderInfo> providers; 8013 synchronized (mSelf) { 8014 ProcessRecord app = mSelf.mProcessNames.get("system", Process.SYSTEM_UID); 8015 providers = mSelf.generateApplicationProvidersLocked(app); 8016 if (providers != null) { 8017 for (int i=providers.size()-1; i>=0; i--) { 8018 ProviderInfo pi = (ProviderInfo)providers.get(i); 8019 if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) { 8020 Slog.w(TAG, "Not installing system proc provider " + pi.name 8021 + ": not system .apk"); 8022 providers.remove(i); 8023 } 8024 } 8025 } 8026 } 8027 if (providers != null) { 8028 mSystemThread.installSystemProviders(providers); 8029 } 8030 8031 mSelf.mCoreSettingsObserver = new CoreSettingsObserver(mSelf); 8032 8033 mSelf.mUsageStatsService.monitorPackages(); 8034 } 8035 8036 /** 8037 * Allows app to retrieve the MIME type of a URI without having permission 8038 * to access its content provider. 8039 * 8040 * CTS tests for this functionality can be run with "runtest cts-appsecurity". 8041 * 8042 * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/ 8043 * src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java 8044 */ 8045 public String getProviderMimeType(Uri uri, int userId) { 8046 enforceNotIsolatedCaller("getProviderMimeType"); 8047 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 8048 userId, false, true, "getProviderMimeType", null); 8049 final String name = uri.getAuthority(); 8050 final long ident = Binder.clearCallingIdentity(); 8051 ContentProviderHolder holder = null; 8052 8053 try { 8054 holder = getContentProviderExternalUnchecked(name, null, userId); 8055 if (holder != null) { 8056 return holder.provider.getType(uri); 8057 } 8058 } catch (RemoteException e) { 8059 Log.w(TAG, "Content provider dead retrieving " + uri, e); 8060 return null; 8061 } finally { 8062 if (holder != null) { 8063 removeContentProviderExternalUnchecked(name, null, userId); 8064 } 8065 Binder.restoreCallingIdentity(ident); 8066 } 8067 8068 return null; 8069 } 8070 8071 // ========================================================= 8072 // GLOBAL MANAGEMENT 8073 // ========================================================= 8074 8075 final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess, 8076 boolean isolated) { 8077 String proc = customProcess != null ? customProcess : info.processName; 8078 BatteryStatsImpl.Uid.Proc ps = null; 8079 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 8080 int uid = info.uid; 8081 if (isolated) { 8082 int userId = UserHandle.getUserId(uid); 8083 int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1; 8084 while (true) { 8085 if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID 8086 || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) { 8087 mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID; 8088 } 8089 uid = UserHandle.getUid(userId, mNextIsolatedProcessUid); 8090 mNextIsolatedProcessUid++; 8091 if (mIsolatedProcesses.indexOfKey(uid) < 0) { 8092 // No process for this uid, use it. 8093 break; 8094 } 8095 stepsLeft--; 8096 if (stepsLeft <= 0) { 8097 return null; 8098 } 8099 } 8100 } 8101 return new ProcessRecord(stats, info, proc, uid); 8102 } 8103 8104 final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated) { 8105 ProcessRecord app; 8106 if (!isolated) { 8107 app = getProcessRecordLocked(info.processName, info.uid, true); 8108 } else { 8109 app = null; 8110 } 8111 8112 if (app == null) { 8113 app = newProcessRecordLocked(info, null, isolated); 8114 mProcessNames.put(info.processName, app.uid, app); 8115 if (isolated) { 8116 mIsolatedProcesses.put(app.uid, app); 8117 } 8118 updateLruProcessLocked(app, false, null); 8119 updateOomAdjLocked(); 8120 } 8121 8122 // This package really, really can not be stopped. 8123 try { 8124 AppGlobals.getPackageManager().setPackageStoppedState( 8125 info.packageName, false, UserHandle.getUserId(app.uid)); 8126 } catch (RemoteException e) { 8127 } catch (IllegalArgumentException e) { 8128 Slog.w(TAG, "Failed trying to unstop package " 8129 + info.packageName + ": " + e); 8130 } 8131 8132 if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) 8133 == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) { 8134 app.persistent = true; 8135 app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ; 8136 } 8137 if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) { 8138 mPersistentStartingProcesses.add(app); 8139 startProcessLocked(app, "added application", app.processName); 8140 } 8141 8142 return app; 8143 } 8144 8145 public void unhandledBack() { 8146 enforceCallingPermission(android.Manifest.permission.FORCE_BACK, 8147 "unhandledBack()"); 8148 8149 synchronized(this) { 8150 final long origId = Binder.clearCallingIdentity(); 8151 try { 8152 getFocusedStack().unhandledBackLocked(); 8153 } finally { 8154 Binder.restoreCallingIdentity(origId); 8155 } 8156 } 8157 } 8158 8159 public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException { 8160 enforceNotIsolatedCaller("openContentUri"); 8161 final int userId = UserHandle.getCallingUserId(); 8162 String name = uri.getAuthority(); 8163 ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId); 8164 ParcelFileDescriptor pfd = null; 8165 if (cph != null) { 8166 // We record the binder invoker's uid in thread-local storage before 8167 // going to the content provider to open the file. Later, in the code 8168 // that handles all permissions checks, we look for this uid and use 8169 // that rather than the Activity Manager's own uid. The effect is that 8170 // we do the check against the caller's permissions even though it looks 8171 // to the content provider like the Activity Manager itself is making 8172 // the request. 8173 sCallerIdentity.set(new Identity( 8174 Binder.getCallingPid(), Binder.getCallingUid())); 8175 try { 8176 pfd = cph.provider.openFile(null, uri, "r", null); 8177 } catch (FileNotFoundException e) { 8178 // do nothing; pfd will be returned null 8179 } finally { 8180 // Ensure that whatever happens, we clean up the identity state 8181 sCallerIdentity.remove(); 8182 } 8183 8184 // We've got the fd now, so we're done with the provider. 8185 removeContentProviderExternalUnchecked(name, null, userId); 8186 } else { 8187 Slog.d(TAG, "Failed to get provider for authority '" + name + "'"); 8188 } 8189 return pfd; 8190 } 8191 8192 // Actually is sleeping or shutting down or whatever else in the future 8193 // is an inactive state. 8194 public boolean isSleepingOrShuttingDown() { 8195 return mSleeping || mShuttingDown; 8196 } 8197 8198 public void goingToSleep() { 8199 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER) 8200 != PackageManager.PERMISSION_GRANTED) { 8201 throw new SecurityException("Requires permission " 8202 + android.Manifest.permission.DEVICE_POWER); 8203 } 8204 8205 synchronized(this) { 8206 mWentToSleep = true; 8207 updateEventDispatchingLocked(); 8208 8209 if (!mSleeping) { 8210 mSleeping = true; 8211 mStackSupervisor.goingToSleepLocked(); 8212 8213 // Initialize the wake times of all processes. 8214 checkExcessivePowerUsageLocked(false); 8215 mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 8216 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 8217 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 8218 } 8219 } 8220 } 8221 8222 @Override 8223 public boolean shutdown(int timeout) { 8224 if (checkCallingPermission(android.Manifest.permission.SHUTDOWN) 8225 != PackageManager.PERMISSION_GRANTED) { 8226 throw new SecurityException("Requires permission " 8227 + android.Manifest.permission.SHUTDOWN); 8228 } 8229 8230 boolean timedout = false; 8231 8232 synchronized(this) { 8233 mShuttingDown = true; 8234 updateEventDispatchingLocked(); 8235 timedout = mStackSupervisor.shutdownLocked(timeout); 8236 } 8237 8238 mAppOpsService.shutdown(); 8239 mUsageStatsService.shutdown(); 8240 mBatteryStatsService.shutdown(); 8241 synchronized (this) { 8242 mProcessStats.shutdownLocked(); 8243 } 8244 8245 return timedout; 8246 } 8247 8248 public final void activitySlept(IBinder token) { 8249 if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token); 8250 8251 final long origId = Binder.clearCallingIdentity(); 8252 8253 synchronized (this) { 8254 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 8255 if (r != null) { 8256 mStackSupervisor.activitySleptLocked(r); 8257 } 8258 } 8259 8260 Binder.restoreCallingIdentity(origId); 8261 } 8262 8263 void logLockScreen(String msg) { 8264 if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg + 8265 " mLockScreenShown=" + mLockScreenShown + " mWentToSleep=" + 8266 mWentToSleep + " mSleeping=" + mSleeping + " mDismissKeyguardOnNextActivity=" + 8267 mStackSupervisor.mDismissKeyguardOnNextActivity); 8268 } 8269 8270 private void comeOutOfSleepIfNeededLocked() { 8271 if (!mWentToSleep && !mLockScreenShown) { 8272 if (mSleeping) { 8273 mSleeping = false; 8274 mStackSupervisor.comeOutOfSleepIfNeededLocked(); 8275 } 8276 } 8277 } 8278 8279 public void wakingUp() { 8280 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER) 8281 != PackageManager.PERMISSION_GRANTED) { 8282 throw new SecurityException("Requires permission " 8283 + android.Manifest.permission.DEVICE_POWER); 8284 } 8285 8286 synchronized(this) { 8287 mWentToSleep = false; 8288 updateEventDispatchingLocked(); 8289 comeOutOfSleepIfNeededLocked(); 8290 } 8291 } 8292 8293 private void updateEventDispatchingLocked() { 8294 mWindowManager.setEventDispatching(mBooted && !mWentToSleep && !mShuttingDown); 8295 } 8296 8297 public void setLockScreenShown(boolean shown) { 8298 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER) 8299 != PackageManager.PERMISSION_GRANTED) { 8300 throw new SecurityException("Requires permission " 8301 + android.Manifest.permission.DEVICE_POWER); 8302 } 8303 8304 synchronized(this) { 8305 long ident = Binder.clearCallingIdentity(); 8306 try { 8307 if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown); 8308 mLockScreenShown = shown; 8309 comeOutOfSleepIfNeededLocked(); 8310 } finally { 8311 Binder.restoreCallingIdentity(ident); 8312 } 8313 } 8314 } 8315 8316 public void stopAppSwitches() { 8317 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 8318 != PackageManager.PERMISSION_GRANTED) { 8319 throw new SecurityException("Requires permission " 8320 + android.Manifest.permission.STOP_APP_SWITCHES); 8321 } 8322 8323 synchronized(this) { 8324 mAppSwitchesAllowedTime = SystemClock.uptimeMillis() 8325 + APP_SWITCH_DELAY_TIME; 8326 mDidAppSwitch = false; 8327 mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 8328 Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 8329 mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME); 8330 } 8331 } 8332 8333 public void resumeAppSwitches() { 8334 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 8335 != PackageManager.PERMISSION_GRANTED) { 8336 throw new SecurityException("Requires permission " 8337 + android.Manifest.permission.STOP_APP_SWITCHES); 8338 } 8339 8340 synchronized(this) { 8341 // Note that we don't execute any pending app switches... we will 8342 // let those wait until either the timeout, or the next start 8343 // activity request. 8344 mAppSwitchesAllowedTime = 0; 8345 } 8346 } 8347 8348 boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid, 8349 String name) { 8350 if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) { 8351 return true; 8352 } 8353 8354 final int perm = checkComponentPermission( 8355 android.Manifest.permission.STOP_APP_SWITCHES, callingPid, 8356 callingUid, -1, true); 8357 if (perm == PackageManager.PERMISSION_GRANTED) { 8358 return true; 8359 } 8360 8361 Slog.w(TAG, name + " request from " + callingUid + " stopped"); 8362 return false; 8363 } 8364 8365 public void setDebugApp(String packageName, boolean waitForDebugger, 8366 boolean persistent) { 8367 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP, 8368 "setDebugApp()"); 8369 8370 long ident = Binder.clearCallingIdentity(); 8371 try { 8372 // Note that this is not really thread safe if there are multiple 8373 // callers into it at the same time, but that's not a situation we 8374 // care about. 8375 if (persistent) { 8376 final ContentResolver resolver = mContext.getContentResolver(); 8377 Settings.Global.putString( 8378 resolver, Settings.Global.DEBUG_APP, 8379 packageName); 8380 Settings.Global.putInt( 8381 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 8382 waitForDebugger ? 1 : 0); 8383 } 8384 8385 synchronized (this) { 8386 if (!persistent) { 8387 mOrigDebugApp = mDebugApp; 8388 mOrigWaitForDebugger = mWaitForDebugger; 8389 } 8390 mDebugApp = packageName; 8391 mWaitForDebugger = waitForDebugger; 8392 mDebugTransient = !persistent; 8393 if (packageName != null) { 8394 forceStopPackageLocked(packageName, -1, false, false, true, true, 8395 UserHandle.USER_ALL, "set debug app"); 8396 } 8397 } 8398 } finally { 8399 Binder.restoreCallingIdentity(ident); 8400 } 8401 } 8402 8403 void setOpenGlTraceApp(ApplicationInfo app, String processName) { 8404 synchronized (this) { 8405 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 8406 if (!isDebuggable) { 8407 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 8408 throw new SecurityException("Process not debuggable: " + app.packageName); 8409 } 8410 } 8411 8412 mOpenGlTraceApp = processName; 8413 } 8414 } 8415 8416 void setProfileApp(ApplicationInfo app, String processName, String profileFile, 8417 ParcelFileDescriptor profileFd, boolean autoStopProfiler) { 8418 synchronized (this) { 8419 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 8420 if (!isDebuggable) { 8421 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 8422 throw new SecurityException("Process not debuggable: " + app.packageName); 8423 } 8424 } 8425 mProfileApp = processName; 8426 mProfileFile = profileFile; 8427 if (mProfileFd != null) { 8428 try { 8429 mProfileFd.close(); 8430 } catch (IOException e) { 8431 } 8432 mProfileFd = null; 8433 } 8434 mProfileFd = profileFd; 8435 mProfileType = 0; 8436 mAutoStopProfiler = autoStopProfiler; 8437 } 8438 } 8439 8440 @Override 8441 public void setAlwaysFinish(boolean enabled) { 8442 enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH, 8443 "setAlwaysFinish()"); 8444 8445 Settings.Global.putInt( 8446 mContext.getContentResolver(), 8447 Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0); 8448 8449 synchronized (this) { 8450 mAlwaysFinishActivities = enabled; 8451 } 8452 } 8453 8454 @Override 8455 public void setActivityController(IActivityController controller) { 8456 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 8457 "setActivityController()"); 8458 synchronized (this) { 8459 mController = controller; 8460 Watchdog.getInstance().setActivityController(controller); 8461 } 8462 } 8463 8464 @Override 8465 public void setUserIsMonkey(boolean userIsMonkey) { 8466 synchronized (this) { 8467 synchronized (mPidsSelfLocked) { 8468 final int callingPid = Binder.getCallingPid(); 8469 ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid); 8470 if (precessRecord == null) { 8471 throw new SecurityException("Unknown process: " + callingPid); 8472 } 8473 if (precessRecord.instrumentationUiAutomationConnection == null) { 8474 throw new SecurityException("Only an instrumentation process " 8475 + "with a UiAutomation can call setUserIsMonkey"); 8476 } 8477 } 8478 mUserIsMonkey = userIsMonkey; 8479 } 8480 } 8481 8482 @Override 8483 public boolean isUserAMonkey() { 8484 synchronized (this) { 8485 // If there is a controller also implies the user is a monkey. 8486 return (mUserIsMonkey || mController != null); 8487 } 8488 } 8489 8490 public void requestBugReport() { 8491 enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport"); 8492 SystemProperties.set("ctl.start", "bugreport"); 8493 } 8494 8495 public static long getInputDispatchingTimeoutLocked(ActivityRecord r) { 8496 return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT; 8497 } 8498 8499 public static long getInputDispatchingTimeoutLocked(ProcessRecord r) { 8500 if (r != null && (r.instrumentationClass != null || r.usingWrapper)) { 8501 return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT; 8502 } 8503 return KEY_DISPATCHING_TIMEOUT; 8504 } 8505 8506 @Override 8507 public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) { 8508 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS) 8509 != PackageManager.PERMISSION_GRANTED) { 8510 throw new SecurityException("Requires permission " 8511 + android.Manifest.permission.FILTER_EVENTS); 8512 } 8513 ProcessRecord proc; 8514 long timeout; 8515 synchronized (this) { 8516 synchronized (mPidsSelfLocked) { 8517 proc = mPidsSelfLocked.get(pid); 8518 } 8519 timeout = getInputDispatchingTimeoutLocked(proc); 8520 } 8521 8522 if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) { 8523 return -1; 8524 } 8525 8526 return timeout; 8527 } 8528 8529 /** 8530 * Handle input dispatching timeouts. 8531 * Returns whether input dispatching should be aborted or not. 8532 */ 8533 public boolean inputDispatchingTimedOut(final ProcessRecord proc, 8534 final ActivityRecord activity, final ActivityRecord parent, 8535 final boolean aboveSystem, String reason) { 8536 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS) 8537 != PackageManager.PERMISSION_GRANTED) { 8538 throw new SecurityException("Requires permission " 8539 + android.Manifest.permission.FILTER_EVENTS); 8540 } 8541 8542 final String annotation; 8543 if (reason == null) { 8544 annotation = "Input dispatching timed out"; 8545 } else { 8546 annotation = "Input dispatching timed out (" + reason + ")"; 8547 } 8548 8549 if (proc != null) { 8550 synchronized (this) { 8551 if (proc.debugging) { 8552 return false; 8553 } 8554 8555 if (mDidDexOpt) { 8556 // Give more time since we were dexopting. 8557 mDidDexOpt = false; 8558 return false; 8559 } 8560 8561 if (proc.instrumentationClass != null) { 8562 Bundle info = new Bundle(); 8563 info.putString("shortMsg", "keyDispatchingTimedOut"); 8564 info.putString("longMsg", annotation); 8565 finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info); 8566 return true; 8567 } 8568 } 8569 mHandler.post(new Runnable() { 8570 @Override 8571 public void run() { 8572 appNotResponding(proc, activity, parent, aboveSystem, annotation); 8573 } 8574 }); 8575 } 8576 8577 return true; 8578 } 8579 8580 public Bundle getAssistContextExtras(int requestType) { 8581 enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO, 8582 "getAssistContextExtras()"); 8583 PendingAssistExtras pae; 8584 Bundle extras = new Bundle(); 8585 synchronized (this) { 8586 ActivityRecord activity = getFocusedStack().mResumedActivity; 8587 if (activity == null) { 8588 Slog.w(TAG, "getAssistContextExtras failed: no resumed activity"); 8589 return null; 8590 } 8591 extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName); 8592 if (activity.app == null || activity.app.thread == null) { 8593 Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity); 8594 return extras; 8595 } 8596 if (activity.app.pid == Binder.getCallingPid()) { 8597 Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity); 8598 return extras; 8599 } 8600 pae = new PendingAssistExtras(activity); 8601 try { 8602 activity.app.thread.requestAssistContextExtras(activity.appToken, pae, 8603 requestType); 8604 mPendingAssistExtras.add(pae); 8605 mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT); 8606 } catch (RemoteException e) { 8607 Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity); 8608 return extras; 8609 } 8610 } 8611 synchronized (pae) { 8612 while (!pae.haveResult) { 8613 try { 8614 pae.wait(); 8615 } catch (InterruptedException e) { 8616 } 8617 } 8618 if (pae.result != null) { 8619 extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result); 8620 } 8621 } 8622 synchronized (this) { 8623 mPendingAssistExtras.remove(pae); 8624 mHandler.removeCallbacks(pae); 8625 } 8626 return extras; 8627 } 8628 8629 public void reportAssistContextExtras(IBinder token, Bundle extras) { 8630 PendingAssistExtras pae = (PendingAssistExtras)token; 8631 synchronized (pae) { 8632 pae.result = extras; 8633 pae.haveResult = true; 8634 pae.notifyAll(); 8635 } 8636 } 8637 8638 public void registerProcessObserver(IProcessObserver observer) { 8639 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 8640 "registerProcessObserver()"); 8641 synchronized (this) { 8642 mProcessObservers.register(observer); 8643 } 8644 } 8645 8646 @Override 8647 public void unregisterProcessObserver(IProcessObserver observer) { 8648 synchronized (this) { 8649 mProcessObservers.unregister(observer); 8650 } 8651 } 8652 8653 @Override 8654 public boolean convertFromTranslucent(IBinder token) { 8655 final long origId = Binder.clearCallingIdentity(); 8656 try { 8657 synchronized (this) { 8658 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 8659 if (r == null) { 8660 return false; 8661 } 8662 if (r.changeWindowTranslucency(true)) { 8663 mWindowManager.setAppFullscreen(token, true); 8664 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 8665 return true; 8666 } 8667 return false; 8668 } 8669 } finally { 8670 Binder.restoreCallingIdentity(origId); 8671 } 8672 } 8673 8674 @Override 8675 public boolean convertToTranslucent(IBinder token) { 8676 final long origId = Binder.clearCallingIdentity(); 8677 try { 8678 synchronized (this) { 8679 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 8680 if (r == null) { 8681 return false; 8682 } 8683 if (r.changeWindowTranslucency(false)) { 8684 r.task.stack.convertToTranslucent(r); 8685 mWindowManager.setAppFullscreen(token, false); 8686 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 8687 return true; 8688 } 8689 return false; 8690 } 8691 } finally { 8692 Binder.restoreCallingIdentity(origId); 8693 } 8694 } 8695 8696 @Override 8697 public void setImmersive(IBinder token, boolean immersive) { 8698 synchronized(this) { 8699 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 8700 if (r == null) { 8701 throw new IllegalArgumentException(); 8702 } 8703 r.immersive = immersive; 8704 8705 // update associated state if we're frontmost 8706 if (r == mFocusedActivity) { 8707 if (DEBUG_IMMERSIVE) { 8708 Slog.d(TAG, "Frontmost changed immersion: "+ r); 8709 } 8710 applyUpdateLockStateLocked(r); 8711 } 8712 } 8713 } 8714 8715 @Override 8716 public boolean isImmersive(IBinder token) { 8717 synchronized (this) { 8718 ActivityRecord r = ActivityRecord.isInStackLocked(token); 8719 if (r == null) { 8720 throw new IllegalArgumentException(); 8721 } 8722 return r.immersive; 8723 } 8724 } 8725 8726 public boolean isTopActivityImmersive() { 8727 enforceNotIsolatedCaller("startActivity"); 8728 synchronized (this) { 8729 ActivityRecord r = getFocusedStack().topRunningActivityLocked(null); 8730 return (r != null) ? r.immersive : false; 8731 } 8732 } 8733 8734 public final void enterSafeMode() { 8735 synchronized(this) { 8736 // It only makes sense to do this before the system is ready 8737 // and started launching other packages. 8738 if (!mSystemReady) { 8739 try { 8740 AppGlobals.getPackageManager().enterSafeMode(); 8741 } catch (RemoteException e) { 8742 } 8743 } 8744 } 8745 } 8746 8747 public final void showSafeModeOverlay() { 8748 View v = LayoutInflater.from(mContext).inflate( 8749 com.android.internal.R.layout.safe_mode, null); 8750 WindowManager.LayoutParams lp = new WindowManager.LayoutParams(); 8751 lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY; 8752 lp.width = WindowManager.LayoutParams.WRAP_CONTENT; 8753 lp.height = WindowManager.LayoutParams.WRAP_CONTENT; 8754 lp.gravity = Gravity.BOTTOM | Gravity.START; 8755 lp.format = v.getBackground().getOpacity(); 8756 lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE 8757 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE; 8758 lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS; 8759 ((WindowManager)mContext.getSystemService( 8760 Context.WINDOW_SERVICE)).addView(v, lp); 8761 } 8762 8763 public void noteWakeupAlarm(IIntentSender sender) { 8764 if (!(sender instanceof PendingIntentRecord)) { 8765 return; 8766 } 8767 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 8768 synchronized (stats) { 8769 if (mBatteryStatsService.isOnBattery()) { 8770 mBatteryStatsService.enforceCallingPermission(); 8771 PendingIntentRecord rec = (PendingIntentRecord)sender; 8772 int MY_UID = Binder.getCallingUid(); 8773 int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid; 8774 BatteryStatsImpl.Uid.Pkg pkg = 8775 stats.getPackageStatsLocked(uid, rec.key.packageName); 8776 pkg.incWakeupsLocked(); 8777 } 8778 } 8779 } 8780 8781 public boolean killPids(int[] pids, String pReason, boolean secure) { 8782 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 8783 throw new SecurityException("killPids only available to the system"); 8784 } 8785 String reason = (pReason == null) ? "Unknown" : pReason; 8786 // XXX Note: don't acquire main activity lock here, because the window 8787 // manager calls in with its locks held. 8788 8789 boolean killed = false; 8790 synchronized (mPidsSelfLocked) { 8791 int[] types = new int[pids.length]; 8792 int worstType = 0; 8793 for (int i=0; i<pids.length; i++) { 8794 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 8795 if (proc != null) { 8796 int type = proc.setAdj; 8797 types[i] = type; 8798 if (type > worstType) { 8799 worstType = type; 8800 } 8801 } 8802 } 8803 8804 // If the worst oom_adj is somewhere in the cached proc LRU range, 8805 // then constrain it so we will kill all cached procs. 8806 if (worstType < ProcessList.CACHED_APP_MAX_ADJ 8807 && worstType > ProcessList.CACHED_APP_MIN_ADJ) { 8808 worstType = ProcessList.CACHED_APP_MIN_ADJ; 8809 } 8810 8811 // If this is not a secure call, don't let it kill processes that 8812 // are important. 8813 if (!secure && worstType < ProcessList.SERVICE_ADJ) { 8814 worstType = ProcessList.SERVICE_ADJ; 8815 } 8816 8817 Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType); 8818 for (int i=0; i<pids.length; i++) { 8819 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 8820 if (proc == null) { 8821 continue; 8822 } 8823 int adj = proc.setAdj; 8824 if (adj >= worstType && !proc.killedByAm) { 8825 killUnneededProcessLocked(proc, reason); 8826 killed = true; 8827 } 8828 } 8829 } 8830 return killed; 8831 } 8832 8833 @Override 8834 public void killUid(int uid, String reason) { 8835 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 8836 throw new SecurityException("killUid only available to the system"); 8837 } 8838 synchronized (this) { 8839 killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid), 8840 ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false, 8841 reason != null ? reason : "kill uid"); 8842 } 8843 } 8844 8845 @Override 8846 public boolean killProcessesBelowForeground(String reason) { 8847 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 8848 throw new SecurityException("killProcessesBelowForeground() only available to system"); 8849 } 8850 8851 return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason); 8852 } 8853 8854 private boolean killProcessesBelowAdj(int belowAdj, String reason) { 8855 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 8856 throw new SecurityException("killProcessesBelowAdj() only available to system"); 8857 } 8858 8859 boolean killed = false; 8860 synchronized (mPidsSelfLocked) { 8861 final int size = mPidsSelfLocked.size(); 8862 for (int i = 0; i < size; i++) { 8863 final int pid = mPidsSelfLocked.keyAt(i); 8864 final ProcessRecord proc = mPidsSelfLocked.valueAt(i); 8865 if (proc == null) continue; 8866 8867 final int adj = proc.setAdj; 8868 if (adj > belowAdj && !proc.killedByAm) { 8869 killUnneededProcessLocked(proc, reason); 8870 killed = true; 8871 } 8872 } 8873 } 8874 return killed; 8875 } 8876 8877 @Override 8878 public void hang(final IBinder who, boolean allowRestart) { 8879 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 8880 != PackageManager.PERMISSION_GRANTED) { 8881 throw new SecurityException("Requires permission " 8882 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 8883 } 8884 8885 final IBinder.DeathRecipient death = new DeathRecipient() { 8886 @Override 8887 public void binderDied() { 8888 synchronized (this) { 8889 notifyAll(); 8890 } 8891 } 8892 }; 8893 8894 try { 8895 who.linkToDeath(death, 0); 8896 } catch (RemoteException e) { 8897 Slog.w(TAG, "hang: given caller IBinder is already dead."); 8898 return; 8899 } 8900 8901 synchronized (this) { 8902 Watchdog.getInstance().setAllowRestart(allowRestart); 8903 Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid()); 8904 synchronized (death) { 8905 while (who.isBinderAlive()) { 8906 try { 8907 death.wait(); 8908 } catch (InterruptedException e) { 8909 } 8910 } 8911 } 8912 Watchdog.getInstance().setAllowRestart(true); 8913 } 8914 } 8915 8916 @Override 8917 public void restart() { 8918 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 8919 != PackageManager.PERMISSION_GRANTED) { 8920 throw new SecurityException("Requires permission " 8921 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 8922 } 8923 8924 Log.i(TAG, "Sending shutdown broadcast..."); 8925 8926 BroadcastReceiver br = new BroadcastReceiver() { 8927 @Override public void onReceive(Context context, Intent intent) { 8928 // Now the broadcast is done, finish up the low-level shutdown. 8929 Log.i(TAG, "Shutting down activity manager..."); 8930 shutdown(10000); 8931 Log.i(TAG, "Shutdown complete, restarting!"); 8932 Process.killProcess(Process.myPid()); 8933 System.exit(10); 8934 } 8935 }; 8936 8937 // First send the high-level shut down broadcast. 8938 Intent intent = new Intent(Intent.ACTION_SHUTDOWN); 8939 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 8940 intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true); 8941 /* For now we are not doing a clean shutdown, because things seem to get unhappy. 8942 mContext.sendOrderedBroadcastAsUser(intent, 8943 UserHandle.ALL, null, br, mHandler, 0, null, null); 8944 */ 8945 br.onReceive(mContext, intent); 8946 } 8947 8948 private long getLowRamTimeSinceIdle(long now) { 8949 return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0); 8950 } 8951 8952 @Override 8953 public void performIdleMaintenance() { 8954 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 8955 != PackageManager.PERMISSION_GRANTED) { 8956 throw new SecurityException("Requires permission " 8957 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 8958 } 8959 8960 synchronized (this) { 8961 final long now = SystemClock.uptimeMillis(); 8962 final long timeSinceLastIdle = now - mLastIdleTime; 8963 final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now); 8964 mLastIdleTime = now; 8965 mLowRamTimeSinceLastIdle = 0; 8966 if (mLowRamStartTime != 0) { 8967 mLowRamStartTime = now; 8968 } 8969 8970 StringBuilder sb = new StringBuilder(128); 8971 sb.append("Idle maintenance over "); 8972 TimeUtils.formatDuration(timeSinceLastIdle, sb); 8973 sb.append(" low RAM for "); 8974 TimeUtils.formatDuration(lowRamSinceLastIdle, sb); 8975 Slog.i(TAG, sb.toString()); 8976 8977 // If at least 1/3 of our time since the last idle period has been spent 8978 // with RAM low, then we want to kill processes. 8979 boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3); 8980 8981 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 8982 ProcessRecord proc = mLruProcesses.get(i); 8983 if (proc.notCachedSinceIdle) { 8984 if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP 8985 && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) { 8986 if (doKilling && proc.initialIdlePss != 0 8987 && proc.lastPss > ((proc.initialIdlePss*3)/2)) { 8988 killUnneededProcessLocked(proc, "idle maint (pss " + proc.lastPss 8989 + " from " + proc.initialIdlePss + ")"); 8990 } 8991 } 8992 } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) { 8993 proc.notCachedSinceIdle = true; 8994 proc.initialIdlePss = 0; 8995 proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true, 8996 mSleeping, now); 8997 } 8998 } 8999 9000 mHandler.removeMessages(REQUEST_ALL_PSS_MSG); 9001 mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000); 9002 } 9003 } 9004 9005 public final void startRunning(String pkg, String cls, String action, 9006 String data) { 9007 synchronized(this) { 9008 if (mStartRunning) { 9009 return; 9010 } 9011 mStartRunning = true; 9012 mTopComponent = pkg != null && cls != null 9013 ? new ComponentName(pkg, cls) : null; 9014 mTopAction = action != null ? action : Intent.ACTION_MAIN; 9015 mTopData = data; 9016 if (!mSystemReady) { 9017 return; 9018 } 9019 } 9020 9021 systemReady(null); 9022 } 9023 9024 private void retrieveSettings() { 9025 final ContentResolver resolver = mContext.getContentResolver(); 9026 String debugApp = Settings.Global.getString( 9027 resolver, Settings.Global.DEBUG_APP); 9028 boolean waitForDebugger = Settings.Global.getInt( 9029 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0; 9030 boolean alwaysFinishActivities = Settings.Global.getInt( 9031 resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0; 9032 boolean forceRtl = Settings.Global.getInt( 9033 resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0; 9034 // Transfer any global setting for forcing RTL layout, into a System Property 9035 SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0"); 9036 9037 Configuration configuration = new Configuration(); 9038 Settings.System.getConfiguration(resolver, configuration); 9039 if (forceRtl) { 9040 // This will take care of setting the correct layout direction flags 9041 configuration.setLayoutDirection(configuration.locale); 9042 } 9043 9044 synchronized (this) { 9045 mDebugApp = mOrigDebugApp = debugApp; 9046 mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger; 9047 mAlwaysFinishActivities = alwaysFinishActivities; 9048 // This happens before any activities are started, so we can 9049 // change mConfiguration in-place. 9050 updateConfigurationLocked(configuration, null, false, true); 9051 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration); 9052 } 9053 } 9054 9055 public boolean testIsSystemReady() { 9056 // no need to synchronize(this) just to read & return the value 9057 return mSystemReady; 9058 } 9059 9060 private static File getCalledPreBootReceiversFile() { 9061 File dataDir = Environment.getDataDirectory(); 9062 File systemDir = new File(dataDir, "system"); 9063 File fname = new File(systemDir, "called_pre_boots.dat"); 9064 return fname; 9065 } 9066 9067 static final int LAST_DONE_VERSION = 10000; 9068 9069 private static ArrayList<ComponentName> readLastDonePreBootReceivers() { 9070 ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>(); 9071 File file = getCalledPreBootReceiversFile(); 9072 FileInputStream fis = null; 9073 try { 9074 fis = new FileInputStream(file); 9075 DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048)); 9076 int fvers = dis.readInt(); 9077 if (fvers == LAST_DONE_VERSION) { 9078 String vers = dis.readUTF(); 9079 String codename = dis.readUTF(); 9080 String build = dis.readUTF(); 9081 if (android.os.Build.VERSION.RELEASE.equals(vers) 9082 && android.os.Build.VERSION.CODENAME.equals(codename) 9083 && android.os.Build.VERSION.INCREMENTAL.equals(build)) { 9084 int num = dis.readInt(); 9085 while (num > 0) { 9086 num--; 9087 String pkg = dis.readUTF(); 9088 String cls = dis.readUTF(); 9089 lastDoneReceivers.add(new ComponentName(pkg, cls)); 9090 } 9091 } 9092 } 9093 } catch (FileNotFoundException e) { 9094 } catch (IOException e) { 9095 Slog.w(TAG, "Failure reading last done pre-boot receivers", e); 9096 } finally { 9097 if (fis != null) { 9098 try { 9099 fis.close(); 9100 } catch (IOException e) { 9101 } 9102 } 9103 } 9104 return lastDoneReceivers; 9105 } 9106 9107 private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) { 9108 File file = getCalledPreBootReceiversFile(); 9109 FileOutputStream fos = null; 9110 DataOutputStream dos = null; 9111 try { 9112 Slog.i(TAG, "Writing new set of last done pre-boot receivers..."); 9113 fos = new FileOutputStream(file); 9114 dos = new DataOutputStream(new BufferedOutputStream(fos, 2048)); 9115 dos.writeInt(LAST_DONE_VERSION); 9116 dos.writeUTF(android.os.Build.VERSION.RELEASE); 9117 dos.writeUTF(android.os.Build.VERSION.CODENAME); 9118 dos.writeUTF(android.os.Build.VERSION.INCREMENTAL); 9119 dos.writeInt(list.size()); 9120 for (int i=0; i<list.size(); i++) { 9121 dos.writeUTF(list.get(i).getPackageName()); 9122 dos.writeUTF(list.get(i).getClassName()); 9123 } 9124 } catch (IOException e) { 9125 Slog.w(TAG, "Failure writing last done pre-boot receivers", e); 9126 file.delete(); 9127 } finally { 9128 FileUtils.sync(fos); 9129 if (dos != null) { 9130 try { 9131 dos.close(); 9132 } catch (IOException e) { 9133 // TODO Auto-generated catch block 9134 e.printStackTrace(); 9135 } 9136 } 9137 } 9138 } 9139 9140 public void systemReady(final Runnable goingCallback) { 9141 synchronized(this) { 9142 if (mSystemReady) { 9143 if (goingCallback != null) goingCallback.run(); 9144 return; 9145 } 9146 9147 // Check to see if there are any update receivers to run. 9148 if (!mDidUpdate) { 9149 if (mWaitingUpdate) { 9150 return; 9151 } 9152 Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED); 9153 List<ResolveInfo> ris = null; 9154 try { 9155 ris = AppGlobals.getPackageManager().queryIntentReceivers( 9156 intent, null, 0, 0); 9157 } catch (RemoteException e) { 9158 } 9159 if (ris != null) { 9160 for (int i=ris.size()-1; i>=0; i--) { 9161 if ((ris.get(i).activityInfo.applicationInfo.flags 9162 &ApplicationInfo.FLAG_SYSTEM) == 0) { 9163 ris.remove(i); 9164 } 9165 } 9166 intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE); 9167 9168 ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers(); 9169 9170 final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>(); 9171 for (int i=0; i<ris.size(); i++) { 9172 ActivityInfo ai = ris.get(i).activityInfo; 9173 ComponentName comp = new ComponentName(ai.packageName, ai.name); 9174 if (lastDoneReceivers.contains(comp)) { 9175 ris.remove(i); 9176 i--; 9177 } 9178 } 9179 9180 final int[] users = getUsersLocked(); 9181 for (int i=0; i<ris.size(); i++) { 9182 ActivityInfo ai = ris.get(i).activityInfo; 9183 ComponentName comp = new ComponentName(ai.packageName, ai.name); 9184 doneReceivers.add(comp); 9185 intent.setComponent(comp); 9186 for (int j=0; j<users.length; j++) { 9187 IIntentReceiver finisher = null; 9188 if (i == ris.size()-1 && j == users.length-1) { 9189 finisher = new IIntentReceiver.Stub() { 9190 public void performReceive(Intent intent, int resultCode, 9191 String data, Bundle extras, boolean ordered, 9192 boolean sticky, int sendingUser) { 9193 // The raw IIntentReceiver interface is called 9194 // with the AM lock held, so redispatch to 9195 // execute our code without the lock. 9196 mHandler.post(new Runnable() { 9197 public void run() { 9198 synchronized (ActivityManagerService.this) { 9199 mDidUpdate = true; 9200 } 9201 writeLastDonePreBootReceivers(doneReceivers); 9202 showBootMessage(mContext.getText( 9203 R.string.android_upgrading_complete), 9204 false); 9205 systemReady(goingCallback); 9206 } 9207 }); 9208 } 9209 }; 9210 } 9211 Slog.i(TAG, "Sending system update to " + intent.getComponent() 9212 + " for user " + users[j]); 9213 broadcastIntentLocked(null, null, intent, null, finisher, 9214 0, null, null, null, AppOpsManager.OP_NONE, 9215 true, false, MY_PID, Process.SYSTEM_UID, 9216 users[j]); 9217 if (finisher != null) { 9218 mWaitingUpdate = true; 9219 } 9220 } 9221 } 9222 } 9223 if (mWaitingUpdate) { 9224 return; 9225 } 9226 mDidUpdate = true; 9227 } 9228 9229 mAppOpsService.systemReady(); 9230 mSystemReady = true; 9231 if (!mStartRunning) { 9232 return; 9233 } 9234 } 9235 9236 ArrayList<ProcessRecord> procsToKill = null; 9237 synchronized(mPidsSelfLocked) { 9238 for (int i=mPidsSelfLocked.size()-1; i>=0; i--) { 9239 ProcessRecord proc = mPidsSelfLocked.valueAt(i); 9240 if (!isAllowedWhileBooting(proc.info)){ 9241 if (procsToKill == null) { 9242 procsToKill = new ArrayList<ProcessRecord>(); 9243 } 9244 procsToKill.add(proc); 9245 } 9246 } 9247 } 9248 9249 synchronized(this) { 9250 if (procsToKill != null) { 9251 for (int i=procsToKill.size()-1; i>=0; i--) { 9252 ProcessRecord proc = procsToKill.get(i); 9253 Slog.i(TAG, "Removing system update proc: " + proc); 9254 removeProcessLocked(proc, true, false, "system update done"); 9255 } 9256 } 9257 9258 // Now that we have cleaned up any update processes, we 9259 // are ready to start launching real processes and know that 9260 // we won't trample on them any more. 9261 mProcessesReady = true; 9262 } 9263 9264 Slog.i(TAG, "System now ready"); 9265 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY, 9266 SystemClock.uptimeMillis()); 9267 9268 synchronized(this) { 9269 // Make sure we have no pre-ready processes sitting around. 9270 9271 if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL) { 9272 ResolveInfo ri = mContext.getPackageManager() 9273 .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST), 9274 STOCK_PM_FLAGS); 9275 CharSequence errorMsg = null; 9276 if (ri != null) { 9277 ActivityInfo ai = ri.activityInfo; 9278 ApplicationInfo app = ai.applicationInfo; 9279 if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) { 9280 mTopAction = Intent.ACTION_FACTORY_TEST; 9281 mTopData = null; 9282 mTopComponent = new ComponentName(app.packageName, 9283 ai.name); 9284 } else { 9285 errorMsg = mContext.getResources().getText( 9286 com.android.internal.R.string.factorytest_not_system); 9287 } 9288 } else { 9289 errorMsg = mContext.getResources().getText( 9290 com.android.internal.R.string.factorytest_no_action); 9291 } 9292 if (errorMsg != null) { 9293 mTopAction = null; 9294 mTopData = null; 9295 mTopComponent = null; 9296 Message msg = Message.obtain(); 9297 msg.what = SHOW_FACTORY_ERROR_MSG; 9298 msg.getData().putCharSequence("msg", errorMsg); 9299 mHandler.sendMessage(msg); 9300 } 9301 } 9302 } 9303 9304 retrieveSettings(); 9305 9306 synchronized (this) { 9307 readGrantedUriPermissionsLocked(); 9308 } 9309 9310 if (goingCallback != null) goingCallback.run(); 9311 9312 synchronized (this) { 9313 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) { 9314 try { 9315 List apps = AppGlobals.getPackageManager(). 9316 getPersistentApplications(STOCK_PM_FLAGS); 9317 if (apps != null) { 9318 int N = apps.size(); 9319 int i; 9320 for (i=0; i<N; i++) { 9321 ApplicationInfo info 9322 = (ApplicationInfo)apps.get(i); 9323 if (info != null && 9324 !info.packageName.equals("android")) { 9325 addAppLocked(info, false); 9326 } 9327 } 9328 } 9329 } catch (RemoteException ex) { 9330 // pm is in same process, this will never happen. 9331 } 9332 } 9333 9334 // Start up initial activity. 9335 mBooting = true; 9336 9337 try { 9338 if (AppGlobals.getPackageManager().hasSystemUidErrors()) { 9339 Message msg = Message.obtain(); 9340 msg.what = SHOW_UID_ERROR_MSG; 9341 mHandler.sendMessage(msg); 9342 } 9343 } catch (RemoteException e) { 9344 } 9345 9346 long ident = Binder.clearCallingIdentity(); 9347 try { 9348 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 9349 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 9350 | Intent.FLAG_RECEIVER_FOREGROUND); 9351 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); 9352 broadcastIntentLocked(null, null, intent, 9353 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 9354 false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId); 9355 intent = new Intent(Intent.ACTION_USER_STARTING); 9356 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 9357 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); 9358 broadcastIntentLocked(null, null, intent, 9359 null, new IIntentReceiver.Stub() { 9360 @Override 9361 public void performReceive(Intent intent, int resultCode, String data, 9362 Bundle extras, boolean ordered, boolean sticky, int sendingUser) 9363 throws RemoteException { 9364 } 9365 }, 0, null, null, 9366 android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 9367 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 9368 } finally { 9369 Binder.restoreCallingIdentity(ident); 9370 } 9371 mStackSupervisor.resumeTopActivitiesLocked(); 9372 sendUserSwitchBroadcastsLocked(-1, mCurrentUserId); 9373 } 9374 } 9375 9376 private boolean makeAppCrashingLocked(ProcessRecord app, 9377 String shortMsg, String longMsg, String stackTrace) { 9378 app.crashing = true; 9379 app.crashingReport = generateProcessError(app, 9380 ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace); 9381 startAppProblemLocked(app); 9382 app.stopFreezingAllLocked(); 9383 return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace); 9384 } 9385 9386 private void makeAppNotRespondingLocked(ProcessRecord app, 9387 String activity, String shortMsg, String longMsg) { 9388 app.notResponding = true; 9389 app.notRespondingReport = generateProcessError(app, 9390 ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING, 9391 activity, shortMsg, longMsg, null); 9392 startAppProblemLocked(app); 9393 app.stopFreezingAllLocked(); 9394 } 9395 9396 /** 9397 * Generate a process error record, suitable for attachment to a ProcessRecord. 9398 * 9399 * @param app The ProcessRecord in which the error occurred. 9400 * @param condition Crashing, Application Not Responding, etc. Values are defined in 9401 * ActivityManager.AppErrorStateInfo 9402 * @param activity The activity associated with the crash, if known. 9403 * @param shortMsg Short message describing the crash. 9404 * @param longMsg Long message describing the crash. 9405 * @param stackTrace Full crash stack trace, may be null. 9406 * 9407 * @return Returns a fully-formed AppErrorStateInfo record. 9408 */ 9409 private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app, 9410 int condition, String activity, String shortMsg, String longMsg, String stackTrace) { 9411 ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo(); 9412 9413 report.condition = condition; 9414 report.processName = app.processName; 9415 report.pid = app.pid; 9416 report.uid = app.info.uid; 9417 report.tag = activity; 9418 report.shortMsg = shortMsg; 9419 report.longMsg = longMsg; 9420 report.stackTrace = stackTrace; 9421 9422 return report; 9423 } 9424 9425 void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) { 9426 synchronized (this) { 9427 app.crashing = false; 9428 app.crashingReport = null; 9429 app.notResponding = false; 9430 app.notRespondingReport = null; 9431 if (app.anrDialog == fromDialog) { 9432 app.anrDialog = null; 9433 } 9434 if (app.waitDialog == fromDialog) { 9435 app.waitDialog = null; 9436 } 9437 if (app.pid > 0 && app.pid != MY_PID) { 9438 handleAppCrashLocked(app, null, null, null); 9439 killUnneededProcessLocked(app, "user request after error"); 9440 } 9441 } 9442 } 9443 9444 private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg, 9445 String stackTrace) { 9446 long now = SystemClock.uptimeMillis(); 9447 9448 Long crashTime; 9449 if (!app.isolated) { 9450 crashTime = mProcessCrashTimes.get(app.info.processName, app.uid); 9451 } else { 9452 crashTime = null; 9453 } 9454 if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) { 9455 // This process loses! 9456 Slog.w(TAG, "Process " + app.info.processName 9457 + " has crashed too many times: killing!"); 9458 EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH, 9459 app.userId, app.info.processName, app.uid); 9460 mStackSupervisor.handleAppCrashLocked(app); 9461 if (!app.persistent) { 9462 // We don't want to start this process again until the user 9463 // explicitly does so... but for persistent process, we really 9464 // need to keep it running. If a persistent process is actually 9465 // repeatedly crashing, then badness for everyone. 9466 EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid, 9467 app.info.processName); 9468 if (!app.isolated) { 9469 // XXX We don't have a way to mark isolated processes 9470 // as bad, since they don't have a peristent identity. 9471 mBadProcesses.put(app.info.processName, app.uid, 9472 new BadProcessInfo(now, shortMsg, longMsg, stackTrace)); 9473 mProcessCrashTimes.remove(app.info.processName, app.uid); 9474 } 9475 app.bad = true; 9476 app.removed = true; 9477 // Don't let services in this process be restarted and potentially 9478 // annoy the user repeatedly. Unless it is persistent, since those 9479 // processes run critical code. 9480 removeProcessLocked(app, false, false, "crash"); 9481 mStackSupervisor.resumeTopActivitiesLocked(); 9482 return false; 9483 } 9484 mStackSupervisor.resumeTopActivitiesLocked(); 9485 } else { 9486 mStackSupervisor.finishTopRunningActivityLocked(app); 9487 } 9488 9489 // Bump up the crash count of any services currently running in the proc. 9490 for (int i=app.services.size()-1; i>=0; i--) { 9491 // Any services running in the application need to be placed 9492 // back in the pending list. 9493 ServiceRecord sr = app.services.valueAt(i); 9494 sr.crashCount++; 9495 } 9496 9497 // If the crashing process is what we consider to be the "home process" and it has been 9498 // replaced by a third-party app, clear the package preferred activities from packages 9499 // with a home activity running in the process to prevent a repeatedly crashing app 9500 // from blocking the user to manually clear the list. 9501 final ArrayList<ActivityRecord> activities = app.activities; 9502 if (app == mHomeProcess && activities.size() > 0 9503 && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) { 9504 for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) { 9505 final ActivityRecord r = activities.get(activityNdx); 9506 if (r.isHomeActivity()) { 9507 Log.i(TAG, "Clearing package preferred activities from " + r.packageName); 9508 try { 9509 ActivityThread.getPackageManager() 9510 .clearPackagePreferredActivities(r.packageName); 9511 } catch (RemoteException c) { 9512 // pm is in same process, this will never happen. 9513 } 9514 } 9515 } 9516 } 9517 9518 if (!app.isolated) { 9519 // XXX Can't keep track of crash times for isolated processes, 9520 // because they don't have a perisistent identity. 9521 mProcessCrashTimes.put(app.info.processName, app.uid, now); 9522 } 9523 9524 return true; 9525 } 9526 9527 void startAppProblemLocked(ProcessRecord app) { 9528 if (app.userId == mCurrentUserId) { 9529 app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver( 9530 mContext, app.info.packageName, app.info.flags); 9531 } else { 9532 // If this app is not running under the current user, then we 9533 // can't give it a report button because that would require 9534 // launching the report UI under a different user. 9535 app.errorReportReceiver = null; 9536 } 9537 skipCurrentReceiverLocked(app); 9538 } 9539 9540 void skipCurrentReceiverLocked(ProcessRecord app) { 9541 for (BroadcastQueue queue : mBroadcastQueues) { 9542 queue.skipCurrentReceiverLocked(app); 9543 } 9544 } 9545 9546 /** 9547 * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes. 9548 * The application process will exit immediately after this call returns. 9549 * @param app object of the crashing app, null for the system server 9550 * @param crashInfo describing the exception 9551 */ 9552 public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) { 9553 ProcessRecord r = findAppProcess(app, "Crash"); 9554 final String processName = app == null ? "system_server" 9555 : (r == null ? "unknown" : r.processName); 9556 9557 handleApplicationCrashInner("crash", r, processName, crashInfo); 9558 } 9559 9560 /* Native crash reporting uses this inner version because it needs to be somewhat 9561 * decoupled from the AM-managed cleanup lifecycle 9562 */ 9563 void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName, 9564 ApplicationErrorReport.CrashInfo crashInfo) { 9565 EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(), 9566 UserHandle.getUserId(Binder.getCallingUid()), processName, 9567 r == null ? -1 : r.info.flags, 9568 crashInfo.exceptionClassName, 9569 crashInfo.exceptionMessage, 9570 crashInfo.throwFileName, 9571 crashInfo.throwLineNumber); 9572 9573 addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo); 9574 9575 crashApplication(r, crashInfo); 9576 } 9577 9578 public void handleApplicationStrictModeViolation( 9579 IBinder app, 9580 int violationMask, 9581 StrictMode.ViolationInfo info) { 9582 ProcessRecord r = findAppProcess(app, "StrictMode"); 9583 if (r == null) { 9584 return; 9585 } 9586 9587 if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) { 9588 Integer stackFingerprint = info.hashCode(); 9589 boolean logIt = true; 9590 synchronized (mAlreadyLoggedViolatedStacks) { 9591 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) { 9592 logIt = false; 9593 // TODO: sub-sample into EventLog for these, with 9594 // the info.durationMillis? Then we'd get 9595 // the relative pain numbers, without logging all 9596 // the stack traces repeatedly. We'd want to do 9597 // likewise in the client code, which also does 9598 // dup suppression, before the Binder call. 9599 } else { 9600 if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) { 9601 mAlreadyLoggedViolatedStacks.clear(); 9602 } 9603 mAlreadyLoggedViolatedStacks.add(stackFingerprint); 9604 } 9605 } 9606 if (logIt) { 9607 logStrictModeViolationToDropBox(r, info); 9608 } 9609 } 9610 9611 if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) { 9612 AppErrorResult result = new AppErrorResult(); 9613 synchronized (this) { 9614 final long origId = Binder.clearCallingIdentity(); 9615 9616 Message msg = Message.obtain(); 9617 msg.what = SHOW_STRICT_MODE_VIOLATION_MSG; 9618 HashMap<String, Object> data = new HashMap<String, Object>(); 9619 data.put("result", result); 9620 data.put("app", r); 9621 data.put("violationMask", violationMask); 9622 data.put("info", info); 9623 msg.obj = data; 9624 mHandler.sendMessage(msg); 9625 9626 Binder.restoreCallingIdentity(origId); 9627 } 9628 int res = result.get(); 9629 Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res); 9630 } 9631 } 9632 9633 // Depending on the policy in effect, there could be a bunch of 9634 // these in quick succession so we try to batch these together to 9635 // minimize disk writes, number of dropbox entries, and maximize 9636 // compression, by having more fewer, larger records. 9637 private void logStrictModeViolationToDropBox( 9638 ProcessRecord process, 9639 StrictMode.ViolationInfo info) { 9640 if (info == null) { 9641 return; 9642 } 9643 final boolean isSystemApp = process == null || 9644 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM | 9645 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0; 9646 final String processName = process == null ? "unknown" : process.processName; 9647 final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode"; 9648 final DropBoxManager dbox = (DropBoxManager) 9649 mContext.getSystemService(Context.DROPBOX_SERVICE); 9650 9651 // Exit early if the dropbox isn't configured to accept this report type. 9652 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 9653 9654 boolean bufferWasEmpty; 9655 boolean needsFlush; 9656 final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024); 9657 synchronized (sb) { 9658 bufferWasEmpty = sb.length() == 0; 9659 appendDropBoxProcessHeaders(process, processName, sb); 9660 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 9661 sb.append("System-App: ").append(isSystemApp).append("\n"); 9662 sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n"); 9663 if (info.violationNumThisLoop != 0) { 9664 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n"); 9665 } 9666 if (info.numAnimationsRunning != 0) { 9667 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n"); 9668 } 9669 if (info.broadcastIntentAction != null) { 9670 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n"); 9671 } 9672 if (info.durationMillis != -1) { 9673 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n"); 9674 } 9675 if (info.numInstances != -1) { 9676 sb.append("Instance-Count: ").append(info.numInstances).append("\n"); 9677 } 9678 if (info.tags != null) { 9679 for (String tag : info.tags) { 9680 sb.append("Span-Tag: ").append(tag).append("\n"); 9681 } 9682 } 9683 sb.append("\n"); 9684 if (info.crashInfo != null && info.crashInfo.stackTrace != null) { 9685 sb.append(info.crashInfo.stackTrace); 9686 } 9687 sb.append("\n"); 9688 9689 // Only buffer up to ~64k. Various logging bits truncate 9690 // things at 128k. 9691 needsFlush = (sb.length() > 64 * 1024); 9692 } 9693 9694 // Flush immediately if the buffer's grown too large, or this 9695 // is a non-system app. Non-system apps are isolated with a 9696 // different tag & policy and not batched. 9697 // 9698 // Batching is useful during internal testing with 9699 // StrictMode settings turned up high. Without batching, 9700 // thousands of separate files could be created on boot. 9701 if (!isSystemApp || needsFlush) { 9702 new Thread("Error dump: " + dropboxTag) { 9703 @Override 9704 public void run() { 9705 String report; 9706 synchronized (sb) { 9707 report = sb.toString(); 9708 sb.delete(0, sb.length()); 9709 sb.trimToSize(); 9710 } 9711 if (report.length() != 0) { 9712 dbox.addText(dropboxTag, report); 9713 } 9714 } 9715 }.start(); 9716 return; 9717 } 9718 9719 // System app batching: 9720 if (!bufferWasEmpty) { 9721 // An existing dropbox-writing thread is outstanding, so 9722 // we don't need to start it up. The existing thread will 9723 // catch the buffer appends we just did. 9724 return; 9725 } 9726 9727 // Worker thread to both batch writes and to avoid blocking the caller on I/O. 9728 // (After this point, we shouldn't access AMS internal data structures.) 9729 new Thread("Error dump: " + dropboxTag) { 9730 @Override 9731 public void run() { 9732 // 5 second sleep to let stacks arrive and be batched together 9733 try { 9734 Thread.sleep(5000); // 5 seconds 9735 } catch (InterruptedException e) {} 9736 9737 String errorReport; 9738 synchronized (mStrictModeBuffer) { 9739 errorReport = mStrictModeBuffer.toString(); 9740 if (errorReport.length() == 0) { 9741 return; 9742 } 9743 mStrictModeBuffer.delete(0, mStrictModeBuffer.length()); 9744 mStrictModeBuffer.trimToSize(); 9745 } 9746 dbox.addText(dropboxTag, errorReport); 9747 } 9748 }.start(); 9749 } 9750 9751 /** 9752 * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors. 9753 * @param app object of the crashing app, null for the system server 9754 * @param tag reported by the caller 9755 * @param crashInfo describing the context of the error 9756 * @return true if the process should exit immediately (WTF is fatal) 9757 */ 9758 public boolean handleApplicationWtf(IBinder app, String tag, 9759 ApplicationErrorReport.CrashInfo crashInfo) { 9760 ProcessRecord r = findAppProcess(app, "WTF"); 9761 final String processName = app == null ? "system_server" 9762 : (r == null ? "unknown" : r.processName); 9763 9764 EventLog.writeEvent(EventLogTags.AM_WTF, 9765 UserHandle.getUserId(Binder.getCallingUid()), Binder.getCallingPid(), 9766 processName, 9767 r == null ? -1 : r.info.flags, 9768 tag, crashInfo.exceptionMessage); 9769 9770 addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo); 9771 9772 if (r != null && r.pid != Process.myPid() && 9773 Settings.Global.getInt(mContext.getContentResolver(), 9774 Settings.Global.WTF_IS_FATAL, 0) != 0) { 9775 crashApplication(r, crashInfo); 9776 return true; 9777 } else { 9778 return false; 9779 } 9780 } 9781 9782 /** 9783 * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit}) 9784 * @return the corresponding {@link ProcessRecord} object, or null if none could be found 9785 */ 9786 private ProcessRecord findAppProcess(IBinder app, String reason) { 9787 if (app == null) { 9788 return null; 9789 } 9790 9791 synchronized (this) { 9792 final int NP = mProcessNames.getMap().size(); 9793 for (int ip=0; ip<NP; ip++) { 9794 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 9795 final int NA = apps.size(); 9796 for (int ia=0; ia<NA; ia++) { 9797 ProcessRecord p = apps.valueAt(ia); 9798 if (p.thread != null && p.thread.asBinder() == app) { 9799 return p; 9800 } 9801 } 9802 } 9803 9804 Slog.w(TAG, "Can't find mystery application for " + reason 9805 + " from pid=" + Binder.getCallingPid() 9806 + " uid=" + Binder.getCallingUid() + ": " + app); 9807 return null; 9808 } 9809 } 9810 9811 /** 9812 * Utility function for addErrorToDropBox and handleStrictModeViolation's logging 9813 * to append various headers to the dropbox log text. 9814 */ 9815 private void appendDropBoxProcessHeaders(ProcessRecord process, String processName, 9816 StringBuilder sb) { 9817 // Watchdog thread ends up invoking this function (with 9818 // a null ProcessRecord) to add the stack file to dropbox. 9819 // Do not acquire a lock on this (am) in such cases, as it 9820 // could cause a potential deadlock, if and when watchdog 9821 // is invoked due to unavailability of lock on am and it 9822 // would prevent watchdog from killing system_server. 9823 if (process == null) { 9824 sb.append("Process: ").append(processName).append("\n"); 9825 return; 9826 } 9827 // Note: ProcessRecord 'process' is guarded by the service 9828 // instance. (notably process.pkgList, which could otherwise change 9829 // concurrently during execution of this method) 9830 synchronized (this) { 9831 sb.append("Process: ").append(processName).append("\n"); 9832 int flags = process.info.flags; 9833 IPackageManager pm = AppGlobals.getPackageManager(); 9834 sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n"); 9835 for (int ip=0; ip<process.pkgList.size(); ip++) { 9836 String pkg = process.pkgList.keyAt(ip); 9837 sb.append("Package: ").append(pkg); 9838 try { 9839 PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId()); 9840 if (pi != null) { 9841 sb.append(" v").append(pi.versionCode); 9842 if (pi.versionName != null) { 9843 sb.append(" (").append(pi.versionName).append(")"); 9844 } 9845 } 9846 } catch (RemoteException e) { 9847 Slog.e(TAG, "Error getting package info: " + pkg, e); 9848 } 9849 sb.append("\n"); 9850 } 9851 } 9852 } 9853 9854 private static String processClass(ProcessRecord process) { 9855 if (process == null || process.pid == MY_PID) { 9856 return "system_server"; 9857 } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) { 9858 return "system_app"; 9859 } else { 9860 return "data_app"; 9861 } 9862 } 9863 9864 /** 9865 * Write a description of an error (crash, WTF, ANR) to the drop box. 9866 * @param eventType to include in the drop box tag ("crash", "wtf", etc.) 9867 * @param process which caused the error, null means the system server 9868 * @param activity which triggered the error, null if unknown 9869 * @param parent activity related to the error, null if unknown 9870 * @param subject line related to the error, null if absent 9871 * @param report in long form describing the error, null if absent 9872 * @param logFile to include in the report, null if none 9873 * @param crashInfo giving an application stack trace, null if absent 9874 */ 9875 public void addErrorToDropBox(String eventType, 9876 ProcessRecord process, String processName, ActivityRecord activity, 9877 ActivityRecord parent, String subject, 9878 final String report, final File logFile, 9879 final ApplicationErrorReport.CrashInfo crashInfo) { 9880 // NOTE -- this must never acquire the ActivityManagerService lock, 9881 // otherwise the watchdog may be prevented from resetting the system. 9882 9883 final String dropboxTag = processClass(process) + "_" + eventType; 9884 final DropBoxManager dbox = (DropBoxManager) 9885 mContext.getSystemService(Context.DROPBOX_SERVICE); 9886 9887 // Exit early if the dropbox isn't configured to accept this report type. 9888 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 9889 9890 final StringBuilder sb = new StringBuilder(1024); 9891 appendDropBoxProcessHeaders(process, processName, sb); 9892 if (activity != null) { 9893 sb.append("Activity: ").append(activity.shortComponentName).append("\n"); 9894 } 9895 if (parent != null && parent.app != null && parent.app.pid != process.pid) { 9896 sb.append("Parent-Process: ").append(parent.app.processName).append("\n"); 9897 } 9898 if (parent != null && parent != activity) { 9899 sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n"); 9900 } 9901 if (subject != null) { 9902 sb.append("Subject: ").append(subject).append("\n"); 9903 } 9904 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 9905 if (Debug.isDebuggerConnected()) { 9906 sb.append("Debugger: Connected\n"); 9907 } 9908 sb.append("\n"); 9909 9910 // Do the rest in a worker thread to avoid blocking the caller on I/O 9911 // (After this point, we shouldn't access AMS internal data structures.) 9912 Thread worker = new Thread("Error dump: " + dropboxTag) { 9913 @Override 9914 public void run() { 9915 if (report != null) { 9916 sb.append(report); 9917 } 9918 if (logFile != null) { 9919 try { 9920 sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE, 9921 "\n\n[[TRUNCATED]]")); 9922 } catch (IOException e) { 9923 Slog.e(TAG, "Error reading " + logFile, e); 9924 } 9925 } 9926 if (crashInfo != null && crashInfo.stackTrace != null) { 9927 sb.append(crashInfo.stackTrace); 9928 } 9929 9930 String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag; 9931 int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0); 9932 if (lines > 0) { 9933 sb.append("\n"); 9934 9935 // Merge several logcat streams, and take the last N lines 9936 InputStreamReader input = null; 9937 try { 9938 java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat", 9939 "-v", "time", "-b", "events", "-b", "system", "-b", "main", 9940 "-t", String.valueOf(lines)).redirectErrorStream(true).start(); 9941 9942 try { logcat.getOutputStream().close(); } catch (IOException e) {} 9943 try { logcat.getErrorStream().close(); } catch (IOException e) {} 9944 input = new InputStreamReader(logcat.getInputStream()); 9945 9946 int num; 9947 char[] buf = new char[8192]; 9948 while ((num = input.read(buf)) > 0) sb.append(buf, 0, num); 9949 } catch (IOException e) { 9950 Slog.e(TAG, "Error running logcat", e); 9951 } finally { 9952 if (input != null) try { input.close(); } catch (IOException e) {} 9953 } 9954 } 9955 9956 dbox.addText(dropboxTag, sb.toString()); 9957 } 9958 }; 9959 9960 if (process == null) { 9961 // If process is null, we are being called from some internal code 9962 // and may be about to die -- run this synchronously. 9963 worker.run(); 9964 } else { 9965 worker.start(); 9966 } 9967 } 9968 9969 /** 9970 * Bring up the "unexpected error" dialog box for a crashing app. 9971 * Deal with edge cases (intercepts from instrumented applications, 9972 * ActivityController, error intent receivers, that sort of thing). 9973 * @param r the application crashing 9974 * @param crashInfo describing the failure 9975 */ 9976 private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) { 9977 long timeMillis = System.currentTimeMillis(); 9978 String shortMsg = crashInfo.exceptionClassName; 9979 String longMsg = crashInfo.exceptionMessage; 9980 String stackTrace = crashInfo.stackTrace; 9981 if (shortMsg != null && longMsg != null) { 9982 longMsg = shortMsg + ": " + longMsg; 9983 } else if (shortMsg != null) { 9984 longMsg = shortMsg; 9985 } 9986 9987 AppErrorResult result = new AppErrorResult(); 9988 synchronized (this) { 9989 if (mController != null) { 9990 try { 9991 String name = r != null ? r.processName : null; 9992 int pid = r != null ? r.pid : Binder.getCallingPid(); 9993 if (!mController.appCrashed(name, pid, 9994 shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) { 9995 Slog.w(TAG, "Force-killing crashed app " + name 9996 + " at watcher's request"); 9997 Process.killProcess(pid); 9998 return; 9999 } 10000 } catch (RemoteException e) { 10001 mController = null; 10002 Watchdog.getInstance().setActivityController(null); 10003 } 10004 } 10005 10006 final long origId = Binder.clearCallingIdentity(); 10007 10008 // If this process is running instrumentation, finish it. 10009 if (r != null && r.instrumentationClass != null) { 10010 Slog.w(TAG, "Error in app " + r.processName 10011 + " running instrumentation " + r.instrumentationClass + ":"); 10012 if (shortMsg != null) Slog.w(TAG, " " + shortMsg); 10013 if (longMsg != null) Slog.w(TAG, " " + longMsg); 10014 Bundle info = new Bundle(); 10015 info.putString("shortMsg", shortMsg); 10016 info.putString("longMsg", longMsg); 10017 finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info); 10018 Binder.restoreCallingIdentity(origId); 10019 return; 10020 } 10021 10022 // If we can't identify the process or it's already exceeded its crash quota, 10023 // quit right away without showing a crash dialog. 10024 if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) { 10025 Binder.restoreCallingIdentity(origId); 10026 return; 10027 } 10028 10029 Message msg = Message.obtain(); 10030 msg.what = SHOW_ERROR_MSG; 10031 HashMap data = new HashMap(); 10032 data.put("result", result); 10033 data.put("app", r); 10034 msg.obj = data; 10035 mHandler.sendMessage(msg); 10036 10037 Binder.restoreCallingIdentity(origId); 10038 } 10039 10040 int res = result.get(); 10041 10042 Intent appErrorIntent = null; 10043 synchronized (this) { 10044 if (r != null && !r.isolated) { 10045 // XXX Can't keep track of crash time for isolated processes, 10046 // since they don't have a persistent identity. 10047 mProcessCrashTimes.put(r.info.processName, r.uid, 10048 SystemClock.uptimeMillis()); 10049 } 10050 if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) { 10051 appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo); 10052 } 10053 } 10054 10055 if (appErrorIntent != null) { 10056 try { 10057 mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId)); 10058 } catch (ActivityNotFoundException e) { 10059 Slog.w(TAG, "bug report receiver dissappeared", e); 10060 } 10061 } 10062 } 10063 10064 Intent createAppErrorIntentLocked(ProcessRecord r, 10065 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 10066 ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo); 10067 if (report == null) { 10068 return null; 10069 } 10070 Intent result = new Intent(Intent.ACTION_APP_ERROR); 10071 result.setComponent(r.errorReportReceiver); 10072 result.putExtra(Intent.EXTRA_BUG_REPORT, report); 10073 result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 10074 return result; 10075 } 10076 10077 private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r, 10078 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 10079 if (r.errorReportReceiver == null) { 10080 return null; 10081 } 10082 10083 if (!r.crashing && !r.notResponding && !r.forceCrashReport) { 10084 return null; 10085 } 10086 10087 ApplicationErrorReport report = new ApplicationErrorReport(); 10088 report.packageName = r.info.packageName; 10089 report.installerPackageName = r.errorReportReceiver.getPackageName(); 10090 report.processName = r.processName; 10091 report.time = timeMillis; 10092 report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0; 10093 10094 if (r.crashing || r.forceCrashReport) { 10095 report.type = ApplicationErrorReport.TYPE_CRASH; 10096 report.crashInfo = crashInfo; 10097 } else if (r.notResponding) { 10098 report.type = ApplicationErrorReport.TYPE_ANR; 10099 report.anrInfo = new ApplicationErrorReport.AnrInfo(); 10100 10101 report.anrInfo.activity = r.notRespondingReport.tag; 10102 report.anrInfo.cause = r.notRespondingReport.shortMsg; 10103 report.anrInfo.info = r.notRespondingReport.longMsg; 10104 } 10105 10106 return report; 10107 } 10108 10109 public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() { 10110 enforceNotIsolatedCaller("getProcessesInErrorState"); 10111 // assume our apps are happy - lazy create the list 10112 List<ActivityManager.ProcessErrorStateInfo> errList = null; 10113 10114 final boolean allUsers = ActivityManager.checkUidPermission( 10115 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 10116 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 10117 int userId = UserHandle.getUserId(Binder.getCallingUid()); 10118 10119 synchronized (this) { 10120 10121 // iterate across all processes 10122 for (int i=mLruProcesses.size()-1; i>=0; i--) { 10123 ProcessRecord app = mLruProcesses.get(i); 10124 if (!allUsers && app.userId != userId) { 10125 continue; 10126 } 10127 if ((app.thread != null) && (app.crashing || app.notResponding)) { 10128 // This one's in trouble, so we'll generate a report for it 10129 // crashes are higher priority (in case there's a crash *and* an anr) 10130 ActivityManager.ProcessErrorStateInfo report = null; 10131 if (app.crashing) { 10132 report = app.crashingReport; 10133 } else if (app.notResponding) { 10134 report = app.notRespondingReport; 10135 } 10136 10137 if (report != null) { 10138 if (errList == null) { 10139 errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1); 10140 } 10141 errList.add(report); 10142 } else { 10143 Slog.w(TAG, "Missing app error report, app = " + app.processName + 10144 " crashing = " + app.crashing + 10145 " notResponding = " + app.notResponding); 10146 } 10147 } 10148 } 10149 } 10150 10151 return errList; 10152 } 10153 10154 static int oomAdjToImportance(int adj, ActivityManager.RunningAppProcessInfo currApp) { 10155 if (adj >= ProcessList.CACHED_APP_MIN_ADJ) { 10156 if (currApp != null) { 10157 currApp.lru = adj - ProcessList.CACHED_APP_MIN_ADJ + 1; 10158 } 10159 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 10160 } else if (adj >= ProcessList.SERVICE_B_ADJ) { 10161 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 10162 } else if (adj >= ProcessList.HOME_APP_ADJ) { 10163 if (currApp != null) { 10164 currApp.lru = 0; 10165 } 10166 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 10167 } else if (adj >= ProcessList.SERVICE_ADJ) { 10168 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 10169 } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 10170 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE; 10171 } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) { 10172 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE; 10173 } else if (adj >= ProcessList.VISIBLE_APP_ADJ) { 10174 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE; 10175 } else { 10176 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND; 10177 } 10178 } 10179 10180 private void fillInProcMemInfo(ProcessRecord app, 10181 ActivityManager.RunningAppProcessInfo outInfo) { 10182 outInfo.pid = app.pid; 10183 outInfo.uid = app.info.uid; 10184 if (mHeavyWeightProcess == app) { 10185 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE; 10186 } 10187 if (app.persistent) { 10188 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT; 10189 } 10190 if (app.activities.size() > 0) { 10191 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES; 10192 } 10193 outInfo.lastTrimLevel = app.trimMemoryLevel; 10194 int adj = app.curAdj; 10195 outInfo.importance = oomAdjToImportance(adj, outInfo); 10196 outInfo.importanceReasonCode = app.adjTypeCode; 10197 } 10198 10199 public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() { 10200 enforceNotIsolatedCaller("getRunningAppProcesses"); 10201 // Lazy instantiation of list 10202 List<ActivityManager.RunningAppProcessInfo> runList = null; 10203 final boolean allUsers = ActivityManager.checkUidPermission( 10204 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 10205 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 10206 int userId = UserHandle.getUserId(Binder.getCallingUid()); 10207 synchronized (this) { 10208 // Iterate across all processes 10209 for (int i=mLruProcesses.size()-1; i>=0; i--) { 10210 ProcessRecord app = mLruProcesses.get(i); 10211 if (!allUsers && app.userId != userId) { 10212 continue; 10213 } 10214 if ((app.thread != null) && (!app.crashing && !app.notResponding)) { 10215 // Generate process state info for running application 10216 ActivityManager.RunningAppProcessInfo currApp = 10217 new ActivityManager.RunningAppProcessInfo(app.processName, 10218 app.pid, app.getPackageList()); 10219 fillInProcMemInfo(app, currApp); 10220 if (app.adjSource instanceof ProcessRecord) { 10221 currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid; 10222 currApp.importanceReasonImportance = oomAdjToImportance( 10223 app.adjSourceOom, null); 10224 } else if (app.adjSource instanceof ActivityRecord) { 10225 ActivityRecord r = (ActivityRecord)app.adjSource; 10226 if (r.app != null) currApp.importanceReasonPid = r.app.pid; 10227 } 10228 if (app.adjTarget instanceof ComponentName) { 10229 currApp.importanceReasonComponent = (ComponentName)app.adjTarget; 10230 } 10231 //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance 10232 // + " lru=" + currApp.lru); 10233 if (runList == null) { 10234 runList = new ArrayList<ActivityManager.RunningAppProcessInfo>(); 10235 } 10236 runList.add(currApp); 10237 } 10238 } 10239 } 10240 return runList; 10241 } 10242 10243 public List<ApplicationInfo> getRunningExternalApplications() { 10244 enforceNotIsolatedCaller("getRunningExternalApplications"); 10245 List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses(); 10246 List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>(); 10247 if (runningApps != null && runningApps.size() > 0) { 10248 Set<String> extList = new HashSet<String>(); 10249 for (ActivityManager.RunningAppProcessInfo app : runningApps) { 10250 if (app.pkgList != null) { 10251 for (String pkg : app.pkgList) { 10252 extList.add(pkg); 10253 } 10254 } 10255 } 10256 IPackageManager pm = AppGlobals.getPackageManager(); 10257 for (String pkg : extList) { 10258 try { 10259 ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId()); 10260 if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) { 10261 retList.add(info); 10262 } 10263 } catch (RemoteException e) { 10264 } 10265 } 10266 } 10267 return retList; 10268 } 10269 10270 @Override 10271 public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) { 10272 enforceNotIsolatedCaller("getMyMemoryState"); 10273 synchronized (this) { 10274 ProcessRecord proc; 10275 synchronized (mPidsSelfLocked) { 10276 proc = mPidsSelfLocked.get(Binder.getCallingPid()); 10277 } 10278 fillInProcMemInfo(proc, outInfo); 10279 } 10280 } 10281 10282 @Override 10283 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 10284 if (checkCallingPermission(android.Manifest.permission.DUMP) 10285 != PackageManager.PERMISSION_GRANTED) { 10286 pw.println("Permission Denial: can't dump ActivityManager from from pid=" 10287 + Binder.getCallingPid() 10288 + ", uid=" + Binder.getCallingUid() 10289 + " without permission " 10290 + android.Manifest.permission.DUMP); 10291 return; 10292 } 10293 10294 boolean dumpAll = false; 10295 boolean dumpClient = false; 10296 String dumpPackage = null; 10297 10298 int opti = 0; 10299 while (opti < args.length) { 10300 String opt = args[opti]; 10301 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 10302 break; 10303 } 10304 opti++; 10305 if ("-a".equals(opt)) { 10306 dumpAll = true; 10307 } else if ("-c".equals(opt)) { 10308 dumpClient = true; 10309 } else if ("-h".equals(opt)) { 10310 pw.println("Activity manager dump options:"); 10311 pw.println(" [-a] [-c] [-h] [cmd] ..."); 10312 pw.println(" cmd may be one of:"); 10313 pw.println(" a[ctivities]: activity stack state"); 10314 pw.println(" b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state"); 10315 pw.println(" i[ntents] [PACKAGE_NAME]: pending intent state"); 10316 pw.println(" p[rocesses] [PACKAGE_NAME]: process state"); 10317 pw.println(" o[om]: out of memory management"); 10318 pw.println(" prov[iders] [COMP_SPEC ...]: content provider state"); 10319 pw.println(" provider [COMP_SPEC]: provider client-side state"); 10320 pw.println(" s[ervices] [COMP_SPEC ...]: service state"); 10321 pw.println(" service [COMP_SPEC]: service client-side state"); 10322 pw.println(" package [PACKAGE_NAME]: all state related to given package"); 10323 pw.println(" all: dump all activities"); 10324 pw.println(" top: dump the top activity"); 10325 pw.println(" cmd may also be a COMP_SPEC to dump activities."); 10326 pw.println(" COMP_SPEC may be a component name (com.foo/.myApp),"); 10327 pw.println(" a partial substring in a component name, a"); 10328 pw.println(" hex object identifier."); 10329 pw.println(" -a: include all available server state."); 10330 pw.println(" -c: include client state."); 10331 return; 10332 } else { 10333 pw.println("Unknown argument: " + opt + "; use -h for help"); 10334 } 10335 } 10336 10337 long origId = Binder.clearCallingIdentity(); 10338 boolean more = false; 10339 // Is the caller requesting to dump a particular piece of data? 10340 if (opti < args.length) { 10341 String cmd = args[opti]; 10342 opti++; 10343 if ("activities".equals(cmd) || "a".equals(cmd)) { 10344 synchronized (this) { 10345 dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null); 10346 } 10347 } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) { 10348 String[] newArgs; 10349 String name; 10350 if (opti >= args.length) { 10351 name = null; 10352 newArgs = EMPTY_STRING_ARRAY; 10353 } else { 10354 name = args[opti]; 10355 opti++; 10356 newArgs = new String[args.length - opti]; 10357 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 10358 args.length - opti); 10359 } 10360 synchronized (this) { 10361 dumpBroadcastsLocked(fd, pw, args, opti, true, name); 10362 } 10363 } else if ("intents".equals(cmd) || "i".equals(cmd)) { 10364 String[] newArgs; 10365 String name; 10366 if (opti >= args.length) { 10367 name = null; 10368 newArgs = EMPTY_STRING_ARRAY; 10369 } else { 10370 name = args[opti]; 10371 opti++; 10372 newArgs = new String[args.length - opti]; 10373 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 10374 args.length - opti); 10375 } 10376 synchronized (this) { 10377 dumpPendingIntentsLocked(fd, pw, args, opti, true, name); 10378 } 10379 } else if ("processes".equals(cmd) || "p".equals(cmd)) { 10380 String[] newArgs; 10381 String name; 10382 if (opti >= args.length) { 10383 name = null; 10384 newArgs = EMPTY_STRING_ARRAY; 10385 } else { 10386 name = args[opti]; 10387 opti++; 10388 newArgs = new String[args.length - opti]; 10389 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 10390 args.length - opti); 10391 } 10392 synchronized (this) { 10393 dumpProcessesLocked(fd, pw, args, opti, true, name); 10394 } 10395 } else if ("oom".equals(cmd) || "o".equals(cmd)) { 10396 synchronized (this) { 10397 dumpOomLocked(fd, pw, args, opti, true); 10398 } 10399 } else if ("provider".equals(cmd)) { 10400 String[] newArgs; 10401 String name; 10402 if (opti >= args.length) { 10403 name = null; 10404 newArgs = EMPTY_STRING_ARRAY; 10405 } else { 10406 name = args[opti]; 10407 opti++; 10408 newArgs = new String[args.length - opti]; 10409 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti); 10410 } 10411 if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) { 10412 pw.println("No providers match: " + name); 10413 pw.println("Use -h for help."); 10414 } 10415 } else if ("providers".equals(cmd) || "prov".equals(cmd)) { 10416 synchronized (this) { 10417 dumpProvidersLocked(fd, pw, args, opti, true, null); 10418 } 10419 } else if ("service".equals(cmd)) { 10420 String[] newArgs; 10421 String name; 10422 if (opti >= args.length) { 10423 name = null; 10424 newArgs = EMPTY_STRING_ARRAY; 10425 } else { 10426 name = args[opti]; 10427 opti++; 10428 newArgs = new String[args.length - opti]; 10429 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 10430 args.length - opti); 10431 } 10432 if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) { 10433 pw.println("No services match: " + name); 10434 pw.println("Use -h for help."); 10435 } 10436 } else if ("package".equals(cmd)) { 10437 String[] newArgs; 10438 if (opti >= args.length) { 10439 pw.println("package: no package name specified"); 10440 pw.println("Use -h for help."); 10441 } else { 10442 dumpPackage = args[opti]; 10443 opti++; 10444 newArgs = new String[args.length - opti]; 10445 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 10446 args.length - opti); 10447 args = newArgs; 10448 opti = 0; 10449 more = true; 10450 } 10451 } else if ("services".equals(cmd) || "s".equals(cmd)) { 10452 synchronized (this) { 10453 mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null); 10454 } 10455 } else { 10456 // Dumping a single activity? 10457 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) { 10458 pw.println("Bad activity command, or no activities match: " + cmd); 10459 pw.println("Use -h for help."); 10460 } 10461 } 10462 if (!more) { 10463 Binder.restoreCallingIdentity(origId); 10464 return; 10465 } 10466 } 10467 10468 // No piece of data specified, dump everything. 10469 synchronized (this) { 10470 dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 10471 pw.println(); 10472 if (dumpAll) { 10473 pw.println("-------------------------------------------------------------------------------"); 10474 } 10475 dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 10476 pw.println(); 10477 if (dumpAll) { 10478 pw.println("-------------------------------------------------------------------------------"); 10479 } 10480 dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage); 10481 pw.println(); 10482 if (dumpAll) { 10483 pw.println("-------------------------------------------------------------------------------"); 10484 } 10485 mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 10486 pw.println(); 10487 if (dumpAll) { 10488 pw.println("-------------------------------------------------------------------------------"); 10489 } 10490 dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 10491 pw.println(); 10492 if (dumpAll) { 10493 pw.println("-------------------------------------------------------------------------------"); 10494 } 10495 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage); 10496 } 10497 Binder.restoreCallingIdentity(origId); 10498 } 10499 10500 void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 10501 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) { 10502 pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)"); 10503 10504 boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient, 10505 dumpPackage); 10506 boolean needSep = printedAnything; 10507 10508 boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity, 10509 dumpPackage, needSep, " mFocusedActivity: "); 10510 if (printed) { 10511 printedAnything = true; 10512 needSep = false; 10513 } 10514 10515 if (dumpPackage == null) { 10516 if (needSep) { 10517 pw.println(); 10518 } 10519 needSep = true; 10520 printedAnything = true; 10521 mStackSupervisor.dump(pw, " "); 10522 } 10523 10524 if (mRecentTasks.size() > 0) { 10525 boolean printedHeader = false; 10526 10527 final int N = mRecentTasks.size(); 10528 for (int i=0; i<N; i++) { 10529 TaskRecord tr = mRecentTasks.get(i); 10530 if (dumpPackage != null) { 10531 if (tr.realActivity == null || 10532 !dumpPackage.equals(tr.realActivity)) { 10533 continue; 10534 } 10535 } 10536 if (!printedHeader) { 10537 if (needSep) { 10538 pw.println(); 10539 } 10540 pw.println(" Recent tasks:"); 10541 printedHeader = true; 10542 printedAnything = true; 10543 } 10544 pw.print(" * Recent #"); pw.print(i); pw.print(": "); 10545 pw.println(tr); 10546 if (dumpAll) { 10547 mRecentTasks.get(i).dump(pw, " "); 10548 } 10549 } 10550 } 10551 10552 if (!printedAnything) { 10553 pw.println(" (nothing)"); 10554 } 10555 } 10556 10557 void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 10558 int opti, boolean dumpAll, String dumpPackage) { 10559 boolean needSep = false; 10560 boolean printedAnything = false; 10561 int numPers = 0; 10562 10563 pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)"); 10564 10565 if (dumpAll) { 10566 final int NP = mProcessNames.getMap().size(); 10567 for (int ip=0; ip<NP; ip++) { 10568 SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip); 10569 final int NA = procs.size(); 10570 for (int ia=0; ia<NA; ia++) { 10571 ProcessRecord r = procs.valueAt(ia); 10572 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 10573 continue; 10574 } 10575 if (!needSep) { 10576 pw.println(" All known processes:"); 10577 needSep = true; 10578 printedAnything = true; 10579 } 10580 pw.print(r.persistent ? " *PERS*" : " *APP*"); 10581 pw.print(" UID "); pw.print(procs.keyAt(ia)); 10582 pw.print(" "); pw.println(r); 10583 r.dump(pw, " "); 10584 if (r.persistent) { 10585 numPers++; 10586 } 10587 } 10588 } 10589 } 10590 10591 if (mIsolatedProcesses.size() > 0) { 10592 boolean printed = false; 10593 for (int i=0; i<mIsolatedProcesses.size(); i++) { 10594 ProcessRecord r = mIsolatedProcesses.valueAt(i); 10595 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 10596 continue; 10597 } 10598 if (!printed) { 10599 if (needSep) { 10600 pw.println(); 10601 } 10602 pw.println(" Isolated process list (sorted by uid):"); 10603 printedAnything = true; 10604 printed = true; 10605 needSep = true; 10606 } 10607 pw.println(String.format("%sIsolated #%2d: %s", 10608 " ", i, r.toString())); 10609 } 10610 } 10611 10612 if (mLruProcesses.size() > 0) { 10613 if (needSep) { 10614 pw.println(); 10615 } 10616 pw.print(" Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size()); 10617 pw.print(" total, non-act at "); 10618 pw.print(mLruProcesses.size()-mLruProcessActivityStart); 10619 pw.print(", non-svc at "); 10620 pw.print(mLruProcesses.size()-mLruProcessServiceStart); 10621 pw.println("):"); 10622 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", false, dumpPackage); 10623 needSep = true; 10624 printedAnything = true; 10625 } 10626 10627 if (dumpAll || dumpPackage != null) { 10628 synchronized (mPidsSelfLocked) { 10629 boolean printed = false; 10630 for (int i=0; i<mPidsSelfLocked.size(); i++) { 10631 ProcessRecord r = mPidsSelfLocked.valueAt(i); 10632 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 10633 continue; 10634 } 10635 if (!printed) { 10636 if (needSep) pw.println(); 10637 needSep = true; 10638 pw.println(" PID mappings:"); 10639 printed = true; 10640 printedAnything = true; 10641 } 10642 pw.print(" PID #"); pw.print(mPidsSelfLocked.keyAt(i)); 10643 pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i)); 10644 } 10645 } 10646 } 10647 10648 if (mForegroundProcesses.size() > 0) { 10649 synchronized (mPidsSelfLocked) { 10650 boolean printed = false; 10651 for (int i=0; i<mForegroundProcesses.size(); i++) { 10652 ProcessRecord r = mPidsSelfLocked.get( 10653 mForegroundProcesses.valueAt(i).pid); 10654 if (dumpPackage != null && (r == null 10655 || !r.pkgList.containsKey(dumpPackage))) { 10656 continue; 10657 } 10658 if (!printed) { 10659 if (needSep) pw.println(); 10660 needSep = true; 10661 pw.println(" Foreground Processes:"); 10662 printed = true; 10663 printedAnything = true; 10664 } 10665 pw.print(" PID #"); pw.print(mForegroundProcesses.keyAt(i)); 10666 pw.print(": "); pw.println(mForegroundProcesses.valueAt(i)); 10667 } 10668 } 10669 } 10670 10671 if (mPersistentStartingProcesses.size() > 0) { 10672 if (needSep) pw.println(); 10673 needSep = true; 10674 printedAnything = true; 10675 pw.println(" Persisent processes that are starting:"); 10676 dumpProcessList(pw, this, mPersistentStartingProcesses, " ", 10677 "Starting Norm", "Restarting PERS", dumpPackage); 10678 } 10679 10680 if (mRemovedProcesses.size() > 0) { 10681 if (needSep) pw.println(); 10682 needSep = true; 10683 printedAnything = true; 10684 pw.println(" Processes that are being removed:"); 10685 dumpProcessList(pw, this, mRemovedProcesses, " ", 10686 "Removed Norm", "Removed PERS", dumpPackage); 10687 } 10688 10689 if (mProcessesOnHold.size() > 0) { 10690 if (needSep) pw.println(); 10691 needSep = true; 10692 printedAnything = true; 10693 pw.println(" Processes that are on old until the system is ready:"); 10694 dumpProcessList(pw, this, mProcessesOnHold, " ", 10695 "OnHold Norm", "OnHold PERS", dumpPackage); 10696 } 10697 10698 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage); 10699 10700 if (mProcessCrashTimes.getMap().size() > 0) { 10701 boolean printed = false; 10702 long now = SystemClock.uptimeMillis(); 10703 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap(); 10704 final int NP = pmap.size(); 10705 for (int ip=0; ip<NP; ip++) { 10706 String pname = pmap.keyAt(ip); 10707 SparseArray<Long> uids = pmap.valueAt(ip); 10708 final int N = uids.size(); 10709 for (int i=0; i<N; i++) { 10710 int puid = uids.keyAt(i); 10711 ProcessRecord r = mProcessNames.get(pname, puid); 10712 if (dumpPackage != null && (r == null 10713 || !r.pkgList.containsKey(dumpPackage))) { 10714 continue; 10715 } 10716 if (!printed) { 10717 if (needSep) pw.println(); 10718 needSep = true; 10719 pw.println(" Time since processes crashed:"); 10720 printed = true; 10721 printedAnything = true; 10722 } 10723 pw.print(" Process "); pw.print(pname); 10724 pw.print(" uid "); pw.print(puid); 10725 pw.print(": last crashed "); 10726 TimeUtils.formatDuration(now-uids.valueAt(i), pw); 10727 pw.println(" ago"); 10728 } 10729 } 10730 } 10731 10732 if (mBadProcesses.getMap().size() > 0) { 10733 boolean printed = false; 10734 final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap(); 10735 final int NP = pmap.size(); 10736 for (int ip=0; ip<NP; ip++) { 10737 String pname = pmap.keyAt(ip); 10738 SparseArray<BadProcessInfo> uids = pmap.valueAt(ip); 10739 final int N = uids.size(); 10740 for (int i=0; i<N; i++) { 10741 int puid = uids.keyAt(i); 10742 ProcessRecord r = mProcessNames.get(pname, puid); 10743 if (dumpPackage != null && (r == null 10744 || !r.pkgList.containsKey(dumpPackage))) { 10745 continue; 10746 } 10747 if (!printed) { 10748 if (needSep) pw.println(); 10749 needSep = true; 10750 pw.println(" Bad processes:"); 10751 printedAnything = true; 10752 } 10753 BadProcessInfo info = uids.valueAt(i); 10754 pw.print(" Bad process "); pw.print(pname); 10755 pw.print(" uid "); pw.print(puid); 10756 pw.print(": crashed at time "); pw.println(info.time); 10757 if (info.shortMsg != null) { 10758 pw.print(" Short msg: "); pw.println(info.shortMsg); 10759 } 10760 if (info.longMsg != null) { 10761 pw.print(" Long msg: "); pw.println(info.longMsg); 10762 } 10763 if (info.stack != null) { 10764 pw.println(" Stack:"); 10765 int lastPos = 0; 10766 for (int pos=0; pos<info.stack.length(); pos++) { 10767 if (info.stack.charAt(pos) == '\n') { 10768 pw.print(" "); 10769 pw.write(info.stack, lastPos, pos-lastPos); 10770 pw.println(); 10771 lastPos = pos+1; 10772 } 10773 } 10774 if (lastPos < info.stack.length()) { 10775 pw.print(" "); 10776 pw.write(info.stack, lastPos, info.stack.length()-lastPos); 10777 pw.println(); 10778 } 10779 } 10780 } 10781 } 10782 } 10783 10784 if (dumpPackage == null) { 10785 pw.println(); 10786 needSep = false; 10787 pw.println(" mStartedUsers:"); 10788 for (int i=0; i<mStartedUsers.size(); i++) { 10789 UserStartedState uss = mStartedUsers.valueAt(i); 10790 pw.print(" User #"); pw.print(uss.mHandle.getIdentifier()); 10791 pw.print(": "); uss.dump("", pw); 10792 } 10793 pw.print(" mStartedUserArray: ["); 10794 for (int i=0; i<mStartedUserArray.length; i++) { 10795 if (i > 0) pw.print(", "); 10796 pw.print(mStartedUserArray[i]); 10797 } 10798 pw.println("]"); 10799 pw.print(" mUserLru: ["); 10800 for (int i=0; i<mUserLru.size(); i++) { 10801 if (i > 0) pw.print(", "); 10802 pw.print(mUserLru.get(i)); 10803 } 10804 pw.println("]"); 10805 if (dumpAll) { 10806 pw.print(" mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray)); 10807 } 10808 } 10809 if (mHomeProcess != null && (dumpPackage == null 10810 || mHomeProcess.pkgList.containsKey(dumpPackage))) { 10811 if (needSep) { 10812 pw.println(); 10813 needSep = false; 10814 } 10815 pw.println(" mHomeProcess: " + mHomeProcess); 10816 } 10817 if (mPreviousProcess != null && (dumpPackage == null 10818 || mPreviousProcess.pkgList.containsKey(dumpPackage))) { 10819 if (needSep) { 10820 pw.println(); 10821 needSep = false; 10822 } 10823 pw.println(" mPreviousProcess: " + mPreviousProcess); 10824 } 10825 if (dumpAll) { 10826 StringBuilder sb = new StringBuilder(128); 10827 sb.append(" mPreviousProcessVisibleTime: "); 10828 TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb); 10829 pw.println(sb); 10830 } 10831 if (mHeavyWeightProcess != null && (dumpPackage == null 10832 || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) { 10833 if (needSep) { 10834 pw.println(); 10835 needSep = false; 10836 } 10837 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 10838 } 10839 if (dumpPackage == null) { 10840 pw.println(" mConfiguration: " + mConfiguration); 10841 } 10842 if (dumpAll) { 10843 pw.println(" mConfigWillChange: " + getFocusedStack().mConfigWillChange); 10844 if (mCompatModePackages.getPackages().size() > 0) { 10845 boolean printed = false; 10846 for (Map.Entry<String, Integer> entry 10847 : mCompatModePackages.getPackages().entrySet()) { 10848 String pkg = entry.getKey(); 10849 int mode = entry.getValue(); 10850 if (dumpPackage != null && !dumpPackage.equals(pkg)) { 10851 continue; 10852 } 10853 if (!printed) { 10854 pw.println(" mScreenCompatPackages:"); 10855 printed = true; 10856 } 10857 pw.print(" "); pw.print(pkg); pw.print(": "); 10858 pw.print(mode); pw.println(); 10859 } 10860 } 10861 } 10862 if (dumpPackage == null) { 10863 if (mSleeping || mWentToSleep || mLockScreenShown) { 10864 pw.println(" mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep 10865 + " mLockScreenShown " + mLockScreenShown); 10866 } 10867 if (mShuttingDown) { 10868 pw.println(" mShuttingDown=" + mShuttingDown); 10869 } 10870 } 10871 if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient 10872 || mOrigWaitForDebugger) { 10873 if (dumpPackage == null || dumpPackage.equals(mDebugApp) 10874 || dumpPackage.equals(mOrigDebugApp)) { 10875 if (needSep) { 10876 pw.println(); 10877 needSep = false; 10878 } 10879 pw.println(" mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp 10880 + " mDebugTransient=" + mDebugTransient 10881 + " mOrigWaitForDebugger=" + mOrigWaitForDebugger); 10882 } 10883 } 10884 if (mOpenGlTraceApp != null) { 10885 if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) { 10886 if (needSep) { 10887 pw.println(); 10888 needSep = false; 10889 } 10890 pw.println(" mOpenGlTraceApp=" + mOpenGlTraceApp); 10891 } 10892 } 10893 if (mProfileApp != null || mProfileProc != null || mProfileFile != null 10894 || mProfileFd != null) { 10895 if (dumpPackage == null || dumpPackage.equals(mProfileApp)) { 10896 if (needSep) { 10897 pw.println(); 10898 needSep = false; 10899 } 10900 pw.println(" mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc); 10901 pw.println(" mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd); 10902 pw.println(" mProfileType=" + mProfileType + " mAutoStopProfiler=" 10903 + mAutoStopProfiler); 10904 } 10905 } 10906 if (dumpPackage == null) { 10907 if (mAlwaysFinishActivities || mController != null) { 10908 pw.println(" mAlwaysFinishActivities=" + mAlwaysFinishActivities 10909 + " mController=" + mController); 10910 } 10911 if (dumpAll) { 10912 pw.println(" Total persistent processes: " + numPers); 10913 pw.println(" mStartRunning=" + mStartRunning 10914 + " mProcessesReady=" + mProcessesReady 10915 + " mSystemReady=" + mSystemReady); 10916 pw.println(" mBooting=" + mBooting 10917 + " mBooted=" + mBooted 10918 + " mFactoryTest=" + mFactoryTest); 10919 pw.print(" mLastPowerCheckRealtime="); 10920 TimeUtils.formatDuration(mLastPowerCheckRealtime, pw); 10921 pw.println(""); 10922 pw.print(" mLastPowerCheckUptime="); 10923 TimeUtils.formatDuration(mLastPowerCheckUptime, pw); 10924 pw.println(""); 10925 pw.println(" mGoingToSleep=" + mStackSupervisor.mGoingToSleep); 10926 pw.println(" mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity); 10927 pw.println(" mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq); 10928 pw.println(" mNumNonCachedProcs=" + mNumNonCachedProcs 10929 + " (" + mLruProcesses.size() + " total)" 10930 + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs 10931 + " mNumServiceProcs=" + mNumServiceProcs 10932 + " mNewNumServiceProcs=" + mNewNumServiceProcs); 10933 pw.println(" mAllowLowerMemLevel=" + mAllowLowerMemLevel 10934 + " mLastMemoryLevel" + mLastMemoryLevel 10935 + " mLastNumProcesses" + mLastNumProcesses); 10936 long now = SystemClock.uptimeMillis(); 10937 pw.print(" mLastIdleTime="); 10938 TimeUtils.formatDuration(now, mLastIdleTime, pw); 10939 pw.print(" mLowRamSinceLastIdle="); 10940 TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw); 10941 pw.println(); 10942 } 10943 } 10944 10945 if (!printedAnything) { 10946 pw.println(" (nothing)"); 10947 } 10948 } 10949 10950 boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args, 10951 int opti, boolean needSep, boolean dumpAll, String dumpPackage) { 10952 if (mProcessesToGc.size() > 0) { 10953 boolean printed = false; 10954 long now = SystemClock.uptimeMillis(); 10955 for (int i=0; i<mProcessesToGc.size(); i++) { 10956 ProcessRecord proc = mProcessesToGc.get(i); 10957 if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) { 10958 continue; 10959 } 10960 if (!printed) { 10961 if (needSep) pw.println(); 10962 needSep = true; 10963 pw.println(" Processes that are waiting to GC:"); 10964 printed = true; 10965 } 10966 pw.print(" Process "); pw.println(proc); 10967 pw.print(" lowMem="); pw.print(proc.reportLowMemory); 10968 pw.print(", last gced="); 10969 pw.print(now-proc.lastRequestedGc); 10970 pw.print(" ms ago, last lowMem="); 10971 pw.print(now-proc.lastLowMemory); 10972 pw.println(" ms ago"); 10973 10974 } 10975 } 10976 return needSep; 10977 } 10978 10979 void printOomLevel(PrintWriter pw, String name, int adj) { 10980 pw.print(" "); 10981 if (adj >= 0) { 10982 pw.print(' '); 10983 if (adj < 10) pw.print(' '); 10984 } else { 10985 if (adj > -10) pw.print(' '); 10986 } 10987 pw.print(adj); 10988 pw.print(": "); 10989 pw.print(name); 10990 pw.print(" ("); 10991 pw.print(mProcessList.getMemLevel(adj)/1024); 10992 pw.println(" kB)"); 10993 } 10994 10995 boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args, 10996 int opti, boolean dumpAll) { 10997 boolean needSep = false; 10998 10999 if (mLruProcesses.size() > 0) { 11000 if (needSep) pw.println(); 11001 needSep = true; 11002 pw.println(" OOM levels:"); 11003 printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ); 11004 printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ); 11005 printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ); 11006 printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ); 11007 printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ); 11008 printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ); 11009 printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ); 11010 printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ); 11011 printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ); 11012 printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ); 11013 printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ); 11014 printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ); 11015 printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ); 11016 11017 if (needSep) pw.println(); 11018 pw.print(" Process OOM control ("); pw.print(mLruProcesses.size()); 11019 pw.print(" total, non-act at "); 11020 pw.print(mLruProcesses.size()-mLruProcessActivityStart); 11021 pw.print(", non-svc at "); 11022 pw.print(mLruProcesses.size()-mLruProcessServiceStart); 11023 pw.println("):"); 11024 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", true, null); 11025 needSep = true; 11026 } 11027 11028 dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null); 11029 11030 pw.println(); 11031 pw.println(" mHomeProcess: " + mHomeProcess); 11032 pw.println(" mPreviousProcess: " + mPreviousProcess); 11033 if (mHeavyWeightProcess != null) { 11034 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 11035 } 11036 11037 return true; 11038 } 11039 11040 /** 11041 * There are three ways to call this: 11042 * - no provider specified: dump all the providers 11043 * - a flattened component name that matched an existing provider was specified as the 11044 * first arg: dump that one provider 11045 * - the first arg isn't the flattened component name of an existing provider: 11046 * dump all providers whose component contains the first arg as a substring 11047 */ 11048 protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args, 11049 int opti, boolean dumpAll) { 11050 return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll); 11051 } 11052 11053 static class ItemMatcher { 11054 ArrayList<ComponentName> components; 11055 ArrayList<String> strings; 11056 ArrayList<Integer> objects; 11057 boolean all; 11058 11059 ItemMatcher() { 11060 all = true; 11061 } 11062 11063 void build(String name) { 11064 ComponentName componentName = ComponentName.unflattenFromString(name); 11065 if (componentName != null) { 11066 if (components == null) { 11067 components = new ArrayList<ComponentName>(); 11068 } 11069 components.add(componentName); 11070 all = false; 11071 } else { 11072 int objectId = 0; 11073 // Not a '/' separated full component name; maybe an object ID? 11074 try { 11075 objectId = Integer.parseInt(name, 16); 11076 if (objects == null) { 11077 objects = new ArrayList<Integer>(); 11078 } 11079 objects.add(objectId); 11080 all = false; 11081 } catch (RuntimeException e) { 11082 // Not an integer; just do string match. 11083 if (strings == null) { 11084 strings = new ArrayList<String>(); 11085 } 11086 strings.add(name); 11087 all = false; 11088 } 11089 } 11090 } 11091 11092 int build(String[] args, int opti) { 11093 for (; opti<args.length; opti++) { 11094 String name = args[opti]; 11095 if ("--".equals(name)) { 11096 return opti+1; 11097 } 11098 build(name); 11099 } 11100 return opti; 11101 } 11102 11103 boolean match(Object object, ComponentName comp) { 11104 if (all) { 11105 return true; 11106 } 11107 if (components != null) { 11108 for (int i=0; i<components.size(); i++) { 11109 if (components.get(i).equals(comp)) { 11110 return true; 11111 } 11112 } 11113 } 11114 if (objects != null) { 11115 for (int i=0; i<objects.size(); i++) { 11116 if (System.identityHashCode(object) == objects.get(i)) { 11117 return true; 11118 } 11119 } 11120 } 11121 if (strings != null) { 11122 String flat = comp.flattenToString(); 11123 for (int i=0; i<strings.size(); i++) { 11124 if (flat.contains(strings.get(i))) { 11125 return true; 11126 } 11127 } 11128 } 11129 return false; 11130 } 11131 } 11132 11133 /** 11134 * There are three things that cmd can be: 11135 * - a flattened component name that matches an existing activity 11136 * - the cmd arg isn't the flattened component name of an existing activity: 11137 * dump all activity whose component contains the cmd as a substring 11138 * - A hex number of the ActivityRecord object instance. 11139 */ 11140 protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args, 11141 int opti, boolean dumpAll) { 11142 ArrayList<ActivityRecord> activities; 11143 11144 synchronized (this) { 11145 activities = mStackSupervisor.getDumpActivitiesLocked(name); 11146 } 11147 11148 if (activities.size() <= 0) { 11149 return false; 11150 } 11151 11152 String[] newArgs = new String[args.length - opti]; 11153 System.arraycopy(args, opti, newArgs, 0, args.length - opti); 11154 11155 TaskRecord lastTask = null; 11156 boolean needSep = false; 11157 for (int i=activities.size()-1; i>=0; i--) { 11158 ActivityRecord r = activities.get(i); 11159 if (needSep) { 11160 pw.println(); 11161 } 11162 needSep = true; 11163 synchronized (this) { 11164 if (lastTask != r.task) { 11165 lastTask = r.task; 11166 pw.print("TASK "); pw.print(lastTask.affinity); 11167 pw.print(" id="); pw.println(lastTask.taskId); 11168 if (dumpAll) { 11169 lastTask.dump(pw, " "); 11170 } 11171 } 11172 } 11173 dumpActivity(" ", fd, pw, activities.get(i), newArgs, dumpAll); 11174 } 11175 return true; 11176 } 11177 11178 /** 11179 * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if 11180 * there is a thread associated with the activity. 11181 */ 11182 private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw, 11183 final ActivityRecord r, String[] args, boolean dumpAll) { 11184 String innerPrefix = prefix + " "; 11185 synchronized (this) { 11186 pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName); 11187 pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r))); 11188 pw.print(" pid="); 11189 if (r.app != null) pw.println(r.app.pid); 11190 else pw.println("(not running)"); 11191 if (dumpAll) { 11192 r.dump(pw, innerPrefix); 11193 } 11194 } 11195 if (r.app != null && r.app.thread != null) { 11196 // flush anything that is already in the PrintWriter since the thread is going 11197 // to write to the file descriptor directly 11198 pw.flush(); 11199 try { 11200 TransferPipe tp = new TransferPipe(); 11201 try { 11202 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(), 11203 r.appToken, innerPrefix, args); 11204 tp.go(fd); 11205 } finally { 11206 tp.kill(); 11207 } 11208 } catch (IOException e) { 11209 pw.println(innerPrefix + "Failure while dumping the activity: " + e); 11210 } catch (RemoteException e) { 11211 pw.println(innerPrefix + "Got a RemoteException while dumping the activity"); 11212 } 11213 } 11214 } 11215 11216 void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 11217 int opti, boolean dumpAll, String dumpPackage) { 11218 boolean needSep = false; 11219 boolean onlyHistory = false; 11220 boolean printedAnything = false; 11221 11222 if ("history".equals(dumpPackage)) { 11223 if (opti < args.length && "-s".equals(args[opti])) { 11224 dumpAll = false; 11225 } 11226 onlyHistory = true; 11227 dumpPackage = null; 11228 } 11229 11230 pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)"); 11231 if (!onlyHistory && dumpAll) { 11232 if (mRegisteredReceivers.size() > 0) { 11233 boolean printed = false; 11234 Iterator it = mRegisteredReceivers.values().iterator(); 11235 while (it.hasNext()) { 11236 ReceiverList r = (ReceiverList)it.next(); 11237 if (dumpPackage != null && (r.app == null || 11238 !dumpPackage.equals(r.app.info.packageName))) { 11239 continue; 11240 } 11241 if (!printed) { 11242 pw.println(" Registered Receivers:"); 11243 needSep = true; 11244 printed = true; 11245 printedAnything = true; 11246 } 11247 pw.print(" * "); pw.println(r); 11248 r.dump(pw, " "); 11249 } 11250 } 11251 11252 if (mReceiverResolver.dump(pw, needSep ? 11253 "\n Receiver Resolver Table:" : " Receiver Resolver Table:", 11254 " ", dumpPackage, false)) { 11255 needSep = true; 11256 printedAnything = true; 11257 } 11258 } 11259 11260 for (BroadcastQueue q : mBroadcastQueues) { 11261 needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep); 11262 printedAnything |= needSep; 11263 } 11264 11265 needSep = true; 11266 11267 if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) { 11268 for (int user=0; user<mStickyBroadcasts.size(); user++) { 11269 if (needSep) { 11270 pw.println(); 11271 } 11272 needSep = true; 11273 printedAnything = true; 11274 pw.print(" Sticky broadcasts for user "); 11275 pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":"); 11276 StringBuilder sb = new StringBuilder(128); 11277 for (Map.Entry<String, ArrayList<Intent>> ent 11278 : mStickyBroadcasts.valueAt(user).entrySet()) { 11279 pw.print(" * Sticky action "); pw.print(ent.getKey()); 11280 if (dumpAll) { 11281 pw.println(":"); 11282 ArrayList<Intent> intents = ent.getValue(); 11283 final int N = intents.size(); 11284 for (int i=0; i<N; i++) { 11285 sb.setLength(0); 11286 sb.append(" Intent: "); 11287 intents.get(i).toShortString(sb, false, true, false, false); 11288 pw.println(sb.toString()); 11289 Bundle bundle = intents.get(i).getExtras(); 11290 if (bundle != null) { 11291 pw.print(" "); 11292 pw.println(bundle.toString()); 11293 } 11294 } 11295 } else { 11296 pw.println(""); 11297 } 11298 } 11299 } 11300 } 11301 11302 if (!onlyHistory && dumpAll) { 11303 pw.println(); 11304 for (BroadcastQueue queue : mBroadcastQueues) { 11305 pw.println(" mBroadcastsScheduled [" + queue.mQueueName + "]=" 11306 + queue.mBroadcastsScheduled); 11307 } 11308 pw.println(" mHandler:"); 11309 mHandler.dump(new PrintWriterPrinter(pw), " "); 11310 needSep = true; 11311 printedAnything = true; 11312 } 11313 11314 if (!printedAnything) { 11315 pw.println(" (nothing)"); 11316 } 11317 } 11318 11319 void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args, 11320 int opti, boolean dumpAll, String dumpPackage) { 11321 boolean needSep; 11322 boolean printedAnything = false; 11323 11324 ItemMatcher matcher = new ItemMatcher(); 11325 matcher.build(args, opti); 11326 11327 pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)"); 11328 11329 needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage); 11330 printedAnything |= needSep; 11331 11332 if (mLaunchingProviders.size() > 0) { 11333 boolean printed = false; 11334 for (int i=mLaunchingProviders.size()-1; i>=0; i--) { 11335 ContentProviderRecord r = mLaunchingProviders.get(i); 11336 if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) { 11337 continue; 11338 } 11339 if (!printed) { 11340 if (needSep) pw.println(); 11341 needSep = true; 11342 pw.println(" Launching content providers:"); 11343 printed = true; 11344 printedAnything = true; 11345 } 11346 pw.print(" Launching #"); pw.print(i); pw.print(": "); 11347 pw.println(r); 11348 } 11349 } 11350 11351 if (mGrantedUriPermissions.size() > 0) { 11352 boolean printed = false; 11353 int dumpUid = -2; 11354 if (dumpPackage != null) { 11355 try { 11356 dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0); 11357 } catch (NameNotFoundException e) { 11358 dumpUid = -1; 11359 } 11360 } 11361 for (int i=0; i<mGrantedUriPermissions.size(); i++) { 11362 int uid = mGrantedUriPermissions.keyAt(i); 11363 if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) { 11364 continue; 11365 } 11366 ArrayMap<Uri, UriPermission> perms 11367 = mGrantedUriPermissions.valueAt(i); 11368 if (!printed) { 11369 if (needSep) pw.println(); 11370 needSep = true; 11371 pw.println(" Granted Uri Permissions:"); 11372 printed = true; 11373 printedAnything = true; 11374 } 11375 pw.print(" * UID "); pw.print(uid); 11376 pw.println(" holds:"); 11377 for (UriPermission perm : perms.values()) { 11378 pw.print(" "); pw.println(perm); 11379 if (dumpAll) { 11380 perm.dump(pw, " "); 11381 } 11382 } 11383 } 11384 } 11385 11386 if (!printedAnything) { 11387 pw.println(" (nothing)"); 11388 } 11389 } 11390 11391 void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 11392 int opti, boolean dumpAll, String dumpPackage) { 11393 boolean printed = false; 11394 11395 pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)"); 11396 11397 if (mIntentSenderRecords.size() > 0) { 11398 Iterator<WeakReference<PendingIntentRecord>> it 11399 = mIntentSenderRecords.values().iterator(); 11400 while (it.hasNext()) { 11401 WeakReference<PendingIntentRecord> ref = it.next(); 11402 PendingIntentRecord rec = ref != null ? ref.get(): null; 11403 if (dumpPackage != null && (rec == null 11404 || !dumpPackage.equals(rec.key.packageName))) { 11405 continue; 11406 } 11407 printed = true; 11408 if (rec != null) { 11409 pw.print(" * "); pw.println(rec); 11410 if (dumpAll) { 11411 rec.dump(pw, " "); 11412 } 11413 } else { 11414 pw.print(" * "); pw.println(ref); 11415 } 11416 } 11417 } 11418 11419 if (!printed) { 11420 pw.println(" (nothing)"); 11421 } 11422 } 11423 11424 private static final int dumpProcessList(PrintWriter pw, 11425 ActivityManagerService service, List list, 11426 String prefix, String normalLabel, String persistentLabel, 11427 String dumpPackage) { 11428 int numPers = 0; 11429 final int N = list.size()-1; 11430 for (int i=N; i>=0; i--) { 11431 ProcessRecord r = (ProcessRecord)list.get(i); 11432 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 11433 continue; 11434 } 11435 pw.println(String.format("%s%s #%2d: %s", 11436 prefix, (r.persistent ? persistentLabel : normalLabel), 11437 i, r.toString())); 11438 if (r.persistent) { 11439 numPers++; 11440 } 11441 } 11442 return numPers; 11443 } 11444 11445 private static final boolean dumpProcessOomList(PrintWriter pw, 11446 ActivityManagerService service, List<ProcessRecord> origList, 11447 String prefix, String normalLabel, String persistentLabel, 11448 boolean inclDetails, String dumpPackage) { 11449 11450 ArrayList<Pair<ProcessRecord, Integer>> list 11451 = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size()); 11452 for (int i=0; i<origList.size(); i++) { 11453 ProcessRecord r = origList.get(i); 11454 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 11455 continue; 11456 } 11457 list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i)); 11458 } 11459 11460 if (list.size() <= 0) { 11461 return false; 11462 } 11463 11464 Comparator<Pair<ProcessRecord, Integer>> comparator 11465 = new Comparator<Pair<ProcessRecord, Integer>>() { 11466 @Override 11467 public int compare(Pair<ProcessRecord, Integer> object1, 11468 Pair<ProcessRecord, Integer> object2) { 11469 if (object1.first.setAdj != object2.first.setAdj) { 11470 return object1.first.setAdj > object2.first.setAdj ? -1 : 1; 11471 } 11472 if (object1.second.intValue() != object2.second.intValue()) { 11473 return object1.second.intValue() > object2.second.intValue() ? -1 : 1; 11474 } 11475 return 0; 11476 } 11477 }; 11478 11479 Collections.sort(list, comparator); 11480 11481 final long curRealtime = SystemClock.elapsedRealtime(); 11482 final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime; 11483 final long curUptime = SystemClock.uptimeMillis(); 11484 final long uptimeSince = curUptime - service.mLastPowerCheckUptime; 11485 11486 for (int i=list.size()-1; i>=0; i--) { 11487 ProcessRecord r = list.get(i).first; 11488 String oomAdj = ProcessList.makeOomAdjString(r.setAdj); 11489 char schedGroup; 11490 switch (r.setSchedGroup) { 11491 case Process.THREAD_GROUP_BG_NONINTERACTIVE: 11492 schedGroup = 'B'; 11493 break; 11494 case Process.THREAD_GROUP_DEFAULT: 11495 schedGroup = 'F'; 11496 break; 11497 default: 11498 schedGroup = '?'; 11499 break; 11500 } 11501 char foreground; 11502 if (r.foregroundActivities) { 11503 foreground = 'A'; 11504 } else if (r.foregroundServices) { 11505 foreground = 'S'; 11506 } else { 11507 foreground = ' '; 11508 } 11509 String procState = ProcessList.makeProcStateString(r.curProcState); 11510 pw.print(prefix); 11511 pw.print(r.persistent ? persistentLabel : normalLabel); 11512 pw.print(" #"); 11513 int num = (origList.size()-1)-list.get(i).second; 11514 if (num < 10) pw.print(' '); 11515 pw.print(num); 11516 pw.print(": "); 11517 pw.print(oomAdj); 11518 pw.print(' '); 11519 pw.print(schedGroup); 11520 pw.print('/'); 11521 pw.print(foreground); 11522 pw.print('/'); 11523 pw.print(procState); 11524 pw.print(" trm:"); 11525 if (r.trimMemoryLevel < 10) pw.print(' '); 11526 pw.print(r.trimMemoryLevel); 11527 pw.print(' '); 11528 pw.print(r.toShortString()); 11529 pw.print(" ("); 11530 pw.print(r.adjType); 11531 pw.println(')'); 11532 if (r.adjSource != null || r.adjTarget != null) { 11533 pw.print(prefix); 11534 pw.print(" "); 11535 if (r.adjTarget instanceof ComponentName) { 11536 pw.print(((ComponentName)r.adjTarget).flattenToShortString()); 11537 } else if (r.adjTarget != null) { 11538 pw.print(r.adjTarget.toString()); 11539 } else { 11540 pw.print("{null}"); 11541 } 11542 pw.print("<="); 11543 if (r.adjSource instanceof ProcessRecord) { 11544 pw.print("Proc{"); 11545 pw.print(((ProcessRecord)r.adjSource).toShortString()); 11546 pw.println("}"); 11547 } else if (r.adjSource != null) { 11548 pw.println(r.adjSource.toString()); 11549 } else { 11550 pw.println("{null}"); 11551 } 11552 } 11553 if (inclDetails) { 11554 pw.print(prefix); 11555 pw.print(" "); 11556 pw.print("oom: max="); pw.print(r.maxAdj); 11557 pw.print(" curRaw="); pw.print(r.curRawAdj); 11558 pw.print(" setRaw="); pw.print(r.setRawAdj); 11559 pw.print(" cur="); pw.print(r.curAdj); 11560 pw.print(" set="); pw.println(r.setAdj); 11561 pw.print(prefix); 11562 pw.print(" "); 11563 pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState)); 11564 pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState)); 11565 pw.print(" lastPss="); pw.print(r.lastPss); 11566 pw.print(" lastCachedPss="); pw.println(r.lastCachedPss); 11567 pw.print(prefix); 11568 pw.print(" "); 11569 pw.print("keeping="); pw.print(r.keeping); 11570 pw.print(" cached="); pw.print(r.cached); 11571 pw.print(" empty="); pw.print(r.empty); 11572 pw.print(" hasAboveClient="); pw.println(r.hasAboveClient); 11573 11574 if (!r.keeping) { 11575 if (r.lastWakeTime != 0) { 11576 long wtime; 11577 BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics(); 11578 synchronized (stats) { 11579 wtime = stats.getProcessWakeTime(r.info.uid, 11580 r.pid, curRealtime); 11581 } 11582 long timeUsed = wtime - r.lastWakeTime; 11583 pw.print(prefix); 11584 pw.print(" "); 11585 pw.print("keep awake over "); 11586 TimeUtils.formatDuration(realtimeSince, pw); 11587 pw.print(" used "); 11588 TimeUtils.formatDuration(timeUsed, pw); 11589 pw.print(" ("); 11590 pw.print((timeUsed*100)/realtimeSince); 11591 pw.println("%)"); 11592 } 11593 if (r.lastCpuTime != 0) { 11594 long timeUsed = r.curCpuTime - r.lastCpuTime; 11595 pw.print(prefix); 11596 pw.print(" "); 11597 pw.print("run cpu over "); 11598 TimeUtils.formatDuration(uptimeSince, pw); 11599 pw.print(" used "); 11600 TimeUtils.formatDuration(timeUsed, pw); 11601 pw.print(" ("); 11602 pw.print((timeUsed*100)/uptimeSince); 11603 pw.println("%)"); 11604 } 11605 } 11606 } 11607 } 11608 return true; 11609 } 11610 11611 ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) { 11612 ArrayList<ProcessRecord> procs; 11613 synchronized (this) { 11614 if (args != null && args.length > start 11615 && args[start].charAt(0) != '-') { 11616 procs = new ArrayList<ProcessRecord>(); 11617 int pid = -1; 11618 try { 11619 pid = Integer.parseInt(args[start]); 11620 } catch (NumberFormatException e) { 11621 } 11622 for (int i=mLruProcesses.size()-1; i>=0; i--) { 11623 ProcessRecord proc = mLruProcesses.get(i); 11624 if (proc.pid == pid) { 11625 procs.add(proc); 11626 } else if (proc.processName.equals(args[start])) { 11627 procs.add(proc); 11628 } 11629 } 11630 if (procs.size() <= 0) { 11631 return null; 11632 } 11633 } else { 11634 procs = new ArrayList<ProcessRecord>(mLruProcesses); 11635 } 11636 } 11637 return procs; 11638 } 11639 11640 final void dumpGraphicsHardwareUsage(FileDescriptor fd, 11641 PrintWriter pw, String[] args) { 11642 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args); 11643 if (procs == null) { 11644 pw.println("No process found for: " + args[0]); 11645 return; 11646 } 11647 11648 long uptime = SystemClock.uptimeMillis(); 11649 long realtime = SystemClock.elapsedRealtime(); 11650 pw.println("Applications Graphics Acceleration Info:"); 11651 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 11652 11653 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 11654 ProcessRecord r = procs.get(i); 11655 if (r.thread != null) { 11656 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **"); 11657 pw.flush(); 11658 try { 11659 TransferPipe tp = new TransferPipe(); 11660 try { 11661 r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args); 11662 tp.go(fd); 11663 } finally { 11664 tp.kill(); 11665 } 11666 } catch (IOException e) { 11667 pw.println("Failure while dumping the app: " + r); 11668 pw.flush(); 11669 } catch (RemoteException e) { 11670 pw.println("Got a RemoteException while dumping the app " + r); 11671 pw.flush(); 11672 } 11673 } 11674 } 11675 } 11676 11677 final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) { 11678 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args); 11679 if (procs == null) { 11680 pw.println("No process found for: " + args[0]); 11681 return; 11682 } 11683 11684 pw.println("Applications Database Info:"); 11685 11686 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 11687 ProcessRecord r = procs.get(i); 11688 if (r.thread != null) { 11689 pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **"); 11690 pw.flush(); 11691 try { 11692 TransferPipe tp = new TransferPipe(); 11693 try { 11694 r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args); 11695 tp.go(fd); 11696 } finally { 11697 tp.kill(); 11698 } 11699 } catch (IOException e) { 11700 pw.println("Failure while dumping the app: " + r); 11701 pw.flush(); 11702 } catch (RemoteException e) { 11703 pw.println("Got a RemoteException while dumping the app " + r); 11704 pw.flush(); 11705 } 11706 } 11707 } 11708 } 11709 11710 final static class MemItem { 11711 final boolean isProc; 11712 final String label; 11713 final String shortLabel; 11714 final long pss; 11715 final int id; 11716 final boolean hasActivities; 11717 ArrayList<MemItem> subitems; 11718 11719 public MemItem(String _label, String _shortLabel, long _pss, int _id, 11720 boolean _hasActivities) { 11721 isProc = true; 11722 label = _label; 11723 shortLabel = _shortLabel; 11724 pss = _pss; 11725 id = _id; 11726 hasActivities = _hasActivities; 11727 } 11728 11729 public MemItem(String _label, String _shortLabel, long _pss, int _id) { 11730 isProc = false; 11731 label = _label; 11732 shortLabel = _shortLabel; 11733 pss = _pss; 11734 id = _id; 11735 hasActivities = false; 11736 } 11737 } 11738 11739 static final void dumpMemItems(PrintWriter pw, String prefix, String tag, 11740 ArrayList<MemItem> items, boolean sort, boolean isCompact) { 11741 if (sort && !isCompact) { 11742 Collections.sort(items, new Comparator<MemItem>() { 11743 @Override 11744 public int compare(MemItem lhs, MemItem rhs) { 11745 if (lhs.pss < rhs.pss) { 11746 return 1; 11747 } else if (lhs.pss > rhs.pss) { 11748 return -1; 11749 } 11750 return 0; 11751 } 11752 }); 11753 } 11754 11755 for (int i=0; i<items.size(); i++) { 11756 MemItem mi = items.get(i); 11757 if (!isCompact) { 11758 pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label); 11759 } else if (mi.isProc) { 11760 pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel); 11761 pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss); 11762 pw.println(mi.hasActivities ? ",a" : ",e"); 11763 } else { 11764 pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(","); 11765 pw.println(mi.pss); 11766 } 11767 if (mi.subitems != null) { 11768 dumpMemItems(pw, prefix + " ", mi.shortLabel, mi.subitems, 11769 true, isCompact); 11770 } 11771 } 11772 } 11773 11774 // These are in KB. 11775 static final long[] DUMP_MEM_BUCKETS = new long[] { 11776 5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024, 11777 120*1024, 160*1024, 200*1024, 11778 250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024, 11779 1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024 11780 }; 11781 11782 static final void appendMemBucket(StringBuilder out, long memKB, String label, 11783 boolean stackLike) { 11784 int start = label.lastIndexOf('.'); 11785 if (start >= 0) start++; 11786 else start = 0; 11787 int end = label.length(); 11788 for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) { 11789 if (DUMP_MEM_BUCKETS[i] >= memKB) { 11790 long bucket = DUMP_MEM_BUCKETS[i]/1024; 11791 out.append(bucket); 11792 out.append(stackLike ? "MB." : "MB "); 11793 out.append(label, start, end); 11794 return; 11795 } 11796 } 11797 out.append(memKB/1024); 11798 out.append(stackLike ? "MB." : "MB "); 11799 out.append(label, start, end); 11800 } 11801 11802 static final int[] DUMP_MEM_OOM_ADJ = new int[] { 11803 ProcessList.NATIVE_ADJ, 11804 ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ, 11805 ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ, 11806 ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ, 11807 ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ, 11808 ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ 11809 }; 11810 static final String[] DUMP_MEM_OOM_LABEL = new String[] { 11811 "Native", 11812 "System", "Persistent", "Foreground", 11813 "Visible", "Perceptible", 11814 "Heavy Weight", "Backup", 11815 "A Services", "Home", 11816 "Previous", "B Services", "Cached" 11817 }; 11818 static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] { 11819 "native", 11820 "sys", "pers", "fore", 11821 "vis", "percept", 11822 "heavy", "backup", 11823 "servicea", "home", 11824 "prev", "serviceb", "cached" 11825 }; 11826 11827 private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime, 11828 long realtime, boolean isCheckinRequest, boolean isCompact) { 11829 if (isCheckinRequest || isCompact) { 11830 // short checkin version 11831 pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime); 11832 } else { 11833 pw.println("Applications Memory Usage (kB):"); 11834 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 11835 } 11836 } 11837 11838 final void dumpApplicationMemoryUsage(FileDescriptor fd, 11839 PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) { 11840 boolean dumpDetails = false; 11841 boolean dumpFullDetails = false; 11842 boolean dumpDalvik = false; 11843 boolean oomOnly = false; 11844 boolean isCompact = false; 11845 boolean localOnly = false; 11846 11847 int opti = 0; 11848 while (opti < args.length) { 11849 String opt = args[opti]; 11850 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 11851 break; 11852 } 11853 opti++; 11854 if ("-a".equals(opt)) { 11855 dumpDetails = true; 11856 dumpFullDetails = true; 11857 dumpDalvik = true; 11858 } else if ("-d".equals(opt)) { 11859 dumpDalvik = true; 11860 } else if ("-c".equals(opt)) { 11861 isCompact = true; 11862 } else if ("--oom".equals(opt)) { 11863 oomOnly = true; 11864 } else if ("--local".equals(opt)) { 11865 localOnly = true; 11866 } else if ("-h".equals(opt)) { 11867 pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]"); 11868 pw.println(" -a: include all available information for each process."); 11869 pw.println(" -d: include dalvik details when dumping process details."); 11870 pw.println(" -c: dump in a compact machine-parseable representation."); 11871 pw.println(" --oom: only show processes organized by oom adj."); 11872 pw.println(" --local: only collect details locally, don't call process."); 11873 pw.println("If [process] is specified it can be the name or "); 11874 pw.println("pid of a specific process to dump."); 11875 return; 11876 } else { 11877 pw.println("Unknown argument: " + opt + "; use -h for help"); 11878 } 11879 } 11880 11881 final boolean isCheckinRequest = scanArgs(args, "--checkin"); 11882 long uptime = SystemClock.uptimeMillis(); 11883 long realtime = SystemClock.elapsedRealtime(); 11884 final long[] tmpLong = new long[1]; 11885 11886 ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args); 11887 if (procs == null) { 11888 // No Java processes. Maybe they want to print a native process. 11889 if (args != null && args.length > opti 11890 && args[opti].charAt(0) != '-') { 11891 ArrayList<ProcessCpuTracker.Stats> nativeProcs 11892 = new ArrayList<ProcessCpuTracker.Stats>(); 11893 updateCpuStatsNow(); 11894 int findPid = -1; 11895 try { 11896 findPid = Integer.parseInt(args[opti]); 11897 } catch (NumberFormatException e) { 11898 } 11899 synchronized (mProcessCpuThread) { 11900 final int N = mProcessCpuTracker.countStats(); 11901 for (int i=0; i<N; i++) { 11902 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 11903 if (st.pid == findPid || (st.baseName != null 11904 && st.baseName.equals(args[opti]))) { 11905 nativeProcs.add(st); 11906 } 11907 } 11908 } 11909 if (nativeProcs.size() > 0) { 11910 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, 11911 isCompact); 11912 Debug.MemoryInfo mi = null; 11913 for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) { 11914 final ProcessCpuTracker.Stats r = nativeProcs.get(i); 11915 final int pid = r.pid; 11916 if (!isCheckinRequest && dumpDetails) { 11917 pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **"); 11918 } 11919 if (mi == null) { 11920 mi = new Debug.MemoryInfo(); 11921 } 11922 if (dumpDetails || (!brief && !oomOnly)) { 11923 Debug.getMemoryInfo(pid, mi); 11924 } else { 11925 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong); 11926 mi.dalvikPrivateDirty = (int)tmpLong[0]; 11927 } 11928 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails, 11929 dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0); 11930 if (isCheckinRequest) { 11931 pw.println(); 11932 } 11933 } 11934 return; 11935 } 11936 } 11937 pw.println("No process found for: " + args[opti]); 11938 return; 11939 } 11940 11941 if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest)) { 11942 dumpDetails = true; 11943 } 11944 11945 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact); 11946 11947 String[] innerArgs = new String[args.length-opti]; 11948 System.arraycopy(args, opti, innerArgs, 0, args.length-opti); 11949 11950 ArrayList<MemItem> procMems = new ArrayList<MemItem>(); 11951 final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>(); 11952 long nativePss=0, dalvikPss=0, otherPss=0; 11953 long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS]; 11954 11955 long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length]; 11956 ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[]) 11957 new ArrayList[DUMP_MEM_OOM_LABEL.length]; 11958 11959 long totalPss = 0; 11960 long cachedPss = 0; 11961 11962 Debug.MemoryInfo mi = null; 11963 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 11964 final ProcessRecord r = procs.get(i); 11965 final IApplicationThread thread; 11966 final int pid; 11967 final int oomAdj; 11968 final boolean hasActivities; 11969 synchronized (this) { 11970 thread = r.thread; 11971 pid = r.pid; 11972 oomAdj = r.getSetAdjWithServices(); 11973 hasActivities = r.activities.size() > 0; 11974 } 11975 if (thread != null) { 11976 if (!isCheckinRequest && dumpDetails) { 11977 pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **"); 11978 } 11979 if (mi == null) { 11980 mi = new Debug.MemoryInfo(); 11981 } 11982 if (dumpDetails || (!brief && !oomOnly)) { 11983 Debug.getMemoryInfo(pid, mi); 11984 } else { 11985 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong); 11986 mi.dalvikPrivateDirty = (int)tmpLong[0]; 11987 } 11988 if (dumpDetails) { 11989 if (localOnly) { 11990 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails, 11991 dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0); 11992 if (isCheckinRequest) { 11993 pw.println(); 11994 } 11995 } else { 11996 try { 11997 pw.flush(); 11998 thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails, 11999 dumpDalvik, innerArgs); 12000 } catch (RemoteException e) { 12001 if (!isCheckinRequest) { 12002 pw.println("Got RemoteException!"); 12003 pw.flush(); 12004 } 12005 } 12006 } 12007 } 12008 12009 final long myTotalPss = mi.getTotalPss(); 12010 final long myTotalUss = mi.getTotalUss(); 12011 12012 synchronized (this) { 12013 if (r.thread != null && oomAdj == r.getSetAdjWithServices()) { 12014 // Record this for posterity if the process has been stable. 12015 r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList); 12016 } 12017 } 12018 12019 if (!isCheckinRequest && mi != null) { 12020 totalPss += myTotalPss; 12021 MemItem pssItem = new MemItem(r.processName + " (pid " + pid + 12022 (hasActivities ? " / activities)" : ")"), 12023 r.processName, myTotalPss, pid, hasActivities); 12024 procMems.add(pssItem); 12025 procMemsMap.put(pid, pssItem); 12026 12027 nativePss += mi.nativePss; 12028 dalvikPss += mi.dalvikPss; 12029 otherPss += mi.otherPss; 12030 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 12031 long mem = mi.getOtherPss(j); 12032 miscPss[j] += mem; 12033 otherPss -= mem; 12034 } 12035 12036 if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 12037 cachedPss += myTotalPss; 12038 } 12039 12040 for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) { 12041 if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex] 12042 || oomIndex == (oomPss.length-1)) { 12043 oomPss[oomIndex] += myTotalPss; 12044 if (oomProcs[oomIndex] == null) { 12045 oomProcs[oomIndex] = new ArrayList<MemItem>(); 12046 } 12047 oomProcs[oomIndex].add(pssItem); 12048 break; 12049 } 12050 } 12051 } 12052 } 12053 } 12054 12055 if (!isCheckinRequest && procs.size() > 1) { 12056 // If we are showing aggregations, also look for native processes to 12057 // include so that our aggregations are more accurate. 12058 updateCpuStatsNow(); 12059 synchronized (mProcessCpuThread) { 12060 final int N = mProcessCpuTracker.countStats(); 12061 for (int i=0; i<N; i++) { 12062 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 12063 if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) { 12064 if (mi == null) { 12065 mi = new Debug.MemoryInfo(); 12066 } 12067 if (!brief && !oomOnly) { 12068 Debug.getMemoryInfo(st.pid, mi); 12069 } else { 12070 mi.nativePss = (int)Debug.getPss(st.pid, tmpLong); 12071 mi.nativePrivateDirty = (int)tmpLong[0]; 12072 } 12073 12074 final long myTotalPss = mi.getTotalPss(); 12075 totalPss += myTotalPss; 12076 12077 MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")", 12078 st.name, myTotalPss, st.pid, false); 12079 procMems.add(pssItem); 12080 12081 nativePss += mi.nativePss; 12082 dalvikPss += mi.dalvikPss; 12083 otherPss += mi.otherPss; 12084 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 12085 long mem = mi.getOtherPss(j); 12086 miscPss[j] += mem; 12087 otherPss -= mem; 12088 } 12089 oomPss[0] += myTotalPss; 12090 if (oomProcs[0] == null) { 12091 oomProcs[0] = new ArrayList<MemItem>(); 12092 } 12093 oomProcs[0].add(pssItem); 12094 } 12095 } 12096 } 12097 12098 ArrayList<MemItem> catMems = new ArrayList<MemItem>(); 12099 12100 catMems.add(new MemItem("Native", "Native", nativePss, -1)); 12101 catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2)); 12102 catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3)); 12103 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 12104 String label = Debug.MemoryInfo.getOtherLabel(j); 12105 catMems.add(new MemItem(label, label, miscPss[j], j)); 12106 } 12107 12108 ArrayList<MemItem> oomMems = new ArrayList<MemItem>(); 12109 for (int j=0; j<oomPss.length; j++) { 12110 if (oomPss[j] != 0) { 12111 String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j] 12112 : DUMP_MEM_OOM_LABEL[j]; 12113 MemItem item = new MemItem(label, label, oomPss[j], 12114 DUMP_MEM_OOM_ADJ[j]); 12115 item.subitems = oomProcs[j]; 12116 oomMems.add(item); 12117 } 12118 } 12119 12120 if (!brief && !oomOnly && !isCompact) { 12121 pw.println(); 12122 pw.println("Total PSS by process:"); 12123 dumpMemItems(pw, " ", "proc", procMems, true, isCompact); 12124 pw.println(); 12125 } 12126 if (!isCompact) { 12127 pw.println("Total PSS by OOM adjustment:"); 12128 } 12129 dumpMemItems(pw, " ", "oom", oomMems, false, isCompact); 12130 if (!brief && !oomOnly) { 12131 PrintWriter out = categoryPw != null ? categoryPw : pw; 12132 if (!isCompact) { 12133 out.println(); 12134 out.println("Total PSS by category:"); 12135 } 12136 dumpMemItems(out, " ", "cat", catMems, true, isCompact); 12137 } 12138 if (!isCompact) { 12139 pw.println(); 12140 } 12141 MemInfoReader memInfo = new MemInfoReader(); 12142 memInfo.readMemInfo(); 12143 if (!brief) { 12144 if (!isCompact) { 12145 pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb()); 12146 pw.println(" kB"); 12147 pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb() 12148 + memInfo.getFreeSizeKb()); pw.print(" kB ("); 12149 pw.print(cachedPss); pw.print(" cached pss + "); 12150 pw.print(memInfo.getCachedSizeKb()); pw.print(" cached + "); 12151 pw.print(memInfo.getFreeSizeKb()); pw.println(" free)"); 12152 } else { 12153 pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(","); 12154 pw.print(cachedPss + memInfo.getCachedSizeKb() 12155 + memInfo.getFreeSizeKb()); pw.print(","); 12156 pw.println(totalPss - cachedPss); 12157 } 12158 } 12159 if (!isCompact) { 12160 pw.print(" Used RAM: "); pw.print(totalPss - cachedPss 12161 + memInfo.getBuffersSizeKb() + memInfo.getShmemSizeKb() 12162 + memInfo.getSlabSizeKb()); pw.print(" kB ("); 12163 pw.print(totalPss - cachedPss); pw.print(" used pss + "); 12164 pw.print(memInfo.getBuffersSizeKb()); pw.print(" buffers + "); 12165 pw.print(memInfo.getShmemSizeKb()); pw.print(" shmem + "); 12166 pw.print(memInfo.getSlabSizeKb()); pw.println(" slab)"); 12167 pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb() 12168 - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb() 12169 - memInfo.getBuffersSizeKb() - memInfo.getShmemSizeKb() 12170 - memInfo.getSlabSizeKb()); pw.println(" kB"); 12171 } 12172 if (!brief) { 12173 if (memInfo.getZramTotalSizeKb() != 0) { 12174 if (!isCompact) { 12175 pw.print(" ZRAM: "); pw.print(memInfo.getZramTotalSizeKb()); 12176 pw.print(" kB physical used for "); 12177 pw.print(memInfo.getSwapTotalSizeKb() 12178 - memInfo.getSwapFreeSizeKb()); 12179 pw.print(" kB in swap ("); 12180 pw.print(memInfo.getSwapTotalSizeKb()); 12181 pw.println(" kB total swap)"); 12182 } else { 12183 pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(","); 12184 pw.print(memInfo.getSwapTotalSizeKb()); pw.print(","); 12185 pw.println(memInfo.getSwapFreeSizeKb()); 12186 } 12187 } 12188 final int[] SINGLE_LONG_FORMAT = new int[] { 12189 Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG 12190 }; 12191 long[] longOut = new long[1]; 12192 Process.readProcFile("/sys/kernel/mm/ksm/pages_shared", 12193 SINGLE_LONG_FORMAT, null, longOut, null); 12194 long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024; 12195 longOut[0] = 0; 12196 Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing", 12197 SINGLE_LONG_FORMAT, null, longOut, null); 12198 long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024; 12199 longOut[0] = 0; 12200 Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared", 12201 SINGLE_LONG_FORMAT, null, longOut, null); 12202 long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024; 12203 longOut[0] = 0; 12204 Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile", 12205 SINGLE_LONG_FORMAT, null, longOut, null); 12206 long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024; 12207 if (!isCompact) { 12208 if (sharing != 0 || shared != 0 || unshared != 0 || voltile != 0) { 12209 pw.print(" KSM: "); pw.print(sharing); 12210 pw.print(" kB saved from shared "); 12211 pw.print(shared); pw.println(" kB"); 12212 pw.print(" "); pw.print(unshared); pw.print(" kB unshared; "); 12213 pw.print(voltile); pw.println(" kB volatile"); 12214 } 12215 pw.print(" Tuning: "); 12216 pw.print(ActivityManager.staticGetMemoryClass()); 12217 pw.print(" (large "); 12218 pw.print(ActivityManager.staticGetLargeMemoryClass()); 12219 pw.print("), oom "); 12220 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024); 12221 pw.print(" kB"); 12222 pw.print(", restore limit "); 12223 pw.print(mProcessList.getCachedRestoreThresholdKb()); 12224 pw.print(" kB"); 12225 if (ActivityManager.isLowRamDeviceStatic()) { 12226 pw.print(" (low-ram)"); 12227 } 12228 if (ActivityManager.isHighEndGfx()) { 12229 pw.print(" (high-end-gfx)"); 12230 } 12231 pw.println(); 12232 } else { 12233 pw.print("ksm,"); pw.print(sharing); pw.print(","); 12234 pw.print(shared); pw.print(","); pw.print(unshared); pw.print(","); 12235 pw.println(voltile); 12236 pw.print("tuning,"); 12237 pw.print(ActivityManager.staticGetMemoryClass()); 12238 pw.print(','); 12239 pw.print(ActivityManager.staticGetLargeMemoryClass()); 12240 pw.print(','); 12241 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024); 12242 if (ActivityManager.isLowRamDeviceStatic()) { 12243 pw.print(",low-ram"); 12244 } 12245 if (ActivityManager.isHighEndGfx()) { 12246 pw.print(",high-end-gfx"); 12247 } 12248 pw.println(); 12249 } 12250 } 12251 } 12252 } 12253 12254 /** 12255 * Searches array of arguments for the specified string 12256 * @param args array of argument strings 12257 * @param value value to search for 12258 * @return true if the value is contained in the array 12259 */ 12260 private static boolean scanArgs(String[] args, String value) { 12261 if (args != null) { 12262 for (String arg : args) { 12263 if (value.equals(arg)) { 12264 return true; 12265 } 12266 } 12267 } 12268 return false; 12269 } 12270 12271 private final boolean removeDyingProviderLocked(ProcessRecord proc, 12272 ContentProviderRecord cpr, boolean always) { 12273 final boolean inLaunching = mLaunchingProviders.contains(cpr); 12274 12275 if (!inLaunching || always) { 12276 synchronized (cpr) { 12277 cpr.launchingApp = null; 12278 cpr.notifyAll(); 12279 } 12280 mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid)); 12281 String names[] = cpr.info.authority.split(";"); 12282 for (int j = 0; j < names.length; j++) { 12283 mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid)); 12284 } 12285 } 12286 12287 for (int i=0; i<cpr.connections.size(); i++) { 12288 ContentProviderConnection conn = cpr.connections.get(i); 12289 if (conn.waiting) { 12290 // If this connection is waiting for the provider, then we don't 12291 // need to mess with its process unless we are always removing 12292 // or for some reason the provider is not currently launching. 12293 if (inLaunching && !always) { 12294 continue; 12295 } 12296 } 12297 ProcessRecord capp = conn.client; 12298 conn.dead = true; 12299 if (conn.stableCount > 0) { 12300 if (!capp.persistent && capp.thread != null 12301 && capp.pid != 0 12302 && capp.pid != MY_PID) { 12303 killUnneededProcessLocked(capp, "depends on provider " 12304 + cpr.name.flattenToShortString() 12305 + " in dying proc " + (proc != null ? proc.processName : "??")); 12306 } 12307 } else if (capp.thread != null && conn.provider.provider != null) { 12308 try { 12309 capp.thread.unstableProviderDied(conn.provider.provider.asBinder()); 12310 } catch (RemoteException e) { 12311 } 12312 // In the protocol here, we don't expect the client to correctly 12313 // clean up this connection, we'll just remove it. 12314 cpr.connections.remove(i); 12315 conn.client.conProviders.remove(conn); 12316 } 12317 } 12318 12319 if (inLaunching && always) { 12320 mLaunchingProviders.remove(cpr); 12321 } 12322 return inLaunching; 12323 } 12324 12325 /** 12326 * Main code for cleaning up a process when it has gone away. This is 12327 * called both as a result of the process dying, or directly when stopping 12328 * a process when running in single process mode. 12329 */ 12330 private final void cleanUpApplicationRecordLocked(ProcessRecord app, 12331 boolean restarting, boolean allowRestart, int index) { 12332 if (index >= 0) { 12333 removeLruProcessLocked(app); 12334 } 12335 12336 mProcessesToGc.remove(app); 12337 mPendingPssProcesses.remove(app); 12338 12339 // Dismiss any open dialogs. 12340 if (app.crashDialog != null && !app.forceCrashReport) { 12341 app.crashDialog.dismiss(); 12342 app.crashDialog = null; 12343 } 12344 if (app.anrDialog != null) { 12345 app.anrDialog.dismiss(); 12346 app.anrDialog = null; 12347 } 12348 if (app.waitDialog != null) { 12349 app.waitDialog.dismiss(); 12350 app.waitDialog = null; 12351 } 12352 12353 app.crashing = false; 12354 app.notResponding = false; 12355 12356 app.resetPackageList(mProcessStats); 12357 app.unlinkDeathRecipient(); 12358 app.makeInactive(mProcessStats); 12359 app.forcingToForeground = null; 12360 app.foregroundServices = false; 12361 app.foregroundActivities = false; 12362 app.hasShownUi = false; 12363 app.hasAboveClient = false; 12364 12365 mServices.killServicesLocked(app, allowRestart); 12366 12367 boolean restart = false; 12368 12369 // Remove published content providers. 12370 for (int i=app.pubProviders.size()-1; i>=0; i--) { 12371 ContentProviderRecord cpr = app.pubProviders.valueAt(i); 12372 final boolean always = app.bad || !allowRestart; 12373 if (removeDyingProviderLocked(app, cpr, always) || always) { 12374 // We left the provider in the launching list, need to 12375 // restart it. 12376 restart = true; 12377 } 12378 12379 cpr.provider = null; 12380 cpr.proc = null; 12381 } 12382 app.pubProviders.clear(); 12383 12384 // Take care of any launching providers waiting for this process. 12385 if (checkAppInLaunchingProvidersLocked(app, false)) { 12386 restart = true; 12387 } 12388 12389 // Unregister from connected content providers. 12390 if (!app.conProviders.isEmpty()) { 12391 for (int i=0; i<app.conProviders.size(); i++) { 12392 ContentProviderConnection conn = app.conProviders.get(i); 12393 conn.provider.connections.remove(conn); 12394 } 12395 app.conProviders.clear(); 12396 } 12397 12398 // At this point there may be remaining entries in mLaunchingProviders 12399 // where we were the only one waiting, so they are no longer of use. 12400 // Look for these and clean up if found. 12401 // XXX Commented out for now. Trying to figure out a way to reproduce 12402 // the actual situation to identify what is actually going on. 12403 if (false) { 12404 for (int i=0; i<mLaunchingProviders.size(); i++) { 12405 ContentProviderRecord cpr = (ContentProviderRecord) 12406 mLaunchingProviders.get(i); 12407 if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) { 12408 synchronized (cpr) { 12409 cpr.launchingApp = null; 12410 cpr.notifyAll(); 12411 } 12412 } 12413 } 12414 } 12415 12416 skipCurrentReceiverLocked(app); 12417 12418 // Unregister any receivers. 12419 for (int i=app.receivers.size()-1; i>=0; i--) { 12420 removeReceiverLocked(app.receivers.valueAt(i)); 12421 } 12422 app.receivers.clear(); 12423 12424 // If the app is undergoing backup, tell the backup manager about it 12425 if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) { 12426 if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App " 12427 + mBackupTarget.appInfo + " died during backup"); 12428 try { 12429 IBackupManager bm = IBackupManager.Stub.asInterface( 12430 ServiceManager.getService(Context.BACKUP_SERVICE)); 12431 bm.agentDisconnected(app.info.packageName); 12432 } catch (RemoteException e) { 12433 // can't happen; backup manager is local 12434 } 12435 } 12436 12437 for (int i = mPendingProcessChanges.size()-1; i>=0; i--) { 12438 ProcessChangeItem item = mPendingProcessChanges.get(i); 12439 if (item.pid == app.pid) { 12440 mPendingProcessChanges.remove(i); 12441 mAvailProcessChanges.add(item); 12442 } 12443 } 12444 mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget(); 12445 12446 // If the caller is restarting this app, then leave it in its 12447 // current lists and let the caller take care of it. 12448 if (restarting) { 12449 return; 12450 } 12451 12452 if (!app.persistent || app.isolated) { 12453 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, 12454 "Removing non-persistent process during cleanup: " + app); 12455 mProcessNames.remove(app.processName, app.uid); 12456 mIsolatedProcesses.remove(app.uid); 12457 if (mHeavyWeightProcess == app) { 12458 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 12459 mHeavyWeightProcess.userId, 0)); 12460 mHeavyWeightProcess = null; 12461 } 12462 } else if (!app.removed) { 12463 // This app is persistent, so we need to keep its record around. 12464 // If it is not already on the pending app list, add it there 12465 // and start a new process for it. 12466 if (mPersistentStartingProcesses.indexOf(app) < 0) { 12467 mPersistentStartingProcesses.add(app); 12468 restart = true; 12469 } 12470 } 12471 if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG, 12472 "Clean-up removing on hold: " + app); 12473 mProcessesOnHold.remove(app); 12474 12475 if (app == mHomeProcess) { 12476 mHomeProcess = null; 12477 } 12478 if (app == mPreviousProcess) { 12479 mPreviousProcess = null; 12480 } 12481 12482 if (restart && !app.isolated) { 12483 // We have components that still need to be running in the 12484 // process, so re-launch it. 12485 mProcessNames.put(app.processName, app.uid, app); 12486 startProcessLocked(app, "restart", app.processName); 12487 } else if (app.pid > 0 && app.pid != MY_PID) { 12488 // Goodbye! 12489 synchronized (mPidsSelfLocked) { 12490 mPidsSelfLocked.remove(app.pid); 12491 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 12492 } 12493 app.setPid(0); 12494 } 12495 } 12496 12497 boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) { 12498 // Look through the content providers we are waiting to have launched, 12499 // and if any run in this process then either schedule a restart of 12500 // the process or kill the client waiting for it if this process has 12501 // gone bad. 12502 int NL = mLaunchingProviders.size(); 12503 boolean restart = false; 12504 for (int i=0; i<NL; i++) { 12505 ContentProviderRecord cpr = mLaunchingProviders.get(i); 12506 if (cpr.launchingApp == app) { 12507 if (!alwaysBad && !app.bad) { 12508 restart = true; 12509 } else { 12510 removeDyingProviderLocked(app, cpr, true); 12511 // cpr should have been removed from mLaunchingProviders 12512 NL = mLaunchingProviders.size(); 12513 i--; 12514 } 12515 } 12516 } 12517 return restart; 12518 } 12519 12520 // ========================================================= 12521 // SERVICES 12522 // ========================================================= 12523 12524 public List<ActivityManager.RunningServiceInfo> getServices(int maxNum, 12525 int flags) { 12526 enforceNotIsolatedCaller("getServices"); 12527 synchronized (this) { 12528 return mServices.getRunningServiceInfoLocked(maxNum, flags); 12529 } 12530 } 12531 12532 public PendingIntent getRunningServiceControlPanel(ComponentName name) { 12533 enforceNotIsolatedCaller("getRunningServiceControlPanel"); 12534 synchronized (this) { 12535 return mServices.getRunningServiceControlPanelLocked(name); 12536 } 12537 } 12538 12539 public ComponentName startService(IApplicationThread caller, Intent service, 12540 String resolvedType, int userId) { 12541 enforceNotIsolatedCaller("startService"); 12542 // Refuse possible leaked file descriptors 12543 if (service != null && service.hasFileDescriptors() == true) { 12544 throw new IllegalArgumentException("File descriptors passed in Intent"); 12545 } 12546 12547 if (DEBUG_SERVICE) 12548 Slog.v(TAG, "startService: " + service + " type=" + resolvedType); 12549 synchronized(this) { 12550 final int callingPid = Binder.getCallingPid(); 12551 final int callingUid = Binder.getCallingUid(); 12552 final long origId = Binder.clearCallingIdentity(); 12553 ComponentName res = mServices.startServiceLocked(caller, service, 12554 resolvedType, callingPid, callingUid, userId); 12555 Binder.restoreCallingIdentity(origId); 12556 return res; 12557 } 12558 } 12559 12560 ComponentName startServiceInPackage(int uid, 12561 Intent service, String resolvedType, int userId) { 12562 synchronized(this) { 12563 if (DEBUG_SERVICE) 12564 Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType); 12565 final long origId = Binder.clearCallingIdentity(); 12566 ComponentName res = mServices.startServiceLocked(null, service, 12567 resolvedType, -1, uid, userId); 12568 Binder.restoreCallingIdentity(origId); 12569 return res; 12570 } 12571 } 12572 12573 public int stopService(IApplicationThread caller, Intent service, 12574 String resolvedType, int userId) { 12575 enforceNotIsolatedCaller("stopService"); 12576 // Refuse possible leaked file descriptors 12577 if (service != null && service.hasFileDescriptors() == true) { 12578 throw new IllegalArgumentException("File descriptors passed in Intent"); 12579 } 12580 12581 synchronized(this) { 12582 return mServices.stopServiceLocked(caller, service, resolvedType, userId); 12583 } 12584 } 12585 12586 public IBinder peekService(Intent service, String resolvedType) { 12587 enforceNotIsolatedCaller("peekService"); 12588 // Refuse possible leaked file descriptors 12589 if (service != null && service.hasFileDescriptors() == true) { 12590 throw new IllegalArgumentException("File descriptors passed in Intent"); 12591 } 12592 synchronized(this) { 12593 return mServices.peekServiceLocked(service, resolvedType); 12594 } 12595 } 12596 12597 public boolean stopServiceToken(ComponentName className, IBinder token, 12598 int startId) { 12599 synchronized(this) { 12600 return mServices.stopServiceTokenLocked(className, token, startId); 12601 } 12602 } 12603 12604 public void setServiceForeground(ComponentName className, IBinder token, 12605 int id, Notification notification, boolean removeNotification) { 12606 synchronized(this) { 12607 mServices.setServiceForegroundLocked(className, token, id, notification, 12608 removeNotification); 12609 } 12610 } 12611 12612 public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll, 12613 boolean requireFull, String name, String callerPackage) { 12614 final int callingUserId = UserHandle.getUserId(callingUid); 12615 if (callingUserId != userId) { 12616 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 12617 if ((requireFull || checkComponentPermission( 12618 android.Manifest.permission.INTERACT_ACROSS_USERS, 12619 callingPid, callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) 12620 && checkComponentPermission( 12621 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 12622 callingPid, callingUid, -1, true) 12623 != PackageManager.PERMISSION_GRANTED) { 12624 if (userId == UserHandle.USER_CURRENT_OR_SELF) { 12625 // In this case, they would like to just execute as their 12626 // owner user instead of failing. 12627 userId = callingUserId; 12628 } else { 12629 StringBuilder builder = new StringBuilder(128); 12630 builder.append("Permission Denial: "); 12631 builder.append(name); 12632 if (callerPackage != null) { 12633 builder.append(" from "); 12634 builder.append(callerPackage); 12635 } 12636 builder.append(" asks to run as user "); 12637 builder.append(userId); 12638 builder.append(" but is calling from user "); 12639 builder.append(UserHandle.getUserId(callingUid)); 12640 builder.append("; this requires "); 12641 builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL); 12642 if (!requireFull) { 12643 builder.append(" or "); 12644 builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS); 12645 } 12646 String msg = builder.toString(); 12647 Slog.w(TAG, msg); 12648 throw new SecurityException(msg); 12649 } 12650 } 12651 } 12652 if (userId == UserHandle.USER_CURRENT 12653 || userId == UserHandle.USER_CURRENT_OR_SELF) { 12654 // Note that we may be accessing this outside of a lock... 12655 // shouldn't be a big deal, if this is being called outside 12656 // of a locked context there is intrinsically a race with 12657 // the value the caller will receive and someone else changing it. 12658 userId = mCurrentUserId; 12659 } 12660 if (!allowAll && userId < 0) { 12661 throw new IllegalArgumentException( 12662 "Call does not support special user #" + userId); 12663 } 12664 } 12665 return userId; 12666 } 12667 12668 boolean isSingleton(String componentProcessName, ApplicationInfo aInfo, 12669 String className, int flags) { 12670 boolean result = false; 12671 if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) { 12672 if ((flags&ServiceInfo.FLAG_SINGLE_USER) != 0) { 12673 if (ActivityManager.checkUidPermission( 12674 android.Manifest.permission.INTERACT_ACROSS_USERS, 12675 aInfo.uid) != PackageManager.PERMISSION_GRANTED) { 12676 ComponentName comp = new ComponentName(aInfo.packageName, className); 12677 String msg = "Permission Denial: Component " + comp.flattenToShortString() 12678 + " requests FLAG_SINGLE_USER, but app does not hold " 12679 + android.Manifest.permission.INTERACT_ACROSS_USERS; 12680 Slog.w(TAG, msg); 12681 throw new SecurityException(msg); 12682 } 12683 result = true; 12684 } 12685 } else if (componentProcessName == aInfo.packageName) { 12686 result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0; 12687 } else if ("system".equals(componentProcessName)) { 12688 result = true; 12689 } 12690 if (DEBUG_MU) { 12691 Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo 12692 + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result); 12693 } 12694 return result; 12695 } 12696 12697 public int bindService(IApplicationThread caller, IBinder token, 12698 Intent service, String resolvedType, 12699 IServiceConnection connection, int flags, int userId) { 12700 enforceNotIsolatedCaller("bindService"); 12701 // Refuse possible leaked file descriptors 12702 if (service != null && service.hasFileDescriptors() == true) { 12703 throw new IllegalArgumentException("File descriptors passed in Intent"); 12704 } 12705 12706 synchronized(this) { 12707 return mServices.bindServiceLocked(caller, token, service, resolvedType, 12708 connection, flags, userId); 12709 } 12710 } 12711 12712 public boolean unbindService(IServiceConnection connection) { 12713 synchronized (this) { 12714 return mServices.unbindServiceLocked(connection); 12715 } 12716 } 12717 12718 public void publishService(IBinder token, Intent intent, IBinder service) { 12719 // Refuse possible leaked file descriptors 12720 if (intent != null && intent.hasFileDescriptors() == true) { 12721 throw new IllegalArgumentException("File descriptors passed in Intent"); 12722 } 12723 12724 synchronized(this) { 12725 if (!(token instanceof ServiceRecord)) { 12726 throw new IllegalArgumentException("Invalid service token"); 12727 } 12728 mServices.publishServiceLocked((ServiceRecord)token, intent, service); 12729 } 12730 } 12731 12732 public void unbindFinished(IBinder token, Intent intent, boolean doRebind) { 12733 // Refuse possible leaked file descriptors 12734 if (intent != null && intent.hasFileDescriptors() == true) { 12735 throw new IllegalArgumentException("File descriptors passed in Intent"); 12736 } 12737 12738 synchronized(this) { 12739 mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind); 12740 } 12741 } 12742 12743 public void serviceDoneExecuting(IBinder token, int type, int startId, int res) { 12744 synchronized(this) { 12745 if (!(token instanceof ServiceRecord)) { 12746 throw new IllegalArgumentException("Invalid service token"); 12747 } 12748 mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res); 12749 } 12750 } 12751 12752 // ========================================================= 12753 // BACKUP AND RESTORE 12754 // ========================================================= 12755 12756 // Cause the target app to be launched if necessary and its backup agent 12757 // instantiated. The backup agent will invoke backupAgentCreated() on the 12758 // activity manager to announce its creation. 12759 public boolean bindBackupAgent(ApplicationInfo app, int backupMode) { 12760 if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode); 12761 enforceCallingPermission("android.permission.BACKUP", "bindBackupAgent"); 12762 12763 synchronized(this) { 12764 // !!! TODO: currently no check here that we're already bound 12765 BatteryStatsImpl.Uid.Pkg.Serv ss = null; 12766 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 12767 synchronized (stats) { 12768 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name); 12769 } 12770 12771 // Backup agent is now in use, its package can't be stopped. 12772 try { 12773 AppGlobals.getPackageManager().setPackageStoppedState( 12774 app.packageName, false, UserHandle.getUserId(app.uid)); 12775 } catch (RemoteException e) { 12776 } catch (IllegalArgumentException e) { 12777 Slog.w(TAG, "Failed trying to unstop package " 12778 + app.packageName + ": " + e); 12779 } 12780 12781 BackupRecord r = new BackupRecord(ss, app, backupMode); 12782 ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL) 12783 ? new ComponentName(app.packageName, app.backupAgentName) 12784 : new ComponentName("android", "FullBackupAgent"); 12785 // startProcessLocked() returns existing proc's record if it's already running 12786 ProcessRecord proc = startProcessLocked(app.processName, app, 12787 false, 0, "backup", hostingName, false, false, false); 12788 if (proc == null) { 12789 Slog.e(TAG, "Unable to start backup agent process " + r); 12790 return false; 12791 } 12792 12793 r.app = proc; 12794 mBackupTarget = r; 12795 mBackupAppName = app.packageName; 12796 12797 // Try not to kill the process during backup 12798 updateOomAdjLocked(proc); 12799 12800 // If the process is already attached, schedule the creation of the backup agent now. 12801 // If it is not yet live, this will be done when it attaches to the framework. 12802 if (proc.thread != null) { 12803 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc); 12804 try { 12805 proc.thread.scheduleCreateBackupAgent(app, 12806 compatibilityInfoForPackageLocked(app), backupMode); 12807 } catch (RemoteException e) { 12808 // Will time out on the backup manager side 12809 } 12810 } else { 12811 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach"); 12812 } 12813 // Invariants: at this point, the target app process exists and the application 12814 // is either already running or in the process of coming up. mBackupTarget and 12815 // mBackupAppName describe the app, so that when it binds back to the AM we 12816 // know that it's scheduled for a backup-agent operation. 12817 } 12818 12819 return true; 12820 } 12821 12822 @Override 12823 public void clearPendingBackup() { 12824 if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup"); 12825 enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup"); 12826 12827 synchronized (this) { 12828 mBackupTarget = null; 12829 mBackupAppName = null; 12830 } 12831 } 12832 12833 // A backup agent has just come up 12834 public void backupAgentCreated(String agentPackageName, IBinder agent) { 12835 if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName 12836 + " = " + agent); 12837 12838 synchronized(this) { 12839 if (!agentPackageName.equals(mBackupAppName)) { 12840 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!"); 12841 return; 12842 } 12843 } 12844 12845 long oldIdent = Binder.clearCallingIdentity(); 12846 try { 12847 IBackupManager bm = IBackupManager.Stub.asInterface( 12848 ServiceManager.getService(Context.BACKUP_SERVICE)); 12849 bm.agentConnected(agentPackageName, agent); 12850 } catch (RemoteException e) { 12851 // can't happen; the backup manager service is local 12852 } catch (Exception e) { 12853 Slog.w(TAG, "Exception trying to deliver BackupAgent binding: "); 12854 e.printStackTrace(); 12855 } finally { 12856 Binder.restoreCallingIdentity(oldIdent); 12857 } 12858 } 12859 12860 // done with this agent 12861 public void unbindBackupAgent(ApplicationInfo appInfo) { 12862 if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo); 12863 if (appInfo == null) { 12864 Slog.w(TAG, "unbind backup agent for null app"); 12865 return; 12866 } 12867 12868 synchronized(this) { 12869 try { 12870 if (mBackupAppName == null) { 12871 Slog.w(TAG, "Unbinding backup agent with no active backup"); 12872 return; 12873 } 12874 12875 if (!mBackupAppName.equals(appInfo.packageName)) { 12876 Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target"); 12877 return; 12878 } 12879 12880 // Not backing this app up any more; reset its OOM adjustment 12881 final ProcessRecord proc = mBackupTarget.app; 12882 updateOomAdjLocked(proc); 12883 12884 // If the app crashed during backup, 'thread' will be null here 12885 if (proc.thread != null) { 12886 try { 12887 proc.thread.scheduleDestroyBackupAgent(appInfo, 12888 compatibilityInfoForPackageLocked(appInfo)); 12889 } catch (Exception e) { 12890 Slog.e(TAG, "Exception when unbinding backup agent:"); 12891 e.printStackTrace(); 12892 } 12893 } 12894 } finally { 12895 mBackupTarget = null; 12896 mBackupAppName = null; 12897 } 12898 } 12899 } 12900 // ========================================================= 12901 // BROADCASTS 12902 // ========================================================= 12903 12904 private final List getStickiesLocked(String action, IntentFilter filter, 12905 List cur, int userId) { 12906 final ContentResolver resolver = mContext.getContentResolver(); 12907 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 12908 if (stickies == null) { 12909 return cur; 12910 } 12911 final ArrayList<Intent> list = stickies.get(action); 12912 if (list == null) { 12913 return cur; 12914 } 12915 int N = list.size(); 12916 for (int i=0; i<N; i++) { 12917 Intent intent = list.get(i); 12918 if (filter.match(resolver, intent, true, TAG) >= 0) { 12919 if (cur == null) { 12920 cur = new ArrayList<Intent>(); 12921 } 12922 cur.add(intent); 12923 } 12924 } 12925 return cur; 12926 } 12927 12928 boolean isPendingBroadcastProcessLocked(int pid) { 12929 return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid) 12930 || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid); 12931 } 12932 12933 void skipPendingBroadcastLocked(int pid) { 12934 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 12935 for (BroadcastQueue queue : mBroadcastQueues) { 12936 queue.skipPendingBroadcastLocked(pid); 12937 } 12938 } 12939 12940 // The app just attached; send any pending broadcasts that it should receive 12941 boolean sendPendingBroadcastsLocked(ProcessRecord app) { 12942 boolean didSomething = false; 12943 for (BroadcastQueue queue : mBroadcastQueues) { 12944 didSomething |= queue.sendPendingBroadcastsLocked(app); 12945 } 12946 return didSomething; 12947 } 12948 12949 public Intent registerReceiver(IApplicationThread caller, String callerPackage, 12950 IIntentReceiver receiver, IntentFilter filter, String permission, int userId) { 12951 enforceNotIsolatedCaller("registerReceiver"); 12952 int callingUid; 12953 int callingPid; 12954 synchronized(this) { 12955 ProcessRecord callerApp = null; 12956 if (caller != null) { 12957 callerApp = getRecordForAppLocked(caller); 12958 if (callerApp == null) { 12959 throw new SecurityException( 12960 "Unable to find app for caller " + caller 12961 + " (pid=" + Binder.getCallingPid() 12962 + ") when registering receiver " + receiver); 12963 } 12964 if (callerApp.info.uid != Process.SYSTEM_UID && 12965 !callerApp.pkgList.containsKey(callerPackage) && 12966 !"android".equals(callerPackage)) { 12967 throw new SecurityException("Given caller package " + callerPackage 12968 + " is not running in process " + callerApp); 12969 } 12970 callingUid = callerApp.info.uid; 12971 callingPid = callerApp.pid; 12972 } else { 12973 callerPackage = null; 12974 callingUid = Binder.getCallingUid(); 12975 callingPid = Binder.getCallingPid(); 12976 } 12977 12978 userId = this.handleIncomingUser(callingPid, callingUid, userId, 12979 true, true, "registerReceiver", callerPackage); 12980 12981 List allSticky = null; 12982 12983 // Look for any matching sticky broadcasts... 12984 Iterator actions = filter.actionsIterator(); 12985 if (actions != null) { 12986 while (actions.hasNext()) { 12987 String action = (String)actions.next(); 12988 allSticky = getStickiesLocked(action, filter, allSticky, 12989 UserHandle.USER_ALL); 12990 allSticky = getStickiesLocked(action, filter, allSticky, 12991 UserHandle.getUserId(callingUid)); 12992 } 12993 } else { 12994 allSticky = getStickiesLocked(null, filter, allSticky, 12995 UserHandle.USER_ALL); 12996 allSticky = getStickiesLocked(null, filter, allSticky, 12997 UserHandle.getUserId(callingUid)); 12998 } 12999 13000 // The first sticky in the list is returned directly back to 13001 // the client. 13002 Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null; 13003 13004 if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter 13005 + ": " + sticky); 13006 13007 if (receiver == null) { 13008 return sticky; 13009 } 13010 13011 ReceiverList rl 13012 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder()); 13013 if (rl == null) { 13014 rl = new ReceiverList(this, callerApp, callingPid, callingUid, 13015 userId, receiver); 13016 if (rl.app != null) { 13017 rl.app.receivers.add(rl); 13018 } else { 13019 try { 13020 receiver.asBinder().linkToDeath(rl, 0); 13021 } catch (RemoteException e) { 13022 return sticky; 13023 } 13024 rl.linkedToDeath = true; 13025 } 13026 mRegisteredReceivers.put(receiver.asBinder(), rl); 13027 } else if (rl.uid != callingUid) { 13028 throw new IllegalArgumentException( 13029 "Receiver requested to register for uid " + callingUid 13030 + " was previously registered for uid " + rl.uid); 13031 } else if (rl.pid != callingPid) { 13032 throw new IllegalArgumentException( 13033 "Receiver requested to register for pid " + callingPid 13034 + " was previously registered for pid " + rl.pid); 13035 } else if (rl.userId != userId) { 13036 throw new IllegalArgumentException( 13037 "Receiver requested to register for user " + userId 13038 + " was previously registered for user " + rl.userId); 13039 } 13040 BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage, 13041 permission, callingUid, userId); 13042 rl.add(bf); 13043 if (!bf.debugCheck()) { 13044 Slog.w(TAG, "==> For Dynamic broadast"); 13045 } 13046 mReceiverResolver.addFilter(bf); 13047 13048 // Enqueue broadcasts for all existing stickies that match 13049 // this filter. 13050 if (allSticky != null) { 13051 ArrayList receivers = new ArrayList(); 13052 receivers.add(bf); 13053 13054 int N = allSticky.size(); 13055 for (int i=0; i<N; i++) { 13056 Intent intent = (Intent)allSticky.get(i); 13057 BroadcastQueue queue = broadcastQueueForIntent(intent); 13058 BroadcastRecord r = new BroadcastRecord(queue, intent, null, 13059 null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0, 13060 null, null, false, true, true, -1); 13061 queue.enqueueParallelBroadcastLocked(r); 13062 queue.scheduleBroadcastsLocked(); 13063 } 13064 } 13065 13066 return sticky; 13067 } 13068 } 13069 13070 public void unregisterReceiver(IIntentReceiver receiver) { 13071 if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver); 13072 13073 final long origId = Binder.clearCallingIdentity(); 13074 try { 13075 boolean doTrim = false; 13076 13077 synchronized(this) { 13078 ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder()); 13079 if (rl != null) { 13080 if (rl.curBroadcast != null) { 13081 BroadcastRecord r = rl.curBroadcast; 13082 final boolean doNext = finishReceiverLocked( 13083 receiver.asBinder(), r.resultCode, r.resultData, 13084 r.resultExtras, r.resultAbort); 13085 if (doNext) { 13086 doTrim = true; 13087 r.queue.processNextBroadcast(false); 13088 } 13089 } 13090 13091 if (rl.app != null) { 13092 rl.app.receivers.remove(rl); 13093 } 13094 removeReceiverLocked(rl); 13095 if (rl.linkedToDeath) { 13096 rl.linkedToDeath = false; 13097 rl.receiver.asBinder().unlinkToDeath(rl, 0); 13098 } 13099 } 13100 } 13101 13102 // If we actually concluded any broadcasts, we might now be able 13103 // to trim the recipients' apps from our working set 13104 if (doTrim) { 13105 trimApplications(); 13106 return; 13107 } 13108 13109 } finally { 13110 Binder.restoreCallingIdentity(origId); 13111 } 13112 } 13113 13114 void removeReceiverLocked(ReceiverList rl) { 13115 mRegisteredReceivers.remove(rl.receiver.asBinder()); 13116 int N = rl.size(); 13117 for (int i=0; i<N; i++) { 13118 mReceiverResolver.removeFilter(rl.get(i)); 13119 } 13120 } 13121 13122 private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) { 13123 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 13124 ProcessRecord r = mLruProcesses.get(i); 13125 if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) { 13126 try { 13127 r.thread.dispatchPackageBroadcast(cmd, packages); 13128 } catch (RemoteException ex) { 13129 } 13130 } 13131 } 13132 } 13133 13134 private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType, 13135 int[] users) { 13136 List<ResolveInfo> receivers = null; 13137 try { 13138 HashSet<ComponentName> singleUserReceivers = null; 13139 boolean scannedFirstReceivers = false; 13140 for (int user : users) { 13141 List<ResolveInfo> newReceivers = AppGlobals.getPackageManager() 13142 .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user); 13143 if (user != 0 && newReceivers != null) { 13144 // If this is not the primary user, we need to check for 13145 // any receivers that should be filtered out. 13146 for (int i=0; i<newReceivers.size(); i++) { 13147 ResolveInfo ri = newReceivers.get(i); 13148 if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) { 13149 newReceivers.remove(i); 13150 i--; 13151 } 13152 } 13153 } 13154 if (newReceivers != null && newReceivers.size() == 0) { 13155 newReceivers = null; 13156 } 13157 if (receivers == null) { 13158 receivers = newReceivers; 13159 } else if (newReceivers != null) { 13160 // We need to concatenate the additional receivers 13161 // found with what we have do far. This would be easy, 13162 // but we also need to de-dup any receivers that are 13163 // singleUser. 13164 if (!scannedFirstReceivers) { 13165 // Collect any single user receivers we had already retrieved. 13166 scannedFirstReceivers = true; 13167 for (int i=0; i<receivers.size(); i++) { 13168 ResolveInfo ri = receivers.get(i); 13169 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 13170 ComponentName cn = new ComponentName( 13171 ri.activityInfo.packageName, ri.activityInfo.name); 13172 if (singleUserReceivers == null) { 13173 singleUserReceivers = new HashSet<ComponentName>(); 13174 } 13175 singleUserReceivers.add(cn); 13176 } 13177 } 13178 } 13179 // Add the new results to the existing results, tracking 13180 // and de-dupping single user receivers. 13181 for (int i=0; i<newReceivers.size(); i++) { 13182 ResolveInfo ri = newReceivers.get(i); 13183 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 13184 ComponentName cn = new ComponentName( 13185 ri.activityInfo.packageName, ri.activityInfo.name); 13186 if (singleUserReceivers == null) { 13187 singleUserReceivers = new HashSet<ComponentName>(); 13188 } 13189 if (!singleUserReceivers.contains(cn)) { 13190 singleUserReceivers.add(cn); 13191 receivers.add(ri); 13192 } 13193 } else { 13194 receivers.add(ri); 13195 } 13196 } 13197 } 13198 } 13199 } catch (RemoteException ex) { 13200 // pm is in same process, this will never happen. 13201 } 13202 return receivers; 13203 } 13204 13205 private final int broadcastIntentLocked(ProcessRecord callerApp, 13206 String callerPackage, Intent intent, String resolvedType, 13207 IIntentReceiver resultTo, int resultCode, String resultData, 13208 Bundle map, String requiredPermission, int appOp, 13209 boolean ordered, boolean sticky, int callingPid, int callingUid, 13210 int userId) { 13211 intent = new Intent(intent); 13212 13213 // By default broadcasts do not go to stopped apps. 13214 intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES); 13215 13216 if (DEBUG_BROADCAST_LIGHT) Slog.v( 13217 TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent 13218 + " ordered=" + ordered + " userid=" + userId); 13219 if ((resultTo != null) && !ordered) { 13220 Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!"); 13221 } 13222 13223 userId = handleIncomingUser(callingPid, callingUid, userId, 13224 true, false, "broadcast", callerPackage); 13225 13226 // Make sure that the user who is receiving this broadcast is started. 13227 // If not, we will just skip it. 13228 if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) { 13229 if (callingUid != Process.SYSTEM_UID || (intent.getFlags() 13230 & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) { 13231 Slog.w(TAG, "Skipping broadcast of " + intent 13232 + ": user " + userId + " is stopped"); 13233 return ActivityManager.BROADCAST_SUCCESS; 13234 } 13235 } 13236 13237 /* 13238 * Prevent non-system code (defined here to be non-persistent 13239 * processes) from sending protected broadcasts. 13240 */ 13241 int callingAppId = UserHandle.getAppId(callingUid); 13242 if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID 13243 || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID || 13244 callingUid == 0) { 13245 // Always okay. 13246 } else if (callerApp == null || !callerApp.persistent) { 13247 try { 13248 if (AppGlobals.getPackageManager().isProtectedBroadcast( 13249 intent.getAction())) { 13250 String msg = "Permission Denial: not allowed to send broadcast " 13251 + intent.getAction() + " from pid=" 13252 + callingPid + ", uid=" + callingUid; 13253 Slog.w(TAG, msg); 13254 throw new SecurityException(msg); 13255 } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) { 13256 // Special case for compatibility: we don't want apps to send this, 13257 // but historically it has not been protected and apps may be using it 13258 // to poke their own app widget. So, instead of making it protected, 13259 // just limit it to the caller. 13260 if (callerApp == null) { 13261 String msg = "Permission Denial: not allowed to send broadcast " 13262 + intent.getAction() + " from unknown caller."; 13263 Slog.w(TAG, msg); 13264 throw new SecurityException(msg); 13265 } else if (intent.getComponent() != null) { 13266 // They are good enough to send to an explicit component... verify 13267 // it is being sent to the calling app. 13268 if (!intent.getComponent().getPackageName().equals( 13269 callerApp.info.packageName)) { 13270 String msg = "Permission Denial: not allowed to send broadcast " 13271 + intent.getAction() + " to " 13272 + intent.getComponent().getPackageName() + " from " 13273 + callerApp.info.packageName; 13274 Slog.w(TAG, msg); 13275 throw new SecurityException(msg); 13276 } 13277 } else { 13278 // Limit broadcast to their own package. 13279 intent.setPackage(callerApp.info.packageName); 13280 } 13281 } 13282 } catch (RemoteException e) { 13283 Slog.w(TAG, "Remote exception", e); 13284 return ActivityManager.BROADCAST_SUCCESS; 13285 } 13286 } 13287 13288 // Handle special intents: if this broadcast is from the package 13289 // manager about a package being removed, we need to remove all of 13290 // its activities from the history stack. 13291 final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals( 13292 intent.getAction()); 13293 if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction()) 13294 || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction()) 13295 || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction()) 13296 || uidRemoved) { 13297 if (checkComponentPermission( 13298 android.Manifest.permission.BROADCAST_PACKAGE_REMOVED, 13299 callingPid, callingUid, -1, true) 13300 == PackageManager.PERMISSION_GRANTED) { 13301 if (uidRemoved) { 13302 final Bundle intentExtras = intent.getExtras(); 13303 final int uid = intentExtras != null 13304 ? intentExtras.getInt(Intent.EXTRA_UID) : -1; 13305 if (uid >= 0) { 13306 BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics(); 13307 synchronized (bs) { 13308 bs.removeUidStatsLocked(uid); 13309 } 13310 mAppOpsService.uidRemoved(uid); 13311 } 13312 } else { 13313 // If resources are unavailable just force stop all 13314 // those packages and flush the attribute cache as well. 13315 if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) { 13316 String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 13317 if (list != null && (list.length > 0)) { 13318 for (String pkg : list) { 13319 forceStopPackageLocked(pkg, -1, false, true, true, false, userId, 13320 "storage unmount"); 13321 } 13322 sendPackageBroadcastLocked( 13323 IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId); 13324 } 13325 } else { 13326 Uri data = intent.getData(); 13327 String ssp; 13328 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 13329 boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals( 13330 intent.getAction()); 13331 if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) { 13332 forceStopPackageLocked(ssp, UserHandle.getAppId( 13333 intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true, 13334 false, userId, removed ? "pkg removed" : "pkg changed"); 13335 } 13336 if (removed) { 13337 sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED, 13338 new String[] {ssp}, userId); 13339 if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) { 13340 mAppOpsService.packageRemoved( 13341 intent.getIntExtra(Intent.EXTRA_UID, -1), ssp); 13342 13343 // Remove all permissions granted from/to this package 13344 removeUriPermissionsForPackageLocked(ssp, userId, true); 13345 } 13346 } 13347 } 13348 } 13349 } 13350 } else { 13351 String msg = "Permission Denial: " + intent.getAction() 13352 + " broadcast from " + callerPackage + " (pid=" + callingPid 13353 + ", uid=" + callingUid + ")" 13354 + " requires " 13355 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED; 13356 Slog.w(TAG, msg); 13357 throw new SecurityException(msg); 13358 } 13359 13360 // Special case for adding a package: by default turn on compatibility 13361 // mode. 13362 } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) { 13363 Uri data = intent.getData(); 13364 String ssp; 13365 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 13366 mCompatModePackages.handlePackageAddedLocked(ssp, 13367 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)); 13368 } 13369 } 13370 13371 /* 13372 * If this is the time zone changed action, queue up a message that will reset the timezone 13373 * of all currently running processes. This message will get queued up before the broadcast 13374 * happens. 13375 */ 13376 if (intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) { 13377 mHandler.sendEmptyMessage(UPDATE_TIME_ZONE); 13378 } 13379 13380 if (intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) { 13381 mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG); 13382 } 13383 13384 if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) { 13385 ProxyProperties proxy = intent.getParcelableExtra("proxy"); 13386 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy)); 13387 } 13388 13389 // Add to the sticky list if requested. 13390 if (sticky) { 13391 if (checkPermission(android.Manifest.permission.BROADCAST_STICKY, 13392 callingPid, callingUid) 13393 != PackageManager.PERMISSION_GRANTED) { 13394 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid=" 13395 + callingPid + ", uid=" + callingUid 13396 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 13397 Slog.w(TAG, msg); 13398 throw new SecurityException(msg); 13399 } 13400 if (requiredPermission != null) { 13401 Slog.w(TAG, "Can't broadcast sticky intent " + intent 13402 + " and enforce permission " + requiredPermission); 13403 return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION; 13404 } 13405 if (intent.getComponent() != null) { 13406 throw new SecurityException( 13407 "Sticky broadcasts can't target a specific component"); 13408 } 13409 // We use userId directly here, since the "all" target is maintained 13410 // as a separate set of sticky broadcasts. 13411 if (userId != UserHandle.USER_ALL) { 13412 // But first, if this is not a broadcast to all users, then 13413 // make sure it doesn't conflict with an existing broadcast to 13414 // all users. 13415 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get( 13416 UserHandle.USER_ALL); 13417 if (stickies != null) { 13418 ArrayList<Intent> list = stickies.get(intent.getAction()); 13419 if (list != null) { 13420 int N = list.size(); 13421 int i; 13422 for (i=0; i<N; i++) { 13423 if (intent.filterEquals(list.get(i))) { 13424 throw new IllegalArgumentException( 13425 "Sticky broadcast " + intent + " for user " 13426 + userId + " conflicts with existing global broadcast"); 13427 } 13428 } 13429 } 13430 } 13431 } 13432 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 13433 if (stickies == null) { 13434 stickies = new ArrayMap<String, ArrayList<Intent>>(); 13435 mStickyBroadcasts.put(userId, stickies); 13436 } 13437 ArrayList<Intent> list = stickies.get(intent.getAction()); 13438 if (list == null) { 13439 list = new ArrayList<Intent>(); 13440 stickies.put(intent.getAction(), list); 13441 } 13442 int N = list.size(); 13443 int i; 13444 for (i=0; i<N; i++) { 13445 if (intent.filterEquals(list.get(i))) { 13446 // This sticky already exists, replace it. 13447 list.set(i, new Intent(intent)); 13448 break; 13449 } 13450 } 13451 if (i >= N) { 13452 list.add(new Intent(intent)); 13453 } 13454 } 13455 13456 int[] users; 13457 if (userId == UserHandle.USER_ALL) { 13458 // Caller wants broadcast to go to all started users. 13459 users = mStartedUserArray; 13460 } else { 13461 // Caller wants broadcast to go to one specific user. 13462 users = new int[] {userId}; 13463 } 13464 13465 // Figure out who all will receive this broadcast. 13466 List receivers = null; 13467 List<BroadcastFilter> registeredReceivers = null; 13468 // Need to resolve the intent to interested receivers... 13469 if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) 13470 == 0) { 13471 receivers = collectReceiverComponents(intent, resolvedType, users); 13472 } 13473 if (intent.getComponent() == null) { 13474 registeredReceivers = mReceiverResolver.queryIntent(intent, 13475 resolvedType, false, userId); 13476 } 13477 13478 final boolean replacePending = 13479 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0; 13480 13481 if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction() 13482 + " replacePending=" + replacePending); 13483 13484 int NR = registeredReceivers != null ? registeredReceivers.size() : 0; 13485 if (!ordered && NR > 0) { 13486 // If we are not serializing this broadcast, then send the 13487 // registered receivers separately so they don't wait for the 13488 // components to be launched. 13489 final BroadcastQueue queue = broadcastQueueForIntent(intent); 13490 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 13491 callerPackage, callingPid, callingUid, resolvedType, requiredPermission, 13492 appOp, registeredReceivers, resultTo, resultCode, resultData, map, 13493 ordered, sticky, false, userId); 13494 if (DEBUG_BROADCAST) Slog.v( 13495 TAG, "Enqueueing parallel broadcast " + r); 13496 final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r); 13497 if (!replaced) { 13498 queue.enqueueParallelBroadcastLocked(r); 13499 queue.scheduleBroadcastsLocked(); 13500 } 13501 registeredReceivers = null; 13502 NR = 0; 13503 } 13504 13505 // Merge into one list. 13506 int ir = 0; 13507 if (receivers != null) { 13508 // A special case for PACKAGE_ADDED: do not allow the package 13509 // being added to see this broadcast. This prevents them from 13510 // using this as a back door to get run as soon as they are 13511 // installed. Maybe in the future we want to have a special install 13512 // broadcast or such for apps, but we'd like to deliberately make 13513 // this decision. 13514 String skipPackages[] = null; 13515 if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction()) 13516 || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction()) 13517 || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) { 13518 Uri data = intent.getData(); 13519 if (data != null) { 13520 String pkgName = data.getSchemeSpecificPart(); 13521 if (pkgName != null) { 13522 skipPackages = new String[] { pkgName }; 13523 } 13524 } 13525 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) { 13526 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 13527 } 13528 if (skipPackages != null && (skipPackages.length > 0)) { 13529 for (String skipPackage : skipPackages) { 13530 if (skipPackage != null) { 13531 int NT = receivers.size(); 13532 for (int it=0; it<NT; it++) { 13533 ResolveInfo curt = (ResolveInfo)receivers.get(it); 13534 if (curt.activityInfo.packageName.equals(skipPackage)) { 13535 receivers.remove(it); 13536 it--; 13537 NT--; 13538 } 13539 } 13540 } 13541 } 13542 } 13543 13544 int NT = receivers != null ? receivers.size() : 0; 13545 int it = 0; 13546 ResolveInfo curt = null; 13547 BroadcastFilter curr = null; 13548 while (it < NT && ir < NR) { 13549 if (curt == null) { 13550 curt = (ResolveInfo)receivers.get(it); 13551 } 13552 if (curr == null) { 13553 curr = registeredReceivers.get(ir); 13554 } 13555 if (curr.getPriority() >= curt.priority) { 13556 // Insert this broadcast record into the final list. 13557 receivers.add(it, curr); 13558 ir++; 13559 curr = null; 13560 it++; 13561 NT++; 13562 } else { 13563 // Skip to the next ResolveInfo in the final list. 13564 it++; 13565 curt = null; 13566 } 13567 } 13568 } 13569 while (ir < NR) { 13570 if (receivers == null) { 13571 receivers = new ArrayList(); 13572 } 13573 receivers.add(registeredReceivers.get(ir)); 13574 ir++; 13575 } 13576 13577 if ((receivers != null && receivers.size() > 0) 13578 || resultTo != null) { 13579 BroadcastQueue queue = broadcastQueueForIntent(intent); 13580 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 13581 callerPackage, callingPid, callingUid, resolvedType, 13582 requiredPermission, appOp, receivers, resultTo, resultCode, 13583 resultData, map, ordered, sticky, false, userId); 13584 if (DEBUG_BROADCAST) Slog.v( 13585 TAG, "Enqueueing ordered broadcast " + r 13586 + ": prev had " + queue.mOrderedBroadcasts.size()); 13587 if (DEBUG_BROADCAST) { 13588 int seq = r.intent.getIntExtra("seq", -1); 13589 Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq); 13590 } 13591 boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r); 13592 if (!replaced) { 13593 queue.enqueueOrderedBroadcastLocked(r); 13594 queue.scheduleBroadcastsLocked(); 13595 } 13596 } 13597 13598 return ActivityManager.BROADCAST_SUCCESS; 13599 } 13600 13601 final Intent verifyBroadcastLocked(Intent intent) { 13602 // Refuse possible leaked file descriptors 13603 if (intent != null && intent.hasFileDescriptors() == true) { 13604 throw new IllegalArgumentException("File descriptors passed in Intent"); 13605 } 13606 13607 int flags = intent.getFlags(); 13608 13609 if (!mProcessesReady) { 13610 // if the caller really truly claims to know what they're doing, go 13611 // ahead and allow the broadcast without launching any receivers 13612 if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) { 13613 intent = new Intent(intent); 13614 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 13615 } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) { 13616 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent 13617 + " before boot completion"); 13618 throw new IllegalStateException("Cannot broadcast before boot completed"); 13619 } 13620 } 13621 13622 if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 13623 throw new IllegalArgumentException( 13624 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 13625 } 13626 13627 return intent; 13628 } 13629 13630 public final int broadcastIntent(IApplicationThread caller, 13631 Intent intent, String resolvedType, IIntentReceiver resultTo, 13632 int resultCode, String resultData, Bundle map, 13633 String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) { 13634 enforceNotIsolatedCaller("broadcastIntent"); 13635 synchronized(this) { 13636 intent = verifyBroadcastLocked(intent); 13637 13638 final ProcessRecord callerApp = getRecordForAppLocked(caller); 13639 final int callingPid = Binder.getCallingPid(); 13640 final int callingUid = Binder.getCallingUid(); 13641 final long origId = Binder.clearCallingIdentity(); 13642 int res = broadcastIntentLocked(callerApp, 13643 callerApp != null ? callerApp.info.packageName : null, 13644 intent, resolvedType, resultTo, 13645 resultCode, resultData, map, requiredPermission, appOp, serialized, sticky, 13646 callingPid, callingUid, userId); 13647 Binder.restoreCallingIdentity(origId); 13648 return res; 13649 } 13650 } 13651 13652 int broadcastIntentInPackage(String packageName, int uid, 13653 Intent intent, String resolvedType, IIntentReceiver resultTo, 13654 int resultCode, String resultData, Bundle map, 13655 String requiredPermission, boolean serialized, boolean sticky, int userId) { 13656 synchronized(this) { 13657 intent = verifyBroadcastLocked(intent); 13658 13659 final long origId = Binder.clearCallingIdentity(); 13660 int res = broadcastIntentLocked(null, packageName, intent, resolvedType, 13661 resultTo, resultCode, resultData, map, requiredPermission, 13662 AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId); 13663 Binder.restoreCallingIdentity(origId); 13664 return res; 13665 } 13666 } 13667 13668 public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) { 13669 // Refuse possible leaked file descriptors 13670 if (intent != null && intent.hasFileDescriptors() == true) { 13671 throw new IllegalArgumentException("File descriptors passed in Intent"); 13672 } 13673 13674 userId = handleIncomingUser(Binder.getCallingPid(), 13675 Binder.getCallingUid(), userId, true, false, "removeStickyBroadcast", null); 13676 13677 synchronized(this) { 13678 if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY) 13679 != PackageManager.PERMISSION_GRANTED) { 13680 String msg = "Permission Denial: unbroadcastIntent() from pid=" 13681 + Binder.getCallingPid() 13682 + ", uid=" + Binder.getCallingUid() 13683 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 13684 Slog.w(TAG, msg); 13685 throw new SecurityException(msg); 13686 } 13687 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 13688 if (stickies != null) { 13689 ArrayList<Intent> list = stickies.get(intent.getAction()); 13690 if (list != null) { 13691 int N = list.size(); 13692 int i; 13693 for (i=0; i<N; i++) { 13694 if (intent.filterEquals(list.get(i))) { 13695 list.remove(i); 13696 break; 13697 } 13698 } 13699 if (list.size() <= 0) { 13700 stickies.remove(intent.getAction()); 13701 } 13702 } 13703 if (stickies.size() <= 0) { 13704 mStickyBroadcasts.remove(userId); 13705 } 13706 } 13707 } 13708 } 13709 13710 private final boolean finishReceiverLocked(IBinder receiver, int resultCode, 13711 String resultData, Bundle resultExtras, boolean resultAbort) { 13712 final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver); 13713 if (r == null) { 13714 Slog.w(TAG, "finishReceiver called but not found on queue"); 13715 return false; 13716 } 13717 13718 return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false); 13719 } 13720 13721 void backgroundServicesFinishedLocked(int userId) { 13722 for (BroadcastQueue queue : mBroadcastQueues) { 13723 queue.backgroundServicesFinishedLocked(userId); 13724 } 13725 } 13726 13727 public void finishReceiver(IBinder who, int resultCode, String resultData, 13728 Bundle resultExtras, boolean resultAbort) { 13729 if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who); 13730 13731 // Refuse possible leaked file descriptors 13732 if (resultExtras != null && resultExtras.hasFileDescriptors()) { 13733 throw new IllegalArgumentException("File descriptors passed in Bundle"); 13734 } 13735 13736 final long origId = Binder.clearCallingIdentity(); 13737 try { 13738 boolean doNext = false; 13739 BroadcastRecord r; 13740 13741 synchronized(this) { 13742 r = broadcastRecordForReceiverLocked(who); 13743 if (r != null) { 13744 doNext = r.queue.finishReceiverLocked(r, resultCode, 13745 resultData, resultExtras, resultAbort, true); 13746 } 13747 } 13748 13749 if (doNext) { 13750 r.queue.processNextBroadcast(false); 13751 } 13752 trimApplications(); 13753 } finally { 13754 Binder.restoreCallingIdentity(origId); 13755 } 13756 } 13757 13758 // ========================================================= 13759 // INSTRUMENTATION 13760 // ========================================================= 13761 13762 public boolean startInstrumentation(ComponentName className, 13763 String profileFile, int flags, Bundle arguments, 13764 IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection, 13765 int userId) { 13766 enforceNotIsolatedCaller("startInstrumentation"); 13767 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 13768 userId, false, true, "startInstrumentation", null); 13769 // Refuse possible leaked file descriptors 13770 if (arguments != null && arguments.hasFileDescriptors()) { 13771 throw new IllegalArgumentException("File descriptors passed in Bundle"); 13772 } 13773 13774 synchronized(this) { 13775 InstrumentationInfo ii = null; 13776 ApplicationInfo ai = null; 13777 try { 13778 ii = mContext.getPackageManager().getInstrumentationInfo( 13779 className, STOCK_PM_FLAGS); 13780 ai = AppGlobals.getPackageManager().getApplicationInfo( 13781 ii.targetPackage, STOCK_PM_FLAGS, userId); 13782 } catch (PackageManager.NameNotFoundException e) { 13783 } catch (RemoteException e) { 13784 } 13785 if (ii == null) { 13786 reportStartInstrumentationFailure(watcher, className, 13787 "Unable to find instrumentation info for: " + className); 13788 return false; 13789 } 13790 if (ai == null) { 13791 reportStartInstrumentationFailure(watcher, className, 13792 "Unable to find instrumentation target package: " + ii.targetPackage); 13793 return false; 13794 } 13795 13796 int match = mContext.getPackageManager().checkSignatures( 13797 ii.targetPackage, ii.packageName); 13798 if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) { 13799 String msg = "Permission Denial: starting instrumentation " 13800 + className + " from pid=" 13801 + Binder.getCallingPid() 13802 + ", uid=" + Binder.getCallingPid() 13803 + " not allowed because package " + ii.packageName 13804 + " does not have a signature matching the target " 13805 + ii.targetPackage; 13806 reportStartInstrumentationFailure(watcher, className, msg); 13807 throw new SecurityException(msg); 13808 } 13809 13810 final long origId = Binder.clearCallingIdentity(); 13811 // Instrumentation can kill and relaunch even persistent processes 13812 forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, userId, 13813 "start instr"); 13814 ProcessRecord app = addAppLocked(ai, false); 13815 app.instrumentationClass = className; 13816 app.instrumentationInfo = ai; 13817 app.instrumentationProfileFile = profileFile; 13818 app.instrumentationArguments = arguments; 13819 app.instrumentationWatcher = watcher; 13820 app.instrumentationUiAutomationConnection = uiAutomationConnection; 13821 app.instrumentationResultClass = className; 13822 Binder.restoreCallingIdentity(origId); 13823 } 13824 13825 return true; 13826 } 13827 13828 /** 13829 * Report errors that occur while attempting to start Instrumentation. Always writes the 13830 * error to the logs, but if somebody is watching, send the report there too. This enables 13831 * the "am" command to report errors with more information. 13832 * 13833 * @param watcher The IInstrumentationWatcher. Null if there isn't one. 13834 * @param cn The component name of the instrumentation. 13835 * @param report The error report. 13836 */ 13837 private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher, 13838 ComponentName cn, String report) { 13839 Slog.w(TAG, report); 13840 try { 13841 if (watcher != null) { 13842 Bundle results = new Bundle(); 13843 results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService"); 13844 results.putString("Error", report); 13845 watcher.instrumentationStatus(cn, -1, results); 13846 } 13847 } catch (RemoteException e) { 13848 Slog.w(TAG, e); 13849 } 13850 } 13851 13852 void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) { 13853 if (app.instrumentationWatcher != null) { 13854 try { 13855 // NOTE: IInstrumentationWatcher *must* be oneway here 13856 app.instrumentationWatcher.instrumentationFinished( 13857 app.instrumentationClass, 13858 resultCode, 13859 results); 13860 } catch (RemoteException e) { 13861 } 13862 } 13863 if (app.instrumentationUiAutomationConnection != null) { 13864 try { 13865 app.instrumentationUiAutomationConnection.shutdown(); 13866 } catch (RemoteException re) { 13867 /* ignore */ 13868 } 13869 // Only a UiAutomation can set this flag and now that 13870 // it is finished we make sure it is reset to its default. 13871 mUserIsMonkey = false; 13872 } 13873 app.instrumentationWatcher = null; 13874 app.instrumentationUiAutomationConnection = null; 13875 app.instrumentationClass = null; 13876 app.instrumentationInfo = null; 13877 app.instrumentationProfileFile = null; 13878 app.instrumentationArguments = null; 13879 13880 forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, app.userId, 13881 "finished inst"); 13882 } 13883 13884 public void finishInstrumentation(IApplicationThread target, 13885 int resultCode, Bundle results) { 13886 int userId = UserHandle.getCallingUserId(); 13887 // Refuse possible leaked file descriptors 13888 if (results != null && results.hasFileDescriptors()) { 13889 throw new IllegalArgumentException("File descriptors passed in Intent"); 13890 } 13891 13892 synchronized(this) { 13893 ProcessRecord app = getRecordForAppLocked(target); 13894 if (app == null) { 13895 Slog.w(TAG, "finishInstrumentation: no app for " + target); 13896 return; 13897 } 13898 final long origId = Binder.clearCallingIdentity(); 13899 finishInstrumentationLocked(app, resultCode, results); 13900 Binder.restoreCallingIdentity(origId); 13901 } 13902 } 13903 13904 // ========================================================= 13905 // CONFIGURATION 13906 // ========================================================= 13907 13908 public ConfigurationInfo getDeviceConfigurationInfo() { 13909 ConfigurationInfo config = new ConfigurationInfo(); 13910 synchronized (this) { 13911 config.reqTouchScreen = mConfiguration.touchscreen; 13912 config.reqKeyboardType = mConfiguration.keyboard; 13913 config.reqNavigation = mConfiguration.navigation; 13914 if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD 13915 || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) { 13916 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV; 13917 } 13918 if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED 13919 && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) { 13920 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD; 13921 } 13922 config.reqGlEsVersion = GL_ES_VERSION; 13923 } 13924 return config; 13925 } 13926 13927 ActivityStack getFocusedStack() { 13928 return mStackSupervisor.getFocusedStack(); 13929 } 13930 13931 public Configuration getConfiguration() { 13932 Configuration ci; 13933 synchronized(this) { 13934 ci = new Configuration(mConfiguration); 13935 } 13936 return ci; 13937 } 13938 13939 public void updatePersistentConfiguration(Configuration values) { 13940 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 13941 "updateConfiguration()"); 13942 enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS, 13943 "updateConfiguration()"); 13944 if (values == null) { 13945 throw new NullPointerException("Configuration must not be null"); 13946 } 13947 13948 synchronized(this) { 13949 final long origId = Binder.clearCallingIdentity(); 13950 updateConfigurationLocked(values, null, true, false); 13951 Binder.restoreCallingIdentity(origId); 13952 } 13953 } 13954 13955 public void updateConfiguration(Configuration values) { 13956 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 13957 "updateConfiguration()"); 13958 13959 synchronized(this) { 13960 if (values == null && mWindowManager != null) { 13961 // sentinel: fetch the current configuration from the window manager 13962 values = mWindowManager.computeNewConfiguration(); 13963 } 13964 13965 if (mWindowManager != null) { 13966 mProcessList.applyDisplaySize(mWindowManager); 13967 } 13968 13969 final long origId = Binder.clearCallingIdentity(); 13970 if (values != null) { 13971 Settings.System.clearConfiguration(values); 13972 } 13973 updateConfigurationLocked(values, null, false, false); 13974 Binder.restoreCallingIdentity(origId); 13975 } 13976 } 13977 13978 /** 13979 * Do either or both things: (1) change the current configuration, and (2) 13980 * make sure the given activity is running with the (now) current 13981 * configuration. Returns true if the activity has been left running, or 13982 * false if <var>starting</var> is being destroyed to match the new 13983 * configuration. 13984 * @param persistent TODO 13985 */ 13986 boolean updateConfigurationLocked(Configuration values, 13987 ActivityRecord starting, boolean persistent, boolean initLocale) { 13988 int changes = 0; 13989 13990 if (values != null) { 13991 Configuration newConfig = new Configuration(mConfiguration); 13992 changes = newConfig.updateFrom(values); 13993 if (changes != 0) { 13994 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) { 13995 Slog.i(TAG, "Updating configuration to: " + values); 13996 } 13997 13998 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes); 13999 14000 if (values.locale != null && !initLocale) { 14001 saveLocaleLocked(values.locale, 14002 !values.locale.equals(mConfiguration.locale), 14003 values.userSetLocale); 14004 } 14005 14006 mConfigurationSeq++; 14007 if (mConfigurationSeq <= 0) { 14008 mConfigurationSeq = 1; 14009 } 14010 newConfig.seq = mConfigurationSeq; 14011 mConfiguration = newConfig; 14012 Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig); 14013 14014 final Configuration configCopy = new Configuration(mConfiguration); 14015 14016 // TODO: If our config changes, should we auto dismiss any currently 14017 // showing dialogs? 14018 mShowDialogs = shouldShowDialogs(newConfig); 14019 14020 AttributeCache ac = AttributeCache.instance(); 14021 if (ac != null) { 14022 ac.updateConfiguration(configCopy); 14023 } 14024 14025 // Make sure all resources in our process are updated 14026 // right now, so that anyone who is going to retrieve 14027 // resource values after we return will be sure to get 14028 // the new ones. This is especially important during 14029 // boot, where the first config change needs to guarantee 14030 // all resources have that config before following boot 14031 // code is executed. 14032 mSystemThread.applyConfigurationToResources(configCopy); 14033 14034 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) { 14035 Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG); 14036 msg.obj = new Configuration(configCopy); 14037 mHandler.sendMessage(msg); 14038 } 14039 14040 for (int i=mLruProcesses.size()-1; i>=0; i--) { 14041 ProcessRecord app = mLruProcesses.get(i); 14042 try { 14043 if (app.thread != null) { 14044 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc " 14045 + app.processName + " new config " + mConfiguration); 14046 app.thread.scheduleConfigurationChanged(configCopy); 14047 } 14048 } catch (Exception e) { 14049 } 14050 } 14051 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED); 14052 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 14053 | Intent.FLAG_RECEIVER_REPLACE_PENDING 14054 | Intent.FLAG_RECEIVER_FOREGROUND); 14055 broadcastIntentLocked(null, null, intent, null, null, 0, null, null, 14056 null, AppOpsManager.OP_NONE, false, false, MY_PID, 14057 Process.SYSTEM_UID, UserHandle.USER_ALL); 14058 if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) { 14059 intent = new Intent(Intent.ACTION_LOCALE_CHANGED); 14060 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 14061 broadcastIntentLocked(null, null, intent, 14062 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 14063 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 14064 } 14065 } 14066 } 14067 14068 boolean kept = true; 14069 final ActivityStack mainStack = mStackSupervisor.getFocusedStack(); 14070 // mainStack is null during startup. 14071 if (mainStack != null) { 14072 if (changes != 0 && starting == null) { 14073 // If the configuration changed, and the caller is not already 14074 // in the process of starting an activity, then find the top 14075 // activity to check if its configuration needs to change. 14076 starting = mainStack.topRunningActivityLocked(null); 14077 } 14078 14079 if (starting != null) { 14080 kept = mainStack.ensureActivityConfigurationLocked(starting, changes); 14081 // And we need to make sure at this point that all other activities 14082 // are made visible with the correct configuration. 14083 mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes); 14084 } 14085 } 14086 14087 if (values != null && mWindowManager != null) { 14088 mWindowManager.setNewConfiguration(mConfiguration); 14089 } 14090 14091 return kept; 14092 } 14093 14094 /** 14095 * Decide based on the configuration whether we should shouw the ANR, 14096 * crash, etc dialogs. The idea is that if there is no affordnace to 14097 * press the on-screen buttons, we shouldn't show the dialog. 14098 * 14099 * A thought: SystemUI might also want to get told about this, the Power 14100 * dialog / global actions also might want different behaviors. 14101 */ 14102 private static final boolean shouldShowDialogs(Configuration config) { 14103 return !(config.keyboard == Configuration.KEYBOARD_NOKEYS 14104 && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH); 14105 } 14106 14107 /** 14108 * Save the locale. You must be inside a synchronized (this) block. 14109 */ 14110 private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) { 14111 if(isDiff) { 14112 SystemProperties.set("user.language", l.getLanguage()); 14113 SystemProperties.set("user.region", l.getCountry()); 14114 } 14115 14116 if(isPersist) { 14117 SystemProperties.set("persist.sys.language", l.getLanguage()); 14118 SystemProperties.set("persist.sys.country", l.getCountry()); 14119 SystemProperties.set("persist.sys.localevar", l.getVariant()); 14120 } 14121 } 14122 14123 @Override 14124 public boolean targetTaskAffinityMatchesActivity(IBinder token, String destAffinity) { 14125 ActivityRecord srec = ActivityRecord.forToken(token); 14126 return srec != null && srec.task.affinity != null && 14127 srec.task.affinity.equals(destAffinity); 14128 } 14129 14130 public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode, 14131 Intent resultData) { 14132 14133 synchronized (this) { 14134 final ActivityStack stack = ActivityRecord.getStackLocked(token); 14135 if (stack != null) { 14136 return stack.navigateUpToLocked(token, destIntent, resultCode, resultData); 14137 } 14138 return false; 14139 } 14140 } 14141 14142 public int getLaunchedFromUid(IBinder activityToken) { 14143 ActivityRecord srec = ActivityRecord.forToken(activityToken); 14144 if (srec == null) { 14145 return -1; 14146 } 14147 return srec.launchedFromUid; 14148 } 14149 14150 public String getLaunchedFromPackage(IBinder activityToken) { 14151 ActivityRecord srec = ActivityRecord.forToken(activityToken); 14152 if (srec == null) { 14153 return null; 14154 } 14155 return srec.launchedFromPackage; 14156 } 14157 14158 // ========================================================= 14159 // LIFETIME MANAGEMENT 14160 // ========================================================= 14161 14162 // Returns which broadcast queue the app is the current [or imminent] receiver 14163 // on, or 'null' if the app is not an active broadcast recipient. 14164 private BroadcastQueue isReceivingBroadcast(ProcessRecord app) { 14165 BroadcastRecord r = app.curReceiver; 14166 if (r != null) { 14167 return r.queue; 14168 } 14169 14170 // It's not the current receiver, but it might be starting up to become one 14171 synchronized (this) { 14172 for (BroadcastQueue queue : mBroadcastQueues) { 14173 r = queue.mPendingBroadcast; 14174 if (r != null && r.curApp == app) { 14175 // found it; report which queue it's in 14176 return queue; 14177 } 14178 } 14179 } 14180 14181 return null; 14182 } 14183 14184 private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP, 14185 boolean doingAll, long now) { 14186 if (mAdjSeq == app.adjSeq) { 14187 // This adjustment has already been computed. 14188 return app.curRawAdj; 14189 } 14190 14191 if (app.thread == null) { 14192 app.adjSeq = mAdjSeq; 14193 app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 14194 app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 14195 return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ); 14196 } 14197 14198 app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN; 14199 app.adjSource = null; 14200 app.adjTarget = null; 14201 app.empty = false; 14202 app.cached = false; 14203 14204 final int activitiesSize = app.activities.size(); 14205 14206 if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) { 14207 // The max adjustment doesn't allow this app to be anything 14208 // below foreground, so it is not worth doing work for it. 14209 app.adjType = "fixed"; 14210 app.adjSeq = mAdjSeq; 14211 app.curRawAdj = app.maxAdj; 14212 app.foregroundActivities = false; 14213 app.keeping = true; 14214 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT; 14215 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT; 14216 // System process can do UI, and when they do we want to have 14217 // them trim their memory after the user leaves the UI. To 14218 // facilitate this, here we need to determine whether or not it 14219 // is currently showing UI. 14220 app.systemNoUi = true; 14221 if (app == TOP_APP) { 14222 app.systemNoUi = false; 14223 } else if (activitiesSize > 0) { 14224 for (int j = 0; j < activitiesSize; j++) { 14225 final ActivityRecord r = app.activities.get(j); 14226 if (r.visible) { 14227 app.systemNoUi = false; 14228 } 14229 } 14230 } 14231 if (!app.systemNoUi) { 14232 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI; 14233 } 14234 return (app.curAdj=app.maxAdj); 14235 } 14236 14237 app.keeping = false; 14238 app.systemNoUi = false; 14239 14240 // Determine the importance of the process, starting with most 14241 // important to least, and assign an appropriate OOM adjustment. 14242 int adj; 14243 int schedGroup; 14244 int procState; 14245 boolean foregroundActivities = false; 14246 boolean interesting = false; 14247 BroadcastQueue queue; 14248 if (app == TOP_APP) { 14249 // The last app on the list is the foreground app. 14250 adj = ProcessList.FOREGROUND_APP_ADJ; 14251 schedGroup = Process.THREAD_GROUP_DEFAULT; 14252 app.adjType = "top-activity"; 14253 foregroundActivities = true; 14254 interesting = true; 14255 procState = ActivityManager.PROCESS_STATE_TOP; 14256 } else if (app.instrumentationClass != null) { 14257 // Don't want to kill running instrumentation. 14258 adj = ProcessList.FOREGROUND_APP_ADJ; 14259 schedGroup = Process.THREAD_GROUP_DEFAULT; 14260 app.adjType = "instrumentation"; 14261 interesting = true; 14262 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14263 } else if ((queue = isReceivingBroadcast(app)) != null) { 14264 // An app that is currently receiving a broadcast also 14265 // counts as being in the foreground for OOM killer purposes. 14266 // It's placed in a sched group based on the nature of the 14267 // broadcast as reflected by which queue it's active in. 14268 adj = ProcessList.FOREGROUND_APP_ADJ; 14269 schedGroup = (queue == mFgBroadcastQueue) 14270 ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 14271 app.adjType = "broadcast"; 14272 procState = ActivityManager.PROCESS_STATE_RECEIVER; 14273 } else if (app.executingServices.size() > 0) { 14274 // An app that is currently executing a service callback also 14275 // counts as being in the foreground. 14276 adj = ProcessList.FOREGROUND_APP_ADJ; 14277 schedGroup = app.execServicesFg ? 14278 Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 14279 app.adjType = "exec-service"; 14280 procState = ActivityManager.PROCESS_STATE_SERVICE; 14281 //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app); 14282 } else { 14283 // As far as we know the process is empty. We may change our mind later. 14284 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 14285 // At this point we don't actually know the adjustment. Use the cached adj 14286 // value that the caller wants us to. 14287 adj = cachedAdj; 14288 procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 14289 app.cached = true; 14290 app.empty = true; 14291 app.adjType = "cch-empty"; 14292 } 14293 14294 // Examine all activities if not already foreground. 14295 if (!foregroundActivities && activitiesSize > 0) { 14296 for (int j = 0; j < activitiesSize; j++) { 14297 final ActivityRecord r = app.activities.get(j); 14298 if (r.app != app) { 14299 Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc " 14300 + app + "?!?"); 14301 continue; 14302 } 14303 if (r.visible) { 14304 // App has a visible activity; only upgrade adjustment. 14305 if (adj > ProcessList.VISIBLE_APP_ADJ) { 14306 adj = ProcessList.VISIBLE_APP_ADJ; 14307 app.adjType = "visible"; 14308 } 14309 if (procState > ActivityManager.PROCESS_STATE_TOP) { 14310 procState = ActivityManager.PROCESS_STATE_TOP; 14311 } 14312 schedGroup = Process.THREAD_GROUP_DEFAULT; 14313 app.cached = false; 14314 app.empty = false; 14315 foregroundActivities = true; 14316 break; 14317 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) { 14318 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14319 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 14320 app.adjType = "pausing"; 14321 } 14322 if (procState > ActivityManager.PROCESS_STATE_TOP) { 14323 procState = ActivityManager.PROCESS_STATE_TOP; 14324 } 14325 schedGroup = Process.THREAD_GROUP_DEFAULT; 14326 app.cached = false; 14327 app.empty = false; 14328 foregroundActivities = true; 14329 } else if (r.state == ActivityState.STOPPING) { 14330 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14331 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 14332 app.adjType = "stopping"; 14333 } 14334 // For the process state, we will at this point consider the 14335 // process to be cached. It will be cached either as an activity 14336 // or empty depending on whether the activity is finishing. We do 14337 // this so that we can treat the process as cached for purposes of 14338 // memory trimming (determing current memory level, trim command to 14339 // send to process) since there can be an arbitrary number of stopping 14340 // processes and they should soon all go into the cached state. 14341 if (!r.finishing) { 14342 if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 14343 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 14344 } 14345 } 14346 app.cached = false; 14347 app.empty = false; 14348 foregroundActivities = true; 14349 } else { 14350 if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 14351 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 14352 app.adjType = "cch-act"; 14353 } 14354 } 14355 } 14356 } 14357 14358 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14359 if (app.foregroundServices) { 14360 // The user is aware of this app, so make it visible. 14361 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 14362 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14363 app.cached = false; 14364 app.adjType = "fg-service"; 14365 schedGroup = Process.THREAD_GROUP_DEFAULT; 14366 } else if (app.forcingToForeground != null) { 14367 // The user is aware of this app, so make it visible. 14368 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 14369 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14370 app.cached = false; 14371 app.adjType = "force-fg"; 14372 app.adjSource = app.forcingToForeground; 14373 schedGroup = Process.THREAD_GROUP_DEFAULT; 14374 } 14375 } 14376 14377 if (app.foregroundServices) { 14378 interesting = true; 14379 } 14380 14381 if (app == mHeavyWeightProcess) { 14382 if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) { 14383 // We don't want to kill the current heavy-weight process. 14384 adj = ProcessList.HEAVY_WEIGHT_APP_ADJ; 14385 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 14386 app.cached = false; 14387 app.adjType = "heavy"; 14388 } 14389 if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) { 14390 procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT; 14391 } 14392 } 14393 14394 if (app == mHomeProcess) { 14395 if (adj > ProcessList.HOME_APP_ADJ) { 14396 // This process is hosting what we currently consider to be the 14397 // home app, so we don't want to let it go into the background. 14398 adj = ProcessList.HOME_APP_ADJ; 14399 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 14400 app.cached = false; 14401 app.adjType = "home"; 14402 } 14403 if (procState > ActivityManager.PROCESS_STATE_HOME) { 14404 procState = ActivityManager.PROCESS_STATE_HOME; 14405 } 14406 } 14407 14408 if (app == mPreviousProcess && app.activities.size() > 0) { 14409 if (adj > ProcessList.PREVIOUS_APP_ADJ) { 14410 // This was the previous process that showed UI to the user. 14411 // We want to try to keep it around more aggressively, to give 14412 // a good experience around switching between two apps. 14413 adj = ProcessList.PREVIOUS_APP_ADJ; 14414 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 14415 app.cached = false; 14416 app.adjType = "previous"; 14417 } 14418 if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) { 14419 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY; 14420 } 14421 } 14422 14423 if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj 14424 + " reason=" + app.adjType); 14425 14426 // By default, we use the computed adjustment. It may be changed if 14427 // there are applications dependent on our services or providers, but 14428 // this gives us a baseline and makes sure we don't get into an 14429 // infinite recursion. 14430 app.adjSeq = mAdjSeq; 14431 app.curRawAdj = adj; 14432 app.hasStartedServices = false; 14433 14434 if (mBackupTarget != null && app == mBackupTarget.app) { 14435 // If possible we want to avoid killing apps while they're being backed up 14436 if (adj > ProcessList.BACKUP_APP_ADJ) { 14437 if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app); 14438 adj = ProcessList.BACKUP_APP_ADJ; 14439 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) { 14440 procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND; 14441 } 14442 app.adjType = "backup"; 14443 app.cached = false; 14444 } 14445 if (procState > ActivityManager.PROCESS_STATE_BACKUP) { 14446 procState = ActivityManager.PROCESS_STATE_BACKUP; 14447 } 14448 } 14449 14450 boolean mayBeTop = false; 14451 14452 for (int is = app.services.size()-1; 14453 is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 14454 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 14455 || procState > ActivityManager.PROCESS_STATE_TOP); 14456 is--) { 14457 ServiceRecord s = app.services.valueAt(is); 14458 if (s.startRequested) { 14459 app.hasStartedServices = true; 14460 if (procState > ActivityManager.PROCESS_STATE_SERVICE) { 14461 procState = ActivityManager.PROCESS_STATE_SERVICE; 14462 } 14463 if (app.hasShownUi && app != mHomeProcess) { 14464 // If this process has shown some UI, let it immediately 14465 // go to the LRU list because it may be pretty heavy with 14466 // UI stuff. We'll tag it with a label just to help 14467 // debug and understand what is going on. 14468 if (adj > ProcessList.SERVICE_ADJ) { 14469 app.adjType = "cch-started-ui-services"; 14470 } 14471 } else { 14472 if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) { 14473 // This service has seen some activity within 14474 // recent memory, so we will keep its process ahead 14475 // of the background processes. 14476 if (adj > ProcessList.SERVICE_ADJ) { 14477 adj = ProcessList.SERVICE_ADJ; 14478 app.adjType = "started-services"; 14479 app.cached = false; 14480 } 14481 } 14482 // If we have let the service slide into the background 14483 // state, still have some text describing what it is doing 14484 // even though the service no longer has an impact. 14485 if (adj > ProcessList.SERVICE_ADJ) { 14486 app.adjType = "cch-started-services"; 14487 } 14488 } 14489 // Don't kill this process because it is doing work; it 14490 // has said it is doing work. 14491 app.keeping = true; 14492 } 14493 for (int conni = s.connections.size()-1; 14494 conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 14495 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 14496 || procState > ActivityManager.PROCESS_STATE_TOP); 14497 conni--) { 14498 ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni); 14499 for (int i = 0; 14500 i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ 14501 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 14502 || procState > ActivityManager.PROCESS_STATE_TOP); 14503 i++) { 14504 // XXX should compute this based on the max of 14505 // all connected clients. 14506 ConnectionRecord cr = clist.get(i); 14507 if (cr.binding.client == app) { 14508 // Binding to ourself is not interesting. 14509 continue; 14510 } 14511 if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) { 14512 ProcessRecord client = cr.binding.client; 14513 int clientAdj = computeOomAdjLocked(client, cachedAdj, 14514 TOP_APP, doingAll, now); 14515 int clientProcState = client.curProcState; 14516 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 14517 // If the other app is cached for any reason, for purposes here 14518 // we are going to consider it empty. The specific cached state 14519 // doesn't propagate except under certain conditions. 14520 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 14521 } 14522 String adjType = null; 14523 if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) { 14524 // Not doing bind OOM management, so treat 14525 // this guy more like a started service. 14526 if (app.hasShownUi && app != mHomeProcess) { 14527 // If this process has shown some UI, let it immediately 14528 // go to the LRU list because it may be pretty heavy with 14529 // UI stuff. We'll tag it with a label just to help 14530 // debug and understand what is going on. 14531 if (adj > clientAdj) { 14532 adjType = "cch-bound-ui-services"; 14533 } 14534 app.cached = false; 14535 clientAdj = adj; 14536 clientProcState = procState; 14537 } else { 14538 if (now >= (s.lastActivity 14539 + ActiveServices.MAX_SERVICE_INACTIVITY)) { 14540 // This service has not seen activity within 14541 // recent memory, so allow it to drop to the 14542 // LRU list if there is no other reason to keep 14543 // it around. We'll also tag it with a label just 14544 // to help debug and undertand what is going on. 14545 if (adj > clientAdj) { 14546 adjType = "cch-bound-services"; 14547 } 14548 clientAdj = adj; 14549 } 14550 } 14551 } 14552 if (adj > clientAdj) { 14553 // If this process has recently shown UI, and 14554 // the process that is binding to it is less 14555 // important than being visible, then we don't 14556 // care about the binding as much as we care 14557 // about letting this process get into the LRU 14558 // list to be killed and restarted if needed for 14559 // memory. 14560 if (app.hasShownUi && app != mHomeProcess 14561 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14562 adjType = "cch-bound-ui-services"; 14563 } else { 14564 if ((cr.flags&(Context.BIND_ABOVE_CLIENT 14565 |Context.BIND_IMPORTANT)) != 0) { 14566 adj = clientAdj; 14567 } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0 14568 && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ 14569 && adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14570 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 14571 } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) { 14572 adj = clientAdj; 14573 } else { 14574 if (adj > ProcessList.VISIBLE_APP_ADJ) { 14575 adj = ProcessList.VISIBLE_APP_ADJ; 14576 } 14577 } 14578 if (!client.cached) { 14579 app.cached = false; 14580 } 14581 if (client.keeping) { 14582 app.keeping = true; 14583 } 14584 adjType = "service"; 14585 } 14586 } 14587 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 14588 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 14589 schedGroup = Process.THREAD_GROUP_DEFAULT; 14590 } 14591 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) { 14592 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) { 14593 // Special handling of clients who are in the top state. 14594 // We *may* want to consider this process to be in the 14595 // top state as well, but only if there is not another 14596 // reason for it to be running. Being on the top is a 14597 // special state, meaning you are specifically running 14598 // for the current top app. If the process is already 14599 // running in the background for some other reason, it 14600 // is more important to continue considering it to be 14601 // in the background state. 14602 mayBeTop = true; 14603 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 14604 } else { 14605 // Special handling for above-top states (persistent 14606 // processes). These should not bring the current process 14607 // into the top state, since they are not on top. Instead 14608 // give them the best state after that. 14609 clientProcState = 14610 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14611 } 14612 } 14613 } else { 14614 if (clientProcState < 14615 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) { 14616 clientProcState = 14617 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND; 14618 } 14619 } 14620 if (procState > clientProcState) { 14621 procState = clientProcState; 14622 } 14623 if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 14624 && (cr.flags&Context.BIND_SHOWING_UI) != 0) { 14625 app.pendingUiClean = true; 14626 } 14627 if (adjType != null) { 14628 app.adjType = adjType; 14629 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 14630 .REASON_SERVICE_IN_USE; 14631 app.adjSource = cr.binding.client; 14632 app.adjSourceOom = clientAdj; 14633 app.adjTarget = s.name; 14634 } 14635 } 14636 final ActivityRecord a = cr.activity; 14637 if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) { 14638 if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ && 14639 (a.visible || a.state == ActivityState.RESUMED 14640 || a.state == ActivityState.PAUSING)) { 14641 adj = ProcessList.FOREGROUND_APP_ADJ; 14642 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 14643 schedGroup = Process.THREAD_GROUP_DEFAULT; 14644 } 14645 app.cached = false; 14646 app.adjType = "service"; 14647 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 14648 .REASON_SERVICE_IN_USE; 14649 app.adjSource = a; 14650 app.adjSourceOom = adj; 14651 app.adjTarget = s.name; 14652 } 14653 } 14654 } 14655 } 14656 } 14657 14658 for (int provi = app.pubProviders.size()-1; 14659 provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 14660 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 14661 || procState > ActivityManager.PROCESS_STATE_TOP); 14662 provi--) { 14663 ContentProviderRecord cpr = app.pubProviders.valueAt(provi); 14664 for (int i = cpr.connections.size()-1; 14665 i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 14666 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 14667 || procState > ActivityManager.PROCESS_STATE_TOP); 14668 i--) { 14669 ContentProviderConnection conn = cpr.connections.get(i); 14670 ProcessRecord client = conn.client; 14671 if (client == app) { 14672 // Being our own client is not interesting. 14673 continue; 14674 } 14675 int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now); 14676 int clientProcState = client.curProcState; 14677 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 14678 // If the other app is cached for any reason, for purposes here 14679 // we are going to consider it empty. 14680 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 14681 } 14682 if (adj > clientAdj) { 14683 if (app.hasShownUi && app != mHomeProcess 14684 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14685 app.adjType = "cch-ui-provider"; 14686 } else { 14687 adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ 14688 ? clientAdj : ProcessList.FOREGROUND_APP_ADJ; 14689 app.adjType = "provider"; 14690 } 14691 app.cached &= client.cached; 14692 app.keeping |= client.keeping; 14693 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 14694 .REASON_PROVIDER_IN_USE; 14695 app.adjSource = client; 14696 app.adjSourceOom = clientAdj; 14697 app.adjTarget = cpr.name; 14698 } 14699 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) { 14700 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) { 14701 // Special handling of clients who are in the top state. 14702 // We *may* want to consider this process to be in the 14703 // top state as well, but only if there is not another 14704 // reason for it to be running. Being on the top is a 14705 // special state, meaning you are specifically running 14706 // for the current top app. If the process is already 14707 // running in the background for some other reason, it 14708 // is more important to continue considering it to be 14709 // in the background state. 14710 mayBeTop = true; 14711 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 14712 } else { 14713 // Special handling for above-top states (persistent 14714 // processes). These should not bring the current process 14715 // into the top state, since they are not on top. Instead 14716 // give them the best state after that. 14717 clientProcState = 14718 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14719 } 14720 } 14721 if (procState > clientProcState) { 14722 procState = clientProcState; 14723 } 14724 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 14725 schedGroup = Process.THREAD_GROUP_DEFAULT; 14726 } 14727 } 14728 // If the provider has external (non-framework) process 14729 // dependencies, ensure that its adjustment is at least 14730 // FOREGROUND_APP_ADJ. 14731 if (cpr.hasExternalProcessHandles()) { 14732 if (adj > ProcessList.FOREGROUND_APP_ADJ) { 14733 adj = ProcessList.FOREGROUND_APP_ADJ; 14734 schedGroup = Process.THREAD_GROUP_DEFAULT; 14735 app.cached = false; 14736 app.keeping = true; 14737 app.adjType = "provider"; 14738 app.adjTarget = cpr.name; 14739 } 14740 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) { 14741 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14742 } 14743 } 14744 } 14745 14746 if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) { 14747 // A client of one of our services or providers is in the top state. We 14748 // *may* want to be in the top state, but not if we are already running in 14749 // the background for some other reason. For the decision here, we are going 14750 // to pick out a few specific states that we want to remain in when a client 14751 // is top (states that tend to be longer-term) and otherwise allow it to go 14752 // to the top state. 14753 switch (procState) { 14754 case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND: 14755 case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND: 14756 case ActivityManager.PROCESS_STATE_SERVICE: 14757 // These all are longer-term states, so pull them up to the top 14758 // of the background states, but not all the way to the top state. 14759 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14760 break; 14761 default: 14762 // Otherwise, top is a better choice, so take it. 14763 procState = ActivityManager.PROCESS_STATE_TOP; 14764 break; 14765 } 14766 } 14767 14768 if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY && app.hasClientActivities) { 14769 // This is a cached process, but with client activities. Mark it so. 14770 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT; 14771 app.adjType = "cch-client-act"; 14772 } 14773 14774 if (adj == ProcessList.SERVICE_ADJ) { 14775 if (doingAll) { 14776 app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3); 14777 mNewNumServiceProcs++; 14778 //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb); 14779 if (!app.serviceb) { 14780 // This service isn't far enough down on the LRU list to 14781 // normally be a B service, but if we are low on RAM and it 14782 // is large we want to force it down since we would prefer to 14783 // keep launcher over it. 14784 if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL 14785 && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) { 14786 app.serviceHighRam = true; 14787 app.serviceb = true; 14788 //Slog.i(TAG, "ADJ " + app + " high ram!"); 14789 } else { 14790 mNewNumAServiceProcs++; 14791 //Slog.i(TAG, "ADJ " + app + " not high ram!"); 14792 } 14793 } else { 14794 app.serviceHighRam = false; 14795 } 14796 } 14797 if (app.serviceb) { 14798 adj = ProcessList.SERVICE_B_ADJ; 14799 } 14800 } 14801 14802 app.curRawAdj = adj; 14803 14804 //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid + 14805 // " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj); 14806 if (adj > app.maxAdj) { 14807 adj = app.maxAdj; 14808 if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 14809 schedGroup = Process.THREAD_GROUP_DEFAULT; 14810 } 14811 } 14812 if (adj < ProcessList.CACHED_APP_MIN_ADJ) { 14813 app.keeping = true; 14814 } 14815 14816 // Do final modification to adj. Everything we do between here and applying 14817 // the final setAdj must be done in this function, because we will also use 14818 // it when computing the final cached adj later. Note that we don't need to 14819 // worry about this for max adj above, since max adj will always be used to 14820 // keep it out of the cached vaues. 14821 adj = app.modifyRawOomAdj(adj); 14822 14823 app.curProcState = procState; 14824 14825 int importance = app.memImportance; 14826 if (importance == 0 || adj != app.curAdj || schedGroup != app.curSchedGroup) { 14827 app.curAdj = adj; 14828 app.curSchedGroup = schedGroup; 14829 if (!interesting) { 14830 // For this reporting, if there is not something explicitly 14831 // interesting in this process then we will push it to the 14832 // background importance. 14833 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 14834 } else if (adj >= ProcessList.CACHED_APP_MIN_ADJ) { 14835 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 14836 } else if (adj >= ProcessList.SERVICE_B_ADJ) { 14837 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 14838 } else if (adj >= ProcessList.HOME_APP_ADJ) { 14839 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 14840 } else if (adj >= ProcessList.SERVICE_ADJ) { 14841 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 14842 } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 14843 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE; 14844 } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) { 14845 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE; 14846 } else if (adj >= ProcessList.VISIBLE_APP_ADJ) { 14847 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE; 14848 } else if (adj >= ProcessList.FOREGROUND_APP_ADJ) { 14849 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND; 14850 } else { 14851 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERSISTENT; 14852 } 14853 } 14854 14855 int changes = importance != app.memImportance ? ProcessChangeItem.CHANGE_IMPORTANCE : 0; 14856 if (foregroundActivities != app.foregroundActivities) { 14857 changes |= ProcessChangeItem.CHANGE_ACTIVITIES; 14858 } 14859 if (changes != 0) { 14860 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes); 14861 app.memImportance = importance; 14862 app.foregroundActivities = foregroundActivities; 14863 int i = mPendingProcessChanges.size()-1; 14864 ProcessChangeItem item = null; 14865 while (i >= 0) { 14866 item = mPendingProcessChanges.get(i); 14867 if (item.pid == app.pid) { 14868 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item); 14869 break; 14870 } 14871 i--; 14872 } 14873 if (i < 0) { 14874 // No existing item in pending changes; need a new one. 14875 final int NA = mAvailProcessChanges.size(); 14876 if (NA > 0) { 14877 item = mAvailProcessChanges.remove(NA-1); 14878 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item); 14879 } else { 14880 item = new ProcessChangeItem(); 14881 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item); 14882 } 14883 item.changes = 0; 14884 item.pid = app.pid; 14885 item.uid = app.info.uid; 14886 if (mPendingProcessChanges.size() == 0) { 14887 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, 14888 "*** Enqueueing dispatch processes changed!"); 14889 mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget(); 14890 } 14891 mPendingProcessChanges.add(item); 14892 } 14893 item.changes |= changes; 14894 item.importance = importance; 14895 item.foregroundActivities = foregroundActivities; 14896 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item " 14897 + Integer.toHexString(System.identityHashCode(item)) 14898 + " " + app.toShortString() + ": changes=" + item.changes 14899 + " importance=" + item.importance 14900 + " foreground=" + item.foregroundActivities 14901 + " type=" + app.adjType + " source=" + app.adjSource 14902 + " target=" + app.adjTarget); 14903 } 14904 14905 return app.curRawAdj; 14906 } 14907 14908 /** 14909 * Schedule PSS collection of a process. 14910 */ 14911 void requestPssLocked(ProcessRecord proc, int procState) { 14912 if (mPendingPssProcesses.contains(proc)) { 14913 return; 14914 } 14915 if (mPendingPssProcesses.size() == 0) { 14916 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG); 14917 } 14918 if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc); 14919 proc.pssProcState = procState; 14920 mPendingPssProcesses.add(proc); 14921 } 14922 14923 /** 14924 * Schedule PSS collection of all processes. 14925 */ 14926 void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) { 14927 if (!always) { 14928 if (now < (mLastFullPssTime + 14929 (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) { 14930 return; 14931 } 14932 } 14933 if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs! memLowered=" + memLowered); 14934 mLastFullPssTime = now; 14935 mPendingPssProcesses.ensureCapacity(mLruProcesses.size()); 14936 mPendingPssProcesses.clear(); 14937 for (int i=mLruProcesses.size()-1; i>=0; i--) { 14938 ProcessRecord app = mLruProcesses.get(i); 14939 if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) { 14940 app.pssProcState = app.setProcState; 14941 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true, 14942 mSleeping, now); 14943 mPendingPssProcesses.add(app); 14944 } 14945 } 14946 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG); 14947 } 14948 14949 /** 14950 * Ask a given process to GC right now. 14951 */ 14952 final void performAppGcLocked(ProcessRecord app) { 14953 try { 14954 app.lastRequestedGc = SystemClock.uptimeMillis(); 14955 if (app.thread != null) { 14956 if (app.reportLowMemory) { 14957 app.reportLowMemory = false; 14958 app.thread.scheduleLowMemory(); 14959 } else { 14960 app.thread.processInBackground(); 14961 } 14962 } 14963 } catch (Exception e) { 14964 // whatever. 14965 } 14966 } 14967 14968 /** 14969 * Returns true if things are idle enough to perform GCs. 14970 */ 14971 private final boolean canGcNowLocked() { 14972 boolean processingBroadcasts = false; 14973 for (BroadcastQueue q : mBroadcastQueues) { 14974 if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) { 14975 processingBroadcasts = true; 14976 } 14977 } 14978 return !processingBroadcasts 14979 && (mSleeping || mStackSupervisor.allResumedActivitiesIdle()); 14980 } 14981 14982 /** 14983 * Perform GCs on all processes that are waiting for it, but only 14984 * if things are idle. 14985 */ 14986 final void performAppGcsLocked() { 14987 final int N = mProcessesToGc.size(); 14988 if (N <= 0) { 14989 return; 14990 } 14991 if (canGcNowLocked()) { 14992 while (mProcessesToGc.size() > 0) { 14993 ProcessRecord proc = mProcessesToGc.remove(0); 14994 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) { 14995 if ((proc.lastRequestedGc+GC_MIN_INTERVAL) 14996 <= SystemClock.uptimeMillis()) { 14997 // To avoid spamming the system, we will GC processes one 14998 // at a time, waiting a few seconds between each. 14999 performAppGcLocked(proc); 15000 scheduleAppGcsLocked(); 15001 return; 15002 } else { 15003 // It hasn't been long enough since we last GCed this 15004 // process... put it in the list to wait for its time. 15005 addProcessToGcListLocked(proc); 15006 break; 15007 } 15008 } 15009 } 15010 15011 scheduleAppGcsLocked(); 15012 } 15013 } 15014 15015 /** 15016 * If all looks good, perform GCs on all processes waiting for them. 15017 */ 15018 final void performAppGcsIfAppropriateLocked() { 15019 if (canGcNowLocked()) { 15020 performAppGcsLocked(); 15021 return; 15022 } 15023 // Still not idle, wait some more. 15024 scheduleAppGcsLocked(); 15025 } 15026 15027 /** 15028 * Schedule the execution of all pending app GCs. 15029 */ 15030 final void scheduleAppGcsLocked() { 15031 mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG); 15032 15033 if (mProcessesToGc.size() > 0) { 15034 // Schedule a GC for the time to the next process. 15035 ProcessRecord proc = mProcessesToGc.get(0); 15036 Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG); 15037 15038 long when = proc.lastRequestedGc + GC_MIN_INTERVAL; 15039 long now = SystemClock.uptimeMillis(); 15040 if (when < (now+GC_TIMEOUT)) { 15041 when = now + GC_TIMEOUT; 15042 } 15043 mHandler.sendMessageAtTime(msg, when); 15044 } 15045 } 15046 15047 /** 15048 * Add a process to the array of processes waiting to be GCed. Keeps the 15049 * list in sorted order by the last GC time. The process can't already be 15050 * on the list. 15051 */ 15052 final void addProcessToGcListLocked(ProcessRecord proc) { 15053 boolean added = false; 15054 for (int i=mProcessesToGc.size()-1; i>=0; i--) { 15055 if (mProcessesToGc.get(i).lastRequestedGc < 15056 proc.lastRequestedGc) { 15057 added = true; 15058 mProcessesToGc.add(i+1, proc); 15059 break; 15060 } 15061 } 15062 if (!added) { 15063 mProcessesToGc.add(0, proc); 15064 } 15065 } 15066 15067 /** 15068 * Set up to ask a process to GC itself. This will either do it 15069 * immediately, or put it on the list of processes to gc the next 15070 * time things are idle. 15071 */ 15072 final void scheduleAppGcLocked(ProcessRecord app) { 15073 long now = SystemClock.uptimeMillis(); 15074 if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) { 15075 return; 15076 } 15077 if (!mProcessesToGc.contains(app)) { 15078 addProcessToGcListLocked(app); 15079 scheduleAppGcsLocked(); 15080 } 15081 } 15082 15083 final void checkExcessivePowerUsageLocked(boolean doKills) { 15084 updateCpuStatsNow(); 15085 15086 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 15087 boolean doWakeKills = doKills; 15088 boolean doCpuKills = doKills; 15089 if (mLastPowerCheckRealtime == 0) { 15090 doWakeKills = false; 15091 } 15092 if (mLastPowerCheckUptime == 0) { 15093 doCpuKills = false; 15094 } 15095 if (stats.isScreenOn()) { 15096 doWakeKills = false; 15097 } 15098 final long curRealtime = SystemClock.elapsedRealtime(); 15099 final long realtimeSince = curRealtime - mLastPowerCheckRealtime; 15100 final long curUptime = SystemClock.uptimeMillis(); 15101 final long uptimeSince = curUptime - mLastPowerCheckUptime; 15102 mLastPowerCheckRealtime = curRealtime; 15103 mLastPowerCheckUptime = curUptime; 15104 if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) { 15105 doWakeKills = false; 15106 } 15107 if (uptimeSince < CPU_MIN_CHECK_DURATION) { 15108 doCpuKills = false; 15109 } 15110 int i = mLruProcesses.size(); 15111 while (i > 0) { 15112 i--; 15113 ProcessRecord app = mLruProcesses.get(i); 15114 if (!app.keeping) { 15115 long wtime; 15116 synchronized (stats) { 15117 wtime = stats.getProcessWakeTime(app.info.uid, 15118 app.pid, curRealtime); 15119 } 15120 long wtimeUsed = wtime - app.lastWakeTime; 15121 long cputimeUsed = app.curCpuTime - app.lastCpuTime; 15122 if (DEBUG_POWER) { 15123 StringBuilder sb = new StringBuilder(128); 15124 sb.append("Wake for "); 15125 app.toShortString(sb); 15126 sb.append(": over "); 15127 TimeUtils.formatDuration(realtimeSince, sb); 15128 sb.append(" used "); 15129 TimeUtils.formatDuration(wtimeUsed, sb); 15130 sb.append(" ("); 15131 sb.append((wtimeUsed*100)/realtimeSince); 15132 sb.append("%)"); 15133 Slog.i(TAG, sb.toString()); 15134 sb.setLength(0); 15135 sb.append("CPU for "); 15136 app.toShortString(sb); 15137 sb.append(": over "); 15138 TimeUtils.formatDuration(uptimeSince, sb); 15139 sb.append(" used "); 15140 TimeUtils.formatDuration(cputimeUsed, sb); 15141 sb.append(" ("); 15142 sb.append((cputimeUsed*100)/uptimeSince); 15143 sb.append("%)"); 15144 Slog.i(TAG, sb.toString()); 15145 } 15146 // If a process has held a wake lock for more 15147 // than 50% of the time during this period, 15148 // that sounds bad. Kill! 15149 if (doWakeKills && realtimeSince > 0 15150 && ((wtimeUsed*100)/realtimeSince) >= 50) { 15151 synchronized (stats) { 15152 stats.reportExcessiveWakeLocked(app.info.uid, app.processName, 15153 realtimeSince, wtimeUsed); 15154 } 15155 killUnneededProcessLocked(app, "excessive wake held " + wtimeUsed 15156 + " during " + realtimeSince); 15157 app.baseProcessTracker.reportExcessiveWake(app.pkgList); 15158 } else if (doCpuKills && uptimeSince > 0 15159 && ((cputimeUsed*100)/uptimeSince) >= 50) { 15160 synchronized (stats) { 15161 stats.reportExcessiveCpuLocked(app.info.uid, app.processName, 15162 uptimeSince, cputimeUsed); 15163 } 15164 killUnneededProcessLocked(app, "excessive cpu " + cputimeUsed 15165 + " during " + uptimeSince); 15166 app.baseProcessTracker.reportExcessiveCpu(app.pkgList); 15167 } else { 15168 app.lastWakeTime = wtime; 15169 app.lastCpuTime = app.curCpuTime; 15170 } 15171 } 15172 } 15173 } 15174 15175 private final boolean applyOomAdjLocked(ProcessRecord app, boolean wasKeeping, 15176 ProcessRecord TOP_APP, boolean doingAll, boolean reportingProcessState, long now) { 15177 boolean success = true; 15178 15179 if (app.curRawAdj != app.setRawAdj) { 15180 if (wasKeeping && !app.keeping) { 15181 // This app is no longer something we want to keep. Note 15182 // its current wake lock time to later know to kill it if 15183 // it is not behaving well. 15184 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 15185 synchronized (stats) { 15186 app.lastWakeTime = stats.getProcessWakeTime(app.info.uid, 15187 app.pid, SystemClock.elapsedRealtime()); 15188 } 15189 app.lastCpuTime = app.curCpuTime; 15190 } 15191 15192 app.setRawAdj = app.curRawAdj; 15193 } 15194 15195 if (app.curAdj != app.setAdj) { 15196 if (Process.setOomAdj(app.pid, app.curAdj)) { 15197 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v( 15198 TAG, "Set " + app.pid + " " + app.processName + 15199 " adj " + app.curAdj + ": " + app.adjType); 15200 app.setAdj = app.curAdj; 15201 } else { 15202 success = false; 15203 Slog.w(TAG, "Failed setting oom adj of " + app + " to " + app.curAdj); 15204 } 15205 } 15206 if (app.setSchedGroup != app.curSchedGroup) { 15207 app.setSchedGroup = app.curSchedGroup; 15208 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 15209 "Setting process group of " + app.processName 15210 + " to " + app.curSchedGroup); 15211 if (app.waitingToKill != null && 15212 app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 15213 killUnneededProcessLocked(app, app.waitingToKill); 15214 success = false; 15215 } else { 15216 if (true) { 15217 long oldId = Binder.clearCallingIdentity(); 15218 try { 15219 Process.setProcessGroup(app.pid, app.curSchedGroup); 15220 } catch (Exception e) { 15221 Slog.w(TAG, "Failed setting process group of " + app.pid 15222 + " to " + app.curSchedGroup); 15223 e.printStackTrace(); 15224 } finally { 15225 Binder.restoreCallingIdentity(oldId); 15226 } 15227 } else { 15228 if (app.thread != null) { 15229 try { 15230 app.thread.setSchedulingGroup(app.curSchedGroup); 15231 } catch (RemoteException e) { 15232 } 15233 } 15234 } 15235 Process.setSwappiness(app.pid, 15236 app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE); 15237 } 15238 } 15239 if (app.repProcState != app.curProcState) { 15240 app.repProcState = app.curProcState; 15241 if (!reportingProcessState && app.thread != null) { 15242 try { 15243 if (false) { 15244 //RuntimeException h = new RuntimeException("here"); 15245 Slog.i(TAG, "Sending new process state " + app.repProcState 15246 + " to " + app /*, h*/); 15247 } 15248 app.thread.setProcessState(app.repProcState); 15249 } catch (RemoteException e) { 15250 } 15251 } 15252 } 15253 if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState, 15254 app.setProcState)) { 15255 app.lastStateTime = now; 15256 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true, 15257 mSleeping, now); 15258 if (DEBUG_PSS) Slog.d(TAG, "Process state change from " 15259 + ProcessList.makeProcStateString(app.setProcState) + " to " 15260 + ProcessList.makeProcStateString(app.curProcState) + " next pss in " 15261 + (app.nextPssTime-now) + ": " + app); 15262 } else { 15263 if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL) 15264 && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) { 15265 requestPssLocked(app, app.setProcState); 15266 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false, 15267 mSleeping, now); 15268 } else if (false && DEBUG_PSS) { 15269 Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now)); 15270 } 15271 } 15272 if (app.setProcState != app.curProcState) { 15273 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 15274 "Proc state change of " + app.processName 15275 + " to " + app.curProcState); 15276 app.setProcState = app.curProcState; 15277 if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) { 15278 app.notCachedSinceIdle = false; 15279 } 15280 if (!doingAll) { 15281 setProcessTrackerState(app, mProcessStats.getMemFactorLocked(), now); 15282 } else { 15283 app.procStateChanged = true; 15284 } 15285 } 15286 return success; 15287 } 15288 15289 private final void setProcessTrackerState(ProcessRecord proc, int memFactor, long now) { 15290 if (proc.thread != null && proc.baseProcessTracker != null) { 15291 proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList); 15292 } 15293 } 15294 15295 private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj, 15296 ProcessRecord TOP_APP, boolean doingAll, boolean reportingProcessState, long now) { 15297 if (app.thread == null) { 15298 return false; 15299 } 15300 15301 final boolean wasKeeping = app.keeping; 15302 15303 computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now); 15304 15305 return applyOomAdjLocked(app, wasKeeping, TOP_APP, doingAll, 15306 reportingProcessState, now); 15307 } 15308 15309 private final ActivityRecord resumedAppLocked() { 15310 return mStackSupervisor.resumedAppLocked(); 15311 } 15312 15313 final boolean updateOomAdjLocked(ProcessRecord app) { 15314 return updateOomAdjLocked(app, false); 15315 } 15316 15317 final boolean updateOomAdjLocked(ProcessRecord app, boolean doingProcessState) { 15318 final ActivityRecord TOP_ACT = resumedAppLocked(); 15319 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 15320 final boolean wasCached = app.cached; 15321 15322 mAdjSeq++; 15323 15324 // This is the desired cached adjusment we want to tell it to use. 15325 // If our app is currently cached, we know it, and that is it. Otherwise, 15326 // we don't know it yet, and it needs to now be cached we will then 15327 // need to do a complete oom adj. 15328 final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ 15329 ? app.curRawAdj : ProcessList.UNKNOWN_ADJ; 15330 boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false, doingProcessState, 15331 SystemClock.uptimeMillis()); 15332 if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) { 15333 // Changed to/from cached state, so apps after it in the LRU 15334 // list may also be changed. 15335 updateOomAdjLocked(); 15336 } 15337 return success; 15338 } 15339 15340 final void updateOomAdjLocked() { 15341 final ActivityRecord TOP_ACT = resumedAppLocked(); 15342 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 15343 final long now = SystemClock.uptimeMillis(); 15344 final long oldTime = now - ProcessList.MAX_EMPTY_TIME; 15345 final int N = mLruProcesses.size(); 15346 15347 if (false) { 15348 RuntimeException e = new RuntimeException(); 15349 e.fillInStackTrace(); 15350 Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e); 15351 } 15352 15353 mAdjSeq++; 15354 mNewNumServiceProcs = 0; 15355 mNewNumAServiceProcs = 0; 15356 15357 final int emptyProcessLimit; 15358 final int cachedProcessLimit; 15359 if (mProcessLimit <= 0) { 15360 emptyProcessLimit = cachedProcessLimit = 0; 15361 } else if (mProcessLimit == 1) { 15362 emptyProcessLimit = 1; 15363 cachedProcessLimit = 0; 15364 } else { 15365 emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit); 15366 cachedProcessLimit = mProcessLimit - emptyProcessLimit; 15367 } 15368 15369 // Let's determine how many processes we have running vs. 15370 // how many slots we have for background processes; we may want 15371 // to put multiple processes in a slot of there are enough of 15372 // them. 15373 int numSlots = (ProcessList.CACHED_APP_MAX_ADJ 15374 - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2; 15375 int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs; 15376 if (numEmptyProcs > cachedProcessLimit) { 15377 // If there are more empty processes than our limit on cached 15378 // processes, then use the cached process limit for the factor. 15379 // This ensures that the really old empty processes get pushed 15380 // down to the bottom, so if we are running low on memory we will 15381 // have a better chance at keeping around more cached processes 15382 // instead of a gazillion empty processes. 15383 numEmptyProcs = cachedProcessLimit; 15384 } 15385 int emptyFactor = numEmptyProcs/numSlots; 15386 if (emptyFactor < 1) emptyFactor = 1; 15387 int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots; 15388 if (cachedFactor < 1) cachedFactor = 1; 15389 int stepCached = 0; 15390 int stepEmpty = 0; 15391 int numCached = 0; 15392 int numEmpty = 0; 15393 int numTrimming = 0; 15394 15395 mNumNonCachedProcs = 0; 15396 mNumCachedHiddenProcs = 0; 15397 15398 // First update the OOM adjustment for each of the 15399 // application processes based on their current state. 15400 int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ; 15401 int nextCachedAdj = curCachedAdj+1; 15402 int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ; 15403 int nextEmptyAdj = curEmptyAdj+2; 15404 for (int i=N-1; i>=0; i--) { 15405 ProcessRecord app = mLruProcesses.get(i); 15406 if (!app.killedByAm && app.thread != null) { 15407 app.procStateChanged = false; 15408 final boolean wasKeeping = app.keeping; 15409 computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now); 15410 15411 // If we haven't yet assigned the final cached adj 15412 // to the process, do that now. 15413 if (app.curAdj >= ProcessList.UNKNOWN_ADJ) { 15414 switch (app.curProcState) { 15415 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY: 15416 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: 15417 // This process is a cached process holding activities... 15418 // assign it the next cached value for that type, and then 15419 // step that cached level. 15420 app.curRawAdj = curCachedAdj; 15421 app.curAdj = app.modifyRawOomAdj(curCachedAdj); 15422 if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i 15423 + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj 15424 + ")"); 15425 if (curCachedAdj != nextCachedAdj) { 15426 stepCached++; 15427 if (stepCached >= cachedFactor) { 15428 stepCached = 0; 15429 curCachedAdj = nextCachedAdj; 15430 nextCachedAdj += 2; 15431 if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) { 15432 nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ; 15433 } 15434 } 15435 } 15436 break; 15437 default: 15438 // For everything else, assign next empty cached process 15439 // level and bump that up. Note that this means that 15440 // long-running services that have dropped down to the 15441 // cached level will be treated as empty (since their process 15442 // state is still as a service), which is what we want. 15443 app.curRawAdj = curEmptyAdj; 15444 app.curAdj = app.modifyRawOomAdj(curEmptyAdj); 15445 if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i 15446 + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj 15447 + ")"); 15448 if (curEmptyAdj != nextEmptyAdj) { 15449 stepEmpty++; 15450 if (stepEmpty >= emptyFactor) { 15451 stepEmpty = 0; 15452 curEmptyAdj = nextEmptyAdj; 15453 nextEmptyAdj += 2; 15454 if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) { 15455 nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ; 15456 } 15457 } 15458 } 15459 break; 15460 } 15461 } 15462 15463 applyOomAdjLocked(app, wasKeeping, TOP_APP, true, false, now); 15464 15465 // Count the number of process types. 15466 switch (app.curProcState) { 15467 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY: 15468 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: 15469 mNumCachedHiddenProcs++; 15470 numCached++; 15471 if (numCached > cachedProcessLimit) { 15472 killUnneededProcessLocked(app, "cached #" + numCached); 15473 } 15474 break; 15475 case ActivityManager.PROCESS_STATE_CACHED_EMPTY: 15476 if (numEmpty > ProcessList.TRIM_EMPTY_APPS 15477 && app.lastActivityTime < oldTime) { 15478 killUnneededProcessLocked(app, "empty for " 15479 + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime) 15480 / 1000) + "s"); 15481 } else { 15482 numEmpty++; 15483 if (numEmpty > emptyProcessLimit) { 15484 killUnneededProcessLocked(app, "empty #" + numEmpty); 15485 } 15486 } 15487 break; 15488 default: 15489 mNumNonCachedProcs++; 15490 break; 15491 } 15492 15493 if (app.isolated && app.services.size() <= 0) { 15494 // If this is an isolated process, and there are no 15495 // services running in it, then the process is no longer 15496 // needed. We agressively kill these because we can by 15497 // definition not re-use the same process again, and it is 15498 // good to avoid having whatever code was running in them 15499 // left sitting around after no longer needed. 15500 killUnneededProcessLocked(app, "isolated not needed"); 15501 } 15502 15503 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME 15504 && !app.killedByAm) { 15505 numTrimming++; 15506 } 15507 } 15508 } 15509 15510 mNumServiceProcs = mNewNumServiceProcs; 15511 15512 // Now determine the memory trimming level of background processes. 15513 // Unfortunately we need to start at the back of the list to do this 15514 // properly. We only do this if the number of background apps we 15515 // are managing to keep around is less than half the maximum we desire; 15516 // if we are keeping a good number around, we'll let them use whatever 15517 // memory they want. 15518 final int numCachedAndEmpty = numCached + numEmpty; 15519 int memFactor; 15520 if (numCached <= ProcessList.TRIM_CACHED_APPS 15521 && numEmpty <= ProcessList.TRIM_EMPTY_APPS) { 15522 if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) { 15523 memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL; 15524 } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) { 15525 memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW; 15526 } else { 15527 memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE; 15528 } 15529 } else { 15530 memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL; 15531 } 15532 // We always allow the memory level to go up (better). We only allow it to go 15533 // down if we are in a state where that is allowed, *and* the total number of processes 15534 // has gone down since last time. 15535 if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel 15536 + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size() 15537 + " last=" + mLastNumProcesses); 15538 if (memFactor > mLastMemoryLevel) { 15539 if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) { 15540 memFactor = mLastMemoryLevel; 15541 if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!"); 15542 } 15543 } 15544 mLastMemoryLevel = memFactor; 15545 mLastNumProcesses = mLruProcesses.size(); 15546 boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !mSleeping, now); 15547 final int trackerMemFactor = mProcessStats.getMemFactorLocked(); 15548 if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) { 15549 if (mLowRamStartTime == 0) { 15550 mLowRamStartTime = now; 15551 } 15552 int step = 0; 15553 int fgTrimLevel; 15554 switch (memFactor) { 15555 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL: 15556 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL; 15557 break; 15558 case ProcessStats.ADJ_MEM_FACTOR_LOW: 15559 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW; 15560 break; 15561 default: 15562 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE; 15563 break; 15564 } 15565 int factor = numTrimming/3; 15566 int minFactor = 2; 15567 if (mHomeProcess != null) minFactor++; 15568 if (mPreviousProcess != null) minFactor++; 15569 if (factor < minFactor) factor = minFactor; 15570 int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE; 15571 for (int i=N-1; i>=0; i--) { 15572 ProcessRecord app = mLruProcesses.get(i); 15573 if (allChanged || app.procStateChanged) { 15574 setProcessTrackerState(app, trackerMemFactor, now); 15575 app.procStateChanged = false; 15576 } 15577 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME 15578 && !app.killedByAm) { 15579 if (app.trimMemoryLevel < curLevel && app.thread != null) { 15580 try { 15581 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 15582 "Trimming memory of " + app.processName 15583 + " to " + curLevel); 15584 app.thread.scheduleTrimMemory(curLevel); 15585 } catch (RemoteException e) { 15586 } 15587 if (false) { 15588 // For now we won't do this; our memory trimming seems 15589 // to be good enough at this point that destroying 15590 // activities causes more harm than good. 15591 if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE 15592 && app != mHomeProcess && app != mPreviousProcess) { 15593 // Need to do this on its own message because the stack may not 15594 // be in a consistent state at this point. 15595 // For these apps we will also finish their activities 15596 // to help them free memory. 15597 mStackSupervisor.scheduleDestroyAllActivities(app, "trim"); 15598 } 15599 } 15600 } 15601 app.trimMemoryLevel = curLevel; 15602 step++; 15603 if (step >= factor) { 15604 step = 0; 15605 switch (curLevel) { 15606 case ComponentCallbacks2.TRIM_MEMORY_COMPLETE: 15607 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE; 15608 break; 15609 case ComponentCallbacks2.TRIM_MEMORY_MODERATE: 15610 curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 15611 break; 15612 } 15613 } 15614 } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) { 15615 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND 15616 && app.thread != null) { 15617 try { 15618 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 15619 "Trimming memory of heavy-weight " + app.processName 15620 + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 15621 app.thread.scheduleTrimMemory( 15622 ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 15623 } catch (RemoteException e) { 15624 } 15625 } 15626 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 15627 } else { 15628 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 15629 || app.systemNoUi) && app.pendingUiClean) { 15630 // If this application is now in the background and it 15631 // had done UI, then give it the special trim level to 15632 // have it free UI resources. 15633 final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN; 15634 if (app.trimMemoryLevel < level && app.thread != null) { 15635 try { 15636 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 15637 "Trimming memory of bg-ui " + app.processName 15638 + " to " + level); 15639 app.thread.scheduleTrimMemory(level); 15640 } catch (RemoteException e) { 15641 } 15642 } 15643 app.pendingUiClean = false; 15644 } 15645 if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) { 15646 try { 15647 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 15648 "Trimming memory of fg " + app.processName 15649 + " to " + fgTrimLevel); 15650 app.thread.scheduleTrimMemory(fgTrimLevel); 15651 } catch (RemoteException e) { 15652 } 15653 } 15654 app.trimMemoryLevel = fgTrimLevel; 15655 } 15656 } 15657 } else { 15658 if (mLowRamStartTime != 0) { 15659 mLowRamTimeSinceLastIdle += now - mLowRamStartTime; 15660 mLowRamStartTime = 0; 15661 } 15662 for (int i=N-1; i>=0; i--) { 15663 ProcessRecord app = mLruProcesses.get(i); 15664 if (allChanged || app.procStateChanged) { 15665 setProcessTrackerState(app, trackerMemFactor, now); 15666 app.procStateChanged = false; 15667 } 15668 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 15669 || app.systemNoUi) && app.pendingUiClean) { 15670 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN 15671 && app.thread != null) { 15672 try { 15673 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 15674 "Trimming memory of ui hidden " + app.processName 15675 + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 15676 app.thread.scheduleTrimMemory( 15677 ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 15678 } catch (RemoteException e) { 15679 } 15680 } 15681 app.pendingUiClean = false; 15682 } 15683 app.trimMemoryLevel = 0; 15684 } 15685 } 15686 15687 if (mAlwaysFinishActivities) { 15688 // Need to do this on its own message because the stack may not 15689 // be in a consistent state at this point. 15690 mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish"); 15691 } 15692 15693 if (allChanged) { 15694 requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered()); 15695 } 15696 15697 if (mProcessStats.shouldWriteNowLocked(now)) { 15698 mHandler.post(new Runnable() { 15699 @Override public void run() { 15700 synchronized (ActivityManagerService.this) { 15701 mProcessStats.writeStateAsyncLocked(); 15702 } 15703 } 15704 }); 15705 } 15706 15707 if (DEBUG_OOM_ADJ) { 15708 Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms"); 15709 } 15710 } 15711 15712 final void trimApplications() { 15713 synchronized (this) { 15714 int i; 15715 15716 // First remove any unused application processes whose package 15717 // has been removed. 15718 for (i=mRemovedProcesses.size()-1; i>=0; i--) { 15719 final ProcessRecord app = mRemovedProcesses.get(i); 15720 if (app.activities.size() == 0 15721 && app.curReceiver == null && app.services.size() == 0) { 15722 Slog.i( 15723 TAG, "Exiting empty application process " 15724 + app.processName + " (" 15725 + (app.thread != null ? app.thread.asBinder() : null) 15726 + ")\n"); 15727 if (app.pid > 0 && app.pid != MY_PID) { 15728 EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid, 15729 app.processName, app.setAdj, "empty"); 15730 app.killedByAm = true; 15731 Process.killProcessQuiet(app.pid); 15732 } else { 15733 try { 15734 app.thread.scheduleExit(); 15735 } catch (Exception e) { 15736 // Ignore exceptions. 15737 } 15738 } 15739 cleanUpApplicationRecordLocked(app, false, true, -1); 15740 mRemovedProcesses.remove(i); 15741 15742 if (app.persistent) { 15743 if (app.persistent) { 15744 addAppLocked(app.info, false); 15745 } 15746 } 15747 } 15748 } 15749 15750 // Now update the oom adj for all processes. 15751 updateOomAdjLocked(); 15752 } 15753 } 15754 15755 /** This method sends the specified signal to each of the persistent apps */ 15756 public void signalPersistentProcesses(int sig) throws RemoteException { 15757 if (sig != Process.SIGNAL_USR1) { 15758 throw new SecurityException("Only SIGNAL_USR1 is allowed"); 15759 } 15760 15761 synchronized (this) { 15762 if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES) 15763 != PackageManager.PERMISSION_GRANTED) { 15764 throw new SecurityException("Requires permission " 15765 + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES); 15766 } 15767 15768 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 15769 ProcessRecord r = mLruProcesses.get(i); 15770 if (r.thread != null && r.persistent) { 15771 Process.sendSignal(r.pid, sig); 15772 } 15773 } 15774 } 15775 } 15776 15777 private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) { 15778 if (proc == null || proc == mProfileProc) { 15779 proc = mProfileProc; 15780 path = mProfileFile; 15781 profileType = mProfileType; 15782 clearProfilerLocked(); 15783 } 15784 if (proc == null) { 15785 return; 15786 } 15787 try { 15788 proc.thread.profilerControl(false, path, null, profileType); 15789 } catch (RemoteException e) { 15790 throw new IllegalStateException("Process disappeared"); 15791 } 15792 } 15793 15794 private void clearProfilerLocked() { 15795 if (mProfileFd != null) { 15796 try { 15797 mProfileFd.close(); 15798 } catch (IOException e) { 15799 } 15800 } 15801 mProfileApp = null; 15802 mProfileProc = null; 15803 mProfileFile = null; 15804 mProfileType = 0; 15805 mAutoStopProfiler = false; 15806 } 15807 15808 public boolean profileControl(String process, int userId, boolean start, 15809 String path, ParcelFileDescriptor fd, int profileType) throws RemoteException { 15810 15811 try { 15812 synchronized (this) { 15813 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 15814 // its own permission. 15815 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 15816 != PackageManager.PERMISSION_GRANTED) { 15817 throw new SecurityException("Requires permission " 15818 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 15819 } 15820 15821 if (start && fd == null) { 15822 throw new IllegalArgumentException("null fd"); 15823 } 15824 15825 ProcessRecord proc = null; 15826 if (process != null) { 15827 proc = findProcessLocked(process, userId, "profileControl"); 15828 } 15829 15830 if (start && (proc == null || proc.thread == null)) { 15831 throw new IllegalArgumentException("Unknown process: " + process); 15832 } 15833 15834 if (start) { 15835 stopProfilerLocked(null, null, 0); 15836 setProfileApp(proc.info, proc.processName, path, fd, false); 15837 mProfileProc = proc; 15838 mProfileType = profileType; 15839 try { 15840 fd = fd.dup(); 15841 } catch (IOException e) { 15842 fd = null; 15843 } 15844 proc.thread.profilerControl(start, path, fd, profileType); 15845 fd = null; 15846 mProfileFd = null; 15847 } else { 15848 stopProfilerLocked(proc, path, profileType); 15849 if (fd != null) { 15850 try { 15851 fd.close(); 15852 } catch (IOException e) { 15853 } 15854 } 15855 } 15856 15857 return true; 15858 } 15859 } catch (RemoteException e) { 15860 throw new IllegalStateException("Process disappeared"); 15861 } finally { 15862 if (fd != null) { 15863 try { 15864 fd.close(); 15865 } catch (IOException e) { 15866 } 15867 } 15868 } 15869 } 15870 15871 private ProcessRecord findProcessLocked(String process, int userId, String callName) { 15872 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 15873 userId, true, true, callName, null); 15874 ProcessRecord proc = null; 15875 try { 15876 int pid = Integer.parseInt(process); 15877 synchronized (mPidsSelfLocked) { 15878 proc = mPidsSelfLocked.get(pid); 15879 } 15880 } catch (NumberFormatException e) { 15881 } 15882 15883 if (proc == null) { 15884 ArrayMap<String, SparseArray<ProcessRecord>> all 15885 = mProcessNames.getMap(); 15886 SparseArray<ProcessRecord> procs = all.get(process); 15887 if (procs != null && procs.size() > 0) { 15888 proc = procs.valueAt(0); 15889 if (userId != UserHandle.USER_ALL && proc.userId != userId) { 15890 for (int i=1; i<procs.size(); i++) { 15891 ProcessRecord thisProc = procs.valueAt(i); 15892 if (thisProc.userId == userId) { 15893 proc = thisProc; 15894 break; 15895 } 15896 } 15897 } 15898 } 15899 } 15900 15901 return proc; 15902 } 15903 15904 public boolean dumpHeap(String process, int userId, boolean managed, 15905 String path, ParcelFileDescriptor fd) throws RemoteException { 15906 15907 try { 15908 synchronized (this) { 15909 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 15910 // its own permission (same as profileControl). 15911 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 15912 != PackageManager.PERMISSION_GRANTED) { 15913 throw new SecurityException("Requires permission " 15914 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 15915 } 15916 15917 if (fd == null) { 15918 throw new IllegalArgumentException("null fd"); 15919 } 15920 15921 ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap"); 15922 if (proc == null || proc.thread == null) { 15923 throw new IllegalArgumentException("Unknown process: " + process); 15924 } 15925 15926 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 15927 if (!isDebuggable) { 15928 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 15929 throw new SecurityException("Process not debuggable: " + proc); 15930 } 15931 } 15932 15933 proc.thread.dumpHeap(managed, path, fd); 15934 fd = null; 15935 return true; 15936 } 15937 } catch (RemoteException e) { 15938 throw new IllegalStateException("Process disappeared"); 15939 } finally { 15940 if (fd != null) { 15941 try { 15942 fd.close(); 15943 } catch (IOException e) { 15944 } 15945 } 15946 } 15947 } 15948 15949 /** In this method we try to acquire our lock to make sure that we have not deadlocked */ 15950 public void monitor() { 15951 synchronized (this) { } 15952 } 15953 15954 void onCoreSettingsChange(Bundle settings) { 15955 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 15956 ProcessRecord processRecord = mLruProcesses.get(i); 15957 try { 15958 if (processRecord.thread != null) { 15959 processRecord.thread.setCoreSettings(settings); 15960 } 15961 } catch (RemoteException re) { 15962 /* ignore */ 15963 } 15964 } 15965 } 15966 15967 // Multi-user methods 15968 15969 @Override 15970 public boolean switchUser(final int userId) { 15971 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 15972 != PackageManager.PERMISSION_GRANTED) { 15973 String msg = "Permission Denial: switchUser() from pid=" 15974 + Binder.getCallingPid() 15975 + ", uid=" + Binder.getCallingUid() 15976 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 15977 Slog.w(TAG, msg); 15978 throw new SecurityException(msg); 15979 } 15980 15981 final long ident = Binder.clearCallingIdentity(); 15982 try { 15983 synchronized (this) { 15984 final int oldUserId = mCurrentUserId; 15985 if (oldUserId == userId) { 15986 return true; 15987 } 15988 15989 final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId); 15990 if (userInfo == null) { 15991 Slog.w(TAG, "No user info for user #" + userId); 15992 return false; 15993 } 15994 15995 mWindowManager.startFreezingScreen(R.anim.screen_user_exit, 15996 R.anim.screen_user_enter); 15997 15998 boolean needStart = false; 15999 16000 // If the user we are switching to is not currently started, then 16001 // we need to start it now. 16002 if (mStartedUsers.get(userId) == null) { 16003 mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false)); 16004 updateStartedUserArrayLocked(); 16005 needStart = true; 16006 } 16007 16008 mCurrentUserId = userId; 16009 final Integer userIdInt = Integer.valueOf(userId); 16010 mUserLru.remove(userIdInt); 16011 mUserLru.add(userIdInt); 16012 16013 mWindowManager.setCurrentUser(userId); 16014 16015 // Once the internal notion of the active user has switched, we lock the device 16016 // with the option to show the user switcher on the keyguard. 16017 mWindowManager.lockNow(null); 16018 16019 final UserStartedState uss = mStartedUsers.get(userId); 16020 16021 // Make sure user is in the started state. If it is currently 16022 // stopping, we need to knock that off. 16023 if (uss.mState == UserStartedState.STATE_STOPPING) { 16024 // If we are stopping, we haven't sent ACTION_SHUTDOWN, 16025 // so we can just fairly silently bring the user back from 16026 // the almost-dead. 16027 uss.mState = UserStartedState.STATE_RUNNING; 16028 updateStartedUserArrayLocked(); 16029 needStart = true; 16030 } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) { 16031 // This means ACTION_SHUTDOWN has been sent, so we will 16032 // need to treat this as a new boot of the user. 16033 uss.mState = UserStartedState.STATE_BOOTING; 16034 updateStartedUserArrayLocked(); 16035 needStart = true; 16036 } 16037 16038 mHandler.removeMessages(REPORT_USER_SWITCH_MSG); 16039 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 16040 mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG, 16041 oldUserId, userId, uss)); 16042 mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG, 16043 oldUserId, userId, uss), USER_SWITCH_TIMEOUT); 16044 if (needStart) { 16045 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 16046 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16047 | Intent.FLAG_RECEIVER_FOREGROUND); 16048 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 16049 broadcastIntentLocked(null, null, intent, 16050 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 16051 false, false, MY_PID, Process.SYSTEM_UID, userId); 16052 } 16053 16054 if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) { 16055 if (userId != 0) { 16056 Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE); 16057 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 16058 broadcastIntentLocked(null, null, intent, null, 16059 new IIntentReceiver.Stub() { 16060 public void performReceive(Intent intent, int resultCode, 16061 String data, Bundle extras, boolean ordered, 16062 boolean sticky, int sendingUser) { 16063 userInitialized(uss, userId); 16064 } 16065 }, 0, null, null, null, AppOpsManager.OP_NONE, 16066 true, false, MY_PID, Process.SYSTEM_UID, 16067 userId); 16068 uss.initializing = true; 16069 } else { 16070 getUserManagerLocked().makeInitialized(userInfo.id); 16071 } 16072 } 16073 16074 boolean homeInFront = mStackSupervisor.switchUserLocked(userId, uss); 16075 if (homeInFront) { 16076 startHomeActivityLocked(userId); 16077 } else { 16078 mStackSupervisor.resumeTopActivitiesLocked(); 16079 } 16080 16081 EventLogTags.writeAmSwitchUser(userId); 16082 getUserManagerLocked().userForeground(userId); 16083 sendUserSwitchBroadcastsLocked(oldUserId, userId); 16084 if (needStart) { 16085 Intent intent = new Intent(Intent.ACTION_USER_STARTING); 16086 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 16087 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 16088 broadcastIntentLocked(null, null, intent, 16089 null, new IIntentReceiver.Stub() { 16090 @Override 16091 public void performReceive(Intent intent, int resultCode, String data, 16092 Bundle extras, boolean ordered, boolean sticky, int sendingUser) 16093 throws RemoteException { 16094 } 16095 }, 0, null, null, 16096 android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 16097 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 16098 } 16099 } 16100 } finally { 16101 Binder.restoreCallingIdentity(ident); 16102 } 16103 16104 return true; 16105 } 16106 16107 void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) { 16108 long ident = Binder.clearCallingIdentity(); 16109 try { 16110 Intent intent; 16111 if (oldUserId >= 0) { 16112 intent = new Intent(Intent.ACTION_USER_BACKGROUND); 16113 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16114 | Intent.FLAG_RECEIVER_FOREGROUND); 16115 intent.putExtra(Intent.EXTRA_USER_HANDLE, oldUserId); 16116 broadcastIntentLocked(null, null, intent, 16117 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 16118 false, false, MY_PID, Process.SYSTEM_UID, oldUserId); 16119 } 16120 if (newUserId >= 0) { 16121 intent = new Intent(Intent.ACTION_USER_FOREGROUND); 16122 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16123 | Intent.FLAG_RECEIVER_FOREGROUND); 16124 intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId); 16125 broadcastIntentLocked(null, null, intent, 16126 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 16127 false, false, MY_PID, Process.SYSTEM_UID, newUserId); 16128 intent = new Intent(Intent.ACTION_USER_SWITCHED); 16129 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16130 | Intent.FLAG_RECEIVER_FOREGROUND); 16131 intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId); 16132 broadcastIntentLocked(null, null, intent, 16133 null, null, 0, null, null, 16134 android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE, 16135 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 16136 } 16137 } finally { 16138 Binder.restoreCallingIdentity(ident); 16139 } 16140 } 16141 16142 void dispatchUserSwitch(final UserStartedState uss, final int oldUserId, 16143 final int newUserId) { 16144 final int N = mUserSwitchObservers.beginBroadcast(); 16145 if (N > 0) { 16146 final IRemoteCallback callback = new IRemoteCallback.Stub() { 16147 int mCount = 0; 16148 @Override 16149 public void sendResult(Bundle data) throws RemoteException { 16150 synchronized (ActivityManagerService.this) { 16151 if (mCurUserSwitchCallback == this) { 16152 mCount++; 16153 if (mCount == N) { 16154 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 16155 } 16156 } 16157 } 16158 } 16159 }; 16160 synchronized (this) { 16161 uss.switching = true; 16162 mCurUserSwitchCallback = callback; 16163 } 16164 for (int i=0; i<N; i++) { 16165 try { 16166 mUserSwitchObservers.getBroadcastItem(i).onUserSwitching( 16167 newUserId, callback); 16168 } catch (RemoteException e) { 16169 } 16170 } 16171 } else { 16172 synchronized (this) { 16173 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 16174 } 16175 } 16176 mUserSwitchObservers.finishBroadcast(); 16177 } 16178 16179 void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 16180 synchronized (this) { 16181 Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId); 16182 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 16183 } 16184 } 16185 16186 void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) { 16187 mCurUserSwitchCallback = null; 16188 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 16189 mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG, 16190 oldUserId, newUserId, uss)); 16191 } 16192 16193 void userInitialized(UserStartedState uss, int newUserId) { 16194 completeSwitchAndInitalize(uss, newUserId, true, false); 16195 } 16196 16197 void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 16198 completeSwitchAndInitalize(uss, newUserId, false, true); 16199 } 16200 16201 void completeSwitchAndInitalize(UserStartedState uss, int newUserId, 16202 boolean clearInitializing, boolean clearSwitching) { 16203 boolean unfrozen = false; 16204 synchronized (this) { 16205 if (clearInitializing) { 16206 uss.initializing = false; 16207 getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier()); 16208 } 16209 if (clearSwitching) { 16210 uss.switching = false; 16211 } 16212 if (!uss.switching && !uss.initializing) { 16213 mWindowManager.stopFreezingScreen(); 16214 unfrozen = true; 16215 } 16216 } 16217 if (unfrozen) { 16218 final int N = mUserSwitchObservers.beginBroadcast(); 16219 for (int i=0; i<N; i++) { 16220 try { 16221 mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId); 16222 } catch (RemoteException e) { 16223 } 16224 } 16225 mUserSwitchObservers.finishBroadcast(); 16226 } 16227 } 16228 16229 void finishUserSwitch(UserStartedState uss) { 16230 synchronized (this) { 16231 if (uss.mState == UserStartedState.STATE_BOOTING 16232 && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) { 16233 uss.mState = UserStartedState.STATE_RUNNING; 16234 final int userId = uss.mHandle.getIdentifier(); 16235 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 16236 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 16237 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT); 16238 broadcastIntentLocked(null, null, intent, 16239 null, null, 0, null, null, 16240 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE, 16241 true, false, MY_PID, Process.SYSTEM_UID, userId); 16242 } 16243 int num = mUserLru.size(); 16244 int i = 0; 16245 while (num > MAX_RUNNING_USERS && i < mUserLru.size()) { 16246 Integer oldUserId = mUserLru.get(i); 16247 UserStartedState oldUss = mStartedUsers.get(oldUserId); 16248 if (oldUss == null) { 16249 // Shouldn't happen, but be sane if it does. 16250 mUserLru.remove(i); 16251 num--; 16252 continue; 16253 } 16254 if (oldUss.mState == UserStartedState.STATE_STOPPING 16255 || oldUss.mState == UserStartedState.STATE_SHUTDOWN) { 16256 // This user is already stopping, doesn't count. 16257 num--; 16258 i++; 16259 continue; 16260 } 16261 if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) { 16262 // Owner and current can't be stopped, but count as running. 16263 i++; 16264 continue; 16265 } 16266 // This is a user to be stopped. 16267 stopUserLocked(oldUserId, null); 16268 num--; 16269 i++; 16270 } 16271 } 16272 } 16273 16274 @Override 16275 public int stopUser(final int userId, final IStopUserCallback callback) { 16276 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 16277 != PackageManager.PERMISSION_GRANTED) { 16278 String msg = "Permission Denial: switchUser() from pid=" 16279 + Binder.getCallingPid() 16280 + ", uid=" + Binder.getCallingUid() 16281 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 16282 Slog.w(TAG, msg); 16283 throw new SecurityException(msg); 16284 } 16285 if (userId <= 0) { 16286 throw new IllegalArgumentException("Can't stop primary user " + userId); 16287 } 16288 synchronized (this) { 16289 return stopUserLocked(userId, callback); 16290 } 16291 } 16292 16293 private int stopUserLocked(final int userId, final IStopUserCallback callback) { 16294 if (mCurrentUserId == userId) { 16295 return ActivityManager.USER_OP_IS_CURRENT; 16296 } 16297 16298 final UserStartedState uss = mStartedUsers.get(userId); 16299 if (uss == null) { 16300 // User is not started, nothing to do... but we do need to 16301 // callback if requested. 16302 if (callback != null) { 16303 mHandler.post(new Runnable() { 16304 @Override 16305 public void run() { 16306 try { 16307 callback.userStopped(userId); 16308 } catch (RemoteException e) { 16309 } 16310 } 16311 }); 16312 } 16313 return ActivityManager.USER_OP_SUCCESS; 16314 } 16315 16316 if (callback != null) { 16317 uss.mStopCallbacks.add(callback); 16318 } 16319 16320 if (uss.mState != UserStartedState.STATE_STOPPING 16321 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 16322 uss.mState = UserStartedState.STATE_STOPPING; 16323 updateStartedUserArrayLocked(); 16324 16325 long ident = Binder.clearCallingIdentity(); 16326 try { 16327 // We are going to broadcast ACTION_USER_STOPPING and then 16328 // once that is done send a final ACTION_SHUTDOWN and then 16329 // stop the user. 16330 final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING); 16331 stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 16332 stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 16333 stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true); 16334 final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN); 16335 // This is the result receiver for the final shutdown broadcast. 16336 final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() { 16337 @Override 16338 public void performReceive(Intent intent, int resultCode, String data, 16339 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 16340 finishUserStop(uss); 16341 } 16342 }; 16343 // This is the result receiver for the initial stopping broadcast. 16344 final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() { 16345 @Override 16346 public void performReceive(Intent intent, int resultCode, String data, 16347 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 16348 // On to the next. 16349 synchronized (ActivityManagerService.this) { 16350 if (uss.mState != UserStartedState.STATE_STOPPING) { 16351 // Whoops, we are being started back up. Abort, abort! 16352 return; 16353 } 16354 uss.mState = UserStartedState.STATE_SHUTDOWN; 16355 } 16356 broadcastIntentLocked(null, null, shutdownIntent, 16357 null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE, 16358 true, false, MY_PID, Process.SYSTEM_UID, userId); 16359 } 16360 }; 16361 // Kick things off. 16362 broadcastIntentLocked(null, null, stoppingIntent, 16363 null, stoppingReceiver, 0, null, null, 16364 android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 16365 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 16366 } finally { 16367 Binder.restoreCallingIdentity(ident); 16368 } 16369 } 16370 16371 return ActivityManager.USER_OP_SUCCESS; 16372 } 16373 16374 void finishUserStop(UserStartedState uss) { 16375 final int userId = uss.mHandle.getIdentifier(); 16376 boolean stopped; 16377 ArrayList<IStopUserCallback> callbacks; 16378 synchronized (this) { 16379 callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks); 16380 if (mStartedUsers.get(userId) != uss) { 16381 stopped = false; 16382 } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) { 16383 stopped = false; 16384 } else { 16385 stopped = true; 16386 // User can no longer run. 16387 mStartedUsers.remove(userId); 16388 mUserLru.remove(Integer.valueOf(userId)); 16389 updateStartedUserArrayLocked(); 16390 16391 // Clean up all state and processes associated with the user. 16392 // Kill all the processes for the user. 16393 forceStopUserLocked(userId, "finish user"); 16394 } 16395 } 16396 16397 for (int i=0; i<callbacks.size(); i++) { 16398 try { 16399 if (stopped) callbacks.get(i).userStopped(userId); 16400 else callbacks.get(i).userStopAborted(userId); 16401 } catch (RemoteException e) { 16402 } 16403 } 16404 16405 mStackSupervisor.removeUserLocked(userId); 16406 } 16407 16408 @Override 16409 public UserInfo getCurrentUser() { 16410 if ((checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) 16411 != PackageManager.PERMISSION_GRANTED) && ( 16412 checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 16413 != PackageManager.PERMISSION_GRANTED)) { 16414 String msg = "Permission Denial: getCurrentUser() from pid=" 16415 + Binder.getCallingPid() 16416 + ", uid=" + Binder.getCallingUid() 16417 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS; 16418 Slog.w(TAG, msg); 16419 throw new SecurityException(msg); 16420 } 16421 synchronized (this) { 16422 return getUserManagerLocked().getUserInfo(mCurrentUserId); 16423 } 16424 } 16425 16426 int getCurrentUserIdLocked() { 16427 return mCurrentUserId; 16428 } 16429 16430 @Override 16431 public boolean isUserRunning(int userId, boolean orStopped) { 16432 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) 16433 != PackageManager.PERMISSION_GRANTED) { 16434 String msg = "Permission Denial: isUserRunning() from pid=" 16435 + Binder.getCallingPid() 16436 + ", uid=" + Binder.getCallingUid() 16437 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS; 16438 Slog.w(TAG, msg); 16439 throw new SecurityException(msg); 16440 } 16441 synchronized (this) { 16442 return isUserRunningLocked(userId, orStopped); 16443 } 16444 } 16445 16446 boolean isUserRunningLocked(int userId, boolean orStopped) { 16447 UserStartedState state = mStartedUsers.get(userId); 16448 if (state == null) { 16449 return false; 16450 } 16451 if (orStopped) { 16452 return true; 16453 } 16454 return state.mState != UserStartedState.STATE_STOPPING 16455 && state.mState != UserStartedState.STATE_SHUTDOWN; 16456 } 16457 16458 @Override 16459 public int[] getRunningUserIds() { 16460 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) 16461 != PackageManager.PERMISSION_GRANTED) { 16462 String msg = "Permission Denial: isUserRunning() from pid=" 16463 + Binder.getCallingPid() 16464 + ", uid=" + Binder.getCallingUid() 16465 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS; 16466 Slog.w(TAG, msg); 16467 throw new SecurityException(msg); 16468 } 16469 synchronized (this) { 16470 return mStartedUserArray; 16471 } 16472 } 16473 16474 private void updateStartedUserArrayLocked() { 16475 int num = 0; 16476 for (int i=0; i<mStartedUsers.size(); i++) { 16477 UserStartedState uss = mStartedUsers.valueAt(i); 16478 // This list does not include stopping users. 16479 if (uss.mState != UserStartedState.STATE_STOPPING 16480 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 16481 num++; 16482 } 16483 } 16484 mStartedUserArray = new int[num]; 16485 num = 0; 16486 for (int i=0; i<mStartedUsers.size(); i++) { 16487 UserStartedState uss = mStartedUsers.valueAt(i); 16488 if (uss.mState != UserStartedState.STATE_STOPPING 16489 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 16490 mStartedUserArray[num] = mStartedUsers.keyAt(i); 16491 num++; 16492 } 16493 } 16494 } 16495 16496 @Override 16497 public void registerUserSwitchObserver(IUserSwitchObserver observer) { 16498 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 16499 != PackageManager.PERMISSION_GRANTED) { 16500 String msg = "Permission Denial: registerUserSwitchObserver() from pid=" 16501 + Binder.getCallingPid() 16502 + ", uid=" + Binder.getCallingUid() 16503 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 16504 Slog.w(TAG, msg); 16505 throw new SecurityException(msg); 16506 } 16507 16508 mUserSwitchObservers.register(observer); 16509 } 16510 16511 @Override 16512 public void unregisterUserSwitchObserver(IUserSwitchObserver observer) { 16513 mUserSwitchObservers.unregister(observer); 16514 } 16515 16516 private boolean userExists(int userId) { 16517 if (userId == 0) { 16518 return true; 16519 } 16520 UserManagerService ums = getUserManagerLocked(); 16521 return ums != null ? (ums.getUserInfo(userId) != null) : false; 16522 } 16523 16524 int[] getUsersLocked() { 16525 UserManagerService ums = getUserManagerLocked(); 16526 return ums != null ? ums.getUserIds() : new int[] { 0 }; 16527 } 16528 16529 UserManagerService getUserManagerLocked() { 16530 if (mUserManager == null) { 16531 IBinder b = ServiceManager.getService(Context.USER_SERVICE); 16532 mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b); 16533 } 16534 return mUserManager; 16535 } 16536 16537 private int applyUserId(int uid, int userId) { 16538 return UserHandle.getUid(userId, uid); 16539 } 16540 16541 ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) { 16542 if (info == null) return null; 16543 ApplicationInfo newInfo = new ApplicationInfo(info); 16544 newInfo.uid = applyUserId(info.uid, userId); 16545 newInfo.dataDir = USER_DATA_DIR + userId + "/" 16546 + info.packageName; 16547 return newInfo; 16548 } 16549 16550 ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) { 16551 if (aInfo == null 16552 || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) { 16553 return aInfo; 16554 } 16555 16556 ActivityInfo info = new ActivityInfo(aInfo); 16557 info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId); 16558 return info; 16559 } 16560} 16561