ActivityManagerService.java revision 21de56a94668e0fda1b8bb4ee4f99a09b40d28fd
1/* 2 * Copyright (C) 2006-2008 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17package com.android.server.am; 18 19import static android.content.pm.PackageManager.PERMISSION_GRANTED; 20import static com.android.internal.util.XmlUtils.readBooleanAttribute; 21import static com.android.internal.util.XmlUtils.readIntAttribute; 22import static com.android.internal.util.XmlUtils.readLongAttribute; 23import static com.android.internal.util.XmlUtils.writeBooleanAttribute; 24import static com.android.internal.util.XmlUtils.writeIntAttribute; 25import static com.android.internal.util.XmlUtils.writeLongAttribute; 26import static com.android.server.Watchdog.NATIVE_STACKS_OF_INTEREST; 27import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT; 28import static org.xmlpull.v1.XmlPullParser.START_TAG; 29import static com.android.server.am.ActivityStackSupervisor.HOME_STACK_ID; 30 31import android.app.AppOpsManager; 32import android.app.IActivityContainer; 33import android.app.IActivityContainerCallback; 34import android.appwidget.AppWidgetManager; 35import android.graphics.Rect; 36import android.os.BatteryStats; 37import android.util.ArrayMap; 38 39import com.android.internal.R; 40import com.android.internal.annotations.GuardedBy; 41import com.android.internal.app.IAppOpsService; 42import com.android.internal.app.ProcessMap; 43import com.android.internal.app.ProcessStats; 44import com.android.internal.os.BackgroundThread; 45import com.android.internal.os.BatteryStatsImpl; 46import com.android.internal.os.ProcessCpuTracker; 47import com.android.internal.os.TransferPipe; 48import com.android.internal.os.Zygote; 49import com.android.internal.util.FastPrintWriter; 50import com.android.internal.util.FastXmlSerializer; 51import com.android.internal.util.MemInfoReader; 52import com.android.internal.util.Preconditions; 53import com.android.server.AppOpsService; 54import com.android.server.AttributeCache; 55import com.android.server.IntentResolver; 56import com.android.server.LocalServices; 57import com.android.server.ServiceThread; 58import com.android.server.SystemService; 59import com.android.server.Watchdog; 60import com.android.server.am.ActivityStack.ActivityState; 61import com.android.server.firewall.IntentFirewall; 62import com.android.server.pm.UserManagerService; 63import com.android.server.wm.AppTransition; 64import com.android.server.wm.WindowManagerService; 65import com.google.android.collect.Lists; 66import com.google.android.collect.Maps; 67 68import libcore.io.IoUtils; 69 70import org.xmlpull.v1.XmlPullParser; 71import org.xmlpull.v1.XmlPullParserException; 72import org.xmlpull.v1.XmlSerializer; 73 74import android.app.Activity; 75import android.app.ActivityManager; 76import android.app.ActivityManager.RunningTaskInfo; 77import android.app.ActivityManager.StackInfo; 78import android.app.ActivityManagerInternal; 79import android.app.ActivityManagerNative; 80import android.app.ActivityOptions; 81import android.app.ActivityThread; 82import android.app.AlertDialog; 83import android.app.AppGlobals; 84import android.app.ApplicationErrorReport; 85import android.app.Dialog; 86import android.app.IActivityController; 87import android.app.IApplicationThread; 88import android.app.IInstrumentationWatcher; 89import android.app.INotificationManager; 90import android.app.IProcessObserver; 91import android.app.IServiceConnection; 92import android.app.IStopUserCallback; 93import android.app.IThumbnailReceiver; 94import android.app.IUiAutomationConnection; 95import android.app.IUserSwitchObserver; 96import android.app.Instrumentation; 97import android.app.Notification; 98import android.app.NotificationManager; 99import android.app.PendingIntent; 100import android.app.backup.IBackupManager; 101import android.content.ActivityNotFoundException; 102import android.content.BroadcastReceiver; 103import android.content.ClipData; 104import android.content.ComponentCallbacks2; 105import android.content.ComponentName; 106import android.content.ContentProvider; 107import android.content.ContentResolver; 108import android.content.Context; 109import android.content.DialogInterface; 110import android.content.IContentProvider; 111import android.content.IIntentReceiver; 112import android.content.IIntentSender; 113import android.content.Intent; 114import android.content.IntentFilter; 115import android.content.IntentSender; 116import android.content.pm.ActivityInfo; 117import android.content.pm.ApplicationInfo; 118import android.content.pm.ConfigurationInfo; 119import android.content.pm.IPackageDataObserver; 120import android.content.pm.IPackageManager; 121import android.content.pm.InstrumentationInfo; 122import android.content.pm.PackageInfo; 123import android.content.pm.PackageManager; 124import android.content.pm.ParceledListSlice; 125import android.content.pm.UserInfo; 126import android.content.pm.PackageManager.NameNotFoundException; 127import android.content.pm.PathPermission; 128import android.content.pm.ProviderInfo; 129import android.content.pm.ResolveInfo; 130import android.content.pm.ServiceInfo; 131import android.content.res.CompatibilityInfo; 132import android.content.res.Configuration; 133import android.graphics.Bitmap; 134import android.net.Proxy; 135import android.net.ProxyProperties; 136import android.net.Uri; 137import android.os.Binder; 138import android.os.Build; 139import android.os.Bundle; 140import android.os.Debug; 141import android.os.DropBoxManager; 142import android.os.Environment; 143import android.os.FactoryTest; 144import android.os.FileObserver; 145import android.os.FileUtils; 146import android.os.Handler; 147import android.os.IBinder; 148import android.os.IPermissionController; 149import android.os.IRemoteCallback; 150import android.os.IUserManager; 151import android.os.Looper; 152import android.os.Message; 153import android.os.Parcel; 154import android.os.ParcelFileDescriptor; 155import android.os.Process; 156import android.os.RemoteCallbackList; 157import android.os.RemoteException; 158import android.os.SELinux; 159import android.os.ServiceManager; 160import android.os.StrictMode; 161import android.os.SystemClock; 162import android.os.SystemProperties; 163import android.os.UpdateLock; 164import android.os.UserHandle; 165import android.provider.Settings; 166import android.text.format.DateUtils; 167import android.text.format.Time; 168import android.util.AtomicFile; 169import android.util.EventLog; 170import android.util.Log; 171import android.util.Pair; 172import android.util.PrintWriterPrinter; 173import android.util.Slog; 174import android.util.SparseArray; 175import android.util.TimeUtils; 176import android.util.Xml; 177import android.view.Gravity; 178import android.view.LayoutInflater; 179import android.view.View; 180import android.view.WindowManager; 181 182import java.io.BufferedInputStream; 183import java.io.BufferedOutputStream; 184import java.io.DataInputStream; 185import java.io.DataOutputStream; 186import java.io.File; 187import java.io.FileDescriptor; 188import java.io.FileInputStream; 189import java.io.FileNotFoundException; 190import java.io.FileOutputStream; 191import java.io.IOException; 192import java.io.InputStreamReader; 193import java.io.PrintWriter; 194import java.io.StringWriter; 195import java.lang.ref.WeakReference; 196import java.util.ArrayList; 197import java.util.Arrays; 198import java.util.Collections; 199import java.util.Comparator; 200import java.util.HashMap; 201import java.util.HashSet; 202import java.util.Iterator; 203import java.util.List; 204import java.util.Locale; 205import java.util.Map; 206import java.util.Set; 207import java.util.concurrent.atomic.AtomicBoolean; 208import java.util.concurrent.atomic.AtomicLong; 209 210public final class ActivityManagerService extends ActivityManagerNative 211 implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback { 212 private static final String USER_DATA_DIR = "/data/user/"; 213 static final String TAG = "ActivityManager"; 214 static final String TAG_MU = "ActivityManagerServiceMU"; 215 static final boolean DEBUG = false; 216 static final boolean localLOGV = DEBUG; 217 static final boolean DEBUG_BACKUP = localLOGV || false; 218 static final boolean DEBUG_BROADCAST = localLOGV || false; 219 static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false; 220 static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false; 221 static final boolean DEBUG_CLEANUP = localLOGV || false; 222 static final boolean DEBUG_CONFIGURATION = localLOGV || false; 223 static final boolean DEBUG_FOCUS = false; 224 static final boolean DEBUG_IMMERSIVE = localLOGV || false; 225 static final boolean DEBUG_MU = localLOGV || false; 226 static final boolean DEBUG_OOM_ADJ = localLOGV || false; 227 static final boolean DEBUG_LRU = localLOGV || false; 228 static final boolean DEBUG_PAUSE = localLOGV || false; 229 static final boolean DEBUG_POWER = localLOGV || false; 230 static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false; 231 static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false; 232 static final boolean DEBUG_PROCESSES = localLOGV || false; 233 static final boolean DEBUG_PROVIDER = localLOGV || false; 234 static final boolean DEBUG_RESULTS = localLOGV || false; 235 static final boolean DEBUG_SERVICE = localLOGV || false; 236 static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false; 237 static final boolean DEBUG_STACK = localLOGV || false; 238 static final boolean DEBUG_SWITCH = localLOGV || false; 239 static final boolean DEBUG_TASKS = localLOGV || false; 240 static final boolean DEBUG_THUMBNAILS = localLOGV || false; 241 static final boolean DEBUG_TRANSITION = localLOGV || false; 242 static final boolean DEBUG_URI_PERMISSION = localLOGV || false; 243 static final boolean DEBUG_USER_LEAVING = localLOGV || false; 244 static final boolean DEBUG_VISBILITY = localLOGV || false; 245 static final boolean DEBUG_PSS = localLOGV || false; 246 static final boolean DEBUG_LOCKSCREEN = localLOGV || false; 247 static final boolean VALIDATE_TOKENS = false; 248 static final boolean SHOW_ACTIVITY_START_TIME = true; 249 250 // Control over CPU and battery monitoring. 251 static final long BATTERY_STATS_TIME = 30*60*1000; // write battery stats every 30 minutes. 252 static final boolean MONITOR_CPU_USAGE = true; 253 static final long MONITOR_CPU_MIN_TIME = 5*1000; // don't sample cpu less than every 5 seconds. 254 static final long MONITOR_CPU_MAX_TIME = 0x0fffffff; // wait possibly forever for next cpu sample. 255 static final boolean MONITOR_THREAD_CPU_USAGE = false; 256 257 // The flags that are set for all calls we make to the package manager. 258 static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES; 259 260 private static final String SYSTEM_DEBUGGABLE = "ro.debuggable"; 261 262 static final boolean IS_USER_BUILD = "user".equals(Build.TYPE); 263 264 // Maximum number of recent tasks that we can remember. 265 static final int MAX_RECENT_TASKS = ActivityManager.isLowRamDeviceStatic() ? 10 : 20; 266 267 // Amount of time after a call to stopAppSwitches() during which we will 268 // prevent further untrusted switches from happening. 269 static final long APP_SWITCH_DELAY_TIME = 5*1000; 270 271 // How long we wait for a launched process to attach to the activity manager 272 // before we decide it's never going to come up for real. 273 static final int PROC_START_TIMEOUT = 10*1000; 274 275 // How long we wait for a launched process to attach to the activity manager 276 // before we decide it's never going to come up for real, when the process was 277 // started with a wrapper for instrumentation (such as Valgrind) because it 278 // could take much longer than usual. 279 static final int PROC_START_TIMEOUT_WITH_WRAPPER = 300*1000; 280 281 // How long to wait after going idle before forcing apps to GC. 282 static final int GC_TIMEOUT = 5*1000; 283 284 // The minimum amount of time between successive GC requests for a process. 285 static final int GC_MIN_INTERVAL = 60*1000; 286 287 // The minimum amount of time between successive PSS requests for a process. 288 static final int FULL_PSS_MIN_INTERVAL = 10*60*1000; 289 290 // The minimum amount of time between successive PSS requests for a process 291 // when the request is due to the memory state being lowered. 292 static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000; 293 294 // The rate at which we check for apps using excessive power -- 15 mins. 295 static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000; 296 297 // The minimum sample duration we will allow before deciding we have 298 // enough data on wake locks to start killing things. 299 static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000; 300 301 // The minimum sample duration we will allow before deciding we have 302 // enough data on CPU usage to start killing things. 303 static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000; 304 305 // How long we allow a receiver to run before giving up on it. 306 static final int BROADCAST_FG_TIMEOUT = 10*1000; 307 static final int BROADCAST_BG_TIMEOUT = 60*1000; 308 309 // How long we wait until we timeout on key dispatching. 310 static final int KEY_DISPATCHING_TIMEOUT = 5*1000; 311 312 // How long we wait until we timeout on key dispatching during instrumentation. 313 static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000; 314 315 // Amount of time we wait for observers to handle a user switch before 316 // giving up on them and unfreezing the screen. 317 static final int USER_SWITCH_TIMEOUT = 2*1000; 318 319 // Maximum number of users we allow to be running at a time. 320 static final int MAX_RUNNING_USERS = 3; 321 322 // How long to wait in getAssistContextExtras for the activity and foreground services 323 // to respond with the result. 324 static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500; 325 326 // Maximum number of persisted Uri grants a package is allowed 327 static final int MAX_PERSISTED_URI_GRANTS = 128; 328 329 static final int MY_PID = Process.myPid(); 330 331 static final String[] EMPTY_STRING_ARRAY = new String[0]; 332 333 // How many bytes to write into the dropbox log before truncating 334 static final int DROPBOX_MAX_SIZE = 256 * 1024; 335 336 /** Run all ActivityStacks through this */ 337 ActivityStackSupervisor mStackSupervisor; 338 339 public IntentFirewall mIntentFirewall; 340 341 // Whether we should show our dialogs (ANR, crash, etc) or just perform their 342 // default actuion automatically. Important for devices without direct input 343 // devices. 344 private boolean mShowDialogs = true; 345 346 /** 347 * Description of a request to start a new activity, which has been held 348 * due to app switches being disabled. 349 */ 350 static class PendingActivityLaunch { 351 final ActivityRecord r; 352 final ActivityRecord sourceRecord; 353 final int startFlags; 354 final ActivityStack stack; 355 356 PendingActivityLaunch(ActivityRecord _r, ActivityRecord _sourceRecord, 357 int _startFlags, ActivityStack _stack) { 358 r = _r; 359 sourceRecord = _sourceRecord; 360 startFlags = _startFlags; 361 stack = _stack; 362 } 363 } 364 365 final ArrayList<PendingActivityLaunch> mPendingActivityLaunches 366 = new ArrayList<PendingActivityLaunch>(); 367 368 BroadcastQueue mFgBroadcastQueue; 369 BroadcastQueue mBgBroadcastQueue; 370 // Convenient for easy iteration over the queues. Foreground is first 371 // so that dispatch of foreground broadcasts gets precedence. 372 final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2]; 373 374 BroadcastQueue broadcastQueueForIntent(Intent intent) { 375 final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0; 376 if (DEBUG_BACKGROUND_BROADCAST) { 377 Slog.i(TAG, "Broadcast intent " + intent + " on " 378 + (isFg ? "foreground" : "background") 379 + " queue"); 380 } 381 return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue; 382 } 383 384 BroadcastRecord broadcastRecordForReceiverLocked(IBinder receiver) { 385 for (BroadcastQueue queue : mBroadcastQueues) { 386 BroadcastRecord r = queue.getMatchingOrderedReceiver(receiver); 387 if (r != null) { 388 return r; 389 } 390 } 391 return null; 392 } 393 394 /** 395 * Activity we have told the window manager to have key focus. 396 */ 397 ActivityRecord mFocusedActivity = null; 398 399 /** 400 * List of intents that were used to start the most recent tasks. 401 */ 402 private final ArrayList<TaskRecord> mRecentTasks = new ArrayList<TaskRecord>(); 403 404 public class PendingAssistExtras extends Binder implements Runnable { 405 public final ActivityRecord activity; 406 public boolean haveResult = false; 407 public Bundle result = null; 408 public PendingAssistExtras(ActivityRecord _activity) { 409 activity = _activity; 410 } 411 @Override 412 public void run() { 413 Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity); 414 synchronized (this) { 415 haveResult = true; 416 notifyAll(); 417 } 418 } 419 } 420 421 final ArrayList<PendingAssistExtras> mPendingAssistExtras 422 = new ArrayList<PendingAssistExtras>(); 423 424 /** 425 * Process management. 426 */ 427 final ProcessList mProcessList = new ProcessList(); 428 429 /** 430 * All of the applications we currently have running organized by name. 431 * The keys are strings of the application package name (as 432 * returned by the package manager), and the keys are ApplicationRecord 433 * objects. 434 */ 435 final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>(); 436 437 /** 438 * Tracking long-term execution of processes to look for abuse and other 439 * bad app behavior. 440 */ 441 final ProcessStatsService mProcessStats; 442 443 /** 444 * The currently running isolated processes. 445 */ 446 final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>(); 447 448 /** 449 * Counter for assigning isolated process uids, to avoid frequently reusing the 450 * same ones. 451 */ 452 int mNextIsolatedProcessUid = 0; 453 454 /** 455 * The currently running heavy-weight process, if any. 456 */ 457 ProcessRecord mHeavyWeightProcess = null; 458 459 /** 460 * The last time that various processes have crashed. 461 */ 462 final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>(); 463 464 /** 465 * Information about a process that is currently marked as bad. 466 */ 467 static final class BadProcessInfo { 468 BadProcessInfo(long time, String shortMsg, String longMsg, String stack) { 469 this.time = time; 470 this.shortMsg = shortMsg; 471 this.longMsg = longMsg; 472 this.stack = stack; 473 } 474 475 final long time; 476 final String shortMsg; 477 final String longMsg; 478 final String stack; 479 } 480 481 /** 482 * Set of applications that we consider to be bad, and will reject 483 * incoming broadcasts from (which the user has no control over). 484 * Processes are added to this set when they have crashed twice within 485 * a minimum amount of time; they are removed from it when they are 486 * later restarted (hopefully due to some user action). The value is the 487 * time it was added to the list. 488 */ 489 final ProcessMap<BadProcessInfo> mBadProcesses = new ProcessMap<BadProcessInfo>(); 490 491 /** 492 * All of the processes we currently have running organized by pid. 493 * The keys are the pid running the application. 494 * 495 * <p>NOTE: This object is protected by its own lock, NOT the global 496 * activity manager lock! 497 */ 498 final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>(); 499 500 /** 501 * All of the processes that have been forced to be foreground. The key 502 * is the pid of the caller who requested it (we hold a death 503 * link on it). 504 */ 505 abstract class ForegroundToken implements IBinder.DeathRecipient { 506 int pid; 507 IBinder token; 508 } 509 final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>(); 510 511 /** 512 * List of records for processes that someone had tried to start before the 513 * system was ready. We don't start them at that point, but ensure they 514 * are started by the time booting is complete. 515 */ 516 final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>(); 517 518 /** 519 * List of persistent applications that are in the process 520 * of being started. 521 */ 522 final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>(); 523 524 /** 525 * Processes that are being forcibly torn down. 526 */ 527 final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>(); 528 529 /** 530 * List of running applications, sorted by recent usage. 531 * The first entry in the list is the least recently used. 532 */ 533 final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>(); 534 535 /** 536 * Where in mLruProcesses that the processes hosting activities start. 537 */ 538 int mLruProcessActivityStart = 0; 539 540 /** 541 * Where in mLruProcesses that the processes hosting services start. 542 * This is after (lower index) than mLruProcessesActivityStart. 543 */ 544 int mLruProcessServiceStart = 0; 545 546 /** 547 * List of processes that should gc as soon as things are idle. 548 */ 549 final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>(); 550 551 /** 552 * Processes we want to collect PSS data from. 553 */ 554 final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>(); 555 556 /** 557 * Last time we requested PSS data of all processes. 558 */ 559 long mLastFullPssTime = SystemClock.uptimeMillis(); 560 561 /** 562 * This is the process holding what we currently consider to be 563 * the "home" activity. 564 */ 565 ProcessRecord mHomeProcess; 566 567 /** 568 * This is the process holding the activity the user last visited that 569 * is in a different process from the one they are currently in. 570 */ 571 ProcessRecord mPreviousProcess; 572 573 /** 574 * The time at which the previous process was last visible. 575 */ 576 long mPreviousProcessVisibleTime; 577 578 /** 579 * Which uses have been started, so are allowed to run code. 580 */ 581 final SparseArray<UserStartedState> mStartedUsers = new SparseArray<UserStartedState>(); 582 583 /** 584 * LRU list of history of current users. Most recently current is at the end. 585 */ 586 final ArrayList<Integer> mUserLru = new ArrayList<Integer>(); 587 588 /** 589 * Constant array of the users that are currently started. 590 */ 591 int[] mStartedUserArray = new int[] { 0 }; 592 593 /** 594 * Registered observers of the user switching mechanics. 595 */ 596 final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers 597 = new RemoteCallbackList<IUserSwitchObserver>(); 598 599 /** 600 * Currently active user switch. 601 */ 602 Object mCurUserSwitchCallback; 603 604 /** 605 * Packages that the user has asked to have run in screen size 606 * compatibility mode instead of filling the screen. 607 */ 608 final CompatModePackages mCompatModePackages; 609 610 /** 611 * Set of IntentSenderRecord objects that are currently active. 612 */ 613 final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords 614 = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>(); 615 616 /** 617 * Fingerprints (hashCode()) of stack traces that we've 618 * already logged DropBox entries for. Guarded by itself. If 619 * something (rogue user app) forces this over 620 * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared. 621 */ 622 private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>(); 623 private static final int MAX_DUP_SUPPRESSED_STACKS = 5000; 624 625 /** 626 * Strict Mode background batched logging state. 627 * 628 * The string buffer is guarded by itself, and its lock is also 629 * used to determine if another batched write is already 630 * in-flight. 631 */ 632 private final StringBuilder mStrictModeBuffer = new StringBuilder(); 633 634 /** 635 * Keeps track of all IIntentReceivers that have been registered for 636 * broadcasts. Hash keys are the receiver IBinder, hash value is 637 * a ReceiverList. 638 */ 639 final HashMap<IBinder, ReceiverList> mRegisteredReceivers = 640 new HashMap<IBinder, ReceiverList>(); 641 642 /** 643 * Resolver for broadcast intents to registered receivers. 644 * Holds BroadcastFilter (subclass of IntentFilter). 645 */ 646 final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver 647 = new IntentResolver<BroadcastFilter, BroadcastFilter>() { 648 @Override 649 protected boolean allowFilterResult( 650 BroadcastFilter filter, List<BroadcastFilter> dest) { 651 IBinder target = filter.receiverList.receiver.asBinder(); 652 for (int i=dest.size()-1; i>=0; i--) { 653 if (dest.get(i).receiverList.receiver.asBinder() == target) { 654 return false; 655 } 656 } 657 return true; 658 } 659 660 @Override 661 protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) { 662 if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL 663 || userId == filter.owningUserId) { 664 return super.newResult(filter, match, userId); 665 } 666 return null; 667 } 668 669 @Override 670 protected BroadcastFilter[] newArray(int size) { 671 return new BroadcastFilter[size]; 672 } 673 674 @Override 675 protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) { 676 return packageName.equals(filter.packageName); 677 } 678 }; 679 680 /** 681 * State of all active sticky broadcasts per user. Keys are the action of the 682 * sticky Intent, values are an ArrayList of all broadcasted intents with 683 * that action (which should usually be one). The SparseArray is keyed 684 * by the user ID the sticky is for, and can include UserHandle.USER_ALL 685 * for stickies that are sent to all users. 686 */ 687 final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts = 688 new SparseArray<ArrayMap<String, ArrayList<Intent>>>(); 689 690 final ActiveServices mServices; 691 692 /** 693 * Backup/restore process management 694 */ 695 String mBackupAppName = null; 696 BackupRecord mBackupTarget = null; 697 698 /** 699 * List of PendingThumbnailsRecord objects of clients who are still 700 * waiting to receive all of the thumbnails for a task. 701 */ 702 final ArrayList<PendingThumbnailsRecord> mPendingThumbnails = 703 new ArrayList<PendingThumbnailsRecord>(); 704 705 final ProviderMap mProviderMap; 706 707 /** 708 * List of content providers who have clients waiting for them. The 709 * application is currently being launched and the provider will be 710 * removed from this list once it is published. 711 */ 712 final ArrayList<ContentProviderRecord> mLaunchingProviders 713 = new ArrayList<ContentProviderRecord>(); 714 715 /** 716 * File storing persisted {@link #mGrantedUriPermissions}. 717 */ 718 private final AtomicFile mGrantFile; 719 720 /** XML constants used in {@link #mGrantFile} */ 721 private static final String TAG_URI_GRANTS = "uri-grants"; 722 private static final String TAG_URI_GRANT = "uri-grant"; 723 private static final String ATTR_USER_HANDLE = "userHandle"; 724 private static final String ATTR_SOURCE_PKG = "sourcePkg"; 725 private static final String ATTR_TARGET_PKG = "targetPkg"; 726 private static final String ATTR_URI = "uri"; 727 private static final String ATTR_MODE_FLAGS = "modeFlags"; 728 private static final String ATTR_CREATED_TIME = "createdTime"; 729 private static final String ATTR_PREFIX = "prefix"; 730 731 /** 732 * Global set of specific {@link Uri} permissions that have been granted. 733 * This optimized lookup structure maps from {@link UriPermission#targetUid} 734 * to {@link UriPermission#uri} to {@link UriPermission}. 735 */ 736 @GuardedBy("this") 737 private final SparseArray<ArrayMap<GrantUri, UriPermission>> 738 mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>(); 739 740 public static class GrantUri { 741 public final Uri uri; 742 public final boolean prefix; 743 744 public GrantUri(Uri uri, boolean prefix) { 745 this.uri = uri; 746 this.prefix = prefix; 747 } 748 749 @Override 750 public int hashCode() { 751 return toString().hashCode(); 752 } 753 754 @Override 755 public boolean equals(Object o) { 756 if (o instanceof GrantUri) { 757 GrantUri other = (GrantUri) o; 758 return uri.equals(other.uri) && prefix == other.prefix; 759 } 760 return false; 761 } 762 763 @Override 764 public String toString() { 765 if (prefix) { 766 return uri.toString() + " [prefix]"; 767 } else { 768 return uri.toString(); 769 } 770 } 771 } 772 773 CoreSettingsObserver mCoreSettingsObserver; 774 775 /** 776 * Thread-local storage used to carry caller permissions over through 777 * indirect content-provider access. 778 */ 779 private class Identity { 780 public int pid; 781 public int uid; 782 783 Identity(int _pid, int _uid) { 784 pid = _pid; 785 uid = _uid; 786 } 787 } 788 789 private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>(); 790 791 /** 792 * All information we have collected about the runtime performance of 793 * any user id that can impact battery performance. 794 */ 795 final BatteryStatsService mBatteryStatsService; 796 797 /** 798 * Information about component usage 799 */ 800 final UsageStatsService mUsageStatsService; 801 802 /** 803 * Information about and control over application operations 804 */ 805 final AppOpsService mAppOpsService; 806 807 /** 808 * Current configuration information. HistoryRecord objects are given 809 * a reference to this object to indicate which configuration they are 810 * currently running in, so this object must be kept immutable. 811 */ 812 Configuration mConfiguration = new Configuration(); 813 814 /** 815 * Current sequencing integer of the configuration, for skipping old 816 * configurations. 817 */ 818 int mConfigurationSeq = 0; 819 820 /** 821 * Hardware-reported OpenGLES version. 822 */ 823 final int GL_ES_VERSION; 824 825 /** 826 * List of initialization arguments to pass to all processes when binding applications to them. 827 * For example, references to the commonly used services. 828 */ 829 HashMap<String, IBinder> mAppBindArgs; 830 831 /** 832 * Temporary to avoid allocations. Protected by main lock. 833 */ 834 final StringBuilder mStringBuilder = new StringBuilder(256); 835 836 /** 837 * Used to control how we initialize the service. 838 */ 839 ComponentName mTopComponent; 840 String mTopAction = Intent.ACTION_MAIN; 841 String mTopData; 842 boolean mProcessesReady = false; 843 boolean mSystemReady = false; 844 boolean mBooting = false; 845 boolean mWaitingUpdate = false; 846 boolean mDidUpdate = false; 847 boolean mOnBattery = false; 848 boolean mLaunchWarningShown = false; 849 850 Context mContext; 851 852 int mFactoryTest; 853 854 boolean mCheckedForSetup; 855 856 /** 857 * The time at which we will allow normal application switches again, 858 * after a call to {@link #stopAppSwitches()}. 859 */ 860 long mAppSwitchesAllowedTime; 861 862 /** 863 * This is set to true after the first switch after mAppSwitchesAllowedTime 864 * is set; any switches after that will clear the time. 865 */ 866 boolean mDidAppSwitch; 867 868 /** 869 * Last time (in realtime) at which we checked for power usage. 870 */ 871 long mLastPowerCheckRealtime; 872 873 /** 874 * Last time (in uptime) at which we checked for power usage. 875 */ 876 long mLastPowerCheckUptime; 877 878 /** 879 * Set while we are wanting to sleep, to prevent any 880 * activities from being started/resumed. 881 */ 882 boolean mSleeping = false; 883 884 /** 885 * State of external calls telling us if the device is asleep. 886 */ 887 boolean mWentToSleep = false; 888 889 /** 890 * State of external call telling us if the lock screen is shown. 891 */ 892 boolean mLockScreenShown = false; 893 894 /** 895 * Set if we are shutting down the system, similar to sleeping. 896 */ 897 boolean mShuttingDown = false; 898 899 /** 900 * Current sequence id for oom_adj computation traversal. 901 */ 902 int mAdjSeq = 0; 903 904 /** 905 * Current sequence id for process LRU updating. 906 */ 907 int mLruSeq = 0; 908 909 /** 910 * Keep track of the non-cached/empty process we last found, to help 911 * determine how to distribute cached/empty processes next time. 912 */ 913 int mNumNonCachedProcs = 0; 914 915 /** 916 * Keep track of the number of cached hidden procs, to balance oom adj 917 * distribution between those and empty procs. 918 */ 919 int mNumCachedHiddenProcs = 0; 920 921 /** 922 * Keep track of the number of service processes we last found, to 923 * determine on the next iteration which should be B services. 924 */ 925 int mNumServiceProcs = 0; 926 int mNewNumAServiceProcs = 0; 927 int mNewNumServiceProcs = 0; 928 929 /** 930 * Allow the current computed overall memory level of the system to go down? 931 * This is set to false when we are killing processes for reasons other than 932 * memory management, so that the now smaller process list will not be taken as 933 * an indication that memory is tighter. 934 */ 935 boolean mAllowLowerMemLevel = false; 936 937 /** 938 * The last computed memory level, for holding when we are in a state that 939 * processes are going away for other reasons. 940 */ 941 int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL; 942 943 /** 944 * The last total number of process we have, to determine if changes actually look 945 * like a shrinking number of process due to lower RAM. 946 */ 947 int mLastNumProcesses; 948 949 /** 950 * The uptime of the last time we performed idle maintenance. 951 */ 952 long mLastIdleTime = SystemClock.uptimeMillis(); 953 954 /** 955 * Total time spent with RAM that has been added in the past since the last idle time. 956 */ 957 long mLowRamTimeSinceLastIdle = 0; 958 959 /** 960 * If RAM is currently low, when that horrible situation started. 961 */ 962 long mLowRamStartTime = 0; 963 964 /** 965 * For reporting to battery stats the current top application. 966 */ 967 private String mCurResumedPackage = null; 968 private int mCurResumedUid = -1; 969 970 /** 971 * For reporting to battery stats the apps currently running foreground 972 * service. The ProcessMap is package/uid tuples; each of these contain 973 * an array of the currently foreground processes. 974 */ 975 final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages 976 = new ProcessMap<ArrayList<ProcessRecord>>(); 977 978 /** 979 * This is set if we had to do a delayed dexopt of an app before launching 980 * it, to increasing the ANR timeouts in that case. 981 */ 982 boolean mDidDexOpt; 983 984 /** 985 * Set if the systemServer made a call to enterSafeMode. 986 */ 987 boolean mSafeMode; 988 989 String mDebugApp = null; 990 boolean mWaitForDebugger = false; 991 boolean mDebugTransient = false; 992 String mOrigDebugApp = null; 993 boolean mOrigWaitForDebugger = false; 994 boolean mAlwaysFinishActivities = false; 995 IActivityController mController = null; 996 String mProfileApp = null; 997 ProcessRecord mProfileProc = null; 998 String mProfileFile; 999 ParcelFileDescriptor mProfileFd; 1000 int mProfileType = 0; 1001 boolean mAutoStopProfiler = false; 1002 String mOpenGlTraceApp = null; 1003 1004 static class ProcessChangeItem { 1005 static final int CHANGE_ACTIVITIES = 1<<0; 1006 static final int CHANGE_IMPORTANCE= 1<<1; 1007 int changes; 1008 int uid; 1009 int pid; 1010 int importance; 1011 boolean foregroundActivities; 1012 } 1013 1014 final RemoteCallbackList<IProcessObserver> mProcessObservers 1015 = new RemoteCallbackList<IProcessObserver>(); 1016 ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5]; 1017 1018 final ArrayList<ProcessChangeItem> mPendingProcessChanges 1019 = new ArrayList<ProcessChangeItem>(); 1020 final ArrayList<ProcessChangeItem> mAvailProcessChanges 1021 = new ArrayList<ProcessChangeItem>(); 1022 1023 /** 1024 * Runtime CPU use collection thread. This object's lock is used to 1025 * protect all related state. 1026 */ 1027 final Thread mProcessCpuThread; 1028 1029 /** 1030 * Used to collect process stats when showing not responding dialog. 1031 * Protected by mProcessCpuThread. 1032 */ 1033 final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker( 1034 MONITOR_THREAD_CPU_USAGE); 1035 final AtomicLong mLastCpuTime = new AtomicLong(0); 1036 final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true); 1037 1038 long mLastWriteTime = 0; 1039 1040 /** 1041 * Used to retain an update lock when the foreground activity is in 1042 * immersive mode. 1043 */ 1044 final UpdateLock mUpdateLock = new UpdateLock("immersive"); 1045 1046 /** 1047 * Set to true after the system has finished booting. 1048 */ 1049 boolean mBooted = false; 1050 1051 int mProcessLimit = ProcessList.MAX_CACHED_APPS; 1052 int mProcessLimitOverride = -1; 1053 1054 WindowManagerService mWindowManager; 1055 1056 final ActivityThread mSystemThread; 1057 1058 int mCurrentUserId = 0; 1059 int[] mCurrentProfileIds = new int[] {UserHandle.USER_OWNER}; // Accessed by ActivityStack 1060 private UserManagerService mUserManager; 1061 1062 private final class AppDeathRecipient implements IBinder.DeathRecipient { 1063 final ProcessRecord mApp; 1064 final int mPid; 1065 final IApplicationThread mAppThread; 1066 1067 AppDeathRecipient(ProcessRecord app, int pid, 1068 IApplicationThread thread) { 1069 if (localLOGV) Slog.v( 1070 TAG, "New death recipient " + this 1071 + " for thread " + thread.asBinder()); 1072 mApp = app; 1073 mPid = pid; 1074 mAppThread = thread; 1075 } 1076 1077 @Override 1078 public void binderDied() { 1079 if (localLOGV) Slog.v( 1080 TAG, "Death received in " + this 1081 + " for thread " + mAppThread.asBinder()); 1082 synchronized(ActivityManagerService.this) { 1083 appDiedLocked(mApp, mPid, mAppThread); 1084 } 1085 } 1086 } 1087 1088 static final int SHOW_ERROR_MSG = 1; 1089 static final int SHOW_NOT_RESPONDING_MSG = 2; 1090 static final int SHOW_FACTORY_ERROR_MSG = 3; 1091 static final int UPDATE_CONFIGURATION_MSG = 4; 1092 static final int GC_BACKGROUND_PROCESSES_MSG = 5; 1093 static final int WAIT_FOR_DEBUGGER_MSG = 6; 1094 static final int SERVICE_TIMEOUT_MSG = 12; 1095 static final int UPDATE_TIME_ZONE = 13; 1096 static final int SHOW_UID_ERROR_MSG = 14; 1097 static final int IM_FEELING_LUCKY_MSG = 15; 1098 static final int PROC_START_TIMEOUT_MSG = 20; 1099 static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21; 1100 static final int KILL_APPLICATION_MSG = 22; 1101 static final int FINALIZE_PENDING_INTENT_MSG = 23; 1102 static final int POST_HEAVY_NOTIFICATION_MSG = 24; 1103 static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25; 1104 static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26; 1105 static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27; 1106 static final int CLEAR_DNS_CACHE_MSG = 28; 1107 static final int UPDATE_HTTP_PROXY_MSG = 29; 1108 static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30; 1109 static final int DISPATCH_PROCESSES_CHANGED = 31; 1110 static final int DISPATCH_PROCESS_DIED = 32; 1111 static final int REPORT_MEM_USAGE_MSG = 33; 1112 static final int REPORT_USER_SWITCH_MSG = 34; 1113 static final int CONTINUE_USER_SWITCH_MSG = 35; 1114 static final int USER_SWITCH_TIMEOUT_MSG = 36; 1115 static final int IMMERSIVE_MODE_LOCK_MSG = 37; 1116 static final int PERSIST_URI_GRANTS_MSG = 38; 1117 static final int REQUEST_ALL_PSS_MSG = 39; 1118 static final int START_PROFILES_MSG = 40; 1119 static final int UPDATE_TIME = 41; 1120 1121 static final int FIRST_ACTIVITY_STACK_MSG = 100; 1122 static final int FIRST_BROADCAST_QUEUE_MSG = 200; 1123 static final int FIRST_COMPAT_MODE_MSG = 300; 1124 static final int FIRST_SUPERVISOR_STACK_MSG = 100; 1125 1126 AlertDialog mUidAlert; 1127 CompatModeDialog mCompatModeDialog; 1128 long mLastMemUsageReportTime = 0; 1129 1130 /** 1131 * Flag whether the current user is a "monkey", i.e. whether 1132 * the UI is driven by a UI automation tool. 1133 */ 1134 private boolean mUserIsMonkey; 1135 1136 final ServiceThread mHandlerThread; 1137 final MainHandler mHandler; 1138 1139 final class MainHandler extends Handler { 1140 public MainHandler(Looper looper) { 1141 super(looper, null, true); 1142 } 1143 1144 @Override 1145 public void handleMessage(Message msg) { 1146 switch (msg.what) { 1147 case SHOW_ERROR_MSG: { 1148 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1149 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), 1150 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; 1151 synchronized (ActivityManagerService.this) { 1152 ProcessRecord proc = (ProcessRecord)data.get("app"); 1153 AppErrorResult res = (AppErrorResult) data.get("result"); 1154 if (proc != null && proc.crashDialog != null) { 1155 Slog.e(TAG, "App already has crash dialog: " + proc); 1156 if (res != null) { 1157 res.set(0); 1158 } 1159 return; 1160 } 1161 if (!showBackground && UserHandle.getAppId(proc.uid) 1162 >= Process.FIRST_APPLICATION_UID && proc.userId != mCurrentUserId 1163 && proc.pid != MY_PID) { 1164 Slog.w(TAG, "Skipping crash dialog of " + proc + ": background"); 1165 if (res != null) { 1166 res.set(0); 1167 } 1168 return; 1169 } 1170 if (mShowDialogs && !mSleeping && !mShuttingDown) { 1171 Dialog d = new AppErrorDialog(mContext, 1172 ActivityManagerService.this, res, proc); 1173 d.show(); 1174 proc.crashDialog = d; 1175 } else { 1176 // The device is asleep, so just pretend that the user 1177 // saw a crash dialog and hit "force quit". 1178 if (res != null) { 1179 res.set(0); 1180 } 1181 } 1182 } 1183 1184 ensureBootCompleted(); 1185 } break; 1186 case SHOW_NOT_RESPONDING_MSG: { 1187 synchronized (ActivityManagerService.this) { 1188 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1189 ProcessRecord proc = (ProcessRecord)data.get("app"); 1190 if (proc != null && proc.anrDialog != null) { 1191 Slog.e(TAG, "App already has anr dialog: " + proc); 1192 return; 1193 } 1194 1195 Intent intent = new Intent("android.intent.action.ANR"); 1196 if (!mProcessesReady) { 1197 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 1198 | Intent.FLAG_RECEIVER_FOREGROUND); 1199 } 1200 broadcastIntentLocked(null, null, intent, 1201 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 1202 false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */); 1203 1204 if (mShowDialogs) { 1205 Dialog d = new AppNotRespondingDialog(ActivityManagerService.this, 1206 mContext, proc, (ActivityRecord)data.get("activity"), 1207 msg.arg1 != 0); 1208 d.show(); 1209 proc.anrDialog = d; 1210 } else { 1211 // Just kill the app if there is no dialog to be shown. 1212 killAppAtUsersRequest(proc, null); 1213 } 1214 } 1215 1216 ensureBootCompleted(); 1217 } break; 1218 case SHOW_STRICT_MODE_VIOLATION_MSG: { 1219 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1220 synchronized (ActivityManagerService.this) { 1221 ProcessRecord proc = (ProcessRecord) data.get("app"); 1222 if (proc == null) { 1223 Slog.e(TAG, "App not found when showing strict mode dialog."); 1224 break; 1225 } 1226 if (proc.crashDialog != null) { 1227 Slog.e(TAG, "App already has strict mode dialog: " + proc); 1228 return; 1229 } 1230 AppErrorResult res = (AppErrorResult) data.get("result"); 1231 if (mShowDialogs && !mSleeping && !mShuttingDown) { 1232 Dialog d = new StrictModeViolationDialog(mContext, 1233 ActivityManagerService.this, res, proc); 1234 d.show(); 1235 proc.crashDialog = d; 1236 } else { 1237 // The device is asleep, so just pretend that the user 1238 // saw a crash dialog and hit "force quit". 1239 res.set(0); 1240 } 1241 } 1242 ensureBootCompleted(); 1243 } break; 1244 case SHOW_FACTORY_ERROR_MSG: { 1245 Dialog d = new FactoryErrorDialog( 1246 mContext, msg.getData().getCharSequence("msg")); 1247 d.show(); 1248 ensureBootCompleted(); 1249 } break; 1250 case UPDATE_CONFIGURATION_MSG: { 1251 final ContentResolver resolver = mContext.getContentResolver(); 1252 Settings.System.putConfiguration(resolver, (Configuration)msg.obj); 1253 } break; 1254 case GC_BACKGROUND_PROCESSES_MSG: { 1255 synchronized (ActivityManagerService.this) { 1256 performAppGcsIfAppropriateLocked(); 1257 } 1258 } break; 1259 case WAIT_FOR_DEBUGGER_MSG: { 1260 synchronized (ActivityManagerService.this) { 1261 ProcessRecord app = (ProcessRecord)msg.obj; 1262 if (msg.arg1 != 0) { 1263 if (!app.waitedForDebugger) { 1264 Dialog d = new AppWaitingForDebuggerDialog( 1265 ActivityManagerService.this, 1266 mContext, app); 1267 app.waitDialog = d; 1268 app.waitedForDebugger = true; 1269 d.show(); 1270 } 1271 } else { 1272 if (app.waitDialog != null) { 1273 app.waitDialog.dismiss(); 1274 app.waitDialog = null; 1275 } 1276 } 1277 } 1278 } break; 1279 case SERVICE_TIMEOUT_MSG: { 1280 if (mDidDexOpt) { 1281 mDidDexOpt = false; 1282 Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG); 1283 nmsg.obj = msg.obj; 1284 mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT); 1285 return; 1286 } 1287 mServices.serviceTimeout((ProcessRecord)msg.obj); 1288 } break; 1289 case UPDATE_TIME_ZONE: { 1290 synchronized (ActivityManagerService.this) { 1291 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1292 ProcessRecord r = mLruProcesses.get(i); 1293 if (r.thread != null) { 1294 try { 1295 r.thread.updateTimeZone(); 1296 } catch (RemoteException ex) { 1297 Slog.w(TAG, "Failed to update time zone for: " + r.info.processName); 1298 } 1299 } 1300 } 1301 } 1302 } break; 1303 case CLEAR_DNS_CACHE_MSG: { 1304 synchronized (ActivityManagerService.this) { 1305 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1306 ProcessRecord r = mLruProcesses.get(i); 1307 if (r.thread != null) { 1308 try { 1309 r.thread.clearDnsCache(); 1310 } catch (RemoteException ex) { 1311 Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName); 1312 } 1313 } 1314 } 1315 } 1316 } break; 1317 case UPDATE_HTTP_PROXY_MSG: { 1318 ProxyProperties proxy = (ProxyProperties)msg.obj; 1319 String host = ""; 1320 String port = ""; 1321 String exclList = ""; 1322 String pacFileUrl = null; 1323 if (proxy != null) { 1324 host = proxy.getHost(); 1325 port = Integer.toString(proxy.getPort()); 1326 exclList = proxy.getExclusionList(); 1327 pacFileUrl = proxy.getPacFileUrl(); 1328 } 1329 synchronized (ActivityManagerService.this) { 1330 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1331 ProcessRecord r = mLruProcesses.get(i); 1332 if (r.thread != null) { 1333 try { 1334 r.thread.setHttpProxy(host, port, exclList, pacFileUrl); 1335 } catch (RemoteException ex) { 1336 Slog.w(TAG, "Failed to update http proxy for: " + 1337 r.info.processName); 1338 } 1339 } 1340 } 1341 } 1342 } break; 1343 case SHOW_UID_ERROR_MSG: { 1344 String title = "System UIDs Inconsistent"; 1345 String text = "UIDs on the system are inconsistent, you need to wipe your" 1346 + " data partition or your device will be unstable."; 1347 Log.e(TAG, title + ": " + text); 1348 if (mShowDialogs) { 1349 // XXX This is a temporary dialog, no need to localize. 1350 AlertDialog d = new BaseErrorDialog(mContext); 1351 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR); 1352 d.setCancelable(false); 1353 d.setTitle(title); 1354 d.setMessage(text); 1355 d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky", 1356 mHandler.obtainMessage(IM_FEELING_LUCKY_MSG)); 1357 mUidAlert = d; 1358 d.show(); 1359 } 1360 } break; 1361 case IM_FEELING_LUCKY_MSG: { 1362 if (mUidAlert != null) { 1363 mUidAlert.dismiss(); 1364 mUidAlert = null; 1365 } 1366 } break; 1367 case PROC_START_TIMEOUT_MSG: { 1368 if (mDidDexOpt) { 1369 mDidDexOpt = false; 1370 Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 1371 nmsg.obj = msg.obj; 1372 mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT); 1373 return; 1374 } 1375 ProcessRecord app = (ProcessRecord)msg.obj; 1376 synchronized (ActivityManagerService.this) { 1377 processStartTimedOutLocked(app); 1378 } 1379 } break; 1380 case DO_PENDING_ACTIVITY_LAUNCHES_MSG: { 1381 synchronized (ActivityManagerService.this) { 1382 doPendingActivityLaunchesLocked(true); 1383 } 1384 } break; 1385 case KILL_APPLICATION_MSG: { 1386 synchronized (ActivityManagerService.this) { 1387 int appid = msg.arg1; 1388 boolean restart = (msg.arg2 == 1); 1389 Bundle bundle = (Bundle)msg.obj; 1390 String pkg = bundle.getString("pkg"); 1391 String reason = bundle.getString("reason"); 1392 forceStopPackageLocked(pkg, appid, restart, false, true, false, 1393 false, UserHandle.USER_ALL, reason); 1394 } 1395 } break; 1396 case FINALIZE_PENDING_INTENT_MSG: { 1397 ((PendingIntentRecord)msg.obj).completeFinalize(); 1398 } break; 1399 case POST_HEAVY_NOTIFICATION_MSG: { 1400 INotificationManager inm = NotificationManager.getService(); 1401 if (inm == null) { 1402 return; 1403 } 1404 1405 ActivityRecord root = (ActivityRecord)msg.obj; 1406 ProcessRecord process = root.app; 1407 if (process == null) { 1408 return; 1409 } 1410 1411 try { 1412 Context context = mContext.createPackageContext(process.info.packageName, 0); 1413 String text = mContext.getString(R.string.heavy_weight_notification, 1414 context.getApplicationInfo().loadLabel(context.getPackageManager())); 1415 Notification notification = new Notification(); 1416 notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon; 1417 notification.when = 0; 1418 notification.flags = Notification.FLAG_ONGOING_EVENT; 1419 notification.tickerText = text; 1420 notification.defaults = 0; // please be quiet 1421 notification.sound = null; 1422 notification.vibrate = null; 1423 notification.setLatestEventInfo(context, text, 1424 mContext.getText(R.string.heavy_weight_notification_detail), 1425 PendingIntent.getActivityAsUser(mContext, 0, root.intent, 1426 PendingIntent.FLAG_CANCEL_CURRENT, null, 1427 new UserHandle(root.userId))); 1428 1429 try { 1430 int[] outId = new int[1]; 1431 inm.enqueueNotificationWithTag("android", "android", null, 1432 R.string.heavy_weight_notification, 1433 notification, outId, root.userId); 1434 } catch (RuntimeException e) { 1435 Slog.w(ActivityManagerService.TAG, 1436 "Error showing notification for heavy-weight app", e); 1437 } catch (RemoteException e) { 1438 } 1439 } catch (NameNotFoundException e) { 1440 Slog.w(TAG, "Unable to create context for heavy notification", e); 1441 } 1442 } break; 1443 case CANCEL_HEAVY_NOTIFICATION_MSG: { 1444 INotificationManager inm = NotificationManager.getService(); 1445 if (inm == null) { 1446 return; 1447 } 1448 try { 1449 inm.cancelNotificationWithTag("android", null, 1450 R.string.heavy_weight_notification, msg.arg1); 1451 } catch (RuntimeException e) { 1452 Slog.w(ActivityManagerService.TAG, 1453 "Error canceling notification for service", e); 1454 } catch (RemoteException e) { 1455 } 1456 } break; 1457 case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: { 1458 synchronized (ActivityManagerService.this) { 1459 checkExcessivePowerUsageLocked(true); 1460 removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1461 Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1462 sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 1463 } 1464 } break; 1465 case SHOW_COMPAT_MODE_DIALOG_MSG: { 1466 synchronized (ActivityManagerService.this) { 1467 ActivityRecord ar = (ActivityRecord)msg.obj; 1468 if (mCompatModeDialog != null) { 1469 if (mCompatModeDialog.mAppInfo.packageName.equals( 1470 ar.info.applicationInfo.packageName)) { 1471 return; 1472 } 1473 mCompatModeDialog.dismiss(); 1474 mCompatModeDialog = null; 1475 } 1476 if (ar != null && false) { 1477 if (mCompatModePackages.getPackageAskCompatModeLocked( 1478 ar.packageName)) { 1479 int mode = mCompatModePackages.computeCompatModeLocked( 1480 ar.info.applicationInfo); 1481 if (mode == ActivityManager.COMPAT_MODE_DISABLED 1482 || mode == ActivityManager.COMPAT_MODE_ENABLED) { 1483 mCompatModeDialog = new CompatModeDialog( 1484 ActivityManagerService.this, mContext, 1485 ar.info.applicationInfo); 1486 mCompatModeDialog.show(); 1487 } 1488 } 1489 } 1490 } 1491 break; 1492 } 1493 case DISPATCH_PROCESSES_CHANGED: { 1494 dispatchProcessesChanged(); 1495 break; 1496 } 1497 case DISPATCH_PROCESS_DIED: { 1498 final int pid = msg.arg1; 1499 final int uid = msg.arg2; 1500 dispatchProcessDied(pid, uid); 1501 break; 1502 } 1503 case REPORT_MEM_USAGE_MSG: { 1504 final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj; 1505 Thread thread = new Thread() { 1506 @Override public void run() { 1507 final SparseArray<ProcessMemInfo> infoMap 1508 = new SparseArray<ProcessMemInfo>(memInfos.size()); 1509 for (int i=0, N=memInfos.size(); i<N; i++) { 1510 ProcessMemInfo mi = memInfos.get(i); 1511 infoMap.put(mi.pid, mi); 1512 } 1513 updateCpuStatsNow(); 1514 synchronized (mProcessCpuThread) { 1515 final int N = mProcessCpuTracker.countStats(); 1516 for (int i=0; i<N; i++) { 1517 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 1518 if (st.vsize > 0) { 1519 long pss = Debug.getPss(st.pid, null); 1520 if (pss > 0) { 1521 if (infoMap.indexOfKey(st.pid) < 0) { 1522 ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid, 1523 ProcessList.NATIVE_ADJ, -1, "native", null); 1524 mi.pss = pss; 1525 memInfos.add(mi); 1526 } 1527 } 1528 } 1529 } 1530 } 1531 1532 long totalPss = 0; 1533 for (int i=0, N=memInfos.size(); i<N; i++) { 1534 ProcessMemInfo mi = memInfos.get(i); 1535 if (mi.pss == 0) { 1536 mi.pss = Debug.getPss(mi.pid, null); 1537 } 1538 totalPss += mi.pss; 1539 } 1540 Collections.sort(memInfos, new Comparator<ProcessMemInfo>() { 1541 @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) { 1542 if (lhs.oomAdj != rhs.oomAdj) { 1543 return lhs.oomAdj < rhs.oomAdj ? -1 : 1; 1544 } 1545 if (lhs.pss != rhs.pss) { 1546 return lhs.pss < rhs.pss ? 1 : -1; 1547 } 1548 return 0; 1549 } 1550 }); 1551 1552 StringBuilder tag = new StringBuilder(128); 1553 StringBuilder stack = new StringBuilder(128); 1554 tag.append("Low on memory -- "); 1555 appendMemBucket(tag, totalPss, "total", false); 1556 appendMemBucket(stack, totalPss, "total", true); 1557 1558 StringBuilder logBuilder = new StringBuilder(1024); 1559 logBuilder.append("Low on memory:\n"); 1560 1561 boolean firstLine = true; 1562 int lastOomAdj = Integer.MIN_VALUE; 1563 for (int i=0, N=memInfos.size(); i<N; i++) { 1564 ProcessMemInfo mi = memInfos.get(i); 1565 1566 if (mi.oomAdj != ProcessList.NATIVE_ADJ 1567 && (mi.oomAdj < ProcessList.SERVICE_ADJ 1568 || mi.oomAdj == ProcessList.HOME_APP_ADJ 1569 || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) { 1570 if (lastOomAdj != mi.oomAdj) { 1571 lastOomAdj = mi.oomAdj; 1572 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) { 1573 tag.append(" / "); 1574 } 1575 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) { 1576 if (firstLine) { 1577 stack.append(":"); 1578 firstLine = false; 1579 } 1580 stack.append("\n\t at "); 1581 } else { 1582 stack.append("$"); 1583 } 1584 } else { 1585 tag.append(" "); 1586 stack.append("$"); 1587 } 1588 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) { 1589 appendMemBucket(tag, mi.pss, mi.name, false); 1590 } 1591 appendMemBucket(stack, mi.pss, mi.name, true); 1592 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ 1593 && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) { 1594 stack.append("("); 1595 for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) { 1596 if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) { 1597 stack.append(DUMP_MEM_OOM_LABEL[k]); 1598 stack.append(":"); 1599 stack.append(DUMP_MEM_OOM_ADJ[k]); 1600 } 1601 } 1602 stack.append(")"); 1603 } 1604 } 1605 1606 logBuilder.append(" "); 1607 logBuilder.append(ProcessList.makeOomAdjString(mi.oomAdj)); 1608 logBuilder.append(' '); 1609 logBuilder.append(ProcessList.makeProcStateString(mi.procState)); 1610 logBuilder.append(' '); 1611 ProcessList.appendRamKb(logBuilder, mi.pss); 1612 logBuilder.append(" kB: "); 1613 logBuilder.append(mi.name); 1614 logBuilder.append(" ("); 1615 logBuilder.append(mi.pid); 1616 logBuilder.append(") "); 1617 logBuilder.append(mi.adjType); 1618 logBuilder.append('\n'); 1619 if (mi.adjReason != null) { 1620 logBuilder.append(" "); 1621 logBuilder.append(mi.adjReason); 1622 logBuilder.append('\n'); 1623 } 1624 } 1625 1626 logBuilder.append(" "); 1627 ProcessList.appendRamKb(logBuilder, totalPss); 1628 logBuilder.append(" kB: TOTAL\n"); 1629 1630 long[] infos = new long[Debug.MEMINFO_COUNT]; 1631 Debug.getMemInfo(infos); 1632 logBuilder.append(" MemInfo: "); 1633 logBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, "); 1634 logBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, "); 1635 logBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, "); 1636 logBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, "); 1637 logBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n"); 1638 if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) { 1639 logBuilder.append(" ZRAM: "); 1640 logBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]); 1641 logBuilder.append(" kB RAM, "); 1642 logBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]); 1643 logBuilder.append(" kB swap total, "); 1644 logBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]); 1645 logBuilder.append(" kB swap free\n"); 1646 } 1647 Slog.i(TAG, logBuilder.toString()); 1648 1649 StringBuilder dropBuilder = new StringBuilder(1024); 1650 /* 1651 StringWriter oomSw = new StringWriter(); 1652 PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256); 1653 StringWriter catSw = new StringWriter(); 1654 PrintWriter catPw = new FastPrintWriter(catSw, false, 256); 1655 String[] emptyArgs = new String[] { }; 1656 dumpApplicationMemoryUsage(null, oomPw, " ", emptyArgs, true, catPw); 1657 oomPw.flush(); 1658 String oomString = oomSw.toString(); 1659 */ 1660 dropBuilder.append(stack); 1661 dropBuilder.append('\n'); 1662 dropBuilder.append('\n'); 1663 dropBuilder.append(logBuilder); 1664 dropBuilder.append('\n'); 1665 /* 1666 dropBuilder.append(oomString); 1667 dropBuilder.append('\n'); 1668 */ 1669 StringWriter catSw = new StringWriter(); 1670 synchronized (ActivityManagerService.this) { 1671 PrintWriter catPw = new FastPrintWriter(catSw, false, 256); 1672 String[] emptyArgs = new String[] { }; 1673 catPw.println(); 1674 dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null); 1675 catPw.println(); 1676 mServices.dumpServicesLocked(null, catPw, emptyArgs, 0, 1677 false, false, null); 1678 catPw.println(); 1679 dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null); 1680 catPw.flush(); 1681 } 1682 dropBuilder.append(catSw.toString()); 1683 addErrorToDropBox("lowmem", null, "system_server", null, 1684 null, tag.toString(), dropBuilder.toString(), null, null); 1685 //Slog.i(TAG, "Sent to dropbox:"); 1686 //Slog.i(TAG, dropBuilder.toString()); 1687 synchronized (ActivityManagerService.this) { 1688 long now = SystemClock.uptimeMillis(); 1689 if (mLastMemUsageReportTime < now) { 1690 mLastMemUsageReportTime = now; 1691 } 1692 } 1693 } 1694 }; 1695 thread.start(); 1696 break; 1697 } 1698 case REPORT_USER_SWITCH_MSG: { 1699 dispatchUserSwitch((UserStartedState)msg.obj, msg.arg1, msg.arg2); 1700 break; 1701 } 1702 case CONTINUE_USER_SWITCH_MSG: { 1703 continueUserSwitch((UserStartedState)msg.obj, msg.arg1, msg.arg2); 1704 break; 1705 } 1706 case USER_SWITCH_TIMEOUT_MSG: { 1707 timeoutUserSwitch((UserStartedState)msg.obj, msg.arg1, msg.arg2); 1708 break; 1709 } 1710 case IMMERSIVE_MODE_LOCK_MSG: { 1711 final boolean nextState = (msg.arg1 != 0); 1712 if (mUpdateLock.isHeld() != nextState) { 1713 if (DEBUG_IMMERSIVE) { 1714 final ActivityRecord r = (ActivityRecord) msg.obj; 1715 Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r); 1716 } 1717 if (nextState) { 1718 mUpdateLock.acquire(); 1719 } else { 1720 mUpdateLock.release(); 1721 } 1722 } 1723 break; 1724 } 1725 case PERSIST_URI_GRANTS_MSG: { 1726 writeGrantedUriPermissions(); 1727 break; 1728 } 1729 case REQUEST_ALL_PSS_MSG: { 1730 requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false); 1731 break; 1732 } 1733 case START_PROFILES_MSG: { 1734 synchronized (ActivityManagerService.this) { 1735 startProfilesLocked(); 1736 } 1737 break; 1738 } 1739 case UPDATE_TIME: { 1740 synchronized (ActivityManagerService.this) { 1741 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1742 ProcessRecord r = mLruProcesses.get(i); 1743 if (r.thread != null) { 1744 try { 1745 r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true); 1746 } catch (RemoteException ex) { 1747 Slog.w(TAG, "Failed to update preferences for: " + r.info.processName); 1748 } 1749 } 1750 } 1751 } 1752 break; 1753 } 1754 } 1755 } 1756 }; 1757 1758 static final int COLLECT_PSS_BG_MSG = 1; 1759 1760 final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) { 1761 @Override 1762 public void handleMessage(Message msg) { 1763 switch (msg.what) { 1764 case COLLECT_PSS_BG_MSG: { 1765 int i=0, num=0; 1766 long start = SystemClock.uptimeMillis(); 1767 long[] tmp = new long[1]; 1768 do { 1769 ProcessRecord proc; 1770 int procState; 1771 int pid; 1772 synchronized (ActivityManagerService.this) { 1773 if (i >= mPendingPssProcesses.size()) { 1774 if (DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num + " of " + i 1775 + " processes in " + (SystemClock.uptimeMillis()-start) + "ms"); 1776 mPendingPssProcesses.clear(); 1777 return; 1778 } 1779 proc = mPendingPssProcesses.get(i); 1780 procState = proc.pssProcState; 1781 if (proc.thread != null && procState == proc.setProcState) { 1782 pid = proc.pid; 1783 } else { 1784 proc = null; 1785 pid = 0; 1786 } 1787 i++; 1788 } 1789 if (proc != null) { 1790 long pss = Debug.getPss(pid, tmp); 1791 synchronized (ActivityManagerService.this) { 1792 if (proc.thread != null && proc.setProcState == procState 1793 && proc.pid == pid) { 1794 num++; 1795 proc.lastPssTime = SystemClock.uptimeMillis(); 1796 proc.baseProcessTracker.addPss(pss, tmp[0], true, proc.pkgList); 1797 if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString() 1798 + ": " + pss + " lastPss=" + proc.lastPss 1799 + " state=" + ProcessList.makeProcStateString(procState)); 1800 if (proc.initialIdlePss == 0) { 1801 proc.initialIdlePss = pss; 1802 } 1803 proc.lastPss = pss; 1804 if (procState >= ActivityManager.PROCESS_STATE_HOME) { 1805 proc.lastCachedPss = pss; 1806 } 1807 } 1808 } 1809 } 1810 } while (true); 1811 } 1812 } 1813 } 1814 }; 1815 1816 public void setSystemProcess() { 1817 try { 1818 ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true); 1819 ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats); 1820 ServiceManager.addService("meminfo", new MemBinder(this)); 1821 ServiceManager.addService("gfxinfo", new GraphicsBinder(this)); 1822 ServiceManager.addService("dbinfo", new DbBinder(this)); 1823 if (MONITOR_CPU_USAGE) { 1824 ServiceManager.addService("cpuinfo", new CpuBinder(this)); 1825 } 1826 ServiceManager.addService("permission", new PermissionController(this)); 1827 1828 ApplicationInfo info = mContext.getPackageManager().getApplicationInfo( 1829 "android", STOCK_PM_FLAGS); 1830 mSystemThread.installSystemApplicationInfo(info); 1831 1832 synchronized (this) { 1833 ProcessRecord app = newProcessRecordLocked(info, info.processName, false); 1834 app.persistent = true; 1835 app.pid = MY_PID; 1836 app.maxAdj = ProcessList.SYSTEM_ADJ; 1837 app.makeActive(mSystemThread.getApplicationThread(), mProcessStats); 1838 mProcessNames.put(app.processName, app.uid, app); 1839 synchronized (mPidsSelfLocked) { 1840 mPidsSelfLocked.put(app.pid, app); 1841 } 1842 updateLruProcessLocked(app, false, null); 1843 updateOomAdjLocked(); 1844 } 1845 } catch (PackageManager.NameNotFoundException e) { 1846 throw new RuntimeException( 1847 "Unable to find android system package", e); 1848 } 1849 } 1850 1851 public void setWindowManager(WindowManagerService wm) { 1852 mWindowManager = wm; 1853 mStackSupervisor.setWindowManager(wm); 1854 } 1855 1856 public void startObservingNativeCrashes() { 1857 final NativeCrashListener ncl = new NativeCrashListener(this); 1858 ncl.start(); 1859 } 1860 1861 public IAppOpsService getAppOpsService() { 1862 return mAppOpsService; 1863 } 1864 1865 static class MemBinder extends Binder { 1866 ActivityManagerService mActivityManagerService; 1867 MemBinder(ActivityManagerService activityManagerService) { 1868 mActivityManagerService = activityManagerService; 1869 } 1870 1871 @Override 1872 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1873 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1874 != PackageManager.PERMISSION_GRANTED) { 1875 pw.println("Permission Denial: can't dump meminfo from from pid=" 1876 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1877 + " without permission " + android.Manifest.permission.DUMP); 1878 return; 1879 } 1880 1881 mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, " ", args, false, null); 1882 } 1883 } 1884 1885 static class GraphicsBinder extends Binder { 1886 ActivityManagerService mActivityManagerService; 1887 GraphicsBinder(ActivityManagerService activityManagerService) { 1888 mActivityManagerService = activityManagerService; 1889 } 1890 1891 @Override 1892 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1893 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1894 != PackageManager.PERMISSION_GRANTED) { 1895 pw.println("Permission Denial: can't dump gfxinfo from from pid=" 1896 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1897 + " without permission " + android.Manifest.permission.DUMP); 1898 return; 1899 } 1900 1901 mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args); 1902 } 1903 } 1904 1905 static class DbBinder extends Binder { 1906 ActivityManagerService mActivityManagerService; 1907 DbBinder(ActivityManagerService activityManagerService) { 1908 mActivityManagerService = activityManagerService; 1909 } 1910 1911 @Override 1912 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1913 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1914 != PackageManager.PERMISSION_GRANTED) { 1915 pw.println("Permission Denial: can't dump dbinfo from from pid=" 1916 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1917 + " without permission " + android.Manifest.permission.DUMP); 1918 return; 1919 } 1920 1921 mActivityManagerService.dumpDbInfo(fd, pw, args); 1922 } 1923 } 1924 1925 static class CpuBinder extends Binder { 1926 ActivityManagerService mActivityManagerService; 1927 CpuBinder(ActivityManagerService activityManagerService) { 1928 mActivityManagerService = activityManagerService; 1929 } 1930 1931 @Override 1932 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1933 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1934 != PackageManager.PERMISSION_GRANTED) { 1935 pw.println("Permission Denial: can't dump cpuinfo from from pid=" 1936 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1937 + " without permission " + android.Manifest.permission.DUMP); 1938 return; 1939 } 1940 1941 synchronized (mActivityManagerService.mProcessCpuThread) { 1942 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad()); 1943 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState( 1944 SystemClock.uptimeMillis())); 1945 } 1946 } 1947 } 1948 1949 public static final class Lifecycle extends SystemService { 1950 private final ActivityManagerService mService; 1951 1952 public Lifecycle(Context context) { 1953 super(context); 1954 mService = new ActivityManagerService(context); 1955 } 1956 1957 @Override 1958 public void onStart() { 1959 mService.start(); 1960 } 1961 1962 public ActivityManagerService getService() { 1963 return mService; 1964 } 1965 } 1966 1967 // Note: This method is invoked on the main thread but may need to attach various 1968 // handlers to other threads. So take care to be explicit about the looper. 1969 public ActivityManagerService(Context systemContext) { 1970 mContext = systemContext; 1971 mFactoryTest = FactoryTest.getMode(); 1972 mSystemThread = ActivityThread.currentActivityThread(); 1973 1974 Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass()); 1975 1976 mHandlerThread = new ServiceThread(TAG, 1977 android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/); 1978 mHandlerThread.start(); 1979 mHandler = new MainHandler(mHandlerThread.getLooper()); 1980 1981 mFgBroadcastQueue = new BroadcastQueue(this, mHandler, 1982 "foreground", BROADCAST_FG_TIMEOUT, false); 1983 mBgBroadcastQueue = new BroadcastQueue(this, mHandler, 1984 "background", BROADCAST_BG_TIMEOUT, true); 1985 mBroadcastQueues[0] = mFgBroadcastQueue; 1986 mBroadcastQueues[1] = mBgBroadcastQueue; 1987 1988 mServices = new ActiveServices(this); 1989 mProviderMap = new ProviderMap(this); 1990 1991 // TODO: Move creation of battery stats service outside of activity manager service. 1992 File dataDir = Environment.getDataDirectory(); 1993 File systemDir = new File(dataDir, "system"); 1994 systemDir.mkdirs(); 1995 mBatteryStatsService = new BatteryStatsService(new File( 1996 systemDir, "batterystats.bin").toString(), mHandler); 1997 mBatteryStatsService.getActiveStatistics().readLocked(); 1998 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 1999 mOnBattery = DEBUG_POWER ? true 2000 : mBatteryStatsService.getActiveStatistics().getIsOnBattery(); 2001 mBatteryStatsService.getActiveStatistics().setCallback(this); 2002 2003 mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats")); 2004 2005 mUsageStatsService = new UsageStatsService(new File(systemDir, "usagestats").toString()); 2006 mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler); 2007 2008 mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml")); 2009 2010 // User 0 is the first and only user that runs at boot. 2011 mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true)); 2012 mUserLru.add(Integer.valueOf(0)); 2013 updateStartedUserArrayLocked(); 2014 2015 GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version", 2016 ConfigurationInfo.GL_ES_VERSION_UNDEFINED); 2017 2018 mConfiguration.setToDefaults(); 2019 mConfiguration.setLocale(Locale.getDefault()); 2020 2021 mConfigurationSeq = mConfiguration.seq = 1; 2022 mProcessCpuTracker.init(); 2023 2024 mCompatModePackages = new CompatModePackages(this, systemDir, mHandler); 2025 mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler); 2026 mStackSupervisor = new ActivityStackSupervisor(this); 2027 2028 mProcessCpuThread = new Thread("CpuTracker") { 2029 @Override 2030 public void run() { 2031 while (true) { 2032 try { 2033 try { 2034 synchronized(this) { 2035 final long now = SystemClock.uptimeMillis(); 2036 long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now; 2037 long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now; 2038 //Slog.i(TAG, "Cpu delay=" + nextCpuDelay 2039 // + ", write delay=" + nextWriteDelay); 2040 if (nextWriteDelay < nextCpuDelay) { 2041 nextCpuDelay = nextWriteDelay; 2042 } 2043 if (nextCpuDelay > 0) { 2044 mProcessCpuMutexFree.set(true); 2045 this.wait(nextCpuDelay); 2046 } 2047 } 2048 } catch (InterruptedException e) { 2049 } 2050 updateCpuStatsNow(); 2051 } catch (Exception e) { 2052 Slog.e(TAG, "Unexpected exception collecting process stats", e); 2053 } 2054 } 2055 } 2056 }; 2057 2058 Watchdog.getInstance().addMonitor(this); 2059 Watchdog.getInstance().addThread(mHandler); 2060 } 2061 2062 private void start() { 2063 mProcessCpuThread.start(); 2064 2065 mBatteryStatsService.publish(mContext); 2066 mUsageStatsService.publish(mContext); 2067 mAppOpsService.publish(mContext); 2068 2069 LocalServices.addService(ActivityManagerInternal.class, new LocalService()); 2070 } 2071 2072 @Override 2073 public boolean onTransact(int code, Parcel data, Parcel reply, int flags) 2074 throws RemoteException { 2075 if (code == SYSPROPS_TRANSACTION) { 2076 // We need to tell all apps about the system property change. 2077 ArrayList<IBinder> procs = new ArrayList<IBinder>(); 2078 synchronized(this) { 2079 final int NP = mProcessNames.getMap().size(); 2080 for (int ip=0; ip<NP; ip++) { 2081 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 2082 final int NA = apps.size(); 2083 for (int ia=0; ia<NA; ia++) { 2084 ProcessRecord app = apps.valueAt(ia); 2085 if (app.thread != null) { 2086 procs.add(app.thread.asBinder()); 2087 } 2088 } 2089 } 2090 } 2091 2092 int N = procs.size(); 2093 for (int i=0; i<N; i++) { 2094 Parcel data2 = Parcel.obtain(); 2095 try { 2096 procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0); 2097 } catch (RemoteException e) { 2098 } 2099 data2.recycle(); 2100 } 2101 } 2102 try { 2103 return super.onTransact(code, data, reply, flags); 2104 } catch (RuntimeException e) { 2105 // The activity manager only throws security exceptions, so let's 2106 // log all others. 2107 if (!(e instanceof SecurityException)) { 2108 Slog.wtf(TAG, "Activity Manager Crash", e); 2109 } 2110 throw e; 2111 } 2112 } 2113 2114 void updateCpuStats() { 2115 final long now = SystemClock.uptimeMillis(); 2116 if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) { 2117 return; 2118 } 2119 if (mProcessCpuMutexFree.compareAndSet(true, false)) { 2120 synchronized (mProcessCpuThread) { 2121 mProcessCpuThread.notify(); 2122 } 2123 } 2124 } 2125 2126 void updateCpuStatsNow() { 2127 synchronized (mProcessCpuThread) { 2128 mProcessCpuMutexFree.set(false); 2129 final long now = SystemClock.uptimeMillis(); 2130 boolean haveNewCpuStats = false; 2131 2132 if (MONITOR_CPU_USAGE && 2133 mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) { 2134 mLastCpuTime.set(now); 2135 haveNewCpuStats = true; 2136 mProcessCpuTracker.update(); 2137 //Slog.i(TAG, mProcessCpu.printCurrentState()); 2138 //Slog.i(TAG, "Total CPU usage: " 2139 // + mProcessCpu.getTotalCpuPercent() + "%"); 2140 2141 // Slog the cpu usage if the property is set. 2142 if ("true".equals(SystemProperties.get("events.cpu"))) { 2143 int user = mProcessCpuTracker.getLastUserTime(); 2144 int system = mProcessCpuTracker.getLastSystemTime(); 2145 int iowait = mProcessCpuTracker.getLastIoWaitTime(); 2146 int irq = mProcessCpuTracker.getLastIrqTime(); 2147 int softIrq = mProcessCpuTracker.getLastSoftIrqTime(); 2148 int idle = mProcessCpuTracker.getLastIdleTime(); 2149 2150 int total = user + system + iowait + irq + softIrq + idle; 2151 if (total == 0) total = 1; 2152 2153 EventLog.writeEvent(EventLogTags.CPU, 2154 ((user+system+iowait+irq+softIrq) * 100) / total, 2155 (user * 100) / total, 2156 (system * 100) / total, 2157 (iowait * 100) / total, 2158 (irq * 100) / total, 2159 (softIrq * 100) / total); 2160 } 2161 } 2162 2163 long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes(); 2164 final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics(); 2165 synchronized(bstats) { 2166 synchronized(mPidsSelfLocked) { 2167 if (haveNewCpuStats) { 2168 if (mOnBattery) { 2169 int perc = bstats.startAddingCpuLocked(); 2170 int totalUTime = 0; 2171 int totalSTime = 0; 2172 final int N = mProcessCpuTracker.countStats(); 2173 for (int i=0; i<N; i++) { 2174 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 2175 if (!st.working) { 2176 continue; 2177 } 2178 ProcessRecord pr = mPidsSelfLocked.get(st.pid); 2179 int otherUTime = (st.rel_utime*perc)/100; 2180 int otherSTime = (st.rel_stime*perc)/100; 2181 totalUTime += otherUTime; 2182 totalSTime += otherSTime; 2183 if (pr != null) { 2184 BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats; 2185 if (ps == null || !ps.isActive()) { 2186 pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked( 2187 pr.info.uid, pr.processName); 2188 } 2189 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 2190 st.rel_stime-otherSTime); 2191 ps.addSpeedStepTimes(cpuSpeedTimes); 2192 pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10; 2193 } else { 2194 BatteryStatsImpl.Uid.Proc ps = st.batteryStats; 2195 if (ps == null || !ps.isActive()) { 2196 st.batteryStats = ps = bstats.getProcessStatsLocked( 2197 bstats.mapUid(st.uid), st.name); 2198 } 2199 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 2200 st.rel_stime-otherSTime); 2201 ps.addSpeedStepTimes(cpuSpeedTimes); 2202 } 2203 } 2204 bstats.finishAddingCpuLocked(perc, totalUTime, 2205 totalSTime, cpuSpeedTimes); 2206 } 2207 } 2208 } 2209 2210 if (mLastWriteTime < (now-BATTERY_STATS_TIME)) { 2211 mLastWriteTime = now; 2212 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 2213 } 2214 } 2215 } 2216 } 2217 2218 @Override 2219 public void batteryNeedsCpuUpdate() { 2220 updateCpuStatsNow(); 2221 } 2222 2223 @Override 2224 public void batteryPowerChanged(boolean onBattery) { 2225 // When plugging in, update the CPU stats first before changing 2226 // the plug state. 2227 updateCpuStatsNow(); 2228 synchronized (this) { 2229 synchronized(mPidsSelfLocked) { 2230 mOnBattery = DEBUG_POWER ? true : onBattery; 2231 } 2232 } 2233 } 2234 2235 /** 2236 * Initialize the application bind args. These are passed to each 2237 * process when the bindApplication() IPC is sent to the process. They're 2238 * lazily setup to make sure the services are running when they're asked for. 2239 */ 2240 private HashMap<String, IBinder> getCommonServicesLocked() { 2241 if (mAppBindArgs == null) { 2242 mAppBindArgs = new HashMap<String, IBinder>(); 2243 2244 // Setup the application init args 2245 mAppBindArgs.put("package", ServiceManager.getService("package")); 2246 mAppBindArgs.put("window", ServiceManager.getService("window")); 2247 mAppBindArgs.put(Context.ALARM_SERVICE, 2248 ServiceManager.getService(Context.ALARM_SERVICE)); 2249 } 2250 return mAppBindArgs; 2251 } 2252 2253 final void setFocusedActivityLocked(ActivityRecord r) { 2254 if (mFocusedActivity != r) { 2255 if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r); 2256 mFocusedActivity = r; 2257 mStackSupervisor.setFocusedStack(r); 2258 if (r != null) { 2259 mWindowManager.setFocusedApp(r.appToken, true); 2260 } 2261 applyUpdateLockStateLocked(r); 2262 } 2263 } 2264 2265 @Override 2266 public void setFocusedStack(int stackId) { 2267 if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId); 2268 synchronized (ActivityManagerService.this) { 2269 ActivityStack stack = mStackSupervisor.getStack(stackId); 2270 if (stack != null) { 2271 ActivityRecord r = stack.topRunningActivityLocked(null); 2272 if (r != null) { 2273 setFocusedActivityLocked(r); 2274 } 2275 } 2276 } 2277 } 2278 2279 @Override 2280 public void notifyActivityDrawn(IBinder token) { 2281 if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token); 2282 synchronized (this) { 2283 ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token); 2284 if (r != null) { 2285 r.task.stack.notifyActivityDrawnLocked(r); 2286 } 2287 } 2288 } 2289 2290 final void applyUpdateLockStateLocked(ActivityRecord r) { 2291 // Modifications to the UpdateLock state are done on our handler, outside 2292 // the activity manager's locks. The new state is determined based on the 2293 // state *now* of the relevant activity record. The object is passed to 2294 // the handler solely for logging detail, not to be consulted/modified. 2295 final boolean nextState = r != null && r.immersive; 2296 mHandler.sendMessage( 2297 mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r)); 2298 } 2299 2300 final void showAskCompatModeDialogLocked(ActivityRecord r) { 2301 Message msg = Message.obtain(); 2302 msg.what = SHOW_COMPAT_MODE_DIALOG_MSG; 2303 msg.obj = r.task.askedCompatMode ? null : r; 2304 mHandler.sendMessage(msg); 2305 } 2306 2307 private final int updateLruProcessInternalLocked(ProcessRecord app, long now, int index, 2308 String what, Object obj, ProcessRecord srcApp) { 2309 app.lastActivityTime = now; 2310 2311 if (app.activities.size() > 0) { 2312 // Don't want to touch dependent processes that are hosting activities. 2313 return index; 2314 } 2315 2316 int lrui = mLruProcesses.lastIndexOf(app); 2317 if (lrui < 0) { 2318 Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: " 2319 + what + " " + obj + " from " + srcApp); 2320 return index; 2321 } 2322 2323 if (lrui >= index) { 2324 // Don't want to cause this to move dependent processes *back* in the 2325 // list as if they were less frequently used. 2326 return index; 2327 } 2328 2329 if (lrui >= mLruProcessActivityStart) { 2330 // Don't want to touch dependent processes that are hosting activities. 2331 return index; 2332 } 2333 2334 mLruProcesses.remove(lrui); 2335 if (index > 0) { 2336 index--; 2337 } 2338 if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index 2339 + " in LRU list: " + app); 2340 mLruProcesses.add(index, app); 2341 return index; 2342 } 2343 2344 final void removeLruProcessLocked(ProcessRecord app) { 2345 int lrui = mLruProcesses.lastIndexOf(app); 2346 if (lrui >= 0) { 2347 if (lrui <= mLruProcessActivityStart) { 2348 mLruProcessActivityStart--; 2349 } 2350 if (lrui <= mLruProcessServiceStart) { 2351 mLruProcessServiceStart--; 2352 } 2353 mLruProcesses.remove(lrui); 2354 } 2355 } 2356 2357 final void updateLruProcessLocked(ProcessRecord app, boolean activityChange, 2358 ProcessRecord client) { 2359 final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities 2360 || app.treatLikeActivity; 2361 final boolean hasService = false; // not impl yet. app.services.size() > 0; 2362 if (!activityChange && hasActivity) { 2363 // The process has activities, so we are only allowing activity-based adjustments 2364 // to move it. It should be kept in the front of the list with other 2365 // processes that have activities, and we don't want those to change their 2366 // order except due to activity operations. 2367 return; 2368 } 2369 2370 mLruSeq++; 2371 final long now = SystemClock.uptimeMillis(); 2372 app.lastActivityTime = now; 2373 2374 // First a quick reject: if the app is already at the position we will 2375 // put it, then there is nothing to do. 2376 if (hasActivity) { 2377 final int N = mLruProcesses.size(); 2378 if (N > 0 && mLruProcesses.get(N-1) == app) { 2379 if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app); 2380 return; 2381 } 2382 } else { 2383 if (mLruProcessServiceStart > 0 2384 && mLruProcesses.get(mLruProcessServiceStart-1) == app) { 2385 if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app); 2386 return; 2387 } 2388 } 2389 2390 int lrui = mLruProcesses.lastIndexOf(app); 2391 2392 if (app.persistent && lrui >= 0) { 2393 // We don't care about the position of persistent processes, as long as 2394 // they are in the list. 2395 if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app); 2396 return; 2397 } 2398 2399 /* In progress: compute new position first, so we can avoid doing work 2400 if the process is not actually going to move. Not yet working. 2401 int addIndex; 2402 int nextIndex; 2403 boolean inActivity = false, inService = false; 2404 if (hasActivity) { 2405 // Process has activities, put it at the very tipsy-top. 2406 addIndex = mLruProcesses.size(); 2407 nextIndex = mLruProcessServiceStart; 2408 inActivity = true; 2409 } else if (hasService) { 2410 // Process has services, put it at the top of the service list. 2411 addIndex = mLruProcessActivityStart; 2412 nextIndex = mLruProcessServiceStart; 2413 inActivity = true; 2414 inService = true; 2415 } else { 2416 // Process not otherwise of interest, it goes to the top of the non-service area. 2417 addIndex = mLruProcessServiceStart; 2418 if (client != null) { 2419 int clientIndex = mLruProcesses.lastIndexOf(client); 2420 if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating " 2421 + app); 2422 if (clientIndex >= 0 && addIndex > clientIndex) { 2423 addIndex = clientIndex; 2424 } 2425 } 2426 nextIndex = addIndex > 0 ? addIndex-1 : addIndex; 2427 } 2428 2429 Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act=" 2430 + mLruProcessActivityStart + "): " + app); 2431 */ 2432 2433 if (lrui >= 0) { 2434 if (lrui < mLruProcessActivityStart) { 2435 mLruProcessActivityStart--; 2436 } 2437 if (lrui < mLruProcessServiceStart) { 2438 mLruProcessServiceStart--; 2439 } 2440 /* 2441 if (addIndex > lrui) { 2442 addIndex--; 2443 } 2444 if (nextIndex > lrui) { 2445 nextIndex--; 2446 } 2447 */ 2448 mLruProcesses.remove(lrui); 2449 } 2450 2451 /* 2452 mLruProcesses.add(addIndex, app); 2453 if (inActivity) { 2454 mLruProcessActivityStart++; 2455 } 2456 if (inService) { 2457 mLruProcessActivityStart++; 2458 } 2459 */ 2460 2461 int nextIndex; 2462 if (hasActivity) { 2463 final int N = mLruProcesses.size(); 2464 if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) { 2465 // Process doesn't have activities, but has clients with 2466 // activities... move it up, but one below the top (the top 2467 // should always have a real activity). 2468 if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app); 2469 mLruProcesses.add(N-1, app); 2470 // To keep it from spamming the LRU list (by making a bunch of clients), 2471 // we will push down any other entries owned by the app. 2472 final int uid = app.info.uid; 2473 for (int i=N-2; i>mLruProcessActivityStart; i--) { 2474 ProcessRecord subProc = mLruProcesses.get(i); 2475 if (subProc.info.uid == uid) { 2476 // We want to push this one down the list. If the process after 2477 // it is for the same uid, however, don't do so, because we don't 2478 // want them internally to be re-ordered. 2479 if (mLruProcesses.get(i-1).info.uid != uid) { 2480 if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i 2481 + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1)); 2482 ProcessRecord tmp = mLruProcesses.get(i); 2483 mLruProcesses.set(i, mLruProcesses.get(i-1)); 2484 mLruProcesses.set(i-1, tmp); 2485 i--; 2486 } 2487 } else { 2488 // A gap, we can stop here. 2489 break; 2490 } 2491 } 2492 } else { 2493 // Process has activities, put it at the very tipsy-top. 2494 if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app); 2495 mLruProcesses.add(app); 2496 } 2497 nextIndex = mLruProcessServiceStart; 2498 } else if (hasService) { 2499 // Process has services, put it at the top of the service list. 2500 if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app); 2501 mLruProcesses.add(mLruProcessActivityStart, app); 2502 nextIndex = mLruProcessServiceStart; 2503 mLruProcessActivityStart++; 2504 } else { 2505 // Process not otherwise of interest, it goes to the top of the non-service area. 2506 int index = mLruProcessServiceStart; 2507 if (client != null) { 2508 // If there is a client, don't allow the process to be moved up higher 2509 // in the list than that client. 2510 int clientIndex = mLruProcesses.lastIndexOf(client); 2511 if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client 2512 + " when updating " + app); 2513 if (clientIndex <= lrui) { 2514 // Don't allow the client index restriction to push it down farther in the 2515 // list than it already is. 2516 clientIndex = lrui; 2517 } 2518 if (clientIndex >= 0 && index > clientIndex) { 2519 index = clientIndex; 2520 } 2521 } 2522 if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app); 2523 mLruProcesses.add(index, app); 2524 nextIndex = index-1; 2525 mLruProcessActivityStart++; 2526 mLruProcessServiceStart++; 2527 } 2528 2529 // If the app is currently using a content provider or service, 2530 // bump those processes as well. 2531 for (int j=app.connections.size()-1; j>=0; j--) { 2532 ConnectionRecord cr = app.connections.valueAt(j); 2533 if (cr.binding != null && !cr.serviceDead && cr.binding.service != null 2534 && cr.binding.service.app != null 2535 && cr.binding.service.app.lruSeq != mLruSeq 2536 && !cr.binding.service.app.persistent) { 2537 nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex, 2538 "service connection", cr, app); 2539 } 2540 } 2541 for (int j=app.conProviders.size()-1; j>=0; j--) { 2542 ContentProviderRecord cpr = app.conProviders.get(j).provider; 2543 if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) { 2544 nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex, 2545 "provider reference", cpr, app); 2546 } 2547 } 2548 } 2549 2550 final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) { 2551 if (uid == Process.SYSTEM_UID) { 2552 // The system gets to run in any process. If there are multiple 2553 // processes with the same uid, just pick the first (this 2554 // should never happen). 2555 SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName); 2556 if (procs == null) return null; 2557 final int N = procs.size(); 2558 for (int i = 0; i < N; i++) { 2559 if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i); 2560 } 2561 } 2562 ProcessRecord proc = mProcessNames.get(processName, uid); 2563 if (false && proc != null && !keepIfLarge 2564 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY 2565 && proc.lastCachedPss >= 4000) { 2566 // Turn this condition on to cause killing to happen regularly, for testing. 2567 if (proc.baseProcessTracker != null) { 2568 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss); 2569 } 2570 killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss) 2571 + "k from cached"); 2572 } else if (proc != null && !keepIfLarge 2573 && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL 2574 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) { 2575 if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss); 2576 if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) { 2577 if (proc.baseProcessTracker != null) { 2578 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss); 2579 } 2580 killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss) 2581 + "k from cached"); 2582 } 2583 } 2584 return proc; 2585 } 2586 2587 void ensurePackageDexOpt(String packageName) { 2588 IPackageManager pm = AppGlobals.getPackageManager(); 2589 try { 2590 if (pm.performDexOpt(packageName)) { 2591 mDidDexOpt = true; 2592 } 2593 } catch (RemoteException e) { 2594 } 2595 } 2596 2597 boolean isNextTransitionForward() { 2598 int transit = mWindowManager.getPendingAppTransition(); 2599 return transit == AppTransition.TRANSIT_ACTIVITY_OPEN 2600 || transit == AppTransition.TRANSIT_TASK_OPEN 2601 || transit == AppTransition.TRANSIT_TASK_TO_FRONT; 2602 } 2603 2604 final ProcessRecord startProcessLocked(String processName, 2605 ApplicationInfo info, boolean knownToBeDead, int intentFlags, 2606 String hostingType, ComponentName hostingName, boolean allowWhileBooting, 2607 boolean isolated, boolean keepIfLarge) { 2608 ProcessRecord app; 2609 if (!isolated) { 2610 app = getProcessRecordLocked(processName, info.uid, keepIfLarge); 2611 } else { 2612 // If this is an isolated process, it can't re-use an existing process. 2613 app = null; 2614 } 2615 // We don't have to do anything more if: 2616 // (1) There is an existing application record; and 2617 // (2) The caller doesn't think it is dead, OR there is no thread 2618 // object attached to it so we know it couldn't have crashed; and 2619 // (3) There is a pid assigned to it, so it is either starting or 2620 // already running. 2621 if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName 2622 + " app=" + app + " knownToBeDead=" + knownToBeDead 2623 + " thread=" + (app != null ? app.thread : null) 2624 + " pid=" + (app != null ? app.pid : -1)); 2625 if (app != null && app.pid > 0) { 2626 if (!knownToBeDead || app.thread == null) { 2627 // We already have the app running, or are waiting for it to 2628 // come up (we have a pid but not yet its thread), so keep it. 2629 if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app); 2630 // If this is a new package in the process, add the package to the list 2631 app.addPackage(info.packageName, mProcessStats); 2632 return app; 2633 } 2634 2635 // An application record is attached to a previous process, 2636 // clean it up now. 2637 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app); 2638 handleAppDiedLocked(app, true, true); 2639 } 2640 2641 String hostingNameStr = hostingName != null 2642 ? hostingName.flattenToShortString() : null; 2643 2644 if (!isolated) { 2645 if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) { 2646 // If we are in the background, then check to see if this process 2647 // is bad. If so, we will just silently fail. 2648 if (mBadProcesses.get(info.processName, info.uid) != null) { 2649 if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid 2650 + "/" + info.processName); 2651 return null; 2652 } 2653 } else { 2654 // When the user is explicitly starting a process, then clear its 2655 // crash count so that we won't make it bad until they see at 2656 // least one crash dialog again, and make the process good again 2657 // if it had been bad. 2658 if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid 2659 + "/" + info.processName); 2660 mProcessCrashTimes.remove(info.processName, info.uid); 2661 if (mBadProcesses.get(info.processName, info.uid) != null) { 2662 EventLog.writeEvent(EventLogTags.AM_PROC_GOOD, 2663 UserHandle.getUserId(info.uid), info.uid, 2664 info.processName); 2665 mBadProcesses.remove(info.processName, info.uid); 2666 if (app != null) { 2667 app.bad = false; 2668 } 2669 } 2670 } 2671 } 2672 2673 if (app == null) { 2674 app = newProcessRecordLocked(info, processName, isolated); 2675 if (app == null) { 2676 Slog.w(TAG, "Failed making new process record for " 2677 + processName + "/" + info.uid + " isolated=" + isolated); 2678 return null; 2679 } 2680 mProcessNames.put(processName, app.uid, app); 2681 if (isolated) { 2682 mIsolatedProcesses.put(app.uid, app); 2683 } 2684 } else { 2685 // If this is a new package in the process, add the package to the list 2686 app.addPackage(info.packageName, mProcessStats); 2687 } 2688 2689 // If the system is not ready yet, then hold off on starting this 2690 // process until it is. 2691 if (!mProcessesReady 2692 && !isAllowedWhileBooting(info) 2693 && !allowWhileBooting) { 2694 if (!mProcessesOnHold.contains(app)) { 2695 mProcessesOnHold.add(app); 2696 } 2697 if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app); 2698 return app; 2699 } 2700 2701 startProcessLocked(app, hostingType, hostingNameStr); 2702 return (app.pid != 0) ? app : null; 2703 } 2704 2705 boolean isAllowedWhileBooting(ApplicationInfo ai) { 2706 return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0; 2707 } 2708 2709 private final void startProcessLocked(ProcessRecord app, 2710 String hostingType, String hostingNameStr) { 2711 if (app.pid > 0 && app.pid != MY_PID) { 2712 synchronized (mPidsSelfLocked) { 2713 mPidsSelfLocked.remove(app.pid); 2714 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 2715 } 2716 app.setPid(0); 2717 } 2718 2719 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 2720 "startProcessLocked removing on hold: " + app); 2721 mProcessesOnHold.remove(app); 2722 2723 updateCpuStats(); 2724 2725 try { 2726 int uid = app.uid; 2727 2728 int[] gids = null; 2729 int mountExternal = Zygote.MOUNT_EXTERNAL_NONE; 2730 if (!app.isolated) { 2731 int[] permGids = null; 2732 try { 2733 final PackageManager pm = mContext.getPackageManager(); 2734 permGids = pm.getPackageGids(app.info.packageName); 2735 2736 if (Environment.isExternalStorageEmulated()) { 2737 if (pm.checkPermission( 2738 android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE, 2739 app.info.packageName) == PERMISSION_GRANTED) { 2740 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL; 2741 } else { 2742 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER; 2743 } 2744 } 2745 } catch (PackageManager.NameNotFoundException e) { 2746 Slog.w(TAG, "Unable to retrieve gids", e); 2747 } 2748 2749 /* 2750 * Add shared application GID so applications can share some 2751 * resources like shared libraries 2752 */ 2753 if (permGids == null) { 2754 gids = new int[1]; 2755 } else { 2756 gids = new int[permGids.length + 1]; 2757 System.arraycopy(permGids, 0, gids, 1, permGids.length); 2758 } 2759 gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid)); 2760 } 2761 if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) { 2762 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL 2763 && mTopComponent != null 2764 && app.processName.equals(mTopComponent.getPackageName())) { 2765 uid = 0; 2766 } 2767 if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL 2768 && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) { 2769 uid = 0; 2770 } 2771 } 2772 int debugFlags = 0; 2773 if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) { 2774 debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER; 2775 // Also turn on CheckJNI for debuggable apps. It's quite 2776 // awkward to turn on otherwise. 2777 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 2778 } 2779 // Run the app in safe mode if its manifest requests so or the 2780 // system is booted in safe mode. 2781 if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 || 2782 mSafeMode == true) { 2783 debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE; 2784 } 2785 if ("1".equals(SystemProperties.get("debug.checkjni"))) { 2786 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 2787 } 2788 if ("1".equals(SystemProperties.get("debug.jni.logging"))) { 2789 debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING; 2790 } 2791 if ("1".equals(SystemProperties.get("debug.assert"))) { 2792 debugFlags |= Zygote.DEBUG_ENABLE_ASSERT; 2793 } 2794 2795 String requiredAbi = app.info.requiredCpuAbi; 2796 if (requiredAbi == null) { 2797 requiredAbi = Build.SUPPORTED_ABIS[0]; 2798 } 2799 2800 // Start the process. It will either succeed and return a result containing 2801 // the PID of the new process, or else throw a RuntimeException. 2802 Process.ProcessStartResult startResult = Process.start("android.app.ActivityThread", 2803 app.processName, uid, uid, gids, debugFlags, mountExternal, 2804 app.info.targetSdkVersion, app.info.seinfo, requiredAbi, null); 2805 2806 BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics(); 2807 synchronized (bs) { 2808 if (bs.isOnBattery()) { 2809 bs.getProcessStatsLocked(app.uid, app.processName).incStartsLocked(); 2810 } 2811 } 2812 2813 EventLog.writeEvent(EventLogTags.AM_PROC_START, 2814 UserHandle.getUserId(uid), startResult.pid, uid, 2815 app.processName, hostingType, 2816 hostingNameStr != null ? hostingNameStr : ""); 2817 2818 if (app.persistent) { 2819 Watchdog.getInstance().processStarted(app.processName, startResult.pid); 2820 } 2821 2822 StringBuilder buf = mStringBuilder; 2823 buf.setLength(0); 2824 buf.append("Start proc "); 2825 buf.append(app.processName); 2826 buf.append(" for "); 2827 buf.append(hostingType); 2828 if (hostingNameStr != null) { 2829 buf.append(" "); 2830 buf.append(hostingNameStr); 2831 } 2832 buf.append(": pid="); 2833 buf.append(startResult.pid); 2834 buf.append(" uid="); 2835 buf.append(uid); 2836 buf.append(" gids={"); 2837 if (gids != null) { 2838 for (int gi=0; gi<gids.length; gi++) { 2839 if (gi != 0) buf.append(", "); 2840 buf.append(gids[gi]); 2841 2842 } 2843 } 2844 buf.append("}"); 2845 Slog.i(TAG, buf.toString()); 2846 app.setPid(startResult.pid); 2847 app.usingWrapper = startResult.usingWrapper; 2848 app.removed = false; 2849 synchronized (mPidsSelfLocked) { 2850 this.mPidsSelfLocked.put(startResult.pid, app); 2851 Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 2852 msg.obj = app; 2853 mHandler.sendMessageDelayed(msg, startResult.usingWrapper 2854 ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT); 2855 } 2856 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_START, 2857 app.processName, app.info.uid); 2858 if (app.isolated) { 2859 mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid); 2860 } 2861 } catch (RuntimeException e) { 2862 // XXX do better error recovery. 2863 app.setPid(0); 2864 Slog.e(TAG, "Failure starting process " + app.processName, e); 2865 } 2866 } 2867 2868 void updateUsageStats(ActivityRecord component, boolean resumed) { 2869 if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed); 2870 final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 2871 if (resumed) { 2872 mUsageStatsService.noteResumeComponent(component.realActivity); 2873 synchronized (stats) { 2874 stats.noteActivityResumedLocked(component.app.uid); 2875 } 2876 } else { 2877 mUsageStatsService.notePauseComponent(component.realActivity); 2878 synchronized (stats) { 2879 stats.noteActivityPausedLocked(component.app.uid); 2880 } 2881 } 2882 } 2883 2884 Intent getHomeIntent() { 2885 Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null); 2886 intent.setComponent(mTopComponent); 2887 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 2888 intent.addCategory(Intent.CATEGORY_HOME); 2889 } 2890 return intent; 2891 } 2892 2893 boolean startHomeActivityLocked(int userId) { 2894 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL 2895 && mTopAction == null) { 2896 // We are running in factory test mode, but unable to find 2897 // the factory test app, so just sit around displaying the 2898 // error message and don't try to start anything. 2899 return false; 2900 } 2901 Intent intent = getHomeIntent(); 2902 ActivityInfo aInfo = 2903 resolveActivityInfo(intent, STOCK_PM_FLAGS, userId); 2904 if (aInfo != null) { 2905 intent.setComponent(new ComponentName( 2906 aInfo.applicationInfo.packageName, aInfo.name)); 2907 // Don't do this if the home app is currently being 2908 // instrumented. 2909 aInfo = new ActivityInfo(aInfo); 2910 aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId); 2911 ProcessRecord app = getProcessRecordLocked(aInfo.processName, 2912 aInfo.applicationInfo.uid, true); 2913 if (app == null || app.instrumentationClass == null) { 2914 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK); 2915 mStackSupervisor.startHomeActivity(intent, aInfo); 2916 } 2917 } 2918 2919 return true; 2920 } 2921 2922 private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) { 2923 ActivityInfo ai = null; 2924 ComponentName comp = intent.getComponent(); 2925 try { 2926 if (comp != null) { 2927 ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId); 2928 } else { 2929 ResolveInfo info = AppGlobals.getPackageManager().resolveIntent( 2930 intent, 2931 intent.resolveTypeIfNeeded(mContext.getContentResolver()), 2932 flags, userId); 2933 2934 if (info != null) { 2935 ai = info.activityInfo; 2936 } 2937 } 2938 } catch (RemoteException e) { 2939 // ignore 2940 } 2941 2942 return ai; 2943 } 2944 2945 /** 2946 * Starts the "new version setup screen" if appropriate. 2947 */ 2948 void startSetupActivityLocked() { 2949 // Only do this once per boot. 2950 if (mCheckedForSetup) { 2951 return; 2952 } 2953 2954 // We will show this screen if the current one is a different 2955 // version than the last one shown, and we are not running in 2956 // low-level factory test mode. 2957 final ContentResolver resolver = mContext.getContentResolver(); 2958 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL && 2959 Settings.Global.getInt(resolver, 2960 Settings.Global.DEVICE_PROVISIONED, 0) != 0) { 2961 mCheckedForSetup = true; 2962 2963 // See if we should be showing the platform update setup UI. 2964 Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP); 2965 List<ResolveInfo> ris = mContext.getPackageManager() 2966 .queryIntentActivities(intent, PackageManager.GET_META_DATA); 2967 2968 // We don't allow third party apps to replace this. 2969 ResolveInfo ri = null; 2970 for (int i=0; ris != null && i<ris.size(); i++) { 2971 if ((ris.get(i).activityInfo.applicationInfo.flags 2972 & ApplicationInfo.FLAG_SYSTEM) != 0) { 2973 ri = ris.get(i); 2974 break; 2975 } 2976 } 2977 2978 if (ri != null) { 2979 String vers = ri.activityInfo.metaData != null 2980 ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION) 2981 : null; 2982 if (vers == null && ri.activityInfo.applicationInfo.metaData != null) { 2983 vers = ri.activityInfo.applicationInfo.metaData.getString( 2984 Intent.METADATA_SETUP_VERSION); 2985 } 2986 String lastVers = Settings.Secure.getString( 2987 resolver, Settings.Secure.LAST_SETUP_SHOWN); 2988 if (vers != null && !vers.equals(lastVers)) { 2989 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 2990 intent.setComponent(new ComponentName( 2991 ri.activityInfo.packageName, ri.activityInfo.name)); 2992 mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo, 2993 null, null, 0, 0, 0, null, 0, null, false, null, null); 2994 } 2995 } 2996 } 2997 } 2998 2999 CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) { 3000 return mCompatModePackages.compatibilityInfoForPackageLocked(ai); 3001 } 3002 3003 void enforceNotIsolatedCaller(String caller) { 3004 if (UserHandle.isIsolated(Binder.getCallingUid())) { 3005 throw new SecurityException("Isolated process not allowed to call " + caller); 3006 } 3007 } 3008 3009 @Override 3010 public int getFrontActivityScreenCompatMode() { 3011 enforceNotIsolatedCaller("getFrontActivityScreenCompatMode"); 3012 synchronized (this) { 3013 return mCompatModePackages.getFrontActivityScreenCompatModeLocked(); 3014 } 3015 } 3016 3017 @Override 3018 public void setFrontActivityScreenCompatMode(int mode) { 3019 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3020 "setFrontActivityScreenCompatMode"); 3021 synchronized (this) { 3022 mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode); 3023 } 3024 } 3025 3026 @Override 3027 public int getPackageScreenCompatMode(String packageName) { 3028 enforceNotIsolatedCaller("getPackageScreenCompatMode"); 3029 synchronized (this) { 3030 return mCompatModePackages.getPackageScreenCompatModeLocked(packageName); 3031 } 3032 } 3033 3034 @Override 3035 public void setPackageScreenCompatMode(String packageName, int mode) { 3036 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3037 "setPackageScreenCompatMode"); 3038 synchronized (this) { 3039 mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode); 3040 } 3041 } 3042 3043 @Override 3044 public boolean getPackageAskScreenCompat(String packageName) { 3045 enforceNotIsolatedCaller("getPackageAskScreenCompat"); 3046 synchronized (this) { 3047 return mCompatModePackages.getPackageAskCompatModeLocked(packageName); 3048 } 3049 } 3050 3051 @Override 3052 public void setPackageAskScreenCompat(String packageName, boolean ask) { 3053 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3054 "setPackageAskScreenCompat"); 3055 synchronized (this) { 3056 mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask); 3057 } 3058 } 3059 3060 private void dispatchProcessesChanged() { 3061 int N; 3062 synchronized (this) { 3063 N = mPendingProcessChanges.size(); 3064 if (mActiveProcessChanges.length < N) { 3065 mActiveProcessChanges = new ProcessChangeItem[N]; 3066 } 3067 mPendingProcessChanges.toArray(mActiveProcessChanges); 3068 mAvailProcessChanges.addAll(mPendingProcessChanges); 3069 mPendingProcessChanges.clear(); 3070 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes"); 3071 } 3072 3073 int i = mProcessObservers.beginBroadcast(); 3074 while (i > 0) { 3075 i--; 3076 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 3077 if (observer != null) { 3078 try { 3079 for (int j=0; j<N; j++) { 3080 ProcessChangeItem item = mActiveProcessChanges[j]; 3081 if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) { 3082 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid=" 3083 + item.pid + " uid=" + item.uid + ": " 3084 + item.foregroundActivities); 3085 observer.onForegroundActivitiesChanged(item.pid, item.uid, 3086 item.foregroundActivities); 3087 } 3088 if ((item.changes&ProcessChangeItem.CHANGE_IMPORTANCE) != 0) { 3089 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "IMPORTANCE CHANGED pid=" 3090 + item.pid + " uid=" + item.uid + ": " + item.importance); 3091 observer.onImportanceChanged(item.pid, item.uid, 3092 item.importance); 3093 } 3094 } 3095 } catch (RemoteException e) { 3096 } 3097 } 3098 } 3099 mProcessObservers.finishBroadcast(); 3100 } 3101 3102 private void dispatchProcessDied(int pid, int uid) { 3103 int i = mProcessObservers.beginBroadcast(); 3104 while (i > 0) { 3105 i--; 3106 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 3107 if (observer != null) { 3108 try { 3109 observer.onProcessDied(pid, uid); 3110 } catch (RemoteException e) { 3111 } 3112 } 3113 } 3114 mProcessObservers.finishBroadcast(); 3115 } 3116 3117 final void doPendingActivityLaunchesLocked(boolean doResume) { 3118 final int N = mPendingActivityLaunches.size(); 3119 if (N <= 0) { 3120 return; 3121 } 3122 for (int i=0; i<N; i++) { 3123 PendingActivityLaunch pal = mPendingActivityLaunches.get(i); 3124 mStackSupervisor.startActivityUncheckedLocked(pal.r, pal.sourceRecord, pal.startFlags, 3125 doResume && i == (N-1), null); 3126 } 3127 mPendingActivityLaunches.clear(); 3128 } 3129 3130 @Override 3131 public final int startActivity(IApplicationThread caller, String callingPackage, 3132 Intent intent, String resolvedType, IBinder resultTo, 3133 String resultWho, int requestCode, int startFlags, 3134 String profileFile, ParcelFileDescriptor profileFd, Bundle options) { 3135 return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo, 3136 resultWho, requestCode, 3137 startFlags, profileFile, profileFd, options, UserHandle.getCallingUserId()); 3138 } 3139 3140 @Override 3141 public final int startActivityAsUser(IApplicationThread caller, String callingPackage, 3142 Intent intent, String resolvedType, IBinder resultTo, 3143 String resultWho, int requestCode, int startFlags, 3144 String profileFile, ParcelFileDescriptor profileFd, Bundle options, int userId) { 3145 enforceNotIsolatedCaller("startActivity"); 3146 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3147 false, true, "startActivity", null); 3148 // TODO: Switch to user app stacks here. 3149 return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType, 3150 resultTo, resultWho, requestCode, startFlags, profileFile, profileFd, 3151 null, null, options, userId, null); 3152 } 3153 3154 @Override 3155 public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage, 3156 Intent intent, String resolvedType, IBinder resultTo, 3157 String resultWho, int requestCode, int startFlags, String profileFile, 3158 ParcelFileDescriptor profileFd, Bundle options, int userId) { 3159 enforceNotIsolatedCaller("startActivityAndWait"); 3160 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3161 false, true, "startActivityAndWait", null); 3162 WaitResult res = new WaitResult(); 3163 // TODO: Switch to user app stacks here. 3164 mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType, 3165 resultTo, resultWho, requestCode, startFlags, profileFile, profileFd, 3166 res, null, options, UserHandle.getCallingUserId(), null); 3167 return res; 3168 } 3169 3170 @Override 3171 public final int startActivityWithConfig(IApplicationThread caller, String callingPackage, 3172 Intent intent, String resolvedType, IBinder resultTo, 3173 String resultWho, int requestCode, int startFlags, Configuration config, 3174 Bundle options, int userId) { 3175 enforceNotIsolatedCaller("startActivityWithConfig"); 3176 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3177 false, true, "startActivityWithConfig", null); 3178 // TODO: Switch to user app stacks here. 3179 int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, 3180 resolvedType, resultTo, resultWho, requestCode, startFlags, 3181 null, null, null, config, options, userId, null); 3182 return ret; 3183 } 3184 3185 @Override 3186 public int startActivityIntentSender(IApplicationThread caller, 3187 IntentSender intent, Intent fillInIntent, String resolvedType, 3188 IBinder resultTo, String resultWho, int requestCode, 3189 int flagsMask, int flagsValues, Bundle options) { 3190 enforceNotIsolatedCaller("startActivityIntentSender"); 3191 // Refuse possible leaked file descriptors 3192 if (fillInIntent != null && fillInIntent.hasFileDescriptors()) { 3193 throw new IllegalArgumentException("File descriptors passed in Intent"); 3194 } 3195 3196 IIntentSender sender = intent.getTarget(); 3197 if (!(sender instanceof PendingIntentRecord)) { 3198 throw new IllegalArgumentException("Bad PendingIntent object"); 3199 } 3200 3201 PendingIntentRecord pir = (PendingIntentRecord)sender; 3202 3203 synchronized (this) { 3204 // If this is coming from the currently resumed activity, it is 3205 // effectively saying that app switches are allowed at this point. 3206 final ActivityStack stack = getFocusedStack(); 3207 if (stack.mResumedActivity != null && 3208 stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) { 3209 mAppSwitchesAllowedTime = 0; 3210 } 3211 } 3212 int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null, 3213 resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null); 3214 return ret; 3215 } 3216 3217 @Override 3218 public boolean startNextMatchingActivity(IBinder callingActivity, 3219 Intent intent, Bundle options) { 3220 // Refuse possible leaked file descriptors 3221 if (intent != null && intent.hasFileDescriptors() == true) { 3222 throw new IllegalArgumentException("File descriptors passed in Intent"); 3223 } 3224 3225 synchronized (this) { 3226 final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity); 3227 if (r == null) { 3228 ActivityOptions.abort(options); 3229 return false; 3230 } 3231 if (r.app == null || r.app.thread == null) { 3232 // The caller is not running... d'oh! 3233 ActivityOptions.abort(options); 3234 return false; 3235 } 3236 intent = new Intent(intent); 3237 // The caller is not allowed to change the data. 3238 intent.setDataAndType(r.intent.getData(), r.intent.getType()); 3239 // And we are resetting to find the next component... 3240 intent.setComponent(null); 3241 3242 final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0); 3243 3244 ActivityInfo aInfo = null; 3245 try { 3246 List<ResolveInfo> resolves = 3247 AppGlobals.getPackageManager().queryIntentActivities( 3248 intent, r.resolvedType, 3249 PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS, 3250 UserHandle.getCallingUserId()); 3251 3252 // Look for the original activity in the list... 3253 final int N = resolves != null ? resolves.size() : 0; 3254 for (int i=0; i<N; i++) { 3255 ResolveInfo rInfo = resolves.get(i); 3256 if (rInfo.activityInfo.packageName.equals(r.packageName) 3257 && rInfo.activityInfo.name.equals(r.info.name)) { 3258 // We found the current one... the next matching is 3259 // after it. 3260 i++; 3261 if (i<N) { 3262 aInfo = resolves.get(i).activityInfo; 3263 } 3264 if (debug) { 3265 Slog.v(TAG, "Next matching activity: found current " + r.packageName 3266 + "/" + r.info.name); 3267 Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName 3268 + "/" + aInfo.name); 3269 } 3270 break; 3271 } 3272 } 3273 } catch (RemoteException e) { 3274 } 3275 3276 if (aInfo == null) { 3277 // Nobody who is next! 3278 ActivityOptions.abort(options); 3279 if (debug) Slog.d(TAG, "Next matching activity: nothing found"); 3280 return false; 3281 } 3282 3283 intent.setComponent(new ComponentName( 3284 aInfo.applicationInfo.packageName, aInfo.name)); 3285 intent.setFlags(intent.getFlags()&~( 3286 Intent.FLAG_ACTIVITY_FORWARD_RESULT| 3287 Intent.FLAG_ACTIVITY_CLEAR_TOP| 3288 Intent.FLAG_ACTIVITY_MULTIPLE_TASK| 3289 Intent.FLAG_ACTIVITY_NEW_TASK)); 3290 3291 // Okay now we need to start the new activity, replacing the 3292 // currently running activity. This is a little tricky because 3293 // we want to start the new one as if the current one is finished, 3294 // but not finish the current one first so that there is no flicker. 3295 // And thus... 3296 final boolean wasFinishing = r.finishing; 3297 r.finishing = true; 3298 3299 // Propagate reply information over to the new activity. 3300 final ActivityRecord resultTo = r.resultTo; 3301 final String resultWho = r.resultWho; 3302 final int requestCode = r.requestCode; 3303 r.resultTo = null; 3304 if (resultTo != null) { 3305 resultTo.removeResultsLocked(r, resultWho, requestCode); 3306 } 3307 3308 final long origId = Binder.clearCallingIdentity(); 3309 int res = mStackSupervisor.startActivityLocked(r.app.thread, intent, 3310 r.resolvedType, aInfo, resultTo != null ? resultTo.appToken : null, 3311 resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage, 0, 3312 options, false, null, null); 3313 Binder.restoreCallingIdentity(origId); 3314 3315 r.finishing = wasFinishing; 3316 if (res != ActivityManager.START_SUCCESS) { 3317 return false; 3318 } 3319 return true; 3320 } 3321 } 3322 3323 final int startActivityInPackage(int uid, String callingPackage, 3324 Intent intent, String resolvedType, IBinder resultTo, 3325 String resultWho, int requestCode, int startFlags, Bundle options, int userId, 3326 IActivityContainer container) { 3327 3328 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3329 false, true, "startActivityInPackage", null); 3330 3331 // TODO: Switch to user app stacks here. 3332 int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent, resolvedType, 3333 resultTo, resultWho, requestCode, startFlags, 3334 null, null, null, null, options, userId, container); 3335 return ret; 3336 } 3337 3338 @Override 3339 public final int startActivities(IApplicationThread caller, String callingPackage, 3340 Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options, 3341 int userId) { 3342 enforceNotIsolatedCaller("startActivities"); 3343 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3344 false, true, "startActivity", null); 3345 // TODO: Switch to user app stacks here. 3346 int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents, 3347 resolvedTypes, resultTo, options, userId); 3348 return ret; 3349 } 3350 3351 final int startActivitiesInPackage(int uid, String callingPackage, 3352 Intent[] intents, String[] resolvedTypes, IBinder resultTo, 3353 Bundle options, int userId) { 3354 3355 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3356 false, true, "startActivityInPackage", null); 3357 // TODO: Switch to user app stacks here. 3358 int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes, 3359 resultTo, options, userId); 3360 return ret; 3361 } 3362 3363 final void addRecentTaskLocked(TaskRecord task) { 3364 int N = mRecentTasks.size(); 3365 // Quick case: check if the top-most recent task is the same. 3366 if (N > 0 && mRecentTasks.get(0) == task) { 3367 return; 3368 } 3369 // Remove any existing entries that are the same kind of task. 3370 final Intent intent = task.intent; 3371 final boolean document = intent != null && intent.isDocument(); 3372 for (int i=0; i<N; i++) { 3373 TaskRecord tr = mRecentTasks.get(i); 3374 if (task != tr) { 3375 if (task.userId != tr.userId) { 3376 continue; 3377 } 3378 final Intent trIntent = tr.intent; 3379 if ((task.affinity == null || !task.affinity.equals(tr.affinity)) && 3380 (intent == null || !intent.filterEquals(trIntent))) { 3381 continue; 3382 } 3383 if (document || trIntent != null && trIntent.isDocument()) { 3384 // Document tasks do not match other tasks. 3385 continue; 3386 } 3387 } 3388 3389 // Either task and tr are the same or, their affinities match or their intents match 3390 // and neither of them is a document. 3391 tr.disposeThumbnail(); 3392 mRecentTasks.remove(i); 3393 i--; 3394 N--; 3395 if (task.intent == null) { 3396 // If the new recent task we are adding is not fully 3397 // specified, then replace it with the existing recent task. 3398 task = tr; 3399 } 3400 } 3401 if (N >= MAX_RECENT_TASKS) { 3402 mRecentTasks.remove(N-1).disposeThumbnail(); 3403 } 3404 mRecentTasks.add(0, task); 3405 } 3406 3407 @Override 3408 public void reportActivityFullyDrawn(IBinder token) { 3409 synchronized (this) { 3410 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3411 if (r == null) { 3412 return; 3413 } 3414 r.reportFullyDrawnLocked(); 3415 } 3416 } 3417 3418 @Override 3419 public void setRequestedOrientation(IBinder token, int requestedOrientation) { 3420 synchronized (this) { 3421 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3422 if (r == null) { 3423 return; 3424 } 3425 final long origId = Binder.clearCallingIdentity(); 3426 mWindowManager.setAppOrientation(r.appToken, requestedOrientation); 3427 Configuration config = mWindowManager.updateOrientationFromAppTokens( 3428 mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null); 3429 if (config != null) { 3430 r.frozenBeforeDestroy = true; 3431 if (!updateConfigurationLocked(config, r, false, false)) { 3432 mStackSupervisor.resumeTopActivitiesLocked(); 3433 } 3434 } 3435 Binder.restoreCallingIdentity(origId); 3436 } 3437 } 3438 3439 @Override 3440 public int getRequestedOrientation(IBinder token) { 3441 synchronized (this) { 3442 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3443 if (r == null) { 3444 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; 3445 } 3446 return mWindowManager.getAppOrientation(r.appToken); 3447 } 3448 } 3449 3450 /** 3451 * This is the internal entry point for handling Activity.finish(). 3452 * 3453 * @param token The Binder token referencing the Activity we want to finish. 3454 * @param resultCode Result code, if any, from this Activity. 3455 * @param resultData Result data (Intent), if any, from this Activity. 3456 * 3457 * @return Returns true if the activity successfully finished, or false if it is still running. 3458 */ 3459 @Override 3460 public final boolean finishActivity(IBinder token, int resultCode, Intent resultData) { 3461 // Refuse possible leaked file descriptors 3462 if (resultData != null && resultData.hasFileDescriptors() == true) { 3463 throw new IllegalArgumentException("File descriptors passed in Intent"); 3464 } 3465 3466 synchronized(this) { 3467 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3468 if (r == null) { 3469 return true; 3470 } 3471 if (mController != null) { 3472 // Find the first activity that is not finishing. 3473 ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0); 3474 if (next != null) { 3475 // ask watcher if this is allowed 3476 boolean resumeOK = true; 3477 try { 3478 resumeOK = mController.activityResuming(next.packageName); 3479 } catch (RemoteException e) { 3480 mController = null; 3481 Watchdog.getInstance().setActivityController(null); 3482 } 3483 3484 if (!resumeOK) { 3485 return false; 3486 } 3487 } 3488 } 3489 final long origId = Binder.clearCallingIdentity(); 3490 boolean res = r.task.stack.requestFinishActivityLocked(token, resultCode, 3491 resultData, "app-request", true); 3492 Binder.restoreCallingIdentity(origId); 3493 return res; 3494 } 3495 } 3496 3497 @Override 3498 public final void finishHeavyWeightApp() { 3499 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 3500 != PackageManager.PERMISSION_GRANTED) { 3501 String msg = "Permission Denial: finishHeavyWeightApp() from pid=" 3502 + Binder.getCallingPid() 3503 + ", uid=" + Binder.getCallingUid() 3504 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 3505 Slog.w(TAG, msg); 3506 throw new SecurityException(msg); 3507 } 3508 3509 synchronized(this) { 3510 if (mHeavyWeightProcess == null) { 3511 return; 3512 } 3513 3514 ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>( 3515 mHeavyWeightProcess.activities); 3516 for (int i=0; i<activities.size(); i++) { 3517 ActivityRecord r = activities.get(i); 3518 if (!r.finishing) { 3519 r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED, 3520 null, "finish-heavy", true); 3521 } 3522 } 3523 3524 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 3525 mHeavyWeightProcess.userId, 0)); 3526 mHeavyWeightProcess = null; 3527 } 3528 } 3529 3530 @Override 3531 public void crashApplication(int uid, int initialPid, String packageName, 3532 String message) { 3533 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 3534 != PackageManager.PERMISSION_GRANTED) { 3535 String msg = "Permission Denial: crashApplication() from pid=" 3536 + Binder.getCallingPid() 3537 + ", uid=" + Binder.getCallingUid() 3538 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 3539 Slog.w(TAG, msg); 3540 throw new SecurityException(msg); 3541 } 3542 3543 synchronized(this) { 3544 ProcessRecord proc = null; 3545 3546 // Figure out which process to kill. We don't trust that initialPid 3547 // still has any relation to current pids, so must scan through the 3548 // list. 3549 synchronized (mPidsSelfLocked) { 3550 for (int i=0; i<mPidsSelfLocked.size(); i++) { 3551 ProcessRecord p = mPidsSelfLocked.valueAt(i); 3552 if (p.uid != uid) { 3553 continue; 3554 } 3555 if (p.pid == initialPid) { 3556 proc = p; 3557 break; 3558 } 3559 if (p.pkgList.containsKey(packageName)) { 3560 proc = p; 3561 } 3562 } 3563 } 3564 3565 if (proc == null) { 3566 Slog.w(TAG, "crashApplication: nothing for uid=" + uid 3567 + " initialPid=" + initialPid 3568 + " packageName=" + packageName); 3569 return; 3570 } 3571 3572 if (proc.thread != null) { 3573 if (proc.pid == Process.myPid()) { 3574 Log.w(TAG, "crashApplication: trying to crash self!"); 3575 return; 3576 } 3577 long ident = Binder.clearCallingIdentity(); 3578 try { 3579 proc.thread.scheduleCrash(message); 3580 } catch (RemoteException e) { 3581 } 3582 Binder.restoreCallingIdentity(ident); 3583 } 3584 } 3585 } 3586 3587 @Override 3588 public final void finishSubActivity(IBinder token, String resultWho, 3589 int requestCode) { 3590 synchronized(this) { 3591 final long origId = Binder.clearCallingIdentity(); 3592 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3593 if (r != null) { 3594 r.task.stack.finishSubActivityLocked(r, resultWho, requestCode); 3595 } 3596 Binder.restoreCallingIdentity(origId); 3597 } 3598 } 3599 3600 @Override 3601 public boolean finishActivityAffinity(IBinder token) { 3602 synchronized(this) { 3603 final long origId = Binder.clearCallingIdentity(); 3604 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3605 boolean res = false; 3606 if (r != null) { 3607 res = r.task.stack.finishActivityAffinityLocked(r); 3608 } 3609 Binder.restoreCallingIdentity(origId); 3610 return res; 3611 } 3612 } 3613 3614 @Override 3615 public boolean willActivityBeVisible(IBinder token) { 3616 synchronized(this) { 3617 ActivityStack stack = ActivityRecord.getStackLocked(token); 3618 if (stack != null) { 3619 return stack.willActivityBeVisibleLocked(token); 3620 } 3621 return false; 3622 } 3623 } 3624 3625 @Override 3626 public void overridePendingTransition(IBinder token, String packageName, 3627 int enterAnim, int exitAnim) { 3628 synchronized(this) { 3629 ActivityRecord self = ActivityRecord.isInStackLocked(token); 3630 if (self == null) { 3631 return; 3632 } 3633 3634 final long origId = Binder.clearCallingIdentity(); 3635 3636 if (self.state == ActivityState.RESUMED 3637 || self.state == ActivityState.PAUSING) { 3638 mWindowManager.overridePendingAppTransition(packageName, 3639 enterAnim, exitAnim, null); 3640 } 3641 3642 Binder.restoreCallingIdentity(origId); 3643 } 3644 } 3645 3646 /** 3647 * Main function for removing an existing process from the activity manager 3648 * as a result of that process going away. Clears out all connections 3649 * to the process. 3650 */ 3651 private final void handleAppDiedLocked(ProcessRecord app, 3652 boolean restarting, boolean allowRestart) { 3653 int pid = app.pid; 3654 cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1); 3655 if (!restarting) { 3656 removeLruProcessLocked(app); 3657 if (pid > 0) { 3658 ProcessList.remove(pid); 3659 } 3660 } 3661 3662 if (mProfileProc == app) { 3663 clearProfilerLocked(); 3664 } 3665 3666 // Remove this application's activities from active lists. 3667 boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app); 3668 3669 app.activities.clear(); 3670 3671 if (app.instrumentationClass != null) { 3672 Slog.w(TAG, "Crash of app " + app.processName 3673 + " running instrumentation " + app.instrumentationClass); 3674 Bundle info = new Bundle(); 3675 info.putString("shortMsg", "Process crashed."); 3676 finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info); 3677 } 3678 3679 if (!restarting) { 3680 if (!mStackSupervisor.resumeTopActivitiesLocked()) { 3681 // If there was nothing to resume, and we are not already 3682 // restarting this process, but there is a visible activity that 3683 // is hosted by the process... then make sure all visible 3684 // activities are running, taking care of restarting this 3685 // process. 3686 if (hasVisibleActivities) { 3687 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 3688 } 3689 } 3690 } 3691 } 3692 3693 private final int getLRURecordIndexForAppLocked(IApplicationThread thread) { 3694 IBinder threadBinder = thread.asBinder(); 3695 // Find the application record. 3696 for (int i=mLruProcesses.size()-1; i>=0; i--) { 3697 ProcessRecord rec = mLruProcesses.get(i); 3698 if (rec.thread != null && rec.thread.asBinder() == threadBinder) { 3699 return i; 3700 } 3701 } 3702 return -1; 3703 } 3704 3705 final ProcessRecord getRecordForAppLocked( 3706 IApplicationThread thread) { 3707 if (thread == null) { 3708 return null; 3709 } 3710 3711 int appIndex = getLRURecordIndexForAppLocked(thread); 3712 return appIndex >= 0 ? mLruProcesses.get(appIndex) : null; 3713 } 3714 3715 final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) { 3716 // If there are no longer any background processes running, 3717 // and the app that died was not running instrumentation, 3718 // then tell everyone we are now low on memory. 3719 boolean haveBg = false; 3720 for (int i=mLruProcesses.size()-1; i>=0; i--) { 3721 ProcessRecord rec = mLruProcesses.get(i); 3722 if (rec.thread != null 3723 && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 3724 haveBg = true; 3725 break; 3726 } 3727 } 3728 3729 if (!haveBg) { 3730 boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 3731 if (doReport) { 3732 long now = SystemClock.uptimeMillis(); 3733 if (now < (mLastMemUsageReportTime+5*60*1000)) { 3734 doReport = false; 3735 } else { 3736 mLastMemUsageReportTime = now; 3737 } 3738 } 3739 final ArrayList<ProcessMemInfo> memInfos 3740 = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null; 3741 EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size()); 3742 long now = SystemClock.uptimeMillis(); 3743 for (int i=mLruProcesses.size()-1; i>=0; i--) { 3744 ProcessRecord rec = mLruProcesses.get(i); 3745 if (rec == dyingProc || rec.thread == null) { 3746 continue; 3747 } 3748 if (doReport) { 3749 memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj, 3750 rec.setProcState, rec.adjType, rec.makeAdjReason())); 3751 } 3752 if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) { 3753 // The low memory report is overriding any current 3754 // state for a GC request. Make sure to do 3755 // heavy/important/visible/foreground processes first. 3756 if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 3757 rec.lastRequestedGc = 0; 3758 } else { 3759 rec.lastRequestedGc = rec.lastLowMemory; 3760 } 3761 rec.reportLowMemory = true; 3762 rec.lastLowMemory = now; 3763 mProcessesToGc.remove(rec); 3764 addProcessToGcListLocked(rec); 3765 } 3766 } 3767 if (doReport) { 3768 Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos); 3769 mHandler.sendMessage(msg); 3770 } 3771 scheduleAppGcsLocked(); 3772 } 3773 } 3774 3775 final void appDiedLocked(ProcessRecord app, int pid, 3776 IApplicationThread thread) { 3777 3778 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 3779 synchronized (stats) { 3780 stats.noteProcessDiedLocked(app.info.uid, pid); 3781 } 3782 3783 // Clean up already done if the process has been re-started. 3784 if (app.pid == pid && app.thread != null && 3785 app.thread.asBinder() == thread.asBinder()) { 3786 boolean doLowMem = app.instrumentationClass == null; 3787 boolean doOomAdj = doLowMem; 3788 if (!app.killedByAm) { 3789 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 3790 + ") has died."); 3791 mAllowLowerMemLevel = true; 3792 } else { 3793 // Note that we always want to do oom adj to update our state with the 3794 // new number of procs. 3795 mAllowLowerMemLevel = false; 3796 doLowMem = false; 3797 } 3798 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName); 3799 if (DEBUG_CLEANUP) Slog.v( 3800 TAG, "Dying app: " + app + ", pid: " + pid 3801 + ", thread: " + thread.asBinder()); 3802 handleAppDiedLocked(app, false, true); 3803 3804 if (doOomAdj) { 3805 updateOomAdjLocked(); 3806 } 3807 if (doLowMem) { 3808 doLowMemReportIfNeededLocked(app); 3809 } 3810 } else if (app.pid != pid) { 3811 // A new process has already been started. 3812 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 3813 + ") has died and restarted (pid " + app.pid + ")."); 3814 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName); 3815 } else if (DEBUG_PROCESSES) { 3816 Slog.d(TAG, "Received spurious death notification for thread " 3817 + thread.asBinder()); 3818 } 3819 } 3820 3821 /** 3822 * If a stack trace dump file is configured, dump process stack traces. 3823 * @param clearTraces causes the dump file to be erased prior to the new 3824 * traces being written, if true; when false, the new traces will be 3825 * appended to any existing file content. 3826 * @param firstPids of dalvik VM processes to dump stack traces for first 3827 * @param lastPids of dalvik VM processes to dump stack traces for last 3828 * @param nativeProcs optional list of native process names to dump stack crawls 3829 * @return file containing stack traces, or null if no dump file is configured 3830 */ 3831 public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids, 3832 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) { 3833 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 3834 if (tracesPath == null || tracesPath.length() == 0) { 3835 return null; 3836 } 3837 3838 File tracesFile = new File(tracesPath); 3839 try { 3840 File tracesDir = tracesFile.getParentFile(); 3841 if (!tracesDir.exists()) { 3842 tracesFile.mkdirs(); 3843 if (!SELinux.restorecon(tracesDir)) { 3844 return null; 3845 } 3846 } 3847 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 3848 3849 if (clearTraces && tracesFile.exists()) tracesFile.delete(); 3850 tracesFile.createNewFile(); 3851 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 3852 } catch (IOException e) { 3853 Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e); 3854 return null; 3855 } 3856 3857 dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs); 3858 return tracesFile; 3859 } 3860 3861 private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids, 3862 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) { 3863 // Use a FileObserver to detect when traces finish writing. 3864 // The order of traces is considered important to maintain for legibility. 3865 FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) { 3866 @Override 3867 public synchronized void onEvent(int event, String path) { notify(); } 3868 }; 3869 3870 try { 3871 observer.startWatching(); 3872 3873 // First collect all of the stacks of the most important pids. 3874 if (firstPids != null) { 3875 try { 3876 int num = firstPids.size(); 3877 for (int i = 0; i < num; i++) { 3878 synchronized (observer) { 3879 Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT); 3880 observer.wait(200); // Wait for write-close, give up after 200msec 3881 } 3882 } 3883 } catch (InterruptedException e) { 3884 Log.wtf(TAG, e); 3885 } 3886 } 3887 3888 // Next collect the stacks of the native pids 3889 if (nativeProcs != null) { 3890 int[] pids = Process.getPidsForCommands(nativeProcs); 3891 if (pids != null) { 3892 for (int pid : pids) { 3893 Debug.dumpNativeBacktraceToFile(pid, tracesPath); 3894 } 3895 } 3896 } 3897 3898 // Lastly, measure CPU usage. 3899 if (processCpuTracker != null) { 3900 processCpuTracker.init(); 3901 System.gc(); 3902 processCpuTracker.update(); 3903 try { 3904 synchronized (processCpuTracker) { 3905 processCpuTracker.wait(500); // measure over 1/2 second. 3906 } 3907 } catch (InterruptedException e) { 3908 } 3909 processCpuTracker.update(); 3910 3911 // We'll take the stack crawls of just the top apps using CPU. 3912 final int N = processCpuTracker.countWorkingStats(); 3913 int numProcs = 0; 3914 for (int i=0; i<N && numProcs<5; i++) { 3915 ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i); 3916 if (lastPids.indexOfKey(stats.pid) >= 0) { 3917 numProcs++; 3918 try { 3919 synchronized (observer) { 3920 Process.sendSignal(stats.pid, Process.SIGNAL_QUIT); 3921 observer.wait(200); // Wait for write-close, give up after 200msec 3922 } 3923 } catch (InterruptedException e) { 3924 Log.wtf(TAG, e); 3925 } 3926 3927 } 3928 } 3929 } 3930 } finally { 3931 observer.stopWatching(); 3932 } 3933 } 3934 3935 final void logAppTooSlow(ProcessRecord app, long startTime, String msg) { 3936 if (true || IS_USER_BUILD) { 3937 return; 3938 } 3939 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 3940 if (tracesPath == null || tracesPath.length() == 0) { 3941 return; 3942 } 3943 3944 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads(); 3945 StrictMode.allowThreadDiskWrites(); 3946 try { 3947 final File tracesFile = new File(tracesPath); 3948 final File tracesDir = tracesFile.getParentFile(); 3949 final File tracesTmp = new File(tracesDir, "__tmp__"); 3950 try { 3951 if (!tracesDir.exists()) { 3952 tracesFile.mkdirs(); 3953 if (!SELinux.restorecon(tracesDir.getPath())) { 3954 return; 3955 } 3956 } 3957 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 3958 3959 if (tracesFile.exists()) { 3960 tracesTmp.delete(); 3961 tracesFile.renameTo(tracesTmp); 3962 } 3963 StringBuilder sb = new StringBuilder(); 3964 Time tobj = new Time(); 3965 tobj.set(System.currentTimeMillis()); 3966 sb.append(tobj.format("%Y-%m-%d %H:%M:%S")); 3967 sb.append(": "); 3968 TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb); 3969 sb.append(" since "); 3970 sb.append(msg); 3971 FileOutputStream fos = new FileOutputStream(tracesFile); 3972 fos.write(sb.toString().getBytes()); 3973 if (app == null) { 3974 fos.write("\n*** No application process!".getBytes()); 3975 } 3976 fos.close(); 3977 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 3978 } catch (IOException e) { 3979 Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e); 3980 return; 3981 } 3982 3983 if (app != null) { 3984 ArrayList<Integer> firstPids = new ArrayList<Integer>(); 3985 firstPids.add(app.pid); 3986 dumpStackTraces(tracesPath, firstPids, null, null, null); 3987 } 3988 3989 File lastTracesFile = null; 3990 File curTracesFile = null; 3991 for (int i=9; i>=0; i--) { 3992 String name = String.format(Locale.US, "slow%02d.txt", i); 3993 curTracesFile = new File(tracesDir, name); 3994 if (curTracesFile.exists()) { 3995 if (lastTracesFile != null) { 3996 curTracesFile.renameTo(lastTracesFile); 3997 } else { 3998 curTracesFile.delete(); 3999 } 4000 } 4001 lastTracesFile = curTracesFile; 4002 } 4003 tracesFile.renameTo(curTracesFile); 4004 if (tracesTmp.exists()) { 4005 tracesTmp.renameTo(tracesFile); 4006 } 4007 } finally { 4008 StrictMode.setThreadPolicy(oldPolicy); 4009 } 4010 } 4011 4012 final void appNotResponding(ProcessRecord app, ActivityRecord activity, 4013 ActivityRecord parent, boolean aboveSystem, final String annotation) { 4014 ArrayList<Integer> firstPids = new ArrayList<Integer>(5); 4015 SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20); 4016 4017 if (mController != null) { 4018 try { 4019 // 0 == continue, -1 = kill process immediately 4020 int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation); 4021 if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid); 4022 } catch (RemoteException e) { 4023 mController = null; 4024 Watchdog.getInstance().setActivityController(null); 4025 } 4026 } 4027 4028 long anrTime = SystemClock.uptimeMillis(); 4029 if (MONITOR_CPU_USAGE) { 4030 updateCpuStatsNow(); 4031 } 4032 4033 synchronized (this) { 4034 // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down. 4035 if (mShuttingDown) { 4036 Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation); 4037 return; 4038 } else if (app.notResponding) { 4039 Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation); 4040 return; 4041 } else if (app.crashing) { 4042 Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation); 4043 return; 4044 } 4045 4046 // In case we come through here for the same app before completing 4047 // this one, mark as anring now so we will bail out. 4048 app.notResponding = true; 4049 4050 // Log the ANR to the event log. 4051 EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid, 4052 app.processName, app.info.flags, annotation); 4053 4054 // Dump thread traces as quickly as we can, starting with "interesting" processes. 4055 firstPids.add(app.pid); 4056 4057 int parentPid = app.pid; 4058 if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid; 4059 if (parentPid != app.pid) firstPids.add(parentPid); 4060 4061 if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID); 4062 4063 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 4064 ProcessRecord r = mLruProcesses.get(i); 4065 if (r != null && r.thread != null) { 4066 int pid = r.pid; 4067 if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) { 4068 if (r.persistent) { 4069 firstPids.add(pid); 4070 } else { 4071 lastPids.put(pid, Boolean.TRUE); 4072 } 4073 } 4074 } 4075 } 4076 } 4077 4078 // Log the ANR to the main log. 4079 StringBuilder info = new StringBuilder(); 4080 info.setLength(0); 4081 info.append("ANR in ").append(app.processName); 4082 if (activity != null && activity.shortComponentName != null) { 4083 info.append(" (").append(activity.shortComponentName).append(")"); 4084 } 4085 info.append("\n"); 4086 info.append("PID: ").append(app.pid).append("\n"); 4087 if (annotation != null) { 4088 info.append("Reason: ").append(annotation).append("\n"); 4089 } 4090 if (parent != null && parent != activity) { 4091 info.append("Parent: ").append(parent.shortComponentName).append("\n"); 4092 } 4093 4094 final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true); 4095 4096 File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids, 4097 NATIVE_STACKS_OF_INTEREST); 4098 4099 String cpuInfo = null; 4100 if (MONITOR_CPU_USAGE) { 4101 updateCpuStatsNow(); 4102 synchronized (mProcessCpuThread) { 4103 cpuInfo = mProcessCpuTracker.printCurrentState(anrTime); 4104 } 4105 info.append(processCpuTracker.printCurrentLoad()); 4106 info.append(cpuInfo); 4107 } 4108 4109 info.append(processCpuTracker.printCurrentState(anrTime)); 4110 4111 Slog.e(TAG, info.toString()); 4112 if (tracesFile == null) { 4113 // There is no trace file, so dump (only) the alleged culprit's threads to the log 4114 Process.sendSignal(app.pid, Process.SIGNAL_QUIT); 4115 } 4116 4117 addErrorToDropBox("anr", app, app.processName, activity, parent, annotation, 4118 cpuInfo, tracesFile, null); 4119 4120 if (mController != null) { 4121 try { 4122 // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately 4123 int res = mController.appNotResponding(app.processName, app.pid, info.toString()); 4124 if (res != 0) { 4125 if (res < 0 && app.pid != MY_PID) { 4126 Process.killProcess(app.pid); 4127 } else { 4128 synchronized (this) { 4129 mServices.scheduleServiceTimeoutLocked(app); 4130 } 4131 } 4132 return; 4133 } 4134 } catch (RemoteException e) { 4135 mController = null; 4136 Watchdog.getInstance().setActivityController(null); 4137 } 4138 } 4139 4140 // Unless configured otherwise, swallow ANRs in background processes & kill the process. 4141 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), 4142 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; 4143 4144 synchronized (this) { 4145 if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) { 4146 killUnneededProcessLocked(app, "background ANR"); 4147 return; 4148 } 4149 4150 // Set the app's notResponding state, and look up the errorReportReceiver 4151 makeAppNotRespondingLocked(app, 4152 activity != null ? activity.shortComponentName : null, 4153 annotation != null ? "ANR " + annotation : "ANR", 4154 info.toString()); 4155 4156 // Bring up the infamous App Not Responding dialog 4157 Message msg = Message.obtain(); 4158 HashMap<String, Object> map = new HashMap<String, Object>(); 4159 msg.what = SHOW_NOT_RESPONDING_MSG; 4160 msg.obj = map; 4161 msg.arg1 = aboveSystem ? 1 : 0; 4162 map.put("app", app); 4163 if (activity != null) { 4164 map.put("activity", activity); 4165 } 4166 4167 mHandler.sendMessage(msg); 4168 } 4169 } 4170 4171 final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) { 4172 if (!mLaunchWarningShown) { 4173 mLaunchWarningShown = true; 4174 mHandler.post(new Runnable() { 4175 @Override 4176 public void run() { 4177 synchronized (ActivityManagerService.this) { 4178 final Dialog d = new LaunchWarningWindow(mContext, cur, next); 4179 d.show(); 4180 mHandler.postDelayed(new Runnable() { 4181 @Override 4182 public void run() { 4183 synchronized (ActivityManagerService.this) { 4184 d.dismiss(); 4185 mLaunchWarningShown = false; 4186 } 4187 } 4188 }, 4000); 4189 } 4190 } 4191 }); 4192 } 4193 } 4194 4195 @Override 4196 public boolean clearApplicationUserData(final String packageName, 4197 final IPackageDataObserver observer, int userId) { 4198 enforceNotIsolatedCaller("clearApplicationUserData"); 4199 int uid = Binder.getCallingUid(); 4200 int pid = Binder.getCallingPid(); 4201 userId = handleIncomingUser(pid, uid, 4202 userId, false, true, "clearApplicationUserData", null); 4203 long callingId = Binder.clearCallingIdentity(); 4204 try { 4205 IPackageManager pm = AppGlobals.getPackageManager(); 4206 int pkgUid = -1; 4207 synchronized(this) { 4208 try { 4209 pkgUid = pm.getPackageUid(packageName, userId); 4210 } catch (RemoteException e) { 4211 } 4212 if (pkgUid == -1) { 4213 Slog.w(TAG, "Invalid packageName: " + packageName); 4214 if (observer != null) { 4215 try { 4216 observer.onRemoveCompleted(packageName, false); 4217 } catch (RemoteException e) { 4218 Slog.i(TAG, "Observer no longer exists."); 4219 } 4220 } 4221 return false; 4222 } 4223 if (uid == pkgUid || checkComponentPermission( 4224 android.Manifest.permission.CLEAR_APP_USER_DATA, 4225 pid, uid, -1, true) 4226 == PackageManager.PERMISSION_GRANTED) { 4227 forceStopPackageLocked(packageName, pkgUid, "clear data"); 4228 } else { 4229 throw new SecurityException("PID " + pid + " does not have permission " 4230 + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data" 4231 + " of package " + packageName); 4232 } 4233 } 4234 4235 try { 4236 // Clear application user data 4237 pm.clearApplicationUserData(packageName, observer, userId); 4238 4239 // Remove all permissions granted from/to this package 4240 removeUriPermissionsForPackageLocked(packageName, userId, true); 4241 4242 Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED, 4243 Uri.fromParts("package", packageName, null)); 4244 intent.putExtra(Intent.EXTRA_UID, pkgUid); 4245 broadcastIntentInPackage("android", Process.SYSTEM_UID, intent, 4246 null, null, 0, null, null, null, false, false, userId); 4247 } catch (RemoteException e) { 4248 } 4249 } finally { 4250 Binder.restoreCallingIdentity(callingId); 4251 } 4252 return true; 4253 } 4254 4255 @Override 4256 public void killBackgroundProcesses(final String packageName, int userId) { 4257 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 4258 != PackageManager.PERMISSION_GRANTED && 4259 checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES) 4260 != PackageManager.PERMISSION_GRANTED) { 4261 String msg = "Permission Denial: killBackgroundProcesses() from pid=" 4262 + Binder.getCallingPid() 4263 + ", uid=" + Binder.getCallingUid() 4264 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 4265 Slog.w(TAG, msg); 4266 throw new SecurityException(msg); 4267 } 4268 4269 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 4270 userId, true, true, "killBackgroundProcesses", null); 4271 long callingId = Binder.clearCallingIdentity(); 4272 try { 4273 IPackageManager pm = AppGlobals.getPackageManager(); 4274 synchronized(this) { 4275 int appId = -1; 4276 try { 4277 appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0)); 4278 } catch (RemoteException e) { 4279 } 4280 if (appId == -1) { 4281 Slog.w(TAG, "Invalid packageName: " + packageName); 4282 return; 4283 } 4284 killPackageProcessesLocked(packageName, appId, userId, 4285 ProcessList.SERVICE_ADJ, false, true, true, false, "kill background"); 4286 } 4287 } finally { 4288 Binder.restoreCallingIdentity(callingId); 4289 } 4290 } 4291 4292 @Override 4293 public void killAllBackgroundProcesses() { 4294 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 4295 != PackageManager.PERMISSION_GRANTED) { 4296 String msg = "Permission Denial: killAllBackgroundProcesses() from pid=" 4297 + Binder.getCallingPid() 4298 + ", uid=" + Binder.getCallingUid() 4299 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 4300 Slog.w(TAG, msg); 4301 throw new SecurityException(msg); 4302 } 4303 4304 long callingId = Binder.clearCallingIdentity(); 4305 try { 4306 synchronized(this) { 4307 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 4308 final int NP = mProcessNames.getMap().size(); 4309 for (int ip=0; ip<NP; ip++) { 4310 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 4311 final int NA = apps.size(); 4312 for (int ia=0; ia<NA; ia++) { 4313 ProcessRecord app = apps.valueAt(ia); 4314 if (app.persistent) { 4315 // we don't kill persistent processes 4316 continue; 4317 } 4318 if (app.removed) { 4319 procs.add(app); 4320 } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 4321 app.removed = true; 4322 procs.add(app); 4323 } 4324 } 4325 } 4326 4327 int N = procs.size(); 4328 for (int i=0; i<N; i++) { 4329 removeProcessLocked(procs.get(i), false, true, "kill all background"); 4330 } 4331 mAllowLowerMemLevel = true; 4332 updateOomAdjLocked(); 4333 doLowMemReportIfNeededLocked(null); 4334 } 4335 } finally { 4336 Binder.restoreCallingIdentity(callingId); 4337 } 4338 } 4339 4340 @Override 4341 public void forceStopPackage(final String packageName, int userId) { 4342 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 4343 != PackageManager.PERMISSION_GRANTED) { 4344 String msg = "Permission Denial: forceStopPackage() from pid=" 4345 + Binder.getCallingPid() 4346 + ", uid=" + Binder.getCallingUid() 4347 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 4348 Slog.w(TAG, msg); 4349 throw new SecurityException(msg); 4350 } 4351 final int callingPid = Binder.getCallingPid(); 4352 userId = handleIncomingUser(callingPid, Binder.getCallingUid(), 4353 userId, true, true, "forceStopPackage", null); 4354 long callingId = Binder.clearCallingIdentity(); 4355 try { 4356 IPackageManager pm = AppGlobals.getPackageManager(); 4357 synchronized(this) { 4358 int[] users = userId == UserHandle.USER_ALL 4359 ? getUsersLocked() : new int[] { userId }; 4360 for (int user : users) { 4361 int pkgUid = -1; 4362 try { 4363 pkgUid = pm.getPackageUid(packageName, user); 4364 } catch (RemoteException e) { 4365 } 4366 if (pkgUid == -1) { 4367 Slog.w(TAG, "Invalid packageName: " + packageName); 4368 continue; 4369 } 4370 try { 4371 pm.setPackageStoppedState(packageName, true, user); 4372 } catch (RemoteException e) { 4373 } catch (IllegalArgumentException e) { 4374 Slog.w(TAG, "Failed trying to unstop package " 4375 + packageName + ": " + e); 4376 } 4377 if (isUserRunningLocked(user, false)) { 4378 forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid); 4379 } 4380 } 4381 } 4382 } finally { 4383 Binder.restoreCallingIdentity(callingId); 4384 } 4385 } 4386 4387 /* 4388 * The pkg name and app id have to be specified. 4389 */ 4390 @Override 4391 public void killApplicationWithAppId(String pkg, int appid, String reason) { 4392 if (pkg == null) { 4393 return; 4394 } 4395 // Make sure the uid is valid. 4396 if (appid < 0) { 4397 Slog.w(TAG, "Invalid appid specified for pkg : " + pkg); 4398 return; 4399 } 4400 int callerUid = Binder.getCallingUid(); 4401 // Only the system server can kill an application 4402 if (callerUid == Process.SYSTEM_UID) { 4403 // Post an aysnc message to kill the application 4404 Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG); 4405 msg.arg1 = appid; 4406 msg.arg2 = 0; 4407 Bundle bundle = new Bundle(); 4408 bundle.putString("pkg", pkg); 4409 bundle.putString("reason", reason); 4410 msg.obj = bundle; 4411 mHandler.sendMessage(msg); 4412 } else { 4413 throw new SecurityException(callerUid + " cannot kill pkg: " + 4414 pkg); 4415 } 4416 } 4417 4418 @Override 4419 public void closeSystemDialogs(String reason) { 4420 enforceNotIsolatedCaller("closeSystemDialogs"); 4421 4422 final int pid = Binder.getCallingPid(); 4423 final int uid = Binder.getCallingUid(); 4424 final long origId = Binder.clearCallingIdentity(); 4425 try { 4426 synchronized (this) { 4427 // Only allow this from foreground processes, so that background 4428 // applications can't abuse it to prevent system UI from being shown. 4429 if (uid >= Process.FIRST_APPLICATION_UID) { 4430 ProcessRecord proc; 4431 synchronized (mPidsSelfLocked) { 4432 proc = mPidsSelfLocked.get(pid); 4433 } 4434 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 4435 Slog.w(TAG, "Ignoring closeSystemDialogs " + reason 4436 + " from background process " + proc); 4437 return; 4438 } 4439 } 4440 closeSystemDialogsLocked(reason); 4441 } 4442 } finally { 4443 Binder.restoreCallingIdentity(origId); 4444 } 4445 } 4446 4447 void closeSystemDialogsLocked(String reason) { 4448 Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS); 4449 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 4450 | Intent.FLAG_RECEIVER_FOREGROUND); 4451 if (reason != null) { 4452 intent.putExtra("reason", reason); 4453 } 4454 mWindowManager.closeSystemDialogs(reason); 4455 4456 mStackSupervisor.closeSystemDialogsLocked(); 4457 4458 broadcastIntentLocked(null, null, intent, null, 4459 null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1, 4460 Process.SYSTEM_UID, UserHandle.USER_ALL); 4461 } 4462 4463 @Override 4464 public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) { 4465 enforceNotIsolatedCaller("getProcessMemoryInfo"); 4466 Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length]; 4467 for (int i=pids.length-1; i>=0; i--) { 4468 ProcessRecord proc; 4469 int oomAdj; 4470 synchronized (this) { 4471 synchronized (mPidsSelfLocked) { 4472 proc = mPidsSelfLocked.get(pids[i]); 4473 oomAdj = proc != null ? proc.setAdj : 0; 4474 } 4475 } 4476 infos[i] = new Debug.MemoryInfo(); 4477 Debug.getMemoryInfo(pids[i], infos[i]); 4478 if (proc != null) { 4479 synchronized (this) { 4480 if (proc.thread != null && proc.setAdj == oomAdj) { 4481 // Record this for posterity if the process has been stable. 4482 proc.baseProcessTracker.addPss(infos[i].getTotalPss(), 4483 infos[i].getTotalUss(), false, proc.pkgList); 4484 } 4485 } 4486 } 4487 } 4488 return infos; 4489 } 4490 4491 @Override 4492 public long[] getProcessPss(int[] pids) { 4493 enforceNotIsolatedCaller("getProcessPss"); 4494 long[] pss = new long[pids.length]; 4495 for (int i=pids.length-1; i>=0; i--) { 4496 ProcessRecord proc; 4497 int oomAdj; 4498 synchronized (this) { 4499 synchronized (mPidsSelfLocked) { 4500 proc = mPidsSelfLocked.get(pids[i]); 4501 oomAdj = proc != null ? proc.setAdj : 0; 4502 } 4503 } 4504 long[] tmpUss = new long[1]; 4505 pss[i] = Debug.getPss(pids[i], tmpUss); 4506 if (proc != null) { 4507 synchronized (this) { 4508 if (proc.thread != null && proc.setAdj == oomAdj) { 4509 // Record this for posterity if the process has been stable. 4510 proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList); 4511 } 4512 } 4513 } 4514 } 4515 return pss; 4516 } 4517 4518 @Override 4519 public void killApplicationProcess(String processName, int uid) { 4520 if (processName == null) { 4521 return; 4522 } 4523 4524 int callerUid = Binder.getCallingUid(); 4525 // Only the system server can kill an application 4526 if (callerUid == Process.SYSTEM_UID) { 4527 synchronized (this) { 4528 ProcessRecord app = getProcessRecordLocked(processName, uid, true); 4529 if (app != null && app.thread != null) { 4530 try { 4531 app.thread.scheduleSuicide(); 4532 } catch (RemoteException e) { 4533 // If the other end already died, then our work here is done. 4534 } 4535 } else { 4536 Slog.w(TAG, "Process/uid not found attempting kill of " 4537 + processName + " / " + uid); 4538 } 4539 } 4540 } else { 4541 throw new SecurityException(callerUid + " cannot kill app process: " + 4542 processName); 4543 } 4544 } 4545 4546 private void forceStopPackageLocked(final String packageName, int uid, String reason) { 4547 forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false, 4548 false, true, false, false, UserHandle.getUserId(uid), reason); 4549 Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED, 4550 Uri.fromParts("package", packageName, null)); 4551 if (!mProcessesReady) { 4552 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 4553 | Intent.FLAG_RECEIVER_FOREGROUND); 4554 } 4555 intent.putExtra(Intent.EXTRA_UID, uid); 4556 intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid)); 4557 broadcastIntentLocked(null, null, intent, 4558 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 4559 false, false, 4560 MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid)); 4561 } 4562 4563 private void forceStopUserLocked(int userId, String reason) { 4564 forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason); 4565 Intent intent = new Intent(Intent.ACTION_USER_STOPPED); 4566 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 4567 | Intent.FLAG_RECEIVER_FOREGROUND); 4568 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 4569 broadcastIntentLocked(null, null, intent, 4570 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 4571 false, false, 4572 MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 4573 } 4574 4575 private final boolean killPackageProcessesLocked(String packageName, int appId, 4576 int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart, 4577 boolean doit, boolean evenPersistent, String reason) { 4578 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 4579 4580 // Remove all processes this package may have touched: all with the 4581 // same UID (except for the system or root user), and all whose name 4582 // matches the package name. 4583 final String procNamePrefix = packageName != null ? (packageName + ":") : null; 4584 final int NP = mProcessNames.getMap().size(); 4585 for (int ip=0; ip<NP; ip++) { 4586 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 4587 final int NA = apps.size(); 4588 for (int ia=0; ia<NA; ia++) { 4589 ProcessRecord app = apps.valueAt(ia); 4590 if (app.persistent && !evenPersistent) { 4591 // we don't kill persistent processes 4592 continue; 4593 } 4594 if (app.removed) { 4595 if (doit) { 4596 procs.add(app); 4597 } 4598 continue; 4599 } 4600 4601 // Skip process if it doesn't meet our oom adj requirement. 4602 if (app.setAdj < minOomAdj) { 4603 continue; 4604 } 4605 4606 // If no package is specified, we call all processes under the 4607 // give user id. 4608 if (packageName == null) { 4609 if (app.userId != userId) { 4610 continue; 4611 } 4612 if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) { 4613 continue; 4614 } 4615 // Package has been specified, we want to hit all processes 4616 // that match it. We need to qualify this by the processes 4617 // that are running under the specified app and user ID. 4618 } else { 4619 if (UserHandle.getAppId(app.uid) != appId) { 4620 continue; 4621 } 4622 if (userId != UserHandle.USER_ALL && app.userId != userId) { 4623 continue; 4624 } 4625 if (!app.pkgList.containsKey(packageName)) { 4626 continue; 4627 } 4628 } 4629 4630 // Process has passed all conditions, kill it! 4631 if (!doit) { 4632 return true; 4633 } 4634 app.removed = true; 4635 procs.add(app); 4636 } 4637 } 4638 4639 int N = procs.size(); 4640 for (int i=0; i<N; i++) { 4641 removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason); 4642 } 4643 updateOomAdjLocked(); 4644 return N > 0; 4645 } 4646 4647 private final boolean forceStopPackageLocked(String name, int appId, 4648 boolean callerWillRestart, boolean purgeCache, boolean doit, 4649 boolean evenPersistent, boolean uninstalling, int userId, String reason) { 4650 int i; 4651 int N; 4652 4653 if (userId == UserHandle.USER_ALL && name == null) { 4654 Slog.w(TAG, "Can't force stop all processes of all users, that is insane!"); 4655 } 4656 4657 if (appId < 0 && name != null) { 4658 try { 4659 appId = UserHandle.getAppId( 4660 AppGlobals.getPackageManager().getPackageUid(name, 0)); 4661 } catch (RemoteException e) { 4662 } 4663 } 4664 4665 if (doit) { 4666 if (name != null) { 4667 Slog.i(TAG, "Force stopping " + name + " appid=" + appId 4668 + " user=" + userId + ": " + reason); 4669 } else { 4670 Slog.i(TAG, "Force stopping u" + userId + ": " + reason); 4671 } 4672 4673 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap(); 4674 for (int ip=pmap.size()-1; ip>=0; ip--) { 4675 SparseArray<Long> ba = pmap.valueAt(ip); 4676 for (i=ba.size()-1; i>=0; i--) { 4677 boolean remove = false; 4678 final int entUid = ba.keyAt(i); 4679 if (name != null) { 4680 if (userId == UserHandle.USER_ALL) { 4681 if (UserHandle.getAppId(entUid) == appId) { 4682 remove = true; 4683 } 4684 } else { 4685 if (entUid == UserHandle.getUid(userId, appId)) { 4686 remove = true; 4687 } 4688 } 4689 } else if (UserHandle.getUserId(entUid) == userId) { 4690 remove = true; 4691 } 4692 if (remove) { 4693 ba.removeAt(i); 4694 } 4695 } 4696 if (ba.size() == 0) { 4697 pmap.removeAt(ip); 4698 } 4699 } 4700 } 4701 4702 boolean didSomething = killPackageProcessesLocked(name, appId, userId, 4703 -100, callerWillRestart, true, doit, evenPersistent, 4704 name == null ? ("stop user " + userId) : ("stop " + name)); 4705 4706 if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) { 4707 if (!doit) { 4708 return true; 4709 } 4710 didSomething = true; 4711 } 4712 4713 if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) { 4714 if (!doit) { 4715 return true; 4716 } 4717 didSomething = true; 4718 } 4719 4720 if (name == null) { 4721 // Remove all sticky broadcasts from this user. 4722 mStickyBroadcasts.remove(userId); 4723 } 4724 4725 ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>(); 4726 if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent, 4727 userId, providers)) { 4728 if (!doit) { 4729 return true; 4730 } 4731 didSomething = true; 4732 } 4733 N = providers.size(); 4734 for (i=0; i<N; i++) { 4735 removeDyingProviderLocked(null, providers.get(i), true); 4736 } 4737 4738 // Remove transient permissions granted from/to this package/user 4739 removeUriPermissionsForPackageLocked(name, userId, false); 4740 4741 if (name == null || uninstalling) { 4742 // Remove pending intents. For now we only do this when force 4743 // stopping users, because we have some problems when doing this 4744 // for packages -- app widgets are not currently cleaned up for 4745 // such packages, so they can be left with bad pending intents. 4746 if (mIntentSenderRecords.size() > 0) { 4747 Iterator<WeakReference<PendingIntentRecord>> it 4748 = mIntentSenderRecords.values().iterator(); 4749 while (it.hasNext()) { 4750 WeakReference<PendingIntentRecord> wpir = it.next(); 4751 if (wpir == null) { 4752 it.remove(); 4753 continue; 4754 } 4755 PendingIntentRecord pir = wpir.get(); 4756 if (pir == null) { 4757 it.remove(); 4758 continue; 4759 } 4760 if (name == null) { 4761 // Stopping user, remove all objects for the user. 4762 if (pir.key.userId != userId) { 4763 // Not the same user, skip it. 4764 continue; 4765 } 4766 } else { 4767 if (UserHandle.getAppId(pir.uid) != appId) { 4768 // Different app id, skip it. 4769 continue; 4770 } 4771 if (userId != UserHandle.USER_ALL && pir.key.userId != userId) { 4772 // Different user, skip it. 4773 continue; 4774 } 4775 if (!pir.key.packageName.equals(name)) { 4776 // Different package, skip it. 4777 continue; 4778 } 4779 } 4780 if (!doit) { 4781 return true; 4782 } 4783 didSomething = true; 4784 it.remove(); 4785 pir.canceled = true; 4786 if (pir.key.activity != null) { 4787 pir.key.activity.pendingResults.remove(pir.ref); 4788 } 4789 } 4790 } 4791 } 4792 4793 if (doit) { 4794 if (purgeCache && name != null) { 4795 AttributeCache ac = AttributeCache.instance(); 4796 if (ac != null) { 4797 ac.removePackage(name); 4798 } 4799 } 4800 if (mBooted) { 4801 mStackSupervisor.resumeTopActivitiesLocked(); 4802 mStackSupervisor.scheduleIdleLocked(); 4803 } 4804 } 4805 4806 return didSomething; 4807 } 4808 4809 private final boolean removeProcessLocked(ProcessRecord app, 4810 boolean callerWillRestart, boolean allowRestart, String reason) { 4811 final String name = app.processName; 4812 final int uid = app.uid; 4813 if (DEBUG_PROCESSES) Slog.d( 4814 TAG, "Force removing proc " + app.toShortString() + " (" + name 4815 + "/" + uid + ")"); 4816 4817 mProcessNames.remove(name, uid); 4818 mIsolatedProcesses.remove(app.uid); 4819 if (mHeavyWeightProcess == app) { 4820 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 4821 mHeavyWeightProcess.userId, 0)); 4822 mHeavyWeightProcess = null; 4823 } 4824 boolean needRestart = false; 4825 if (app.pid > 0 && app.pid != MY_PID) { 4826 int pid = app.pid; 4827 synchronized (mPidsSelfLocked) { 4828 mPidsSelfLocked.remove(pid); 4829 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 4830 } 4831 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH, 4832 app.processName, app.info.uid); 4833 if (app.isolated) { 4834 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 4835 } 4836 killUnneededProcessLocked(app, reason); 4837 handleAppDiedLocked(app, true, allowRestart); 4838 removeLruProcessLocked(app); 4839 4840 if (app.persistent && !app.isolated) { 4841 if (!callerWillRestart) { 4842 addAppLocked(app.info, false); 4843 } else { 4844 needRestart = true; 4845 } 4846 } 4847 } else { 4848 mRemovedProcesses.add(app); 4849 } 4850 4851 return needRestart; 4852 } 4853 4854 private final void processStartTimedOutLocked(ProcessRecord app) { 4855 final int pid = app.pid; 4856 boolean gone = false; 4857 synchronized (mPidsSelfLocked) { 4858 ProcessRecord knownApp = mPidsSelfLocked.get(pid); 4859 if (knownApp != null && knownApp.thread == null) { 4860 mPidsSelfLocked.remove(pid); 4861 gone = true; 4862 } 4863 } 4864 4865 if (gone) { 4866 Slog.w(TAG, "Process " + app + " failed to attach"); 4867 EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId, 4868 pid, app.uid, app.processName); 4869 mProcessNames.remove(app.processName, app.uid); 4870 mIsolatedProcesses.remove(app.uid); 4871 if (mHeavyWeightProcess == app) { 4872 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 4873 mHeavyWeightProcess.userId, 0)); 4874 mHeavyWeightProcess = null; 4875 } 4876 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH, 4877 app.processName, app.info.uid); 4878 if (app.isolated) { 4879 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 4880 } 4881 // Take care of any launching providers waiting for this process. 4882 checkAppInLaunchingProvidersLocked(app, true); 4883 // Take care of any services that are waiting for the process. 4884 mServices.processStartTimedOutLocked(app); 4885 killUnneededProcessLocked(app, "start timeout"); 4886 if (mBackupTarget != null && mBackupTarget.app.pid == pid) { 4887 Slog.w(TAG, "Unattached app died before backup, skipping"); 4888 try { 4889 IBackupManager bm = IBackupManager.Stub.asInterface( 4890 ServiceManager.getService(Context.BACKUP_SERVICE)); 4891 bm.agentDisconnected(app.info.packageName); 4892 } catch (RemoteException e) { 4893 // Can't happen; the backup manager is local 4894 } 4895 } 4896 if (isPendingBroadcastProcessLocked(pid)) { 4897 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 4898 skipPendingBroadcastLocked(pid); 4899 } 4900 } else { 4901 Slog.w(TAG, "Spurious process start timeout - pid not known for " + app); 4902 } 4903 } 4904 4905 private final boolean attachApplicationLocked(IApplicationThread thread, 4906 int pid) { 4907 4908 // Find the application record that is being attached... either via 4909 // the pid if we are running in multiple processes, or just pull the 4910 // next app record if we are emulating process with anonymous threads. 4911 ProcessRecord app; 4912 if (pid != MY_PID && pid >= 0) { 4913 synchronized (mPidsSelfLocked) { 4914 app = mPidsSelfLocked.get(pid); 4915 } 4916 } else { 4917 app = null; 4918 } 4919 4920 if (app == null) { 4921 Slog.w(TAG, "No pending application record for pid " + pid 4922 + " (IApplicationThread " + thread + "); dropping process"); 4923 EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid); 4924 if (pid > 0 && pid != MY_PID) { 4925 Process.killProcessQuiet(pid); 4926 } else { 4927 try { 4928 thread.scheduleExit(); 4929 } catch (Exception e) { 4930 // Ignore exceptions. 4931 } 4932 } 4933 return false; 4934 } 4935 4936 // If this application record is still attached to a previous 4937 // process, clean it up now. 4938 if (app.thread != null) { 4939 handleAppDiedLocked(app, true, true); 4940 } 4941 4942 // Tell the process all about itself. 4943 4944 if (localLOGV) Slog.v( 4945 TAG, "Binding process pid " + pid + " to record " + app); 4946 4947 final String processName = app.processName; 4948 try { 4949 AppDeathRecipient adr = new AppDeathRecipient( 4950 app, pid, thread); 4951 thread.asBinder().linkToDeath(adr, 0); 4952 app.deathRecipient = adr; 4953 } catch (RemoteException e) { 4954 app.resetPackageList(mProcessStats); 4955 startProcessLocked(app, "link fail", processName); 4956 return false; 4957 } 4958 4959 EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName); 4960 4961 app.makeActive(thread, mProcessStats); 4962 app.curAdj = app.setAdj = -100; 4963 app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT; 4964 app.forcingToForeground = null; 4965 updateProcessForegroundLocked(app, false, false); 4966 app.hasShownUi = false; 4967 app.debugging = false; 4968 app.cached = false; 4969 4970 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 4971 4972 boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info); 4973 List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null; 4974 4975 if (!normalMode) { 4976 Slog.i(TAG, "Launching preboot mode app: " + app); 4977 } 4978 4979 if (localLOGV) Slog.v( 4980 TAG, "New app record " + app 4981 + " thread=" + thread.asBinder() + " pid=" + pid); 4982 try { 4983 int testMode = IApplicationThread.DEBUG_OFF; 4984 if (mDebugApp != null && mDebugApp.equals(processName)) { 4985 testMode = mWaitForDebugger 4986 ? IApplicationThread.DEBUG_WAIT 4987 : IApplicationThread.DEBUG_ON; 4988 app.debugging = true; 4989 if (mDebugTransient) { 4990 mDebugApp = mOrigDebugApp; 4991 mWaitForDebugger = mOrigWaitForDebugger; 4992 } 4993 } 4994 String profileFile = app.instrumentationProfileFile; 4995 ParcelFileDescriptor profileFd = null; 4996 boolean profileAutoStop = false; 4997 if (mProfileApp != null && mProfileApp.equals(processName)) { 4998 mProfileProc = app; 4999 profileFile = mProfileFile; 5000 profileFd = mProfileFd; 5001 profileAutoStop = mAutoStopProfiler; 5002 } 5003 boolean enableOpenGlTrace = false; 5004 if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) { 5005 enableOpenGlTrace = true; 5006 mOpenGlTraceApp = null; 5007 } 5008 5009 // If the app is being launched for restore or full backup, set it up specially 5010 boolean isRestrictedBackupMode = false; 5011 if (mBackupTarget != null && mBackupAppName.equals(processName)) { 5012 isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE) 5013 || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL) 5014 || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL); 5015 } 5016 5017 ensurePackageDexOpt(app.instrumentationInfo != null 5018 ? app.instrumentationInfo.packageName 5019 : app.info.packageName); 5020 if (app.instrumentationClass != null) { 5021 ensurePackageDexOpt(app.instrumentationClass.getPackageName()); 5022 } 5023 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc " 5024 + processName + " with config " + mConfiguration); 5025 ApplicationInfo appInfo = app.instrumentationInfo != null 5026 ? app.instrumentationInfo : app.info; 5027 app.compat = compatibilityInfoForPackageLocked(appInfo); 5028 if (profileFd != null) { 5029 profileFd = profileFd.dup(); 5030 } 5031 thread.bindApplication(processName, appInfo, providers, 5032 app.instrumentationClass, profileFile, profileFd, profileAutoStop, 5033 app.instrumentationArguments, app.instrumentationWatcher, 5034 app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace, 5035 isRestrictedBackupMode || !normalMode, app.persistent, 5036 new Configuration(mConfiguration), app.compat, getCommonServicesLocked(), 5037 mCoreSettingsObserver.getCoreSettingsLocked()); 5038 updateLruProcessLocked(app, false, null); 5039 app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis(); 5040 } catch (Exception e) { 5041 // todo: Yikes! What should we do? For now we will try to 5042 // start another process, but that could easily get us in 5043 // an infinite loop of restarting processes... 5044 Slog.w(TAG, "Exception thrown during bind!", e); 5045 5046 app.resetPackageList(mProcessStats); 5047 app.unlinkDeathRecipient(); 5048 startProcessLocked(app, "bind fail", processName); 5049 return false; 5050 } 5051 5052 // Remove this record from the list of starting applications. 5053 mPersistentStartingProcesses.remove(app); 5054 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 5055 "Attach application locked removing on hold: " + app); 5056 mProcessesOnHold.remove(app); 5057 5058 boolean badApp = false; 5059 boolean didSomething = false; 5060 5061 // See if the top visible activity is waiting to run in this process... 5062 if (normalMode) { 5063 try { 5064 if (mStackSupervisor.attachApplicationLocked(app)) { 5065 didSomething = true; 5066 } 5067 } catch (Exception e) { 5068 badApp = true; 5069 } 5070 } 5071 5072 // Find any services that should be running in this process... 5073 if (!badApp) { 5074 try { 5075 didSomething |= mServices.attachApplicationLocked(app, processName); 5076 } catch (Exception e) { 5077 badApp = true; 5078 } 5079 } 5080 5081 // Check if a next-broadcast receiver is in this process... 5082 if (!badApp && isPendingBroadcastProcessLocked(pid)) { 5083 try { 5084 didSomething |= sendPendingBroadcastsLocked(app); 5085 } catch (Exception e) { 5086 // If the app died trying to launch the receiver we declare it 'bad' 5087 badApp = true; 5088 } 5089 } 5090 5091 // Check whether the next backup agent is in this process... 5092 if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) { 5093 if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app); 5094 ensurePackageDexOpt(mBackupTarget.appInfo.packageName); 5095 try { 5096 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo, 5097 compatibilityInfoForPackageLocked(mBackupTarget.appInfo), 5098 mBackupTarget.backupMode); 5099 } catch (Exception e) { 5100 Slog.w(TAG, "Exception scheduling backup agent creation: "); 5101 e.printStackTrace(); 5102 } 5103 } 5104 5105 if (badApp) { 5106 // todo: Also need to kill application to deal with all 5107 // kinds of exceptions. 5108 handleAppDiedLocked(app, false, true); 5109 return false; 5110 } 5111 5112 if (!didSomething) { 5113 updateOomAdjLocked(); 5114 } 5115 5116 return true; 5117 } 5118 5119 @Override 5120 public final void attachApplication(IApplicationThread thread) { 5121 synchronized (this) { 5122 int callingPid = Binder.getCallingPid(); 5123 final long origId = Binder.clearCallingIdentity(); 5124 attachApplicationLocked(thread, callingPid); 5125 Binder.restoreCallingIdentity(origId); 5126 } 5127 } 5128 5129 @Override 5130 public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) { 5131 final long origId = Binder.clearCallingIdentity(); 5132 synchronized (this) { 5133 ActivityStack stack = ActivityRecord.getStackLocked(token); 5134 if (stack != null) { 5135 ActivityRecord r = 5136 mStackSupervisor.activityIdleInternalLocked(token, false, config); 5137 if (stopProfiling) { 5138 if ((mProfileProc == r.app) && (mProfileFd != null)) { 5139 try { 5140 mProfileFd.close(); 5141 } catch (IOException e) { 5142 } 5143 clearProfilerLocked(); 5144 } 5145 } 5146 } 5147 } 5148 Binder.restoreCallingIdentity(origId); 5149 } 5150 5151 void enableScreenAfterBoot() { 5152 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN, 5153 SystemClock.uptimeMillis()); 5154 mWindowManager.enableScreenAfterBoot(); 5155 5156 synchronized (this) { 5157 updateEventDispatchingLocked(); 5158 } 5159 } 5160 5161 @Override 5162 public void showBootMessage(final CharSequence msg, final boolean always) { 5163 enforceNotIsolatedCaller("showBootMessage"); 5164 mWindowManager.showBootMessage(msg, always); 5165 } 5166 5167 @Override 5168 public void dismissKeyguardOnNextActivity() { 5169 enforceNotIsolatedCaller("dismissKeyguardOnNextActivity"); 5170 final long token = Binder.clearCallingIdentity(); 5171 try { 5172 synchronized (this) { 5173 if (DEBUG_LOCKSCREEN) logLockScreen(""); 5174 if (mLockScreenShown) { 5175 mLockScreenShown = false; 5176 comeOutOfSleepIfNeededLocked(); 5177 } 5178 mStackSupervisor.setDismissKeyguard(true); 5179 } 5180 } finally { 5181 Binder.restoreCallingIdentity(token); 5182 } 5183 } 5184 5185 final void finishBooting() { 5186 IntentFilter pkgFilter = new IntentFilter(); 5187 pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART); 5188 pkgFilter.addDataScheme("package"); 5189 mContext.registerReceiver(new BroadcastReceiver() { 5190 @Override 5191 public void onReceive(Context context, Intent intent) { 5192 String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES); 5193 if (pkgs != null) { 5194 for (String pkg : pkgs) { 5195 synchronized (ActivityManagerService.this) { 5196 if (forceStopPackageLocked(pkg, -1, false, false, false, false, false, 0, 5197 "finished booting")) { 5198 setResultCode(Activity.RESULT_OK); 5199 return; 5200 } 5201 } 5202 } 5203 } 5204 } 5205 }, pkgFilter); 5206 5207 synchronized (this) { 5208 // Ensure that any processes we had put on hold are now started 5209 // up. 5210 final int NP = mProcessesOnHold.size(); 5211 if (NP > 0) { 5212 ArrayList<ProcessRecord> procs = 5213 new ArrayList<ProcessRecord>(mProcessesOnHold); 5214 for (int ip=0; ip<NP; ip++) { 5215 if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: " 5216 + procs.get(ip)); 5217 startProcessLocked(procs.get(ip), "on-hold", null); 5218 } 5219 } 5220 5221 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 5222 // Start looking for apps that are abusing wake locks. 5223 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 5224 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 5225 // Tell anyone interested that we are done booting! 5226 SystemProperties.set("sys.boot_completed", "1"); 5227 SystemProperties.set("dev.bootcomplete", "1"); 5228 for (int i=0; i<mStartedUsers.size(); i++) { 5229 UserStartedState uss = mStartedUsers.valueAt(i); 5230 if (uss.mState == UserStartedState.STATE_BOOTING) { 5231 uss.mState = UserStartedState.STATE_RUNNING; 5232 final int userId = mStartedUsers.keyAt(i); 5233 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 5234 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 5235 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT); 5236 broadcastIntentLocked(null, null, intent, null, 5237 new IIntentReceiver.Stub() { 5238 @Override 5239 public void performReceive(Intent intent, int resultCode, 5240 String data, Bundle extras, boolean ordered, 5241 boolean sticky, int sendingUser) { 5242 synchronized (ActivityManagerService.this) { 5243 requestPssAllProcsLocked(SystemClock.uptimeMillis(), 5244 true, false); 5245 } 5246 } 5247 }, 5248 0, null, null, 5249 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, 5250 AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID, 5251 userId); 5252 } 5253 } 5254 scheduleStartProfilesLocked(); 5255 } 5256 } 5257 } 5258 5259 final void ensureBootCompleted() { 5260 boolean booting; 5261 boolean enableScreen; 5262 synchronized (this) { 5263 booting = mBooting; 5264 mBooting = false; 5265 enableScreen = !mBooted; 5266 mBooted = true; 5267 } 5268 5269 if (booting) { 5270 finishBooting(); 5271 } 5272 5273 if (enableScreen) { 5274 enableScreenAfterBoot(); 5275 } 5276 } 5277 5278 @Override 5279 public final void activityResumed(IBinder token) { 5280 final long origId = Binder.clearCallingIdentity(); 5281 synchronized(this) { 5282 ActivityStack stack = ActivityRecord.getStackLocked(token); 5283 if (stack != null) { 5284 ActivityRecord.activityResumedLocked(token); 5285 } 5286 } 5287 Binder.restoreCallingIdentity(origId); 5288 } 5289 5290 @Override 5291 public final void activityPaused(IBinder token) { 5292 final long origId = Binder.clearCallingIdentity(); 5293 synchronized(this) { 5294 ActivityStack stack = ActivityRecord.getStackLocked(token); 5295 if (stack != null) { 5296 stack.activityPausedLocked(token, false); 5297 } 5298 } 5299 Binder.restoreCallingIdentity(origId); 5300 } 5301 5302 @Override 5303 public final void activityStopped(IBinder token, Bundle icicle, Bitmap thumbnail, 5304 CharSequence description) { 5305 if (localLOGV) Slog.v( 5306 TAG, "Activity stopped: token=" + token); 5307 5308 // Refuse possible leaked file descriptors 5309 if (icicle != null && icicle.hasFileDescriptors()) { 5310 throw new IllegalArgumentException("File descriptors passed in Bundle"); 5311 } 5312 5313 ActivityRecord r = null; 5314 5315 final long origId = Binder.clearCallingIdentity(); 5316 5317 synchronized (this) { 5318 r = ActivityRecord.isInStackLocked(token); 5319 if (r != null) { 5320 r.task.stack.activityStoppedLocked(r, icicle, thumbnail, description); 5321 } 5322 } 5323 5324 if (r != null) { 5325 sendPendingThumbnail(r, null, null, null, false); 5326 } 5327 5328 trimApplications(); 5329 5330 Binder.restoreCallingIdentity(origId); 5331 } 5332 5333 @Override 5334 public final void activityDestroyed(IBinder token) { 5335 if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token); 5336 synchronized (this) { 5337 ActivityStack stack = ActivityRecord.getStackLocked(token); 5338 if (stack != null) { 5339 stack.activityDestroyedLocked(token); 5340 } 5341 } 5342 } 5343 5344 @Override 5345 public String getCallingPackage(IBinder token) { 5346 synchronized (this) { 5347 ActivityRecord r = getCallingRecordLocked(token); 5348 return r != null ? r.info.packageName : null; 5349 } 5350 } 5351 5352 @Override 5353 public ComponentName getCallingActivity(IBinder token) { 5354 synchronized (this) { 5355 ActivityRecord r = getCallingRecordLocked(token); 5356 return r != null ? r.intent.getComponent() : null; 5357 } 5358 } 5359 5360 private ActivityRecord getCallingRecordLocked(IBinder token) { 5361 ActivityRecord r = ActivityRecord.isInStackLocked(token); 5362 if (r == null) { 5363 return null; 5364 } 5365 return r.resultTo; 5366 } 5367 5368 @Override 5369 public ComponentName getActivityClassForToken(IBinder token) { 5370 synchronized(this) { 5371 ActivityRecord r = ActivityRecord.isInStackLocked(token); 5372 if (r == null) { 5373 return null; 5374 } 5375 return r.intent.getComponent(); 5376 } 5377 } 5378 5379 @Override 5380 public String getPackageForToken(IBinder token) { 5381 synchronized(this) { 5382 ActivityRecord r = ActivityRecord.isInStackLocked(token); 5383 if (r == null) { 5384 return null; 5385 } 5386 return r.packageName; 5387 } 5388 } 5389 5390 @Override 5391 public IIntentSender getIntentSender(int type, 5392 String packageName, IBinder token, String resultWho, 5393 int requestCode, Intent[] intents, String[] resolvedTypes, 5394 int flags, Bundle options, int userId) { 5395 enforceNotIsolatedCaller("getIntentSender"); 5396 // Refuse possible leaked file descriptors 5397 if (intents != null) { 5398 if (intents.length < 1) { 5399 throw new IllegalArgumentException("Intents array length must be >= 1"); 5400 } 5401 for (int i=0; i<intents.length; i++) { 5402 Intent intent = intents[i]; 5403 if (intent != null) { 5404 if (intent.hasFileDescriptors()) { 5405 throw new IllegalArgumentException("File descriptors passed in Intent"); 5406 } 5407 if (type == ActivityManager.INTENT_SENDER_BROADCAST && 5408 (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 5409 throw new IllegalArgumentException( 5410 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 5411 } 5412 intents[i] = new Intent(intent); 5413 } 5414 } 5415 if (resolvedTypes != null && resolvedTypes.length != intents.length) { 5416 throw new IllegalArgumentException( 5417 "Intent array length does not match resolvedTypes length"); 5418 } 5419 } 5420 if (options != null) { 5421 if (options.hasFileDescriptors()) { 5422 throw new IllegalArgumentException("File descriptors passed in options"); 5423 } 5424 } 5425 5426 synchronized(this) { 5427 int callingUid = Binder.getCallingUid(); 5428 int origUserId = userId; 5429 userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId, 5430 type == ActivityManager.INTENT_SENDER_BROADCAST, false, 5431 "getIntentSender", null); 5432 if (origUserId == UserHandle.USER_CURRENT) { 5433 // We don't want to evaluate this until the pending intent is 5434 // actually executed. However, we do want to always do the 5435 // security checking for it above. 5436 userId = UserHandle.USER_CURRENT; 5437 } 5438 try { 5439 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 5440 int uid = AppGlobals.getPackageManager() 5441 .getPackageUid(packageName, UserHandle.getUserId(callingUid)); 5442 if (!UserHandle.isSameApp(callingUid, uid)) { 5443 String msg = "Permission Denial: getIntentSender() from pid=" 5444 + Binder.getCallingPid() 5445 + ", uid=" + Binder.getCallingUid() 5446 + ", (need uid=" + uid + ")" 5447 + " is not allowed to send as package " + packageName; 5448 Slog.w(TAG, msg); 5449 throw new SecurityException(msg); 5450 } 5451 } 5452 5453 return getIntentSenderLocked(type, packageName, callingUid, userId, 5454 token, resultWho, requestCode, intents, resolvedTypes, flags, options); 5455 5456 } catch (RemoteException e) { 5457 throw new SecurityException(e); 5458 } 5459 } 5460 } 5461 5462 IIntentSender getIntentSenderLocked(int type, String packageName, 5463 int callingUid, int userId, IBinder token, String resultWho, 5464 int requestCode, Intent[] intents, String[] resolvedTypes, int flags, 5465 Bundle options) { 5466 if (DEBUG_MU) 5467 Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid); 5468 ActivityRecord activity = null; 5469 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 5470 activity = ActivityRecord.isInStackLocked(token); 5471 if (activity == null) { 5472 return null; 5473 } 5474 if (activity.finishing) { 5475 return null; 5476 } 5477 } 5478 5479 final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0; 5480 final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0; 5481 final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0; 5482 flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT 5483 |PendingIntent.FLAG_UPDATE_CURRENT); 5484 5485 PendingIntentRecord.Key key = new PendingIntentRecord.Key( 5486 type, packageName, activity, resultWho, 5487 requestCode, intents, resolvedTypes, flags, options, userId); 5488 WeakReference<PendingIntentRecord> ref; 5489 ref = mIntentSenderRecords.get(key); 5490 PendingIntentRecord rec = ref != null ? ref.get() : null; 5491 if (rec != null) { 5492 if (!cancelCurrent) { 5493 if (updateCurrent) { 5494 if (rec.key.requestIntent != null) { 5495 rec.key.requestIntent.replaceExtras(intents != null ? 5496 intents[intents.length - 1] : null); 5497 } 5498 if (intents != null) { 5499 intents[intents.length-1] = rec.key.requestIntent; 5500 rec.key.allIntents = intents; 5501 rec.key.allResolvedTypes = resolvedTypes; 5502 } else { 5503 rec.key.allIntents = null; 5504 rec.key.allResolvedTypes = null; 5505 } 5506 } 5507 return rec; 5508 } 5509 rec.canceled = true; 5510 mIntentSenderRecords.remove(key); 5511 } 5512 if (noCreate) { 5513 return rec; 5514 } 5515 rec = new PendingIntentRecord(this, key, callingUid); 5516 mIntentSenderRecords.put(key, rec.ref); 5517 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 5518 if (activity.pendingResults == null) { 5519 activity.pendingResults 5520 = new HashSet<WeakReference<PendingIntentRecord>>(); 5521 } 5522 activity.pendingResults.add(rec.ref); 5523 } 5524 return rec; 5525 } 5526 5527 @Override 5528 public void cancelIntentSender(IIntentSender sender) { 5529 if (!(sender instanceof PendingIntentRecord)) { 5530 return; 5531 } 5532 synchronized(this) { 5533 PendingIntentRecord rec = (PendingIntentRecord)sender; 5534 try { 5535 int uid = AppGlobals.getPackageManager() 5536 .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId()); 5537 if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) { 5538 String msg = "Permission Denial: cancelIntentSender() from pid=" 5539 + Binder.getCallingPid() 5540 + ", uid=" + Binder.getCallingUid() 5541 + " is not allowed to cancel packges " 5542 + rec.key.packageName; 5543 Slog.w(TAG, msg); 5544 throw new SecurityException(msg); 5545 } 5546 } catch (RemoteException e) { 5547 throw new SecurityException(e); 5548 } 5549 cancelIntentSenderLocked(rec, true); 5550 } 5551 } 5552 5553 void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) { 5554 rec.canceled = true; 5555 mIntentSenderRecords.remove(rec.key); 5556 if (cleanActivity && rec.key.activity != null) { 5557 rec.key.activity.pendingResults.remove(rec.ref); 5558 } 5559 } 5560 5561 @Override 5562 public String getPackageForIntentSender(IIntentSender pendingResult) { 5563 if (!(pendingResult instanceof PendingIntentRecord)) { 5564 return null; 5565 } 5566 try { 5567 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5568 return res.key.packageName; 5569 } catch (ClassCastException e) { 5570 } 5571 return null; 5572 } 5573 5574 @Override 5575 public int getUidForIntentSender(IIntentSender sender) { 5576 if (sender instanceof PendingIntentRecord) { 5577 try { 5578 PendingIntentRecord res = (PendingIntentRecord)sender; 5579 return res.uid; 5580 } catch (ClassCastException e) { 5581 } 5582 } 5583 return -1; 5584 } 5585 5586 @Override 5587 public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) { 5588 if (!(pendingResult instanceof PendingIntentRecord)) { 5589 return false; 5590 } 5591 try { 5592 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5593 if (res.key.allIntents == null) { 5594 return false; 5595 } 5596 for (int i=0; i<res.key.allIntents.length; i++) { 5597 Intent intent = res.key.allIntents[i]; 5598 if (intent.getPackage() != null && intent.getComponent() != null) { 5599 return false; 5600 } 5601 } 5602 return true; 5603 } catch (ClassCastException e) { 5604 } 5605 return false; 5606 } 5607 5608 @Override 5609 public boolean isIntentSenderAnActivity(IIntentSender pendingResult) { 5610 if (!(pendingResult instanceof PendingIntentRecord)) { 5611 return false; 5612 } 5613 try { 5614 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5615 if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) { 5616 return true; 5617 } 5618 return false; 5619 } catch (ClassCastException e) { 5620 } 5621 return false; 5622 } 5623 5624 @Override 5625 public Intent getIntentForIntentSender(IIntentSender pendingResult) { 5626 if (!(pendingResult instanceof PendingIntentRecord)) { 5627 return null; 5628 } 5629 try { 5630 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5631 return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null; 5632 } catch (ClassCastException e) { 5633 } 5634 return null; 5635 } 5636 5637 @Override 5638 public String getTagForIntentSender(IIntentSender pendingResult, String prefix) { 5639 if (!(pendingResult instanceof PendingIntentRecord)) { 5640 return null; 5641 } 5642 try { 5643 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5644 Intent intent = res.key.requestIntent; 5645 if (intent != null) { 5646 if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null 5647 || res.lastTagPrefix.equals(prefix))) { 5648 return res.lastTag; 5649 } 5650 res.lastTagPrefix = prefix; 5651 StringBuilder sb = new StringBuilder(128); 5652 if (prefix != null) { 5653 sb.append(prefix); 5654 } 5655 if (intent.getAction() != null) { 5656 sb.append(intent.getAction()); 5657 } else if (intent.getComponent() != null) { 5658 intent.getComponent().appendShortString(sb); 5659 } else { 5660 sb.append("?"); 5661 } 5662 return res.lastTag = sb.toString(); 5663 } 5664 } catch (ClassCastException e) { 5665 } 5666 return null; 5667 } 5668 5669 @Override 5670 public void setProcessLimit(int max) { 5671 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 5672 "setProcessLimit()"); 5673 synchronized (this) { 5674 mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max; 5675 mProcessLimitOverride = max; 5676 } 5677 trimApplications(); 5678 } 5679 5680 @Override 5681 public int getProcessLimit() { 5682 synchronized (this) { 5683 return mProcessLimitOverride; 5684 } 5685 } 5686 5687 void foregroundTokenDied(ForegroundToken token) { 5688 synchronized (ActivityManagerService.this) { 5689 synchronized (mPidsSelfLocked) { 5690 ForegroundToken cur 5691 = mForegroundProcesses.get(token.pid); 5692 if (cur != token) { 5693 return; 5694 } 5695 mForegroundProcesses.remove(token.pid); 5696 ProcessRecord pr = mPidsSelfLocked.get(token.pid); 5697 if (pr == null) { 5698 return; 5699 } 5700 pr.forcingToForeground = null; 5701 updateProcessForegroundLocked(pr, false, false); 5702 } 5703 updateOomAdjLocked(); 5704 } 5705 } 5706 5707 @Override 5708 public void setProcessForeground(IBinder token, int pid, boolean isForeground) { 5709 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 5710 "setProcessForeground()"); 5711 synchronized(this) { 5712 boolean changed = false; 5713 5714 synchronized (mPidsSelfLocked) { 5715 ProcessRecord pr = mPidsSelfLocked.get(pid); 5716 if (pr == null && isForeground) { 5717 Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid); 5718 return; 5719 } 5720 ForegroundToken oldToken = mForegroundProcesses.get(pid); 5721 if (oldToken != null) { 5722 oldToken.token.unlinkToDeath(oldToken, 0); 5723 mForegroundProcesses.remove(pid); 5724 if (pr != null) { 5725 pr.forcingToForeground = null; 5726 } 5727 changed = true; 5728 } 5729 if (isForeground && token != null) { 5730 ForegroundToken newToken = new ForegroundToken() { 5731 @Override 5732 public void binderDied() { 5733 foregroundTokenDied(this); 5734 } 5735 }; 5736 newToken.pid = pid; 5737 newToken.token = token; 5738 try { 5739 token.linkToDeath(newToken, 0); 5740 mForegroundProcesses.put(pid, newToken); 5741 pr.forcingToForeground = token; 5742 changed = true; 5743 } catch (RemoteException e) { 5744 // If the process died while doing this, we will later 5745 // do the cleanup with the process death link. 5746 } 5747 } 5748 } 5749 5750 if (changed) { 5751 updateOomAdjLocked(); 5752 } 5753 } 5754 } 5755 5756 // ========================================================= 5757 // PERMISSIONS 5758 // ========================================================= 5759 5760 static class PermissionController extends IPermissionController.Stub { 5761 ActivityManagerService mActivityManagerService; 5762 PermissionController(ActivityManagerService activityManagerService) { 5763 mActivityManagerService = activityManagerService; 5764 } 5765 5766 @Override 5767 public boolean checkPermission(String permission, int pid, int uid) { 5768 return mActivityManagerService.checkPermission(permission, pid, 5769 uid) == PackageManager.PERMISSION_GRANTED; 5770 } 5771 } 5772 5773 class IntentFirewallInterface implements IntentFirewall.AMSInterface { 5774 @Override 5775 public int checkComponentPermission(String permission, int pid, int uid, 5776 int owningUid, boolean exported) { 5777 return ActivityManagerService.this.checkComponentPermission(permission, pid, uid, 5778 owningUid, exported); 5779 } 5780 5781 @Override 5782 public Object getAMSLock() { 5783 return ActivityManagerService.this; 5784 } 5785 } 5786 5787 /** 5788 * This can be called with or without the global lock held. 5789 */ 5790 int checkComponentPermission(String permission, int pid, int uid, 5791 int owningUid, boolean exported) { 5792 // We might be performing an operation on behalf of an indirect binder 5793 // invocation, e.g. via {@link #openContentUri}. Check and adjust the 5794 // client identity accordingly before proceeding. 5795 Identity tlsIdentity = sCallerIdentity.get(); 5796 if (tlsIdentity != null) { 5797 Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {" 5798 + tlsIdentity.pid + "," + tlsIdentity.uid + "}"); 5799 uid = tlsIdentity.uid; 5800 pid = tlsIdentity.pid; 5801 } 5802 5803 if (pid == MY_PID) { 5804 return PackageManager.PERMISSION_GRANTED; 5805 } 5806 5807 return ActivityManager.checkComponentPermission(permission, uid, 5808 owningUid, exported); 5809 } 5810 5811 /** 5812 * As the only public entry point for permissions checking, this method 5813 * can enforce the semantic that requesting a check on a null global 5814 * permission is automatically denied. (Internally a null permission 5815 * string is used when calling {@link #checkComponentPermission} in cases 5816 * when only uid-based security is needed.) 5817 * 5818 * This can be called with or without the global lock held. 5819 */ 5820 @Override 5821 public int checkPermission(String permission, int pid, int uid) { 5822 if (permission == null) { 5823 return PackageManager.PERMISSION_DENIED; 5824 } 5825 return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true); 5826 } 5827 5828 /** 5829 * Binder IPC calls go through the public entry point. 5830 * This can be called with or without the global lock held. 5831 */ 5832 int checkCallingPermission(String permission) { 5833 return checkPermission(permission, 5834 Binder.getCallingPid(), 5835 UserHandle.getAppId(Binder.getCallingUid())); 5836 } 5837 5838 /** 5839 * This can be called with or without the global lock held. 5840 */ 5841 void enforceCallingPermission(String permission, String func) { 5842 if (checkCallingPermission(permission) 5843 == PackageManager.PERMISSION_GRANTED) { 5844 return; 5845 } 5846 5847 String msg = "Permission Denial: " + func + " from pid=" 5848 + Binder.getCallingPid() 5849 + ", uid=" + Binder.getCallingUid() 5850 + " requires " + permission; 5851 Slog.w(TAG, msg); 5852 throw new SecurityException(msg); 5853 } 5854 5855 /** 5856 * Determine if UID is holding permissions required to access {@link Uri} in 5857 * the given {@link ProviderInfo}. Final permission checking is always done 5858 * in {@link ContentProvider}. 5859 */ 5860 private final boolean checkHoldingPermissionsLocked( 5861 IPackageManager pm, ProviderInfo pi, Uri uri, int uid, final int modeFlags) { 5862 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5863 "checkHoldingPermissionsLocked: uri=" + uri + " uid=" + uid); 5864 5865 if (pi.applicationInfo.uid == uid) { 5866 return true; 5867 } else if (!pi.exported) { 5868 return false; 5869 } 5870 5871 boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0; 5872 boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0; 5873 try { 5874 // check if target holds top-level <provider> permissions 5875 if (!readMet && pi.readPermission != null 5876 && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) { 5877 readMet = true; 5878 } 5879 if (!writeMet && pi.writePermission != null 5880 && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) { 5881 writeMet = true; 5882 } 5883 5884 // track if unprotected read/write is allowed; any denied 5885 // <path-permission> below removes this ability 5886 boolean allowDefaultRead = pi.readPermission == null; 5887 boolean allowDefaultWrite = pi.writePermission == null; 5888 5889 // check if target holds any <path-permission> that match uri 5890 final PathPermission[] pps = pi.pathPermissions; 5891 if (pps != null) { 5892 final String path = uri.getPath(); 5893 int i = pps.length; 5894 while (i > 0 && (!readMet || !writeMet)) { 5895 i--; 5896 PathPermission pp = pps[i]; 5897 if (pp.match(path)) { 5898 if (!readMet) { 5899 final String pprperm = pp.getReadPermission(); 5900 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for " 5901 + pprperm + " for " + pp.getPath() 5902 + ": match=" + pp.match(path) 5903 + " check=" + pm.checkUidPermission(pprperm, uid)); 5904 if (pprperm != null) { 5905 if (pm.checkUidPermission(pprperm, uid) == PERMISSION_GRANTED) { 5906 readMet = true; 5907 } else { 5908 allowDefaultRead = false; 5909 } 5910 } 5911 } 5912 if (!writeMet) { 5913 final String ppwperm = pp.getWritePermission(); 5914 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm " 5915 + ppwperm + " for " + pp.getPath() 5916 + ": match=" + pp.match(path) 5917 + " check=" + pm.checkUidPermission(ppwperm, uid)); 5918 if (ppwperm != null) { 5919 if (pm.checkUidPermission(ppwperm, uid) == PERMISSION_GRANTED) { 5920 writeMet = true; 5921 } else { 5922 allowDefaultWrite = false; 5923 } 5924 } 5925 } 5926 } 5927 } 5928 } 5929 5930 // grant unprotected <provider> read/write, if not blocked by 5931 // <path-permission> above 5932 if (allowDefaultRead) readMet = true; 5933 if (allowDefaultWrite) writeMet = true; 5934 5935 } catch (RemoteException e) { 5936 return false; 5937 } 5938 5939 return readMet && writeMet; 5940 } 5941 5942 private ProviderInfo getProviderInfoLocked(String authority, int userHandle) { 5943 ProviderInfo pi = null; 5944 ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle); 5945 if (cpr != null) { 5946 pi = cpr.info; 5947 } else { 5948 try { 5949 pi = AppGlobals.getPackageManager().resolveContentProvider( 5950 authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle); 5951 } catch (RemoteException ex) { 5952 } 5953 } 5954 return pi; 5955 } 5956 5957 private UriPermission findUriPermissionLocked(int targetUid, GrantUri uri) { 5958 final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid); 5959 if (targetUris != null) { 5960 return targetUris.get(uri); 5961 } 5962 return null; 5963 } 5964 5965 private UriPermission findOrCreateUriPermissionLocked(String sourcePkg, 5966 String targetPkg, int targetUid, GrantUri uri) { 5967 ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid); 5968 if (targetUris == null) { 5969 targetUris = Maps.newArrayMap(); 5970 mGrantedUriPermissions.put(targetUid, targetUris); 5971 } 5972 5973 UriPermission perm = targetUris.get(uri); 5974 if (perm == null) { 5975 perm = new UriPermission(sourcePkg, targetPkg, targetUid, uri); 5976 targetUris.put(uri, perm); 5977 } 5978 5979 return perm; 5980 } 5981 5982 private final boolean checkUriPermissionLocked(Uri uri, int uid, final int modeFlags) { 5983 final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0; 5984 final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE 5985 : UriPermission.STRENGTH_OWNED; 5986 5987 // Root gets to do everything. 5988 if (uid == 0) { 5989 return true; 5990 } 5991 5992 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid); 5993 if (perms == null) return false; 5994 5995 // First look for exact match 5996 final UriPermission exactPerm = perms.get(new GrantUri(uri, false)); 5997 if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) { 5998 return true; 5999 } 6000 6001 // No exact match, look for prefixes 6002 final int N = perms.size(); 6003 for (int i = 0; i < N; i++) { 6004 final UriPermission perm = perms.valueAt(i); 6005 if (perm.uri.prefix && uri.isPathPrefixMatch(perm.uri.uri) 6006 && perm.getStrength(modeFlags) >= minStrength) { 6007 return true; 6008 } 6009 } 6010 6011 return false; 6012 } 6013 6014 @Override 6015 public int checkUriPermission(Uri uri, int pid, int uid, final int modeFlags) { 6016 enforceNotIsolatedCaller("checkUriPermission"); 6017 6018 // Another redirected-binder-call permissions check as in 6019 // {@link checkComponentPermission}. 6020 Identity tlsIdentity = sCallerIdentity.get(); 6021 if (tlsIdentity != null) { 6022 uid = tlsIdentity.uid; 6023 pid = tlsIdentity.pid; 6024 } 6025 6026 // Our own process gets to do everything. 6027 if (pid == MY_PID) { 6028 return PackageManager.PERMISSION_GRANTED; 6029 } 6030 synchronized (this) { 6031 return checkUriPermissionLocked(uri, uid, modeFlags) 6032 ? PackageManager.PERMISSION_GRANTED 6033 : PackageManager.PERMISSION_DENIED; 6034 } 6035 } 6036 6037 /** 6038 * Check if the targetPkg can be granted permission to access uri by 6039 * the callingUid using the given modeFlags. Throws a security exception 6040 * if callingUid is not allowed to do this. Returns the uid of the target 6041 * if the URI permission grant should be performed; returns -1 if it is not 6042 * needed (for example targetPkg already has permission to access the URI). 6043 * If you already know the uid of the target, you can supply it in 6044 * lastTargetUid else set that to -1. 6045 */ 6046 int checkGrantUriPermissionLocked(int callingUid, String targetPkg, 6047 Uri uri, final int modeFlags, int lastTargetUid) { 6048 if (!Intent.isAccessUriMode(modeFlags)) { 6049 return -1; 6050 } 6051 6052 if (targetPkg != null) { 6053 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6054 "Checking grant " + targetPkg + " permission to " + uri); 6055 } 6056 6057 final IPackageManager pm = AppGlobals.getPackageManager(); 6058 6059 // If this is not a content: uri, we can't do anything with it. 6060 if (!ContentResolver.SCHEME_CONTENT.equals(uri.getScheme())) { 6061 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6062 "Can't grant URI permission for non-content URI: " + uri); 6063 return -1; 6064 } 6065 6066 final String authority = uri.getAuthority(); 6067 final ProviderInfo pi = getProviderInfoLocked(authority, UserHandle.getUserId(callingUid)); 6068 if (pi == null) { 6069 Slog.w(TAG, "No content provider found for permission check: " + uri.toSafeString()); 6070 return -1; 6071 } 6072 6073 int targetUid = lastTargetUid; 6074 if (targetUid < 0 && targetPkg != null) { 6075 try { 6076 targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid)); 6077 if (targetUid < 0) { 6078 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6079 "Can't grant URI permission no uid for: " + targetPkg); 6080 return -1; 6081 } 6082 } catch (RemoteException ex) { 6083 return -1; 6084 } 6085 } 6086 6087 if (targetUid >= 0) { 6088 // First... does the target actually need this permission? 6089 if (checkHoldingPermissionsLocked(pm, pi, uri, targetUid, modeFlags)) { 6090 // No need to grant the target this permission. 6091 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6092 "Target " + targetPkg + " already has full permission to " + uri); 6093 return -1; 6094 } 6095 } else { 6096 // First... there is no target package, so can anyone access it? 6097 boolean allowed = pi.exported; 6098 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) { 6099 if (pi.readPermission != null) { 6100 allowed = false; 6101 } 6102 } 6103 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) { 6104 if (pi.writePermission != null) { 6105 allowed = false; 6106 } 6107 } 6108 if (allowed) { 6109 return -1; 6110 } 6111 } 6112 6113 // Second... is the provider allowing granting of URI permissions? 6114 if (!pi.grantUriPermissions) { 6115 throw new SecurityException("Provider " + pi.packageName 6116 + "/" + pi.name 6117 + " does not allow granting of Uri permissions (uri " 6118 + uri + ")"); 6119 } 6120 if (pi.uriPermissionPatterns != null) { 6121 final int N = pi.uriPermissionPatterns.length; 6122 boolean allowed = false; 6123 for (int i=0; i<N; i++) { 6124 if (pi.uriPermissionPatterns[i] != null 6125 && pi.uriPermissionPatterns[i].match(uri.getPath())) { 6126 allowed = true; 6127 break; 6128 } 6129 } 6130 if (!allowed) { 6131 throw new SecurityException("Provider " + pi.packageName 6132 + "/" + pi.name 6133 + " does not allow granting of permission to path of Uri " 6134 + uri); 6135 } 6136 } 6137 6138 // Third... does the caller itself have permission to access 6139 // this uri? 6140 if (callingUid != Process.myUid()) { 6141 if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) { 6142 // Require they hold a strong enough Uri permission 6143 if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) { 6144 throw new SecurityException("Uid " + callingUid 6145 + " does not have permission to uri " + uri); 6146 } 6147 } 6148 } 6149 6150 return targetUid; 6151 } 6152 6153 @Override 6154 public int checkGrantUriPermission(int callingUid, String targetPkg, 6155 Uri uri, final int modeFlags) { 6156 enforceNotIsolatedCaller("checkGrantUriPermission"); 6157 synchronized(this) { 6158 return checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1); 6159 } 6160 } 6161 6162 void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, Uri uri, 6163 final int modeFlags, UriPermissionOwner owner) { 6164 if (!Intent.isAccessUriMode(modeFlags)) { 6165 return; 6166 } 6167 6168 // So here we are: the caller has the assumed permission 6169 // to the uri, and the target doesn't. Let's now give this to 6170 // the target. 6171 6172 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6173 "Granting " + targetPkg + "/" + targetUid + " permission to " + uri); 6174 6175 final String authority = uri.getAuthority(); 6176 final ProviderInfo pi = getProviderInfoLocked(authority, UserHandle.getUserId(targetUid)); 6177 if (pi == null) { 6178 Slog.w(TAG, "No content provider found for grant: " + uri.toSafeString()); 6179 return; 6180 } 6181 6182 final boolean prefix = (modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0; 6183 final UriPermission perm = findOrCreateUriPermissionLocked( 6184 pi.packageName, targetPkg, targetUid, new GrantUri(uri, prefix)); 6185 perm.grantModes(modeFlags, owner); 6186 } 6187 6188 void grantUriPermissionLocked(int callingUid, String targetPkg, Uri uri, 6189 final int modeFlags, UriPermissionOwner owner) { 6190 if (targetPkg == null) { 6191 throw new NullPointerException("targetPkg"); 6192 } 6193 6194 int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1); 6195 if (targetUid < 0) { 6196 return; 6197 } 6198 6199 grantUriPermissionUncheckedLocked(targetUid, targetPkg, uri, modeFlags, owner); 6200 } 6201 6202 static class NeededUriGrants extends ArrayList<Uri> { 6203 final String targetPkg; 6204 final int targetUid; 6205 final int flags; 6206 6207 NeededUriGrants(String targetPkg, int targetUid, int flags) { 6208 this.targetPkg = targetPkg; 6209 this.targetUid = targetUid; 6210 this.flags = flags; 6211 } 6212 } 6213 6214 /** 6215 * Like checkGrantUriPermissionLocked, but takes an Intent. 6216 */ 6217 NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid, 6218 String targetPkg, Intent intent, int mode, NeededUriGrants needed) { 6219 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6220 "Checking URI perm to data=" + (intent != null ? intent.getData() : null) 6221 + " clip=" + (intent != null ? intent.getClipData() : null) 6222 + " from " + intent + "; flags=0x" 6223 + Integer.toHexString(intent != null ? intent.getFlags() : 0)); 6224 6225 if (targetPkg == null) { 6226 throw new NullPointerException("targetPkg"); 6227 } 6228 6229 if (intent == null) { 6230 return null; 6231 } 6232 Uri data = intent.getData(); 6233 ClipData clip = intent.getClipData(); 6234 if (data == null && clip == null) { 6235 return null; 6236 } 6237 6238 if (data != null) { 6239 int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, data, 6240 mode, needed != null ? needed.targetUid : -1); 6241 if (targetUid > 0) { 6242 if (needed == null) { 6243 needed = new NeededUriGrants(targetPkg, targetUid, mode); 6244 } 6245 needed.add(data); 6246 } 6247 } 6248 if (clip != null) { 6249 for (int i=0; i<clip.getItemCount(); i++) { 6250 Uri uri = clip.getItemAt(i).getUri(); 6251 if (uri != null) { 6252 int targetUid = -1; 6253 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri, 6254 mode, needed != null ? needed.targetUid : -1); 6255 if (targetUid > 0) { 6256 if (needed == null) { 6257 needed = new NeededUriGrants(targetPkg, targetUid, mode); 6258 } 6259 needed.add(uri); 6260 } 6261 } else { 6262 Intent clipIntent = clip.getItemAt(i).getIntent(); 6263 if (clipIntent != null) { 6264 NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked( 6265 callingUid, targetPkg, clipIntent, mode, needed); 6266 if (newNeeded != null) { 6267 needed = newNeeded; 6268 } 6269 } 6270 } 6271 } 6272 } 6273 6274 return needed; 6275 } 6276 6277 /** 6278 * Like grantUriPermissionUncheckedLocked, but takes an Intent. 6279 */ 6280 void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed, 6281 UriPermissionOwner owner) { 6282 if (needed != null) { 6283 for (int i=0; i<needed.size(); i++) { 6284 grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg, 6285 needed.get(i), needed.flags, owner); 6286 } 6287 } 6288 } 6289 6290 void grantUriPermissionFromIntentLocked(int callingUid, 6291 String targetPkg, Intent intent, UriPermissionOwner owner) { 6292 NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg, 6293 intent, intent != null ? intent.getFlags() : 0, null); 6294 if (needed == null) { 6295 return; 6296 } 6297 6298 grantUriPermissionUncheckedFromIntentLocked(needed, owner); 6299 } 6300 6301 @Override 6302 public void grantUriPermission(IApplicationThread caller, String targetPkg, 6303 Uri uri, final int modeFlags) { 6304 enforceNotIsolatedCaller("grantUriPermission"); 6305 synchronized(this) { 6306 final ProcessRecord r = getRecordForAppLocked(caller); 6307 if (r == null) { 6308 throw new SecurityException("Unable to find app for caller " 6309 + caller 6310 + " when granting permission to uri " + uri); 6311 } 6312 if (targetPkg == null) { 6313 throw new IllegalArgumentException("null target"); 6314 } 6315 if (uri == null) { 6316 throw new IllegalArgumentException("null uri"); 6317 } 6318 6319 Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION 6320 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION 6321 | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION 6322 | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION); 6323 6324 grantUriPermissionLocked(r.uid, targetPkg, uri, modeFlags, null); 6325 } 6326 } 6327 6328 void removeUriPermissionIfNeededLocked(UriPermission perm) { 6329 if (perm.modeFlags == 0) { 6330 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get( 6331 perm.targetUid); 6332 if (perms != null) { 6333 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6334 "Removing " + perm.targetUid + " permission to " + perm.uri); 6335 6336 perms.remove(perm.uri); 6337 if (perms.isEmpty()) { 6338 mGrantedUriPermissions.remove(perm.targetUid); 6339 } 6340 } 6341 } 6342 } 6343 6344 private void revokeUriPermissionLocked(int callingUid, Uri uri, final int modeFlags) { 6345 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + uri); 6346 6347 final IPackageManager pm = AppGlobals.getPackageManager(); 6348 final String authority = uri.getAuthority(); 6349 final ProviderInfo pi = getProviderInfoLocked(authority, UserHandle.getUserId(callingUid)); 6350 if (pi == null) { 6351 Slog.w(TAG, "No content provider found for permission revoke: " + uri.toSafeString()); 6352 return; 6353 } 6354 6355 // Does the caller have this permission on the URI? 6356 if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) { 6357 // Right now, if you are not the original owner of the permission, 6358 // you are not allowed to revoke it. 6359 //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) { 6360 throw new SecurityException("Uid " + callingUid 6361 + " does not have permission to uri " + uri); 6362 //} 6363 } 6364 6365 boolean persistChanged = false; 6366 6367 // Go through all of the permissions and remove any that match. 6368 int N = mGrantedUriPermissions.size(); 6369 for (int i = 0; i < N; i++) { 6370 final int targetUid = mGrantedUriPermissions.keyAt(i); 6371 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 6372 6373 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) { 6374 final UriPermission perm = it.next(); 6375 if (perm.uri.uri.isPathPrefixMatch(uri)) { 6376 if (DEBUG_URI_PERMISSION) 6377 Slog.v(TAG, 6378 "Revoking " + perm.targetUid + " permission to " + perm.uri); 6379 persistChanged |= perm.revokeModes( 6380 modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION); 6381 if (perm.modeFlags == 0) { 6382 it.remove(); 6383 } 6384 } 6385 } 6386 6387 if (perms.isEmpty()) { 6388 mGrantedUriPermissions.remove(targetUid); 6389 N--; 6390 i--; 6391 } 6392 } 6393 6394 if (persistChanged) { 6395 schedulePersistUriGrants(); 6396 } 6397 } 6398 6399 @Override 6400 public void revokeUriPermission(IApplicationThread caller, Uri uri, 6401 final int modeFlags) { 6402 enforceNotIsolatedCaller("revokeUriPermission"); 6403 synchronized(this) { 6404 final ProcessRecord r = getRecordForAppLocked(caller); 6405 if (r == null) { 6406 throw new SecurityException("Unable to find app for caller " 6407 + caller 6408 + " when revoking permission to uri " + uri); 6409 } 6410 if (uri == null) { 6411 Slog.w(TAG, "revokeUriPermission: null uri"); 6412 return; 6413 } 6414 6415 if (!Intent.isAccessUriMode(modeFlags)) { 6416 return; 6417 } 6418 6419 final IPackageManager pm = AppGlobals.getPackageManager(); 6420 final String authority = uri.getAuthority(); 6421 final ProviderInfo pi = getProviderInfoLocked(authority, r.userId); 6422 if (pi == null) { 6423 Slog.w(TAG, "No content provider found for permission revoke: " 6424 + uri.toSafeString()); 6425 return; 6426 } 6427 6428 revokeUriPermissionLocked(r.uid, uri, modeFlags); 6429 } 6430 } 6431 6432 /** 6433 * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the 6434 * given package. 6435 * 6436 * @param packageName Package name to match, or {@code null} to apply to all 6437 * packages. 6438 * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply 6439 * to all users. 6440 * @param persistable If persistable grants should be removed. 6441 */ 6442 private void removeUriPermissionsForPackageLocked( 6443 String packageName, int userHandle, boolean persistable) { 6444 if (userHandle == UserHandle.USER_ALL && packageName == null) { 6445 throw new IllegalArgumentException("Must narrow by either package or user"); 6446 } 6447 6448 boolean persistChanged = false; 6449 6450 int N = mGrantedUriPermissions.size(); 6451 for (int i = 0; i < N; i++) { 6452 final int targetUid = mGrantedUriPermissions.keyAt(i); 6453 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 6454 6455 // Only inspect grants matching user 6456 if (userHandle == UserHandle.USER_ALL 6457 || userHandle == UserHandle.getUserId(targetUid)) { 6458 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) { 6459 final UriPermission perm = it.next(); 6460 6461 // Only inspect grants matching package 6462 if (packageName == null || perm.sourcePkg.equals(packageName) 6463 || perm.targetPkg.equals(packageName)) { 6464 persistChanged |= perm.revokeModes( 6465 persistable ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION); 6466 6467 // Only remove when no modes remain; any persisted grants 6468 // will keep this alive. 6469 if (perm.modeFlags == 0) { 6470 it.remove(); 6471 } 6472 } 6473 } 6474 6475 if (perms.isEmpty()) { 6476 mGrantedUriPermissions.remove(targetUid); 6477 N--; 6478 i--; 6479 } 6480 } 6481 } 6482 6483 if (persistChanged) { 6484 schedulePersistUriGrants(); 6485 } 6486 } 6487 6488 @Override 6489 public IBinder newUriPermissionOwner(String name) { 6490 enforceNotIsolatedCaller("newUriPermissionOwner"); 6491 synchronized(this) { 6492 UriPermissionOwner owner = new UriPermissionOwner(this, name); 6493 return owner.getExternalTokenLocked(); 6494 } 6495 } 6496 6497 @Override 6498 public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, 6499 Uri uri, final int modeFlags) { 6500 synchronized(this) { 6501 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 6502 if (owner == null) { 6503 throw new IllegalArgumentException("Unknown owner: " + token); 6504 } 6505 if (fromUid != Binder.getCallingUid()) { 6506 if (Binder.getCallingUid() != Process.myUid()) { 6507 // Only system code can grant URI permissions on behalf 6508 // of other users. 6509 throw new SecurityException("nice try"); 6510 } 6511 } 6512 if (targetPkg == null) { 6513 throw new IllegalArgumentException("null target"); 6514 } 6515 if (uri == null) { 6516 throw new IllegalArgumentException("null uri"); 6517 } 6518 6519 grantUriPermissionLocked(fromUid, targetPkg, uri, modeFlags, owner); 6520 } 6521 } 6522 6523 @Override 6524 public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode) { 6525 synchronized(this) { 6526 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 6527 if (owner == null) { 6528 throw new IllegalArgumentException("Unknown owner: " + token); 6529 } 6530 6531 if (uri == null) { 6532 owner.removeUriPermissionsLocked(mode); 6533 } else { 6534 owner.removeUriPermissionLocked(uri, mode); 6535 } 6536 } 6537 } 6538 6539 private void schedulePersistUriGrants() { 6540 if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) { 6541 mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG), 6542 10 * DateUtils.SECOND_IN_MILLIS); 6543 } 6544 } 6545 6546 private void writeGrantedUriPermissions() { 6547 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()"); 6548 6549 // Snapshot permissions so we can persist without lock 6550 ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList(); 6551 synchronized (this) { 6552 final int size = mGrantedUriPermissions.size(); 6553 for (int i = 0; i < size; i++) { 6554 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 6555 for (UriPermission perm : perms.values()) { 6556 if (perm.persistedModeFlags != 0) { 6557 persist.add(perm.snapshot()); 6558 } 6559 } 6560 } 6561 } 6562 6563 FileOutputStream fos = null; 6564 try { 6565 fos = mGrantFile.startWrite(); 6566 6567 XmlSerializer out = new FastXmlSerializer(); 6568 out.setOutput(fos, "utf-8"); 6569 out.startDocument(null, true); 6570 out.startTag(null, TAG_URI_GRANTS); 6571 for (UriPermission.Snapshot perm : persist) { 6572 out.startTag(null, TAG_URI_GRANT); 6573 writeIntAttribute(out, ATTR_USER_HANDLE, perm.userHandle); 6574 out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg); 6575 out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg); 6576 out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri)); 6577 writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix); 6578 writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags); 6579 writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime); 6580 out.endTag(null, TAG_URI_GRANT); 6581 } 6582 out.endTag(null, TAG_URI_GRANTS); 6583 out.endDocument(); 6584 6585 mGrantFile.finishWrite(fos); 6586 } catch (IOException e) { 6587 if (fos != null) { 6588 mGrantFile.failWrite(fos); 6589 } 6590 } 6591 } 6592 6593 private void readGrantedUriPermissionsLocked() { 6594 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()"); 6595 6596 final long now = System.currentTimeMillis(); 6597 6598 FileInputStream fis = null; 6599 try { 6600 fis = mGrantFile.openRead(); 6601 final XmlPullParser in = Xml.newPullParser(); 6602 in.setInput(fis, null); 6603 6604 int type; 6605 while ((type = in.next()) != END_DOCUMENT) { 6606 final String tag = in.getName(); 6607 if (type == START_TAG) { 6608 if (TAG_URI_GRANT.equals(tag)) { 6609 final int userHandle = readIntAttribute(in, ATTR_USER_HANDLE); 6610 final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG); 6611 final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG); 6612 final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI)); 6613 final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX); 6614 final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS); 6615 final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now); 6616 6617 // Sanity check that provider still belongs to source package 6618 final ProviderInfo pi = getProviderInfoLocked( 6619 uri.getAuthority(), userHandle); 6620 if (pi != null && sourcePkg.equals(pi.packageName)) { 6621 int targetUid = -1; 6622 try { 6623 targetUid = AppGlobals.getPackageManager() 6624 .getPackageUid(targetPkg, userHandle); 6625 } catch (RemoteException e) { 6626 } 6627 if (targetUid != -1) { 6628 final UriPermission perm = findOrCreateUriPermissionLocked( 6629 sourcePkg, targetPkg, targetUid, new GrantUri(uri, prefix)); 6630 perm.initPersistedModes(modeFlags, createdTime); 6631 } 6632 } else { 6633 Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg 6634 + " but instead found " + pi); 6635 } 6636 } 6637 } 6638 } 6639 } catch (FileNotFoundException e) { 6640 // Missing grants is okay 6641 } catch (IOException e) { 6642 Log.wtf(TAG, "Failed reading Uri grants", e); 6643 } catch (XmlPullParserException e) { 6644 Log.wtf(TAG, "Failed reading Uri grants", e); 6645 } finally { 6646 IoUtils.closeQuietly(fis); 6647 } 6648 } 6649 6650 @Override 6651 public void takePersistableUriPermission(Uri uri, final int modeFlags) { 6652 enforceNotIsolatedCaller("takePersistableUriPermission"); 6653 6654 Preconditions.checkFlagsArgument(modeFlags, 6655 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 6656 6657 synchronized (this) { 6658 final int callingUid = Binder.getCallingUid(); 6659 boolean persistChanged = false; 6660 6661 UriPermission exactPerm = findUriPermissionLocked(callingUid, new GrantUri(uri, false)); 6662 UriPermission prefixPerm = findUriPermissionLocked(callingUid, new GrantUri(uri, true)); 6663 6664 final boolean exactValid = (exactPerm != null) 6665 && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags); 6666 final boolean prefixValid = (prefixPerm != null) 6667 && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags); 6668 6669 if (!(exactValid || prefixValid)) { 6670 throw new SecurityException("No persistable permission grants found for UID " 6671 + callingUid + " and Uri " + uri.toSafeString()); 6672 } 6673 6674 if (exactValid) { 6675 persistChanged |= exactPerm.takePersistableModes(modeFlags); 6676 } 6677 if (prefixValid) { 6678 persistChanged |= prefixPerm.takePersistableModes(modeFlags); 6679 } 6680 6681 persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid); 6682 6683 if (persistChanged) { 6684 schedulePersistUriGrants(); 6685 } 6686 } 6687 } 6688 6689 @Override 6690 public void releasePersistableUriPermission(Uri uri, final int modeFlags) { 6691 enforceNotIsolatedCaller("releasePersistableUriPermission"); 6692 6693 Preconditions.checkFlagsArgument(modeFlags, 6694 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 6695 6696 synchronized (this) { 6697 final int callingUid = Binder.getCallingUid(); 6698 boolean persistChanged = false; 6699 6700 UriPermission exactPerm = findUriPermissionLocked(callingUid, new GrantUri(uri, false)); 6701 UriPermission prefixPerm = findUriPermissionLocked(callingUid, new GrantUri(uri, true)); 6702 if (exactPerm == null && prefixPerm == null) { 6703 throw new SecurityException("No permission grants found for UID " + callingUid 6704 + " and Uri " + uri.toSafeString()); 6705 } 6706 6707 if (exactPerm != null) { 6708 persistChanged |= exactPerm.releasePersistableModes(modeFlags); 6709 removeUriPermissionIfNeededLocked(exactPerm); 6710 } 6711 if (prefixPerm != null) { 6712 persistChanged |= prefixPerm.releasePersistableModes(modeFlags); 6713 removeUriPermissionIfNeededLocked(prefixPerm); 6714 } 6715 6716 if (persistChanged) { 6717 schedulePersistUriGrants(); 6718 } 6719 } 6720 } 6721 6722 /** 6723 * Prune any older {@link UriPermission} for the given UID until outstanding 6724 * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}. 6725 * 6726 * @return if any mutations occured that require persisting. 6727 */ 6728 private boolean maybePrunePersistedUriGrantsLocked(int uid) { 6729 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid); 6730 if (perms == null) return false; 6731 if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false; 6732 6733 final ArrayList<UriPermission> persisted = Lists.newArrayList(); 6734 for (UriPermission perm : perms.values()) { 6735 if (perm.persistedModeFlags != 0) { 6736 persisted.add(perm); 6737 } 6738 } 6739 6740 final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS; 6741 if (trimCount <= 0) return false; 6742 6743 Collections.sort(persisted, new UriPermission.PersistedTimeComparator()); 6744 for (int i = 0; i < trimCount; i++) { 6745 final UriPermission perm = persisted.get(i); 6746 6747 if (DEBUG_URI_PERMISSION) { 6748 Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime); 6749 } 6750 6751 perm.releasePersistableModes(~0); 6752 removeUriPermissionIfNeededLocked(perm); 6753 } 6754 6755 return true; 6756 } 6757 6758 @Override 6759 public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions( 6760 String packageName, boolean incoming) { 6761 enforceNotIsolatedCaller("getPersistedUriPermissions"); 6762 Preconditions.checkNotNull(packageName, "packageName"); 6763 6764 final int callingUid = Binder.getCallingUid(); 6765 final IPackageManager pm = AppGlobals.getPackageManager(); 6766 try { 6767 final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid)); 6768 if (packageUid != callingUid) { 6769 throw new SecurityException( 6770 "Package " + packageName + " does not belong to calling UID " + callingUid); 6771 } 6772 } catch (RemoteException e) { 6773 throw new SecurityException("Failed to verify package name ownership"); 6774 } 6775 6776 final ArrayList<android.content.UriPermission> result = Lists.newArrayList(); 6777 synchronized (this) { 6778 if (incoming) { 6779 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get( 6780 callingUid); 6781 if (perms == null) { 6782 Slog.w(TAG, "No permission grants found for " + packageName); 6783 } else { 6784 for (UriPermission perm : perms.values()) { 6785 if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) { 6786 result.add(perm.buildPersistedPublicApiObject()); 6787 } 6788 } 6789 } 6790 } else { 6791 final int size = mGrantedUriPermissions.size(); 6792 for (int i = 0; i < size; i++) { 6793 final ArrayMap<GrantUri, UriPermission> perms = 6794 mGrantedUriPermissions.valueAt(i); 6795 for (UriPermission perm : perms.values()) { 6796 if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) { 6797 result.add(perm.buildPersistedPublicApiObject()); 6798 } 6799 } 6800 } 6801 } 6802 } 6803 return new ParceledListSlice<android.content.UriPermission>(result); 6804 } 6805 6806 @Override 6807 public void showWaitingForDebugger(IApplicationThread who, boolean waiting) { 6808 synchronized (this) { 6809 ProcessRecord app = 6810 who != null ? getRecordForAppLocked(who) : null; 6811 if (app == null) return; 6812 6813 Message msg = Message.obtain(); 6814 msg.what = WAIT_FOR_DEBUGGER_MSG; 6815 msg.obj = app; 6816 msg.arg1 = waiting ? 1 : 0; 6817 mHandler.sendMessage(msg); 6818 } 6819 } 6820 6821 @Override 6822 public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) { 6823 final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ); 6824 final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ); 6825 outInfo.availMem = Process.getFreeMemory(); 6826 outInfo.totalMem = Process.getTotalMemory(); 6827 outInfo.threshold = homeAppMem; 6828 outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2)); 6829 outInfo.hiddenAppThreshold = cachedAppMem; 6830 outInfo.secondaryServerThreshold = mProcessList.getMemLevel( 6831 ProcessList.SERVICE_ADJ); 6832 outInfo.visibleAppThreshold = mProcessList.getMemLevel( 6833 ProcessList.VISIBLE_APP_ADJ); 6834 outInfo.foregroundAppThreshold = mProcessList.getMemLevel( 6835 ProcessList.FOREGROUND_APP_ADJ); 6836 } 6837 6838 // ========================================================= 6839 // TASK MANAGEMENT 6840 // ========================================================= 6841 6842 @Override 6843 public List<RunningTaskInfo> getTasks(int maxNum, int flags, 6844 IThumbnailReceiver receiver) { 6845 ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>(); 6846 6847 PendingThumbnailsRecord pending = new PendingThumbnailsRecord(receiver); 6848 ActivityRecord topRecord = null; 6849 6850 synchronized(this) { 6851 if (localLOGV) Slog.v( 6852 TAG, "getTasks: max=" + maxNum + ", flags=" + flags 6853 + ", receiver=" + receiver); 6854 6855 if (checkCallingPermission(android.Manifest.permission.GET_TASKS) 6856 != PackageManager.PERMISSION_GRANTED) { 6857 if (receiver != null) { 6858 // If the caller wants to wait for pending thumbnails, 6859 // it ain't gonna get them. 6860 try { 6861 receiver.finished(); 6862 } catch (RemoteException ex) { 6863 } 6864 } 6865 String msg = "Permission Denial: getTasks() from pid=" 6866 + Binder.getCallingPid() 6867 + ", uid=" + Binder.getCallingUid() 6868 + " requires " + android.Manifest.permission.GET_TASKS; 6869 Slog.w(TAG, msg); 6870 throw new SecurityException(msg); 6871 } 6872 6873 // TODO: Improve with MRU list from all ActivityStacks. 6874 topRecord = mStackSupervisor.getTasksLocked(maxNum, receiver, pending, list); 6875 6876 if (!pending.pendingRecords.isEmpty()) { 6877 mPendingThumbnails.add(pending); 6878 } 6879 } 6880 6881 if (localLOGV) Slog.v(TAG, "We have pending thumbnails: " + pending); 6882 6883 if (topRecord != null) { 6884 if (localLOGV) Slog.v(TAG, "Requesting top thumbnail"); 6885 try { 6886 IApplicationThread topThumbnail = topRecord.app.thread; 6887 topThumbnail.requestThumbnail(topRecord.appToken); 6888 } catch (Exception e) { 6889 Slog.w(TAG, "Exception thrown when requesting thumbnail", e); 6890 sendPendingThumbnail(null, topRecord.appToken, null, null, true); 6891 } 6892 } 6893 6894 if (pending.pendingRecords.isEmpty() && receiver != null) { 6895 // In this case all thumbnails were available and the client 6896 // is being asked to be told when the remaining ones come in... 6897 // which is unusually, since the top-most currently running 6898 // activity should never have a canned thumbnail! Oh well. 6899 try { 6900 receiver.finished(); 6901 } catch (RemoteException ex) { 6902 } 6903 } 6904 6905 return list; 6906 } 6907 6908 TaskRecord getMostRecentTask() { 6909 return mRecentTasks.get(0); 6910 } 6911 6912 @Override 6913 public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, 6914 int flags, int userId) { 6915 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 6916 false, true, "getRecentTasks", null); 6917 6918 synchronized (this) { 6919 enforceCallingPermission(android.Manifest.permission.GET_TASKS, 6920 "getRecentTasks()"); 6921 final boolean detailed = checkCallingPermission( 6922 android.Manifest.permission.GET_DETAILED_TASKS) 6923 == PackageManager.PERMISSION_GRANTED; 6924 6925 IPackageManager pm = AppGlobals.getPackageManager(); 6926 6927 final int N = mRecentTasks.size(); 6928 ArrayList<ActivityManager.RecentTaskInfo> res 6929 = new ArrayList<ActivityManager.RecentTaskInfo>( 6930 maxNum < N ? maxNum : N); 6931 6932 final Set<Integer> includedUsers; 6933 if ((flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0) { 6934 includedUsers = getProfileIdsLocked(userId); 6935 } else { 6936 includedUsers = new HashSet<Integer>(); 6937 } 6938 includedUsers.add(Integer.valueOf(userId)); 6939 for (int i=0; i<N && maxNum > 0; i++) { 6940 TaskRecord tr = mRecentTasks.get(i); 6941 // Only add calling user or related users recent tasks 6942 if (!includedUsers.contains(Integer.valueOf(tr.userId))) continue; 6943 6944 // Return the entry if desired by the caller. We always return 6945 // the first entry, because callers always expect this to be the 6946 // foreground app. We may filter others if the caller has 6947 // not supplied RECENT_WITH_EXCLUDED and there is some reason 6948 // we should exclude the entry. 6949 6950 if (i == 0 6951 || ((flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0) 6952 || (tr.intent == null) 6953 || ((tr.intent.getFlags() 6954 &Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0)) { 6955 ActivityManager.RecentTaskInfo rti 6956 = new ActivityManager.RecentTaskInfo(); 6957 rti.id = tr.numActivities > 0 ? tr.taskId : -1; 6958 rti.persistentId = tr.taskId; 6959 rti.baseIntent = new Intent( 6960 tr.intent != null ? tr.intent : tr.affinityIntent); 6961 if (!detailed) { 6962 rti.baseIntent.replaceExtras((Bundle)null); 6963 } 6964 rti.origActivity = tr.origActivity; 6965 rti.description = tr.lastDescription; 6966 rti.stackId = tr.stack.mStackId; 6967 rti.userId = tr.userId; 6968 6969 // Traverse upwards looking for any break between main task activities and 6970 // utility activities. 6971 final ArrayList<ActivityRecord> activities = tr.mActivities; 6972 int activityNdx; 6973 final int numActivities = activities.size(); 6974 for (activityNdx = Math.min(numActivities, 1); activityNdx < numActivities; 6975 ++activityNdx) { 6976 final ActivityRecord r = activities.get(activityNdx); 6977 if (r.intent != null && 6978 (r.intent.getFlags() & Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET) 6979 != 0) { 6980 break; 6981 } 6982 } 6983 // Traverse downwards starting below break looking for set label and icon. 6984 for (--activityNdx; activityNdx >= 0; --activityNdx) { 6985 final ActivityRecord r = activities.get(activityNdx); 6986 if (r.activityLabel != null || r.activityIcon != null) { 6987 rti.activityLabel = r.activityLabel; 6988 rti.activityIcon = r.activityIcon; 6989 break; 6990 } 6991 } 6992 6993 if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) { 6994 // Check whether this activity is currently available. 6995 try { 6996 if (rti.origActivity != null) { 6997 if (pm.getActivityInfo(rti.origActivity, 0, userId) 6998 == null) { 6999 continue; 7000 } 7001 } else if (rti.baseIntent != null) { 7002 if (pm.queryIntentActivities(rti.baseIntent, 7003 null, 0, userId) == null) { 7004 continue; 7005 } 7006 } 7007 } catch (RemoteException e) { 7008 // Will never happen. 7009 } 7010 } 7011 7012 res.add(rti); 7013 maxNum--; 7014 } 7015 } 7016 return res; 7017 } 7018 } 7019 7020 private TaskRecord recentTaskForIdLocked(int id) { 7021 final int N = mRecentTasks.size(); 7022 for (int i=0; i<N; i++) { 7023 TaskRecord tr = mRecentTasks.get(i); 7024 if (tr.taskId == id) { 7025 return tr; 7026 } 7027 } 7028 return null; 7029 } 7030 7031 @Override 7032 public ActivityManager.TaskThumbnails getTaskThumbnails(int id) { 7033 synchronized (this) { 7034 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER, 7035 "getTaskThumbnails()"); 7036 TaskRecord tr = recentTaskForIdLocked(id); 7037 if (tr != null) { 7038 return tr.getTaskThumbnailsLocked(); 7039 } 7040 } 7041 return null; 7042 } 7043 7044 @Override 7045 public Bitmap getTaskTopThumbnail(int id) { 7046 synchronized (this) { 7047 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER, 7048 "getTaskTopThumbnail()"); 7049 TaskRecord tr = recentTaskForIdLocked(id); 7050 if (tr != null) { 7051 return tr.getTaskTopThumbnailLocked(); 7052 } 7053 } 7054 return null; 7055 } 7056 7057 @Override 7058 public void setActivityLabelAndIcon(IBinder token, CharSequence activityLabel, 7059 Bitmap activityIcon) { 7060 synchronized (this) { 7061 ActivityRecord r = ActivityRecord.isInStackLocked(token); 7062 if (r != null) { 7063 r.activityLabel = activityLabel.toString(); 7064 r.activityIcon = activityIcon; 7065 } 7066 } 7067 } 7068 7069 @Override 7070 public boolean removeSubTask(int taskId, int subTaskIndex) { 7071 synchronized (this) { 7072 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, 7073 "removeSubTask()"); 7074 long ident = Binder.clearCallingIdentity(); 7075 try { 7076 TaskRecord tr = recentTaskForIdLocked(taskId); 7077 if (tr != null) { 7078 return tr.removeTaskActivitiesLocked(subTaskIndex, true) != null; 7079 } 7080 return false; 7081 } finally { 7082 Binder.restoreCallingIdentity(ident); 7083 } 7084 } 7085 } 7086 7087 private void killUnneededProcessLocked(ProcessRecord pr, String reason) { 7088 if (!pr.killedByAm) { 7089 Slog.i(TAG, "Killing " + pr.toShortString() + " (adj " + pr.setAdj + "): " + reason); 7090 EventLog.writeEvent(EventLogTags.AM_KILL, pr.userId, pr.pid, 7091 pr.processName, pr.setAdj, reason); 7092 pr.killedByAm = true; 7093 Process.killProcessQuiet(pr.pid); 7094 } 7095 } 7096 7097 private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) { 7098 tr.disposeThumbnail(); 7099 mRecentTasks.remove(tr); 7100 final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0; 7101 Intent baseIntent = new Intent( 7102 tr.intent != null ? tr.intent : tr.affinityIntent); 7103 ComponentName component = baseIntent.getComponent(); 7104 if (component == null) { 7105 Slog.w(TAG, "Now component for base intent of task: " + tr); 7106 return; 7107 } 7108 7109 // Find any running services associated with this app. 7110 mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent); 7111 7112 if (killProcesses) { 7113 // Find any running processes associated with this app. 7114 final String pkg = component.getPackageName(); 7115 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 7116 ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap(); 7117 for (int i=0; i<pmap.size(); i++) { 7118 SparseArray<ProcessRecord> uids = pmap.valueAt(i); 7119 for (int j=0; j<uids.size(); j++) { 7120 ProcessRecord proc = uids.valueAt(j); 7121 if (proc.userId != tr.userId) { 7122 continue; 7123 } 7124 if (!proc.pkgList.containsKey(pkg)) { 7125 continue; 7126 } 7127 procs.add(proc); 7128 } 7129 } 7130 7131 // Kill the running processes. 7132 for (int i=0; i<procs.size(); i++) { 7133 ProcessRecord pr = procs.get(i); 7134 if (pr == mHomeProcess) { 7135 // Don't kill the home process along with tasks from the same package. 7136 continue; 7137 } 7138 if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 7139 killUnneededProcessLocked(pr, "remove task"); 7140 } else { 7141 pr.waitingToKill = "remove task"; 7142 } 7143 } 7144 } 7145 } 7146 7147 @Override 7148 public boolean removeTask(int taskId, int flags) { 7149 synchronized (this) { 7150 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, 7151 "removeTask()"); 7152 long ident = Binder.clearCallingIdentity(); 7153 try { 7154 TaskRecord tr = recentTaskForIdLocked(taskId); 7155 if (tr != null) { 7156 ActivityRecord r = tr.removeTaskActivitiesLocked(-1, false); 7157 if (r != null) { 7158 cleanUpRemovedTaskLocked(tr, flags); 7159 return true; 7160 } 7161 if (tr.mActivities.size() == 0) { 7162 // Caller is just removing a recent task that is 7163 // not actively running. That is easy! 7164 cleanUpRemovedTaskLocked(tr, flags); 7165 return true; 7166 } 7167 Slog.w(TAG, "removeTask: task " + taskId 7168 + " does not have activities to remove, " 7169 + " but numActivities=" + tr.numActivities 7170 + ": " + tr); 7171 } 7172 } finally { 7173 Binder.restoreCallingIdentity(ident); 7174 } 7175 } 7176 return false; 7177 } 7178 7179 /** 7180 * TODO: Add mController hook 7181 */ 7182 @Override 7183 public void moveTaskToFront(int taskId, int flags, Bundle options) { 7184 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 7185 "moveTaskToFront()"); 7186 7187 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId); 7188 synchronized(this) { 7189 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 7190 Binder.getCallingUid(), "Task to front")) { 7191 ActivityOptions.abort(options); 7192 return; 7193 } 7194 final long origId = Binder.clearCallingIdentity(); 7195 try { 7196 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId); 7197 if (task == null) { 7198 return; 7199 } 7200 if (mStackSupervisor.isLockTaskModeViolation(task)) { 7201 Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode"); 7202 return; 7203 } 7204 mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options); 7205 } finally { 7206 Binder.restoreCallingIdentity(origId); 7207 } 7208 ActivityOptions.abort(options); 7209 } 7210 } 7211 7212 @Override 7213 public void moveTaskToBack(int taskId) { 7214 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 7215 "moveTaskToBack()"); 7216 7217 synchronized(this) { 7218 TaskRecord tr = recentTaskForIdLocked(taskId); 7219 if (tr != null) { 7220 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr); 7221 ActivityStack stack = tr.stack; 7222 if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) { 7223 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 7224 Binder.getCallingUid(), "Task to back")) { 7225 return; 7226 } 7227 } 7228 final long origId = Binder.clearCallingIdentity(); 7229 try { 7230 stack.moveTaskToBackLocked(taskId, null); 7231 } finally { 7232 Binder.restoreCallingIdentity(origId); 7233 } 7234 } 7235 } 7236 } 7237 7238 /** 7239 * Moves an activity, and all of the other activities within the same task, to the bottom 7240 * of the history stack. The activity's order within the task is unchanged. 7241 * 7242 * @param token A reference to the activity we wish to move 7243 * @param nonRoot If false then this only works if the activity is the root 7244 * of a task; if true it will work for any activity in a task. 7245 * @return Returns true if the move completed, false if not. 7246 */ 7247 @Override 7248 public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) { 7249 enforceNotIsolatedCaller("moveActivityTaskToBack"); 7250 synchronized(this) { 7251 final long origId = Binder.clearCallingIdentity(); 7252 int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot); 7253 if (taskId >= 0) { 7254 return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null); 7255 } 7256 Binder.restoreCallingIdentity(origId); 7257 } 7258 return false; 7259 } 7260 7261 @Override 7262 public void moveTaskBackwards(int task) { 7263 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 7264 "moveTaskBackwards()"); 7265 7266 synchronized(this) { 7267 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 7268 Binder.getCallingUid(), "Task backwards")) { 7269 return; 7270 } 7271 final long origId = Binder.clearCallingIdentity(); 7272 moveTaskBackwardsLocked(task); 7273 Binder.restoreCallingIdentity(origId); 7274 } 7275 } 7276 7277 private final void moveTaskBackwardsLocked(int task) { 7278 Slog.e(TAG, "moveTaskBackwards not yet implemented!"); 7279 } 7280 7281 @Override 7282 public IBinder getHomeActivityToken() throws RemoteException { 7283 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7284 "getHomeActivityToken()"); 7285 synchronized (this) { 7286 return mStackSupervisor.getHomeActivityToken(); 7287 } 7288 } 7289 7290 @Override 7291 public IActivityContainer createActivityContainer(IBinder parentActivityToken, 7292 IActivityContainerCallback callback) throws RemoteException { 7293 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7294 "createActivityContainer()"); 7295 synchronized (this) { 7296 if (parentActivityToken == null) { 7297 throw new IllegalArgumentException("parent token must not be null"); 7298 } 7299 ActivityRecord r = ActivityRecord.forToken(parentActivityToken); 7300 if (r == null) { 7301 return null; 7302 } 7303 if (callback == null) { 7304 throw new IllegalArgumentException("callback must not be null"); 7305 } 7306 return mStackSupervisor.createActivityContainer(r, callback); 7307 } 7308 } 7309 7310 @Override 7311 public void deleteActivityContainer(IActivityContainer container) throws RemoteException { 7312 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7313 "deleteActivityContainer()"); 7314 synchronized (this) { 7315 mStackSupervisor.deleteActivityContainer(container); 7316 } 7317 } 7318 7319 @Override 7320 public IActivityContainer getEnclosingActivityContainer(IBinder activityToken) 7321 throws RemoteException { 7322 synchronized (this) { 7323 ActivityStack stack = ActivityRecord.getStackLocked(activityToken); 7324 if (stack != null) { 7325 return stack.mActivityContainer; 7326 } 7327 return null; 7328 } 7329 } 7330 7331 @Override 7332 public void moveTaskToStack(int taskId, int stackId, boolean toTop) { 7333 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7334 "moveTaskToStack()"); 7335 if (stackId == HOME_STACK_ID) { 7336 Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack", 7337 new RuntimeException("here").fillInStackTrace()); 7338 } 7339 synchronized (this) { 7340 long ident = Binder.clearCallingIdentity(); 7341 try { 7342 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId=" 7343 + stackId + " toTop=" + toTop); 7344 mStackSupervisor.moveTaskToStack(taskId, stackId, toTop); 7345 } finally { 7346 Binder.restoreCallingIdentity(ident); 7347 } 7348 } 7349 } 7350 7351 @Override 7352 public void resizeStack(int stackBoxId, Rect bounds) { 7353 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7354 "resizeStackBox()"); 7355 long ident = Binder.clearCallingIdentity(); 7356 try { 7357 mWindowManager.resizeStack(stackBoxId, bounds); 7358 } finally { 7359 Binder.restoreCallingIdentity(ident); 7360 } 7361 } 7362 7363 @Override 7364 public List<StackInfo> getAllStackInfos() { 7365 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7366 "getAllStackInfos()"); 7367 long ident = Binder.clearCallingIdentity(); 7368 try { 7369 synchronized (this) { 7370 return mStackSupervisor.getAllStackInfosLocked(); 7371 } 7372 } finally { 7373 Binder.restoreCallingIdentity(ident); 7374 } 7375 } 7376 7377 @Override 7378 public StackInfo getStackInfo(int stackId) { 7379 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7380 "getStackInfo()"); 7381 long ident = Binder.clearCallingIdentity(); 7382 try { 7383 synchronized (this) { 7384 return mStackSupervisor.getStackInfoLocked(stackId); 7385 } 7386 } finally { 7387 Binder.restoreCallingIdentity(ident); 7388 } 7389 } 7390 7391 @Override 7392 public boolean isInHomeStack(int taskId) { 7393 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7394 "getStackInfo()"); 7395 long ident = Binder.clearCallingIdentity(); 7396 try { 7397 synchronized (this) { 7398 TaskRecord tr = recentTaskForIdLocked(taskId); 7399 if (tr != null) { 7400 return tr.stack.isHomeStack(); 7401 } 7402 } 7403 } finally { 7404 Binder.restoreCallingIdentity(ident); 7405 } 7406 return false; 7407 } 7408 7409 @Override 7410 public int getTaskForActivity(IBinder token, boolean onlyRoot) { 7411 synchronized(this) { 7412 return ActivityRecord.getTaskForActivityLocked(token, onlyRoot); 7413 } 7414 } 7415 7416 private boolean isLockTaskAuthorized(ComponentName name) { 7417// enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 7418// "startLockTaskMode()"); 7419// DevicePolicyManager dpm = (DevicePolicyManager) 7420// mContext.getSystemService(Context.DEVICE_POLICY_SERVICE); 7421// return dpm != null && dpm.isLockTaskPermitted(name); 7422 return true; 7423 } 7424 7425 private void startLockTaskMode(TaskRecord task) { 7426 if (!isLockTaskAuthorized(task.intent.getComponent())) { 7427 return; 7428 } 7429 long ident = Binder.clearCallingIdentity(); 7430 try { 7431 synchronized (this) { 7432 // Since we lost lock on task, make sure it is still there. 7433 task = mStackSupervisor.anyTaskForIdLocked(task.taskId); 7434 if (task != null) { 7435 mStackSupervisor.setLockTaskModeLocked(task); 7436 } 7437 } 7438 } finally { 7439 Binder.restoreCallingIdentity(ident); 7440 } 7441 } 7442 7443 @Override 7444 public void startLockTaskMode(int taskId) { 7445 long ident = Binder.clearCallingIdentity(); 7446 try { 7447 final TaskRecord task; 7448 synchronized (this) { 7449 task = mStackSupervisor.anyTaskForIdLocked(taskId); 7450 } 7451 if (task != null) { 7452 startLockTaskMode(task); 7453 } 7454 } finally { 7455 Binder.restoreCallingIdentity(ident); 7456 } 7457 } 7458 7459 @Override 7460 public void startLockTaskMode(IBinder token) { 7461 long ident = Binder.clearCallingIdentity(); 7462 try { 7463 final TaskRecord task; 7464 synchronized (this) { 7465 final ActivityRecord r = ActivityRecord.forToken(token); 7466 if (r == null) { 7467 return; 7468 } 7469 task = r.task; 7470 } 7471 if (task != null) { 7472 startLockTaskMode(task); 7473 } 7474 } finally { 7475 Binder.restoreCallingIdentity(ident); 7476 } 7477 } 7478 7479 @Override 7480 public void stopLockTaskMode() { 7481// enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 7482// "stopLockTaskMode()"); 7483 synchronized (this) { 7484 mStackSupervisor.setLockTaskModeLocked(null); 7485 } 7486 } 7487 7488 @Override 7489 public boolean isInLockTaskMode() { 7490 synchronized (this) { 7491 return mStackSupervisor.isInLockTaskMode(); 7492 } 7493 } 7494 7495 // ========================================================= 7496 // THUMBNAILS 7497 // ========================================================= 7498 7499 public void reportThumbnail(IBinder token, 7500 Bitmap thumbnail, CharSequence description) { 7501 //System.out.println("Report thumbnail for " + token + ": " + thumbnail); 7502 final long origId = Binder.clearCallingIdentity(); 7503 sendPendingThumbnail(null, token, thumbnail, description, true); 7504 Binder.restoreCallingIdentity(origId); 7505 } 7506 7507 final void sendPendingThumbnail(ActivityRecord r, IBinder token, 7508 Bitmap thumbnail, CharSequence description, boolean always) { 7509 TaskRecord task; 7510 ArrayList<PendingThumbnailsRecord> receivers = null; 7511 7512 //System.out.println("Send pending thumbnail: " + r); 7513 7514 synchronized(this) { 7515 if (r == null) { 7516 r = ActivityRecord.isInStackLocked(token); 7517 if (r == null) { 7518 return; 7519 } 7520 } 7521 if (thumbnail == null && r.thumbHolder != null) { 7522 thumbnail = r.thumbHolder.lastThumbnail; 7523 description = r.thumbHolder.lastDescription; 7524 } 7525 if (thumbnail == null && !always) { 7526 // If there is no thumbnail, and this entry is not actually 7527 // going away, then abort for now and pick up the next 7528 // thumbnail we get. 7529 return; 7530 } 7531 task = r.task; 7532 7533 int N = mPendingThumbnails.size(); 7534 int i=0; 7535 while (i<N) { 7536 PendingThumbnailsRecord pr = mPendingThumbnails.get(i); 7537 //System.out.println("Looking in " + pr.pendingRecords); 7538 if (pr.pendingRecords.remove(r)) { 7539 if (receivers == null) { 7540 receivers = new ArrayList<PendingThumbnailsRecord>(); 7541 } 7542 receivers.add(pr); 7543 if (pr.pendingRecords.size() == 0) { 7544 pr.finished = true; 7545 mPendingThumbnails.remove(i); 7546 N--; 7547 continue; 7548 } 7549 } 7550 i++; 7551 } 7552 } 7553 7554 if (receivers != null) { 7555 final int N = receivers.size(); 7556 for (int i=0; i<N; i++) { 7557 try { 7558 PendingThumbnailsRecord pr = receivers.get(i); 7559 pr.receiver.newThumbnail( 7560 task != null ? task.taskId : -1, thumbnail, description); 7561 if (pr.finished) { 7562 pr.receiver.finished(); 7563 } 7564 } catch (Exception e) { 7565 Slog.w(TAG, "Exception thrown when sending thumbnail", e); 7566 } 7567 } 7568 } 7569 } 7570 7571 // ========================================================= 7572 // CONTENT PROVIDERS 7573 // ========================================================= 7574 7575 private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) { 7576 List<ProviderInfo> providers = null; 7577 try { 7578 providers = AppGlobals.getPackageManager(). 7579 queryContentProviders(app.processName, app.uid, 7580 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS); 7581 } catch (RemoteException ex) { 7582 } 7583 if (DEBUG_MU) 7584 Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid); 7585 int userId = app.userId; 7586 if (providers != null) { 7587 int N = providers.size(); 7588 app.pubProviders.ensureCapacity(N + app.pubProviders.size()); 7589 for (int i=0; i<N; i++) { 7590 ProviderInfo cpi = 7591 (ProviderInfo)providers.get(i); 7592 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo, 7593 cpi.name, cpi.flags); 7594 if (singleton && UserHandle.getUserId(app.uid) != 0) { 7595 // This is a singleton provider, but a user besides the 7596 // default user is asking to initialize a process it runs 7597 // in... well, no, it doesn't actually run in this process, 7598 // it runs in the process of the default user. Get rid of it. 7599 providers.remove(i); 7600 N--; 7601 i--; 7602 continue; 7603 } 7604 7605 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 7606 ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId); 7607 if (cpr == null) { 7608 cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton); 7609 mProviderMap.putProviderByClass(comp, cpr); 7610 } 7611 if (DEBUG_MU) 7612 Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid); 7613 app.pubProviders.put(cpi.name, cpr); 7614 if (!cpi.multiprocess || !"android".equals(cpi.packageName)) { 7615 // Don't add this if it is a platform component that is marked 7616 // to run in multiple processes, because this is actually 7617 // part of the framework so doesn't make sense to track as a 7618 // separate apk in the process. 7619 app.addPackage(cpi.applicationInfo.packageName, mProcessStats); 7620 } 7621 ensurePackageDexOpt(cpi.applicationInfo.packageName); 7622 } 7623 } 7624 return providers; 7625 } 7626 7627 /** 7628 * Check if {@link ProcessRecord} has a possible chance at accessing the 7629 * given {@link ProviderInfo}. Final permission checking is always done 7630 * in {@link ContentProvider}. 7631 */ 7632 private final String checkContentProviderPermissionLocked( 7633 ProviderInfo cpi, ProcessRecord r) { 7634 final int callingPid = (r != null) ? r.pid : Binder.getCallingPid(); 7635 final int callingUid = (r != null) ? r.uid : Binder.getCallingUid(); 7636 if (checkComponentPermission(cpi.readPermission, callingPid, callingUid, 7637 cpi.applicationInfo.uid, cpi.exported) 7638 == PackageManager.PERMISSION_GRANTED) { 7639 return null; 7640 } 7641 if (checkComponentPermission(cpi.writePermission, callingPid, callingUid, 7642 cpi.applicationInfo.uid, cpi.exported) 7643 == PackageManager.PERMISSION_GRANTED) { 7644 return null; 7645 } 7646 7647 PathPermission[] pps = cpi.pathPermissions; 7648 if (pps != null) { 7649 int i = pps.length; 7650 while (i > 0) { 7651 i--; 7652 PathPermission pp = pps[i]; 7653 if (checkComponentPermission(pp.getReadPermission(), callingPid, callingUid, 7654 cpi.applicationInfo.uid, cpi.exported) 7655 == PackageManager.PERMISSION_GRANTED) { 7656 return null; 7657 } 7658 if (checkComponentPermission(pp.getWritePermission(), callingPid, callingUid, 7659 cpi.applicationInfo.uid, cpi.exported) 7660 == PackageManager.PERMISSION_GRANTED) { 7661 return null; 7662 } 7663 } 7664 } 7665 7666 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid); 7667 if (perms != null) { 7668 for (GrantUri uri : perms.keySet()) { 7669 if (uri.uri.getAuthority().equals(cpi.authority)) { 7670 return null; 7671 } 7672 } 7673 } 7674 7675 String msg; 7676 if (!cpi.exported) { 7677 msg = "Permission Denial: opening provider " + cpi.name 7678 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 7679 + ", uid=" + callingUid + ") that is not exported from uid " 7680 + cpi.applicationInfo.uid; 7681 } else { 7682 msg = "Permission Denial: opening provider " + cpi.name 7683 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 7684 + ", uid=" + callingUid + ") requires " 7685 + cpi.readPermission + " or " + cpi.writePermission; 7686 } 7687 Slog.w(TAG, msg); 7688 return msg; 7689 } 7690 7691 ContentProviderConnection incProviderCountLocked(ProcessRecord r, 7692 final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 7693 if (r != null) { 7694 for (int i=0; i<r.conProviders.size(); i++) { 7695 ContentProviderConnection conn = r.conProviders.get(i); 7696 if (conn.provider == cpr) { 7697 if (DEBUG_PROVIDER) Slog.v(TAG, 7698 "Adding provider requested by " 7699 + r.processName + " from process " 7700 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 7701 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 7702 if (stable) { 7703 conn.stableCount++; 7704 conn.numStableIncs++; 7705 } else { 7706 conn.unstableCount++; 7707 conn.numUnstableIncs++; 7708 } 7709 return conn; 7710 } 7711 } 7712 ContentProviderConnection conn = new ContentProviderConnection(cpr, r); 7713 if (stable) { 7714 conn.stableCount = 1; 7715 conn.numStableIncs = 1; 7716 } else { 7717 conn.unstableCount = 1; 7718 conn.numUnstableIncs = 1; 7719 } 7720 cpr.connections.add(conn); 7721 r.conProviders.add(conn); 7722 return conn; 7723 } 7724 cpr.addExternalProcessHandleLocked(externalProcessToken); 7725 return null; 7726 } 7727 7728 boolean decProviderCountLocked(ContentProviderConnection conn, 7729 ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 7730 if (conn != null) { 7731 cpr = conn.provider; 7732 if (DEBUG_PROVIDER) Slog.v(TAG, 7733 "Removing provider requested by " 7734 + conn.client.processName + " from process " 7735 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 7736 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 7737 if (stable) { 7738 conn.stableCount--; 7739 } else { 7740 conn.unstableCount--; 7741 } 7742 if (conn.stableCount == 0 && conn.unstableCount == 0) { 7743 cpr.connections.remove(conn); 7744 conn.client.conProviders.remove(conn); 7745 return true; 7746 } 7747 return false; 7748 } 7749 cpr.removeExternalProcessHandleLocked(externalProcessToken); 7750 return false; 7751 } 7752 7753 private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller, 7754 String name, IBinder token, boolean stable, int userId) { 7755 ContentProviderRecord cpr; 7756 ContentProviderConnection conn = null; 7757 ProviderInfo cpi = null; 7758 7759 synchronized(this) { 7760 ProcessRecord r = null; 7761 if (caller != null) { 7762 r = getRecordForAppLocked(caller); 7763 if (r == null) { 7764 throw new SecurityException( 7765 "Unable to find app for caller " + caller 7766 + " (pid=" + Binder.getCallingPid() 7767 + ") when getting content provider " + name); 7768 } 7769 } 7770 7771 // First check if this content provider has been published... 7772 cpr = mProviderMap.getProviderByName(name, userId); 7773 boolean providerRunning = cpr != null; 7774 if (providerRunning) { 7775 cpi = cpr.info; 7776 String msg; 7777 if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) { 7778 throw new SecurityException(msg); 7779 } 7780 7781 if (r != null && cpr.canRunHere(r)) { 7782 // This provider has been published or is in the process 7783 // of being published... but it is also allowed to run 7784 // in the caller's process, so don't make a connection 7785 // and just let the caller instantiate its own instance. 7786 ContentProviderHolder holder = cpr.newHolder(null); 7787 // don't give caller the provider object, it needs 7788 // to make its own. 7789 holder.provider = null; 7790 return holder; 7791 } 7792 7793 final long origId = Binder.clearCallingIdentity(); 7794 7795 // In this case the provider instance already exists, so we can 7796 // return it right away. 7797 conn = incProviderCountLocked(r, cpr, token, stable); 7798 if (conn != null && (conn.stableCount+conn.unstableCount) == 1) { 7799 if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 7800 // If this is a perceptible app accessing the provider, 7801 // make sure to count it as being accessed and thus 7802 // back up on the LRU list. This is good because 7803 // content providers are often expensive to start. 7804 updateLruProcessLocked(cpr.proc, false, null); 7805 } 7806 } 7807 7808 if (cpr.proc != null) { 7809 if (false) { 7810 if (cpr.name.flattenToShortString().equals( 7811 "com.android.providers.calendar/.CalendarProvider2")) { 7812 Slog.v(TAG, "****************** KILLING " 7813 + cpr.name.flattenToShortString()); 7814 Process.killProcess(cpr.proc.pid); 7815 } 7816 } 7817 boolean success = updateOomAdjLocked(cpr.proc); 7818 if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success); 7819 // NOTE: there is still a race here where a signal could be 7820 // pending on the process even though we managed to update its 7821 // adj level. Not sure what to do about this, but at least 7822 // the race is now smaller. 7823 if (!success) { 7824 // Uh oh... it looks like the provider's process 7825 // has been killed on us. We need to wait for a new 7826 // process to be started, and make sure its death 7827 // doesn't kill our process. 7828 Slog.i(TAG, 7829 "Existing provider " + cpr.name.flattenToShortString() 7830 + " is crashing; detaching " + r); 7831 boolean lastRef = decProviderCountLocked(conn, cpr, token, stable); 7832 appDiedLocked(cpr.proc, cpr.proc.pid, cpr.proc.thread); 7833 if (!lastRef) { 7834 // This wasn't the last ref our process had on 7835 // the provider... we have now been killed, bail. 7836 return null; 7837 } 7838 providerRunning = false; 7839 conn = null; 7840 } 7841 } 7842 7843 Binder.restoreCallingIdentity(origId); 7844 } 7845 7846 boolean singleton; 7847 if (!providerRunning) { 7848 try { 7849 cpi = AppGlobals.getPackageManager(). 7850 resolveContentProvider(name, 7851 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId); 7852 } catch (RemoteException ex) { 7853 } 7854 if (cpi == null) { 7855 return null; 7856 } 7857 singleton = isSingleton(cpi.processName, cpi.applicationInfo, 7858 cpi.name, cpi.flags); 7859 if (singleton) { 7860 userId = 0; 7861 } 7862 cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId); 7863 7864 String msg; 7865 if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) { 7866 throw new SecurityException(msg); 7867 } 7868 7869 if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate 7870 && !cpi.processName.equals("system")) { 7871 // If this content provider does not run in the system 7872 // process, and the system is not yet ready to run other 7873 // processes, then fail fast instead of hanging. 7874 throw new IllegalArgumentException( 7875 "Attempt to launch content provider before system ready"); 7876 } 7877 7878 // Make sure that the user who owns this provider is started. If not, 7879 // we don't want to allow it to run. 7880 if (mStartedUsers.get(userId) == null) { 7881 Slog.w(TAG, "Unable to launch app " 7882 + cpi.applicationInfo.packageName + "/" 7883 + cpi.applicationInfo.uid + " for provider " 7884 + name + ": user " + userId + " is stopped"); 7885 return null; 7886 } 7887 7888 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 7889 cpr = mProviderMap.getProviderByClass(comp, userId); 7890 final boolean firstClass = cpr == null; 7891 if (firstClass) { 7892 try { 7893 ApplicationInfo ai = 7894 AppGlobals.getPackageManager(). 7895 getApplicationInfo( 7896 cpi.applicationInfo.packageName, 7897 STOCK_PM_FLAGS, userId); 7898 if (ai == null) { 7899 Slog.w(TAG, "No package info for content provider " 7900 + cpi.name); 7901 return null; 7902 } 7903 ai = getAppInfoForUser(ai, userId); 7904 cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton); 7905 } catch (RemoteException ex) { 7906 // pm is in same process, this will never happen. 7907 } 7908 } 7909 7910 if (r != null && cpr.canRunHere(r)) { 7911 // If this is a multiprocess provider, then just return its 7912 // info and allow the caller to instantiate it. Only do 7913 // this if the provider is the same user as the caller's 7914 // process, or can run as root (so can be in any process). 7915 return cpr.newHolder(null); 7916 } 7917 7918 if (DEBUG_PROVIDER) { 7919 RuntimeException e = new RuntimeException("here"); 7920 Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null) 7921 + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e); 7922 } 7923 7924 // This is single process, and our app is now connecting to it. 7925 // See if we are already in the process of launching this 7926 // provider. 7927 final int N = mLaunchingProviders.size(); 7928 int i; 7929 for (i=0; i<N; i++) { 7930 if (mLaunchingProviders.get(i) == cpr) { 7931 break; 7932 } 7933 } 7934 7935 // If the provider is not already being launched, then get it 7936 // started. 7937 if (i >= N) { 7938 final long origId = Binder.clearCallingIdentity(); 7939 7940 try { 7941 // Content provider is now in use, its package can't be stopped. 7942 try { 7943 AppGlobals.getPackageManager().setPackageStoppedState( 7944 cpr.appInfo.packageName, false, userId); 7945 } catch (RemoteException e) { 7946 } catch (IllegalArgumentException e) { 7947 Slog.w(TAG, "Failed trying to unstop package " 7948 + cpr.appInfo.packageName + ": " + e); 7949 } 7950 7951 // Use existing process if already started 7952 ProcessRecord proc = getProcessRecordLocked( 7953 cpi.processName, cpr.appInfo.uid, false); 7954 if (proc != null && proc.thread != null) { 7955 if (DEBUG_PROVIDER) { 7956 Slog.d(TAG, "Installing in existing process " + proc); 7957 } 7958 proc.pubProviders.put(cpi.name, cpr); 7959 try { 7960 proc.thread.scheduleInstallProvider(cpi); 7961 } catch (RemoteException e) { 7962 } 7963 } else { 7964 proc = startProcessLocked(cpi.processName, 7965 cpr.appInfo, false, 0, "content provider", 7966 new ComponentName(cpi.applicationInfo.packageName, 7967 cpi.name), false, false, false); 7968 if (proc == null) { 7969 Slog.w(TAG, "Unable to launch app " 7970 + cpi.applicationInfo.packageName + "/" 7971 + cpi.applicationInfo.uid + " for provider " 7972 + name + ": process is bad"); 7973 return null; 7974 } 7975 } 7976 cpr.launchingApp = proc; 7977 mLaunchingProviders.add(cpr); 7978 } finally { 7979 Binder.restoreCallingIdentity(origId); 7980 } 7981 } 7982 7983 // Make sure the provider is published (the same provider class 7984 // may be published under multiple names). 7985 if (firstClass) { 7986 mProviderMap.putProviderByClass(comp, cpr); 7987 } 7988 7989 mProviderMap.putProviderByName(name, cpr); 7990 conn = incProviderCountLocked(r, cpr, token, stable); 7991 if (conn != null) { 7992 conn.waiting = true; 7993 } 7994 } 7995 } 7996 7997 // Wait for the provider to be published... 7998 synchronized (cpr) { 7999 while (cpr.provider == null) { 8000 if (cpr.launchingApp == null) { 8001 Slog.w(TAG, "Unable to launch app " 8002 + cpi.applicationInfo.packageName + "/" 8003 + cpi.applicationInfo.uid + " for provider " 8004 + name + ": launching app became null"); 8005 EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS, 8006 UserHandle.getUserId(cpi.applicationInfo.uid), 8007 cpi.applicationInfo.packageName, 8008 cpi.applicationInfo.uid, name); 8009 return null; 8010 } 8011 try { 8012 if (DEBUG_MU) { 8013 Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp=" 8014 + cpr.launchingApp); 8015 } 8016 if (conn != null) { 8017 conn.waiting = true; 8018 } 8019 cpr.wait(); 8020 } catch (InterruptedException ex) { 8021 } finally { 8022 if (conn != null) { 8023 conn.waiting = false; 8024 } 8025 } 8026 } 8027 } 8028 return cpr != null ? cpr.newHolder(conn) : null; 8029 } 8030 8031 public final ContentProviderHolder getContentProvider( 8032 IApplicationThread caller, String name, int userId, boolean stable) { 8033 enforceNotIsolatedCaller("getContentProvider"); 8034 if (caller == null) { 8035 String msg = "null IApplicationThread when getting content provider " 8036 + name; 8037 Slog.w(TAG, msg); 8038 throw new SecurityException(msg); 8039 } 8040 8041 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 8042 false, true, "getContentProvider", null); 8043 return getContentProviderImpl(caller, name, null, stable, userId); 8044 } 8045 8046 public ContentProviderHolder getContentProviderExternal( 8047 String name, int userId, IBinder token) { 8048 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 8049 "Do not have permission in call getContentProviderExternal()"); 8050 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 8051 false, true, "getContentProvider", null); 8052 return getContentProviderExternalUnchecked(name, token, userId); 8053 } 8054 8055 private ContentProviderHolder getContentProviderExternalUnchecked(String name, 8056 IBinder token, int userId) { 8057 return getContentProviderImpl(null, name, token, true, userId); 8058 } 8059 8060 /** 8061 * Drop a content provider from a ProcessRecord's bookkeeping 8062 */ 8063 public void removeContentProvider(IBinder connection, boolean stable) { 8064 enforceNotIsolatedCaller("removeContentProvider"); 8065 long ident = Binder.clearCallingIdentity(); 8066 try { 8067 synchronized (this) { 8068 ContentProviderConnection conn; 8069 try { 8070 conn = (ContentProviderConnection)connection; 8071 } catch (ClassCastException e) { 8072 String msg ="removeContentProvider: " + connection 8073 + " not a ContentProviderConnection"; 8074 Slog.w(TAG, msg); 8075 throw new IllegalArgumentException(msg); 8076 } 8077 if (conn == null) { 8078 throw new NullPointerException("connection is null"); 8079 } 8080 if (decProviderCountLocked(conn, null, null, stable)) { 8081 updateOomAdjLocked(); 8082 } 8083 } 8084 } finally { 8085 Binder.restoreCallingIdentity(ident); 8086 } 8087 } 8088 8089 public void removeContentProviderExternal(String name, IBinder token) { 8090 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 8091 "Do not have permission in call removeContentProviderExternal()"); 8092 removeContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId()); 8093 } 8094 8095 private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) { 8096 synchronized (this) { 8097 ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId); 8098 if(cpr == null) { 8099 //remove from mProvidersByClass 8100 if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list"); 8101 return; 8102 } 8103 8104 //update content provider record entry info 8105 ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name); 8106 ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId); 8107 if (localCpr.hasExternalProcessHandles()) { 8108 if (localCpr.removeExternalProcessHandleLocked(token)) { 8109 updateOomAdjLocked(); 8110 } else { 8111 Slog.e(TAG, "Attmpt to remove content provider " + localCpr 8112 + " with no external reference for token: " 8113 + token + "."); 8114 } 8115 } else { 8116 Slog.e(TAG, "Attmpt to remove content provider: " + localCpr 8117 + " with no external references."); 8118 } 8119 } 8120 } 8121 8122 public final void publishContentProviders(IApplicationThread caller, 8123 List<ContentProviderHolder> providers) { 8124 if (providers == null) { 8125 return; 8126 } 8127 8128 enforceNotIsolatedCaller("publishContentProviders"); 8129 synchronized (this) { 8130 final ProcessRecord r = getRecordForAppLocked(caller); 8131 if (DEBUG_MU) 8132 Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid); 8133 if (r == null) { 8134 throw new SecurityException( 8135 "Unable to find app for caller " + caller 8136 + " (pid=" + Binder.getCallingPid() 8137 + ") when publishing content providers"); 8138 } 8139 8140 final long origId = Binder.clearCallingIdentity(); 8141 8142 final int N = providers.size(); 8143 for (int i=0; i<N; i++) { 8144 ContentProviderHolder src = providers.get(i); 8145 if (src == null || src.info == null || src.provider == null) { 8146 continue; 8147 } 8148 ContentProviderRecord dst = r.pubProviders.get(src.info.name); 8149 if (DEBUG_MU) 8150 Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid); 8151 if (dst != null) { 8152 ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name); 8153 mProviderMap.putProviderByClass(comp, dst); 8154 String names[] = dst.info.authority.split(";"); 8155 for (int j = 0; j < names.length; j++) { 8156 mProviderMap.putProviderByName(names[j], dst); 8157 } 8158 8159 int NL = mLaunchingProviders.size(); 8160 int j; 8161 for (j=0; j<NL; j++) { 8162 if (mLaunchingProviders.get(j) == dst) { 8163 mLaunchingProviders.remove(j); 8164 j--; 8165 NL--; 8166 } 8167 } 8168 synchronized (dst) { 8169 dst.provider = src.provider; 8170 dst.proc = r; 8171 dst.notifyAll(); 8172 } 8173 updateOomAdjLocked(r); 8174 } 8175 } 8176 8177 Binder.restoreCallingIdentity(origId); 8178 } 8179 } 8180 8181 public boolean refContentProvider(IBinder connection, int stable, int unstable) { 8182 ContentProviderConnection conn; 8183 try { 8184 conn = (ContentProviderConnection)connection; 8185 } catch (ClassCastException e) { 8186 String msg ="refContentProvider: " + connection 8187 + " not a ContentProviderConnection"; 8188 Slog.w(TAG, msg); 8189 throw new IllegalArgumentException(msg); 8190 } 8191 if (conn == null) { 8192 throw new NullPointerException("connection is null"); 8193 } 8194 8195 synchronized (this) { 8196 if (stable > 0) { 8197 conn.numStableIncs += stable; 8198 } 8199 stable = conn.stableCount + stable; 8200 if (stable < 0) { 8201 throw new IllegalStateException("stableCount < 0: " + stable); 8202 } 8203 8204 if (unstable > 0) { 8205 conn.numUnstableIncs += unstable; 8206 } 8207 unstable = conn.unstableCount + unstable; 8208 if (unstable < 0) { 8209 throw new IllegalStateException("unstableCount < 0: " + unstable); 8210 } 8211 8212 if ((stable+unstable) <= 0) { 8213 throw new IllegalStateException("ref counts can't go to zero here: stable=" 8214 + stable + " unstable=" + unstable); 8215 } 8216 conn.stableCount = stable; 8217 conn.unstableCount = unstable; 8218 return !conn.dead; 8219 } 8220 } 8221 8222 public void unstableProviderDied(IBinder connection) { 8223 ContentProviderConnection conn; 8224 try { 8225 conn = (ContentProviderConnection)connection; 8226 } catch (ClassCastException e) { 8227 String msg ="refContentProvider: " + connection 8228 + " not a ContentProviderConnection"; 8229 Slog.w(TAG, msg); 8230 throw new IllegalArgumentException(msg); 8231 } 8232 if (conn == null) { 8233 throw new NullPointerException("connection is null"); 8234 } 8235 8236 // Safely retrieve the content provider associated with the connection. 8237 IContentProvider provider; 8238 synchronized (this) { 8239 provider = conn.provider.provider; 8240 } 8241 8242 if (provider == null) { 8243 // Um, yeah, we're way ahead of you. 8244 return; 8245 } 8246 8247 // Make sure the caller is being honest with us. 8248 if (provider.asBinder().pingBinder()) { 8249 // Er, no, still looks good to us. 8250 synchronized (this) { 8251 Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid() 8252 + " says " + conn + " died, but we don't agree"); 8253 return; 8254 } 8255 } 8256 8257 // Well look at that! It's dead! 8258 synchronized (this) { 8259 if (conn.provider.provider != provider) { 8260 // But something changed... good enough. 8261 return; 8262 } 8263 8264 ProcessRecord proc = conn.provider.proc; 8265 if (proc == null || proc.thread == null) { 8266 // Seems like the process is already cleaned up. 8267 return; 8268 } 8269 8270 // As far as we're concerned, this is just like receiving a 8271 // death notification... just a bit prematurely. 8272 Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid 8273 + ") early provider death"); 8274 final long ident = Binder.clearCallingIdentity(); 8275 try { 8276 appDiedLocked(proc, proc.pid, proc.thread); 8277 } finally { 8278 Binder.restoreCallingIdentity(ident); 8279 } 8280 } 8281 } 8282 8283 @Override 8284 public void appNotRespondingViaProvider(IBinder connection) { 8285 enforceCallingPermission( 8286 android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()"); 8287 8288 final ContentProviderConnection conn = (ContentProviderConnection) connection; 8289 if (conn == null) { 8290 Slog.w(TAG, "ContentProviderConnection is null"); 8291 return; 8292 } 8293 8294 final ProcessRecord host = conn.provider.proc; 8295 if (host == null) { 8296 Slog.w(TAG, "Failed to find hosting ProcessRecord"); 8297 return; 8298 } 8299 8300 final long token = Binder.clearCallingIdentity(); 8301 try { 8302 appNotResponding(host, null, null, false, "ContentProvider not responding"); 8303 } finally { 8304 Binder.restoreCallingIdentity(token); 8305 } 8306 } 8307 8308 public final void installSystemProviders() { 8309 List<ProviderInfo> providers; 8310 synchronized (this) { 8311 ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID); 8312 providers = generateApplicationProvidersLocked(app); 8313 if (providers != null) { 8314 for (int i=providers.size()-1; i>=0; i--) { 8315 ProviderInfo pi = (ProviderInfo)providers.get(i); 8316 if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) { 8317 Slog.w(TAG, "Not installing system proc provider " + pi.name 8318 + ": not system .apk"); 8319 providers.remove(i); 8320 } 8321 } 8322 } 8323 } 8324 if (providers != null) { 8325 mSystemThread.installSystemProviders(providers); 8326 } 8327 8328 mCoreSettingsObserver = new CoreSettingsObserver(this); 8329 8330 mUsageStatsService.monitorPackages(); 8331 } 8332 8333 /** 8334 * Allows app to retrieve the MIME type of a URI without having permission 8335 * to access its content provider. 8336 * 8337 * CTS tests for this functionality can be run with "runtest cts-appsecurity". 8338 * 8339 * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/ 8340 * src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java 8341 */ 8342 public String getProviderMimeType(Uri uri, int userId) { 8343 enforceNotIsolatedCaller("getProviderMimeType"); 8344 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 8345 userId, false, true, "getProviderMimeType", null); 8346 final String name = uri.getAuthority(); 8347 final long ident = Binder.clearCallingIdentity(); 8348 ContentProviderHolder holder = null; 8349 8350 try { 8351 holder = getContentProviderExternalUnchecked(name, null, userId); 8352 if (holder != null) { 8353 return holder.provider.getType(uri); 8354 } 8355 } catch (RemoteException e) { 8356 Log.w(TAG, "Content provider dead retrieving " + uri, e); 8357 return null; 8358 } finally { 8359 if (holder != null) { 8360 removeContentProviderExternalUnchecked(name, null, userId); 8361 } 8362 Binder.restoreCallingIdentity(ident); 8363 } 8364 8365 return null; 8366 } 8367 8368 // ========================================================= 8369 // GLOBAL MANAGEMENT 8370 // ========================================================= 8371 8372 final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess, 8373 boolean isolated) { 8374 String proc = customProcess != null ? customProcess : info.processName; 8375 BatteryStatsImpl.Uid.Proc ps = null; 8376 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 8377 int uid = info.uid; 8378 if (isolated) { 8379 int userId = UserHandle.getUserId(uid); 8380 int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1; 8381 while (true) { 8382 if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID 8383 || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) { 8384 mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID; 8385 } 8386 uid = UserHandle.getUid(userId, mNextIsolatedProcessUid); 8387 mNextIsolatedProcessUid++; 8388 if (mIsolatedProcesses.indexOfKey(uid) < 0) { 8389 // No process for this uid, use it. 8390 break; 8391 } 8392 stepsLeft--; 8393 if (stepsLeft <= 0) { 8394 return null; 8395 } 8396 } 8397 } 8398 return new ProcessRecord(stats, info, proc, uid); 8399 } 8400 8401 final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated) { 8402 ProcessRecord app; 8403 if (!isolated) { 8404 app = getProcessRecordLocked(info.processName, info.uid, true); 8405 } else { 8406 app = null; 8407 } 8408 8409 if (app == null) { 8410 app = newProcessRecordLocked(info, null, isolated); 8411 mProcessNames.put(info.processName, app.uid, app); 8412 if (isolated) { 8413 mIsolatedProcesses.put(app.uid, app); 8414 } 8415 updateLruProcessLocked(app, false, null); 8416 updateOomAdjLocked(); 8417 } 8418 8419 // This package really, really can not be stopped. 8420 try { 8421 AppGlobals.getPackageManager().setPackageStoppedState( 8422 info.packageName, false, UserHandle.getUserId(app.uid)); 8423 } catch (RemoteException e) { 8424 } catch (IllegalArgumentException e) { 8425 Slog.w(TAG, "Failed trying to unstop package " 8426 + info.packageName + ": " + e); 8427 } 8428 8429 if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) 8430 == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) { 8431 app.persistent = true; 8432 app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ; 8433 } 8434 if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) { 8435 mPersistentStartingProcesses.add(app); 8436 startProcessLocked(app, "added application", app.processName); 8437 } 8438 8439 return app; 8440 } 8441 8442 public void unhandledBack() { 8443 enforceCallingPermission(android.Manifest.permission.FORCE_BACK, 8444 "unhandledBack()"); 8445 8446 synchronized(this) { 8447 final long origId = Binder.clearCallingIdentity(); 8448 try { 8449 getFocusedStack().unhandledBackLocked(); 8450 } finally { 8451 Binder.restoreCallingIdentity(origId); 8452 } 8453 } 8454 } 8455 8456 public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException { 8457 enforceNotIsolatedCaller("openContentUri"); 8458 final int userId = UserHandle.getCallingUserId(); 8459 String name = uri.getAuthority(); 8460 ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId); 8461 ParcelFileDescriptor pfd = null; 8462 if (cph != null) { 8463 // We record the binder invoker's uid in thread-local storage before 8464 // going to the content provider to open the file. Later, in the code 8465 // that handles all permissions checks, we look for this uid and use 8466 // that rather than the Activity Manager's own uid. The effect is that 8467 // we do the check against the caller's permissions even though it looks 8468 // to the content provider like the Activity Manager itself is making 8469 // the request. 8470 sCallerIdentity.set(new Identity( 8471 Binder.getCallingPid(), Binder.getCallingUid())); 8472 try { 8473 pfd = cph.provider.openFile(null, uri, "r", null); 8474 } catch (FileNotFoundException e) { 8475 // do nothing; pfd will be returned null 8476 } finally { 8477 // Ensure that whatever happens, we clean up the identity state 8478 sCallerIdentity.remove(); 8479 } 8480 8481 // We've got the fd now, so we're done with the provider. 8482 removeContentProviderExternalUnchecked(name, null, userId); 8483 } else { 8484 Slog.d(TAG, "Failed to get provider for authority '" + name + "'"); 8485 } 8486 return pfd; 8487 } 8488 8489 // Actually is sleeping or shutting down or whatever else in the future 8490 // is an inactive state. 8491 public boolean isSleepingOrShuttingDown() { 8492 return mSleeping || mShuttingDown; 8493 } 8494 8495 void goingToSleep() { 8496 synchronized(this) { 8497 mWentToSleep = true; 8498 updateEventDispatchingLocked(); 8499 8500 if (!mSleeping) { 8501 mSleeping = true; 8502 mStackSupervisor.goingToSleepLocked(); 8503 8504 // Initialize the wake times of all processes. 8505 checkExcessivePowerUsageLocked(false); 8506 mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 8507 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 8508 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 8509 } 8510 } 8511 } 8512 8513 @Override 8514 public boolean shutdown(int timeout) { 8515 if (checkCallingPermission(android.Manifest.permission.SHUTDOWN) 8516 != PackageManager.PERMISSION_GRANTED) { 8517 throw new SecurityException("Requires permission " 8518 + android.Manifest.permission.SHUTDOWN); 8519 } 8520 8521 boolean timedout = false; 8522 8523 synchronized(this) { 8524 mShuttingDown = true; 8525 updateEventDispatchingLocked(); 8526 timedout = mStackSupervisor.shutdownLocked(timeout); 8527 } 8528 8529 mAppOpsService.shutdown(); 8530 mUsageStatsService.shutdown(); 8531 mBatteryStatsService.shutdown(); 8532 synchronized (this) { 8533 mProcessStats.shutdownLocked(); 8534 } 8535 8536 return timedout; 8537 } 8538 8539 public final void activitySlept(IBinder token) { 8540 if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token); 8541 8542 final long origId = Binder.clearCallingIdentity(); 8543 8544 synchronized (this) { 8545 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 8546 if (r != null) { 8547 mStackSupervisor.activitySleptLocked(r); 8548 } 8549 } 8550 8551 Binder.restoreCallingIdentity(origId); 8552 } 8553 8554 void logLockScreen(String msg) { 8555 if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg + 8556 " mLockScreenShown=" + mLockScreenShown + " mWentToSleep=" + 8557 mWentToSleep + " mSleeping=" + mSleeping + " mDismissKeyguardOnNextActivity=" + 8558 mStackSupervisor.mDismissKeyguardOnNextActivity); 8559 } 8560 8561 private void comeOutOfSleepIfNeededLocked() { 8562 if (!mWentToSleep && !mLockScreenShown) { 8563 if (mSleeping) { 8564 mSleeping = false; 8565 mStackSupervisor.comeOutOfSleepIfNeededLocked(); 8566 } 8567 } 8568 } 8569 8570 void wakingUp() { 8571 synchronized(this) { 8572 mWentToSleep = false; 8573 updateEventDispatchingLocked(); 8574 comeOutOfSleepIfNeededLocked(); 8575 } 8576 } 8577 8578 private void updateEventDispatchingLocked() { 8579 mWindowManager.setEventDispatching(mBooted && !mWentToSleep && !mShuttingDown); 8580 } 8581 8582 public void setLockScreenShown(boolean shown) { 8583 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER) 8584 != PackageManager.PERMISSION_GRANTED) { 8585 throw new SecurityException("Requires permission " 8586 + android.Manifest.permission.DEVICE_POWER); 8587 } 8588 8589 synchronized(this) { 8590 long ident = Binder.clearCallingIdentity(); 8591 try { 8592 if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown); 8593 mLockScreenShown = shown; 8594 comeOutOfSleepIfNeededLocked(); 8595 } finally { 8596 Binder.restoreCallingIdentity(ident); 8597 } 8598 } 8599 } 8600 8601 public void stopAppSwitches() { 8602 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 8603 != PackageManager.PERMISSION_GRANTED) { 8604 throw new SecurityException("Requires permission " 8605 + android.Manifest.permission.STOP_APP_SWITCHES); 8606 } 8607 8608 synchronized(this) { 8609 mAppSwitchesAllowedTime = SystemClock.uptimeMillis() 8610 + APP_SWITCH_DELAY_TIME; 8611 mDidAppSwitch = false; 8612 mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 8613 Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 8614 mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME); 8615 } 8616 } 8617 8618 public void resumeAppSwitches() { 8619 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 8620 != PackageManager.PERMISSION_GRANTED) { 8621 throw new SecurityException("Requires permission " 8622 + android.Manifest.permission.STOP_APP_SWITCHES); 8623 } 8624 8625 synchronized(this) { 8626 // Note that we don't execute any pending app switches... we will 8627 // let those wait until either the timeout, or the next start 8628 // activity request. 8629 mAppSwitchesAllowedTime = 0; 8630 } 8631 } 8632 8633 boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid, 8634 String name) { 8635 if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) { 8636 return true; 8637 } 8638 8639 final int perm = checkComponentPermission( 8640 android.Manifest.permission.STOP_APP_SWITCHES, callingPid, 8641 callingUid, -1, true); 8642 if (perm == PackageManager.PERMISSION_GRANTED) { 8643 return true; 8644 } 8645 8646 Slog.w(TAG, name + " request from " + callingUid + " stopped"); 8647 return false; 8648 } 8649 8650 public void setDebugApp(String packageName, boolean waitForDebugger, 8651 boolean persistent) { 8652 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP, 8653 "setDebugApp()"); 8654 8655 long ident = Binder.clearCallingIdentity(); 8656 try { 8657 // Note that this is not really thread safe if there are multiple 8658 // callers into it at the same time, but that's not a situation we 8659 // care about. 8660 if (persistent) { 8661 final ContentResolver resolver = mContext.getContentResolver(); 8662 Settings.Global.putString( 8663 resolver, Settings.Global.DEBUG_APP, 8664 packageName); 8665 Settings.Global.putInt( 8666 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 8667 waitForDebugger ? 1 : 0); 8668 } 8669 8670 synchronized (this) { 8671 if (!persistent) { 8672 mOrigDebugApp = mDebugApp; 8673 mOrigWaitForDebugger = mWaitForDebugger; 8674 } 8675 mDebugApp = packageName; 8676 mWaitForDebugger = waitForDebugger; 8677 mDebugTransient = !persistent; 8678 if (packageName != null) { 8679 forceStopPackageLocked(packageName, -1, false, false, true, true, 8680 false, UserHandle.USER_ALL, "set debug app"); 8681 } 8682 } 8683 } finally { 8684 Binder.restoreCallingIdentity(ident); 8685 } 8686 } 8687 8688 void setOpenGlTraceApp(ApplicationInfo app, String processName) { 8689 synchronized (this) { 8690 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 8691 if (!isDebuggable) { 8692 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 8693 throw new SecurityException("Process not debuggable: " + app.packageName); 8694 } 8695 } 8696 8697 mOpenGlTraceApp = processName; 8698 } 8699 } 8700 8701 void setProfileApp(ApplicationInfo app, String processName, String profileFile, 8702 ParcelFileDescriptor profileFd, boolean autoStopProfiler) { 8703 synchronized (this) { 8704 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 8705 if (!isDebuggable) { 8706 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 8707 throw new SecurityException("Process not debuggable: " + app.packageName); 8708 } 8709 } 8710 mProfileApp = processName; 8711 mProfileFile = profileFile; 8712 if (mProfileFd != null) { 8713 try { 8714 mProfileFd.close(); 8715 } catch (IOException e) { 8716 } 8717 mProfileFd = null; 8718 } 8719 mProfileFd = profileFd; 8720 mProfileType = 0; 8721 mAutoStopProfiler = autoStopProfiler; 8722 } 8723 } 8724 8725 @Override 8726 public void setAlwaysFinish(boolean enabled) { 8727 enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH, 8728 "setAlwaysFinish()"); 8729 8730 Settings.Global.putInt( 8731 mContext.getContentResolver(), 8732 Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0); 8733 8734 synchronized (this) { 8735 mAlwaysFinishActivities = enabled; 8736 } 8737 } 8738 8739 @Override 8740 public void setActivityController(IActivityController controller) { 8741 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 8742 "setActivityController()"); 8743 synchronized (this) { 8744 mController = controller; 8745 Watchdog.getInstance().setActivityController(controller); 8746 } 8747 } 8748 8749 @Override 8750 public void setUserIsMonkey(boolean userIsMonkey) { 8751 synchronized (this) { 8752 synchronized (mPidsSelfLocked) { 8753 final int callingPid = Binder.getCallingPid(); 8754 ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid); 8755 if (precessRecord == null) { 8756 throw new SecurityException("Unknown process: " + callingPid); 8757 } 8758 if (precessRecord.instrumentationUiAutomationConnection == null) { 8759 throw new SecurityException("Only an instrumentation process " 8760 + "with a UiAutomation can call setUserIsMonkey"); 8761 } 8762 } 8763 mUserIsMonkey = userIsMonkey; 8764 } 8765 } 8766 8767 @Override 8768 public boolean isUserAMonkey() { 8769 synchronized (this) { 8770 // If there is a controller also implies the user is a monkey. 8771 return (mUserIsMonkey || mController != null); 8772 } 8773 } 8774 8775 public void requestBugReport() { 8776 enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport"); 8777 SystemProperties.set("ctl.start", "bugreport"); 8778 } 8779 8780 public static long getInputDispatchingTimeoutLocked(ActivityRecord r) { 8781 return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT; 8782 } 8783 8784 public static long getInputDispatchingTimeoutLocked(ProcessRecord r) { 8785 if (r != null && (r.instrumentationClass != null || r.usingWrapper)) { 8786 return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT; 8787 } 8788 return KEY_DISPATCHING_TIMEOUT; 8789 } 8790 8791 @Override 8792 public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) { 8793 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS) 8794 != PackageManager.PERMISSION_GRANTED) { 8795 throw new SecurityException("Requires permission " 8796 + android.Manifest.permission.FILTER_EVENTS); 8797 } 8798 ProcessRecord proc; 8799 long timeout; 8800 synchronized (this) { 8801 synchronized (mPidsSelfLocked) { 8802 proc = mPidsSelfLocked.get(pid); 8803 } 8804 timeout = getInputDispatchingTimeoutLocked(proc); 8805 } 8806 8807 if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) { 8808 return -1; 8809 } 8810 8811 return timeout; 8812 } 8813 8814 /** 8815 * Handle input dispatching timeouts. 8816 * Returns whether input dispatching should be aborted or not. 8817 */ 8818 public boolean inputDispatchingTimedOut(final ProcessRecord proc, 8819 final ActivityRecord activity, final ActivityRecord parent, 8820 final boolean aboveSystem, String reason) { 8821 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS) 8822 != PackageManager.PERMISSION_GRANTED) { 8823 throw new SecurityException("Requires permission " 8824 + android.Manifest.permission.FILTER_EVENTS); 8825 } 8826 8827 final String annotation; 8828 if (reason == null) { 8829 annotation = "Input dispatching timed out"; 8830 } else { 8831 annotation = "Input dispatching timed out (" + reason + ")"; 8832 } 8833 8834 if (proc != null) { 8835 synchronized (this) { 8836 if (proc.debugging) { 8837 return false; 8838 } 8839 8840 if (mDidDexOpt) { 8841 // Give more time since we were dexopting. 8842 mDidDexOpt = false; 8843 return false; 8844 } 8845 8846 if (proc.instrumentationClass != null) { 8847 Bundle info = new Bundle(); 8848 info.putString("shortMsg", "keyDispatchingTimedOut"); 8849 info.putString("longMsg", annotation); 8850 finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info); 8851 return true; 8852 } 8853 } 8854 mHandler.post(new Runnable() { 8855 @Override 8856 public void run() { 8857 appNotResponding(proc, activity, parent, aboveSystem, annotation); 8858 } 8859 }); 8860 } 8861 8862 return true; 8863 } 8864 8865 public Bundle getAssistContextExtras(int requestType) { 8866 enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO, 8867 "getAssistContextExtras()"); 8868 PendingAssistExtras pae; 8869 Bundle extras = new Bundle(); 8870 synchronized (this) { 8871 ActivityRecord activity = getFocusedStack().mResumedActivity; 8872 if (activity == null) { 8873 Slog.w(TAG, "getAssistContextExtras failed: no resumed activity"); 8874 return null; 8875 } 8876 extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName); 8877 if (activity.app == null || activity.app.thread == null) { 8878 Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity); 8879 return extras; 8880 } 8881 if (activity.app.pid == Binder.getCallingPid()) { 8882 Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity); 8883 return extras; 8884 } 8885 pae = new PendingAssistExtras(activity); 8886 try { 8887 activity.app.thread.requestAssistContextExtras(activity.appToken, pae, 8888 requestType); 8889 mPendingAssistExtras.add(pae); 8890 mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT); 8891 } catch (RemoteException e) { 8892 Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity); 8893 return extras; 8894 } 8895 } 8896 synchronized (pae) { 8897 while (!pae.haveResult) { 8898 try { 8899 pae.wait(); 8900 } catch (InterruptedException e) { 8901 } 8902 } 8903 if (pae.result != null) { 8904 extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result); 8905 } 8906 } 8907 synchronized (this) { 8908 mPendingAssistExtras.remove(pae); 8909 mHandler.removeCallbacks(pae); 8910 } 8911 return extras; 8912 } 8913 8914 public void reportAssistContextExtras(IBinder token, Bundle extras) { 8915 PendingAssistExtras pae = (PendingAssistExtras)token; 8916 synchronized (pae) { 8917 pae.result = extras; 8918 pae.haveResult = true; 8919 pae.notifyAll(); 8920 } 8921 } 8922 8923 public void registerProcessObserver(IProcessObserver observer) { 8924 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 8925 "registerProcessObserver()"); 8926 synchronized (this) { 8927 mProcessObservers.register(observer); 8928 } 8929 } 8930 8931 @Override 8932 public void unregisterProcessObserver(IProcessObserver observer) { 8933 synchronized (this) { 8934 mProcessObservers.unregister(observer); 8935 } 8936 } 8937 8938 @Override 8939 public boolean convertFromTranslucent(IBinder token) { 8940 final long origId = Binder.clearCallingIdentity(); 8941 try { 8942 synchronized (this) { 8943 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 8944 if (r == null) { 8945 return false; 8946 } 8947 if (r.changeWindowTranslucency(true)) { 8948 mWindowManager.setAppFullscreen(token, true); 8949 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 8950 return true; 8951 } 8952 return false; 8953 } 8954 } finally { 8955 Binder.restoreCallingIdentity(origId); 8956 } 8957 } 8958 8959 @Override 8960 public boolean convertToTranslucent(IBinder token) { 8961 final long origId = Binder.clearCallingIdentity(); 8962 try { 8963 synchronized (this) { 8964 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 8965 if (r == null) { 8966 return false; 8967 } 8968 if (r.changeWindowTranslucency(false)) { 8969 r.task.stack.convertToTranslucent(r); 8970 mWindowManager.setAppFullscreen(token, false); 8971 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 8972 return true; 8973 } 8974 return false; 8975 } 8976 } finally { 8977 Binder.restoreCallingIdentity(origId); 8978 } 8979 } 8980 8981 @Override 8982 public void setImmersive(IBinder token, boolean immersive) { 8983 synchronized(this) { 8984 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 8985 if (r == null) { 8986 throw new IllegalArgumentException(); 8987 } 8988 r.immersive = immersive; 8989 8990 // update associated state if we're frontmost 8991 if (r == mFocusedActivity) { 8992 if (DEBUG_IMMERSIVE) { 8993 Slog.d(TAG, "Frontmost changed immersion: "+ r); 8994 } 8995 applyUpdateLockStateLocked(r); 8996 } 8997 } 8998 } 8999 9000 @Override 9001 public boolean isImmersive(IBinder token) { 9002 synchronized (this) { 9003 ActivityRecord r = ActivityRecord.isInStackLocked(token); 9004 if (r == null) { 9005 throw new IllegalArgumentException(); 9006 } 9007 return r.immersive; 9008 } 9009 } 9010 9011 public boolean isTopActivityImmersive() { 9012 enforceNotIsolatedCaller("startActivity"); 9013 synchronized (this) { 9014 ActivityRecord r = getFocusedStack().topRunningActivityLocked(null); 9015 return (r != null) ? r.immersive : false; 9016 } 9017 } 9018 9019 public final void enterSafeMode() { 9020 synchronized(this) { 9021 // It only makes sense to do this before the system is ready 9022 // and started launching other packages. 9023 if (!mSystemReady) { 9024 try { 9025 AppGlobals.getPackageManager().enterSafeMode(); 9026 } catch (RemoteException e) { 9027 } 9028 } 9029 9030 mSafeMode = true; 9031 } 9032 } 9033 9034 public final void showSafeModeOverlay() { 9035 View v = LayoutInflater.from(mContext).inflate( 9036 com.android.internal.R.layout.safe_mode, null); 9037 WindowManager.LayoutParams lp = new WindowManager.LayoutParams(); 9038 lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY; 9039 lp.width = WindowManager.LayoutParams.WRAP_CONTENT; 9040 lp.height = WindowManager.LayoutParams.WRAP_CONTENT; 9041 lp.gravity = Gravity.BOTTOM | Gravity.START; 9042 lp.format = v.getBackground().getOpacity(); 9043 lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE 9044 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE; 9045 lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS; 9046 ((WindowManager)mContext.getSystemService( 9047 Context.WINDOW_SERVICE)).addView(v, lp); 9048 } 9049 9050 public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) { 9051 if (!(sender instanceof PendingIntentRecord)) { 9052 return; 9053 } 9054 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 9055 synchronized (stats) { 9056 if (mBatteryStatsService.isOnBattery()) { 9057 mBatteryStatsService.enforceCallingPermission(); 9058 PendingIntentRecord rec = (PendingIntentRecord)sender; 9059 int MY_UID = Binder.getCallingUid(); 9060 int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid; 9061 BatteryStatsImpl.Uid.Pkg pkg = 9062 stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid, 9063 sourcePkg != null ? sourcePkg : rec.key.packageName); 9064 pkg.incWakeupsLocked(); 9065 } 9066 } 9067 } 9068 9069 public boolean killPids(int[] pids, String pReason, boolean secure) { 9070 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 9071 throw new SecurityException("killPids only available to the system"); 9072 } 9073 String reason = (pReason == null) ? "Unknown" : pReason; 9074 // XXX Note: don't acquire main activity lock here, because the window 9075 // manager calls in with its locks held. 9076 9077 boolean killed = false; 9078 synchronized (mPidsSelfLocked) { 9079 int[] types = new int[pids.length]; 9080 int worstType = 0; 9081 for (int i=0; i<pids.length; i++) { 9082 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 9083 if (proc != null) { 9084 int type = proc.setAdj; 9085 types[i] = type; 9086 if (type > worstType) { 9087 worstType = type; 9088 } 9089 } 9090 } 9091 9092 // If the worst oom_adj is somewhere in the cached proc LRU range, 9093 // then constrain it so we will kill all cached procs. 9094 if (worstType < ProcessList.CACHED_APP_MAX_ADJ 9095 && worstType > ProcessList.CACHED_APP_MIN_ADJ) { 9096 worstType = ProcessList.CACHED_APP_MIN_ADJ; 9097 } 9098 9099 // If this is not a secure call, don't let it kill processes that 9100 // are important. 9101 if (!secure && worstType < ProcessList.SERVICE_ADJ) { 9102 worstType = ProcessList.SERVICE_ADJ; 9103 } 9104 9105 Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType); 9106 for (int i=0; i<pids.length; i++) { 9107 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 9108 if (proc == null) { 9109 continue; 9110 } 9111 int adj = proc.setAdj; 9112 if (adj >= worstType && !proc.killedByAm) { 9113 killUnneededProcessLocked(proc, reason); 9114 killed = true; 9115 } 9116 } 9117 } 9118 return killed; 9119 } 9120 9121 @Override 9122 public void killUid(int uid, String reason) { 9123 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 9124 throw new SecurityException("killUid only available to the system"); 9125 } 9126 synchronized (this) { 9127 killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid), 9128 ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false, 9129 reason != null ? reason : "kill uid"); 9130 } 9131 } 9132 9133 @Override 9134 public boolean killProcessesBelowForeground(String reason) { 9135 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 9136 throw new SecurityException("killProcessesBelowForeground() only available to system"); 9137 } 9138 9139 return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason); 9140 } 9141 9142 private boolean killProcessesBelowAdj(int belowAdj, String reason) { 9143 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 9144 throw new SecurityException("killProcessesBelowAdj() only available to system"); 9145 } 9146 9147 boolean killed = false; 9148 synchronized (mPidsSelfLocked) { 9149 final int size = mPidsSelfLocked.size(); 9150 for (int i = 0; i < size; i++) { 9151 final int pid = mPidsSelfLocked.keyAt(i); 9152 final ProcessRecord proc = mPidsSelfLocked.valueAt(i); 9153 if (proc == null) continue; 9154 9155 final int adj = proc.setAdj; 9156 if (adj > belowAdj && !proc.killedByAm) { 9157 killUnneededProcessLocked(proc, reason); 9158 killed = true; 9159 } 9160 } 9161 } 9162 return killed; 9163 } 9164 9165 @Override 9166 public void hang(final IBinder who, boolean allowRestart) { 9167 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 9168 != PackageManager.PERMISSION_GRANTED) { 9169 throw new SecurityException("Requires permission " 9170 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 9171 } 9172 9173 final IBinder.DeathRecipient death = new DeathRecipient() { 9174 @Override 9175 public void binderDied() { 9176 synchronized (this) { 9177 notifyAll(); 9178 } 9179 } 9180 }; 9181 9182 try { 9183 who.linkToDeath(death, 0); 9184 } catch (RemoteException e) { 9185 Slog.w(TAG, "hang: given caller IBinder is already dead."); 9186 return; 9187 } 9188 9189 synchronized (this) { 9190 Watchdog.getInstance().setAllowRestart(allowRestart); 9191 Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid()); 9192 synchronized (death) { 9193 while (who.isBinderAlive()) { 9194 try { 9195 death.wait(); 9196 } catch (InterruptedException e) { 9197 } 9198 } 9199 } 9200 Watchdog.getInstance().setAllowRestart(true); 9201 } 9202 } 9203 9204 @Override 9205 public void restart() { 9206 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 9207 != PackageManager.PERMISSION_GRANTED) { 9208 throw new SecurityException("Requires permission " 9209 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 9210 } 9211 9212 Log.i(TAG, "Sending shutdown broadcast..."); 9213 9214 BroadcastReceiver br = new BroadcastReceiver() { 9215 @Override public void onReceive(Context context, Intent intent) { 9216 // Now the broadcast is done, finish up the low-level shutdown. 9217 Log.i(TAG, "Shutting down activity manager..."); 9218 shutdown(10000); 9219 Log.i(TAG, "Shutdown complete, restarting!"); 9220 Process.killProcess(Process.myPid()); 9221 System.exit(10); 9222 } 9223 }; 9224 9225 // First send the high-level shut down broadcast. 9226 Intent intent = new Intent(Intent.ACTION_SHUTDOWN); 9227 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 9228 intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true); 9229 /* For now we are not doing a clean shutdown, because things seem to get unhappy. 9230 mContext.sendOrderedBroadcastAsUser(intent, 9231 UserHandle.ALL, null, br, mHandler, 0, null, null); 9232 */ 9233 br.onReceive(mContext, intent); 9234 } 9235 9236 private long getLowRamTimeSinceIdle(long now) { 9237 return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0); 9238 } 9239 9240 @Override 9241 public void performIdleMaintenance() { 9242 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 9243 != PackageManager.PERMISSION_GRANTED) { 9244 throw new SecurityException("Requires permission " 9245 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 9246 } 9247 9248 synchronized (this) { 9249 final long now = SystemClock.uptimeMillis(); 9250 final long timeSinceLastIdle = now - mLastIdleTime; 9251 final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now); 9252 mLastIdleTime = now; 9253 mLowRamTimeSinceLastIdle = 0; 9254 if (mLowRamStartTime != 0) { 9255 mLowRamStartTime = now; 9256 } 9257 9258 StringBuilder sb = new StringBuilder(128); 9259 sb.append("Idle maintenance over "); 9260 TimeUtils.formatDuration(timeSinceLastIdle, sb); 9261 sb.append(" low RAM for "); 9262 TimeUtils.formatDuration(lowRamSinceLastIdle, sb); 9263 Slog.i(TAG, sb.toString()); 9264 9265 // If at least 1/3 of our time since the last idle period has been spent 9266 // with RAM low, then we want to kill processes. 9267 boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3); 9268 9269 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 9270 ProcessRecord proc = mLruProcesses.get(i); 9271 if (proc.notCachedSinceIdle) { 9272 if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP 9273 && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) { 9274 if (doKilling && proc.initialIdlePss != 0 9275 && proc.lastPss > ((proc.initialIdlePss*3)/2)) { 9276 killUnneededProcessLocked(proc, "idle maint (pss " + proc.lastPss 9277 + " from " + proc.initialIdlePss + ")"); 9278 } 9279 } 9280 } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) { 9281 proc.notCachedSinceIdle = true; 9282 proc.initialIdlePss = 0; 9283 proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true, 9284 mSleeping, now); 9285 } 9286 } 9287 9288 mHandler.removeMessages(REQUEST_ALL_PSS_MSG); 9289 mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000); 9290 } 9291 } 9292 9293 private void retrieveSettings() { 9294 final ContentResolver resolver = mContext.getContentResolver(); 9295 String debugApp = Settings.Global.getString( 9296 resolver, Settings.Global.DEBUG_APP); 9297 boolean waitForDebugger = Settings.Global.getInt( 9298 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0; 9299 boolean alwaysFinishActivities = Settings.Global.getInt( 9300 resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0; 9301 boolean forceRtl = Settings.Global.getInt( 9302 resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0; 9303 // Transfer any global setting for forcing RTL layout, into a System Property 9304 SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0"); 9305 9306 Configuration configuration = new Configuration(); 9307 Settings.System.getConfiguration(resolver, configuration); 9308 if (forceRtl) { 9309 // This will take care of setting the correct layout direction flags 9310 configuration.setLayoutDirection(configuration.locale); 9311 } 9312 9313 synchronized (this) { 9314 mDebugApp = mOrigDebugApp = debugApp; 9315 mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger; 9316 mAlwaysFinishActivities = alwaysFinishActivities; 9317 // This happens before any activities are started, so we can 9318 // change mConfiguration in-place. 9319 updateConfigurationLocked(configuration, null, false, true); 9320 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration); 9321 } 9322 } 9323 9324 public boolean testIsSystemReady() { 9325 // no need to synchronize(this) just to read & return the value 9326 return mSystemReady; 9327 } 9328 9329 private static File getCalledPreBootReceiversFile() { 9330 File dataDir = Environment.getDataDirectory(); 9331 File systemDir = new File(dataDir, "system"); 9332 File fname = new File(systemDir, "called_pre_boots.dat"); 9333 return fname; 9334 } 9335 9336 static final int LAST_DONE_VERSION = 10000; 9337 9338 private static ArrayList<ComponentName> readLastDonePreBootReceivers() { 9339 ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>(); 9340 File file = getCalledPreBootReceiversFile(); 9341 FileInputStream fis = null; 9342 try { 9343 fis = new FileInputStream(file); 9344 DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048)); 9345 int fvers = dis.readInt(); 9346 if (fvers == LAST_DONE_VERSION) { 9347 String vers = dis.readUTF(); 9348 String codename = dis.readUTF(); 9349 String build = dis.readUTF(); 9350 if (android.os.Build.VERSION.RELEASE.equals(vers) 9351 && android.os.Build.VERSION.CODENAME.equals(codename) 9352 && android.os.Build.VERSION.INCREMENTAL.equals(build)) { 9353 int num = dis.readInt(); 9354 while (num > 0) { 9355 num--; 9356 String pkg = dis.readUTF(); 9357 String cls = dis.readUTF(); 9358 lastDoneReceivers.add(new ComponentName(pkg, cls)); 9359 } 9360 } 9361 } 9362 } catch (FileNotFoundException e) { 9363 } catch (IOException e) { 9364 Slog.w(TAG, "Failure reading last done pre-boot receivers", e); 9365 } finally { 9366 if (fis != null) { 9367 try { 9368 fis.close(); 9369 } catch (IOException e) { 9370 } 9371 } 9372 } 9373 return lastDoneReceivers; 9374 } 9375 9376 private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) { 9377 File file = getCalledPreBootReceiversFile(); 9378 FileOutputStream fos = null; 9379 DataOutputStream dos = null; 9380 try { 9381 Slog.i(TAG, "Writing new set of last done pre-boot receivers..."); 9382 fos = new FileOutputStream(file); 9383 dos = new DataOutputStream(new BufferedOutputStream(fos, 2048)); 9384 dos.writeInt(LAST_DONE_VERSION); 9385 dos.writeUTF(android.os.Build.VERSION.RELEASE); 9386 dos.writeUTF(android.os.Build.VERSION.CODENAME); 9387 dos.writeUTF(android.os.Build.VERSION.INCREMENTAL); 9388 dos.writeInt(list.size()); 9389 for (int i=0; i<list.size(); i++) { 9390 dos.writeUTF(list.get(i).getPackageName()); 9391 dos.writeUTF(list.get(i).getClassName()); 9392 } 9393 } catch (IOException e) { 9394 Slog.w(TAG, "Failure writing last done pre-boot receivers", e); 9395 file.delete(); 9396 } finally { 9397 FileUtils.sync(fos); 9398 if (dos != null) { 9399 try { 9400 dos.close(); 9401 } catch (IOException e) { 9402 // TODO Auto-generated catch block 9403 e.printStackTrace(); 9404 } 9405 } 9406 } 9407 } 9408 9409 public void systemReady(final Runnable goingCallback) { 9410 synchronized(this) { 9411 if (mSystemReady) { 9412 if (goingCallback != null) goingCallback.run(); 9413 return; 9414 } 9415 9416 // Check to see if there are any update receivers to run. 9417 if (!mDidUpdate) { 9418 if (mWaitingUpdate) { 9419 return; 9420 } 9421 Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED); 9422 List<ResolveInfo> ris = null; 9423 try { 9424 ris = AppGlobals.getPackageManager().queryIntentReceivers( 9425 intent, null, 0, 0); 9426 } catch (RemoteException e) { 9427 } 9428 if (ris != null) { 9429 for (int i=ris.size()-1; i>=0; i--) { 9430 if ((ris.get(i).activityInfo.applicationInfo.flags 9431 &ApplicationInfo.FLAG_SYSTEM) == 0) { 9432 ris.remove(i); 9433 } 9434 } 9435 intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE); 9436 9437 ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers(); 9438 9439 final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>(); 9440 for (int i=0; i<ris.size(); i++) { 9441 ActivityInfo ai = ris.get(i).activityInfo; 9442 ComponentName comp = new ComponentName(ai.packageName, ai.name); 9443 if (lastDoneReceivers.contains(comp)) { 9444 // We already did the pre boot receiver for this app with the current 9445 // platform version, so don't do it again... 9446 ris.remove(i); 9447 i--; 9448 // ...however, do keep it as one that has been done, so we don't 9449 // forget about it when rewriting the file of last done receivers. 9450 doneReceivers.add(comp); 9451 } 9452 } 9453 9454 final int[] users = getUsersLocked(); 9455 for (int i=0; i<ris.size(); i++) { 9456 ActivityInfo ai = ris.get(i).activityInfo; 9457 ComponentName comp = new ComponentName(ai.packageName, ai.name); 9458 doneReceivers.add(comp); 9459 intent.setComponent(comp); 9460 for (int j=0; j<users.length; j++) { 9461 IIntentReceiver finisher = null; 9462 if (i == ris.size()-1 && j == users.length-1) { 9463 finisher = new IIntentReceiver.Stub() { 9464 public void performReceive(Intent intent, int resultCode, 9465 String data, Bundle extras, boolean ordered, 9466 boolean sticky, int sendingUser) { 9467 // The raw IIntentReceiver interface is called 9468 // with the AM lock held, so redispatch to 9469 // execute our code without the lock. 9470 mHandler.post(new Runnable() { 9471 public void run() { 9472 synchronized (ActivityManagerService.this) { 9473 mDidUpdate = true; 9474 } 9475 writeLastDonePreBootReceivers(doneReceivers); 9476 showBootMessage(mContext.getText( 9477 R.string.android_upgrading_complete), 9478 false); 9479 systemReady(goingCallback); 9480 } 9481 }); 9482 } 9483 }; 9484 } 9485 Slog.i(TAG, "Sending system update to " + intent.getComponent() 9486 + " for user " + users[j]); 9487 broadcastIntentLocked(null, null, intent, null, finisher, 9488 0, null, null, null, AppOpsManager.OP_NONE, 9489 true, false, MY_PID, Process.SYSTEM_UID, 9490 users[j]); 9491 if (finisher != null) { 9492 mWaitingUpdate = true; 9493 } 9494 } 9495 } 9496 } 9497 if (mWaitingUpdate) { 9498 return; 9499 } 9500 mDidUpdate = true; 9501 } 9502 9503 mAppOpsService.systemReady(); 9504 mSystemReady = true; 9505 } 9506 9507 ArrayList<ProcessRecord> procsToKill = null; 9508 synchronized(mPidsSelfLocked) { 9509 for (int i=mPidsSelfLocked.size()-1; i>=0; i--) { 9510 ProcessRecord proc = mPidsSelfLocked.valueAt(i); 9511 if (!isAllowedWhileBooting(proc.info)){ 9512 if (procsToKill == null) { 9513 procsToKill = new ArrayList<ProcessRecord>(); 9514 } 9515 procsToKill.add(proc); 9516 } 9517 } 9518 } 9519 9520 synchronized(this) { 9521 if (procsToKill != null) { 9522 for (int i=procsToKill.size()-1; i>=0; i--) { 9523 ProcessRecord proc = procsToKill.get(i); 9524 Slog.i(TAG, "Removing system update proc: " + proc); 9525 removeProcessLocked(proc, true, false, "system update done"); 9526 } 9527 } 9528 9529 // Now that we have cleaned up any update processes, we 9530 // are ready to start launching real processes and know that 9531 // we won't trample on them any more. 9532 mProcessesReady = true; 9533 } 9534 9535 Slog.i(TAG, "System now ready"); 9536 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY, 9537 SystemClock.uptimeMillis()); 9538 9539 synchronized(this) { 9540 // Make sure we have no pre-ready processes sitting around. 9541 9542 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) { 9543 ResolveInfo ri = mContext.getPackageManager() 9544 .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST), 9545 STOCK_PM_FLAGS); 9546 CharSequence errorMsg = null; 9547 if (ri != null) { 9548 ActivityInfo ai = ri.activityInfo; 9549 ApplicationInfo app = ai.applicationInfo; 9550 if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) { 9551 mTopAction = Intent.ACTION_FACTORY_TEST; 9552 mTopData = null; 9553 mTopComponent = new ComponentName(app.packageName, 9554 ai.name); 9555 } else { 9556 errorMsg = mContext.getResources().getText( 9557 com.android.internal.R.string.factorytest_not_system); 9558 } 9559 } else { 9560 errorMsg = mContext.getResources().getText( 9561 com.android.internal.R.string.factorytest_no_action); 9562 } 9563 if (errorMsg != null) { 9564 mTopAction = null; 9565 mTopData = null; 9566 mTopComponent = null; 9567 Message msg = Message.obtain(); 9568 msg.what = SHOW_FACTORY_ERROR_MSG; 9569 msg.getData().putCharSequence("msg", errorMsg); 9570 mHandler.sendMessage(msg); 9571 } 9572 } 9573 } 9574 9575 retrieveSettings(); 9576 9577 synchronized (this) { 9578 readGrantedUriPermissionsLocked(); 9579 } 9580 9581 if (goingCallback != null) goingCallback.run(); 9582 9583 synchronized (this) { 9584 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 9585 try { 9586 List apps = AppGlobals.getPackageManager(). 9587 getPersistentApplications(STOCK_PM_FLAGS); 9588 if (apps != null) { 9589 int N = apps.size(); 9590 int i; 9591 for (i=0; i<N; i++) { 9592 ApplicationInfo info 9593 = (ApplicationInfo)apps.get(i); 9594 if (info != null && 9595 !info.packageName.equals("android")) { 9596 addAppLocked(info, false); 9597 } 9598 } 9599 } 9600 } catch (RemoteException ex) { 9601 // pm is in same process, this will never happen. 9602 } 9603 } 9604 9605 // Start up initial activity. 9606 mBooting = true; 9607 9608 try { 9609 if (AppGlobals.getPackageManager().hasSystemUidErrors()) { 9610 Message msg = Message.obtain(); 9611 msg.what = SHOW_UID_ERROR_MSG; 9612 mHandler.sendMessage(msg); 9613 } 9614 } catch (RemoteException e) { 9615 } 9616 9617 long ident = Binder.clearCallingIdentity(); 9618 try { 9619 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 9620 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 9621 | Intent.FLAG_RECEIVER_FOREGROUND); 9622 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); 9623 broadcastIntentLocked(null, null, intent, 9624 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 9625 false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId); 9626 intent = new Intent(Intent.ACTION_USER_STARTING); 9627 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 9628 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); 9629 broadcastIntentLocked(null, null, intent, 9630 null, new IIntentReceiver.Stub() { 9631 @Override 9632 public void performReceive(Intent intent, int resultCode, String data, 9633 Bundle extras, boolean ordered, boolean sticky, int sendingUser) 9634 throws RemoteException { 9635 } 9636 }, 0, null, null, 9637 android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 9638 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 9639 } finally { 9640 Binder.restoreCallingIdentity(ident); 9641 } 9642 mStackSupervisor.resumeTopActivitiesLocked(); 9643 sendUserSwitchBroadcastsLocked(-1, mCurrentUserId); 9644 } 9645 } 9646 9647 private boolean makeAppCrashingLocked(ProcessRecord app, 9648 String shortMsg, String longMsg, String stackTrace) { 9649 app.crashing = true; 9650 app.crashingReport = generateProcessError(app, 9651 ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace); 9652 startAppProblemLocked(app); 9653 app.stopFreezingAllLocked(); 9654 return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace); 9655 } 9656 9657 private void makeAppNotRespondingLocked(ProcessRecord app, 9658 String activity, String shortMsg, String longMsg) { 9659 app.notResponding = true; 9660 app.notRespondingReport = generateProcessError(app, 9661 ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING, 9662 activity, shortMsg, longMsg, null); 9663 startAppProblemLocked(app); 9664 app.stopFreezingAllLocked(); 9665 } 9666 9667 /** 9668 * Generate a process error record, suitable for attachment to a ProcessRecord. 9669 * 9670 * @param app The ProcessRecord in which the error occurred. 9671 * @param condition Crashing, Application Not Responding, etc. Values are defined in 9672 * ActivityManager.AppErrorStateInfo 9673 * @param activity The activity associated with the crash, if known. 9674 * @param shortMsg Short message describing the crash. 9675 * @param longMsg Long message describing the crash. 9676 * @param stackTrace Full crash stack trace, may be null. 9677 * 9678 * @return Returns a fully-formed AppErrorStateInfo record. 9679 */ 9680 private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app, 9681 int condition, String activity, String shortMsg, String longMsg, String stackTrace) { 9682 ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo(); 9683 9684 report.condition = condition; 9685 report.processName = app.processName; 9686 report.pid = app.pid; 9687 report.uid = app.info.uid; 9688 report.tag = activity; 9689 report.shortMsg = shortMsg; 9690 report.longMsg = longMsg; 9691 report.stackTrace = stackTrace; 9692 9693 return report; 9694 } 9695 9696 void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) { 9697 synchronized (this) { 9698 app.crashing = false; 9699 app.crashingReport = null; 9700 app.notResponding = false; 9701 app.notRespondingReport = null; 9702 if (app.anrDialog == fromDialog) { 9703 app.anrDialog = null; 9704 } 9705 if (app.waitDialog == fromDialog) { 9706 app.waitDialog = null; 9707 } 9708 if (app.pid > 0 && app.pid != MY_PID) { 9709 handleAppCrashLocked(app, null, null, null); 9710 killUnneededProcessLocked(app, "user request after error"); 9711 } 9712 } 9713 } 9714 9715 private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg, 9716 String stackTrace) { 9717 long now = SystemClock.uptimeMillis(); 9718 9719 Long crashTime; 9720 if (!app.isolated) { 9721 crashTime = mProcessCrashTimes.get(app.info.processName, app.uid); 9722 } else { 9723 crashTime = null; 9724 } 9725 if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) { 9726 // This process loses! 9727 Slog.w(TAG, "Process " + app.info.processName 9728 + " has crashed too many times: killing!"); 9729 EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH, 9730 app.userId, app.info.processName, app.uid); 9731 mStackSupervisor.handleAppCrashLocked(app); 9732 if (!app.persistent) { 9733 // We don't want to start this process again until the user 9734 // explicitly does so... but for persistent process, we really 9735 // need to keep it running. If a persistent process is actually 9736 // repeatedly crashing, then badness for everyone. 9737 EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid, 9738 app.info.processName); 9739 if (!app.isolated) { 9740 // XXX We don't have a way to mark isolated processes 9741 // as bad, since they don't have a peristent identity. 9742 mBadProcesses.put(app.info.processName, app.uid, 9743 new BadProcessInfo(now, shortMsg, longMsg, stackTrace)); 9744 mProcessCrashTimes.remove(app.info.processName, app.uid); 9745 } 9746 app.bad = true; 9747 app.removed = true; 9748 // Don't let services in this process be restarted and potentially 9749 // annoy the user repeatedly. Unless it is persistent, since those 9750 // processes run critical code. 9751 removeProcessLocked(app, false, false, "crash"); 9752 mStackSupervisor.resumeTopActivitiesLocked(); 9753 return false; 9754 } 9755 mStackSupervisor.resumeTopActivitiesLocked(); 9756 } else { 9757 mStackSupervisor.finishTopRunningActivityLocked(app); 9758 } 9759 9760 // Bump up the crash count of any services currently running in the proc. 9761 for (int i=app.services.size()-1; i>=0; i--) { 9762 // Any services running in the application need to be placed 9763 // back in the pending list. 9764 ServiceRecord sr = app.services.valueAt(i); 9765 sr.crashCount++; 9766 } 9767 9768 // If the crashing process is what we consider to be the "home process" and it has been 9769 // replaced by a third-party app, clear the package preferred activities from packages 9770 // with a home activity running in the process to prevent a repeatedly crashing app 9771 // from blocking the user to manually clear the list. 9772 final ArrayList<ActivityRecord> activities = app.activities; 9773 if (app == mHomeProcess && activities.size() > 0 9774 && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) { 9775 for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) { 9776 final ActivityRecord r = activities.get(activityNdx); 9777 if (r.isHomeActivity()) { 9778 Log.i(TAG, "Clearing package preferred activities from " + r.packageName); 9779 try { 9780 ActivityThread.getPackageManager() 9781 .clearPackagePreferredActivities(r.packageName); 9782 } catch (RemoteException c) { 9783 // pm is in same process, this will never happen. 9784 } 9785 } 9786 } 9787 } 9788 9789 if (!app.isolated) { 9790 // XXX Can't keep track of crash times for isolated processes, 9791 // because they don't have a perisistent identity. 9792 mProcessCrashTimes.put(app.info.processName, app.uid, now); 9793 } 9794 9795 return true; 9796 } 9797 9798 void startAppProblemLocked(ProcessRecord app) { 9799 if (app.userId == mCurrentUserId) { 9800 app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver( 9801 mContext, app.info.packageName, app.info.flags); 9802 } else { 9803 // If this app is not running under the current user, then we 9804 // can't give it a report button because that would require 9805 // launching the report UI under a different user. 9806 app.errorReportReceiver = null; 9807 } 9808 skipCurrentReceiverLocked(app); 9809 } 9810 9811 void skipCurrentReceiverLocked(ProcessRecord app) { 9812 for (BroadcastQueue queue : mBroadcastQueues) { 9813 queue.skipCurrentReceiverLocked(app); 9814 } 9815 } 9816 9817 /** 9818 * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes. 9819 * The application process will exit immediately after this call returns. 9820 * @param app object of the crashing app, null for the system server 9821 * @param crashInfo describing the exception 9822 */ 9823 public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) { 9824 ProcessRecord r = findAppProcess(app, "Crash"); 9825 final String processName = app == null ? "system_server" 9826 : (r == null ? "unknown" : r.processName); 9827 9828 handleApplicationCrashInner("crash", r, processName, crashInfo); 9829 } 9830 9831 /* Native crash reporting uses this inner version because it needs to be somewhat 9832 * decoupled from the AM-managed cleanup lifecycle 9833 */ 9834 void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName, 9835 ApplicationErrorReport.CrashInfo crashInfo) { 9836 EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(), 9837 UserHandle.getUserId(Binder.getCallingUid()), processName, 9838 r == null ? -1 : r.info.flags, 9839 crashInfo.exceptionClassName, 9840 crashInfo.exceptionMessage, 9841 crashInfo.throwFileName, 9842 crashInfo.throwLineNumber); 9843 9844 addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo); 9845 9846 crashApplication(r, crashInfo); 9847 } 9848 9849 public void handleApplicationStrictModeViolation( 9850 IBinder app, 9851 int violationMask, 9852 StrictMode.ViolationInfo info) { 9853 ProcessRecord r = findAppProcess(app, "StrictMode"); 9854 if (r == null) { 9855 return; 9856 } 9857 9858 if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) { 9859 Integer stackFingerprint = info.hashCode(); 9860 boolean logIt = true; 9861 synchronized (mAlreadyLoggedViolatedStacks) { 9862 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) { 9863 logIt = false; 9864 // TODO: sub-sample into EventLog for these, with 9865 // the info.durationMillis? Then we'd get 9866 // the relative pain numbers, without logging all 9867 // the stack traces repeatedly. We'd want to do 9868 // likewise in the client code, which also does 9869 // dup suppression, before the Binder call. 9870 } else { 9871 if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) { 9872 mAlreadyLoggedViolatedStacks.clear(); 9873 } 9874 mAlreadyLoggedViolatedStacks.add(stackFingerprint); 9875 } 9876 } 9877 if (logIt) { 9878 logStrictModeViolationToDropBox(r, info); 9879 } 9880 } 9881 9882 if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) { 9883 AppErrorResult result = new AppErrorResult(); 9884 synchronized (this) { 9885 final long origId = Binder.clearCallingIdentity(); 9886 9887 Message msg = Message.obtain(); 9888 msg.what = SHOW_STRICT_MODE_VIOLATION_MSG; 9889 HashMap<String, Object> data = new HashMap<String, Object>(); 9890 data.put("result", result); 9891 data.put("app", r); 9892 data.put("violationMask", violationMask); 9893 data.put("info", info); 9894 msg.obj = data; 9895 mHandler.sendMessage(msg); 9896 9897 Binder.restoreCallingIdentity(origId); 9898 } 9899 int res = result.get(); 9900 Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res); 9901 } 9902 } 9903 9904 // Depending on the policy in effect, there could be a bunch of 9905 // these in quick succession so we try to batch these together to 9906 // minimize disk writes, number of dropbox entries, and maximize 9907 // compression, by having more fewer, larger records. 9908 private void logStrictModeViolationToDropBox( 9909 ProcessRecord process, 9910 StrictMode.ViolationInfo info) { 9911 if (info == null) { 9912 return; 9913 } 9914 final boolean isSystemApp = process == null || 9915 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM | 9916 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0; 9917 final String processName = process == null ? "unknown" : process.processName; 9918 final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode"; 9919 final DropBoxManager dbox = (DropBoxManager) 9920 mContext.getSystemService(Context.DROPBOX_SERVICE); 9921 9922 // Exit early if the dropbox isn't configured to accept this report type. 9923 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 9924 9925 boolean bufferWasEmpty; 9926 boolean needsFlush; 9927 final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024); 9928 synchronized (sb) { 9929 bufferWasEmpty = sb.length() == 0; 9930 appendDropBoxProcessHeaders(process, processName, sb); 9931 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 9932 sb.append("System-App: ").append(isSystemApp).append("\n"); 9933 sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n"); 9934 if (info.violationNumThisLoop != 0) { 9935 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n"); 9936 } 9937 if (info.numAnimationsRunning != 0) { 9938 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n"); 9939 } 9940 if (info.broadcastIntentAction != null) { 9941 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n"); 9942 } 9943 if (info.durationMillis != -1) { 9944 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n"); 9945 } 9946 if (info.numInstances != -1) { 9947 sb.append("Instance-Count: ").append(info.numInstances).append("\n"); 9948 } 9949 if (info.tags != null) { 9950 for (String tag : info.tags) { 9951 sb.append("Span-Tag: ").append(tag).append("\n"); 9952 } 9953 } 9954 sb.append("\n"); 9955 if (info.crashInfo != null && info.crashInfo.stackTrace != null) { 9956 sb.append(info.crashInfo.stackTrace); 9957 } 9958 sb.append("\n"); 9959 9960 // Only buffer up to ~64k. Various logging bits truncate 9961 // things at 128k. 9962 needsFlush = (sb.length() > 64 * 1024); 9963 } 9964 9965 // Flush immediately if the buffer's grown too large, or this 9966 // is a non-system app. Non-system apps are isolated with a 9967 // different tag & policy and not batched. 9968 // 9969 // Batching is useful during internal testing with 9970 // StrictMode settings turned up high. Without batching, 9971 // thousands of separate files could be created on boot. 9972 if (!isSystemApp || needsFlush) { 9973 new Thread("Error dump: " + dropboxTag) { 9974 @Override 9975 public void run() { 9976 String report; 9977 synchronized (sb) { 9978 report = sb.toString(); 9979 sb.delete(0, sb.length()); 9980 sb.trimToSize(); 9981 } 9982 if (report.length() != 0) { 9983 dbox.addText(dropboxTag, report); 9984 } 9985 } 9986 }.start(); 9987 return; 9988 } 9989 9990 // System app batching: 9991 if (!bufferWasEmpty) { 9992 // An existing dropbox-writing thread is outstanding, so 9993 // we don't need to start it up. The existing thread will 9994 // catch the buffer appends we just did. 9995 return; 9996 } 9997 9998 // Worker thread to both batch writes and to avoid blocking the caller on I/O. 9999 // (After this point, we shouldn't access AMS internal data structures.) 10000 new Thread("Error dump: " + dropboxTag) { 10001 @Override 10002 public void run() { 10003 // 5 second sleep to let stacks arrive and be batched together 10004 try { 10005 Thread.sleep(5000); // 5 seconds 10006 } catch (InterruptedException e) {} 10007 10008 String errorReport; 10009 synchronized (mStrictModeBuffer) { 10010 errorReport = mStrictModeBuffer.toString(); 10011 if (errorReport.length() == 0) { 10012 return; 10013 } 10014 mStrictModeBuffer.delete(0, mStrictModeBuffer.length()); 10015 mStrictModeBuffer.trimToSize(); 10016 } 10017 dbox.addText(dropboxTag, errorReport); 10018 } 10019 }.start(); 10020 } 10021 10022 /** 10023 * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors. 10024 * @param app object of the crashing app, null for the system server 10025 * @param tag reported by the caller 10026 * @param crashInfo describing the context of the error 10027 * @return true if the process should exit immediately (WTF is fatal) 10028 */ 10029 public boolean handleApplicationWtf(IBinder app, String tag, 10030 ApplicationErrorReport.CrashInfo crashInfo) { 10031 ProcessRecord r = findAppProcess(app, "WTF"); 10032 final String processName = app == null ? "system_server" 10033 : (r == null ? "unknown" : r.processName); 10034 10035 EventLog.writeEvent(EventLogTags.AM_WTF, 10036 UserHandle.getUserId(Binder.getCallingUid()), Binder.getCallingPid(), 10037 processName, 10038 r == null ? -1 : r.info.flags, 10039 tag, crashInfo.exceptionMessage); 10040 10041 addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo); 10042 10043 if (r != null && r.pid != Process.myPid() && 10044 Settings.Global.getInt(mContext.getContentResolver(), 10045 Settings.Global.WTF_IS_FATAL, 0) != 0) { 10046 crashApplication(r, crashInfo); 10047 return true; 10048 } else { 10049 return false; 10050 } 10051 } 10052 10053 /** 10054 * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit}) 10055 * @return the corresponding {@link ProcessRecord} object, or null if none could be found 10056 */ 10057 private ProcessRecord findAppProcess(IBinder app, String reason) { 10058 if (app == null) { 10059 return null; 10060 } 10061 10062 synchronized (this) { 10063 final int NP = mProcessNames.getMap().size(); 10064 for (int ip=0; ip<NP; ip++) { 10065 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 10066 final int NA = apps.size(); 10067 for (int ia=0; ia<NA; ia++) { 10068 ProcessRecord p = apps.valueAt(ia); 10069 if (p.thread != null && p.thread.asBinder() == app) { 10070 return p; 10071 } 10072 } 10073 } 10074 10075 Slog.w(TAG, "Can't find mystery application for " + reason 10076 + " from pid=" + Binder.getCallingPid() 10077 + " uid=" + Binder.getCallingUid() + ": " + app); 10078 return null; 10079 } 10080 } 10081 10082 /** 10083 * Utility function for addErrorToDropBox and handleStrictModeViolation's logging 10084 * to append various headers to the dropbox log text. 10085 */ 10086 private void appendDropBoxProcessHeaders(ProcessRecord process, String processName, 10087 StringBuilder sb) { 10088 // Watchdog thread ends up invoking this function (with 10089 // a null ProcessRecord) to add the stack file to dropbox. 10090 // Do not acquire a lock on this (am) in such cases, as it 10091 // could cause a potential deadlock, if and when watchdog 10092 // is invoked due to unavailability of lock on am and it 10093 // would prevent watchdog from killing system_server. 10094 if (process == null) { 10095 sb.append("Process: ").append(processName).append("\n"); 10096 return; 10097 } 10098 // Note: ProcessRecord 'process' is guarded by the service 10099 // instance. (notably process.pkgList, which could otherwise change 10100 // concurrently during execution of this method) 10101 synchronized (this) { 10102 sb.append("Process: ").append(processName).append("\n"); 10103 int flags = process.info.flags; 10104 IPackageManager pm = AppGlobals.getPackageManager(); 10105 sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n"); 10106 for (int ip=0; ip<process.pkgList.size(); ip++) { 10107 String pkg = process.pkgList.keyAt(ip); 10108 sb.append("Package: ").append(pkg); 10109 try { 10110 PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId()); 10111 if (pi != null) { 10112 sb.append(" v").append(pi.versionCode); 10113 if (pi.versionName != null) { 10114 sb.append(" (").append(pi.versionName).append(")"); 10115 } 10116 } 10117 } catch (RemoteException e) { 10118 Slog.e(TAG, "Error getting package info: " + pkg, e); 10119 } 10120 sb.append("\n"); 10121 } 10122 } 10123 } 10124 10125 private static String processClass(ProcessRecord process) { 10126 if (process == null || process.pid == MY_PID) { 10127 return "system_server"; 10128 } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) { 10129 return "system_app"; 10130 } else { 10131 return "data_app"; 10132 } 10133 } 10134 10135 /** 10136 * Write a description of an error (crash, WTF, ANR) to the drop box. 10137 * @param eventType to include in the drop box tag ("crash", "wtf", etc.) 10138 * @param process which caused the error, null means the system server 10139 * @param activity which triggered the error, null if unknown 10140 * @param parent activity related to the error, null if unknown 10141 * @param subject line related to the error, null if absent 10142 * @param report in long form describing the error, null if absent 10143 * @param logFile to include in the report, null if none 10144 * @param crashInfo giving an application stack trace, null if absent 10145 */ 10146 public void addErrorToDropBox(String eventType, 10147 ProcessRecord process, String processName, ActivityRecord activity, 10148 ActivityRecord parent, String subject, 10149 final String report, final File logFile, 10150 final ApplicationErrorReport.CrashInfo crashInfo) { 10151 // NOTE -- this must never acquire the ActivityManagerService lock, 10152 // otherwise the watchdog may be prevented from resetting the system. 10153 10154 final String dropboxTag = processClass(process) + "_" + eventType; 10155 final DropBoxManager dbox = (DropBoxManager) 10156 mContext.getSystemService(Context.DROPBOX_SERVICE); 10157 10158 // Exit early if the dropbox isn't configured to accept this report type. 10159 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 10160 10161 final StringBuilder sb = new StringBuilder(1024); 10162 appendDropBoxProcessHeaders(process, processName, sb); 10163 if (activity != null) { 10164 sb.append("Activity: ").append(activity.shortComponentName).append("\n"); 10165 } 10166 if (parent != null && parent.app != null && parent.app.pid != process.pid) { 10167 sb.append("Parent-Process: ").append(parent.app.processName).append("\n"); 10168 } 10169 if (parent != null && parent != activity) { 10170 sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n"); 10171 } 10172 if (subject != null) { 10173 sb.append("Subject: ").append(subject).append("\n"); 10174 } 10175 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 10176 if (Debug.isDebuggerConnected()) { 10177 sb.append("Debugger: Connected\n"); 10178 } 10179 sb.append("\n"); 10180 10181 // Do the rest in a worker thread to avoid blocking the caller on I/O 10182 // (After this point, we shouldn't access AMS internal data structures.) 10183 Thread worker = new Thread("Error dump: " + dropboxTag) { 10184 @Override 10185 public void run() { 10186 if (report != null) { 10187 sb.append(report); 10188 } 10189 if (logFile != null) { 10190 try { 10191 sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE, 10192 "\n\n[[TRUNCATED]]")); 10193 } catch (IOException e) { 10194 Slog.e(TAG, "Error reading " + logFile, e); 10195 } 10196 } 10197 if (crashInfo != null && crashInfo.stackTrace != null) { 10198 sb.append(crashInfo.stackTrace); 10199 } 10200 10201 String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag; 10202 int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0); 10203 if (lines > 0) { 10204 sb.append("\n"); 10205 10206 // Merge several logcat streams, and take the last N lines 10207 InputStreamReader input = null; 10208 try { 10209 java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat", 10210 "-v", "time", "-b", "events", "-b", "system", "-b", "main", 10211 "-t", String.valueOf(lines)).redirectErrorStream(true).start(); 10212 10213 try { logcat.getOutputStream().close(); } catch (IOException e) {} 10214 try { logcat.getErrorStream().close(); } catch (IOException e) {} 10215 input = new InputStreamReader(logcat.getInputStream()); 10216 10217 int num; 10218 char[] buf = new char[8192]; 10219 while ((num = input.read(buf)) > 0) sb.append(buf, 0, num); 10220 } catch (IOException e) { 10221 Slog.e(TAG, "Error running logcat", e); 10222 } finally { 10223 if (input != null) try { input.close(); } catch (IOException e) {} 10224 } 10225 } 10226 10227 dbox.addText(dropboxTag, sb.toString()); 10228 } 10229 }; 10230 10231 if (process == null) { 10232 // If process is null, we are being called from some internal code 10233 // and may be about to die -- run this synchronously. 10234 worker.run(); 10235 } else { 10236 worker.start(); 10237 } 10238 } 10239 10240 /** 10241 * Bring up the "unexpected error" dialog box for a crashing app. 10242 * Deal with edge cases (intercepts from instrumented applications, 10243 * ActivityController, error intent receivers, that sort of thing). 10244 * @param r the application crashing 10245 * @param crashInfo describing the failure 10246 */ 10247 private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) { 10248 long timeMillis = System.currentTimeMillis(); 10249 String shortMsg = crashInfo.exceptionClassName; 10250 String longMsg = crashInfo.exceptionMessage; 10251 String stackTrace = crashInfo.stackTrace; 10252 if (shortMsg != null && longMsg != null) { 10253 longMsg = shortMsg + ": " + longMsg; 10254 } else if (shortMsg != null) { 10255 longMsg = shortMsg; 10256 } 10257 10258 AppErrorResult result = new AppErrorResult(); 10259 synchronized (this) { 10260 if (mController != null) { 10261 try { 10262 String name = r != null ? r.processName : null; 10263 int pid = r != null ? r.pid : Binder.getCallingPid(); 10264 if (!mController.appCrashed(name, pid, 10265 shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) { 10266 Slog.w(TAG, "Force-killing crashed app " + name 10267 + " at watcher's request"); 10268 Process.killProcess(pid); 10269 return; 10270 } 10271 } catch (RemoteException e) { 10272 mController = null; 10273 Watchdog.getInstance().setActivityController(null); 10274 } 10275 } 10276 10277 final long origId = Binder.clearCallingIdentity(); 10278 10279 // If this process is running instrumentation, finish it. 10280 if (r != null && r.instrumentationClass != null) { 10281 Slog.w(TAG, "Error in app " + r.processName 10282 + " running instrumentation " + r.instrumentationClass + ":"); 10283 if (shortMsg != null) Slog.w(TAG, " " + shortMsg); 10284 if (longMsg != null) Slog.w(TAG, " " + longMsg); 10285 Bundle info = new Bundle(); 10286 info.putString("shortMsg", shortMsg); 10287 info.putString("longMsg", longMsg); 10288 finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info); 10289 Binder.restoreCallingIdentity(origId); 10290 return; 10291 } 10292 10293 // If we can't identify the process or it's already exceeded its crash quota, 10294 // quit right away without showing a crash dialog. 10295 if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) { 10296 Binder.restoreCallingIdentity(origId); 10297 return; 10298 } 10299 10300 Message msg = Message.obtain(); 10301 msg.what = SHOW_ERROR_MSG; 10302 HashMap data = new HashMap(); 10303 data.put("result", result); 10304 data.put("app", r); 10305 msg.obj = data; 10306 mHandler.sendMessage(msg); 10307 10308 Binder.restoreCallingIdentity(origId); 10309 } 10310 10311 int res = result.get(); 10312 10313 Intent appErrorIntent = null; 10314 synchronized (this) { 10315 if (r != null && !r.isolated) { 10316 // XXX Can't keep track of crash time for isolated processes, 10317 // since they don't have a persistent identity. 10318 mProcessCrashTimes.put(r.info.processName, r.uid, 10319 SystemClock.uptimeMillis()); 10320 } 10321 if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) { 10322 appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo); 10323 } 10324 } 10325 10326 if (appErrorIntent != null) { 10327 try { 10328 mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId)); 10329 } catch (ActivityNotFoundException e) { 10330 Slog.w(TAG, "bug report receiver dissappeared", e); 10331 } 10332 } 10333 } 10334 10335 Intent createAppErrorIntentLocked(ProcessRecord r, 10336 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 10337 ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo); 10338 if (report == null) { 10339 return null; 10340 } 10341 Intent result = new Intent(Intent.ACTION_APP_ERROR); 10342 result.setComponent(r.errorReportReceiver); 10343 result.putExtra(Intent.EXTRA_BUG_REPORT, report); 10344 result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 10345 return result; 10346 } 10347 10348 private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r, 10349 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 10350 if (r.errorReportReceiver == null) { 10351 return null; 10352 } 10353 10354 if (!r.crashing && !r.notResponding && !r.forceCrashReport) { 10355 return null; 10356 } 10357 10358 ApplicationErrorReport report = new ApplicationErrorReport(); 10359 report.packageName = r.info.packageName; 10360 report.installerPackageName = r.errorReportReceiver.getPackageName(); 10361 report.processName = r.processName; 10362 report.time = timeMillis; 10363 report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0; 10364 10365 if (r.crashing || r.forceCrashReport) { 10366 report.type = ApplicationErrorReport.TYPE_CRASH; 10367 report.crashInfo = crashInfo; 10368 } else if (r.notResponding) { 10369 report.type = ApplicationErrorReport.TYPE_ANR; 10370 report.anrInfo = new ApplicationErrorReport.AnrInfo(); 10371 10372 report.anrInfo.activity = r.notRespondingReport.tag; 10373 report.anrInfo.cause = r.notRespondingReport.shortMsg; 10374 report.anrInfo.info = r.notRespondingReport.longMsg; 10375 } 10376 10377 return report; 10378 } 10379 10380 public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() { 10381 enforceNotIsolatedCaller("getProcessesInErrorState"); 10382 // assume our apps are happy - lazy create the list 10383 List<ActivityManager.ProcessErrorStateInfo> errList = null; 10384 10385 final boolean allUsers = ActivityManager.checkUidPermission( 10386 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 10387 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 10388 int userId = UserHandle.getUserId(Binder.getCallingUid()); 10389 10390 synchronized (this) { 10391 10392 // iterate across all processes 10393 for (int i=mLruProcesses.size()-1; i>=0; i--) { 10394 ProcessRecord app = mLruProcesses.get(i); 10395 if (!allUsers && app.userId != userId) { 10396 continue; 10397 } 10398 if ((app.thread != null) && (app.crashing || app.notResponding)) { 10399 // This one's in trouble, so we'll generate a report for it 10400 // crashes are higher priority (in case there's a crash *and* an anr) 10401 ActivityManager.ProcessErrorStateInfo report = null; 10402 if (app.crashing) { 10403 report = app.crashingReport; 10404 } else if (app.notResponding) { 10405 report = app.notRespondingReport; 10406 } 10407 10408 if (report != null) { 10409 if (errList == null) { 10410 errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1); 10411 } 10412 errList.add(report); 10413 } else { 10414 Slog.w(TAG, "Missing app error report, app = " + app.processName + 10415 " crashing = " + app.crashing + 10416 " notResponding = " + app.notResponding); 10417 } 10418 } 10419 } 10420 } 10421 10422 return errList; 10423 } 10424 10425 static int oomAdjToImportance(int adj, ActivityManager.RunningAppProcessInfo currApp) { 10426 if (adj >= ProcessList.CACHED_APP_MIN_ADJ) { 10427 if (currApp != null) { 10428 currApp.lru = adj - ProcessList.CACHED_APP_MIN_ADJ + 1; 10429 } 10430 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 10431 } else if (adj >= ProcessList.SERVICE_B_ADJ) { 10432 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 10433 } else if (adj >= ProcessList.HOME_APP_ADJ) { 10434 if (currApp != null) { 10435 currApp.lru = 0; 10436 } 10437 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 10438 } else if (adj >= ProcessList.SERVICE_ADJ) { 10439 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 10440 } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 10441 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE; 10442 } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) { 10443 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE; 10444 } else if (adj >= ProcessList.VISIBLE_APP_ADJ) { 10445 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE; 10446 } else { 10447 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND; 10448 } 10449 } 10450 10451 private void fillInProcMemInfo(ProcessRecord app, 10452 ActivityManager.RunningAppProcessInfo outInfo) { 10453 outInfo.pid = app.pid; 10454 outInfo.uid = app.info.uid; 10455 if (mHeavyWeightProcess == app) { 10456 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE; 10457 } 10458 if (app.persistent) { 10459 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT; 10460 } 10461 if (app.activities.size() > 0) { 10462 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES; 10463 } 10464 outInfo.lastTrimLevel = app.trimMemoryLevel; 10465 int adj = app.curAdj; 10466 outInfo.importance = oomAdjToImportance(adj, outInfo); 10467 outInfo.importanceReasonCode = app.adjTypeCode; 10468 } 10469 10470 public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() { 10471 enforceNotIsolatedCaller("getRunningAppProcesses"); 10472 // Lazy instantiation of list 10473 List<ActivityManager.RunningAppProcessInfo> runList = null; 10474 final boolean allUsers = ActivityManager.checkUidPermission( 10475 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 10476 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 10477 int userId = UserHandle.getUserId(Binder.getCallingUid()); 10478 synchronized (this) { 10479 // Iterate across all processes 10480 for (int i=mLruProcesses.size()-1; i>=0; i--) { 10481 ProcessRecord app = mLruProcesses.get(i); 10482 if (!allUsers && app.userId != userId) { 10483 continue; 10484 } 10485 if ((app.thread != null) && (!app.crashing && !app.notResponding)) { 10486 // Generate process state info for running application 10487 ActivityManager.RunningAppProcessInfo currApp = 10488 new ActivityManager.RunningAppProcessInfo(app.processName, 10489 app.pid, app.getPackageList()); 10490 fillInProcMemInfo(app, currApp); 10491 if (app.adjSource instanceof ProcessRecord) { 10492 currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid; 10493 currApp.importanceReasonImportance = oomAdjToImportance( 10494 app.adjSourceOom, null); 10495 } else if (app.adjSource instanceof ActivityRecord) { 10496 ActivityRecord r = (ActivityRecord)app.adjSource; 10497 if (r.app != null) currApp.importanceReasonPid = r.app.pid; 10498 } 10499 if (app.adjTarget instanceof ComponentName) { 10500 currApp.importanceReasonComponent = (ComponentName)app.adjTarget; 10501 } 10502 //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance 10503 // + " lru=" + currApp.lru); 10504 if (runList == null) { 10505 runList = new ArrayList<ActivityManager.RunningAppProcessInfo>(); 10506 } 10507 runList.add(currApp); 10508 } 10509 } 10510 } 10511 return runList; 10512 } 10513 10514 public List<ApplicationInfo> getRunningExternalApplications() { 10515 enforceNotIsolatedCaller("getRunningExternalApplications"); 10516 List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses(); 10517 List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>(); 10518 if (runningApps != null && runningApps.size() > 0) { 10519 Set<String> extList = new HashSet<String>(); 10520 for (ActivityManager.RunningAppProcessInfo app : runningApps) { 10521 if (app.pkgList != null) { 10522 for (String pkg : app.pkgList) { 10523 extList.add(pkg); 10524 } 10525 } 10526 } 10527 IPackageManager pm = AppGlobals.getPackageManager(); 10528 for (String pkg : extList) { 10529 try { 10530 ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId()); 10531 if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) { 10532 retList.add(info); 10533 } 10534 } catch (RemoteException e) { 10535 } 10536 } 10537 } 10538 return retList; 10539 } 10540 10541 @Override 10542 public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) { 10543 enforceNotIsolatedCaller("getMyMemoryState"); 10544 synchronized (this) { 10545 ProcessRecord proc; 10546 synchronized (mPidsSelfLocked) { 10547 proc = mPidsSelfLocked.get(Binder.getCallingPid()); 10548 } 10549 fillInProcMemInfo(proc, outInfo); 10550 } 10551 } 10552 10553 @Override 10554 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 10555 if (checkCallingPermission(android.Manifest.permission.DUMP) 10556 != PackageManager.PERMISSION_GRANTED) { 10557 pw.println("Permission Denial: can't dump ActivityManager from from pid=" 10558 + Binder.getCallingPid() 10559 + ", uid=" + Binder.getCallingUid() 10560 + " without permission " 10561 + android.Manifest.permission.DUMP); 10562 return; 10563 } 10564 10565 boolean dumpAll = false; 10566 boolean dumpClient = false; 10567 String dumpPackage = null; 10568 10569 int opti = 0; 10570 while (opti < args.length) { 10571 String opt = args[opti]; 10572 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 10573 break; 10574 } 10575 opti++; 10576 if ("-a".equals(opt)) { 10577 dumpAll = true; 10578 } else if ("-c".equals(opt)) { 10579 dumpClient = true; 10580 } else if ("-h".equals(opt)) { 10581 pw.println("Activity manager dump options:"); 10582 pw.println(" [-a] [-c] [-h] [cmd] ..."); 10583 pw.println(" cmd may be one of:"); 10584 pw.println(" a[ctivities]: activity stack state"); 10585 pw.println(" b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state"); 10586 pw.println(" i[ntents] [PACKAGE_NAME]: pending intent state"); 10587 pw.println(" p[rocesses] [PACKAGE_NAME]: process state"); 10588 pw.println(" o[om]: out of memory management"); 10589 pw.println(" prov[iders] [COMP_SPEC ...]: content provider state"); 10590 pw.println(" provider [COMP_SPEC]: provider client-side state"); 10591 pw.println(" s[ervices] [COMP_SPEC ...]: service state"); 10592 pw.println(" service [COMP_SPEC]: service client-side state"); 10593 pw.println(" package [PACKAGE_NAME]: all state related to given package"); 10594 pw.println(" all: dump all activities"); 10595 pw.println(" top: dump the top activity"); 10596 pw.println(" cmd may also be a COMP_SPEC to dump activities."); 10597 pw.println(" COMP_SPEC may be a component name (com.foo/.myApp),"); 10598 pw.println(" a partial substring in a component name, a"); 10599 pw.println(" hex object identifier."); 10600 pw.println(" -a: include all available server state."); 10601 pw.println(" -c: include client state."); 10602 return; 10603 } else { 10604 pw.println("Unknown argument: " + opt + "; use -h for help"); 10605 } 10606 } 10607 10608 long origId = Binder.clearCallingIdentity(); 10609 boolean more = false; 10610 // Is the caller requesting to dump a particular piece of data? 10611 if (opti < args.length) { 10612 String cmd = args[opti]; 10613 opti++; 10614 if ("activities".equals(cmd) || "a".equals(cmd)) { 10615 synchronized (this) { 10616 dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null); 10617 } 10618 } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) { 10619 String[] newArgs; 10620 String name; 10621 if (opti >= args.length) { 10622 name = null; 10623 newArgs = EMPTY_STRING_ARRAY; 10624 } else { 10625 name = args[opti]; 10626 opti++; 10627 newArgs = new String[args.length - opti]; 10628 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 10629 args.length - opti); 10630 } 10631 synchronized (this) { 10632 dumpBroadcastsLocked(fd, pw, args, opti, true, name); 10633 } 10634 } else if ("intents".equals(cmd) || "i".equals(cmd)) { 10635 String[] newArgs; 10636 String name; 10637 if (opti >= args.length) { 10638 name = null; 10639 newArgs = EMPTY_STRING_ARRAY; 10640 } else { 10641 name = args[opti]; 10642 opti++; 10643 newArgs = new String[args.length - opti]; 10644 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 10645 args.length - opti); 10646 } 10647 synchronized (this) { 10648 dumpPendingIntentsLocked(fd, pw, args, opti, true, name); 10649 } 10650 } else if ("processes".equals(cmd) || "p".equals(cmd)) { 10651 String[] newArgs; 10652 String name; 10653 if (opti >= args.length) { 10654 name = null; 10655 newArgs = EMPTY_STRING_ARRAY; 10656 } else { 10657 name = args[opti]; 10658 opti++; 10659 newArgs = new String[args.length - opti]; 10660 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 10661 args.length - opti); 10662 } 10663 synchronized (this) { 10664 dumpProcessesLocked(fd, pw, args, opti, true, name); 10665 } 10666 } else if ("oom".equals(cmd) || "o".equals(cmd)) { 10667 synchronized (this) { 10668 dumpOomLocked(fd, pw, args, opti, true); 10669 } 10670 } else if ("provider".equals(cmd)) { 10671 String[] newArgs; 10672 String name; 10673 if (opti >= args.length) { 10674 name = null; 10675 newArgs = EMPTY_STRING_ARRAY; 10676 } else { 10677 name = args[opti]; 10678 opti++; 10679 newArgs = new String[args.length - opti]; 10680 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti); 10681 } 10682 if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) { 10683 pw.println("No providers match: " + name); 10684 pw.println("Use -h for help."); 10685 } 10686 } else if ("providers".equals(cmd) || "prov".equals(cmd)) { 10687 synchronized (this) { 10688 dumpProvidersLocked(fd, pw, args, opti, true, null); 10689 } 10690 } else if ("service".equals(cmd)) { 10691 String[] newArgs; 10692 String name; 10693 if (opti >= args.length) { 10694 name = null; 10695 newArgs = EMPTY_STRING_ARRAY; 10696 } else { 10697 name = args[opti]; 10698 opti++; 10699 newArgs = new String[args.length - opti]; 10700 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 10701 args.length - opti); 10702 } 10703 if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) { 10704 pw.println("No services match: " + name); 10705 pw.println("Use -h for help."); 10706 } 10707 } else if ("package".equals(cmd)) { 10708 String[] newArgs; 10709 if (opti >= args.length) { 10710 pw.println("package: no package name specified"); 10711 pw.println("Use -h for help."); 10712 } else { 10713 dumpPackage = args[opti]; 10714 opti++; 10715 newArgs = new String[args.length - opti]; 10716 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 10717 args.length - opti); 10718 args = newArgs; 10719 opti = 0; 10720 more = true; 10721 } 10722 } else if ("services".equals(cmd) || "s".equals(cmd)) { 10723 synchronized (this) { 10724 mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null); 10725 } 10726 } else { 10727 // Dumping a single activity? 10728 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) { 10729 pw.println("Bad activity command, or no activities match: " + cmd); 10730 pw.println("Use -h for help."); 10731 } 10732 } 10733 if (!more) { 10734 Binder.restoreCallingIdentity(origId); 10735 return; 10736 } 10737 } 10738 10739 // No piece of data specified, dump everything. 10740 synchronized (this) { 10741 dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 10742 pw.println(); 10743 if (dumpAll) { 10744 pw.println("-------------------------------------------------------------------------------"); 10745 } 10746 dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 10747 pw.println(); 10748 if (dumpAll) { 10749 pw.println("-------------------------------------------------------------------------------"); 10750 } 10751 dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage); 10752 pw.println(); 10753 if (dumpAll) { 10754 pw.println("-------------------------------------------------------------------------------"); 10755 } 10756 mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 10757 pw.println(); 10758 if (dumpAll) { 10759 pw.println("-------------------------------------------------------------------------------"); 10760 } 10761 dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 10762 pw.println(); 10763 if (dumpAll) { 10764 pw.println("-------------------------------------------------------------------------------"); 10765 } 10766 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage); 10767 } 10768 Binder.restoreCallingIdentity(origId); 10769 } 10770 10771 void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 10772 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) { 10773 pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)"); 10774 10775 boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient, 10776 dumpPackage); 10777 boolean needSep = printedAnything; 10778 10779 boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity, 10780 dumpPackage, needSep, " mFocusedActivity: "); 10781 if (printed) { 10782 printedAnything = true; 10783 needSep = false; 10784 } 10785 10786 if (dumpPackage == null) { 10787 if (needSep) { 10788 pw.println(); 10789 } 10790 needSep = true; 10791 printedAnything = true; 10792 mStackSupervisor.dump(pw, " "); 10793 } 10794 10795 if (mRecentTasks.size() > 0) { 10796 boolean printedHeader = false; 10797 10798 final int N = mRecentTasks.size(); 10799 for (int i=0; i<N; i++) { 10800 TaskRecord tr = mRecentTasks.get(i); 10801 if (dumpPackage != null) { 10802 if (tr.realActivity == null || 10803 !dumpPackage.equals(tr.realActivity)) { 10804 continue; 10805 } 10806 } 10807 if (!printedHeader) { 10808 if (needSep) { 10809 pw.println(); 10810 } 10811 pw.println(" Recent tasks:"); 10812 printedHeader = true; 10813 printedAnything = true; 10814 } 10815 pw.print(" * Recent #"); pw.print(i); pw.print(": "); 10816 pw.println(tr); 10817 if (dumpAll) { 10818 mRecentTasks.get(i).dump(pw, " "); 10819 } 10820 } 10821 } 10822 10823 if (!printedAnything) { 10824 pw.println(" (nothing)"); 10825 } 10826 } 10827 10828 void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 10829 int opti, boolean dumpAll, String dumpPackage) { 10830 boolean needSep = false; 10831 boolean printedAnything = false; 10832 int numPers = 0; 10833 10834 pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)"); 10835 10836 if (dumpAll) { 10837 final int NP = mProcessNames.getMap().size(); 10838 for (int ip=0; ip<NP; ip++) { 10839 SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip); 10840 final int NA = procs.size(); 10841 for (int ia=0; ia<NA; ia++) { 10842 ProcessRecord r = procs.valueAt(ia); 10843 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 10844 continue; 10845 } 10846 if (!needSep) { 10847 pw.println(" All known processes:"); 10848 needSep = true; 10849 printedAnything = true; 10850 } 10851 pw.print(r.persistent ? " *PERS*" : " *APP*"); 10852 pw.print(" UID "); pw.print(procs.keyAt(ia)); 10853 pw.print(" "); pw.println(r); 10854 r.dump(pw, " "); 10855 if (r.persistent) { 10856 numPers++; 10857 } 10858 } 10859 } 10860 } 10861 10862 if (mIsolatedProcesses.size() > 0) { 10863 boolean printed = false; 10864 for (int i=0; i<mIsolatedProcesses.size(); i++) { 10865 ProcessRecord r = mIsolatedProcesses.valueAt(i); 10866 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 10867 continue; 10868 } 10869 if (!printed) { 10870 if (needSep) { 10871 pw.println(); 10872 } 10873 pw.println(" Isolated process list (sorted by uid):"); 10874 printedAnything = true; 10875 printed = true; 10876 needSep = true; 10877 } 10878 pw.println(String.format("%sIsolated #%2d: %s", 10879 " ", i, r.toString())); 10880 } 10881 } 10882 10883 if (mLruProcesses.size() > 0) { 10884 if (needSep) { 10885 pw.println(); 10886 } 10887 pw.print(" Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size()); 10888 pw.print(" total, non-act at "); 10889 pw.print(mLruProcesses.size()-mLruProcessActivityStart); 10890 pw.print(", non-svc at "); 10891 pw.print(mLruProcesses.size()-mLruProcessServiceStart); 10892 pw.println("):"); 10893 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", false, dumpPackage); 10894 needSep = true; 10895 printedAnything = true; 10896 } 10897 10898 if (dumpAll || dumpPackage != null) { 10899 synchronized (mPidsSelfLocked) { 10900 boolean printed = false; 10901 for (int i=0; i<mPidsSelfLocked.size(); i++) { 10902 ProcessRecord r = mPidsSelfLocked.valueAt(i); 10903 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 10904 continue; 10905 } 10906 if (!printed) { 10907 if (needSep) pw.println(); 10908 needSep = true; 10909 pw.println(" PID mappings:"); 10910 printed = true; 10911 printedAnything = true; 10912 } 10913 pw.print(" PID #"); pw.print(mPidsSelfLocked.keyAt(i)); 10914 pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i)); 10915 } 10916 } 10917 } 10918 10919 if (mForegroundProcesses.size() > 0) { 10920 synchronized (mPidsSelfLocked) { 10921 boolean printed = false; 10922 for (int i=0; i<mForegroundProcesses.size(); i++) { 10923 ProcessRecord r = mPidsSelfLocked.get( 10924 mForegroundProcesses.valueAt(i).pid); 10925 if (dumpPackage != null && (r == null 10926 || !r.pkgList.containsKey(dumpPackage))) { 10927 continue; 10928 } 10929 if (!printed) { 10930 if (needSep) pw.println(); 10931 needSep = true; 10932 pw.println(" Foreground Processes:"); 10933 printed = true; 10934 printedAnything = true; 10935 } 10936 pw.print(" PID #"); pw.print(mForegroundProcesses.keyAt(i)); 10937 pw.print(": "); pw.println(mForegroundProcesses.valueAt(i)); 10938 } 10939 } 10940 } 10941 10942 if (mPersistentStartingProcesses.size() > 0) { 10943 if (needSep) pw.println(); 10944 needSep = true; 10945 printedAnything = true; 10946 pw.println(" Persisent processes that are starting:"); 10947 dumpProcessList(pw, this, mPersistentStartingProcesses, " ", 10948 "Starting Norm", "Restarting PERS", dumpPackage); 10949 } 10950 10951 if (mRemovedProcesses.size() > 0) { 10952 if (needSep) pw.println(); 10953 needSep = true; 10954 printedAnything = true; 10955 pw.println(" Processes that are being removed:"); 10956 dumpProcessList(pw, this, mRemovedProcesses, " ", 10957 "Removed Norm", "Removed PERS", dumpPackage); 10958 } 10959 10960 if (mProcessesOnHold.size() > 0) { 10961 if (needSep) pw.println(); 10962 needSep = true; 10963 printedAnything = true; 10964 pw.println(" Processes that are on old until the system is ready:"); 10965 dumpProcessList(pw, this, mProcessesOnHold, " ", 10966 "OnHold Norm", "OnHold PERS", dumpPackage); 10967 } 10968 10969 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage); 10970 10971 if (mProcessCrashTimes.getMap().size() > 0) { 10972 boolean printed = false; 10973 long now = SystemClock.uptimeMillis(); 10974 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap(); 10975 final int NP = pmap.size(); 10976 for (int ip=0; ip<NP; ip++) { 10977 String pname = pmap.keyAt(ip); 10978 SparseArray<Long> uids = pmap.valueAt(ip); 10979 final int N = uids.size(); 10980 for (int i=0; i<N; i++) { 10981 int puid = uids.keyAt(i); 10982 ProcessRecord r = mProcessNames.get(pname, puid); 10983 if (dumpPackage != null && (r == null 10984 || !r.pkgList.containsKey(dumpPackage))) { 10985 continue; 10986 } 10987 if (!printed) { 10988 if (needSep) pw.println(); 10989 needSep = true; 10990 pw.println(" Time since processes crashed:"); 10991 printed = true; 10992 printedAnything = true; 10993 } 10994 pw.print(" Process "); pw.print(pname); 10995 pw.print(" uid "); pw.print(puid); 10996 pw.print(": last crashed "); 10997 TimeUtils.formatDuration(now-uids.valueAt(i), pw); 10998 pw.println(" ago"); 10999 } 11000 } 11001 } 11002 11003 if (mBadProcesses.getMap().size() > 0) { 11004 boolean printed = false; 11005 final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap(); 11006 final int NP = pmap.size(); 11007 for (int ip=0; ip<NP; ip++) { 11008 String pname = pmap.keyAt(ip); 11009 SparseArray<BadProcessInfo> uids = pmap.valueAt(ip); 11010 final int N = uids.size(); 11011 for (int i=0; i<N; i++) { 11012 int puid = uids.keyAt(i); 11013 ProcessRecord r = mProcessNames.get(pname, puid); 11014 if (dumpPackage != null && (r == null 11015 || !r.pkgList.containsKey(dumpPackage))) { 11016 continue; 11017 } 11018 if (!printed) { 11019 if (needSep) pw.println(); 11020 needSep = true; 11021 pw.println(" Bad processes:"); 11022 printedAnything = true; 11023 } 11024 BadProcessInfo info = uids.valueAt(i); 11025 pw.print(" Bad process "); pw.print(pname); 11026 pw.print(" uid "); pw.print(puid); 11027 pw.print(": crashed at time "); pw.println(info.time); 11028 if (info.shortMsg != null) { 11029 pw.print(" Short msg: "); pw.println(info.shortMsg); 11030 } 11031 if (info.longMsg != null) { 11032 pw.print(" Long msg: "); pw.println(info.longMsg); 11033 } 11034 if (info.stack != null) { 11035 pw.println(" Stack:"); 11036 int lastPos = 0; 11037 for (int pos=0; pos<info.stack.length(); pos++) { 11038 if (info.stack.charAt(pos) == '\n') { 11039 pw.print(" "); 11040 pw.write(info.stack, lastPos, pos-lastPos); 11041 pw.println(); 11042 lastPos = pos+1; 11043 } 11044 } 11045 if (lastPos < info.stack.length()) { 11046 pw.print(" "); 11047 pw.write(info.stack, lastPos, info.stack.length()-lastPos); 11048 pw.println(); 11049 } 11050 } 11051 } 11052 } 11053 } 11054 11055 if (dumpPackage == null) { 11056 pw.println(); 11057 needSep = false; 11058 pw.println(" mStartedUsers:"); 11059 for (int i=0; i<mStartedUsers.size(); i++) { 11060 UserStartedState uss = mStartedUsers.valueAt(i); 11061 pw.print(" User #"); pw.print(uss.mHandle.getIdentifier()); 11062 pw.print(": "); uss.dump("", pw); 11063 } 11064 pw.print(" mStartedUserArray: ["); 11065 for (int i=0; i<mStartedUserArray.length; i++) { 11066 if (i > 0) pw.print(", "); 11067 pw.print(mStartedUserArray[i]); 11068 } 11069 pw.println("]"); 11070 pw.print(" mUserLru: ["); 11071 for (int i=0; i<mUserLru.size(); i++) { 11072 if (i > 0) pw.print(", "); 11073 pw.print(mUserLru.get(i)); 11074 } 11075 pw.println("]"); 11076 if (dumpAll) { 11077 pw.print(" mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray)); 11078 } 11079 } 11080 if (mHomeProcess != null && (dumpPackage == null 11081 || mHomeProcess.pkgList.containsKey(dumpPackage))) { 11082 if (needSep) { 11083 pw.println(); 11084 needSep = false; 11085 } 11086 pw.println(" mHomeProcess: " + mHomeProcess); 11087 } 11088 if (mPreviousProcess != null && (dumpPackage == null 11089 || mPreviousProcess.pkgList.containsKey(dumpPackage))) { 11090 if (needSep) { 11091 pw.println(); 11092 needSep = false; 11093 } 11094 pw.println(" mPreviousProcess: " + mPreviousProcess); 11095 } 11096 if (dumpAll) { 11097 StringBuilder sb = new StringBuilder(128); 11098 sb.append(" mPreviousProcessVisibleTime: "); 11099 TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb); 11100 pw.println(sb); 11101 } 11102 if (mHeavyWeightProcess != null && (dumpPackage == null 11103 || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) { 11104 if (needSep) { 11105 pw.println(); 11106 needSep = false; 11107 } 11108 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 11109 } 11110 if (dumpPackage == null) { 11111 pw.println(" mConfiguration: " + mConfiguration); 11112 } 11113 if (dumpAll) { 11114 pw.println(" mConfigWillChange: " + getFocusedStack().mConfigWillChange); 11115 if (mCompatModePackages.getPackages().size() > 0) { 11116 boolean printed = false; 11117 for (Map.Entry<String, Integer> entry 11118 : mCompatModePackages.getPackages().entrySet()) { 11119 String pkg = entry.getKey(); 11120 int mode = entry.getValue(); 11121 if (dumpPackage != null && !dumpPackage.equals(pkg)) { 11122 continue; 11123 } 11124 if (!printed) { 11125 pw.println(" mScreenCompatPackages:"); 11126 printed = true; 11127 } 11128 pw.print(" "); pw.print(pkg); pw.print(": "); 11129 pw.print(mode); pw.println(); 11130 } 11131 } 11132 } 11133 if (dumpPackage == null) { 11134 if (mSleeping || mWentToSleep || mLockScreenShown) { 11135 pw.println(" mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep 11136 + " mLockScreenShown " + mLockScreenShown); 11137 } 11138 if (mShuttingDown) { 11139 pw.println(" mShuttingDown=" + mShuttingDown); 11140 } 11141 } 11142 if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient 11143 || mOrigWaitForDebugger) { 11144 if (dumpPackage == null || dumpPackage.equals(mDebugApp) 11145 || dumpPackage.equals(mOrigDebugApp)) { 11146 if (needSep) { 11147 pw.println(); 11148 needSep = false; 11149 } 11150 pw.println(" mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp 11151 + " mDebugTransient=" + mDebugTransient 11152 + " mOrigWaitForDebugger=" + mOrigWaitForDebugger); 11153 } 11154 } 11155 if (mOpenGlTraceApp != null) { 11156 if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) { 11157 if (needSep) { 11158 pw.println(); 11159 needSep = false; 11160 } 11161 pw.println(" mOpenGlTraceApp=" + mOpenGlTraceApp); 11162 } 11163 } 11164 if (mProfileApp != null || mProfileProc != null || mProfileFile != null 11165 || mProfileFd != null) { 11166 if (dumpPackage == null || dumpPackage.equals(mProfileApp)) { 11167 if (needSep) { 11168 pw.println(); 11169 needSep = false; 11170 } 11171 pw.println(" mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc); 11172 pw.println(" mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd); 11173 pw.println(" mProfileType=" + mProfileType + " mAutoStopProfiler=" 11174 + mAutoStopProfiler); 11175 } 11176 } 11177 if (dumpPackage == null) { 11178 if (mAlwaysFinishActivities || mController != null) { 11179 pw.println(" mAlwaysFinishActivities=" + mAlwaysFinishActivities 11180 + " mController=" + mController); 11181 } 11182 if (dumpAll) { 11183 pw.println(" Total persistent processes: " + numPers); 11184 pw.println(" mProcessesReady=" + mProcessesReady 11185 + " mSystemReady=" + mSystemReady); 11186 pw.println(" mBooting=" + mBooting 11187 + " mBooted=" + mBooted 11188 + " mFactoryTest=" + mFactoryTest); 11189 pw.print(" mLastPowerCheckRealtime="); 11190 TimeUtils.formatDuration(mLastPowerCheckRealtime, pw); 11191 pw.println(""); 11192 pw.print(" mLastPowerCheckUptime="); 11193 TimeUtils.formatDuration(mLastPowerCheckUptime, pw); 11194 pw.println(""); 11195 pw.println(" mGoingToSleep=" + mStackSupervisor.mGoingToSleep); 11196 pw.println(" mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity); 11197 pw.println(" mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq); 11198 pw.println(" mNumNonCachedProcs=" + mNumNonCachedProcs 11199 + " (" + mLruProcesses.size() + " total)" 11200 + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs 11201 + " mNumServiceProcs=" + mNumServiceProcs 11202 + " mNewNumServiceProcs=" + mNewNumServiceProcs); 11203 pw.println(" mAllowLowerMemLevel=" + mAllowLowerMemLevel 11204 + " mLastMemoryLevel" + mLastMemoryLevel 11205 + " mLastNumProcesses" + mLastNumProcesses); 11206 long now = SystemClock.uptimeMillis(); 11207 pw.print(" mLastIdleTime="); 11208 TimeUtils.formatDuration(now, mLastIdleTime, pw); 11209 pw.print(" mLowRamSinceLastIdle="); 11210 TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw); 11211 pw.println(); 11212 } 11213 } 11214 11215 if (!printedAnything) { 11216 pw.println(" (nothing)"); 11217 } 11218 } 11219 11220 boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args, 11221 int opti, boolean needSep, boolean dumpAll, String dumpPackage) { 11222 if (mProcessesToGc.size() > 0) { 11223 boolean printed = false; 11224 long now = SystemClock.uptimeMillis(); 11225 for (int i=0; i<mProcessesToGc.size(); i++) { 11226 ProcessRecord proc = mProcessesToGc.get(i); 11227 if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) { 11228 continue; 11229 } 11230 if (!printed) { 11231 if (needSep) pw.println(); 11232 needSep = true; 11233 pw.println(" Processes that are waiting to GC:"); 11234 printed = true; 11235 } 11236 pw.print(" Process "); pw.println(proc); 11237 pw.print(" lowMem="); pw.print(proc.reportLowMemory); 11238 pw.print(", last gced="); 11239 pw.print(now-proc.lastRequestedGc); 11240 pw.print(" ms ago, last lowMem="); 11241 pw.print(now-proc.lastLowMemory); 11242 pw.println(" ms ago"); 11243 11244 } 11245 } 11246 return needSep; 11247 } 11248 11249 void printOomLevel(PrintWriter pw, String name, int adj) { 11250 pw.print(" "); 11251 if (adj >= 0) { 11252 pw.print(' '); 11253 if (adj < 10) pw.print(' '); 11254 } else { 11255 if (adj > -10) pw.print(' '); 11256 } 11257 pw.print(adj); 11258 pw.print(": "); 11259 pw.print(name); 11260 pw.print(" ("); 11261 pw.print(mProcessList.getMemLevel(adj)/1024); 11262 pw.println(" kB)"); 11263 } 11264 11265 boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args, 11266 int opti, boolean dumpAll) { 11267 boolean needSep = false; 11268 11269 if (mLruProcesses.size() > 0) { 11270 if (needSep) pw.println(); 11271 needSep = true; 11272 pw.println(" OOM levels:"); 11273 printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ); 11274 printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ); 11275 printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ); 11276 printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ); 11277 printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ); 11278 printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ); 11279 printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ); 11280 printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ); 11281 printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ); 11282 printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ); 11283 printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ); 11284 printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ); 11285 printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ); 11286 11287 if (needSep) pw.println(); 11288 pw.print(" Process OOM control ("); pw.print(mLruProcesses.size()); 11289 pw.print(" total, non-act at "); 11290 pw.print(mLruProcesses.size()-mLruProcessActivityStart); 11291 pw.print(", non-svc at "); 11292 pw.print(mLruProcesses.size()-mLruProcessServiceStart); 11293 pw.println("):"); 11294 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", true, null); 11295 needSep = true; 11296 } 11297 11298 dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null); 11299 11300 pw.println(); 11301 pw.println(" mHomeProcess: " + mHomeProcess); 11302 pw.println(" mPreviousProcess: " + mPreviousProcess); 11303 if (mHeavyWeightProcess != null) { 11304 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 11305 } 11306 11307 return true; 11308 } 11309 11310 /** 11311 * There are three ways to call this: 11312 * - no provider specified: dump all the providers 11313 * - a flattened component name that matched an existing provider was specified as the 11314 * first arg: dump that one provider 11315 * - the first arg isn't the flattened component name of an existing provider: 11316 * dump all providers whose component contains the first arg as a substring 11317 */ 11318 protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args, 11319 int opti, boolean dumpAll) { 11320 return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll); 11321 } 11322 11323 static class ItemMatcher { 11324 ArrayList<ComponentName> components; 11325 ArrayList<String> strings; 11326 ArrayList<Integer> objects; 11327 boolean all; 11328 11329 ItemMatcher() { 11330 all = true; 11331 } 11332 11333 void build(String name) { 11334 ComponentName componentName = ComponentName.unflattenFromString(name); 11335 if (componentName != null) { 11336 if (components == null) { 11337 components = new ArrayList<ComponentName>(); 11338 } 11339 components.add(componentName); 11340 all = false; 11341 } else { 11342 int objectId = 0; 11343 // Not a '/' separated full component name; maybe an object ID? 11344 try { 11345 objectId = Integer.parseInt(name, 16); 11346 if (objects == null) { 11347 objects = new ArrayList<Integer>(); 11348 } 11349 objects.add(objectId); 11350 all = false; 11351 } catch (RuntimeException e) { 11352 // Not an integer; just do string match. 11353 if (strings == null) { 11354 strings = new ArrayList<String>(); 11355 } 11356 strings.add(name); 11357 all = false; 11358 } 11359 } 11360 } 11361 11362 int build(String[] args, int opti) { 11363 for (; opti<args.length; opti++) { 11364 String name = args[opti]; 11365 if ("--".equals(name)) { 11366 return opti+1; 11367 } 11368 build(name); 11369 } 11370 return opti; 11371 } 11372 11373 boolean match(Object object, ComponentName comp) { 11374 if (all) { 11375 return true; 11376 } 11377 if (components != null) { 11378 for (int i=0; i<components.size(); i++) { 11379 if (components.get(i).equals(comp)) { 11380 return true; 11381 } 11382 } 11383 } 11384 if (objects != null) { 11385 for (int i=0; i<objects.size(); i++) { 11386 if (System.identityHashCode(object) == objects.get(i)) { 11387 return true; 11388 } 11389 } 11390 } 11391 if (strings != null) { 11392 String flat = comp.flattenToString(); 11393 for (int i=0; i<strings.size(); i++) { 11394 if (flat.contains(strings.get(i))) { 11395 return true; 11396 } 11397 } 11398 } 11399 return false; 11400 } 11401 } 11402 11403 /** 11404 * There are three things that cmd can be: 11405 * - a flattened component name that matches an existing activity 11406 * - the cmd arg isn't the flattened component name of an existing activity: 11407 * dump all activity whose component contains the cmd as a substring 11408 * - A hex number of the ActivityRecord object instance. 11409 */ 11410 protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args, 11411 int opti, boolean dumpAll) { 11412 ArrayList<ActivityRecord> activities; 11413 11414 synchronized (this) { 11415 activities = mStackSupervisor.getDumpActivitiesLocked(name); 11416 } 11417 11418 if (activities.size() <= 0) { 11419 return false; 11420 } 11421 11422 String[] newArgs = new String[args.length - opti]; 11423 System.arraycopy(args, opti, newArgs, 0, args.length - opti); 11424 11425 TaskRecord lastTask = null; 11426 boolean needSep = false; 11427 for (int i=activities.size()-1; i>=0; i--) { 11428 ActivityRecord r = activities.get(i); 11429 if (needSep) { 11430 pw.println(); 11431 } 11432 needSep = true; 11433 synchronized (this) { 11434 if (lastTask != r.task) { 11435 lastTask = r.task; 11436 pw.print("TASK "); pw.print(lastTask.affinity); 11437 pw.print(" id="); pw.println(lastTask.taskId); 11438 if (dumpAll) { 11439 lastTask.dump(pw, " "); 11440 } 11441 } 11442 } 11443 dumpActivity(" ", fd, pw, activities.get(i), newArgs, dumpAll); 11444 } 11445 return true; 11446 } 11447 11448 /** 11449 * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if 11450 * there is a thread associated with the activity. 11451 */ 11452 private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw, 11453 final ActivityRecord r, String[] args, boolean dumpAll) { 11454 String innerPrefix = prefix + " "; 11455 synchronized (this) { 11456 pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName); 11457 pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r))); 11458 pw.print(" pid="); 11459 if (r.app != null) pw.println(r.app.pid); 11460 else pw.println("(not running)"); 11461 if (dumpAll) { 11462 r.dump(pw, innerPrefix); 11463 } 11464 } 11465 if (r.app != null && r.app.thread != null) { 11466 // flush anything that is already in the PrintWriter since the thread is going 11467 // to write to the file descriptor directly 11468 pw.flush(); 11469 try { 11470 TransferPipe tp = new TransferPipe(); 11471 try { 11472 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(), 11473 r.appToken, innerPrefix, args); 11474 tp.go(fd); 11475 } finally { 11476 tp.kill(); 11477 } 11478 } catch (IOException e) { 11479 pw.println(innerPrefix + "Failure while dumping the activity: " + e); 11480 } catch (RemoteException e) { 11481 pw.println(innerPrefix + "Got a RemoteException while dumping the activity"); 11482 } 11483 } 11484 } 11485 11486 void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 11487 int opti, boolean dumpAll, String dumpPackage) { 11488 boolean needSep = false; 11489 boolean onlyHistory = false; 11490 boolean printedAnything = false; 11491 11492 if ("history".equals(dumpPackage)) { 11493 if (opti < args.length && "-s".equals(args[opti])) { 11494 dumpAll = false; 11495 } 11496 onlyHistory = true; 11497 dumpPackage = null; 11498 } 11499 11500 pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)"); 11501 if (!onlyHistory && dumpAll) { 11502 if (mRegisteredReceivers.size() > 0) { 11503 boolean printed = false; 11504 Iterator it = mRegisteredReceivers.values().iterator(); 11505 while (it.hasNext()) { 11506 ReceiverList r = (ReceiverList)it.next(); 11507 if (dumpPackage != null && (r.app == null || 11508 !dumpPackage.equals(r.app.info.packageName))) { 11509 continue; 11510 } 11511 if (!printed) { 11512 pw.println(" Registered Receivers:"); 11513 needSep = true; 11514 printed = true; 11515 printedAnything = true; 11516 } 11517 pw.print(" * "); pw.println(r); 11518 r.dump(pw, " "); 11519 } 11520 } 11521 11522 if (mReceiverResolver.dump(pw, needSep ? 11523 "\n Receiver Resolver Table:" : " Receiver Resolver Table:", 11524 " ", dumpPackage, false)) { 11525 needSep = true; 11526 printedAnything = true; 11527 } 11528 } 11529 11530 for (BroadcastQueue q : mBroadcastQueues) { 11531 needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep); 11532 printedAnything |= needSep; 11533 } 11534 11535 needSep = true; 11536 11537 if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) { 11538 for (int user=0; user<mStickyBroadcasts.size(); user++) { 11539 if (needSep) { 11540 pw.println(); 11541 } 11542 needSep = true; 11543 printedAnything = true; 11544 pw.print(" Sticky broadcasts for user "); 11545 pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":"); 11546 StringBuilder sb = new StringBuilder(128); 11547 for (Map.Entry<String, ArrayList<Intent>> ent 11548 : mStickyBroadcasts.valueAt(user).entrySet()) { 11549 pw.print(" * Sticky action "); pw.print(ent.getKey()); 11550 if (dumpAll) { 11551 pw.println(":"); 11552 ArrayList<Intent> intents = ent.getValue(); 11553 final int N = intents.size(); 11554 for (int i=0; i<N; i++) { 11555 sb.setLength(0); 11556 sb.append(" Intent: "); 11557 intents.get(i).toShortString(sb, false, true, false, false); 11558 pw.println(sb.toString()); 11559 Bundle bundle = intents.get(i).getExtras(); 11560 if (bundle != null) { 11561 pw.print(" "); 11562 pw.println(bundle.toString()); 11563 } 11564 } 11565 } else { 11566 pw.println(""); 11567 } 11568 } 11569 } 11570 } 11571 11572 if (!onlyHistory && dumpAll) { 11573 pw.println(); 11574 for (BroadcastQueue queue : mBroadcastQueues) { 11575 pw.println(" mBroadcastsScheduled [" + queue.mQueueName + "]=" 11576 + queue.mBroadcastsScheduled); 11577 } 11578 pw.println(" mHandler:"); 11579 mHandler.dump(new PrintWriterPrinter(pw), " "); 11580 needSep = true; 11581 printedAnything = true; 11582 } 11583 11584 if (!printedAnything) { 11585 pw.println(" (nothing)"); 11586 } 11587 } 11588 11589 void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args, 11590 int opti, boolean dumpAll, String dumpPackage) { 11591 boolean needSep; 11592 boolean printedAnything = false; 11593 11594 ItemMatcher matcher = new ItemMatcher(); 11595 matcher.build(args, opti); 11596 11597 pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)"); 11598 11599 needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage); 11600 printedAnything |= needSep; 11601 11602 if (mLaunchingProviders.size() > 0) { 11603 boolean printed = false; 11604 for (int i=mLaunchingProviders.size()-1; i>=0; i--) { 11605 ContentProviderRecord r = mLaunchingProviders.get(i); 11606 if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) { 11607 continue; 11608 } 11609 if (!printed) { 11610 if (needSep) pw.println(); 11611 needSep = true; 11612 pw.println(" Launching content providers:"); 11613 printed = true; 11614 printedAnything = true; 11615 } 11616 pw.print(" Launching #"); pw.print(i); pw.print(": "); 11617 pw.println(r); 11618 } 11619 } 11620 11621 if (mGrantedUriPermissions.size() > 0) { 11622 boolean printed = false; 11623 int dumpUid = -2; 11624 if (dumpPackage != null) { 11625 try { 11626 dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0); 11627 } catch (NameNotFoundException e) { 11628 dumpUid = -1; 11629 } 11630 } 11631 for (int i=0; i<mGrantedUriPermissions.size(); i++) { 11632 int uid = mGrantedUriPermissions.keyAt(i); 11633 if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) { 11634 continue; 11635 } 11636 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 11637 if (!printed) { 11638 if (needSep) pw.println(); 11639 needSep = true; 11640 pw.println(" Granted Uri Permissions:"); 11641 printed = true; 11642 printedAnything = true; 11643 } 11644 pw.print(" * UID "); pw.print(uid); pw.println(" holds:"); 11645 for (UriPermission perm : perms.values()) { 11646 pw.print(" "); pw.println(perm); 11647 if (dumpAll) { 11648 perm.dump(pw, " "); 11649 } 11650 } 11651 } 11652 } 11653 11654 if (!printedAnything) { 11655 pw.println(" (nothing)"); 11656 } 11657 } 11658 11659 void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 11660 int opti, boolean dumpAll, String dumpPackage) { 11661 boolean printed = false; 11662 11663 pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)"); 11664 11665 if (mIntentSenderRecords.size() > 0) { 11666 Iterator<WeakReference<PendingIntentRecord>> it 11667 = mIntentSenderRecords.values().iterator(); 11668 while (it.hasNext()) { 11669 WeakReference<PendingIntentRecord> ref = it.next(); 11670 PendingIntentRecord rec = ref != null ? ref.get(): null; 11671 if (dumpPackage != null && (rec == null 11672 || !dumpPackage.equals(rec.key.packageName))) { 11673 continue; 11674 } 11675 printed = true; 11676 if (rec != null) { 11677 pw.print(" * "); pw.println(rec); 11678 if (dumpAll) { 11679 rec.dump(pw, " "); 11680 } 11681 } else { 11682 pw.print(" * "); pw.println(ref); 11683 } 11684 } 11685 } 11686 11687 if (!printed) { 11688 pw.println(" (nothing)"); 11689 } 11690 } 11691 11692 private static final int dumpProcessList(PrintWriter pw, 11693 ActivityManagerService service, List list, 11694 String prefix, String normalLabel, String persistentLabel, 11695 String dumpPackage) { 11696 int numPers = 0; 11697 final int N = list.size()-1; 11698 for (int i=N; i>=0; i--) { 11699 ProcessRecord r = (ProcessRecord)list.get(i); 11700 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 11701 continue; 11702 } 11703 pw.println(String.format("%s%s #%2d: %s", 11704 prefix, (r.persistent ? persistentLabel : normalLabel), 11705 i, r.toString())); 11706 if (r.persistent) { 11707 numPers++; 11708 } 11709 } 11710 return numPers; 11711 } 11712 11713 private static final boolean dumpProcessOomList(PrintWriter pw, 11714 ActivityManagerService service, List<ProcessRecord> origList, 11715 String prefix, String normalLabel, String persistentLabel, 11716 boolean inclDetails, String dumpPackage) { 11717 11718 ArrayList<Pair<ProcessRecord, Integer>> list 11719 = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size()); 11720 for (int i=0; i<origList.size(); i++) { 11721 ProcessRecord r = origList.get(i); 11722 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 11723 continue; 11724 } 11725 list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i)); 11726 } 11727 11728 if (list.size() <= 0) { 11729 return false; 11730 } 11731 11732 Comparator<Pair<ProcessRecord, Integer>> comparator 11733 = new Comparator<Pair<ProcessRecord, Integer>>() { 11734 @Override 11735 public int compare(Pair<ProcessRecord, Integer> object1, 11736 Pair<ProcessRecord, Integer> object2) { 11737 if (object1.first.setAdj != object2.first.setAdj) { 11738 return object1.first.setAdj > object2.first.setAdj ? -1 : 1; 11739 } 11740 if (object1.second.intValue() != object2.second.intValue()) { 11741 return object1.second.intValue() > object2.second.intValue() ? -1 : 1; 11742 } 11743 return 0; 11744 } 11745 }; 11746 11747 Collections.sort(list, comparator); 11748 11749 final long curRealtime = SystemClock.elapsedRealtime(); 11750 final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime; 11751 final long curUptime = SystemClock.uptimeMillis(); 11752 final long uptimeSince = curUptime - service.mLastPowerCheckUptime; 11753 11754 for (int i=list.size()-1; i>=0; i--) { 11755 ProcessRecord r = list.get(i).first; 11756 String oomAdj = ProcessList.makeOomAdjString(r.setAdj); 11757 char schedGroup; 11758 switch (r.setSchedGroup) { 11759 case Process.THREAD_GROUP_BG_NONINTERACTIVE: 11760 schedGroup = 'B'; 11761 break; 11762 case Process.THREAD_GROUP_DEFAULT: 11763 schedGroup = 'F'; 11764 break; 11765 default: 11766 schedGroup = '?'; 11767 break; 11768 } 11769 char foreground; 11770 if (r.foregroundActivities) { 11771 foreground = 'A'; 11772 } else if (r.foregroundServices) { 11773 foreground = 'S'; 11774 } else { 11775 foreground = ' '; 11776 } 11777 String procState = ProcessList.makeProcStateString(r.curProcState); 11778 pw.print(prefix); 11779 pw.print(r.persistent ? persistentLabel : normalLabel); 11780 pw.print(" #"); 11781 int num = (origList.size()-1)-list.get(i).second; 11782 if (num < 10) pw.print(' '); 11783 pw.print(num); 11784 pw.print(": "); 11785 pw.print(oomAdj); 11786 pw.print(' '); 11787 pw.print(schedGroup); 11788 pw.print('/'); 11789 pw.print(foreground); 11790 pw.print('/'); 11791 pw.print(procState); 11792 pw.print(" trm:"); 11793 if (r.trimMemoryLevel < 10) pw.print(' '); 11794 pw.print(r.trimMemoryLevel); 11795 pw.print(' '); 11796 pw.print(r.toShortString()); 11797 pw.print(" ("); 11798 pw.print(r.adjType); 11799 pw.println(')'); 11800 if (r.adjSource != null || r.adjTarget != null) { 11801 pw.print(prefix); 11802 pw.print(" "); 11803 if (r.adjTarget instanceof ComponentName) { 11804 pw.print(((ComponentName)r.adjTarget).flattenToShortString()); 11805 } else if (r.adjTarget != null) { 11806 pw.print(r.adjTarget.toString()); 11807 } else { 11808 pw.print("{null}"); 11809 } 11810 pw.print("<="); 11811 if (r.adjSource instanceof ProcessRecord) { 11812 pw.print("Proc{"); 11813 pw.print(((ProcessRecord)r.adjSource).toShortString()); 11814 pw.println("}"); 11815 } else if (r.adjSource != null) { 11816 pw.println(r.adjSource.toString()); 11817 } else { 11818 pw.println("{null}"); 11819 } 11820 } 11821 if (inclDetails) { 11822 pw.print(prefix); 11823 pw.print(" "); 11824 pw.print("oom: max="); pw.print(r.maxAdj); 11825 pw.print(" curRaw="); pw.print(r.curRawAdj); 11826 pw.print(" setRaw="); pw.print(r.setRawAdj); 11827 pw.print(" cur="); pw.print(r.curAdj); 11828 pw.print(" set="); pw.println(r.setAdj); 11829 pw.print(prefix); 11830 pw.print(" "); 11831 pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState)); 11832 pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState)); 11833 pw.print(" lastPss="); pw.print(r.lastPss); 11834 pw.print(" lastCachedPss="); pw.println(r.lastCachedPss); 11835 pw.print(prefix); 11836 pw.print(" "); 11837 pw.print("keeping="); pw.print(r.keeping); 11838 pw.print(" cached="); pw.print(r.cached); 11839 pw.print(" empty="); pw.print(r.empty); 11840 pw.print(" hasAboveClient="); pw.println(r.hasAboveClient); 11841 11842 if (!r.keeping) { 11843 if (r.lastWakeTime != 0) { 11844 long wtime; 11845 BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics(); 11846 synchronized (stats) { 11847 wtime = stats.getProcessWakeTime(r.info.uid, 11848 r.pid, curRealtime); 11849 } 11850 long timeUsed = wtime - r.lastWakeTime; 11851 pw.print(prefix); 11852 pw.print(" "); 11853 pw.print("keep awake over "); 11854 TimeUtils.formatDuration(realtimeSince, pw); 11855 pw.print(" used "); 11856 TimeUtils.formatDuration(timeUsed, pw); 11857 pw.print(" ("); 11858 pw.print((timeUsed*100)/realtimeSince); 11859 pw.println("%)"); 11860 } 11861 if (r.lastCpuTime != 0) { 11862 long timeUsed = r.curCpuTime - r.lastCpuTime; 11863 pw.print(prefix); 11864 pw.print(" "); 11865 pw.print("run cpu over "); 11866 TimeUtils.formatDuration(uptimeSince, pw); 11867 pw.print(" used "); 11868 TimeUtils.formatDuration(timeUsed, pw); 11869 pw.print(" ("); 11870 pw.print((timeUsed*100)/uptimeSince); 11871 pw.println("%)"); 11872 } 11873 } 11874 } 11875 } 11876 return true; 11877 } 11878 11879 ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) { 11880 ArrayList<ProcessRecord> procs; 11881 synchronized (this) { 11882 if (args != null && args.length > start 11883 && args[start].charAt(0) != '-') { 11884 procs = new ArrayList<ProcessRecord>(); 11885 int pid = -1; 11886 try { 11887 pid = Integer.parseInt(args[start]); 11888 } catch (NumberFormatException e) { 11889 } 11890 for (int i=mLruProcesses.size()-1; i>=0; i--) { 11891 ProcessRecord proc = mLruProcesses.get(i); 11892 if (proc.pid == pid) { 11893 procs.add(proc); 11894 } else if (proc.processName.equals(args[start])) { 11895 procs.add(proc); 11896 } 11897 } 11898 if (procs.size() <= 0) { 11899 return null; 11900 } 11901 } else { 11902 procs = new ArrayList<ProcessRecord>(mLruProcesses); 11903 } 11904 } 11905 return procs; 11906 } 11907 11908 final void dumpGraphicsHardwareUsage(FileDescriptor fd, 11909 PrintWriter pw, String[] args) { 11910 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args); 11911 if (procs == null) { 11912 pw.println("No process found for: " + args[0]); 11913 return; 11914 } 11915 11916 long uptime = SystemClock.uptimeMillis(); 11917 long realtime = SystemClock.elapsedRealtime(); 11918 pw.println("Applications Graphics Acceleration Info:"); 11919 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 11920 11921 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 11922 ProcessRecord r = procs.get(i); 11923 if (r.thread != null) { 11924 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **"); 11925 pw.flush(); 11926 try { 11927 TransferPipe tp = new TransferPipe(); 11928 try { 11929 r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args); 11930 tp.go(fd); 11931 } finally { 11932 tp.kill(); 11933 } 11934 } catch (IOException e) { 11935 pw.println("Failure while dumping the app: " + r); 11936 pw.flush(); 11937 } catch (RemoteException e) { 11938 pw.println("Got a RemoteException while dumping the app " + r); 11939 pw.flush(); 11940 } 11941 } 11942 } 11943 } 11944 11945 final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) { 11946 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args); 11947 if (procs == null) { 11948 pw.println("No process found for: " + args[0]); 11949 return; 11950 } 11951 11952 pw.println("Applications Database Info:"); 11953 11954 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 11955 ProcessRecord r = procs.get(i); 11956 if (r.thread != null) { 11957 pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **"); 11958 pw.flush(); 11959 try { 11960 TransferPipe tp = new TransferPipe(); 11961 try { 11962 r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args); 11963 tp.go(fd); 11964 } finally { 11965 tp.kill(); 11966 } 11967 } catch (IOException e) { 11968 pw.println("Failure while dumping the app: " + r); 11969 pw.flush(); 11970 } catch (RemoteException e) { 11971 pw.println("Got a RemoteException while dumping the app " + r); 11972 pw.flush(); 11973 } 11974 } 11975 } 11976 } 11977 11978 final static class MemItem { 11979 final boolean isProc; 11980 final String label; 11981 final String shortLabel; 11982 final long pss; 11983 final int id; 11984 final boolean hasActivities; 11985 ArrayList<MemItem> subitems; 11986 11987 public MemItem(String _label, String _shortLabel, long _pss, int _id, 11988 boolean _hasActivities) { 11989 isProc = true; 11990 label = _label; 11991 shortLabel = _shortLabel; 11992 pss = _pss; 11993 id = _id; 11994 hasActivities = _hasActivities; 11995 } 11996 11997 public MemItem(String _label, String _shortLabel, long _pss, int _id) { 11998 isProc = false; 11999 label = _label; 12000 shortLabel = _shortLabel; 12001 pss = _pss; 12002 id = _id; 12003 hasActivities = false; 12004 } 12005 } 12006 12007 static final void dumpMemItems(PrintWriter pw, String prefix, String tag, 12008 ArrayList<MemItem> items, boolean sort, boolean isCompact) { 12009 if (sort && !isCompact) { 12010 Collections.sort(items, new Comparator<MemItem>() { 12011 @Override 12012 public int compare(MemItem lhs, MemItem rhs) { 12013 if (lhs.pss < rhs.pss) { 12014 return 1; 12015 } else if (lhs.pss > rhs.pss) { 12016 return -1; 12017 } 12018 return 0; 12019 } 12020 }); 12021 } 12022 12023 for (int i=0; i<items.size(); i++) { 12024 MemItem mi = items.get(i); 12025 if (!isCompact) { 12026 pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label); 12027 } else if (mi.isProc) { 12028 pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel); 12029 pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss); 12030 pw.println(mi.hasActivities ? ",a" : ",e"); 12031 } else { 12032 pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(","); 12033 pw.println(mi.pss); 12034 } 12035 if (mi.subitems != null) { 12036 dumpMemItems(pw, prefix + " ", mi.shortLabel, mi.subitems, 12037 true, isCompact); 12038 } 12039 } 12040 } 12041 12042 // These are in KB. 12043 static final long[] DUMP_MEM_BUCKETS = new long[] { 12044 5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024, 12045 120*1024, 160*1024, 200*1024, 12046 250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024, 12047 1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024 12048 }; 12049 12050 static final void appendMemBucket(StringBuilder out, long memKB, String label, 12051 boolean stackLike) { 12052 int start = label.lastIndexOf('.'); 12053 if (start >= 0) start++; 12054 else start = 0; 12055 int end = label.length(); 12056 for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) { 12057 if (DUMP_MEM_BUCKETS[i] >= memKB) { 12058 long bucket = DUMP_MEM_BUCKETS[i]/1024; 12059 out.append(bucket); 12060 out.append(stackLike ? "MB." : "MB "); 12061 out.append(label, start, end); 12062 return; 12063 } 12064 } 12065 out.append(memKB/1024); 12066 out.append(stackLike ? "MB." : "MB "); 12067 out.append(label, start, end); 12068 } 12069 12070 static final int[] DUMP_MEM_OOM_ADJ = new int[] { 12071 ProcessList.NATIVE_ADJ, 12072 ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ, 12073 ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ, 12074 ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ, 12075 ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ, 12076 ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ 12077 }; 12078 static final String[] DUMP_MEM_OOM_LABEL = new String[] { 12079 "Native", 12080 "System", "Persistent", "Foreground", 12081 "Visible", "Perceptible", 12082 "Heavy Weight", "Backup", 12083 "A Services", "Home", 12084 "Previous", "B Services", "Cached" 12085 }; 12086 static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] { 12087 "native", 12088 "sys", "pers", "fore", 12089 "vis", "percept", 12090 "heavy", "backup", 12091 "servicea", "home", 12092 "prev", "serviceb", "cached" 12093 }; 12094 12095 private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime, 12096 long realtime, boolean isCheckinRequest, boolean isCompact) { 12097 if (isCheckinRequest || isCompact) { 12098 // short checkin version 12099 pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime); 12100 } else { 12101 pw.println("Applications Memory Usage (kB):"); 12102 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 12103 } 12104 } 12105 12106 final void dumpApplicationMemoryUsage(FileDescriptor fd, 12107 PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) { 12108 boolean dumpDetails = false; 12109 boolean dumpFullDetails = false; 12110 boolean dumpDalvik = false; 12111 boolean oomOnly = false; 12112 boolean isCompact = false; 12113 boolean localOnly = false; 12114 12115 int opti = 0; 12116 while (opti < args.length) { 12117 String opt = args[opti]; 12118 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 12119 break; 12120 } 12121 opti++; 12122 if ("-a".equals(opt)) { 12123 dumpDetails = true; 12124 dumpFullDetails = true; 12125 dumpDalvik = true; 12126 } else if ("-d".equals(opt)) { 12127 dumpDalvik = true; 12128 } else if ("-c".equals(opt)) { 12129 isCompact = true; 12130 } else if ("--oom".equals(opt)) { 12131 oomOnly = true; 12132 } else if ("--local".equals(opt)) { 12133 localOnly = true; 12134 } else if ("-h".equals(opt)) { 12135 pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]"); 12136 pw.println(" -a: include all available information for each process."); 12137 pw.println(" -d: include dalvik details when dumping process details."); 12138 pw.println(" -c: dump in a compact machine-parseable representation."); 12139 pw.println(" --oom: only show processes organized by oom adj."); 12140 pw.println(" --local: only collect details locally, don't call process."); 12141 pw.println("If [process] is specified it can be the name or "); 12142 pw.println("pid of a specific process to dump."); 12143 return; 12144 } else { 12145 pw.println("Unknown argument: " + opt + "; use -h for help"); 12146 } 12147 } 12148 12149 final boolean isCheckinRequest = scanArgs(args, "--checkin"); 12150 long uptime = SystemClock.uptimeMillis(); 12151 long realtime = SystemClock.elapsedRealtime(); 12152 final long[] tmpLong = new long[1]; 12153 12154 ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args); 12155 if (procs == null) { 12156 // No Java processes. Maybe they want to print a native process. 12157 if (args != null && args.length > opti 12158 && args[opti].charAt(0) != '-') { 12159 ArrayList<ProcessCpuTracker.Stats> nativeProcs 12160 = new ArrayList<ProcessCpuTracker.Stats>(); 12161 updateCpuStatsNow(); 12162 int findPid = -1; 12163 try { 12164 findPid = Integer.parseInt(args[opti]); 12165 } catch (NumberFormatException e) { 12166 } 12167 synchronized (mProcessCpuThread) { 12168 final int N = mProcessCpuTracker.countStats(); 12169 for (int i=0; i<N; i++) { 12170 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 12171 if (st.pid == findPid || (st.baseName != null 12172 && st.baseName.equals(args[opti]))) { 12173 nativeProcs.add(st); 12174 } 12175 } 12176 } 12177 if (nativeProcs.size() > 0) { 12178 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, 12179 isCompact); 12180 Debug.MemoryInfo mi = null; 12181 for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) { 12182 final ProcessCpuTracker.Stats r = nativeProcs.get(i); 12183 final int pid = r.pid; 12184 if (!isCheckinRequest && dumpDetails) { 12185 pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **"); 12186 } 12187 if (mi == null) { 12188 mi = new Debug.MemoryInfo(); 12189 } 12190 if (dumpDetails || (!brief && !oomOnly)) { 12191 Debug.getMemoryInfo(pid, mi); 12192 } else { 12193 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong); 12194 mi.dalvikPrivateDirty = (int)tmpLong[0]; 12195 } 12196 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails, 12197 dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0); 12198 if (isCheckinRequest) { 12199 pw.println(); 12200 } 12201 } 12202 return; 12203 } 12204 } 12205 pw.println("No process found for: " + args[opti]); 12206 return; 12207 } 12208 12209 if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest)) { 12210 dumpDetails = true; 12211 } 12212 12213 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact); 12214 12215 String[] innerArgs = new String[args.length-opti]; 12216 System.arraycopy(args, opti, innerArgs, 0, args.length-opti); 12217 12218 ArrayList<MemItem> procMems = new ArrayList<MemItem>(); 12219 final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>(); 12220 long nativePss=0, dalvikPss=0, otherPss=0; 12221 long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS]; 12222 12223 long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length]; 12224 ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[]) 12225 new ArrayList[DUMP_MEM_OOM_LABEL.length]; 12226 12227 long totalPss = 0; 12228 long cachedPss = 0; 12229 12230 Debug.MemoryInfo mi = null; 12231 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 12232 final ProcessRecord r = procs.get(i); 12233 final IApplicationThread thread; 12234 final int pid; 12235 final int oomAdj; 12236 final boolean hasActivities; 12237 synchronized (this) { 12238 thread = r.thread; 12239 pid = r.pid; 12240 oomAdj = r.getSetAdjWithServices(); 12241 hasActivities = r.activities.size() > 0; 12242 } 12243 if (thread != null) { 12244 if (!isCheckinRequest && dumpDetails) { 12245 pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **"); 12246 } 12247 if (mi == null) { 12248 mi = new Debug.MemoryInfo(); 12249 } 12250 if (dumpDetails || (!brief && !oomOnly)) { 12251 Debug.getMemoryInfo(pid, mi); 12252 } else { 12253 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong); 12254 mi.dalvikPrivateDirty = (int)tmpLong[0]; 12255 } 12256 if (dumpDetails) { 12257 if (localOnly) { 12258 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails, 12259 dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0); 12260 if (isCheckinRequest) { 12261 pw.println(); 12262 } 12263 } else { 12264 try { 12265 pw.flush(); 12266 thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails, 12267 dumpDalvik, innerArgs); 12268 } catch (RemoteException e) { 12269 if (!isCheckinRequest) { 12270 pw.println("Got RemoteException!"); 12271 pw.flush(); 12272 } 12273 } 12274 } 12275 } 12276 12277 final long myTotalPss = mi.getTotalPss(); 12278 final long myTotalUss = mi.getTotalUss(); 12279 12280 synchronized (this) { 12281 if (r.thread != null && oomAdj == r.getSetAdjWithServices()) { 12282 // Record this for posterity if the process has been stable. 12283 r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList); 12284 } 12285 } 12286 12287 if (!isCheckinRequest && mi != null) { 12288 totalPss += myTotalPss; 12289 MemItem pssItem = new MemItem(r.processName + " (pid " + pid + 12290 (hasActivities ? " / activities)" : ")"), 12291 r.processName, myTotalPss, pid, hasActivities); 12292 procMems.add(pssItem); 12293 procMemsMap.put(pid, pssItem); 12294 12295 nativePss += mi.nativePss; 12296 dalvikPss += mi.dalvikPss; 12297 otherPss += mi.otherPss; 12298 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 12299 long mem = mi.getOtherPss(j); 12300 miscPss[j] += mem; 12301 otherPss -= mem; 12302 } 12303 12304 if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 12305 cachedPss += myTotalPss; 12306 } 12307 12308 for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) { 12309 if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex] 12310 || oomIndex == (oomPss.length-1)) { 12311 oomPss[oomIndex] += myTotalPss; 12312 if (oomProcs[oomIndex] == null) { 12313 oomProcs[oomIndex] = new ArrayList<MemItem>(); 12314 } 12315 oomProcs[oomIndex].add(pssItem); 12316 break; 12317 } 12318 } 12319 } 12320 } 12321 } 12322 12323 if (!isCheckinRequest && procs.size() > 1) { 12324 // If we are showing aggregations, also look for native processes to 12325 // include so that our aggregations are more accurate. 12326 updateCpuStatsNow(); 12327 synchronized (mProcessCpuThread) { 12328 final int N = mProcessCpuTracker.countStats(); 12329 for (int i=0; i<N; i++) { 12330 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 12331 if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) { 12332 if (mi == null) { 12333 mi = new Debug.MemoryInfo(); 12334 } 12335 if (!brief && !oomOnly) { 12336 Debug.getMemoryInfo(st.pid, mi); 12337 } else { 12338 mi.nativePss = (int)Debug.getPss(st.pid, tmpLong); 12339 mi.nativePrivateDirty = (int)tmpLong[0]; 12340 } 12341 12342 final long myTotalPss = mi.getTotalPss(); 12343 totalPss += myTotalPss; 12344 12345 MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")", 12346 st.name, myTotalPss, st.pid, false); 12347 procMems.add(pssItem); 12348 12349 nativePss += mi.nativePss; 12350 dalvikPss += mi.dalvikPss; 12351 otherPss += mi.otherPss; 12352 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 12353 long mem = mi.getOtherPss(j); 12354 miscPss[j] += mem; 12355 otherPss -= mem; 12356 } 12357 oomPss[0] += myTotalPss; 12358 if (oomProcs[0] == null) { 12359 oomProcs[0] = new ArrayList<MemItem>(); 12360 } 12361 oomProcs[0].add(pssItem); 12362 } 12363 } 12364 } 12365 12366 ArrayList<MemItem> catMems = new ArrayList<MemItem>(); 12367 12368 catMems.add(new MemItem("Native", "Native", nativePss, -1)); 12369 catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2)); 12370 catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3)); 12371 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 12372 String label = Debug.MemoryInfo.getOtherLabel(j); 12373 catMems.add(new MemItem(label, label, miscPss[j], j)); 12374 } 12375 12376 ArrayList<MemItem> oomMems = new ArrayList<MemItem>(); 12377 for (int j=0; j<oomPss.length; j++) { 12378 if (oomPss[j] != 0) { 12379 String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j] 12380 : DUMP_MEM_OOM_LABEL[j]; 12381 MemItem item = new MemItem(label, label, oomPss[j], 12382 DUMP_MEM_OOM_ADJ[j]); 12383 item.subitems = oomProcs[j]; 12384 oomMems.add(item); 12385 } 12386 } 12387 12388 if (!brief && !oomOnly && !isCompact) { 12389 pw.println(); 12390 pw.println("Total PSS by process:"); 12391 dumpMemItems(pw, " ", "proc", procMems, true, isCompact); 12392 pw.println(); 12393 } 12394 if (!isCompact) { 12395 pw.println("Total PSS by OOM adjustment:"); 12396 } 12397 dumpMemItems(pw, " ", "oom", oomMems, false, isCompact); 12398 if (!brief && !oomOnly) { 12399 PrintWriter out = categoryPw != null ? categoryPw : pw; 12400 if (!isCompact) { 12401 out.println(); 12402 out.println("Total PSS by category:"); 12403 } 12404 dumpMemItems(out, " ", "cat", catMems, true, isCompact); 12405 } 12406 if (!isCompact) { 12407 pw.println(); 12408 } 12409 MemInfoReader memInfo = new MemInfoReader(); 12410 memInfo.readMemInfo(); 12411 if (!brief) { 12412 if (!isCompact) { 12413 pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb()); 12414 pw.print(" kB (status "); 12415 switch (mLastMemoryLevel) { 12416 case ProcessStats.ADJ_MEM_FACTOR_NORMAL: 12417 pw.println("normal)"); 12418 break; 12419 case ProcessStats.ADJ_MEM_FACTOR_MODERATE: 12420 pw.println("moderate)"); 12421 break; 12422 case ProcessStats.ADJ_MEM_FACTOR_LOW: 12423 pw.println("low)"); 12424 break; 12425 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL: 12426 pw.println("critical)"); 12427 break; 12428 default: 12429 pw.print(mLastMemoryLevel); 12430 pw.println(")"); 12431 break; 12432 } 12433 pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb() 12434 + memInfo.getFreeSizeKb()); pw.print(" kB ("); 12435 pw.print(cachedPss); pw.print(" cached pss + "); 12436 pw.print(memInfo.getCachedSizeKb()); pw.print(" cached + "); 12437 pw.print(memInfo.getFreeSizeKb()); pw.println(" free)"); 12438 } else { 12439 pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(","); 12440 pw.print(cachedPss + memInfo.getCachedSizeKb() 12441 + memInfo.getFreeSizeKb()); pw.print(","); 12442 pw.println(totalPss - cachedPss); 12443 } 12444 } 12445 if (!isCompact) { 12446 pw.print(" Used RAM: "); pw.print(totalPss - cachedPss 12447 + memInfo.getBuffersSizeKb() + memInfo.getShmemSizeKb() 12448 + memInfo.getSlabSizeKb()); pw.print(" kB ("); 12449 pw.print(totalPss - cachedPss); pw.print(" used pss + "); 12450 pw.print(memInfo.getBuffersSizeKb()); pw.print(" buffers + "); 12451 pw.print(memInfo.getShmemSizeKb()); pw.print(" shmem + "); 12452 pw.print(memInfo.getSlabSizeKb()); pw.println(" slab)"); 12453 pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb() 12454 - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb() 12455 - memInfo.getBuffersSizeKb() - memInfo.getShmemSizeKb() 12456 - memInfo.getSlabSizeKb()); pw.println(" kB"); 12457 } 12458 if (!brief) { 12459 if (memInfo.getZramTotalSizeKb() != 0) { 12460 if (!isCompact) { 12461 pw.print(" ZRAM: "); pw.print(memInfo.getZramTotalSizeKb()); 12462 pw.print(" kB physical used for "); 12463 pw.print(memInfo.getSwapTotalSizeKb() 12464 - memInfo.getSwapFreeSizeKb()); 12465 pw.print(" kB in swap ("); 12466 pw.print(memInfo.getSwapTotalSizeKb()); 12467 pw.println(" kB total swap)"); 12468 } else { 12469 pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(","); 12470 pw.print(memInfo.getSwapTotalSizeKb()); pw.print(","); 12471 pw.println(memInfo.getSwapFreeSizeKb()); 12472 } 12473 } 12474 final int[] SINGLE_LONG_FORMAT = new int[] { 12475 Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG 12476 }; 12477 long[] longOut = new long[1]; 12478 Process.readProcFile("/sys/kernel/mm/ksm/pages_shared", 12479 SINGLE_LONG_FORMAT, null, longOut, null); 12480 long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024; 12481 longOut[0] = 0; 12482 Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing", 12483 SINGLE_LONG_FORMAT, null, longOut, null); 12484 long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024; 12485 longOut[0] = 0; 12486 Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared", 12487 SINGLE_LONG_FORMAT, null, longOut, null); 12488 long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024; 12489 longOut[0] = 0; 12490 Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile", 12491 SINGLE_LONG_FORMAT, null, longOut, null); 12492 long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024; 12493 if (!isCompact) { 12494 if (sharing != 0 || shared != 0 || unshared != 0 || voltile != 0) { 12495 pw.print(" KSM: "); pw.print(sharing); 12496 pw.print(" kB saved from shared "); 12497 pw.print(shared); pw.println(" kB"); 12498 pw.print(" "); pw.print(unshared); pw.print(" kB unshared; "); 12499 pw.print(voltile); pw.println(" kB volatile"); 12500 } 12501 pw.print(" Tuning: "); 12502 pw.print(ActivityManager.staticGetMemoryClass()); 12503 pw.print(" (large "); 12504 pw.print(ActivityManager.staticGetLargeMemoryClass()); 12505 pw.print("), oom "); 12506 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024); 12507 pw.print(" kB"); 12508 pw.print(", restore limit "); 12509 pw.print(mProcessList.getCachedRestoreThresholdKb()); 12510 pw.print(" kB"); 12511 if (ActivityManager.isLowRamDeviceStatic()) { 12512 pw.print(" (low-ram)"); 12513 } 12514 if (ActivityManager.isHighEndGfx()) { 12515 pw.print(" (high-end-gfx)"); 12516 } 12517 pw.println(); 12518 } else { 12519 pw.print("ksm,"); pw.print(sharing); pw.print(","); 12520 pw.print(shared); pw.print(","); pw.print(unshared); pw.print(","); 12521 pw.println(voltile); 12522 pw.print("tuning,"); 12523 pw.print(ActivityManager.staticGetMemoryClass()); 12524 pw.print(','); 12525 pw.print(ActivityManager.staticGetLargeMemoryClass()); 12526 pw.print(','); 12527 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024); 12528 if (ActivityManager.isLowRamDeviceStatic()) { 12529 pw.print(",low-ram"); 12530 } 12531 if (ActivityManager.isHighEndGfx()) { 12532 pw.print(",high-end-gfx"); 12533 } 12534 pw.println(); 12535 } 12536 } 12537 } 12538 } 12539 12540 /** 12541 * Searches array of arguments for the specified string 12542 * @param args array of argument strings 12543 * @param value value to search for 12544 * @return true if the value is contained in the array 12545 */ 12546 private static boolean scanArgs(String[] args, String value) { 12547 if (args != null) { 12548 for (String arg : args) { 12549 if (value.equals(arg)) { 12550 return true; 12551 } 12552 } 12553 } 12554 return false; 12555 } 12556 12557 private final boolean removeDyingProviderLocked(ProcessRecord proc, 12558 ContentProviderRecord cpr, boolean always) { 12559 final boolean inLaunching = mLaunchingProviders.contains(cpr); 12560 12561 if (!inLaunching || always) { 12562 synchronized (cpr) { 12563 cpr.launchingApp = null; 12564 cpr.notifyAll(); 12565 } 12566 mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid)); 12567 String names[] = cpr.info.authority.split(";"); 12568 for (int j = 0; j < names.length; j++) { 12569 mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid)); 12570 } 12571 } 12572 12573 for (int i=0; i<cpr.connections.size(); i++) { 12574 ContentProviderConnection conn = cpr.connections.get(i); 12575 if (conn.waiting) { 12576 // If this connection is waiting for the provider, then we don't 12577 // need to mess with its process unless we are always removing 12578 // or for some reason the provider is not currently launching. 12579 if (inLaunching && !always) { 12580 continue; 12581 } 12582 } 12583 ProcessRecord capp = conn.client; 12584 conn.dead = true; 12585 if (conn.stableCount > 0) { 12586 if (!capp.persistent && capp.thread != null 12587 && capp.pid != 0 12588 && capp.pid != MY_PID) { 12589 killUnneededProcessLocked(capp, "depends on provider " 12590 + cpr.name.flattenToShortString() 12591 + " in dying proc " + (proc != null ? proc.processName : "??")); 12592 } 12593 } else if (capp.thread != null && conn.provider.provider != null) { 12594 try { 12595 capp.thread.unstableProviderDied(conn.provider.provider.asBinder()); 12596 } catch (RemoteException e) { 12597 } 12598 // In the protocol here, we don't expect the client to correctly 12599 // clean up this connection, we'll just remove it. 12600 cpr.connections.remove(i); 12601 conn.client.conProviders.remove(conn); 12602 } 12603 } 12604 12605 if (inLaunching && always) { 12606 mLaunchingProviders.remove(cpr); 12607 } 12608 return inLaunching; 12609 } 12610 12611 /** 12612 * Main code for cleaning up a process when it has gone away. This is 12613 * called both as a result of the process dying, or directly when stopping 12614 * a process when running in single process mode. 12615 */ 12616 private final void cleanUpApplicationRecordLocked(ProcessRecord app, 12617 boolean restarting, boolean allowRestart, int index) { 12618 if (index >= 0) { 12619 removeLruProcessLocked(app); 12620 ProcessList.remove(app.pid); 12621 } 12622 12623 mProcessesToGc.remove(app); 12624 mPendingPssProcesses.remove(app); 12625 12626 // Dismiss any open dialogs. 12627 if (app.crashDialog != null && !app.forceCrashReport) { 12628 app.crashDialog.dismiss(); 12629 app.crashDialog = null; 12630 } 12631 if (app.anrDialog != null) { 12632 app.anrDialog.dismiss(); 12633 app.anrDialog = null; 12634 } 12635 if (app.waitDialog != null) { 12636 app.waitDialog.dismiss(); 12637 app.waitDialog = null; 12638 } 12639 12640 app.crashing = false; 12641 app.notResponding = false; 12642 12643 app.resetPackageList(mProcessStats); 12644 app.unlinkDeathRecipient(); 12645 app.makeInactive(mProcessStats); 12646 app.forcingToForeground = null; 12647 updateProcessForegroundLocked(app, false, false); 12648 app.foregroundActivities = false; 12649 app.hasShownUi = false; 12650 app.treatLikeActivity = false; 12651 app.hasAboveClient = false; 12652 app.hasClientActivities = false; 12653 12654 mServices.killServicesLocked(app, allowRestart); 12655 12656 boolean restart = false; 12657 12658 // Remove published content providers. 12659 for (int i=app.pubProviders.size()-1; i>=0; i--) { 12660 ContentProviderRecord cpr = app.pubProviders.valueAt(i); 12661 final boolean always = app.bad || !allowRestart; 12662 if (removeDyingProviderLocked(app, cpr, always) || always) { 12663 // We left the provider in the launching list, need to 12664 // restart it. 12665 restart = true; 12666 } 12667 12668 cpr.provider = null; 12669 cpr.proc = null; 12670 } 12671 app.pubProviders.clear(); 12672 12673 // Take care of any launching providers waiting for this process. 12674 if (checkAppInLaunchingProvidersLocked(app, false)) { 12675 restart = true; 12676 } 12677 12678 // Unregister from connected content providers. 12679 if (!app.conProviders.isEmpty()) { 12680 for (int i=0; i<app.conProviders.size(); i++) { 12681 ContentProviderConnection conn = app.conProviders.get(i); 12682 conn.provider.connections.remove(conn); 12683 } 12684 app.conProviders.clear(); 12685 } 12686 12687 // At this point there may be remaining entries in mLaunchingProviders 12688 // where we were the only one waiting, so they are no longer of use. 12689 // Look for these and clean up if found. 12690 // XXX Commented out for now. Trying to figure out a way to reproduce 12691 // the actual situation to identify what is actually going on. 12692 if (false) { 12693 for (int i=0; i<mLaunchingProviders.size(); i++) { 12694 ContentProviderRecord cpr = (ContentProviderRecord) 12695 mLaunchingProviders.get(i); 12696 if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) { 12697 synchronized (cpr) { 12698 cpr.launchingApp = null; 12699 cpr.notifyAll(); 12700 } 12701 } 12702 } 12703 } 12704 12705 skipCurrentReceiverLocked(app); 12706 12707 // Unregister any receivers. 12708 for (int i=app.receivers.size()-1; i>=0; i--) { 12709 removeReceiverLocked(app.receivers.valueAt(i)); 12710 } 12711 app.receivers.clear(); 12712 12713 // If the app is undergoing backup, tell the backup manager about it 12714 if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) { 12715 if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App " 12716 + mBackupTarget.appInfo + " died during backup"); 12717 try { 12718 IBackupManager bm = IBackupManager.Stub.asInterface( 12719 ServiceManager.getService(Context.BACKUP_SERVICE)); 12720 bm.agentDisconnected(app.info.packageName); 12721 } catch (RemoteException e) { 12722 // can't happen; backup manager is local 12723 } 12724 } 12725 12726 for (int i = mPendingProcessChanges.size()-1; i>=0; i--) { 12727 ProcessChangeItem item = mPendingProcessChanges.get(i); 12728 if (item.pid == app.pid) { 12729 mPendingProcessChanges.remove(i); 12730 mAvailProcessChanges.add(item); 12731 } 12732 } 12733 mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget(); 12734 12735 // If the caller is restarting this app, then leave it in its 12736 // current lists and let the caller take care of it. 12737 if (restarting) { 12738 return; 12739 } 12740 12741 if (!app.persistent || app.isolated) { 12742 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, 12743 "Removing non-persistent process during cleanup: " + app); 12744 mProcessNames.remove(app.processName, app.uid); 12745 mIsolatedProcesses.remove(app.uid); 12746 if (mHeavyWeightProcess == app) { 12747 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 12748 mHeavyWeightProcess.userId, 0)); 12749 mHeavyWeightProcess = null; 12750 } 12751 } else if (!app.removed) { 12752 // This app is persistent, so we need to keep its record around. 12753 // If it is not already on the pending app list, add it there 12754 // and start a new process for it. 12755 if (mPersistentStartingProcesses.indexOf(app) < 0) { 12756 mPersistentStartingProcesses.add(app); 12757 restart = true; 12758 } 12759 } 12760 if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG, 12761 "Clean-up removing on hold: " + app); 12762 mProcessesOnHold.remove(app); 12763 12764 if (app == mHomeProcess) { 12765 mHomeProcess = null; 12766 } 12767 if (app == mPreviousProcess) { 12768 mPreviousProcess = null; 12769 } 12770 12771 if (restart && !app.isolated) { 12772 // We have components that still need to be running in the 12773 // process, so re-launch it. 12774 mProcessNames.put(app.processName, app.uid, app); 12775 startProcessLocked(app, "restart", app.processName); 12776 } else if (app.pid > 0 && app.pid != MY_PID) { 12777 // Goodbye! 12778 boolean removed; 12779 synchronized (mPidsSelfLocked) { 12780 mPidsSelfLocked.remove(app.pid); 12781 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 12782 } 12783 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH, 12784 app.processName, app.info.uid); 12785 if (app.isolated) { 12786 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 12787 } 12788 app.setPid(0); 12789 } 12790 } 12791 12792 boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) { 12793 // Look through the content providers we are waiting to have launched, 12794 // and if any run in this process then either schedule a restart of 12795 // the process or kill the client waiting for it if this process has 12796 // gone bad. 12797 int NL = mLaunchingProviders.size(); 12798 boolean restart = false; 12799 for (int i=0; i<NL; i++) { 12800 ContentProviderRecord cpr = mLaunchingProviders.get(i); 12801 if (cpr.launchingApp == app) { 12802 if (!alwaysBad && !app.bad) { 12803 restart = true; 12804 } else { 12805 removeDyingProviderLocked(app, cpr, true); 12806 // cpr should have been removed from mLaunchingProviders 12807 NL = mLaunchingProviders.size(); 12808 i--; 12809 } 12810 } 12811 } 12812 return restart; 12813 } 12814 12815 // ========================================================= 12816 // SERVICES 12817 // ========================================================= 12818 12819 public List<ActivityManager.RunningServiceInfo> getServices(int maxNum, 12820 int flags) { 12821 enforceNotIsolatedCaller("getServices"); 12822 synchronized (this) { 12823 return mServices.getRunningServiceInfoLocked(maxNum, flags); 12824 } 12825 } 12826 12827 public PendingIntent getRunningServiceControlPanel(ComponentName name) { 12828 enforceNotIsolatedCaller("getRunningServiceControlPanel"); 12829 synchronized (this) { 12830 return mServices.getRunningServiceControlPanelLocked(name); 12831 } 12832 } 12833 12834 public ComponentName startService(IApplicationThread caller, Intent service, 12835 String resolvedType, int userId) { 12836 enforceNotIsolatedCaller("startService"); 12837 // Refuse possible leaked file descriptors 12838 if (service != null && service.hasFileDescriptors() == true) { 12839 throw new IllegalArgumentException("File descriptors passed in Intent"); 12840 } 12841 12842 if (DEBUG_SERVICE) 12843 Slog.v(TAG, "startService: " + service + " type=" + resolvedType); 12844 synchronized(this) { 12845 final int callingPid = Binder.getCallingPid(); 12846 final int callingUid = Binder.getCallingUid(); 12847 final long origId = Binder.clearCallingIdentity(); 12848 ComponentName res = mServices.startServiceLocked(caller, service, 12849 resolvedType, callingPid, callingUid, userId); 12850 Binder.restoreCallingIdentity(origId); 12851 return res; 12852 } 12853 } 12854 12855 ComponentName startServiceInPackage(int uid, 12856 Intent service, String resolvedType, int userId) { 12857 synchronized(this) { 12858 if (DEBUG_SERVICE) 12859 Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType); 12860 final long origId = Binder.clearCallingIdentity(); 12861 ComponentName res = mServices.startServiceLocked(null, service, 12862 resolvedType, -1, uid, userId); 12863 Binder.restoreCallingIdentity(origId); 12864 return res; 12865 } 12866 } 12867 12868 public int stopService(IApplicationThread caller, Intent service, 12869 String resolvedType, int userId) { 12870 enforceNotIsolatedCaller("stopService"); 12871 // Refuse possible leaked file descriptors 12872 if (service != null && service.hasFileDescriptors() == true) { 12873 throw new IllegalArgumentException("File descriptors passed in Intent"); 12874 } 12875 12876 synchronized(this) { 12877 return mServices.stopServiceLocked(caller, service, resolvedType, userId); 12878 } 12879 } 12880 12881 public IBinder peekService(Intent service, String resolvedType) { 12882 enforceNotIsolatedCaller("peekService"); 12883 // Refuse possible leaked file descriptors 12884 if (service != null && service.hasFileDescriptors() == true) { 12885 throw new IllegalArgumentException("File descriptors passed in Intent"); 12886 } 12887 synchronized(this) { 12888 return mServices.peekServiceLocked(service, resolvedType); 12889 } 12890 } 12891 12892 public boolean stopServiceToken(ComponentName className, IBinder token, 12893 int startId) { 12894 synchronized(this) { 12895 return mServices.stopServiceTokenLocked(className, token, startId); 12896 } 12897 } 12898 12899 public void setServiceForeground(ComponentName className, IBinder token, 12900 int id, Notification notification, boolean removeNotification) { 12901 synchronized(this) { 12902 mServices.setServiceForegroundLocked(className, token, id, notification, 12903 removeNotification); 12904 } 12905 } 12906 12907 public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll, 12908 boolean requireFull, String name, String callerPackage) { 12909 final int callingUserId = UserHandle.getUserId(callingUid); 12910 if (callingUserId != userId) { 12911 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 12912 if ((requireFull || checkComponentPermission( 12913 android.Manifest.permission.INTERACT_ACROSS_USERS, 12914 callingPid, callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) 12915 && checkComponentPermission( 12916 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 12917 callingPid, callingUid, -1, true) 12918 != PackageManager.PERMISSION_GRANTED) { 12919 if (userId == UserHandle.USER_CURRENT_OR_SELF) { 12920 // In this case, they would like to just execute as their 12921 // owner user instead of failing. 12922 userId = callingUserId; 12923 } else { 12924 StringBuilder builder = new StringBuilder(128); 12925 builder.append("Permission Denial: "); 12926 builder.append(name); 12927 if (callerPackage != null) { 12928 builder.append(" from "); 12929 builder.append(callerPackage); 12930 } 12931 builder.append(" asks to run as user "); 12932 builder.append(userId); 12933 builder.append(" but is calling from user "); 12934 builder.append(UserHandle.getUserId(callingUid)); 12935 builder.append("; this requires "); 12936 builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL); 12937 if (!requireFull) { 12938 builder.append(" or "); 12939 builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS); 12940 } 12941 String msg = builder.toString(); 12942 Slog.w(TAG, msg); 12943 throw new SecurityException(msg); 12944 } 12945 } 12946 } 12947 if (userId == UserHandle.USER_CURRENT 12948 || userId == UserHandle.USER_CURRENT_OR_SELF) { 12949 // Note that we may be accessing this outside of a lock... 12950 // shouldn't be a big deal, if this is being called outside 12951 // of a locked context there is intrinsically a race with 12952 // the value the caller will receive and someone else changing it. 12953 userId = mCurrentUserId; 12954 } 12955 if (!allowAll && userId < 0) { 12956 throw new IllegalArgumentException( 12957 "Call does not support special user #" + userId); 12958 } 12959 } 12960 return userId; 12961 } 12962 12963 boolean isSingleton(String componentProcessName, ApplicationInfo aInfo, 12964 String className, int flags) { 12965 boolean result = false; 12966 if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) { 12967 if ((flags&ServiceInfo.FLAG_SINGLE_USER) != 0) { 12968 if (ActivityManager.checkUidPermission( 12969 android.Manifest.permission.INTERACT_ACROSS_USERS, 12970 aInfo.uid) != PackageManager.PERMISSION_GRANTED) { 12971 ComponentName comp = new ComponentName(aInfo.packageName, className); 12972 String msg = "Permission Denial: Component " + comp.flattenToShortString() 12973 + " requests FLAG_SINGLE_USER, but app does not hold " 12974 + android.Manifest.permission.INTERACT_ACROSS_USERS; 12975 Slog.w(TAG, msg); 12976 throw new SecurityException(msg); 12977 } 12978 result = true; 12979 } 12980 } else if (componentProcessName == aInfo.packageName) { 12981 result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0; 12982 } else if ("system".equals(componentProcessName)) { 12983 result = true; 12984 } 12985 if (DEBUG_MU) { 12986 Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo 12987 + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result); 12988 } 12989 return result; 12990 } 12991 12992 public int bindService(IApplicationThread caller, IBinder token, 12993 Intent service, String resolvedType, 12994 IServiceConnection connection, int flags, int userId) { 12995 enforceNotIsolatedCaller("bindService"); 12996 // Refuse possible leaked file descriptors 12997 if (service != null && service.hasFileDescriptors() == true) { 12998 throw new IllegalArgumentException("File descriptors passed in Intent"); 12999 } 13000 13001 synchronized(this) { 13002 return mServices.bindServiceLocked(caller, token, service, resolvedType, 13003 connection, flags, userId); 13004 } 13005 } 13006 13007 public boolean unbindService(IServiceConnection connection) { 13008 synchronized (this) { 13009 return mServices.unbindServiceLocked(connection); 13010 } 13011 } 13012 13013 public void publishService(IBinder token, Intent intent, IBinder service) { 13014 // Refuse possible leaked file descriptors 13015 if (intent != null && intent.hasFileDescriptors() == true) { 13016 throw new IllegalArgumentException("File descriptors passed in Intent"); 13017 } 13018 13019 synchronized(this) { 13020 if (!(token instanceof ServiceRecord)) { 13021 throw new IllegalArgumentException("Invalid service token"); 13022 } 13023 mServices.publishServiceLocked((ServiceRecord)token, intent, service); 13024 } 13025 } 13026 13027 public void unbindFinished(IBinder token, Intent intent, boolean doRebind) { 13028 // Refuse possible leaked file descriptors 13029 if (intent != null && intent.hasFileDescriptors() == true) { 13030 throw new IllegalArgumentException("File descriptors passed in Intent"); 13031 } 13032 13033 synchronized(this) { 13034 mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind); 13035 } 13036 } 13037 13038 public void serviceDoneExecuting(IBinder token, int type, int startId, int res) { 13039 synchronized(this) { 13040 if (!(token instanceof ServiceRecord)) { 13041 throw new IllegalArgumentException("Invalid service token"); 13042 } 13043 mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res); 13044 } 13045 } 13046 13047 // ========================================================= 13048 // BACKUP AND RESTORE 13049 // ========================================================= 13050 13051 // Cause the target app to be launched if necessary and its backup agent 13052 // instantiated. The backup agent will invoke backupAgentCreated() on the 13053 // activity manager to announce its creation. 13054 public boolean bindBackupAgent(ApplicationInfo app, int backupMode) { 13055 if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode); 13056 enforceCallingPermission("android.permission.BACKUP", "bindBackupAgent"); 13057 13058 synchronized(this) { 13059 // !!! TODO: currently no check here that we're already bound 13060 BatteryStatsImpl.Uid.Pkg.Serv ss = null; 13061 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 13062 synchronized (stats) { 13063 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name); 13064 } 13065 13066 // Backup agent is now in use, its package can't be stopped. 13067 try { 13068 AppGlobals.getPackageManager().setPackageStoppedState( 13069 app.packageName, false, UserHandle.getUserId(app.uid)); 13070 } catch (RemoteException e) { 13071 } catch (IllegalArgumentException e) { 13072 Slog.w(TAG, "Failed trying to unstop package " 13073 + app.packageName + ": " + e); 13074 } 13075 13076 BackupRecord r = new BackupRecord(ss, app, backupMode); 13077 ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL) 13078 ? new ComponentName(app.packageName, app.backupAgentName) 13079 : new ComponentName("android", "FullBackupAgent"); 13080 // startProcessLocked() returns existing proc's record if it's already running 13081 ProcessRecord proc = startProcessLocked(app.processName, app, 13082 false, 0, "backup", hostingName, false, false, false); 13083 if (proc == null) { 13084 Slog.e(TAG, "Unable to start backup agent process " + r); 13085 return false; 13086 } 13087 13088 r.app = proc; 13089 mBackupTarget = r; 13090 mBackupAppName = app.packageName; 13091 13092 // Try not to kill the process during backup 13093 updateOomAdjLocked(proc); 13094 13095 // If the process is already attached, schedule the creation of the backup agent now. 13096 // If it is not yet live, this will be done when it attaches to the framework. 13097 if (proc.thread != null) { 13098 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc); 13099 try { 13100 proc.thread.scheduleCreateBackupAgent(app, 13101 compatibilityInfoForPackageLocked(app), backupMode); 13102 } catch (RemoteException e) { 13103 // Will time out on the backup manager side 13104 } 13105 } else { 13106 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach"); 13107 } 13108 // Invariants: at this point, the target app process exists and the application 13109 // is either already running or in the process of coming up. mBackupTarget and 13110 // mBackupAppName describe the app, so that when it binds back to the AM we 13111 // know that it's scheduled for a backup-agent operation. 13112 } 13113 13114 return true; 13115 } 13116 13117 @Override 13118 public void clearPendingBackup() { 13119 if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup"); 13120 enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup"); 13121 13122 synchronized (this) { 13123 mBackupTarget = null; 13124 mBackupAppName = null; 13125 } 13126 } 13127 13128 // A backup agent has just come up 13129 public void backupAgentCreated(String agentPackageName, IBinder agent) { 13130 if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName 13131 + " = " + agent); 13132 13133 synchronized(this) { 13134 if (!agentPackageName.equals(mBackupAppName)) { 13135 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!"); 13136 return; 13137 } 13138 } 13139 13140 long oldIdent = Binder.clearCallingIdentity(); 13141 try { 13142 IBackupManager bm = IBackupManager.Stub.asInterface( 13143 ServiceManager.getService(Context.BACKUP_SERVICE)); 13144 bm.agentConnected(agentPackageName, agent); 13145 } catch (RemoteException e) { 13146 // can't happen; the backup manager service is local 13147 } catch (Exception e) { 13148 Slog.w(TAG, "Exception trying to deliver BackupAgent binding: "); 13149 e.printStackTrace(); 13150 } finally { 13151 Binder.restoreCallingIdentity(oldIdent); 13152 } 13153 } 13154 13155 // done with this agent 13156 public void unbindBackupAgent(ApplicationInfo appInfo) { 13157 if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo); 13158 if (appInfo == null) { 13159 Slog.w(TAG, "unbind backup agent for null app"); 13160 return; 13161 } 13162 13163 synchronized(this) { 13164 try { 13165 if (mBackupAppName == null) { 13166 Slog.w(TAG, "Unbinding backup agent with no active backup"); 13167 return; 13168 } 13169 13170 if (!mBackupAppName.equals(appInfo.packageName)) { 13171 Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target"); 13172 return; 13173 } 13174 13175 // Not backing this app up any more; reset its OOM adjustment 13176 final ProcessRecord proc = mBackupTarget.app; 13177 updateOomAdjLocked(proc); 13178 13179 // If the app crashed during backup, 'thread' will be null here 13180 if (proc.thread != null) { 13181 try { 13182 proc.thread.scheduleDestroyBackupAgent(appInfo, 13183 compatibilityInfoForPackageLocked(appInfo)); 13184 } catch (Exception e) { 13185 Slog.e(TAG, "Exception when unbinding backup agent:"); 13186 e.printStackTrace(); 13187 } 13188 } 13189 } finally { 13190 mBackupTarget = null; 13191 mBackupAppName = null; 13192 } 13193 } 13194 } 13195 // ========================================================= 13196 // BROADCASTS 13197 // ========================================================= 13198 13199 private final List getStickiesLocked(String action, IntentFilter filter, 13200 List cur, int userId) { 13201 final ContentResolver resolver = mContext.getContentResolver(); 13202 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 13203 if (stickies == null) { 13204 return cur; 13205 } 13206 final ArrayList<Intent> list = stickies.get(action); 13207 if (list == null) { 13208 return cur; 13209 } 13210 int N = list.size(); 13211 for (int i=0; i<N; i++) { 13212 Intent intent = list.get(i); 13213 if (filter.match(resolver, intent, true, TAG) >= 0) { 13214 if (cur == null) { 13215 cur = new ArrayList<Intent>(); 13216 } 13217 cur.add(intent); 13218 } 13219 } 13220 return cur; 13221 } 13222 13223 boolean isPendingBroadcastProcessLocked(int pid) { 13224 return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid) 13225 || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid); 13226 } 13227 13228 void skipPendingBroadcastLocked(int pid) { 13229 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 13230 for (BroadcastQueue queue : mBroadcastQueues) { 13231 queue.skipPendingBroadcastLocked(pid); 13232 } 13233 } 13234 13235 // The app just attached; send any pending broadcasts that it should receive 13236 boolean sendPendingBroadcastsLocked(ProcessRecord app) { 13237 boolean didSomething = false; 13238 for (BroadcastQueue queue : mBroadcastQueues) { 13239 didSomething |= queue.sendPendingBroadcastsLocked(app); 13240 } 13241 return didSomething; 13242 } 13243 13244 public Intent registerReceiver(IApplicationThread caller, String callerPackage, 13245 IIntentReceiver receiver, IntentFilter filter, String permission, int userId) { 13246 enforceNotIsolatedCaller("registerReceiver"); 13247 int callingUid; 13248 int callingPid; 13249 synchronized(this) { 13250 ProcessRecord callerApp = null; 13251 if (caller != null) { 13252 callerApp = getRecordForAppLocked(caller); 13253 if (callerApp == null) { 13254 throw new SecurityException( 13255 "Unable to find app for caller " + caller 13256 + " (pid=" + Binder.getCallingPid() 13257 + ") when registering receiver " + receiver); 13258 } 13259 if (callerApp.info.uid != Process.SYSTEM_UID && 13260 !callerApp.pkgList.containsKey(callerPackage) && 13261 !"android".equals(callerPackage)) { 13262 throw new SecurityException("Given caller package " + callerPackage 13263 + " is not running in process " + callerApp); 13264 } 13265 callingUid = callerApp.info.uid; 13266 callingPid = callerApp.pid; 13267 } else { 13268 callerPackage = null; 13269 callingUid = Binder.getCallingUid(); 13270 callingPid = Binder.getCallingPid(); 13271 } 13272 13273 userId = this.handleIncomingUser(callingPid, callingUid, userId, 13274 true, true, "registerReceiver", callerPackage); 13275 13276 List allSticky = null; 13277 13278 // Look for any matching sticky broadcasts... 13279 Iterator actions = filter.actionsIterator(); 13280 if (actions != null) { 13281 while (actions.hasNext()) { 13282 String action = (String)actions.next(); 13283 allSticky = getStickiesLocked(action, filter, allSticky, 13284 UserHandle.USER_ALL); 13285 allSticky = getStickiesLocked(action, filter, allSticky, 13286 UserHandle.getUserId(callingUid)); 13287 } 13288 } else { 13289 allSticky = getStickiesLocked(null, filter, allSticky, 13290 UserHandle.USER_ALL); 13291 allSticky = getStickiesLocked(null, filter, allSticky, 13292 UserHandle.getUserId(callingUid)); 13293 } 13294 13295 // The first sticky in the list is returned directly back to 13296 // the client. 13297 Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null; 13298 13299 if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter 13300 + ": " + sticky); 13301 13302 if (receiver == null) { 13303 return sticky; 13304 } 13305 13306 ReceiverList rl 13307 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder()); 13308 if (rl == null) { 13309 rl = new ReceiverList(this, callerApp, callingPid, callingUid, 13310 userId, receiver); 13311 if (rl.app != null) { 13312 rl.app.receivers.add(rl); 13313 } else { 13314 try { 13315 receiver.asBinder().linkToDeath(rl, 0); 13316 } catch (RemoteException e) { 13317 return sticky; 13318 } 13319 rl.linkedToDeath = true; 13320 } 13321 mRegisteredReceivers.put(receiver.asBinder(), rl); 13322 } else if (rl.uid != callingUid) { 13323 throw new IllegalArgumentException( 13324 "Receiver requested to register for uid " + callingUid 13325 + " was previously registered for uid " + rl.uid); 13326 } else if (rl.pid != callingPid) { 13327 throw new IllegalArgumentException( 13328 "Receiver requested to register for pid " + callingPid 13329 + " was previously registered for pid " + rl.pid); 13330 } else if (rl.userId != userId) { 13331 throw new IllegalArgumentException( 13332 "Receiver requested to register for user " + userId 13333 + " was previously registered for user " + rl.userId); 13334 } 13335 BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage, 13336 permission, callingUid, userId); 13337 rl.add(bf); 13338 if (!bf.debugCheck()) { 13339 Slog.w(TAG, "==> For Dynamic broadast"); 13340 } 13341 mReceiverResolver.addFilter(bf); 13342 13343 // Enqueue broadcasts for all existing stickies that match 13344 // this filter. 13345 if (allSticky != null) { 13346 ArrayList receivers = new ArrayList(); 13347 receivers.add(bf); 13348 13349 int N = allSticky.size(); 13350 for (int i=0; i<N; i++) { 13351 Intent intent = (Intent)allSticky.get(i); 13352 BroadcastQueue queue = broadcastQueueForIntent(intent); 13353 BroadcastRecord r = new BroadcastRecord(queue, intent, null, 13354 null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0, 13355 null, null, false, true, true, -1); 13356 queue.enqueueParallelBroadcastLocked(r); 13357 queue.scheduleBroadcastsLocked(); 13358 } 13359 } 13360 13361 return sticky; 13362 } 13363 } 13364 13365 public void unregisterReceiver(IIntentReceiver receiver) { 13366 if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver); 13367 13368 final long origId = Binder.clearCallingIdentity(); 13369 try { 13370 boolean doTrim = false; 13371 13372 synchronized(this) { 13373 ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder()); 13374 if (rl != null) { 13375 if (rl.curBroadcast != null) { 13376 BroadcastRecord r = rl.curBroadcast; 13377 final boolean doNext = finishReceiverLocked( 13378 receiver.asBinder(), r.resultCode, r.resultData, 13379 r.resultExtras, r.resultAbort); 13380 if (doNext) { 13381 doTrim = true; 13382 r.queue.processNextBroadcast(false); 13383 } 13384 } 13385 13386 if (rl.app != null) { 13387 rl.app.receivers.remove(rl); 13388 } 13389 removeReceiverLocked(rl); 13390 if (rl.linkedToDeath) { 13391 rl.linkedToDeath = false; 13392 rl.receiver.asBinder().unlinkToDeath(rl, 0); 13393 } 13394 } 13395 } 13396 13397 // If we actually concluded any broadcasts, we might now be able 13398 // to trim the recipients' apps from our working set 13399 if (doTrim) { 13400 trimApplications(); 13401 return; 13402 } 13403 13404 } finally { 13405 Binder.restoreCallingIdentity(origId); 13406 } 13407 } 13408 13409 void removeReceiverLocked(ReceiverList rl) { 13410 mRegisteredReceivers.remove(rl.receiver.asBinder()); 13411 int N = rl.size(); 13412 for (int i=0; i<N; i++) { 13413 mReceiverResolver.removeFilter(rl.get(i)); 13414 } 13415 } 13416 13417 private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) { 13418 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 13419 ProcessRecord r = mLruProcesses.get(i); 13420 if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) { 13421 try { 13422 r.thread.dispatchPackageBroadcast(cmd, packages); 13423 } catch (RemoteException ex) { 13424 } 13425 } 13426 } 13427 } 13428 13429 private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType, 13430 int[] users) { 13431 List<ResolveInfo> receivers = null; 13432 try { 13433 HashSet<ComponentName> singleUserReceivers = null; 13434 boolean scannedFirstReceivers = false; 13435 for (int user : users) { 13436 List<ResolveInfo> newReceivers = AppGlobals.getPackageManager() 13437 .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user); 13438 if (user != 0 && newReceivers != null) { 13439 // If this is not the primary user, we need to check for 13440 // any receivers that should be filtered out. 13441 for (int i=0; i<newReceivers.size(); i++) { 13442 ResolveInfo ri = newReceivers.get(i); 13443 if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) { 13444 newReceivers.remove(i); 13445 i--; 13446 } 13447 } 13448 } 13449 if (newReceivers != null && newReceivers.size() == 0) { 13450 newReceivers = null; 13451 } 13452 if (receivers == null) { 13453 receivers = newReceivers; 13454 } else if (newReceivers != null) { 13455 // We need to concatenate the additional receivers 13456 // found with what we have do far. This would be easy, 13457 // but we also need to de-dup any receivers that are 13458 // singleUser. 13459 if (!scannedFirstReceivers) { 13460 // Collect any single user receivers we had already retrieved. 13461 scannedFirstReceivers = true; 13462 for (int i=0; i<receivers.size(); i++) { 13463 ResolveInfo ri = receivers.get(i); 13464 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 13465 ComponentName cn = new ComponentName( 13466 ri.activityInfo.packageName, ri.activityInfo.name); 13467 if (singleUserReceivers == null) { 13468 singleUserReceivers = new HashSet<ComponentName>(); 13469 } 13470 singleUserReceivers.add(cn); 13471 } 13472 } 13473 } 13474 // Add the new results to the existing results, tracking 13475 // and de-dupping single user receivers. 13476 for (int i=0; i<newReceivers.size(); i++) { 13477 ResolveInfo ri = newReceivers.get(i); 13478 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 13479 ComponentName cn = new ComponentName( 13480 ri.activityInfo.packageName, ri.activityInfo.name); 13481 if (singleUserReceivers == null) { 13482 singleUserReceivers = new HashSet<ComponentName>(); 13483 } 13484 if (!singleUserReceivers.contains(cn)) { 13485 singleUserReceivers.add(cn); 13486 receivers.add(ri); 13487 } 13488 } else { 13489 receivers.add(ri); 13490 } 13491 } 13492 } 13493 } 13494 } catch (RemoteException ex) { 13495 // pm is in same process, this will never happen. 13496 } 13497 return receivers; 13498 } 13499 13500 private final int broadcastIntentLocked(ProcessRecord callerApp, 13501 String callerPackage, Intent intent, String resolvedType, 13502 IIntentReceiver resultTo, int resultCode, String resultData, 13503 Bundle map, String requiredPermission, int appOp, 13504 boolean ordered, boolean sticky, int callingPid, int callingUid, 13505 int userId) { 13506 intent = new Intent(intent); 13507 13508 // By default broadcasts do not go to stopped apps. 13509 intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES); 13510 13511 if (DEBUG_BROADCAST_LIGHT) Slog.v( 13512 TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent 13513 + " ordered=" + ordered + " userid=" + userId); 13514 if ((resultTo != null) && !ordered) { 13515 Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!"); 13516 } 13517 13518 userId = handleIncomingUser(callingPid, callingUid, userId, 13519 true, false, "broadcast", callerPackage); 13520 13521 // Make sure that the user who is receiving this broadcast is started. 13522 // If not, we will just skip it. 13523 if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) { 13524 if (callingUid != Process.SYSTEM_UID || (intent.getFlags() 13525 & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) { 13526 Slog.w(TAG, "Skipping broadcast of " + intent 13527 + ": user " + userId + " is stopped"); 13528 return ActivityManager.BROADCAST_SUCCESS; 13529 } 13530 } 13531 13532 /* 13533 * Prevent non-system code (defined here to be non-persistent 13534 * processes) from sending protected broadcasts. 13535 */ 13536 int callingAppId = UserHandle.getAppId(callingUid); 13537 if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID 13538 || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID || 13539 callingUid == 0) { 13540 // Always okay. 13541 } else if (callerApp == null || !callerApp.persistent) { 13542 try { 13543 if (AppGlobals.getPackageManager().isProtectedBroadcast( 13544 intent.getAction())) { 13545 String msg = "Permission Denial: not allowed to send broadcast " 13546 + intent.getAction() + " from pid=" 13547 + callingPid + ", uid=" + callingUid; 13548 Slog.w(TAG, msg); 13549 throw new SecurityException(msg); 13550 } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) { 13551 // Special case for compatibility: we don't want apps to send this, 13552 // but historically it has not been protected and apps may be using it 13553 // to poke their own app widget. So, instead of making it protected, 13554 // just limit it to the caller. 13555 if (callerApp == null) { 13556 String msg = "Permission Denial: not allowed to send broadcast " 13557 + intent.getAction() + " from unknown caller."; 13558 Slog.w(TAG, msg); 13559 throw new SecurityException(msg); 13560 } else if (intent.getComponent() != null) { 13561 // They are good enough to send to an explicit component... verify 13562 // it is being sent to the calling app. 13563 if (!intent.getComponent().getPackageName().equals( 13564 callerApp.info.packageName)) { 13565 String msg = "Permission Denial: not allowed to send broadcast " 13566 + intent.getAction() + " to " 13567 + intent.getComponent().getPackageName() + " from " 13568 + callerApp.info.packageName; 13569 Slog.w(TAG, msg); 13570 throw new SecurityException(msg); 13571 } 13572 } else { 13573 // Limit broadcast to their own package. 13574 intent.setPackage(callerApp.info.packageName); 13575 } 13576 } 13577 } catch (RemoteException e) { 13578 Slog.w(TAG, "Remote exception", e); 13579 return ActivityManager.BROADCAST_SUCCESS; 13580 } 13581 } 13582 13583 // Handle special intents: if this broadcast is from the package 13584 // manager about a package being removed, we need to remove all of 13585 // its activities from the history stack. 13586 final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals( 13587 intent.getAction()); 13588 if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction()) 13589 || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction()) 13590 || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction()) 13591 || uidRemoved) { 13592 if (checkComponentPermission( 13593 android.Manifest.permission.BROADCAST_PACKAGE_REMOVED, 13594 callingPid, callingUid, -1, true) 13595 == PackageManager.PERMISSION_GRANTED) { 13596 if (uidRemoved) { 13597 final Bundle intentExtras = intent.getExtras(); 13598 final int uid = intentExtras != null 13599 ? intentExtras.getInt(Intent.EXTRA_UID) : -1; 13600 if (uid >= 0) { 13601 BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics(); 13602 synchronized (bs) { 13603 bs.removeUidStatsLocked(uid); 13604 } 13605 mAppOpsService.uidRemoved(uid); 13606 } 13607 } else { 13608 // If resources are unavailable just force stop all 13609 // those packages and flush the attribute cache as well. 13610 if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) { 13611 String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 13612 if (list != null && (list.length > 0)) { 13613 for (String pkg : list) { 13614 forceStopPackageLocked(pkg, -1, false, true, true, false, false, userId, 13615 "storage unmount"); 13616 } 13617 sendPackageBroadcastLocked( 13618 IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId); 13619 } 13620 } else { 13621 Uri data = intent.getData(); 13622 String ssp; 13623 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 13624 boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals( 13625 intent.getAction()); 13626 boolean fullUninstall = removed && 13627 !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false); 13628 if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) { 13629 forceStopPackageLocked(ssp, UserHandle.getAppId( 13630 intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true, 13631 false, fullUninstall, userId, 13632 removed ? "pkg removed" : "pkg changed"); 13633 } 13634 if (removed) { 13635 sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED, 13636 new String[] {ssp}, userId); 13637 if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) { 13638 mAppOpsService.packageRemoved( 13639 intent.getIntExtra(Intent.EXTRA_UID, -1), ssp); 13640 13641 // Remove all permissions granted from/to this package 13642 removeUriPermissionsForPackageLocked(ssp, userId, true); 13643 } 13644 } 13645 } 13646 } 13647 } 13648 } else { 13649 String msg = "Permission Denial: " + intent.getAction() 13650 + " broadcast from " + callerPackage + " (pid=" + callingPid 13651 + ", uid=" + callingUid + ")" 13652 + " requires " 13653 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED; 13654 Slog.w(TAG, msg); 13655 throw new SecurityException(msg); 13656 } 13657 13658 // Special case for adding a package: by default turn on compatibility 13659 // mode. 13660 } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) { 13661 Uri data = intent.getData(); 13662 String ssp; 13663 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 13664 mCompatModePackages.handlePackageAddedLocked(ssp, 13665 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)); 13666 } 13667 } 13668 13669 /* 13670 * If this is the time zone changed action, queue up a message that will reset the timezone 13671 * of all currently running processes. This message will get queued up before the broadcast 13672 * happens. 13673 */ 13674 if (Intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) { 13675 mHandler.sendEmptyMessage(UPDATE_TIME_ZONE); 13676 } 13677 13678 /* 13679 * If the user set the time, let all running processes know. 13680 */ 13681 if (Intent.ACTION_TIME_CHANGED.equals(intent.getAction())) { 13682 final int is24Hour = intent.getBooleanExtra( 13683 Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1 : 0; 13684 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0)); 13685 } 13686 13687 if (Intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) { 13688 mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG); 13689 } 13690 13691 if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) { 13692 ProxyProperties proxy = intent.getParcelableExtra("proxy"); 13693 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy)); 13694 } 13695 13696 // Add to the sticky list if requested. 13697 if (sticky) { 13698 if (checkPermission(android.Manifest.permission.BROADCAST_STICKY, 13699 callingPid, callingUid) 13700 != PackageManager.PERMISSION_GRANTED) { 13701 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid=" 13702 + callingPid + ", uid=" + callingUid 13703 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 13704 Slog.w(TAG, msg); 13705 throw new SecurityException(msg); 13706 } 13707 if (requiredPermission != null) { 13708 Slog.w(TAG, "Can't broadcast sticky intent " + intent 13709 + " and enforce permission " + requiredPermission); 13710 return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION; 13711 } 13712 if (intent.getComponent() != null) { 13713 throw new SecurityException( 13714 "Sticky broadcasts can't target a specific component"); 13715 } 13716 // We use userId directly here, since the "all" target is maintained 13717 // as a separate set of sticky broadcasts. 13718 if (userId != UserHandle.USER_ALL) { 13719 // But first, if this is not a broadcast to all users, then 13720 // make sure it doesn't conflict with an existing broadcast to 13721 // all users. 13722 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get( 13723 UserHandle.USER_ALL); 13724 if (stickies != null) { 13725 ArrayList<Intent> list = stickies.get(intent.getAction()); 13726 if (list != null) { 13727 int N = list.size(); 13728 int i; 13729 for (i=0; i<N; i++) { 13730 if (intent.filterEquals(list.get(i))) { 13731 throw new IllegalArgumentException( 13732 "Sticky broadcast " + intent + " for user " 13733 + userId + " conflicts with existing global broadcast"); 13734 } 13735 } 13736 } 13737 } 13738 } 13739 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 13740 if (stickies == null) { 13741 stickies = new ArrayMap<String, ArrayList<Intent>>(); 13742 mStickyBroadcasts.put(userId, stickies); 13743 } 13744 ArrayList<Intent> list = stickies.get(intent.getAction()); 13745 if (list == null) { 13746 list = new ArrayList<Intent>(); 13747 stickies.put(intent.getAction(), list); 13748 } 13749 int N = list.size(); 13750 int i; 13751 for (i=0; i<N; i++) { 13752 if (intent.filterEquals(list.get(i))) { 13753 // This sticky already exists, replace it. 13754 list.set(i, new Intent(intent)); 13755 break; 13756 } 13757 } 13758 if (i >= N) { 13759 list.add(new Intent(intent)); 13760 } 13761 } 13762 13763 int[] users; 13764 if (userId == UserHandle.USER_ALL) { 13765 // Caller wants broadcast to go to all started users. 13766 users = mStartedUserArray; 13767 } else { 13768 // Caller wants broadcast to go to one specific user. 13769 users = new int[] {userId}; 13770 } 13771 13772 // Figure out who all will receive this broadcast. 13773 List receivers = null; 13774 List<BroadcastFilter> registeredReceivers = null; 13775 // Need to resolve the intent to interested receivers... 13776 if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) 13777 == 0) { 13778 receivers = collectReceiverComponents(intent, resolvedType, users); 13779 } 13780 if (intent.getComponent() == null) { 13781 registeredReceivers = mReceiverResolver.queryIntent(intent, 13782 resolvedType, false, userId); 13783 } 13784 13785 final boolean replacePending = 13786 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0; 13787 13788 if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction() 13789 + " replacePending=" + replacePending); 13790 13791 int NR = registeredReceivers != null ? registeredReceivers.size() : 0; 13792 if (!ordered && NR > 0) { 13793 // If we are not serializing this broadcast, then send the 13794 // registered receivers separately so they don't wait for the 13795 // components to be launched. 13796 final BroadcastQueue queue = broadcastQueueForIntent(intent); 13797 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 13798 callerPackage, callingPid, callingUid, resolvedType, requiredPermission, 13799 appOp, registeredReceivers, resultTo, resultCode, resultData, map, 13800 ordered, sticky, false, userId); 13801 if (DEBUG_BROADCAST) Slog.v( 13802 TAG, "Enqueueing parallel broadcast " + r); 13803 final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r); 13804 if (!replaced) { 13805 queue.enqueueParallelBroadcastLocked(r); 13806 queue.scheduleBroadcastsLocked(); 13807 } 13808 registeredReceivers = null; 13809 NR = 0; 13810 } 13811 13812 // Merge into one list. 13813 int ir = 0; 13814 if (receivers != null) { 13815 // A special case for PACKAGE_ADDED: do not allow the package 13816 // being added to see this broadcast. This prevents them from 13817 // using this as a back door to get run as soon as they are 13818 // installed. Maybe in the future we want to have a special install 13819 // broadcast or such for apps, but we'd like to deliberately make 13820 // this decision. 13821 String skipPackages[] = null; 13822 if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction()) 13823 || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction()) 13824 || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) { 13825 Uri data = intent.getData(); 13826 if (data != null) { 13827 String pkgName = data.getSchemeSpecificPart(); 13828 if (pkgName != null) { 13829 skipPackages = new String[] { pkgName }; 13830 } 13831 } 13832 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) { 13833 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 13834 } 13835 if (skipPackages != null && (skipPackages.length > 0)) { 13836 for (String skipPackage : skipPackages) { 13837 if (skipPackage != null) { 13838 int NT = receivers.size(); 13839 for (int it=0; it<NT; it++) { 13840 ResolveInfo curt = (ResolveInfo)receivers.get(it); 13841 if (curt.activityInfo.packageName.equals(skipPackage)) { 13842 receivers.remove(it); 13843 it--; 13844 NT--; 13845 } 13846 } 13847 } 13848 } 13849 } 13850 13851 int NT = receivers != null ? receivers.size() : 0; 13852 int it = 0; 13853 ResolveInfo curt = null; 13854 BroadcastFilter curr = null; 13855 while (it < NT && ir < NR) { 13856 if (curt == null) { 13857 curt = (ResolveInfo)receivers.get(it); 13858 } 13859 if (curr == null) { 13860 curr = registeredReceivers.get(ir); 13861 } 13862 if (curr.getPriority() >= curt.priority) { 13863 // Insert this broadcast record into the final list. 13864 receivers.add(it, curr); 13865 ir++; 13866 curr = null; 13867 it++; 13868 NT++; 13869 } else { 13870 // Skip to the next ResolveInfo in the final list. 13871 it++; 13872 curt = null; 13873 } 13874 } 13875 } 13876 while (ir < NR) { 13877 if (receivers == null) { 13878 receivers = new ArrayList(); 13879 } 13880 receivers.add(registeredReceivers.get(ir)); 13881 ir++; 13882 } 13883 13884 if ((receivers != null && receivers.size() > 0) 13885 || resultTo != null) { 13886 BroadcastQueue queue = broadcastQueueForIntent(intent); 13887 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 13888 callerPackage, callingPid, callingUid, resolvedType, 13889 requiredPermission, appOp, receivers, resultTo, resultCode, 13890 resultData, map, ordered, sticky, false, userId); 13891 if (DEBUG_BROADCAST) Slog.v( 13892 TAG, "Enqueueing ordered broadcast " + r 13893 + ": prev had " + queue.mOrderedBroadcasts.size()); 13894 if (DEBUG_BROADCAST) { 13895 int seq = r.intent.getIntExtra("seq", -1); 13896 Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq); 13897 } 13898 boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r); 13899 if (!replaced) { 13900 queue.enqueueOrderedBroadcastLocked(r); 13901 queue.scheduleBroadcastsLocked(); 13902 } 13903 } 13904 13905 return ActivityManager.BROADCAST_SUCCESS; 13906 } 13907 13908 final Intent verifyBroadcastLocked(Intent intent) { 13909 // Refuse possible leaked file descriptors 13910 if (intent != null && intent.hasFileDescriptors() == true) { 13911 throw new IllegalArgumentException("File descriptors passed in Intent"); 13912 } 13913 13914 int flags = intent.getFlags(); 13915 13916 if (!mProcessesReady) { 13917 // if the caller really truly claims to know what they're doing, go 13918 // ahead and allow the broadcast without launching any receivers 13919 if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) { 13920 intent = new Intent(intent); 13921 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 13922 } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) { 13923 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent 13924 + " before boot completion"); 13925 throw new IllegalStateException("Cannot broadcast before boot completed"); 13926 } 13927 } 13928 13929 if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 13930 throw new IllegalArgumentException( 13931 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 13932 } 13933 13934 return intent; 13935 } 13936 13937 public final int broadcastIntent(IApplicationThread caller, 13938 Intent intent, String resolvedType, IIntentReceiver resultTo, 13939 int resultCode, String resultData, Bundle map, 13940 String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) { 13941 enforceNotIsolatedCaller("broadcastIntent"); 13942 synchronized(this) { 13943 intent = verifyBroadcastLocked(intent); 13944 13945 final ProcessRecord callerApp = getRecordForAppLocked(caller); 13946 final int callingPid = Binder.getCallingPid(); 13947 final int callingUid = Binder.getCallingUid(); 13948 final long origId = Binder.clearCallingIdentity(); 13949 int res = broadcastIntentLocked(callerApp, 13950 callerApp != null ? callerApp.info.packageName : null, 13951 intent, resolvedType, resultTo, 13952 resultCode, resultData, map, requiredPermission, appOp, serialized, sticky, 13953 callingPid, callingUid, userId); 13954 Binder.restoreCallingIdentity(origId); 13955 return res; 13956 } 13957 } 13958 13959 int broadcastIntentInPackage(String packageName, int uid, 13960 Intent intent, String resolvedType, IIntentReceiver resultTo, 13961 int resultCode, String resultData, Bundle map, 13962 String requiredPermission, boolean serialized, boolean sticky, int userId) { 13963 synchronized(this) { 13964 intent = verifyBroadcastLocked(intent); 13965 13966 final long origId = Binder.clearCallingIdentity(); 13967 int res = broadcastIntentLocked(null, packageName, intent, resolvedType, 13968 resultTo, resultCode, resultData, map, requiredPermission, 13969 AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId); 13970 Binder.restoreCallingIdentity(origId); 13971 return res; 13972 } 13973 } 13974 13975 public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) { 13976 // Refuse possible leaked file descriptors 13977 if (intent != null && intent.hasFileDescriptors() == true) { 13978 throw new IllegalArgumentException("File descriptors passed in Intent"); 13979 } 13980 13981 userId = handleIncomingUser(Binder.getCallingPid(), 13982 Binder.getCallingUid(), userId, true, false, "removeStickyBroadcast", null); 13983 13984 synchronized(this) { 13985 if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY) 13986 != PackageManager.PERMISSION_GRANTED) { 13987 String msg = "Permission Denial: unbroadcastIntent() from pid=" 13988 + Binder.getCallingPid() 13989 + ", uid=" + Binder.getCallingUid() 13990 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 13991 Slog.w(TAG, msg); 13992 throw new SecurityException(msg); 13993 } 13994 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 13995 if (stickies != null) { 13996 ArrayList<Intent> list = stickies.get(intent.getAction()); 13997 if (list != null) { 13998 int N = list.size(); 13999 int i; 14000 for (i=0; i<N; i++) { 14001 if (intent.filterEquals(list.get(i))) { 14002 list.remove(i); 14003 break; 14004 } 14005 } 14006 if (list.size() <= 0) { 14007 stickies.remove(intent.getAction()); 14008 } 14009 } 14010 if (stickies.size() <= 0) { 14011 mStickyBroadcasts.remove(userId); 14012 } 14013 } 14014 } 14015 } 14016 14017 private final boolean finishReceiverLocked(IBinder receiver, int resultCode, 14018 String resultData, Bundle resultExtras, boolean resultAbort) { 14019 final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver); 14020 if (r == null) { 14021 Slog.w(TAG, "finishReceiver called but not found on queue"); 14022 return false; 14023 } 14024 14025 return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false); 14026 } 14027 14028 void backgroundServicesFinishedLocked(int userId) { 14029 for (BroadcastQueue queue : mBroadcastQueues) { 14030 queue.backgroundServicesFinishedLocked(userId); 14031 } 14032 } 14033 14034 public void finishReceiver(IBinder who, int resultCode, String resultData, 14035 Bundle resultExtras, boolean resultAbort) { 14036 if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who); 14037 14038 // Refuse possible leaked file descriptors 14039 if (resultExtras != null && resultExtras.hasFileDescriptors()) { 14040 throw new IllegalArgumentException("File descriptors passed in Bundle"); 14041 } 14042 14043 final long origId = Binder.clearCallingIdentity(); 14044 try { 14045 boolean doNext = false; 14046 BroadcastRecord r; 14047 14048 synchronized(this) { 14049 r = broadcastRecordForReceiverLocked(who); 14050 if (r != null) { 14051 doNext = r.queue.finishReceiverLocked(r, resultCode, 14052 resultData, resultExtras, resultAbort, true); 14053 } 14054 } 14055 14056 if (doNext) { 14057 r.queue.processNextBroadcast(false); 14058 } 14059 trimApplications(); 14060 } finally { 14061 Binder.restoreCallingIdentity(origId); 14062 } 14063 } 14064 14065 // ========================================================= 14066 // INSTRUMENTATION 14067 // ========================================================= 14068 14069 public boolean startInstrumentation(ComponentName className, 14070 String profileFile, int flags, Bundle arguments, 14071 IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection, 14072 int userId) { 14073 enforceNotIsolatedCaller("startInstrumentation"); 14074 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 14075 userId, false, true, "startInstrumentation", null); 14076 // Refuse possible leaked file descriptors 14077 if (arguments != null && arguments.hasFileDescriptors()) { 14078 throw new IllegalArgumentException("File descriptors passed in Bundle"); 14079 } 14080 14081 synchronized(this) { 14082 InstrumentationInfo ii = null; 14083 ApplicationInfo ai = null; 14084 try { 14085 ii = mContext.getPackageManager().getInstrumentationInfo( 14086 className, STOCK_PM_FLAGS); 14087 ai = AppGlobals.getPackageManager().getApplicationInfo( 14088 ii.targetPackage, STOCK_PM_FLAGS, userId); 14089 } catch (PackageManager.NameNotFoundException e) { 14090 } catch (RemoteException e) { 14091 } 14092 if (ii == null) { 14093 reportStartInstrumentationFailure(watcher, className, 14094 "Unable to find instrumentation info for: " + className); 14095 return false; 14096 } 14097 if (ai == null) { 14098 reportStartInstrumentationFailure(watcher, className, 14099 "Unable to find instrumentation target package: " + ii.targetPackage); 14100 return false; 14101 } 14102 14103 int match = mContext.getPackageManager().checkSignatures( 14104 ii.targetPackage, ii.packageName); 14105 if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) { 14106 String msg = "Permission Denial: starting instrumentation " 14107 + className + " from pid=" 14108 + Binder.getCallingPid() 14109 + ", uid=" + Binder.getCallingPid() 14110 + " not allowed because package " + ii.packageName 14111 + " does not have a signature matching the target " 14112 + ii.targetPackage; 14113 reportStartInstrumentationFailure(watcher, className, msg); 14114 throw new SecurityException(msg); 14115 } 14116 14117 final long origId = Binder.clearCallingIdentity(); 14118 // Instrumentation can kill and relaunch even persistent processes 14119 forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId, 14120 "start instr"); 14121 ProcessRecord app = addAppLocked(ai, false); 14122 app.instrumentationClass = className; 14123 app.instrumentationInfo = ai; 14124 app.instrumentationProfileFile = profileFile; 14125 app.instrumentationArguments = arguments; 14126 app.instrumentationWatcher = watcher; 14127 app.instrumentationUiAutomationConnection = uiAutomationConnection; 14128 app.instrumentationResultClass = className; 14129 Binder.restoreCallingIdentity(origId); 14130 } 14131 14132 return true; 14133 } 14134 14135 /** 14136 * Report errors that occur while attempting to start Instrumentation. Always writes the 14137 * error to the logs, but if somebody is watching, send the report there too. This enables 14138 * the "am" command to report errors with more information. 14139 * 14140 * @param watcher The IInstrumentationWatcher. Null if there isn't one. 14141 * @param cn The component name of the instrumentation. 14142 * @param report The error report. 14143 */ 14144 private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher, 14145 ComponentName cn, String report) { 14146 Slog.w(TAG, report); 14147 try { 14148 if (watcher != null) { 14149 Bundle results = new Bundle(); 14150 results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService"); 14151 results.putString("Error", report); 14152 watcher.instrumentationStatus(cn, -1, results); 14153 } 14154 } catch (RemoteException e) { 14155 Slog.w(TAG, e); 14156 } 14157 } 14158 14159 void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) { 14160 if (app.instrumentationWatcher != null) { 14161 try { 14162 // NOTE: IInstrumentationWatcher *must* be oneway here 14163 app.instrumentationWatcher.instrumentationFinished( 14164 app.instrumentationClass, 14165 resultCode, 14166 results); 14167 } catch (RemoteException e) { 14168 } 14169 } 14170 if (app.instrumentationUiAutomationConnection != null) { 14171 try { 14172 app.instrumentationUiAutomationConnection.shutdown(); 14173 } catch (RemoteException re) { 14174 /* ignore */ 14175 } 14176 // Only a UiAutomation can set this flag and now that 14177 // it is finished we make sure it is reset to its default. 14178 mUserIsMonkey = false; 14179 } 14180 app.instrumentationWatcher = null; 14181 app.instrumentationUiAutomationConnection = null; 14182 app.instrumentationClass = null; 14183 app.instrumentationInfo = null; 14184 app.instrumentationProfileFile = null; 14185 app.instrumentationArguments = null; 14186 14187 forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId, 14188 "finished inst"); 14189 } 14190 14191 public void finishInstrumentation(IApplicationThread target, 14192 int resultCode, Bundle results) { 14193 int userId = UserHandle.getCallingUserId(); 14194 // Refuse possible leaked file descriptors 14195 if (results != null && results.hasFileDescriptors()) { 14196 throw new IllegalArgumentException("File descriptors passed in Intent"); 14197 } 14198 14199 synchronized(this) { 14200 ProcessRecord app = getRecordForAppLocked(target); 14201 if (app == null) { 14202 Slog.w(TAG, "finishInstrumentation: no app for " + target); 14203 return; 14204 } 14205 final long origId = Binder.clearCallingIdentity(); 14206 finishInstrumentationLocked(app, resultCode, results); 14207 Binder.restoreCallingIdentity(origId); 14208 } 14209 } 14210 14211 // ========================================================= 14212 // CONFIGURATION 14213 // ========================================================= 14214 14215 public ConfigurationInfo getDeviceConfigurationInfo() { 14216 ConfigurationInfo config = new ConfigurationInfo(); 14217 synchronized (this) { 14218 config.reqTouchScreen = mConfiguration.touchscreen; 14219 config.reqKeyboardType = mConfiguration.keyboard; 14220 config.reqNavigation = mConfiguration.navigation; 14221 if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD 14222 || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) { 14223 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV; 14224 } 14225 if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED 14226 && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) { 14227 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD; 14228 } 14229 config.reqGlEsVersion = GL_ES_VERSION; 14230 } 14231 return config; 14232 } 14233 14234 ActivityStack getFocusedStack() { 14235 return mStackSupervisor.getFocusedStack(); 14236 } 14237 14238 public Configuration getConfiguration() { 14239 Configuration ci; 14240 synchronized(this) { 14241 ci = new Configuration(mConfiguration); 14242 } 14243 return ci; 14244 } 14245 14246 public void updatePersistentConfiguration(Configuration values) { 14247 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 14248 "updateConfiguration()"); 14249 enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS, 14250 "updateConfiguration()"); 14251 if (values == null) { 14252 throw new NullPointerException("Configuration must not be null"); 14253 } 14254 14255 synchronized(this) { 14256 final long origId = Binder.clearCallingIdentity(); 14257 updateConfigurationLocked(values, null, true, false); 14258 Binder.restoreCallingIdentity(origId); 14259 } 14260 } 14261 14262 public void updateConfiguration(Configuration values) { 14263 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 14264 "updateConfiguration()"); 14265 14266 synchronized(this) { 14267 if (values == null && mWindowManager != null) { 14268 // sentinel: fetch the current configuration from the window manager 14269 values = mWindowManager.computeNewConfiguration(); 14270 } 14271 14272 if (mWindowManager != null) { 14273 mProcessList.applyDisplaySize(mWindowManager); 14274 } 14275 14276 final long origId = Binder.clearCallingIdentity(); 14277 if (values != null) { 14278 Settings.System.clearConfiguration(values); 14279 } 14280 updateConfigurationLocked(values, null, false, false); 14281 Binder.restoreCallingIdentity(origId); 14282 } 14283 } 14284 14285 /** 14286 * Do either or both things: (1) change the current configuration, and (2) 14287 * make sure the given activity is running with the (now) current 14288 * configuration. Returns true if the activity has been left running, or 14289 * false if <var>starting</var> is being destroyed to match the new 14290 * configuration. 14291 * @param persistent TODO 14292 */ 14293 boolean updateConfigurationLocked(Configuration values, 14294 ActivityRecord starting, boolean persistent, boolean initLocale) { 14295 int changes = 0; 14296 14297 if (values != null) { 14298 Configuration newConfig = new Configuration(mConfiguration); 14299 changes = newConfig.updateFrom(values); 14300 if (changes != 0) { 14301 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) { 14302 Slog.i(TAG, "Updating configuration to: " + values); 14303 } 14304 14305 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes); 14306 14307 if (values.locale != null && !initLocale) { 14308 saveLocaleLocked(values.locale, 14309 !values.locale.equals(mConfiguration.locale), 14310 values.userSetLocale); 14311 } 14312 14313 mConfigurationSeq++; 14314 if (mConfigurationSeq <= 0) { 14315 mConfigurationSeq = 1; 14316 } 14317 newConfig.seq = mConfigurationSeq; 14318 mConfiguration = newConfig; 14319 Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig); 14320 14321 final Configuration configCopy = new Configuration(mConfiguration); 14322 14323 // TODO: If our config changes, should we auto dismiss any currently 14324 // showing dialogs? 14325 mShowDialogs = shouldShowDialogs(newConfig); 14326 14327 AttributeCache ac = AttributeCache.instance(); 14328 if (ac != null) { 14329 ac.updateConfiguration(configCopy); 14330 } 14331 14332 // Make sure all resources in our process are updated 14333 // right now, so that anyone who is going to retrieve 14334 // resource values after we return will be sure to get 14335 // the new ones. This is especially important during 14336 // boot, where the first config change needs to guarantee 14337 // all resources have that config before following boot 14338 // code is executed. 14339 mSystemThread.applyConfigurationToResources(configCopy); 14340 14341 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) { 14342 Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG); 14343 msg.obj = new Configuration(configCopy); 14344 mHandler.sendMessage(msg); 14345 } 14346 14347 for (int i=mLruProcesses.size()-1; i>=0; i--) { 14348 ProcessRecord app = mLruProcesses.get(i); 14349 try { 14350 if (app.thread != null) { 14351 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc " 14352 + app.processName + " new config " + mConfiguration); 14353 app.thread.scheduleConfigurationChanged(configCopy); 14354 } 14355 } catch (Exception e) { 14356 } 14357 } 14358 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED); 14359 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 14360 | Intent.FLAG_RECEIVER_REPLACE_PENDING 14361 | Intent.FLAG_RECEIVER_FOREGROUND); 14362 broadcastIntentLocked(null, null, intent, null, null, 0, null, null, 14363 null, AppOpsManager.OP_NONE, false, false, MY_PID, 14364 Process.SYSTEM_UID, UserHandle.USER_ALL); 14365 if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) { 14366 intent = new Intent(Intent.ACTION_LOCALE_CHANGED); 14367 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 14368 broadcastIntentLocked(null, null, intent, 14369 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 14370 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 14371 } 14372 } 14373 } 14374 14375 boolean kept = true; 14376 final ActivityStack mainStack = mStackSupervisor.getFocusedStack(); 14377 // mainStack is null during startup. 14378 if (mainStack != null) { 14379 if (changes != 0 && starting == null) { 14380 // If the configuration changed, and the caller is not already 14381 // in the process of starting an activity, then find the top 14382 // activity to check if its configuration needs to change. 14383 starting = mainStack.topRunningActivityLocked(null); 14384 } 14385 14386 if (starting != null) { 14387 kept = mainStack.ensureActivityConfigurationLocked(starting, changes); 14388 // And we need to make sure at this point that all other activities 14389 // are made visible with the correct configuration. 14390 mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes); 14391 } 14392 } 14393 14394 if (values != null && mWindowManager != null) { 14395 mWindowManager.setNewConfiguration(mConfiguration); 14396 } 14397 14398 return kept; 14399 } 14400 14401 /** 14402 * Decide based on the configuration whether we should shouw the ANR, 14403 * crash, etc dialogs. The idea is that if there is no affordnace to 14404 * press the on-screen buttons, we shouldn't show the dialog. 14405 * 14406 * A thought: SystemUI might also want to get told about this, the Power 14407 * dialog / global actions also might want different behaviors. 14408 */ 14409 private static final boolean shouldShowDialogs(Configuration config) { 14410 return !(config.keyboard == Configuration.KEYBOARD_NOKEYS 14411 && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH); 14412 } 14413 14414 /** 14415 * Save the locale. You must be inside a synchronized (this) block. 14416 */ 14417 private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) { 14418 if(isDiff) { 14419 SystemProperties.set("user.language", l.getLanguage()); 14420 SystemProperties.set("user.region", l.getCountry()); 14421 } 14422 14423 if(isPersist) { 14424 SystemProperties.set("persist.sys.language", l.getLanguage()); 14425 SystemProperties.set("persist.sys.country", l.getCountry()); 14426 SystemProperties.set("persist.sys.localevar", l.getVariant()); 14427 } 14428 } 14429 14430 @Override 14431 public boolean targetTaskAffinityMatchesActivity(IBinder token, String destAffinity) { 14432 ActivityRecord srec = ActivityRecord.forToken(token); 14433 return srec != null && srec.task.affinity != null && 14434 srec.task.affinity.equals(destAffinity); 14435 } 14436 14437 public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode, 14438 Intent resultData) { 14439 14440 synchronized (this) { 14441 final ActivityStack stack = ActivityRecord.getStackLocked(token); 14442 if (stack != null) { 14443 return stack.navigateUpToLocked(token, destIntent, resultCode, resultData); 14444 } 14445 return false; 14446 } 14447 } 14448 14449 public int getLaunchedFromUid(IBinder activityToken) { 14450 ActivityRecord srec = ActivityRecord.forToken(activityToken); 14451 if (srec == null) { 14452 return -1; 14453 } 14454 return srec.launchedFromUid; 14455 } 14456 14457 public String getLaunchedFromPackage(IBinder activityToken) { 14458 ActivityRecord srec = ActivityRecord.forToken(activityToken); 14459 if (srec == null) { 14460 return null; 14461 } 14462 return srec.launchedFromPackage; 14463 } 14464 14465 // ========================================================= 14466 // LIFETIME MANAGEMENT 14467 // ========================================================= 14468 14469 // Returns which broadcast queue the app is the current [or imminent] receiver 14470 // on, or 'null' if the app is not an active broadcast recipient. 14471 private BroadcastQueue isReceivingBroadcast(ProcessRecord app) { 14472 BroadcastRecord r = app.curReceiver; 14473 if (r != null) { 14474 return r.queue; 14475 } 14476 14477 // It's not the current receiver, but it might be starting up to become one 14478 synchronized (this) { 14479 for (BroadcastQueue queue : mBroadcastQueues) { 14480 r = queue.mPendingBroadcast; 14481 if (r != null && r.curApp == app) { 14482 // found it; report which queue it's in 14483 return queue; 14484 } 14485 } 14486 } 14487 14488 return null; 14489 } 14490 14491 private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP, 14492 boolean doingAll, long now) { 14493 if (mAdjSeq == app.adjSeq) { 14494 // This adjustment has already been computed. 14495 return app.curRawAdj; 14496 } 14497 14498 if (app.thread == null) { 14499 app.adjSeq = mAdjSeq; 14500 app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 14501 app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 14502 return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ); 14503 } 14504 14505 app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN; 14506 app.adjSource = null; 14507 app.adjTarget = null; 14508 app.empty = false; 14509 app.cached = false; 14510 14511 final int activitiesSize = app.activities.size(); 14512 14513 if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) { 14514 // The max adjustment doesn't allow this app to be anything 14515 // below foreground, so it is not worth doing work for it. 14516 app.adjType = "fixed"; 14517 app.adjSeq = mAdjSeq; 14518 app.curRawAdj = app.maxAdj; 14519 app.foregroundActivities = false; 14520 app.keeping = true; 14521 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT; 14522 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT; 14523 // System process can do UI, and when they do we want to have 14524 // them trim their memory after the user leaves the UI. To 14525 // facilitate this, here we need to determine whether or not it 14526 // is currently showing UI. 14527 app.systemNoUi = true; 14528 if (app == TOP_APP) { 14529 app.systemNoUi = false; 14530 } else if (activitiesSize > 0) { 14531 for (int j = 0; j < activitiesSize; j++) { 14532 final ActivityRecord r = app.activities.get(j); 14533 if (r.visible) { 14534 app.systemNoUi = false; 14535 } 14536 } 14537 } 14538 if (!app.systemNoUi) { 14539 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI; 14540 } 14541 return (app.curAdj=app.maxAdj); 14542 } 14543 14544 app.keeping = false; 14545 app.systemNoUi = false; 14546 14547 // Determine the importance of the process, starting with most 14548 // important to least, and assign an appropriate OOM adjustment. 14549 int adj; 14550 int schedGroup; 14551 int procState; 14552 boolean foregroundActivities = false; 14553 boolean interesting = false; 14554 BroadcastQueue queue; 14555 if (app == TOP_APP) { 14556 // The last app on the list is the foreground app. 14557 adj = ProcessList.FOREGROUND_APP_ADJ; 14558 schedGroup = Process.THREAD_GROUP_DEFAULT; 14559 app.adjType = "top-activity"; 14560 foregroundActivities = true; 14561 interesting = true; 14562 procState = ActivityManager.PROCESS_STATE_TOP; 14563 } else if (app.instrumentationClass != null) { 14564 // Don't want to kill running instrumentation. 14565 adj = ProcessList.FOREGROUND_APP_ADJ; 14566 schedGroup = Process.THREAD_GROUP_DEFAULT; 14567 app.adjType = "instrumentation"; 14568 interesting = true; 14569 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14570 } else if ((queue = isReceivingBroadcast(app)) != null) { 14571 // An app that is currently receiving a broadcast also 14572 // counts as being in the foreground for OOM killer purposes. 14573 // It's placed in a sched group based on the nature of the 14574 // broadcast as reflected by which queue it's active in. 14575 adj = ProcessList.FOREGROUND_APP_ADJ; 14576 schedGroup = (queue == mFgBroadcastQueue) 14577 ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 14578 app.adjType = "broadcast"; 14579 procState = ActivityManager.PROCESS_STATE_RECEIVER; 14580 } else if (app.executingServices.size() > 0) { 14581 // An app that is currently executing a service callback also 14582 // counts as being in the foreground. 14583 adj = ProcessList.FOREGROUND_APP_ADJ; 14584 schedGroup = app.execServicesFg ? 14585 Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 14586 app.adjType = "exec-service"; 14587 procState = ActivityManager.PROCESS_STATE_SERVICE; 14588 //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app); 14589 } else { 14590 // As far as we know the process is empty. We may change our mind later. 14591 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 14592 // At this point we don't actually know the adjustment. Use the cached adj 14593 // value that the caller wants us to. 14594 adj = cachedAdj; 14595 procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 14596 app.cached = true; 14597 app.empty = true; 14598 app.adjType = "cch-empty"; 14599 } 14600 14601 // Examine all activities if not already foreground. 14602 if (!foregroundActivities && activitiesSize > 0) { 14603 for (int j = 0; j < activitiesSize; j++) { 14604 final ActivityRecord r = app.activities.get(j); 14605 if (r.app != app) { 14606 Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc " 14607 + app + "?!?"); 14608 continue; 14609 } 14610 if (r.visible) { 14611 // App has a visible activity; only upgrade adjustment. 14612 if (adj > ProcessList.VISIBLE_APP_ADJ) { 14613 adj = ProcessList.VISIBLE_APP_ADJ; 14614 app.adjType = "visible"; 14615 } 14616 if (procState > ActivityManager.PROCESS_STATE_TOP) { 14617 procState = ActivityManager.PROCESS_STATE_TOP; 14618 } 14619 schedGroup = Process.THREAD_GROUP_DEFAULT; 14620 app.cached = false; 14621 app.empty = false; 14622 foregroundActivities = true; 14623 break; 14624 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) { 14625 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14626 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 14627 app.adjType = "pausing"; 14628 } 14629 if (procState > ActivityManager.PROCESS_STATE_TOP) { 14630 procState = ActivityManager.PROCESS_STATE_TOP; 14631 } 14632 schedGroup = Process.THREAD_GROUP_DEFAULT; 14633 app.cached = false; 14634 app.empty = false; 14635 foregroundActivities = true; 14636 } else if (r.state == ActivityState.STOPPING) { 14637 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14638 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 14639 app.adjType = "stopping"; 14640 } 14641 // For the process state, we will at this point consider the 14642 // process to be cached. It will be cached either as an activity 14643 // or empty depending on whether the activity is finishing. We do 14644 // this so that we can treat the process as cached for purposes of 14645 // memory trimming (determing current memory level, trim command to 14646 // send to process) since there can be an arbitrary number of stopping 14647 // processes and they should soon all go into the cached state. 14648 if (!r.finishing) { 14649 if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 14650 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 14651 } 14652 } 14653 app.cached = false; 14654 app.empty = false; 14655 foregroundActivities = true; 14656 } else { 14657 if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 14658 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 14659 app.adjType = "cch-act"; 14660 } 14661 } 14662 } 14663 } 14664 14665 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14666 if (app.foregroundServices) { 14667 // The user is aware of this app, so make it visible. 14668 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 14669 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14670 app.cached = false; 14671 app.adjType = "fg-service"; 14672 schedGroup = Process.THREAD_GROUP_DEFAULT; 14673 } else if (app.forcingToForeground != null) { 14674 // The user is aware of this app, so make it visible. 14675 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 14676 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14677 app.cached = false; 14678 app.adjType = "force-fg"; 14679 app.adjSource = app.forcingToForeground; 14680 schedGroup = Process.THREAD_GROUP_DEFAULT; 14681 } 14682 } 14683 14684 if (app.foregroundServices) { 14685 interesting = true; 14686 } 14687 14688 if (app == mHeavyWeightProcess) { 14689 if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) { 14690 // We don't want to kill the current heavy-weight process. 14691 adj = ProcessList.HEAVY_WEIGHT_APP_ADJ; 14692 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 14693 app.cached = false; 14694 app.adjType = "heavy"; 14695 } 14696 if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) { 14697 procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT; 14698 } 14699 } 14700 14701 if (app == mHomeProcess) { 14702 if (adj > ProcessList.HOME_APP_ADJ) { 14703 // This process is hosting what we currently consider to be the 14704 // home app, so we don't want to let it go into the background. 14705 adj = ProcessList.HOME_APP_ADJ; 14706 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 14707 app.cached = false; 14708 app.adjType = "home"; 14709 } 14710 if (procState > ActivityManager.PROCESS_STATE_HOME) { 14711 procState = ActivityManager.PROCESS_STATE_HOME; 14712 } 14713 } 14714 14715 if (app == mPreviousProcess && app.activities.size() > 0) { 14716 if (adj > ProcessList.PREVIOUS_APP_ADJ) { 14717 // This was the previous process that showed UI to the user. 14718 // We want to try to keep it around more aggressively, to give 14719 // a good experience around switching between two apps. 14720 adj = ProcessList.PREVIOUS_APP_ADJ; 14721 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 14722 app.cached = false; 14723 app.adjType = "previous"; 14724 } 14725 if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) { 14726 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY; 14727 } 14728 } 14729 14730 if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj 14731 + " reason=" + app.adjType); 14732 14733 // By default, we use the computed adjustment. It may be changed if 14734 // there are applications dependent on our services or providers, but 14735 // this gives us a baseline and makes sure we don't get into an 14736 // infinite recursion. 14737 app.adjSeq = mAdjSeq; 14738 app.curRawAdj = adj; 14739 app.hasStartedServices = false; 14740 14741 if (mBackupTarget != null && app == mBackupTarget.app) { 14742 // If possible we want to avoid killing apps while they're being backed up 14743 if (adj > ProcessList.BACKUP_APP_ADJ) { 14744 if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app); 14745 adj = ProcessList.BACKUP_APP_ADJ; 14746 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) { 14747 procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND; 14748 } 14749 app.adjType = "backup"; 14750 app.cached = false; 14751 } 14752 if (procState > ActivityManager.PROCESS_STATE_BACKUP) { 14753 procState = ActivityManager.PROCESS_STATE_BACKUP; 14754 } 14755 } 14756 14757 boolean mayBeTop = false; 14758 14759 for (int is = app.services.size()-1; 14760 is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 14761 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 14762 || procState > ActivityManager.PROCESS_STATE_TOP); 14763 is--) { 14764 ServiceRecord s = app.services.valueAt(is); 14765 if (s.startRequested) { 14766 app.hasStartedServices = true; 14767 if (procState > ActivityManager.PROCESS_STATE_SERVICE) { 14768 procState = ActivityManager.PROCESS_STATE_SERVICE; 14769 } 14770 if (app.hasShownUi && app != mHomeProcess) { 14771 // If this process has shown some UI, let it immediately 14772 // go to the LRU list because it may be pretty heavy with 14773 // UI stuff. We'll tag it with a label just to help 14774 // debug and understand what is going on. 14775 if (adj > ProcessList.SERVICE_ADJ) { 14776 app.adjType = "cch-started-ui-services"; 14777 } 14778 } else { 14779 if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) { 14780 // This service has seen some activity within 14781 // recent memory, so we will keep its process ahead 14782 // of the background processes. 14783 if (adj > ProcessList.SERVICE_ADJ) { 14784 adj = ProcessList.SERVICE_ADJ; 14785 app.adjType = "started-services"; 14786 app.cached = false; 14787 } 14788 } 14789 // If we have let the service slide into the background 14790 // state, still have some text describing what it is doing 14791 // even though the service no longer has an impact. 14792 if (adj > ProcessList.SERVICE_ADJ) { 14793 app.adjType = "cch-started-services"; 14794 } 14795 } 14796 // Don't kill this process because it is doing work; it 14797 // has said it is doing work. 14798 app.keeping = true; 14799 } 14800 for (int conni = s.connections.size()-1; 14801 conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 14802 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 14803 || procState > ActivityManager.PROCESS_STATE_TOP); 14804 conni--) { 14805 ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni); 14806 for (int i = 0; 14807 i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ 14808 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 14809 || procState > ActivityManager.PROCESS_STATE_TOP); 14810 i++) { 14811 // XXX should compute this based on the max of 14812 // all connected clients. 14813 ConnectionRecord cr = clist.get(i); 14814 if (cr.binding.client == app) { 14815 // Binding to ourself is not interesting. 14816 continue; 14817 } 14818 if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) { 14819 ProcessRecord client = cr.binding.client; 14820 int clientAdj = computeOomAdjLocked(client, cachedAdj, 14821 TOP_APP, doingAll, now); 14822 int clientProcState = client.curProcState; 14823 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 14824 // If the other app is cached for any reason, for purposes here 14825 // we are going to consider it empty. The specific cached state 14826 // doesn't propagate except under certain conditions. 14827 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 14828 } 14829 String adjType = null; 14830 if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) { 14831 // Not doing bind OOM management, so treat 14832 // this guy more like a started service. 14833 if (app.hasShownUi && app != mHomeProcess) { 14834 // If this process has shown some UI, let it immediately 14835 // go to the LRU list because it may be pretty heavy with 14836 // UI stuff. We'll tag it with a label just to help 14837 // debug and understand what is going on. 14838 if (adj > clientAdj) { 14839 adjType = "cch-bound-ui-services"; 14840 } 14841 app.cached = false; 14842 clientAdj = adj; 14843 clientProcState = procState; 14844 } else { 14845 if (now >= (s.lastActivity 14846 + ActiveServices.MAX_SERVICE_INACTIVITY)) { 14847 // This service has not seen activity within 14848 // recent memory, so allow it to drop to the 14849 // LRU list if there is no other reason to keep 14850 // it around. We'll also tag it with a label just 14851 // to help debug and undertand what is going on. 14852 if (adj > clientAdj) { 14853 adjType = "cch-bound-services"; 14854 } 14855 clientAdj = adj; 14856 } 14857 } 14858 } 14859 if (adj > clientAdj) { 14860 // If this process has recently shown UI, and 14861 // the process that is binding to it is less 14862 // important than being visible, then we don't 14863 // care about the binding as much as we care 14864 // about letting this process get into the LRU 14865 // list to be killed and restarted if needed for 14866 // memory. 14867 if (app.hasShownUi && app != mHomeProcess 14868 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14869 adjType = "cch-bound-ui-services"; 14870 } else { 14871 if ((cr.flags&(Context.BIND_ABOVE_CLIENT 14872 |Context.BIND_IMPORTANT)) != 0) { 14873 adj = clientAdj; 14874 } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0 14875 && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ 14876 && adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14877 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 14878 } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) { 14879 adj = clientAdj; 14880 } else { 14881 if (adj > ProcessList.VISIBLE_APP_ADJ) { 14882 adj = ProcessList.VISIBLE_APP_ADJ; 14883 } 14884 } 14885 if (!client.cached) { 14886 app.cached = false; 14887 } 14888 if (client.keeping) { 14889 app.keeping = true; 14890 } 14891 adjType = "service"; 14892 } 14893 } 14894 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 14895 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 14896 schedGroup = Process.THREAD_GROUP_DEFAULT; 14897 } 14898 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) { 14899 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) { 14900 // Special handling of clients who are in the top state. 14901 // We *may* want to consider this process to be in the 14902 // top state as well, but only if there is not another 14903 // reason for it to be running. Being on the top is a 14904 // special state, meaning you are specifically running 14905 // for the current top app. If the process is already 14906 // running in the background for some other reason, it 14907 // is more important to continue considering it to be 14908 // in the background state. 14909 mayBeTop = true; 14910 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 14911 } else { 14912 // Special handling for above-top states (persistent 14913 // processes). These should not bring the current process 14914 // into the top state, since they are not on top. Instead 14915 // give them the best state after that. 14916 clientProcState = 14917 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14918 } 14919 } 14920 } else { 14921 if (clientProcState < 14922 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) { 14923 clientProcState = 14924 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND; 14925 } 14926 } 14927 if (procState > clientProcState) { 14928 procState = clientProcState; 14929 } 14930 if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 14931 && (cr.flags&Context.BIND_SHOWING_UI) != 0) { 14932 app.pendingUiClean = true; 14933 } 14934 if (adjType != null) { 14935 app.adjType = adjType; 14936 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 14937 .REASON_SERVICE_IN_USE; 14938 app.adjSource = cr.binding.client; 14939 app.adjSourceOom = clientAdj; 14940 app.adjTarget = s.name; 14941 } 14942 } 14943 if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) { 14944 app.treatLikeActivity = true; 14945 } 14946 final ActivityRecord a = cr.activity; 14947 if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) { 14948 if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ && 14949 (a.visible || a.state == ActivityState.RESUMED 14950 || a.state == ActivityState.PAUSING)) { 14951 adj = ProcessList.FOREGROUND_APP_ADJ; 14952 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 14953 schedGroup = Process.THREAD_GROUP_DEFAULT; 14954 } 14955 app.cached = false; 14956 app.adjType = "service"; 14957 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 14958 .REASON_SERVICE_IN_USE; 14959 app.adjSource = a; 14960 app.adjSourceOom = adj; 14961 app.adjTarget = s.name; 14962 } 14963 } 14964 } 14965 } 14966 } 14967 14968 for (int provi = app.pubProviders.size()-1; 14969 provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 14970 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 14971 || procState > ActivityManager.PROCESS_STATE_TOP); 14972 provi--) { 14973 ContentProviderRecord cpr = app.pubProviders.valueAt(provi); 14974 for (int i = cpr.connections.size()-1; 14975 i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 14976 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 14977 || procState > ActivityManager.PROCESS_STATE_TOP); 14978 i--) { 14979 ContentProviderConnection conn = cpr.connections.get(i); 14980 ProcessRecord client = conn.client; 14981 if (client == app) { 14982 // Being our own client is not interesting. 14983 continue; 14984 } 14985 int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now); 14986 int clientProcState = client.curProcState; 14987 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 14988 // If the other app is cached for any reason, for purposes here 14989 // we are going to consider it empty. 14990 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 14991 } 14992 if (adj > clientAdj) { 14993 if (app.hasShownUi && app != mHomeProcess 14994 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14995 app.adjType = "cch-ui-provider"; 14996 } else { 14997 adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ 14998 ? clientAdj : ProcessList.FOREGROUND_APP_ADJ; 14999 app.adjType = "provider"; 15000 } 15001 app.cached &= client.cached; 15002 app.keeping |= client.keeping; 15003 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 15004 .REASON_PROVIDER_IN_USE; 15005 app.adjSource = client; 15006 app.adjSourceOom = clientAdj; 15007 app.adjTarget = cpr.name; 15008 } 15009 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) { 15010 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) { 15011 // Special handling of clients who are in the top state. 15012 // We *may* want to consider this process to be in the 15013 // top state as well, but only if there is not another 15014 // reason for it to be running. Being on the top is a 15015 // special state, meaning you are specifically running 15016 // for the current top app. If the process is already 15017 // running in the background for some other reason, it 15018 // is more important to continue considering it to be 15019 // in the background state. 15020 mayBeTop = true; 15021 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 15022 } else { 15023 // Special handling for above-top states (persistent 15024 // processes). These should not bring the current process 15025 // into the top state, since they are not on top. Instead 15026 // give them the best state after that. 15027 clientProcState = 15028 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 15029 } 15030 } 15031 if (procState > clientProcState) { 15032 procState = clientProcState; 15033 } 15034 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 15035 schedGroup = Process.THREAD_GROUP_DEFAULT; 15036 } 15037 } 15038 // If the provider has external (non-framework) process 15039 // dependencies, ensure that its adjustment is at least 15040 // FOREGROUND_APP_ADJ. 15041 if (cpr.hasExternalProcessHandles()) { 15042 if (adj > ProcessList.FOREGROUND_APP_ADJ) { 15043 adj = ProcessList.FOREGROUND_APP_ADJ; 15044 schedGroup = Process.THREAD_GROUP_DEFAULT; 15045 app.cached = false; 15046 app.keeping = true; 15047 app.adjType = "provider"; 15048 app.adjTarget = cpr.name; 15049 } 15050 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) { 15051 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 15052 } 15053 } 15054 } 15055 15056 if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) { 15057 // A client of one of our services or providers is in the top state. We 15058 // *may* want to be in the top state, but not if we are already running in 15059 // the background for some other reason. For the decision here, we are going 15060 // to pick out a few specific states that we want to remain in when a client 15061 // is top (states that tend to be longer-term) and otherwise allow it to go 15062 // to the top state. 15063 switch (procState) { 15064 case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND: 15065 case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND: 15066 case ActivityManager.PROCESS_STATE_SERVICE: 15067 // These all are longer-term states, so pull them up to the top 15068 // of the background states, but not all the way to the top state. 15069 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 15070 break; 15071 default: 15072 // Otherwise, top is a better choice, so take it. 15073 procState = ActivityManager.PROCESS_STATE_TOP; 15074 break; 15075 } 15076 } 15077 15078 if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) { 15079 if (app.hasClientActivities) { 15080 // This is a cached process, but with client activities. Mark it so. 15081 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT; 15082 app.adjType = "cch-client-act"; 15083 } else if (app.treatLikeActivity) { 15084 // This is a cached process, but somebody wants us to treat it like it has 15085 // an activity, okay! 15086 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 15087 app.adjType = "cch-as-act"; 15088 } 15089 } 15090 15091 if (adj == ProcessList.SERVICE_ADJ) { 15092 if (doingAll) { 15093 app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3); 15094 mNewNumServiceProcs++; 15095 //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb); 15096 if (!app.serviceb) { 15097 // This service isn't far enough down on the LRU list to 15098 // normally be a B service, but if we are low on RAM and it 15099 // is large we want to force it down since we would prefer to 15100 // keep launcher over it. 15101 if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL 15102 && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) { 15103 app.serviceHighRam = true; 15104 app.serviceb = true; 15105 //Slog.i(TAG, "ADJ " + app + " high ram!"); 15106 } else { 15107 mNewNumAServiceProcs++; 15108 //Slog.i(TAG, "ADJ " + app + " not high ram!"); 15109 } 15110 } else { 15111 app.serviceHighRam = false; 15112 } 15113 } 15114 if (app.serviceb) { 15115 adj = ProcessList.SERVICE_B_ADJ; 15116 } 15117 } 15118 15119 app.curRawAdj = adj; 15120 15121 //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid + 15122 // " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj); 15123 if (adj > app.maxAdj) { 15124 adj = app.maxAdj; 15125 if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 15126 schedGroup = Process.THREAD_GROUP_DEFAULT; 15127 } 15128 } 15129 if (adj < ProcessList.CACHED_APP_MIN_ADJ) { 15130 app.keeping = true; 15131 } 15132 15133 // Do final modification to adj. Everything we do between here and applying 15134 // the final setAdj must be done in this function, because we will also use 15135 // it when computing the final cached adj later. Note that we don't need to 15136 // worry about this for max adj above, since max adj will always be used to 15137 // keep it out of the cached vaues. 15138 adj = app.modifyRawOomAdj(adj); 15139 15140 app.curProcState = procState; 15141 15142 int importance = app.memImportance; 15143 if (importance == 0 || adj != app.curAdj || schedGroup != app.curSchedGroup) { 15144 app.curAdj = adj; 15145 app.curSchedGroup = schedGroup; 15146 if (!interesting) { 15147 // For this reporting, if there is not something explicitly 15148 // interesting in this process then we will push it to the 15149 // background importance. 15150 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 15151 } else if (adj >= ProcessList.CACHED_APP_MIN_ADJ) { 15152 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 15153 } else if (adj >= ProcessList.SERVICE_B_ADJ) { 15154 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 15155 } else if (adj >= ProcessList.HOME_APP_ADJ) { 15156 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 15157 } else if (adj >= ProcessList.SERVICE_ADJ) { 15158 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 15159 } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 15160 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE; 15161 } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) { 15162 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE; 15163 } else if (adj >= ProcessList.VISIBLE_APP_ADJ) { 15164 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE; 15165 } else if (adj >= ProcessList.FOREGROUND_APP_ADJ) { 15166 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND; 15167 } else { 15168 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERSISTENT; 15169 } 15170 } 15171 15172 int changes = importance != app.memImportance ? ProcessChangeItem.CHANGE_IMPORTANCE : 0; 15173 if (foregroundActivities != app.foregroundActivities) { 15174 changes |= ProcessChangeItem.CHANGE_ACTIVITIES; 15175 } 15176 if (changes != 0) { 15177 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes); 15178 app.memImportance = importance; 15179 app.foregroundActivities = foregroundActivities; 15180 int i = mPendingProcessChanges.size()-1; 15181 ProcessChangeItem item = null; 15182 while (i >= 0) { 15183 item = mPendingProcessChanges.get(i); 15184 if (item.pid == app.pid) { 15185 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item); 15186 break; 15187 } 15188 i--; 15189 } 15190 if (i < 0) { 15191 // No existing item in pending changes; need a new one. 15192 final int NA = mAvailProcessChanges.size(); 15193 if (NA > 0) { 15194 item = mAvailProcessChanges.remove(NA-1); 15195 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item); 15196 } else { 15197 item = new ProcessChangeItem(); 15198 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item); 15199 } 15200 item.changes = 0; 15201 item.pid = app.pid; 15202 item.uid = app.info.uid; 15203 if (mPendingProcessChanges.size() == 0) { 15204 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, 15205 "*** Enqueueing dispatch processes changed!"); 15206 mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget(); 15207 } 15208 mPendingProcessChanges.add(item); 15209 } 15210 item.changes |= changes; 15211 item.importance = importance; 15212 item.foregroundActivities = foregroundActivities; 15213 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item " 15214 + Integer.toHexString(System.identityHashCode(item)) 15215 + " " + app.toShortString() + ": changes=" + item.changes 15216 + " importance=" + item.importance 15217 + " foreground=" + item.foregroundActivities 15218 + " type=" + app.adjType + " source=" + app.adjSource 15219 + " target=" + app.adjTarget); 15220 } 15221 15222 return app.curRawAdj; 15223 } 15224 15225 /** 15226 * Schedule PSS collection of a process. 15227 */ 15228 void requestPssLocked(ProcessRecord proc, int procState) { 15229 if (mPendingPssProcesses.contains(proc)) { 15230 return; 15231 } 15232 if (mPendingPssProcesses.size() == 0) { 15233 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG); 15234 } 15235 if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc); 15236 proc.pssProcState = procState; 15237 mPendingPssProcesses.add(proc); 15238 } 15239 15240 /** 15241 * Schedule PSS collection of all processes. 15242 */ 15243 void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) { 15244 if (!always) { 15245 if (now < (mLastFullPssTime + 15246 (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) { 15247 return; 15248 } 15249 } 15250 if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs! memLowered=" + memLowered); 15251 mLastFullPssTime = now; 15252 mPendingPssProcesses.ensureCapacity(mLruProcesses.size()); 15253 mPendingPssProcesses.clear(); 15254 for (int i=mLruProcesses.size()-1; i>=0; i--) { 15255 ProcessRecord app = mLruProcesses.get(i); 15256 if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) { 15257 app.pssProcState = app.setProcState; 15258 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true, 15259 mSleeping, now); 15260 mPendingPssProcesses.add(app); 15261 } 15262 } 15263 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG); 15264 } 15265 15266 /** 15267 * Ask a given process to GC right now. 15268 */ 15269 final void performAppGcLocked(ProcessRecord app) { 15270 try { 15271 app.lastRequestedGc = SystemClock.uptimeMillis(); 15272 if (app.thread != null) { 15273 if (app.reportLowMemory) { 15274 app.reportLowMemory = false; 15275 app.thread.scheduleLowMemory(); 15276 } else { 15277 app.thread.processInBackground(); 15278 } 15279 } 15280 } catch (Exception e) { 15281 // whatever. 15282 } 15283 } 15284 15285 /** 15286 * Returns true if things are idle enough to perform GCs. 15287 */ 15288 private final boolean canGcNowLocked() { 15289 boolean processingBroadcasts = false; 15290 for (BroadcastQueue q : mBroadcastQueues) { 15291 if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) { 15292 processingBroadcasts = true; 15293 } 15294 } 15295 return !processingBroadcasts 15296 && (mSleeping || mStackSupervisor.allResumedActivitiesIdle()); 15297 } 15298 15299 /** 15300 * Perform GCs on all processes that are waiting for it, but only 15301 * if things are idle. 15302 */ 15303 final void performAppGcsLocked() { 15304 final int N = mProcessesToGc.size(); 15305 if (N <= 0) { 15306 return; 15307 } 15308 if (canGcNowLocked()) { 15309 while (mProcessesToGc.size() > 0) { 15310 ProcessRecord proc = mProcessesToGc.remove(0); 15311 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) { 15312 if ((proc.lastRequestedGc+GC_MIN_INTERVAL) 15313 <= SystemClock.uptimeMillis()) { 15314 // To avoid spamming the system, we will GC processes one 15315 // at a time, waiting a few seconds between each. 15316 performAppGcLocked(proc); 15317 scheduleAppGcsLocked(); 15318 return; 15319 } else { 15320 // It hasn't been long enough since we last GCed this 15321 // process... put it in the list to wait for its time. 15322 addProcessToGcListLocked(proc); 15323 break; 15324 } 15325 } 15326 } 15327 15328 scheduleAppGcsLocked(); 15329 } 15330 } 15331 15332 /** 15333 * If all looks good, perform GCs on all processes waiting for them. 15334 */ 15335 final void performAppGcsIfAppropriateLocked() { 15336 if (canGcNowLocked()) { 15337 performAppGcsLocked(); 15338 return; 15339 } 15340 // Still not idle, wait some more. 15341 scheduleAppGcsLocked(); 15342 } 15343 15344 /** 15345 * Schedule the execution of all pending app GCs. 15346 */ 15347 final void scheduleAppGcsLocked() { 15348 mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG); 15349 15350 if (mProcessesToGc.size() > 0) { 15351 // Schedule a GC for the time to the next process. 15352 ProcessRecord proc = mProcessesToGc.get(0); 15353 Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG); 15354 15355 long when = proc.lastRequestedGc + GC_MIN_INTERVAL; 15356 long now = SystemClock.uptimeMillis(); 15357 if (when < (now+GC_TIMEOUT)) { 15358 when = now + GC_TIMEOUT; 15359 } 15360 mHandler.sendMessageAtTime(msg, when); 15361 } 15362 } 15363 15364 /** 15365 * Add a process to the array of processes waiting to be GCed. Keeps the 15366 * list in sorted order by the last GC time. The process can't already be 15367 * on the list. 15368 */ 15369 final void addProcessToGcListLocked(ProcessRecord proc) { 15370 boolean added = false; 15371 for (int i=mProcessesToGc.size()-1; i>=0; i--) { 15372 if (mProcessesToGc.get(i).lastRequestedGc < 15373 proc.lastRequestedGc) { 15374 added = true; 15375 mProcessesToGc.add(i+1, proc); 15376 break; 15377 } 15378 } 15379 if (!added) { 15380 mProcessesToGc.add(0, proc); 15381 } 15382 } 15383 15384 /** 15385 * Set up to ask a process to GC itself. This will either do it 15386 * immediately, or put it on the list of processes to gc the next 15387 * time things are idle. 15388 */ 15389 final void scheduleAppGcLocked(ProcessRecord app) { 15390 long now = SystemClock.uptimeMillis(); 15391 if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) { 15392 return; 15393 } 15394 if (!mProcessesToGc.contains(app)) { 15395 addProcessToGcListLocked(app); 15396 scheduleAppGcsLocked(); 15397 } 15398 } 15399 15400 final void checkExcessivePowerUsageLocked(boolean doKills) { 15401 updateCpuStatsNow(); 15402 15403 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 15404 boolean doWakeKills = doKills; 15405 boolean doCpuKills = doKills; 15406 if (mLastPowerCheckRealtime == 0) { 15407 doWakeKills = false; 15408 } 15409 if (mLastPowerCheckUptime == 0) { 15410 doCpuKills = false; 15411 } 15412 if (stats.isScreenOn()) { 15413 doWakeKills = false; 15414 } 15415 final long curRealtime = SystemClock.elapsedRealtime(); 15416 final long realtimeSince = curRealtime - mLastPowerCheckRealtime; 15417 final long curUptime = SystemClock.uptimeMillis(); 15418 final long uptimeSince = curUptime - mLastPowerCheckUptime; 15419 mLastPowerCheckRealtime = curRealtime; 15420 mLastPowerCheckUptime = curUptime; 15421 if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) { 15422 doWakeKills = false; 15423 } 15424 if (uptimeSince < CPU_MIN_CHECK_DURATION) { 15425 doCpuKills = false; 15426 } 15427 int i = mLruProcesses.size(); 15428 while (i > 0) { 15429 i--; 15430 ProcessRecord app = mLruProcesses.get(i); 15431 if (!app.keeping) { 15432 long wtime; 15433 synchronized (stats) { 15434 wtime = stats.getProcessWakeTime(app.info.uid, 15435 app.pid, curRealtime); 15436 } 15437 long wtimeUsed = wtime - app.lastWakeTime; 15438 long cputimeUsed = app.curCpuTime - app.lastCpuTime; 15439 if (DEBUG_POWER) { 15440 StringBuilder sb = new StringBuilder(128); 15441 sb.append("Wake for "); 15442 app.toShortString(sb); 15443 sb.append(": over "); 15444 TimeUtils.formatDuration(realtimeSince, sb); 15445 sb.append(" used "); 15446 TimeUtils.formatDuration(wtimeUsed, sb); 15447 sb.append(" ("); 15448 sb.append((wtimeUsed*100)/realtimeSince); 15449 sb.append("%)"); 15450 Slog.i(TAG, sb.toString()); 15451 sb.setLength(0); 15452 sb.append("CPU for "); 15453 app.toShortString(sb); 15454 sb.append(": over "); 15455 TimeUtils.formatDuration(uptimeSince, sb); 15456 sb.append(" used "); 15457 TimeUtils.formatDuration(cputimeUsed, sb); 15458 sb.append(" ("); 15459 sb.append((cputimeUsed*100)/uptimeSince); 15460 sb.append("%)"); 15461 Slog.i(TAG, sb.toString()); 15462 } 15463 // If a process has held a wake lock for more 15464 // than 50% of the time during this period, 15465 // that sounds bad. Kill! 15466 if (doWakeKills && realtimeSince > 0 15467 && ((wtimeUsed*100)/realtimeSince) >= 50) { 15468 synchronized (stats) { 15469 stats.reportExcessiveWakeLocked(app.info.uid, app.processName, 15470 realtimeSince, wtimeUsed); 15471 } 15472 killUnneededProcessLocked(app, "excessive wake held " + wtimeUsed 15473 + " during " + realtimeSince); 15474 app.baseProcessTracker.reportExcessiveWake(app.pkgList); 15475 } else if (doCpuKills && uptimeSince > 0 15476 && ((cputimeUsed*100)/uptimeSince) >= 50) { 15477 synchronized (stats) { 15478 stats.reportExcessiveCpuLocked(app.info.uid, app.processName, 15479 uptimeSince, cputimeUsed); 15480 } 15481 killUnneededProcessLocked(app, "excessive cpu " + cputimeUsed 15482 + " during " + uptimeSince); 15483 app.baseProcessTracker.reportExcessiveCpu(app.pkgList); 15484 } else { 15485 app.lastWakeTime = wtime; 15486 app.lastCpuTime = app.curCpuTime; 15487 } 15488 } 15489 } 15490 } 15491 15492 private final boolean applyOomAdjLocked(ProcessRecord app, boolean wasKeeping, 15493 ProcessRecord TOP_APP, boolean doingAll, boolean reportingProcessState, long now) { 15494 boolean success = true; 15495 15496 if (app.curRawAdj != app.setRawAdj) { 15497 if (wasKeeping && !app.keeping) { 15498 // This app is no longer something we want to keep. Note 15499 // its current wake lock time to later know to kill it if 15500 // it is not behaving well. 15501 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 15502 synchronized (stats) { 15503 app.lastWakeTime = stats.getProcessWakeTime(app.info.uid, 15504 app.pid, SystemClock.elapsedRealtime()); 15505 } 15506 app.lastCpuTime = app.curCpuTime; 15507 } 15508 15509 app.setRawAdj = app.curRawAdj; 15510 } 15511 15512 if (app.curAdj != app.setAdj) { 15513 ProcessList.setOomAdj(app.pid, app.curAdj); 15514 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v( 15515 TAG, "Set " + app.pid + " " + app.processName + 15516 " adj " + app.curAdj + ": " + app.adjType); 15517 app.setAdj = app.curAdj; 15518 } 15519 15520 if (app.setSchedGroup != app.curSchedGroup) { 15521 app.setSchedGroup = app.curSchedGroup; 15522 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 15523 "Setting process group of " + app.processName 15524 + " to " + app.curSchedGroup); 15525 if (app.waitingToKill != null && 15526 app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 15527 killUnneededProcessLocked(app, app.waitingToKill); 15528 success = false; 15529 } else { 15530 if (true) { 15531 long oldId = Binder.clearCallingIdentity(); 15532 try { 15533 Process.setProcessGroup(app.pid, app.curSchedGroup); 15534 } catch (Exception e) { 15535 Slog.w(TAG, "Failed setting process group of " + app.pid 15536 + " to " + app.curSchedGroup); 15537 e.printStackTrace(); 15538 } finally { 15539 Binder.restoreCallingIdentity(oldId); 15540 } 15541 } else { 15542 if (app.thread != null) { 15543 try { 15544 app.thread.setSchedulingGroup(app.curSchedGroup); 15545 } catch (RemoteException e) { 15546 } 15547 } 15548 } 15549 Process.setSwappiness(app.pid, 15550 app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE); 15551 } 15552 } 15553 if (app.repProcState != app.curProcState) { 15554 app.repProcState = app.curProcState; 15555 if (!reportingProcessState && app.thread != null) { 15556 try { 15557 if (false) { 15558 //RuntimeException h = new RuntimeException("here"); 15559 Slog.i(TAG, "Sending new process state " + app.repProcState 15560 + " to " + app /*, h*/); 15561 } 15562 app.thread.setProcessState(app.repProcState); 15563 } catch (RemoteException e) { 15564 } 15565 } 15566 } 15567 if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState, 15568 app.setProcState)) { 15569 app.lastStateTime = now; 15570 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true, 15571 mSleeping, now); 15572 if (DEBUG_PSS) Slog.d(TAG, "Process state change from " 15573 + ProcessList.makeProcStateString(app.setProcState) + " to " 15574 + ProcessList.makeProcStateString(app.curProcState) + " next pss in " 15575 + (app.nextPssTime-now) + ": " + app); 15576 } else { 15577 if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL) 15578 && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) { 15579 requestPssLocked(app, app.setProcState); 15580 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false, 15581 mSleeping, now); 15582 } else if (false && DEBUG_PSS) { 15583 Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now)); 15584 } 15585 } 15586 if (app.setProcState != app.curProcState) { 15587 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 15588 "Proc state change of " + app.processName 15589 + " to " + app.curProcState); 15590 app.setProcState = app.curProcState; 15591 if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) { 15592 app.notCachedSinceIdle = false; 15593 } 15594 if (!doingAll) { 15595 setProcessTrackerState(app, mProcessStats.getMemFactorLocked(), now); 15596 } else { 15597 app.procStateChanged = true; 15598 } 15599 } 15600 return success; 15601 } 15602 15603 private final void setProcessTrackerState(ProcessRecord proc, int memFactor, long now) { 15604 if (proc.thread != null && proc.baseProcessTracker != null) { 15605 proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList); 15606 } 15607 } 15608 15609 private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj, 15610 ProcessRecord TOP_APP, boolean doingAll, boolean reportingProcessState, long now) { 15611 if (app.thread == null) { 15612 return false; 15613 } 15614 15615 final boolean wasKeeping = app.keeping; 15616 15617 computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now); 15618 15619 return applyOomAdjLocked(app, wasKeeping, TOP_APP, doingAll, 15620 reportingProcessState, now); 15621 } 15622 15623 final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground, 15624 boolean oomAdj) { 15625 if (isForeground != proc.foregroundServices) { 15626 proc.foregroundServices = isForeground; 15627 ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName, 15628 proc.info.uid); 15629 if (isForeground) { 15630 if (curProcs == null) { 15631 curProcs = new ArrayList<ProcessRecord>(); 15632 mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs); 15633 } 15634 if (!curProcs.contains(proc)) { 15635 curProcs.add(proc); 15636 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START, 15637 proc.info.packageName, proc.info.uid); 15638 } 15639 } else { 15640 if (curProcs != null) { 15641 if (curProcs.remove(proc)) { 15642 mBatteryStatsService.noteEvent( 15643 BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH, 15644 proc.info.packageName, proc.info.uid); 15645 if (curProcs.size() <= 0) { 15646 mForegroundPackages.remove(proc.info.packageName, proc.info.uid); 15647 } 15648 } 15649 } 15650 } 15651 if (oomAdj) { 15652 updateOomAdjLocked(); 15653 } 15654 } 15655 } 15656 15657 private final ActivityRecord resumedAppLocked() { 15658 ActivityRecord act = mStackSupervisor.resumedAppLocked(); 15659 String pkg; 15660 int uid; 15661 if (act != null && !act.sleeping) { 15662 pkg = act.packageName; 15663 uid = act.info.applicationInfo.uid; 15664 } else { 15665 pkg = null; 15666 uid = -1; 15667 } 15668 // Has the UID or resumed package name changed? 15669 if (uid != mCurResumedUid || (pkg != mCurResumedPackage 15670 && (pkg == null || !pkg.equals(mCurResumedPackage)))) { 15671 if (mCurResumedPackage != null) { 15672 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH, 15673 mCurResumedPackage, mCurResumedUid); 15674 } 15675 mCurResumedPackage = pkg; 15676 mCurResumedUid = uid; 15677 if (mCurResumedPackage != null) { 15678 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START, 15679 mCurResumedPackage, mCurResumedUid); 15680 } 15681 } 15682 return act; 15683 } 15684 15685 final boolean updateOomAdjLocked(ProcessRecord app) { 15686 return updateOomAdjLocked(app, false); 15687 } 15688 15689 final boolean updateOomAdjLocked(ProcessRecord app, boolean doingProcessState) { 15690 final ActivityRecord TOP_ACT = resumedAppLocked(); 15691 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 15692 final boolean wasCached = app.cached; 15693 15694 mAdjSeq++; 15695 15696 // This is the desired cached adjusment we want to tell it to use. 15697 // If our app is currently cached, we know it, and that is it. Otherwise, 15698 // we don't know it yet, and it needs to now be cached we will then 15699 // need to do a complete oom adj. 15700 final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ 15701 ? app.curRawAdj : ProcessList.UNKNOWN_ADJ; 15702 boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false, doingProcessState, 15703 SystemClock.uptimeMillis()); 15704 if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) { 15705 // Changed to/from cached state, so apps after it in the LRU 15706 // list may also be changed. 15707 updateOomAdjLocked(); 15708 } 15709 return success; 15710 } 15711 15712 final void updateOomAdjLocked() { 15713 final ActivityRecord TOP_ACT = resumedAppLocked(); 15714 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 15715 final long now = SystemClock.uptimeMillis(); 15716 final long oldTime = now - ProcessList.MAX_EMPTY_TIME; 15717 final int N = mLruProcesses.size(); 15718 15719 if (false) { 15720 RuntimeException e = new RuntimeException(); 15721 e.fillInStackTrace(); 15722 Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e); 15723 } 15724 15725 mAdjSeq++; 15726 mNewNumServiceProcs = 0; 15727 mNewNumAServiceProcs = 0; 15728 15729 final int emptyProcessLimit; 15730 final int cachedProcessLimit; 15731 if (mProcessLimit <= 0) { 15732 emptyProcessLimit = cachedProcessLimit = 0; 15733 } else if (mProcessLimit == 1) { 15734 emptyProcessLimit = 1; 15735 cachedProcessLimit = 0; 15736 } else { 15737 emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit); 15738 cachedProcessLimit = mProcessLimit - emptyProcessLimit; 15739 } 15740 15741 // Let's determine how many processes we have running vs. 15742 // how many slots we have for background processes; we may want 15743 // to put multiple processes in a slot of there are enough of 15744 // them. 15745 int numSlots = (ProcessList.CACHED_APP_MAX_ADJ 15746 - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2; 15747 int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs; 15748 if (numEmptyProcs > cachedProcessLimit) { 15749 // If there are more empty processes than our limit on cached 15750 // processes, then use the cached process limit for the factor. 15751 // This ensures that the really old empty processes get pushed 15752 // down to the bottom, so if we are running low on memory we will 15753 // have a better chance at keeping around more cached processes 15754 // instead of a gazillion empty processes. 15755 numEmptyProcs = cachedProcessLimit; 15756 } 15757 int emptyFactor = numEmptyProcs/numSlots; 15758 if (emptyFactor < 1) emptyFactor = 1; 15759 int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots; 15760 if (cachedFactor < 1) cachedFactor = 1; 15761 int stepCached = 0; 15762 int stepEmpty = 0; 15763 int numCached = 0; 15764 int numEmpty = 0; 15765 int numTrimming = 0; 15766 15767 mNumNonCachedProcs = 0; 15768 mNumCachedHiddenProcs = 0; 15769 15770 // First update the OOM adjustment for each of the 15771 // application processes based on their current state. 15772 int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ; 15773 int nextCachedAdj = curCachedAdj+1; 15774 int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ; 15775 int nextEmptyAdj = curEmptyAdj+2; 15776 for (int i=N-1; i>=0; i--) { 15777 ProcessRecord app = mLruProcesses.get(i); 15778 if (!app.killedByAm && app.thread != null) { 15779 app.procStateChanged = false; 15780 final boolean wasKeeping = app.keeping; 15781 computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now); 15782 15783 // If we haven't yet assigned the final cached adj 15784 // to the process, do that now. 15785 if (app.curAdj >= ProcessList.UNKNOWN_ADJ) { 15786 switch (app.curProcState) { 15787 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY: 15788 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: 15789 // This process is a cached process holding activities... 15790 // assign it the next cached value for that type, and then 15791 // step that cached level. 15792 app.curRawAdj = curCachedAdj; 15793 app.curAdj = app.modifyRawOomAdj(curCachedAdj); 15794 if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i 15795 + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj 15796 + ")"); 15797 if (curCachedAdj != nextCachedAdj) { 15798 stepCached++; 15799 if (stepCached >= cachedFactor) { 15800 stepCached = 0; 15801 curCachedAdj = nextCachedAdj; 15802 nextCachedAdj += 2; 15803 if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) { 15804 nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ; 15805 } 15806 } 15807 } 15808 break; 15809 default: 15810 // For everything else, assign next empty cached process 15811 // level and bump that up. Note that this means that 15812 // long-running services that have dropped down to the 15813 // cached level will be treated as empty (since their process 15814 // state is still as a service), which is what we want. 15815 app.curRawAdj = curEmptyAdj; 15816 app.curAdj = app.modifyRawOomAdj(curEmptyAdj); 15817 if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i 15818 + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj 15819 + ")"); 15820 if (curEmptyAdj != nextEmptyAdj) { 15821 stepEmpty++; 15822 if (stepEmpty >= emptyFactor) { 15823 stepEmpty = 0; 15824 curEmptyAdj = nextEmptyAdj; 15825 nextEmptyAdj += 2; 15826 if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) { 15827 nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ; 15828 } 15829 } 15830 } 15831 break; 15832 } 15833 } 15834 15835 applyOomAdjLocked(app, wasKeeping, TOP_APP, true, false, now); 15836 15837 // Count the number of process types. 15838 switch (app.curProcState) { 15839 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY: 15840 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: 15841 mNumCachedHiddenProcs++; 15842 numCached++; 15843 if (numCached > cachedProcessLimit) { 15844 killUnneededProcessLocked(app, "cached #" + numCached); 15845 } 15846 break; 15847 case ActivityManager.PROCESS_STATE_CACHED_EMPTY: 15848 if (numEmpty > ProcessList.TRIM_EMPTY_APPS 15849 && app.lastActivityTime < oldTime) { 15850 killUnneededProcessLocked(app, "empty for " 15851 + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime) 15852 / 1000) + "s"); 15853 } else { 15854 numEmpty++; 15855 if (numEmpty > emptyProcessLimit) { 15856 killUnneededProcessLocked(app, "empty #" + numEmpty); 15857 } 15858 } 15859 break; 15860 default: 15861 mNumNonCachedProcs++; 15862 break; 15863 } 15864 15865 if (app.isolated && app.services.size() <= 0) { 15866 // If this is an isolated process, and there are no 15867 // services running in it, then the process is no longer 15868 // needed. We agressively kill these because we can by 15869 // definition not re-use the same process again, and it is 15870 // good to avoid having whatever code was running in them 15871 // left sitting around after no longer needed. 15872 killUnneededProcessLocked(app, "isolated not needed"); 15873 } 15874 15875 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME 15876 && !app.killedByAm) { 15877 numTrimming++; 15878 } 15879 } 15880 } 15881 15882 mNumServiceProcs = mNewNumServiceProcs; 15883 15884 // Now determine the memory trimming level of background processes. 15885 // Unfortunately we need to start at the back of the list to do this 15886 // properly. We only do this if the number of background apps we 15887 // are managing to keep around is less than half the maximum we desire; 15888 // if we are keeping a good number around, we'll let them use whatever 15889 // memory they want. 15890 final int numCachedAndEmpty = numCached + numEmpty; 15891 int memFactor; 15892 if (numCached <= ProcessList.TRIM_CACHED_APPS 15893 && numEmpty <= ProcessList.TRIM_EMPTY_APPS) { 15894 if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) { 15895 memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL; 15896 } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) { 15897 memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW; 15898 } else { 15899 memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE; 15900 } 15901 } else { 15902 memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL; 15903 } 15904 // We always allow the memory level to go up (better). We only allow it to go 15905 // down if we are in a state where that is allowed, *and* the total number of processes 15906 // has gone down since last time. 15907 if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel 15908 + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size() 15909 + " last=" + mLastNumProcesses); 15910 if (memFactor > mLastMemoryLevel) { 15911 if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) { 15912 memFactor = mLastMemoryLevel; 15913 if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!"); 15914 } 15915 } 15916 mLastMemoryLevel = memFactor; 15917 mLastNumProcesses = mLruProcesses.size(); 15918 boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !mSleeping, now); 15919 final int trackerMemFactor = mProcessStats.getMemFactorLocked(); 15920 if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) { 15921 if (mLowRamStartTime == 0) { 15922 mLowRamStartTime = now; 15923 } 15924 int step = 0; 15925 int fgTrimLevel; 15926 switch (memFactor) { 15927 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL: 15928 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL; 15929 break; 15930 case ProcessStats.ADJ_MEM_FACTOR_LOW: 15931 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW; 15932 break; 15933 default: 15934 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE; 15935 break; 15936 } 15937 int factor = numTrimming/3; 15938 int minFactor = 2; 15939 if (mHomeProcess != null) minFactor++; 15940 if (mPreviousProcess != null) minFactor++; 15941 if (factor < minFactor) factor = minFactor; 15942 int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE; 15943 for (int i=N-1; i>=0; i--) { 15944 ProcessRecord app = mLruProcesses.get(i); 15945 if (allChanged || app.procStateChanged) { 15946 setProcessTrackerState(app, trackerMemFactor, now); 15947 app.procStateChanged = false; 15948 } 15949 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME 15950 && !app.killedByAm) { 15951 if (app.trimMemoryLevel < curLevel && app.thread != null) { 15952 try { 15953 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 15954 "Trimming memory of " + app.processName 15955 + " to " + curLevel); 15956 app.thread.scheduleTrimMemory(curLevel); 15957 } catch (RemoteException e) { 15958 } 15959 if (false) { 15960 // For now we won't do this; our memory trimming seems 15961 // to be good enough at this point that destroying 15962 // activities causes more harm than good. 15963 if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE 15964 && app != mHomeProcess && app != mPreviousProcess) { 15965 // Need to do this on its own message because the stack may not 15966 // be in a consistent state at this point. 15967 // For these apps we will also finish their activities 15968 // to help them free memory. 15969 mStackSupervisor.scheduleDestroyAllActivities(app, "trim"); 15970 } 15971 } 15972 } 15973 app.trimMemoryLevel = curLevel; 15974 step++; 15975 if (step >= factor) { 15976 step = 0; 15977 switch (curLevel) { 15978 case ComponentCallbacks2.TRIM_MEMORY_COMPLETE: 15979 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE; 15980 break; 15981 case ComponentCallbacks2.TRIM_MEMORY_MODERATE: 15982 curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 15983 break; 15984 } 15985 } 15986 } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) { 15987 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND 15988 && app.thread != null) { 15989 try { 15990 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 15991 "Trimming memory of heavy-weight " + app.processName 15992 + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 15993 app.thread.scheduleTrimMemory( 15994 ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 15995 } catch (RemoteException e) { 15996 } 15997 } 15998 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 15999 } else { 16000 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 16001 || app.systemNoUi) && app.pendingUiClean) { 16002 // If this application is now in the background and it 16003 // had done UI, then give it the special trim level to 16004 // have it free UI resources. 16005 final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN; 16006 if (app.trimMemoryLevel < level && app.thread != null) { 16007 try { 16008 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 16009 "Trimming memory of bg-ui " + app.processName 16010 + " to " + level); 16011 app.thread.scheduleTrimMemory(level); 16012 } catch (RemoteException e) { 16013 } 16014 } 16015 app.pendingUiClean = false; 16016 } 16017 if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) { 16018 try { 16019 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 16020 "Trimming memory of fg " + app.processName 16021 + " to " + fgTrimLevel); 16022 app.thread.scheduleTrimMemory(fgTrimLevel); 16023 } catch (RemoteException e) { 16024 } 16025 } 16026 app.trimMemoryLevel = fgTrimLevel; 16027 } 16028 } 16029 } else { 16030 if (mLowRamStartTime != 0) { 16031 mLowRamTimeSinceLastIdle += now - mLowRamStartTime; 16032 mLowRamStartTime = 0; 16033 } 16034 for (int i=N-1; i>=0; i--) { 16035 ProcessRecord app = mLruProcesses.get(i); 16036 if (allChanged || app.procStateChanged) { 16037 setProcessTrackerState(app, trackerMemFactor, now); 16038 app.procStateChanged = false; 16039 } 16040 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 16041 || app.systemNoUi) && app.pendingUiClean) { 16042 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN 16043 && app.thread != null) { 16044 try { 16045 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 16046 "Trimming memory of ui hidden " + app.processName 16047 + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 16048 app.thread.scheduleTrimMemory( 16049 ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 16050 } catch (RemoteException e) { 16051 } 16052 } 16053 app.pendingUiClean = false; 16054 } 16055 app.trimMemoryLevel = 0; 16056 } 16057 } 16058 16059 if (mAlwaysFinishActivities) { 16060 // Need to do this on its own message because the stack may not 16061 // be in a consistent state at this point. 16062 mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish"); 16063 } 16064 16065 if (allChanged) { 16066 requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered()); 16067 } 16068 16069 if (mProcessStats.shouldWriteNowLocked(now)) { 16070 mHandler.post(new Runnable() { 16071 @Override public void run() { 16072 synchronized (ActivityManagerService.this) { 16073 mProcessStats.writeStateAsyncLocked(); 16074 } 16075 } 16076 }); 16077 } 16078 16079 if (DEBUG_OOM_ADJ) { 16080 Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms"); 16081 } 16082 } 16083 16084 final void trimApplications() { 16085 synchronized (this) { 16086 int i; 16087 16088 // First remove any unused application processes whose package 16089 // has been removed. 16090 for (i=mRemovedProcesses.size()-1; i>=0; i--) { 16091 final ProcessRecord app = mRemovedProcesses.get(i); 16092 if (app.activities.size() == 0 16093 && app.curReceiver == null && app.services.size() == 0) { 16094 Slog.i( 16095 TAG, "Exiting empty application process " 16096 + app.processName + " (" 16097 + (app.thread != null ? app.thread.asBinder() : null) 16098 + ")\n"); 16099 if (app.pid > 0 && app.pid != MY_PID) { 16100 EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid, 16101 app.processName, app.setAdj, "empty"); 16102 app.killedByAm = true; 16103 Process.killProcessQuiet(app.pid); 16104 } else { 16105 try { 16106 app.thread.scheduleExit(); 16107 } catch (Exception e) { 16108 // Ignore exceptions. 16109 } 16110 } 16111 cleanUpApplicationRecordLocked(app, false, true, -1); 16112 mRemovedProcesses.remove(i); 16113 16114 if (app.persistent) { 16115 if (app.persistent) { 16116 addAppLocked(app.info, false); 16117 } 16118 } 16119 } 16120 } 16121 16122 // Now update the oom adj for all processes. 16123 updateOomAdjLocked(); 16124 } 16125 } 16126 16127 /** This method sends the specified signal to each of the persistent apps */ 16128 public void signalPersistentProcesses(int sig) throws RemoteException { 16129 if (sig != Process.SIGNAL_USR1) { 16130 throw new SecurityException("Only SIGNAL_USR1 is allowed"); 16131 } 16132 16133 synchronized (this) { 16134 if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES) 16135 != PackageManager.PERMISSION_GRANTED) { 16136 throw new SecurityException("Requires permission " 16137 + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES); 16138 } 16139 16140 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 16141 ProcessRecord r = mLruProcesses.get(i); 16142 if (r.thread != null && r.persistent) { 16143 Process.sendSignal(r.pid, sig); 16144 } 16145 } 16146 } 16147 } 16148 16149 private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) { 16150 if (proc == null || proc == mProfileProc) { 16151 proc = mProfileProc; 16152 path = mProfileFile; 16153 profileType = mProfileType; 16154 clearProfilerLocked(); 16155 } 16156 if (proc == null) { 16157 return; 16158 } 16159 try { 16160 proc.thread.profilerControl(false, path, null, profileType); 16161 } catch (RemoteException e) { 16162 throw new IllegalStateException("Process disappeared"); 16163 } 16164 } 16165 16166 private void clearProfilerLocked() { 16167 if (mProfileFd != null) { 16168 try { 16169 mProfileFd.close(); 16170 } catch (IOException e) { 16171 } 16172 } 16173 mProfileApp = null; 16174 mProfileProc = null; 16175 mProfileFile = null; 16176 mProfileType = 0; 16177 mAutoStopProfiler = false; 16178 } 16179 16180 public boolean profileControl(String process, int userId, boolean start, 16181 String path, ParcelFileDescriptor fd, int profileType) throws RemoteException { 16182 16183 try { 16184 synchronized (this) { 16185 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 16186 // its own permission. 16187 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 16188 != PackageManager.PERMISSION_GRANTED) { 16189 throw new SecurityException("Requires permission " 16190 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 16191 } 16192 16193 if (start && fd == null) { 16194 throw new IllegalArgumentException("null fd"); 16195 } 16196 16197 ProcessRecord proc = null; 16198 if (process != null) { 16199 proc = findProcessLocked(process, userId, "profileControl"); 16200 } 16201 16202 if (start && (proc == null || proc.thread == null)) { 16203 throw new IllegalArgumentException("Unknown process: " + process); 16204 } 16205 16206 if (start) { 16207 stopProfilerLocked(null, null, 0); 16208 setProfileApp(proc.info, proc.processName, path, fd, false); 16209 mProfileProc = proc; 16210 mProfileType = profileType; 16211 try { 16212 fd = fd.dup(); 16213 } catch (IOException e) { 16214 fd = null; 16215 } 16216 proc.thread.profilerControl(start, path, fd, profileType); 16217 fd = null; 16218 mProfileFd = null; 16219 } else { 16220 stopProfilerLocked(proc, path, profileType); 16221 if (fd != null) { 16222 try { 16223 fd.close(); 16224 } catch (IOException e) { 16225 } 16226 } 16227 } 16228 16229 return true; 16230 } 16231 } catch (RemoteException e) { 16232 throw new IllegalStateException("Process disappeared"); 16233 } finally { 16234 if (fd != null) { 16235 try { 16236 fd.close(); 16237 } catch (IOException e) { 16238 } 16239 } 16240 } 16241 } 16242 16243 private ProcessRecord findProcessLocked(String process, int userId, String callName) { 16244 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 16245 userId, true, true, callName, null); 16246 ProcessRecord proc = null; 16247 try { 16248 int pid = Integer.parseInt(process); 16249 synchronized (mPidsSelfLocked) { 16250 proc = mPidsSelfLocked.get(pid); 16251 } 16252 } catch (NumberFormatException e) { 16253 } 16254 16255 if (proc == null) { 16256 ArrayMap<String, SparseArray<ProcessRecord>> all 16257 = mProcessNames.getMap(); 16258 SparseArray<ProcessRecord> procs = all.get(process); 16259 if (procs != null && procs.size() > 0) { 16260 proc = procs.valueAt(0); 16261 if (userId != UserHandle.USER_ALL && proc.userId != userId) { 16262 for (int i=1; i<procs.size(); i++) { 16263 ProcessRecord thisProc = procs.valueAt(i); 16264 if (thisProc.userId == userId) { 16265 proc = thisProc; 16266 break; 16267 } 16268 } 16269 } 16270 } 16271 } 16272 16273 return proc; 16274 } 16275 16276 public boolean dumpHeap(String process, int userId, boolean managed, 16277 String path, ParcelFileDescriptor fd) throws RemoteException { 16278 16279 try { 16280 synchronized (this) { 16281 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 16282 // its own permission (same as profileControl). 16283 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 16284 != PackageManager.PERMISSION_GRANTED) { 16285 throw new SecurityException("Requires permission " 16286 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 16287 } 16288 16289 if (fd == null) { 16290 throw new IllegalArgumentException("null fd"); 16291 } 16292 16293 ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap"); 16294 if (proc == null || proc.thread == null) { 16295 throw new IllegalArgumentException("Unknown process: " + process); 16296 } 16297 16298 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 16299 if (!isDebuggable) { 16300 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 16301 throw new SecurityException("Process not debuggable: " + proc); 16302 } 16303 } 16304 16305 proc.thread.dumpHeap(managed, path, fd); 16306 fd = null; 16307 return true; 16308 } 16309 } catch (RemoteException e) { 16310 throw new IllegalStateException("Process disappeared"); 16311 } finally { 16312 if (fd != null) { 16313 try { 16314 fd.close(); 16315 } catch (IOException e) { 16316 } 16317 } 16318 } 16319 } 16320 16321 /** In this method we try to acquire our lock to make sure that we have not deadlocked */ 16322 public void monitor() { 16323 synchronized (this) { } 16324 } 16325 16326 void onCoreSettingsChange(Bundle settings) { 16327 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 16328 ProcessRecord processRecord = mLruProcesses.get(i); 16329 try { 16330 if (processRecord.thread != null) { 16331 processRecord.thread.setCoreSettings(settings); 16332 } 16333 } catch (RemoteException re) { 16334 /* ignore */ 16335 } 16336 } 16337 } 16338 16339 // Multi-user methods 16340 16341 /** 16342 * Start user, if its not already running, but don't bring it to foreground. 16343 */ 16344 @Override 16345 public boolean startUserInBackground(final int userId) { 16346 return startUser(userId, /* foreground */ false); 16347 } 16348 16349 /** 16350 * Refreshes the list of users related to the current user when either a 16351 * user switch happens or when a new related user is started in the 16352 * background. 16353 */ 16354 private void updateCurrentProfileIdsLocked() { 16355 final List<UserInfo> profiles = getUserManagerLocked().getProfiles(mCurrentUserId); 16356 int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null 16357 for (int i = 0; i < currentProfileIds.length; i++) { 16358 currentProfileIds[i] = profiles.get(i).id; 16359 } 16360 mCurrentProfileIds = currentProfileIds; 16361 } 16362 16363 private Set getProfileIdsLocked(int userId) { 16364 Set userIds = new HashSet<Integer>(); 16365 final List<UserInfo> profiles = getUserManagerLocked().getProfiles(userId); 16366 for (UserInfo user : profiles) { 16367 userIds.add(Integer.valueOf(user.id)); 16368 } 16369 return userIds; 16370 } 16371 16372 @Override 16373 public boolean switchUser(final int userId) { 16374 return startUser(userId, /* foregound */ true); 16375 } 16376 16377 private boolean startUser(final int userId, boolean foreground) { 16378 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 16379 != PackageManager.PERMISSION_GRANTED) { 16380 String msg = "Permission Denial: switchUser() from pid=" 16381 + Binder.getCallingPid() 16382 + ", uid=" + Binder.getCallingUid() 16383 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 16384 Slog.w(TAG, msg); 16385 throw new SecurityException(msg); 16386 } 16387 16388 if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground); 16389 16390 final long ident = Binder.clearCallingIdentity(); 16391 try { 16392 synchronized (this) { 16393 final int oldUserId = mCurrentUserId; 16394 if (oldUserId == userId) { 16395 return true; 16396 } 16397 16398 mStackSupervisor.setLockTaskModeLocked(null); 16399 16400 final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId); 16401 if (userInfo == null) { 16402 Slog.w(TAG, "No user info for user #" + userId); 16403 return false; 16404 } 16405 16406 if (foreground) { 16407 mWindowManager.startFreezingScreen(R.anim.screen_user_exit, 16408 R.anim.screen_user_enter); 16409 } 16410 16411 boolean needStart = false; 16412 16413 // If the user we are switching to is not currently started, then 16414 // we need to start it now. 16415 if (mStartedUsers.get(userId) == null) { 16416 mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false)); 16417 updateStartedUserArrayLocked(); 16418 needStart = true; 16419 } 16420 16421 final Integer userIdInt = Integer.valueOf(userId); 16422 mUserLru.remove(userIdInt); 16423 mUserLru.add(userIdInt); 16424 16425 if (foreground) { 16426 mCurrentUserId = userId; 16427 updateCurrentProfileIdsLocked(); 16428 mWindowManager.setCurrentUser(userId, mCurrentProfileIds); 16429 // Once the internal notion of the active user has switched, we lock the device 16430 // with the option to show the user switcher on the keyguard. 16431 mWindowManager.lockNow(null); 16432 } else { 16433 final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId); 16434 updateCurrentProfileIdsLocked(); 16435 mWindowManager.setCurrentProfileIds(mCurrentProfileIds); 16436 mUserLru.remove(currentUserIdInt); 16437 mUserLru.add(currentUserIdInt); 16438 } 16439 16440 final UserStartedState uss = mStartedUsers.get(userId); 16441 16442 // Make sure user is in the started state. If it is currently 16443 // stopping, we need to knock that off. 16444 if (uss.mState == UserStartedState.STATE_STOPPING) { 16445 // If we are stopping, we haven't sent ACTION_SHUTDOWN, 16446 // so we can just fairly silently bring the user back from 16447 // the almost-dead. 16448 uss.mState = UserStartedState.STATE_RUNNING; 16449 updateStartedUserArrayLocked(); 16450 needStart = true; 16451 } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) { 16452 // This means ACTION_SHUTDOWN has been sent, so we will 16453 // need to treat this as a new boot of the user. 16454 uss.mState = UserStartedState.STATE_BOOTING; 16455 updateStartedUserArrayLocked(); 16456 needStart = true; 16457 } 16458 16459 if (foreground) { 16460 mHandler.removeMessages(REPORT_USER_SWITCH_MSG); 16461 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 16462 mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG, 16463 oldUserId, userId, uss)); 16464 mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG, 16465 oldUserId, userId, uss), USER_SWITCH_TIMEOUT); 16466 } 16467 16468 if (needStart) { 16469 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 16470 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16471 | Intent.FLAG_RECEIVER_FOREGROUND); 16472 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 16473 broadcastIntentLocked(null, null, intent, 16474 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 16475 false, false, MY_PID, Process.SYSTEM_UID, userId); 16476 } 16477 16478 if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) { 16479 if (userId != 0) { 16480 Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE); 16481 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 16482 broadcastIntentLocked(null, null, intent, null, 16483 new IIntentReceiver.Stub() { 16484 public void performReceive(Intent intent, int resultCode, 16485 String data, Bundle extras, boolean ordered, 16486 boolean sticky, int sendingUser) { 16487 userInitialized(uss, userId); 16488 } 16489 }, 0, null, null, null, AppOpsManager.OP_NONE, 16490 true, false, MY_PID, Process.SYSTEM_UID, 16491 userId); 16492 uss.initializing = true; 16493 } else { 16494 getUserManagerLocked().makeInitialized(userInfo.id); 16495 } 16496 } 16497 16498 if (foreground) { 16499 boolean homeInFront = mStackSupervisor.switchUserLocked(userId, uss); 16500 if (homeInFront) { 16501 startHomeActivityLocked(userId); 16502 } else { 16503 mStackSupervisor.resumeTopActivitiesLocked(); 16504 } 16505 EventLogTags.writeAmSwitchUser(userId); 16506 getUserManagerLocked().userForeground(userId); 16507 sendUserSwitchBroadcastsLocked(oldUserId, userId); 16508 } 16509 16510 if (needStart) { 16511 Intent intent = new Intent(Intent.ACTION_USER_STARTING); 16512 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 16513 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 16514 broadcastIntentLocked(null, null, intent, 16515 null, new IIntentReceiver.Stub() { 16516 @Override 16517 public void performReceive(Intent intent, int resultCode, String data, 16518 Bundle extras, boolean ordered, boolean sticky, int sendingUser) 16519 throws RemoteException { 16520 } 16521 }, 0, null, null, 16522 android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 16523 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 16524 } 16525 } 16526 } finally { 16527 Binder.restoreCallingIdentity(ident); 16528 } 16529 16530 return true; 16531 } 16532 16533 void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) { 16534 long ident = Binder.clearCallingIdentity(); 16535 try { 16536 Intent intent; 16537 if (oldUserId >= 0) { 16538 intent = new Intent(Intent.ACTION_USER_BACKGROUND); 16539 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16540 | Intent.FLAG_RECEIVER_FOREGROUND); 16541 intent.putExtra(Intent.EXTRA_USER_HANDLE, oldUserId); 16542 broadcastIntentLocked(null, null, intent, 16543 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 16544 false, false, MY_PID, Process.SYSTEM_UID, oldUserId); 16545 } 16546 if (newUserId >= 0) { 16547 intent = new Intent(Intent.ACTION_USER_FOREGROUND); 16548 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16549 | Intent.FLAG_RECEIVER_FOREGROUND); 16550 intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId); 16551 broadcastIntentLocked(null, null, intent, 16552 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 16553 false, false, MY_PID, Process.SYSTEM_UID, newUserId); 16554 intent = new Intent(Intent.ACTION_USER_SWITCHED); 16555 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16556 | Intent.FLAG_RECEIVER_FOREGROUND); 16557 intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId); 16558 broadcastIntentLocked(null, null, intent, 16559 null, null, 0, null, null, 16560 android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE, 16561 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 16562 } 16563 } finally { 16564 Binder.restoreCallingIdentity(ident); 16565 } 16566 } 16567 16568 void dispatchUserSwitch(final UserStartedState uss, final int oldUserId, 16569 final int newUserId) { 16570 final int N = mUserSwitchObservers.beginBroadcast(); 16571 if (N > 0) { 16572 final IRemoteCallback callback = new IRemoteCallback.Stub() { 16573 int mCount = 0; 16574 @Override 16575 public void sendResult(Bundle data) throws RemoteException { 16576 synchronized (ActivityManagerService.this) { 16577 if (mCurUserSwitchCallback == this) { 16578 mCount++; 16579 if (mCount == N) { 16580 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 16581 } 16582 } 16583 } 16584 } 16585 }; 16586 synchronized (this) { 16587 uss.switching = true; 16588 mCurUserSwitchCallback = callback; 16589 } 16590 for (int i=0; i<N; i++) { 16591 try { 16592 mUserSwitchObservers.getBroadcastItem(i).onUserSwitching( 16593 newUserId, callback); 16594 } catch (RemoteException e) { 16595 } 16596 } 16597 } else { 16598 synchronized (this) { 16599 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 16600 } 16601 } 16602 mUserSwitchObservers.finishBroadcast(); 16603 } 16604 16605 void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 16606 synchronized (this) { 16607 Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId); 16608 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 16609 } 16610 } 16611 16612 void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) { 16613 mCurUserSwitchCallback = null; 16614 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 16615 mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG, 16616 oldUserId, newUserId, uss)); 16617 } 16618 16619 void userInitialized(UserStartedState uss, int newUserId) { 16620 completeSwitchAndInitalize(uss, newUserId, true, false); 16621 } 16622 16623 void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 16624 completeSwitchAndInitalize(uss, newUserId, false, true); 16625 } 16626 16627 void completeSwitchAndInitalize(UserStartedState uss, int newUserId, 16628 boolean clearInitializing, boolean clearSwitching) { 16629 boolean unfrozen = false; 16630 synchronized (this) { 16631 if (clearInitializing) { 16632 uss.initializing = false; 16633 getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier()); 16634 } 16635 if (clearSwitching) { 16636 uss.switching = false; 16637 } 16638 if (!uss.switching && !uss.initializing) { 16639 mWindowManager.stopFreezingScreen(); 16640 unfrozen = true; 16641 } 16642 } 16643 if (unfrozen) { 16644 final int N = mUserSwitchObservers.beginBroadcast(); 16645 for (int i=0; i<N; i++) { 16646 try { 16647 mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId); 16648 } catch (RemoteException e) { 16649 } 16650 } 16651 mUserSwitchObservers.finishBroadcast(); 16652 } 16653 } 16654 16655 void scheduleStartProfilesLocked() { 16656 if (!mHandler.hasMessages(START_PROFILES_MSG)) { 16657 mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG), 16658 DateUtils.SECOND_IN_MILLIS); 16659 } 16660 } 16661 16662 void startProfilesLocked() { 16663 if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked"); 16664 List<UserInfo> profiles = getUserManagerLocked().getProfiles(mCurrentUserId); 16665 List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size()); 16666 for (UserInfo user : profiles) { 16667 if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED 16668 && user.id != mCurrentUserId) { 16669 toStart.add(user); 16670 } 16671 } 16672 final int n = toStart.size(); 16673 int i = 0; 16674 for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) { 16675 startUserInBackground(toStart.get(i).id); 16676 } 16677 if (i < n) { 16678 Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS"); 16679 } 16680 } 16681 16682 void finishUserSwitch(UserStartedState uss) { 16683 synchronized (this) { 16684 if (uss.mState == UserStartedState.STATE_BOOTING 16685 && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) { 16686 uss.mState = UserStartedState.STATE_RUNNING; 16687 final int userId = uss.mHandle.getIdentifier(); 16688 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 16689 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 16690 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT); 16691 broadcastIntentLocked(null, null, intent, 16692 null, null, 0, null, null, 16693 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE, 16694 true, false, MY_PID, Process.SYSTEM_UID, userId); 16695 } 16696 16697 startProfilesLocked(); 16698 16699 int num = mUserLru.size(); 16700 int i = 0; 16701 while (num > MAX_RUNNING_USERS && i < mUserLru.size()) { 16702 Integer oldUserId = mUserLru.get(i); 16703 UserStartedState oldUss = mStartedUsers.get(oldUserId); 16704 if (oldUss == null) { 16705 // Shouldn't happen, but be sane if it does. 16706 mUserLru.remove(i); 16707 num--; 16708 continue; 16709 } 16710 if (oldUss.mState == UserStartedState.STATE_STOPPING 16711 || oldUss.mState == UserStartedState.STATE_SHUTDOWN) { 16712 // This user is already stopping, doesn't count. 16713 num--; 16714 i++; 16715 continue; 16716 } 16717 if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) { 16718 // Owner and current can't be stopped, but count as running. 16719 i++; 16720 continue; 16721 } 16722 // This is a user to be stopped. 16723 stopUserLocked(oldUserId, null); 16724 num--; 16725 i++; 16726 } 16727 } 16728 } 16729 16730 @Override 16731 public int stopUser(final int userId, final IStopUserCallback callback) { 16732 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 16733 != PackageManager.PERMISSION_GRANTED) { 16734 String msg = "Permission Denial: switchUser() from pid=" 16735 + Binder.getCallingPid() 16736 + ", uid=" + Binder.getCallingUid() 16737 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 16738 Slog.w(TAG, msg); 16739 throw new SecurityException(msg); 16740 } 16741 if (userId <= 0) { 16742 throw new IllegalArgumentException("Can't stop primary user " + userId); 16743 } 16744 synchronized (this) { 16745 return stopUserLocked(userId, callback); 16746 } 16747 } 16748 16749 private int stopUserLocked(final int userId, final IStopUserCallback callback) { 16750 if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId); 16751 if (mCurrentUserId == userId) { 16752 return ActivityManager.USER_OP_IS_CURRENT; 16753 } 16754 16755 final UserStartedState uss = mStartedUsers.get(userId); 16756 if (uss == null) { 16757 // User is not started, nothing to do... but we do need to 16758 // callback if requested. 16759 if (callback != null) { 16760 mHandler.post(new Runnable() { 16761 @Override 16762 public void run() { 16763 try { 16764 callback.userStopped(userId); 16765 } catch (RemoteException e) { 16766 } 16767 } 16768 }); 16769 } 16770 return ActivityManager.USER_OP_SUCCESS; 16771 } 16772 16773 if (callback != null) { 16774 uss.mStopCallbacks.add(callback); 16775 } 16776 16777 if (uss.mState != UserStartedState.STATE_STOPPING 16778 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 16779 uss.mState = UserStartedState.STATE_STOPPING; 16780 updateStartedUserArrayLocked(); 16781 16782 long ident = Binder.clearCallingIdentity(); 16783 try { 16784 // We are going to broadcast ACTION_USER_STOPPING and then 16785 // once that is done send a final ACTION_SHUTDOWN and then 16786 // stop the user. 16787 final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING); 16788 stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 16789 stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 16790 stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true); 16791 final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN); 16792 // This is the result receiver for the final shutdown broadcast. 16793 final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() { 16794 @Override 16795 public void performReceive(Intent intent, int resultCode, String data, 16796 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 16797 finishUserStop(uss); 16798 } 16799 }; 16800 // This is the result receiver for the initial stopping broadcast. 16801 final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() { 16802 @Override 16803 public void performReceive(Intent intent, int resultCode, String data, 16804 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 16805 // On to the next. 16806 synchronized (ActivityManagerService.this) { 16807 if (uss.mState != UserStartedState.STATE_STOPPING) { 16808 // Whoops, we are being started back up. Abort, abort! 16809 return; 16810 } 16811 uss.mState = UserStartedState.STATE_SHUTDOWN; 16812 } 16813 broadcastIntentLocked(null, null, shutdownIntent, 16814 null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE, 16815 true, false, MY_PID, Process.SYSTEM_UID, userId); 16816 } 16817 }; 16818 // Kick things off. 16819 broadcastIntentLocked(null, null, stoppingIntent, 16820 null, stoppingReceiver, 0, null, null, 16821 android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 16822 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 16823 } finally { 16824 Binder.restoreCallingIdentity(ident); 16825 } 16826 } 16827 16828 return ActivityManager.USER_OP_SUCCESS; 16829 } 16830 16831 void finishUserStop(UserStartedState uss) { 16832 final int userId = uss.mHandle.getIdentifier(); 16833 boolean stopped; 16834 ArrayList<IStopUserCallback> callbacks; 16835 synchronized (this) { 16836 callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks); 16837 if (mStartedUsers.get(userId) != uss) { 16838 stopped = false; 16839 } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) { 16840 stopped = false; 16841 } else { 16842 stopped = true; 16843 // User can no longer run. 16844 mStartedUsers.remove(userId); 16845 mUserLru.remove(Integer.valueOf(userId)); 16846 updateStartedUserArrayLocked(); 16847 16848 // Clean up all state and processes associated with the user. 16849 // Kill all the processes for the user. 16850 forceStopUserLocked(userId, "finish user"); 16851 } 16852 } 16853 16854 for (int i=0; i<callbacks.size(); i++) { 16855 try { 16856 if (stopped) callbacks.get(i).userStopped(userId); 16857 else callbacks.get(i).userStopAborted(userId); 16858 } catch (RemoteException e) { 16859 } 16860 } 16861 16862 mStackSupervisor.removeUserLocked(userId); 16863 } 16864 16865 @Override 16866 public UserInfo getCurrentUser() { 16867 if ((checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) 16868 != PackageManager.PERMISSION_GRANTED) && ( 16869 checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 16870 != PackageManager.PERMISSION_GRANTED)) { 16871 String msg = "Permission Denial: getCurrentUser() from pid=" 16872 + Binder.getCallingPid() 16873 + ", uid=" + Binder.getCallingUid() 16874 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS; 16875 Slog.w(TAG, msg); 16876 throw new SecurityException(msg); 16877 } 16878 synchronized (this) { 16879 return getUserManagerLocked().getUserInfo(mCurrentUserId); 16880 } 16881 } 16882 16883 int getCurrentUserIdLocked() { 16884 return mCurrentUserId; 16885 } 16886 16887 @Override 16888 public boolean isUserRunning(int userId, boolean orStopped) { 16889 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) 16890 != PackageManager.PERMISSION_GRANTED) { 16891 String msg = "Permission Denial: isUserRunning() from pid=" 16892 + Binder.getCallingPid() 16893 + ", uid=" + Binder.getCallingUid() 16894 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS; 16895 Slog.w(TAG, msg); 16896 throw new SecurityException(msg); 16897 } 16898 synchronized (this) { 16899 return isUserRunningLocked(userId, orStopped); 16900 } 16901 } 16902 16903 boolean isUserRunningLocked(int userId, boolean orStopped) { 16904 UserStartedState state = mStartedUsers.get(userId); 16905 if (state == null) { 16906 return false; 16907 } 16908 if (orStopped) { 16909 return true; 16910 } 16911 return state.mState != UserStartedState.STATE_STOPPING 16912 && state.mState != UserStartedState.STATE_SHUTDOWN; 16913 } 16914 16915 @Override 16916 public int[] getRunningUserIds() { 16917 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) 16918 != PackageManager.PERMISSION_GRANTED) { 16919 String msg = "Permission Denial: isUserRunning() from pid=" 16920 + Binder.getCallingPid() 16921 + ", uid=" + Binder.getCallingUid() 16922 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS; 16923 Slog.w(TAG, msg); 16924 throw new SecurityException(msg); 16925 } 16926 synchronized (this) { 16927 return mStartedUserArray; 16928 } 16929 } 16930 16931 private void updateStartedUserArrayLocked() { 16932 int num = 0; 16933 for (int i=0; i<mStartedUsers.size(); i++) { 16934 UserStartedState uss = mStartedUsers.valueAt(i); 16935 // This list does not include stopping users. 16936 if (uss.mState != UserStartedState.STATE_STOPPING 16937 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 16938 num++; 16939 } 16940 } 16941 mStartedUserArray = new int[num]; 16942 num = 0; 16943 for (int i=0; i<mStartedUsers.size(); i++) { 16944 UserStartedState uss = mStartedUsers.valueAt(i); 16945 if (uss.mState != UserStartedState.STATE_STOPPING 16946 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 16947 mStartedUserArray[num] = mStartedUsers.keyAt(i); 16948 num++; 16949 } 16950 } 16951 } 16952 16953 @Override 16954 public void registerUserSwitchObserver(IUserSwitchObserver observer) { 16955 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 16956 != PackageManager.PERMISSION_GRANTED) { 16957 String msg = "Permission Denial: registerUserSwitchObserver() from pid=" 16958 + Binder.getCallingPid() 16959 + ", uid=" + Binder.getCallingUid() 16960 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 16961 Slog.w(TAG, msg); 16962 throw new SecurityException(msg); 16963 } 16964 16965 mUserSwitchObservers.register(observer); 16966 } 16967 16968 @Override 16969 public void unregisterUserSwitchObserver(IUserSwitchObserver observer) { 16970 mUserSwitchObservers.unregister(observer); 16971 } 16972 16973 private boolean userExists(int userId) { 16974 if (userId == 0) { 16975 return true; 16976 } 16977 UserManagerService ums = getUserManagerLocked(); 16978 return ums != null ? (ums.getUserInfo(userId) != null) : false; 16979 } 16980 16981 int[] getUsersLocked() { 16982 UserManagerService ums = getUserManagerLocked(); 16983 return ums != null ? ums.getUserIds() : new int[] { 0 }; 16984 } 16985 16986 UserManagerService getUserManagerLocked() { 16987 if (mUserManager == null) { 16988 IBinder b = ServiceManager.getService(Context.USER_SERVICE); 16989 mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b); 16990 } 16991 return mUserManager; 16992 } 16993 16994 private int applyUserId(int uid, int userId) { 16995 return UserHandle.getUid(userId, uid); 16996 } 16997 16998 ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) { 16999 if (info == null) return null; 17000 ApplicationInfo newInfo = new ApplicationInfo(info); 17001 newInfo.uid = applyUserId(info.uid, userId); 17002 newInfo.dataDir = USER_DATA_DIR + userId + "/" 17003 + info.packageName; 17004 return newInfo; 17005 } 17006 17007 ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) { 17008 if (aInfo == null 17009 || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) { 17010 return aInfo; 17011 } 17012 17013 ActivityInfo info = new ActivityInfo(aInfo); 17014 info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId); 17015 return info; 17016 } 17017 17018 private final class LocalService extends ActivityManagerInternal { 17019 @Override 17020 public void goingToSleep() { 17021 ActivityManagerService.this.goingToSleep(); 17022 } 17023 17024 @Override 17025 public void wakingUp() { 17026 ActivityManagerService.this.wakingUp(); 17027 } 17028 } 17029} 17030