ActivityManagerService.java revision 385124d8cee38dee00d4fac31e8fbe46fb30565b
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 * @param finishTask Whether to finish the task associated with this Activity. Only applies to 3457 * the root Activity in the task. 3458 * 3459 * @return Returns true if the activity successfully finished, or false if it is still running. 3460 */ 3461 @Override 3462 public final boolean finishActivity(IBinder token, int resultCode, Intent resultData, 3463 boolean finishTask) { 3464 // Refuse possible leaked file descriptors 3465 if (resultData != null && resultData.hasFileDescriptors() == true) { 3466 throw new IllegalArgumentException("File descriptors passed in Intent"); 3467 } 3468 3469 synchronized(this) { 3470 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3471 if (r == null) { 3472 return true; 3473 } 3474 // Keep track of the root activity of the task before we finish it 3475 TaskRecord tr = r.task; 3476 ActivityRecord rootR = tr.getRootActivity(); 3477 if (mController != null) { 3478 // Find the first activity that is not finishing. 3479 ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0); 3480 if (next != null) { 3481 // ask watcher if this is allowed 3482 boolean resumeOK = true; 3483 try { 3484 resumeOK = mController.activityResuming(next.packageName); 3485 } catch (RemoteException e) { 3486 mController = null; 3487 Watchdog.getInstance().setActivityController(null); 3488 } 3489 3490 if (!resumeOK) { 3491 return false; 3492 } 3493 } 3494 } 3495 final long origId = Binder.clearCallingIdentity(); 3496 try { 3497 boolean res; 3498 if (finishTask && r == rootR) { 3499 // If requested, remove the task that is associated to this activity only if it 3500 // was the root activity in the task. The result code and data is ignored because 3501 // we don't support returning them across task boundaries. 3502 res = removeTaskByIdLocked(tr.taskId, 0); 3503 } else { 3504 res = tr.stack.requestFinishActivityLocked(token, resultCode, 3505 resultData, "app-request", true); 3506 } 3507 return res; 3508 } finally { 3509 Binder.restoreCallingIdentity(origId); 3510 } 3511 } 3512 } 3513 3514 @Override 3515 public final void finishHeavyWeightApp() { 3516 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 3517 != PackageManager.PERMISSION_GRANTED) { 3518 String msg = "Permission Denial: finishHeavyWeightApp() from pid=" 3519 + Binder.getCallingPid() 3520 + ", uid=" + Binder.getCallingUid() 3521 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 3522 Slog.w(TAG, msg); 3523 throw new SecurityException(msg); 3524 } 3525 3526 synchronized(this) { 3527 if (mHeavyWeightProcess == null) { 3528 return; 3529 } 3530 3531 ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>( 3532 mHeavyWeightProcess.activities); 3533 for (int i=0; i<activities.size(); i++) { 3534 ActivityRecord r = activities.get(i); 3535 if (!r.finishing) { 3536 r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED, 3537 null, "finish-heavy", true); 3538 } 3539 } 3540 3541 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 3542 mHeavyWeightProcess.userId, 0)); 3543 mHeavyWeightProcess = null; 3544 } 3545 } 3546 3547 @Override 3548 public void crashApplication(int uid, int initialPid, String packageName, 3549 String message) { 3550 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 3551 != PackageManager.PERMISSION_GRANTED) { 3552 String msg = "Permission Denial: crashApplication() from pid=" 3553 + Binder.getCallingPid() 3554 + ", uid=" + Binder.getCallingUid() 3555 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 3556 Slog.w(TAG, msg); 3557 throw new SecurityException(msg); 3558 } 3559 3560 synchronized(this) { 3561 ProcessRecord proc = null; 3562 3563 // Figure out which process to kill. We don't trust that initialPid 3564 // still has any relation to current pids, so must scan through the 3565 // list. 3566 synchronized (mPidsSelfLocked) { 3567 for (int i=0; i<mPidsSelfLocked.size(); i++) { 3568 ProcessRecord p = mPidsSelfLocked.valueAt(i); 3569 if (p.uid != uid) { 3570 continue; 3571 } 3572 if (p.pid == initialPid) { 3573 proc = p; 3574 break; 3575 } 3576 if (p.pkgList.containsKey(packageName)) { 3577 proc = p; 3578 } 3579 } 3580 } 3581 3582 if (proc == null) { 3583 Slog.w(TAG, "crashApplication: nothing for uid=" + uid 3584 + " initialPid=" + initialPid 3585 + " packageName=" + packageName); 3586 return; 3587 } 3588 3589 if (proc.thread != null) { 3590 if (proc.pid == Process.myPid()) { 3591 Log.w(TAG, "crashApplication: trying to crash self!"); 3592 return; 3593 } 3594 long ident = Binder.clearCallingIdentity(); 3595 try { 3596 proc.thread.scheduleCrash(message); 3597 } catch (RemoteException e) { 3598 } 3599 Binder.restoreCallingIdentity(ident); 3600 } 3601 } 3602 } 3603 3604 @Override 3605 public final void finishSubActivity(IBinder token, String resultWho, 3606 int requestCode) { 3607 synchronized(this) { 3608 final long origId = Binder.clearCallingIdentity(); 3609 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3610 if (r != null) { 3611 r.task.stack.finishSubActivityLocked(r, resultWho, requestCode); 3612 } 3613 Binder.restoreCallingIdentity(origId); 3614 } 3615 } 3616 3617 @Override 3618 public boolean finishActivityAffinity(IBinder token) { 3619 synchronized(this) { 3620 final long origId = Binder.clearCallingIdentity(); 3621 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3622 boolean res = false; 3623 if (r != null) { 3624 res = r.task.stack.finishActivityAffinityLocked(r); 3625 } 3626 Binder.restoreCallingIdentity(origId); 3627 return res; 3628 } 3629 } 3630 3631 @Override 3632 public boolean willActivityBeVisible(IBinder token) { 3633 synchronized(this) { 3634 ActivityStack stack = ActivityRecord.getStackLocked(token); 3635 if (stack != null) { 3636 return stack.willActivityBeVisibleLocked(token); 3637 } 3638 return false; 3639 } 3640 } 3641 3642 @Override 3643 public void overridePendingTransition(IBinder token, String packageName, 3644 int enterAnim, int exitAnim) { 3645 synchronized(this) { 3646 ActivityRecord self = ActivityRecord.isInStackLocked(token); 3647 if (self == null) { 3648 return; 3649 } 3650 3651 final long origId = Binder.clearCallingIdentity(); 3652 3653 if (self.state == ActivityState.RESUMED 3654 || self.state == ActivityState.PAUSING) { 3655 mWindowManager.overridePendingAppTransition(packageName, 3656 enterAnim, exitAnim, null); 3657 } 3658 3659 Binder.restoreCallingIdentity(origId); 3660 } 3661 } 3662 3663 /** 3664 * Main function for removing an existing process from the activity manager 3665 * as a result of that process going away. Clears out all connections 3666 * to the process. 3667 */ 3668 private final void handleAppDiedLocked(ProcessRecord app, 3669 boolean restarting, boolean allowRestart) { 3670 int pid = app.pid; 3671 cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1); 3672 if (!restarting) { 3673 removeLruProcessLocked(app); 3674 if (pid > 0) { 3675 ProcessList.remove(pid); 3676 } 3677 } 3678 3679 if (mProfileProc == app) { 3680 clearProfilerLocked(); 3681 } 3682 3683 // Remove this application's activities from active lists. 3684 boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app); 3685 3686 app.activities.clear(); 3687 3688 if (app.instrumentationClass != null) { 3689 Slog.w(TAG, "Crash of app " + app.processName 3690 + " running instrumentation " + app.instrumentationClass); 3691 Bundle info = new Bundle(); 3692 info.putString("shortMsg", "Process crashed."); 3693 finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info); 3694 } 3695 3696 if (!restarting) { 3697 if (!mStackSupervisor.resumeTopActivitiesLocked()) { 3698 // If there was nothing to resume, and we are not already 3699 // restarting this process, but there is a visible activity that 3700 // is hosted by the process... then make sure all visible 3701 // activities are running, taking care of restarting this 3702 // process. 3703 if (hasVisibleActivities) { 3704 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 3705 } 3706 } 3707 } 3708 } 3709 3710 private final int getLRURecordIndexForAppLocked(IApplicationThread thread) { 3711 IBinder threadBinder = thread.asBinder(); 3712 // Find the application record. 3713 for (int i=mLruProcesses.size()-1; i>=0; i--) { 3714 ProcessRecord rec = mLruProcesses.get(i); 3715 if (rec.thread != null && rec.thread.asBinder() == threadBinder) { 3716 return i; 3717 } 3718 } 3719 return -1; 3720 } 3721 3722 final ProcessRecord getRecordForAppLocked( 3723 IApplicationThread thread) { 3724 if (thread == null) { 3725 return null; 3726 } 3727 3728 int appIndex = getLRURecordIndexForAppLocked(thread); 3729 return appIndex >= 0 ? mLruProcesses.get(appIndex) : null; 3730 } 3731 3732 final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) { 3733 // If there are no longer any background processes running, 3734 // and the app that died was not running instrumentation, 3735 // then tell everyone we are now low on memory. 3736 boolean haveBg = false; 3737 for (int i=mLruProcesses.size()-1; i>=0; i--) { 3738 ProcessRecord rec = mLruProcesses.get(i); 3739 if (rec.thread != null 3740 && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 3741 haveBg = true; 3742 break; 3743 } 3744 } 3745 3746 if (!haveBg) { 3747 boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 3748 if (doReport) { 3749 long now = SystemClock.uptimeMillis(); 3750 if (now < (mLastMemUsageReportTime+5*60*1000)) { 3751 doReport = false; 3752 } else { 3753 mLastMemUsageReportTime = now; 3754 } 3755 } 3756 final ArrayList<ProcessMemInfo> memInfos 3757 = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null; 3758 EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size()); 3759 long now = SystemClock.uptimeMillis(); 3760 for (int i=mLruProcesses.size()-1; i>=0; i--) { 3761 ProcessRecord rec = mLruProcesses.get(i); 3762 if (rec == dyingProc || rec.thread == null) { 3763 continue; 3764 } 3765 if (doReport) { 3766 memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj, 3767 rec.setProcState, rec.adjType, rec.makeAdjReason())); 3768 } 3769 if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) { 3770 // The low memory report is overriding any current 3771 // state for a GC request. Make sure to do 3772 // heavy/important/visible/foreground processes first. 3773 if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 3774 rec.lastRequestedGc = 0; 3775 } else { 3776 rec.lastRequestedGc = rec.lastLowMemory; 3777 } 3778 rec.reportLowMemory = true; 3779 rec.lastLowMemory = now; 3780 mProcessesToGc.remove(rec); 3781 addProcessToGcListLocked(rec); 3782 } 3783 } 3784 if (doReport) { 3785 Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos); 3786 mHandler.sendMessage(msg); 3787 } 3788 scheduleAppGcsLocked(); 3789 } 3790 } 3791 3792 final void appDiedLocked(ProcessRecord app, int pid, 3793 IApplicationThread thread) { 3794 3795 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 3796 synchronized (stats) { 3797 stats.noteProcessDiedLocked(app.info.uid, pid); 3798 } 3799 3800 // Clean up already done if the process has been re-started. 3801 if (app.pid == pid && app.thread != null && 3802 app.thread.asBinder() == thread.asBinder()) { 3803 boolean doLowMem = app.instrumentationClass == null; 3804 boolean doOomAdj = doLowMem; 3805 if (!app.killedByAm) { 3806 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 3807 + ") has died."); 3808 mAllowLowerMemLevel = true; 3809 } else { 3810 // Note that we always want to do oom adj to update our state with the 3811 // new number of procs. 3812 mAllowLowerMemLevel = false; 3813 doLowMem = false; 3814 } 3815 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName); 3816 if (DEBUG_CLEANUP) Slog.v( 3817 TAG, "Dying app: " + app + ", pid: " + pid 3818 + ", thread: " + thread.asBinder()); 3819 handleAppDiedLocked(app, false, true); 3820 3821 if (doOomAdj) { 3822 updateOomAdjLocked(); 3823 } 3824 if (doLowMem) { 3825 doLowMemReportIfNeededLocked(app); 3826 } 3827 } else if (app.pid != pid) { 3828 // A new process has already been started. 3829 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 3830 + ") has died and restarted (pid " + app.pid + ")."); 3831 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName); 3832 } else if (DEBUG_PROCESSES) { 3833 Slog.d(TAG, "Received spurious death notification for thread " 3834 + thread.asBinder()); 3835 } 3836 } 3837 3838 /** 3839 * If a stack trace dump file is configured, dump process stack traces. 3840 * @param clearTraces causes the dump file to be erased prior to the new 3841 * traces being written, if true; when false, the new traces will be 3842 * appended to any existing file content. 3843 * @param firstPids of dalvik VM processes to dump stack traces for first 3844 * @param lastPids of dalvik VM processes to dump stack traces for last 3845 * @param nativeProcs optional list of native process names to dump stack crawls 3846 * @return file containing stack traces, or null if no dump file is configured 3847 */ 3848 public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids, 3849 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) { 3850 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 3851 if (tracesPath == null || tracesPath.length() == 0) { 3852 return null; 3853 } 3854 3855 File tracesFile = new File(tracesPath); 3856 try { 3857 File tracesDir = tracesFile.getParentFile(); 3858 if (!tracesDir.exists()) { 3859 tracesFile.mkdirs(); 3860 if (!SELinux.restorecon(tracesDir)) { 3861 return null; 3862 } 3863 } 3864 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 3865 3866 if (clearTraces && tracesFile.exists()) tracesFile.delete(); 3867 tracesFile.createNewFile(); 3868 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 3869 } catch (IOException e) { 3870 Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e); 3871 return null; 3872 } 3873 3874 dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs); 3875 return tracesFile; 3876 } 3877 3878 private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids, 3879 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) { 3880 // Use a FileObserver to detect when traces finish writing. 3881 // The order of traces is considered important to maintain for legibility. 3882 FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) { 3883 @Override 3884 public synchronized void onEvent(int event, String path) { notify(); } 3885 }; 3886 3887 try { 3888 observer.startWatching(); 3889 3890 // First collect all of the stacks of the most important pids. 3891 if (firstPids != null) { 3892 try { 3893 int num = firstPids.size(); 3894 for (int i = 0; i < num; i++) { 3895 synchronized (observer) { 3896 Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT); 3897 observer.wait(200); // Wait for write-close, give up after 200msec 3898 } 3899 } 3900 } catch (InterruptedException e) { 3901 Log.wtf(TAG, e); 3902 } 3903 } 3904 3905 // Next collect the stacks of the native pids 3906 if (nativeProcs != null) { 3907 int[] pids = Process.getPidsForCommands(nativeProcs); 3908 if (pids != null) { 3909 for (int pid : pids) { 3910 Debug.dumpNativeBacktraceToFile(pid, tracesPath); 3911 } 3912 } 3913 } 3914 3915 // Lastly, measure CPU usage. 3916 if (processCpuTracker != null) { 3917 processCpuTracker.init(); 3918 System.gc(); 3919 processCpuTracker.update(); 3920 try { 3921 synchronized (processCpuTracker) { 3922 processCpuTracker.wait(500); // measure over 1/2 second. 3923 } 3924 } catch (InterruptedException e) { 3925 } 3926 processCpuTracker.update(); 3927 3928 // We'll take the stack crawls of just the top apps using CPU. 3929 final int N = processCpuTracker.countWorkingStats(); 3930 int numProcs = 0; 3931 for (int i=0; i<N && numProcs<5; i++) { 3932 ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i); 3933 if (lastPids.indexOfKey(stats.pid) >= 0) { 3934 numProcs++; 3935 try { 3936 synchronized (observer) { 3937 Process.sendSignal(stats.pid, Process.SIGNAL_QUIT); 3938 observer.wait(200); // Wait for write-close, give up after 200msec 3939 } 3940 } catch (InterruptedException e) { 3941 Log.wtf(TAG, e); 3942 } 3943 3944 } 3945 } 3946 } 3947 } finally { 3948 observer.stopWatching(); 3949 } 3950 } 3951 3952 final void logAppTooSlow(ProcessRecord app, long startTime, String msg) { 3953 if (true || IS_USER_BUILD) { 3954 return; 3955 } 3956 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 3957 if (tracesPath == null || tracesPath.length() == 0) { 3958 return; 3959 } 3960 3961 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads(); 3962 StrictMode.allowThreadDiskWrites(); 3963 try { 3964 final File tracesFile = new File(tracesPath); 3965 final File tracesDir = tracesFile.getParentFile(); 3966 final File tracesTmp = new File(tracesDir, "__tmp__"); 3967 try { 3968 if (!tracesDir.exists()) { 3969 tracesFile.mkdirs(); 3970 if (!SELinux.restorecon(tracesDir.getPath())) { 3971 return; 3972 } 3973 } 3974 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 3975 3976 if (tracesFile.exists()) { 3977 tracesTmp.delete(); 3978 tracesFile.renameTo(tracesTmp); 3979 } 3980 StringBuilder sb = new StringBuilder(); 3981 Time tobj = new Time(); 3982 tobj.set(System.currentTimeMillis()); 3983 sb.append(tobj.format("%Y-%m-%d %H:%M:%S")); 3984 sb.append(": "); 3985 TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb); 3986 sb.append(" since "); 3987 sb.append(msg); 3988 FileOutputStream fos = new FileOutputStream(tracesFile); 3989 fos.write(sb.toString().getBytes()); 3990 if (app == null) { 3991 fos.write("\n*** No application process!".getBytes()); 3992 } 3993 fos.close(); 3994 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 3995 } catch (IOException e) { 3996 Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e); 3997 return; 3998 } 3999 4000 if (app != null) { 4001 ArrayList<Integer> firstPids = new ArrayList<Integer>(); 4002 firstPids.add(app.pid); 4003 dumpStackTraces(tracesPath, firstPids, null, null, null); 4004 } 4005 4006 File lastTracesFile = null; 4007 File curTracesFile = null; 4008 for (int i=9; i>=0; i--) { 4009 String name = String.format(Locale.US, "slow%02d.txt", i); 4010 curTracesFile = new File(tracesDir, name); 4011 if (curTracesFile.exists()) { 4012 if (lastTracesFile != null) { 4013 curTracesFile.renameTo(lastTracesFile); 4014 } else { 4015 curTracesFile.delete(); 4016 } 4017 } 4018 lastTracesFile = curTracesFile; 4019 } 4020 tracesFile.renameTo(curTracesFile); 4021 if (tracesTmp.exists()) { 4022 tracesTmp.renameTo(tracesFile); 4023 } 4024 } finally { 4025 StrictMode.setThreadPolicy(oldPolicy); 4026 } 4027 } 4028 4029 final void appNotResponding(ProcessRecord app, ActivityRecord activity, 4030 ActivityRecord parent, boolean aboveSystem, final String annotation) { 4031 ArrayList<Integer> firstPids = new ArrayList<Integer>(5); 4032 SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20); 4033 4034 if (mController != null) { 4035 try { 4036 // 0 == continue, -1 = kill process immediately 4037 int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation); 4038 if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid); 4039 } catch (RemoteException e) { 4040 mController = null; 4041 Watchdog.getInstance().setActivityController(null); 4042 } 4043 } 4044 4045 long anrTime = SystemClock.uptimeMillis(); 4046 if (MONITOR_CPU_USAGE) { 4047 updateCpuStatsNow(); 4048 } 4049 4050 synchronized (this) { 4051 // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down. 4052 if (mShuttingDown) { 4053 Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation); 4054 return; 4055 } else if (app.notResponding) { 4056 Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation); 4057 return; 4058 } else if (app.crashing) { 4059 Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation); 4060 return; 4061 } 4062 4063 // In case we come through here for the same app before completing 4064 // this one, mark as anring now so we will bail out. 4065 app.notResponding = true; 4066 4067 // Log the ANR to the event log. 4068 EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid, 4069 app.processName, app.info.flags, annotation); 4070 4071 // Dump thread traces as quickly as we can, starting with "interesting" processes. 4072 firstPids.add(app.pid); 4073 4074 int parentPid = app.pid; 4075 if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid; 4076 if (parentPid != app.pid) firstPids.add(parentPid); 4077 4078 if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID); 4079 4080 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 4081 ProcessRecord r = mLruProcesses.get(i); 4082 if (r != null && r.thread != null) { 4083 int pid = r.pid; 4084 if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) { 4085 if (r.persistent) { 4086 firstPids.add(pid); 4087 } else { 4088 lastPids.put(pid, Boolean.TRUE); 4089 } 4090 } 4091 } 4092 } 4093 } 4094 4095 // Log the ANR to the main log. 4096 StringBuilder info = new StringBuilder(); 4097 info.setLength(0); 4098 info.append("ANR in ").append(app.processName); 4099 if (activity != null && activity.shortComponentName != null) { 4100 info.append(" (").append(activity.shortComponentName).append(")"); 4101 } 4102 info.append("\n"); 4103 info.append("PID: ").append(app.pid).append("\n"); 4104 if (annotation != null) { 4105 info.append("Reason: ").append(annotation).append("\n"); 4106 } 4107 if (parent != null && parent != activity) { 4108 info.append("Parent: ").append(parent.shortComponentName).append("\n"); 4109 } 4110 4111 final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true); 4112 4113 File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids, 4114 NATIVE_STACKS_OF_INTEREST); 4115 4116 String cpuInfo = null; 4117 if (MONITOR_CPU_USAGE) { 4118 updateCpuStatsNow(); 4119 synchronized (mProcessCpuThread) { 4120 cpuInfo = mProcessCpuTracker.printCurrentState(anrTime); 4121 } 4122 info.append(processCpuTracker.printCurrentLoad()); 4123 info.append(cpuInfo); 4124 } 4125 4126 info.append(processCpuTracker.printCurrentState(anrTime)); 4127 4128 Slog.e(TAG, info.toString()); 4129 if (tracesFile == null) { 4130 // There is no trace file, so dump (only) the alleged culprit's threads to the log 4131 Process.sendSignal(app.pid, Process.SIGNAL_QUIT); 4132 } 4133 4134 addErrorToDropBox("anr", app, app.processName, activity, parent, annotation, 4135 cpuInfo, tracesFile, null); 4136 4137 if (mController != null) { 4138 try { 4139 // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately 4140 int res = mController.appNotResponding(app.processName, app.pid, info.toString()); 4141 if (res != 0) { 4142 if (res < 0 && app.pid != MY_PID) { 4143 Process.killProcess(app.pid); 4144 } else { 4145 synchronized (this) { 4146 mServices.scheduleServiceTimeoutLocked(app); 4147 } 4148 } 4149 return; 4150 } 4151 } catch (RemoteException e) { 4152 mController = null; 4153 Watchdog.getInstance().setActivityController(null); 4154 } 4155 } 4156 4157 // Unless configured otherwise, swallow ANRs in background processes & kill the process. 4158 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), 4159 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; 4160 4161 synchronized (this) { 4162 if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) { 4163 killUnneededProcessLocked(app, "background ANR"); 4164 return; 4165 } 4166 4167 // Set the app's notResponding state, and look up the errorReportReceiver 4168 makeAppNotRespondingLocked(app, 4169 activity != null ? activity.shortComponentName : null, 4170 annotation != null ? "ANR " + annotation : "ANR", 4171 info.toString()); 4172 4173 // Bring up the infamous App Not Responding dialog 4174 Message msg = Message.obtain(); 4175 HashMap<String, Object> map = new HashMap<String, Object>(); 4176 msg.what = SHOW_NOT_RESPONDING_MSG; 4177 msg.obj = map; 4178 msg.arg1 = aboveSystem ? 1 : 0; 4179 map.put("app", app); 4180 if (activity != null) { 4181 map.put("activity", activity); 4182 } 4183 4184 mHandler.sendMessage(msg); 4185 } 4186 } 4187 4188 final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) { 4189 if (!mLaunchWarningShown) { 4190 mLaunchWarningShown = true; 4191 mHandler.post(new Runnable() { 4192 @Override 4193 public void run() { 4194 synchronized (ActivityManagerService.this) { 4195 final Dialog d = new LaunchWarningWindow(mContext, cur, next); 4196 d.show(); 4197 mHandler.postDelayed(new Runnable() { 4198 @Override 4199 public void run() { 4200 synchronized (ActivityManagerService.this) { 4201 d.dismiss(); 4202 mLaunchWarningShown = false; 4203 } 4204 } 4205 }, 4000); 4206 } 4207 } 4208 }); 4209 } 4210 } 4211 4212 @Override 4213 public boolean clearApplicationUserData(final String packageName, 4214 final IPackageDataObserver observer, int userId) { 4215 enforceNotIsolatedCaller("clearApplicationUserData"); 4216 int uid = Binder.getCallingUid(); 4217 int pid = Binder.getCallingPid(); 4218 userId = handleIncomingUser(pid, uid, 4219 userId, false, true, "clearApplicationUserData", null); 4220 long callingId = Binder.clearCallingIdentity(); 4221 try { 4222 IPackageManager pm = AppGlobals.getPackageManager(); 4223 int pkgUid = -1; 4224 synchronized(this) { 4225 try { 4226 pkgUid = pm.getPackageUid(packageName, userId); 4227 } catch (RemoteException e) { 4228 } 4229 if (pkgUid == -1) { 4230 Slog.w(TAG, "Invalid packageName: " + packageName); 4231 if (observer != null) { 4232 try { 4233 observer.onRemoveCompleted(packageName, false); 4234 } catch (RemoteException e) { 4235 Slog.i(TAG, "Observer no longer exists."); 4236 } 4237 } 4238 return false; 4239 } 4240 if (uid == pkgUid || checkComponentPermission( 4241 android.Manifest.permission.CLEAR_APP_USER_DATA, 4242 pid, uid, -1, true) 4243 == PackageManager.PERMISSION_GRANTED) { 4244 forceStopPackageLocked(packageName, pkgUid, "clear data"); 4245 } else { 4246 throw new SecurityException("PID " + pid + " does not have permission " 4247 + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data" 4248 + " of package " + packageName); 4249 } 4250 } 4251 4252 try { 4253 // Clear application user data 4254 pm.clearApplicationUserData(packageName, observer, userId); 4255 4256 // Remove all permissions granted from/to this package 4257 removeUriPermissionsForPackageLocked(packageName, userId, true); 4258 4259 Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED, 4260 Uri.fromParts("package", packageName, null)); 4261 intent.putExtra(Intent.EXTRA_UID, pkgUid); 4262 broadcastIntentInPackage("android", Process.SYSTEM_UID, intent, 4263 null, null, 0, null, null, null, false, false, userId); 4264 } catch (RemoteException e) { 4265 } 4266 } finally { 4267 Binder.restoreCallingIdentity(callingId); 4268 } 4269 return true; 4270 } 4271 4272 @Override 4273 public void killBackgroundProcesses(final String packageName, int userId) { 4274 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 4275 != PackageManager.PERMISSION_GRANTED && 4276 checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES) 4277 != PackageManager.PERMISSION_GRANTED) { 4278 String msg = "Permission Denial: killBackgroundProcesses() from pid=" 4279 + Binder.getCallingPid() 4280 + ", uid=" + Binder.getCallingUid() 4281 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 4282 Slog.w(TAG, msg); 4283 throw new SecurityException(msg); 4284 } 4285 4286 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 4287 userId, true, true, "killBackgroundProcesses", null); 4288 long callingId = Binder.clearCallingIdentity(); 4289 try { 4290 IPackageManager pm = AppGlobals.getPackageManager(); 4291 synchronized(this) { 4292 int appId = -1; 4293 try { 4294 appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0)); 4295 } catch (RemoteException e) { 4296 } 4297 if (appId == -1) { 4298 Slog.w(TAG, "Invalid packageName: " + packageName); 4299 return; 4300 } 4301 killPackageProcessesLocked(packageName, appId, userId, 4302 ProcessList.SERVICE_ADJ, false, true, true, false, "kill background"); 4303 } 4304 } finally { 4305 Binder.restoreCallingIdentity(callingId); 4306 } 4307 } 4308 4309 @Override 4310 public void killAllBackgroundProcesses() { 4311 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 4312 != PackageManager.PERMISSION_GRANTED) { 4313 String msg = "Permission Denial: killAllBackgroundProcesses() from pid=" 4314 + Binder.getCallingPid() 4315 + ", uid=" + Binder.getCallingUid() 4316 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 4317 Slog.w(TAG, msg); 4318 throw new SecurityException(msg); 4319 } 4320 4321 long callingId = Binder.clearCallingIdentity(); 4322 try { 4323 synchronized(this) { 4324 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 4325 final int NP = mProcessNames.getMap().size(); 4326 for (int ip=0; ip<NP; ip++) { 4327 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 4328 final int NA = apps.size(); 4329 for (int ia=0; ia<NA; ia++) { 4330 ProcessRecord app = apps.valueAt(ia); 4331 if (app.persistent) { 4332 // we don't kill persistent processes 4333 continue; 4334 } 4335 if (app.removed) { 4336 procs.add(app); 4337 } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 4338 app.removed = true; 4339 procs.add(app); 4340 } 4341 } 4342 } 4343 4344 int N = procs.size(); 4345 for (int i=0; i<N; i++) { 4346 removeProcessLocked(procs.get(i), false, true, "kill all background"); 4347 } 4348 mAllowLowerMemLevel = true; 4349 updateOomAdjLocked(); 4350 doLowMemReportIfNeededLocked(null); 4351 } 4352 } finally { 4353 Binder.restoreCallingIdentity(callingId); 4354 } 4355 } 4356 4357 @Override 4358 public void forceStopPackage(final String packageName, int userId) { 4359 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 4360 != PackageManager.PERMISSION_GRANTED) { 4361 String msg = "Permission Denial: forceStopPackage() from pid=" 4362 + Binder.getCallingPid() 4363 + ", uid=" + Binder.getCallingUid() 4364 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 4365 Slog.w(TAG, msg); 4366 throw new SecurityException(msg); 4367 } 4368 final int callingPid = Binder.getCallingPid(); 4369 userId = handleIncomingUser(callingPid, Binder.getCallingUid(), 4370 userId, true, true, "forceStopPackage", null); 4371 long callingId = Binder.clearCallingIdentity(); 4372 try { 4373 IPackageManager pm = AppGlobals.getPackageManager(); 4374 synchronized(this) { 4375 int[] users = userId == UserHandle.USER_ALL 4376 ? getUsersLocked() : new int[] { userId }; 4377 for (int user : users) { 4378 int pkgUid = -1; 4379 try { 4380 pkgUid = pm.getPackageUid(packageName, user); 4381 } catch (RemoteException e) { 4382 } 4383 if (pkgUid == -1) { 4384 Slog.w(TAG, "Invalid packageName: " + packageName); 4385 continue; 4386 } 4387 try { 4388 pm.setPackageStoppedState(packageName, true, user); 4389 } catch (RemoteException e) { 4390 } catch (IllegalArgumentException e) { 4391 Slog.w(TAG, "Failed trying to unstop package " 4392 + packageName + ": " + e); 4393 } 4394 if (isUserRunningLocked(user, false)) { 4395 forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid); 4396 } 4397 } 4398 } 4399 } finally { 4400 Binder.restoreCallingIdentity(callingId); 4401 } 4402 } 4403 4404 /* 4405 * The pkg name and app id have to be specified. 4406 */ 4407 @Override 4408 public void killApplicationWithAppId(String pkg, int appid, String reason) { 4409 if (pkg == null) { 4410 return; 4411 } 4412 // Make sure the uid is valid. 4413 if (appid < 0) { 4414 Slog.w(TAG, "Invalid appid specified for pkg : " + pkg); 4415 return; 4416 } 4417 int callerUid = Binder.getCallingUid(); 4418 // Only the system server can kill an application 4419 if (callerUid == Process.SYSTEM_UID) { 4420 // Post an aysnc message to kill the application 4421 Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG); 4422 msg.arg1 = appid; 4423 msg.arg2 = 0; 4424 Bundle bundle = new Bundle(); 4425 bundle.putString("pkg", pkg); 4426 bundle.putString("reason", reason); 4427 msg.obj = bundle; 4428 mHandler.sendMessage(msg); 4429 } else { 4430 throw new SecurityException(callerUid + " cannot kill pkg: " + 4431 pkg); 4432 } 4433 } 4434 4435 @Override 4436 public void closeSystemDialogs(String reason) { 4437 enforceNotIsolatedCaller("closeSystemDialogs"); 4438 4439 final int pid = Binder.getCallingPid(); 4440 final int uid = Binder.getCallingUid(); 4441 final long origId = Binder.clearCallingIdentity(); 4442 try { 4443 synchronized (this) { 4444 // Only allow this from foreground processes, so that background 4445 // applications can't abuse it to prevent system UI from being shown. 4446 if (uid >= Process.FIRST_APPLICATION_UID) { 4447 ProcessRecord proc; 4448 synchronized (mPidsSelfLocked) { 4449 proc = mPidsSelfLocked.get(pid); 4450 } 4451 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 4452 Slog.w(TAG, "Ignoring closeSystemDialogs " + reason 4453 + " from background process " + proc); 4454 return; 4455 } 4456 } 4457 closeSystemDialogsLocked(reason); 4458 } 4459 } finally { 4460 Binder.restoreCallingIdentity(origId); 4461 } 4462 } 4463 4464 void closeSystemDialogsLocked(String reason) { 4465 Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS); 4466 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 4467 | Intent.FLAG_RECEIVER_FOREGROUND); 4468 if (reason != null) { 4469 intent.putExtra("reason", reason); 4470 } 4471 mWindowManager.closeSystemDialogs(reason); 4472 4473 mStackSupervisor.closeSystemDialogsLocked(); 4474 4475 broadcastIntentLocked(null, null, intent, null, 4476 null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1, 4477 Process.SYSTEM_UID, UserHandle.USER_ALL); 4478 } 4479 4480 @Override 4481 public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) { 4482 enforceNotIsolatedCaller("getProcessMemoryInfo"); 4483 Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length]; 4484 for (int i=pids.length-1; i>=0; i--) { 4485 ProcessRecord proc; 4486 int oomAdj; 4487 synchronized (this) { 4488 synchronized (mPidsSelfLocked) { 4489 proc = mPidsSelfLocked.get(pids[i]); 4490 oomAdj = proc != null ? proc.setAdj : 0; 4491 } 4492 } 4493 infos[i] = new Debug.MemoryInfo(); 4494 Debug.getMemoryInfo(pids[i], infos[i]); 4495 if (proc != null) { 4496 synchronized (this) { 4497 if (proc.thread != null && proc.setAdj == oomAdj) { 4498 // Record this for posterity if the process has been stable. 4499 proc.baseProcessTracker.addPss(infos[i].getTotalPss(), 4500 infos[i].getTotalUss(), false, proc.pkgList); 4501 } 4502 } 4503 } 4504 } 4505 return infos; 4506 } 4507 4508 @Override 4509 public long[] getProcessPss(int[] pids) { 4510 enforceNotIsolatedCaller("getProcessPss"); 4511 long[] pss = new long[pids.length]; 4512 for (int i=pids.length-1; i>=0; i--) { 4513 ProcessRecord proc; 4514 int oomAdj; 4515 synchronized (this) { 4516 synchronized (mPidsSelfLocked) { 4517 proc = mPidsSelfLocked.get(pids[i]); 4518 oomAdj = proc != null ? proc.setAdj : 0; 4519 } 4520 } 4521 long[] tmpUss = new long[1]; 4522 pss[i] = Debug.getPss(pids[i], tmpUss); 4523 if (proc != null) { 4524 synchronized (this) { 4525 if (proc.thread != null && proc.setAdj == oomAdj) { 4526 // Record this for posterity if the process has been stable. 4527 proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList); 4528 } 4529 } 4530 } 4531 } 4532 return pss; 4533 } 4534 4535 @Override 4536 public void killApplicationProcess(String processName, int uid) { 4537 if (processName == null) { 4538 return; 4539 } 4540 4541 int callerUid = Binder.getCallingUid(); 4542 // Only the system server can kill an application 4543 if (callerUid == Process.SYSTEM_UID) { 4544 synchronized (this) { 4545 ProcessRecord app = getProcessRecordLocked(processName, uid, true); 4546 if (app != null && app.thread != null) { 4547 try { 4548 app.thread.scheduleSuicide(); 4549 } catch (RemoteException e) { 4550 // If the other end already died, then our work here is done. 4551 } 4552 } else { 4553 Slog.w(TAG, "Process/uid not found attempting kill of " 4554 + processName + " / " + uid); 4555 } 4556 } 4557 } else { 4558 throw new SecurityException(callerUid + " cannot kill app process: " + 4559 processName); 4560 } 4561 } 4562 4563 private void forceStopPackageLocked(final String packageName, int uid, String reason) { 4564 forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false, 4565 false, true, false, false, UserHandle.getUserId(uid), reason); 4566 Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED, 4567 Uri.fromParts("package", packageName, null)); 4568 if (!mProcessesReady) { 4569 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 4570 | Intent.FLAG_RECEIVER_FOREGROUND); 4571 } 4572 intent.putExtra(Intent.EXTRA_UID, uid); 4573 intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid)); 4574 broadcastIntentLocked(null, null, intent, 4575 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 4576 false, false, 4577 MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid)); 4578 } 4579 4580 private void forceStopUserLocked(int userId, String reason) { 4581 forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason); 4582 Intent intent = new Intent(Intent.ACTION_USER_STOPPED); 4583 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 4584 | Intent.FLAG_RECEIVER_FOREGROUND); 4585 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 4586 broadcastIntentLocked(null, null, intent, 4587 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 4588 false, false, 4589 MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 4590 } 4591 4592 private final boolean killPackageProcessesLocked(String packageName, int appId, 4593 int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart, 4594 boolean doit, boolean evenPersistent, String reason) { 4595 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 4596 4597 // Remove all processes this package may have touched: all with the 4598 // same UID (except for the system or root user), and all whose name 4599 // matches the package name. 4600 final String procNamePrefix = packageName != null ? (packageName + ":") : null; 4601 final int NP = mProcessNames.getMap().size(); 4602 for (int ip=0; ip<NP; ip++) { 4603 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 4604 final int NA = apps.size(); 4605 for (int ia=0; ia<NA; ia++) { 4606 ProcessRecord app = apps.valueAt(ia); 4607 if (app.persistent && !evenPersistent) { 4608 // we don't kill persistent processes 4609 continue; 4610 } 4611 if (app.removed) { 4612 if (doit) { 4613 procs.add(app); 4614 } 4615 continue; 4616 } 4617 4618 // Skip process if it doesn't meet our oom adj requirement. 4619 if (app.setAdj < minOomAdj) { 4620 continue; 4621 } 4622 4623 // If no package is specified, we call all processes under the 4624 // give user id. 4625 if (packageName == null) { 4626 if (app.userId != userId) { 4627 continue; 4628 } 4629 if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) { 4630 continue; 4631 } 4632 // Package has been specified, we want to hit all processes 4633 // that match it. We need to qualify this by the processes 4634 // that are running under the specified app and user ID. 4635 } else { 4636 if (UserHandle.getAppId(app.uid) != appId) { 4637 continue; 4638 } 4639 if (userId != UserHandle.USER_ALL && app.userId != userId) { 4640 continue; 4641 } 4642 if (!app.pkgList.containsKey(packageName)) { 4643 continue; 4644 } 4645 } 4646 4647 // Process has passed all conditions, kill it! 4648 if (!doit) { 4649 return true; 4650 } 4651 app.removed = true; 4652 procs.add(app); 4653 } 4654 } 4655 4656 int N = procs.size(); 4657 for (int i=0; i<N; i++) { 4658 removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason); 4659 } 4660 updateOomAdjLocked(); 4661 return N > 0; 4662 } 4663 4664 private final boolean forceStopPackageLocked(String name, int appId, 4665 boolean callerWillRestart, boolean purgeCache, boolean doit, 4666 boolean evenPersistent, boolean uninstalling, int userId, String reason) { 4667 int i; 4668 int N; 4669 4670 if (userId == UserHandle.USER_ALL && name == null) { 4671 Slog.w(TAG, "Can't force stop all processes of all users, that is insane!"); 4672 } 4673 4674 if (appId < 0 && name != null) { 4675 try { 4676 appId = UserHandle.getAppId( 4677 AppGlobals.getPackageManager().getPackageUid(name, 0)); 4678 } catch (RemoteException e) { 4679 } 4680 } 4681 4682 if (doit) { 4683 if (name != null) { 4684 Slog.i(TAG, "Force stopping " + name + " appid=" + appId 4685 + " user=" + userId + ": " + reason); 4686 } else { 4687 Slog.i(TAG, "Force stopping u" + userId + ": " + reason); 4688 } 4689 4690 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap(); 4691 for (int ip=pmap.size()-1; ip>=0; ip--) { 4692 SparseArray<Long> ba = pmap.valueAt(ip); 4693 for (i=ba.size()-1; i>=0; i--) { 4694 boolean remove = false; 4695 final int entUid = ba.keyAt(i); 4696 if (name != null) { 4697 if (userId == UserHandle.USER_ALL) { 4698 if (UserHandle.getAppId(entUid) == appId) { 4699 remove = true; 4700 } 4701 } else { 4702 if (entUid == UserHandle.getUid(userId, appId)) { 4703 remove = true; 4704 } 4705 } 4706 } else if (UserHandle.getUserId(entUid) == userId) { 4707 remove = true; 4708 } 4709 if (remove) { 4710 ba.removeAt(i); 4711 } 4712 } 4713 if (ba.size() == 0) { 4714 pmap.removeAt(ip); 4715 } 4716 } 4717 } 4718 4719 boolean didSomething = killPackageProcessesLocked(name, appId, userId, 4720 -100, callerWillRestart, true, doit, evenPersistent, 4721 name == null ? ("stop user " + userId) : ("stop " + name)); 4722 4723 if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) { 4724 if (!doit) { 4725 return true; 4726 } 4727 didSomething = true; 4728 } 4729 4730 if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) { 4731 if (!doit) { 4732 return true; 4733 } 4734 didSomething = true; 4735 } 4736 4737 if (name == null) { 4738 // Remove all sticky broadcasts from this user. 4739 mStickyBroadcasts.remove(userId); 4740 } 4741 4742 ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>(); 4743 if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent, 4744 userId, providers)) { 4745 if (!doit) { 4746 return true; 4747 } 4748 didSomething = true; 4749 } 4750 N = providers.size(); 4751 for (i=0; i<N; i++) { 4752 removeDyingProviderLocked(null, providers.get(i), true); 4753 } 4754 4755 // Remove transient permissions granted from/to this package/user 4756 removeUriPermissionsForPackageLocked(name, userId, false); 4757 4758 if (name == null || uninstalling) { 4759 // Remove pending intents. For now we only do this when force 4760 // stopping users, because we have some problems when doing this 4761 // for packages -- app widgets are not currently cleaned up for 4762 // such packages, so they can be left with bad pending intents. 4763 if (mIntentSenderRecords.size() > 0) { 4764 Iterator<WeakReference<PendingIntentRecord>> it 4765 = mIntentSenderRecords.values().iterator(); 4766 while (it.hasNext()) { 4767 WeakReference<PendingIntentRecord> wpir = it.next(); 4768 if (wpir == null) { 4769 it.remove(); 4770 continue; 4771 } 4772 PendingIntentRecord pir = wpir.get(); 4773 if (pir == null) { 4774 it.remove(); 4775 continue; 4776 } 4777 if (name == null) { 4778 // Stopping user, remove all objects for the user. 4779 if (pir.key.userId != userId) { 4780 // Not the same user, skip it. 4781 continue; 4782 } 4783 } else { 4784 if (UserHandle.getAppId(pir.uid) != appId) { 4785 // Different app id, skip it. 4786 continue; 4787 } 4788 if (userId != UserHandle.USER_ALL && pir.key.userId != userId) { 4789 // Different user, skip it. 4790 continue; 4791 } 4792 if (!pir.key.packageName.equals(name)) { 4793 // Different package, skip it. 4794 continue; 4795 } 4796 } 4797 if (!doit) { 4798 return true; 4799 } 4800 didSomething = true; 4801 it.remove(); 4802 pir.canceled = true; 4803 if (pir.key.activity != null) { 4804 pir.key.activity.pendingResults.remove(pir.ref); 4805 } 4806 } 4807 } 4808 } 4809 4810 if (doit) { 4811 if (purgeCache && name != null) { 4812 AttributeCache ac = AttributeCache.instance(); 4813 if (ac != null) { 4814 ac.removePackage(name); 4815 } 4816 } 4817 if (mBooted) { 4818 mStackSupervisor.resumeTopActivitiesLocked(); 4819 mStackSupervisor.scheduleIdleLocked(); 4820 } 4821 } 4822 4823 return didSomething; 4824 } 4825 4826 private final boolean removeProcessLocked(ProcessRecord app, 4827 boolean callerWillRestart, boolean allowRestart, String reason) { 4828 final String name = app.processName; 4829 final int uid = app.uid; 4830 if (DEBUG_PROCESSES) Slog.d( 4831 TAG, "Force removing proc " + app.toShortString() + " (" + name 4832 + "/" + uid + ")"); 4833 4834 mProcessNames.remove(name, uid); 4835 mIsolatedProcesses.remove(app.uid); 4836 if (mHeavyWeightProcess == app) { 4837 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 4838 mHeavyWeightProcess.userId, 0)); 4839 mHeavyWeightProcess = null; 4840 } 4841 boolean needRestart = false; 4842 if (app.pid > 0 && app.pid != MY_PID) { 4843 int pid = app.pid; 4844 synchronized (mPidsSelfLocked) { 4845 mPidsSelfLocked.remove(pid); 4846 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 4847 } 4848 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH, 4849 app.processName, app.info.uid); 4850 if (app.isolated) { 4851 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 4852 } 4853 killUnneededProcessLocked(app, reason); 4854 handleAppDiedLocked(app, true, allowRestart); 4855 removeLruProcessLocked(app); 4856 4857 if (app.persistent && !app.isolated) { 4858 if (!callerWillRestart) { 4859 addAppLocked(app.info, false); 4860 } else { 4861 needRestart = true; 4862 } 4863 } 4864 } else { 4865 mRemovedProcesses.add(app); 4866 } 4867 4868 return needRestart; 4869 } 4870 4871 private final void processStartTimedOutLocked(ProcessRecord app) { 4872 final int pid = app.pid; 4873 boolean gone = false; 4874 synchronized (mPidsSelfLocked) { 4875 ProcessRecord knownApp = mPidsSelfLocked.get(pid); 4876 if (knownApp != null && knownApp.thread == null) { 4877 mPidsSelfLocked.remove(pid); 4878 gone = true; 4879 } 4880 } 4881 4882 if (gone) { 4883 Slog.w(TAG, "Process " + app + " failed to attach"); 4884 EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId, 4885 pid, app.uid, app.processName); 4886 mProcessNames.remove(app.processName, app.uid); 4887 mIsolatedProcesses.remove(app.uid); 4888 if (mHeavyWeightProcess == app) { 4889 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 4890 mHeavyWeightProcess.userId, 0)); 4891 mHeavyWeightProcess = null; 4892 } 4893 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH, 4894 app.processName, app.info.uid); 4895 if (app.isolated) { 4896 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 4897 } 4898 // Take care of any launching providers waiting for this process. 4899 checkAppInLaunchingProvidersLocked(app, true); 4900 // Take care of any services that are waiting for the process. 4901 mServices.processStartTimedOutLocked(app); 4902 killUnneededProcessLocked(app, "start timeout"); 4903 if (mBackupTarget != null && mBackupTarget.app.pid == pid) { 4904 Slog.w(TAG, "Unattached app died before backup, skipping"); 4905 try { 4906 IBackupManager bm = IBackupManager.Stub.asInterface( 4907 ServiceManager.getService(Context.BACKUP_SERVICE)); 4908 bm.agentDisconnected(app.info.packageName); 4909 } catch (RemoteException e) { 4910 // Can't happen; the backup manager is local 4911 } 4912 } 4913 if (isPendingBroadcastProcessLocked(pid)) { 4914 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 4915 skipPendingBroadcastLocked(pid); 4916 } 4917 } else { 4918 Slog.w(TAG, "Spurious process start timeout - pid not known for " + app); 4919 } 4920 } 4921 4922 private final boolean attachApplicationLocked(IApplicationThread thread, 4923 int pid) { 4924 4925 // Find the application record that is being attached... either via 4926 // the pid if we are running in multiple processes, or just pull the 4927 // next app record if we are emulating process with anonymous threads. 4928 ProcessRecord app; 4929 if (pid != MY_PID && pid >= 0) { 4930 synchronized (mPidsSelfLocked) { 4931 app = mPidsSelfLocked.get(pid); 4932 } 4933 } else { 4934 app = null; 4935 } 4936 4937 if (app == null) { 4938 Slog.w(TAG, "No pending application record for pid " + pid 4939 + " (IApplicationThread " + thread + "); dropping process"); 4940 EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid); 4941 if (pid > 0 && pid != MY_PID) { 4942 Process.killProcessQuiet(pid); 4943 } else { 4944 try { 4945 thread.scheduleExit(); 4946 } catch (Exception e) { 4947 // Ignore exceptions. 4948 } 4949 } 4950 return false; 4951 } 4952 4953 // If this application record is still attached to a previous 4954 // process, clean it up now. 4955 if (app.thread != null) { 4956 handleAppDiedLocked(app, true, true); 4957 } 4958 4959 // Tell the process all about itself. 4960 4961 if (localLOGV) Slog.v( 4962 TAG, "Binding process pid " + pid + " to record " + app); 4963 4964 final String processName = app.processName; 4965 try { 4966 AppDeathRecipient adr = new AppDeathRecipient( 4967 app, pid, thread); 4968 thread.asBinder().linkToDeath(adr, 0); 4969 app.deathRecipient = adr; 4970 } catch (RemoteException e) { 4971 app.resetPackageList(mProcessStats); 4972 startProcessLocked(app, "link fail", processName); 4973 return false; 4974 } 4975 4976 EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName); 4977 4978 app.makeActive(thread, mProcessStats); 4979 app.curAdj = app.setAdj = -100; 4980 app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT; 4981 app.forcingToForeground = null; 4982 updateProcessForegroundLocked(app, false, false); 4983 app.hasShownUi = false; 4984 app.debugging = false; 4985 app.cached = false; 4986 4987 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 4988 4989 boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info); 4990 List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null; 4991 4992 if (!normalMode) { 4993 Slog.i(TAG, "Launching preboot mode app: " + app); 4994 } 4995 4996 if (localLOGV) Slog.v( 4997 TAG, "New app record " + app 4998 + " thread=" + thread.asBinder() + " pid=" + pid); 4999 try { 5000 int testMode = IApplicationThread.DEBUG_OFF; 5001 if (mDebugApp != null && mDebugApp.equals(processName)) { 5002 testMode = mWaitForDebugger 5003 ? IApplicationThread.DEBUG_WAIT 5004 : IApplicationThread.DEBUG_ON; 5005 app.debugging = true; 5006 if (mDebugTransient) { 5007 mDebugApp = mOrigDebugApp; 5008 mWaitForDebugger = mOrigWaitForDebugger; 5009 } 5010 } 5011 String profileFile = app.instrumentationProfileFile; 5012 ParcelFileDescriptor profileFd = null; 5013 boolean profileAutoStop = false; 5014 if (mProfileApp != null && mProfileApp.equals(processName)) { 5015 mProfileProc = app; 5016 profileFile = mProfileFile; 5017 profileFd = mProfileFd; 5018 profileAutoStop = mAutoStopProfiler; 5019 } 5020 boolean enableOpenGlTrace = false; 5021 if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) { 5022 enableOpenGlTrace = true; 5023 mOpenGlTraceApp = null; 5024 } 5025 5026 // If the app is being launched for restore or full backup, set it up specially 5027 boolean isRestrictedBackupMode = false; 5028 if (mBackupTarget != null && mBackupAppName.equals(processName)) { 5029 isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE) 5030 || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL) 5031 || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL); 5032 } 5033 5034 ensurePackageDexOpt(app.instrumentationInfo != null 5035 ? app.instrumentationInfo.packageName 5036 : app.info.packageName); 5037 if (app.instrumentationClass != null) { 5038 ensurePackageDexOpt(app.instrumentationClass.getPackageName()); 5039 } 5040 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc " 5041 + processName + " with config " + mConfiguration); 5042 ApplicationInfo appInfo = app.instrumentationInfo != null 5043 ? app.instrumentationInfo : app.info; 5044 app.compat = compatibilityInfoForPackageLocked(appInfo); 5045 if (profileFd != null) { 5046 profileFd = profileFd.dup(); 5047 } 5048 thread.bindApplication(processName, appInfo, providers, 5049 app.instrumentationClass, profileFile, profileFd, profileAutoStop, 5050 app.instrumentationArguments, app.instrumentationWatcher, 5051 app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace, 5052 isRestrictedBackupMode || !normalMode, app.persistent, 5053 new Configuration(mConfiguration), app.compat, getCommonServicesLocked(), 5054 mCoreSettingsObserver.getCoreSettingsLocked()); 5055 updateLruProcessLocked(app, false, null); 5056 app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis(); 5057 } catch (Exception e) { 5058 // todo: Yikes! What should we do? For now we will try to 5059 // start another process, but that could easily get us in 5060 // an infinite loop of restarting processes... 5061 Slog.w(TAG, "Exception thrown during bind!", e); 5062 5063 app.resetPackageList(mProcessStats); 5064 app.unlinkDeathRecipient(); 5065 startProcessLocked(app, "bind fail", processName); 5066 return false; 5067 } 5068 5069 // Remove this record from the list of starting applications. 5070 mPersistentStartingProcesses.remove(app); 5071 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 5072 "Attach application locked removing on hold: " + app); 5073 mProcessesOnHold.remove(app); 5074 5075 boolean badApp = false; 5076 boolean didSomething = false; 5077 5078 // See if the top visible activity is waiting to run in this process... 5079 if (normalMode) { 5080 try { 5081 if (mStackSupervisor.attachApplicationLocked(app)) { 5082 didSomething = true; 5083 } 5084 } catch (Exception e) { 5085 badApp = true; 5086 } 5087 } 5088 5089 // Find any services that should be running in this process... 5090 if (!badApp) { 5091 try { 5092 didSomething |= mServices.attachApplicationLocked(app, processName); 5093 } catch (Exception e) { 5094 badApp = true; 5095 } 5096 } 5097 5098 // Check if a next-broadcast receiver is in this process... 5099 if (!badApp && isPendingBroadcastProcessLocked(pid)) { 5100 try { 5101 didSomething |= sendPendingBroadcastsLocked(app); 5102 } catch (Exception e) { 5103 // If the app died trying to launch the receiver we declare it 'bad' 5104 badApp = true; 5105 } 5106 } 5107 5108 // Check whether the next backup agent is in this process... 5109 if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) { 5110 if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app); 5111 ensurePackageDexOpt(mBackupTarget.appInfo.packageName); 5112 try { 5113 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo, 5114 compatibilityInfoForPackageLocked(mBackupTarget.appInfo), 5115 mBackupTarget.backupMode); 5116 } catch (Exception e) { 5117 Slog.w(TAG, "Exception scheduling backup agent creation: "); 5118 e.printStackTrace(); 5119 } 5120 } 5121 5122 if (badApp) { 5123 // todo: Also need to kill application to deal with all 5124 // kinds of exceptions. 5125 handleAppDiedLocked(app, false, true); 5126 return false; 5127 } 5128 5129 if (!didSomething) { 5130 updateOomAdjLocked(); 5131 } 5132 5133 return true; 5134 } 5135 5136 @Override 5137 public final void attachApplication(IApplicationThread thread) { 5138 synchronized (this) { 5139 int callingPid = Binder.getCallingPid(); 5140 final long origId = Binder.clearCallingIdentity(); 5141 attachApplicationLocked(thread, callingPid); 5142 Binder.restoreCallingIdentity(origId); 5143 } 5144 } 5145 5146 @Override 5147 public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) { 5148 final long origId = Binder.clearCallingIdentity(); 5149 synchronized (this) { 5150 ActivityStack stack = ActivityRecord.getStackLocked(token); 5151 if (stack != null) { 5152 ActivityRecord r = 5153 mStackSupervisor.activityIdleInternalLocked(token, false, config); 5154 if (stopProfiling) { 5155 if ((mProfileProc == r.app) && (mProfileFd != null)) { 5156 try { 5157 mProfileFd.close(); 5158 } catch (IOException e) { 5159 } 5160 clearProfilerLocked(); 5161 } 5162 } 5163 } 5164 } 5165 Binder.restoreCallingIdentity(origId); 5166 } 5167 5168 void enableScreenAfterBoot() { 5169 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN, 5170 SystemClock.uptimeMillis()); 5171 mWindowManager.enableScreenAfterBoot(); 5172 5173 synchronized (this) { 5174 updateEventDispatchingLocked(); 5175 } 5176 } 5177 5178 @Override 5179 public void showBootMessage(final CharSequence msg, final boolean always) { 5180 enforceNotIsolatedCaller("showBootMessage"); 5181 mWindowManager.showBootMessage(msg, always); 5182 } 5183 5184 @Override 5185 public void dismissKeyguardOnNextActivity() { 5186 enforceNotIsolatedCaller("dismissKeyguardOnNextActivity"); 5187 final long token = Binder.clearCallingIdentity(); 5188 try { 5189 synchronized (this) { 5190 if (DEBUG_LOCKSCREEN) logLockScreen(""); 5191 if (mLockScreenShown) { 5192 mLockScreenShown = false; 5193 comeOutOfSleepIfNeededLocked(); 5194 } 5195 mStackSupervisor.setDismissKeyguard(true); 5196 } 5197 } finally { 5198 Binder.restoreCallingIdentity(token); 5199 } 5200 } 5201 5202 final void finishBooting() { 5203 IntentFilter pkgFilter = new IntentFilter(); 5204 pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART); 5205 pkgFilter.addDataScheme("package"); 5206 mContext.registerReceiver(new BroadcastReceiver() { 5207 @Override 5208 public void onReceive(Context context, Intent intent) { 5209 String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES); 5210 if (pkgs != null) { 5211 for (String pkg : pkgs) { 5212 synchronized (ActivityManagerService.this) { 5213 if (forceStopPackageLocked(pkg, -1, false, false, false, false, false, 0, 5214 "finished booting")) { 5215 setResultCode(Activity.RESULT_OK); 5216 return; 5217 } 5218 } 5219 } 5220 } 5221 } 5222 }, pkgFilter); 5223 5224 synchronized (this) { 5225 // Ensure that any processes we had put on hold are now started 5226 // up. 5227 final int NP = mProcessesOnHold.size(); 5228 if (NP > 0) { 5229 ArrayList<ProcessRecord> procs = 5230 new ArrayList<ProcessRecord>(mProcessesOnHold); 5231 for (int ip=0; ip<NP; ip++) { 5232 if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: " 5233 + procs.get(ip)); 5234 startProcessLocked(procs.get(ip), "on-hold", null); 5235 } 5236 } 5237 5238 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 5239 // Start looking for apps that are abusing wake locks. 5240 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 5241 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 5242 // Tell anyone interested that we are done booting! 5243 SystemProperties.set("sys.boot_completed", "1"); 5244 SystemProperties.set("dev.bootcomplete", "1"); 5245 for (int i=0; i<mStartedUsers.size(); i++) { 5246 UserStartedState uss = mStartedUsers.valueAt(i); 5247 if (uss.mState == UserStartedState.STATE_BOOTING) { 5248 uss.mState = UserStartedState.STATE_RUNNING; 5249 final int userId = mStartedUsers.keyAt(i); 5250 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 5251 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 5252 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT); 5253 broadcastIntentLocked(null, null, intent, null, 5254 new IIntentReceiver.Stub() { 5255 @Override 5256 public void performReceive(Intent intent, int resultCode, 5257 String data, Bundle extras, boolean ordered, 5258 boolean sticky, int sendingUser) { 5259 synchronized (ActivityManagerService.this) { 5260 requestPssAllProcsLocked(SystemClock.uptimeMillis(), 5261 true, false); 5262 } 5263 } 5264 }, 5265 0, null, null, 5266 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, 5267 AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID, 5268 userId); 5269 } 5270 } 5271 scheduleStartProfilesLocked(); 5272 } 5273 } 5274 } 5275 5276 final void ensureBootCompleted() { 5277 boolean booting; 5278 boolean enableScreen; 5279 synchronized (this) { 5280 booting = mBooting; 5281 mBooting = false; 5282 enableScreen = !mBooted; 5283 mBooted = true; 5284 } 5285 5286 if (booting) { 5287 finishBooting(); 5288 } 5289 5290 if (enableScreen) { 5291 enableScreenAfterBoot(); 5292 } 5293 } 5294 5295 @Override 5296 public final void activityResumed(IBinder token) { 5297 final long origId = Binder.clearCallingIdentity(); 5298 synchronized(this) { 5299 ActivityStack stack = ActivityRecord.getStackLocked(token); 5300 if (stack != null) { 5301 ActivityRecord.activityResumedLocked(token); 5302 } 5303 } 5304 Binder.restoreCallingIdentity(origId); 5305 } 5306 5307 @Override 5308 public final void activityPaused(IBinder token) { 5309 final long origId = Binder.clearCallingIdentity(); 5310 synchronized(this) { 5311 ActivityStack stack = ActivityRecord.getStackLocked(token); 5312 if (stack != null) { 5313 stack.activityPausedLocked(token, false); 5314 } 5315 } 5316 Binder.restoreCallingIdentity(origId); 5317 } 5318 5319 @Override 5320 public final void activityStopped(IBinder token, Bundle icicle, Bitmap thumbnail, 5321 CharSequence description) { 5322 if (localLOGV) Slog.v( 5323 TAG, "Activity stopped: token=" + token); 5324 5325 // Refuse possible leaked file descriptors 5326 if (icicle != null && icicle.hasFileDescriptors()) { 5327 throw new IllegalArgumentException("File descriptors passed in Bundle"); 5328 } 5329 5330 ActivityRecord r = null; 5331 5332 final long origId = Binder.clearCallingIdentity(); 5333 5334 synchronized (this) { 5335 r = ActivityRecord.isInStackLocked(token); 5336 if (r != null) { 5337 r.task.stack.activityStoppedLocked(r, icicle, thumbnail, description); 5338 } 5339 } 5340 5341 if (r != null) { 5342 sendPendingThumbnail(r, null, null, null, false); 5343 } 5344 5345 trimApplications(); 5346 5347 Binder.restoreCallingIdentity(origId); 5348 } 5349 5350 @Override 5351 public final void activityDestroyed(IBinder token) { 5352 if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token); 5353 synchronized (this) { 5354 ActivityStack stack = ActivityRecord.getStackLocked(token); 5355 if (stack != null) { 5356 stack.activityDestroyedLocked(token); 5357 } 5358 } 5359 } 5360 5361 @Override 5362 public String getCallingPackage(IBinder token) { 5363 synchronized (this) { 5364 ActivityRecord r = getCallingRecordLocked(token); 5365 return r != null ? r.info.packageName : null; 5366 } 5367 } 5368 5369 @Override 5370 public ComponentName getCallingActivity(IBinder token) { 5371 synchronized (this) { 5372 ActivityRecord r = getCallingRecordLocked(token); 5373 return r != null ? r.intent.getComponent() : null; 5374 } 5375 } 5376 5377 private ActivityRecord getCallingRecordLocked(IBinder token) { 5378 ActivityRecord r = ActivityRecord.isInStackLocked(token); 5379 if (r == null) { 5380 return null; 5381 } 5382 return r.resultTo; 5383 } 5384 5385 @Override 5386 public ComponentName getActivityClassForToken(IBinder token) { 5387 synchronized(this) { 5388 ActivityRecord r = ActivityRecord.isInStackLocked(token); 5389 if (r == null) { 5390 return null; 5391 } 5392 return r.intent.getComponent(); 5393 } 5394 } 5395 5396 @Override 5397 public String getPackageForToken(IBinder token) { 5398 synchronized(this) { 5399 ActivityRecord r = ActivityRecord.isInStackLocked(token); 5400 if (r == null) { 5401 return null; 5402 } 5403 return r.packageName; 5404 } 5405 } 5406 5407 @Override 5408 public IIntentSender getIntentSender(int type, 5409 String packageName, IBinder token, String resultWho, 5410 int requestCode, Intent[] intents, String[] resolvedTypes, 5411 int flags, Bundle options, int userId) { 5412 enforceNotIsolatedCaller("getIntentSender"); 5413 // Refuse possible leaked file descriptors 5414 if (intents != null) { 5415 if (intents.length < 1) { 5416 throw new IllegalArgumentException("Intents array length must be >= 1"); 5417 } 5418 for (int i=0; i<intents.length; i++) { 5419 Intent intent = intents[i]; 5420 if (intent != null) { 5421 if (intent.hasFileDescriptors()) { 5422 throw new IllegalArgumentException("File descriptors passed in Intent"); 5423 } 5424 if (type == ActivityManager.INTENT_SENDER_BROADCAST && 5425 (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 5426 throw new IllegalArgumentException( 5427 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 5428 } 5429 intents[i] = new Intent(intent); 5430 } 5431 } 5432 if (resolvedTypes != null && resolvedTypes.length != intents.length) { 5433 throw new IllegalArgumentException( 5434 "Intent array length does not match resolvedTypes length"); 5435 } 5436 } 5437 if (options != null) { 5438 if (options.hasFileDescriptors()) { 5439 throw new IllegalArgumentException("File descriptors passed in options"); 5440 } 5441 } 5442 5443 synchronized(this) { 5444 int callingUid = Binder.getCallingUid(); 5445 int origUserId = userId; 5446 userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId, 5447 type == ActivityManager.INTENT_SENDER_BROADCAST, false, 5448 "getIntentSender", null); 5449 if (origUserId == UserHandle.USER_CURRENT) { 5450 // We don't want to evaluate this until the pending intent is 5451 // actually executed. However, we do want to always do the 5452 // security checking for it above. 5453 userId = UserHandle.USER_CURRENT; 5454 } 5455 try { 5456 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 5457 int uid = AppGlobals.getPackageManager() 5458 .getPackageUid(packageName, UserHandle.getUserId(callingUid)); 5459 if (!UserHandle.isSameApp(callingUid, uid)) { 5460 String msg = "Permission Denial: getIntentSender() from pid=" 5461 + Binder.getCallingPid() 5462 + ", uid=" + Binder.getCallingUid() 5463 + ", (need uid=" + uid + ")" 5464 + " is not allowed to send as package " + packageName; 5465 Slog.w(TAG, msg); 5466 throw new SecurityException(msg); 5467 } 5468 } 5469 5470 return getIntentSenderLocked(type, packageName, callingUid, userId, 5471 token, resultWho, requestCode, intents, resolvedTypes, flags, options); 5472 5473 } catch (RemoteException e) { 5474 throw new SecurityException(e); 5475 } 5476 } 5477 } 5478 5479 IIntentSender getIntentSenderLocked(int type, String packageName, 5480 int callingUid, int userId, IBinder token, String resultWho, 5481 int requestCode, Intent[] intents, String[] resolvedTypes, int flags, 5482 Bundle options) { 5483 if (DEBUG_MU) 5484 Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid); 5485 ActivityRecord activity = null; 5486 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 5487 activity = ActivityRecord.isInStackLocked(token); 5488 if (activity == null) { 5489 return null; 5490 } 5491 if (activity.finishing) { 5492 return null; 5493 } 5494 } 5495 5496 final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0; 5497 final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0; 5498 final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0; 5499 flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT 5500 |PendingIntent.FLAG_UPDATE_CURRENT); 5501 5502 PendingIntentRecord.Key key = new PendingIntentRecord.Key( 5503 type, packageName, activity, resultWho, 5504 requestCode, intents, resolvedTypes, flags, options, userId); 5505 WeakReference<PendingIntentRecord> ref; 5506 ref = mIntentSenderRecords.get(key); 5507 PendingIntentRecord rec = ref != null ? ref.get() : null; 5508 if (rec != null) { 5509 if (!cancelCurrent) { 5510 if (updateCurrent) { 5511 if (rec.key.requestIntent != null) { 5512 rec.key.requestIntent.replaceExtras(intents != null ? 5513 intents[intents.length - 1] : null); 5514 } 5515 if (intents != null) { 5516 intents[intents.length-1] = rec.key.requestIntent; 5517 rec.key.allIntents = intents; 5518 rec.key.allResolvedTypes = resolvedTypes; 5519 } else { 5520 rec.key.allIntents = null; 5521 rec.key.allResolvedTypes = null; 5522 } 5523 } 5524 return rec; 5525 } 5526 rec.canceled = true; 5527 mIntentSenderRecords.remove(key); 5528 } 5529 if (noCreate) { 5530 return rec; 5531 } 5532 rec = new PendingIntentRecord(this, key, callingUid); 5533 mIntentSenderRecords.put(key, rec.ref); 5534 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 5535 if (activity.pendingResults == null) { 5536 activity.pendingResults 5537 = new HashSet<WeakReference<PendingIntentRecord>>(); 5538 } 5539 activity.pendingResults.add(rec.ref); 5540 } 5541 return rec; 5542 } 5543 5544 @Override 5545 public void cancelIntentSender(IIntentSender sender) { 5546 if (!(sender instanceof PendingIntentRecord)) { 5547 return; 5548 } 5549 synchronized(this) { 5550 PendingIntentRecord rec = (PendingIntentRecord)sender; 5551 try { 5552 int uid = AppGlobals.getPackageManager() 5553 .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId()); 5554 if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) { 5555 String msg = "Permission Denial: cancelIntentSender() from pid=" 5556 + Binder.getCallingPid() 5557 + ", uid=" + Binder.getCallingUid() 5558 + " is not allowed to cancel packges " 5559 + rec.key.packageName; 5560 Slog.w(TAG, msg); 5561 throw new SecurityException(msg); 5562 } 5563 } catch (RemoteException e) { 5564 throw new SecurityException(e); 5565 } 5566 cancelIntentSenderLocked(rec, true); 5567 } 5568 } 5569 5570 void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) { 5571 rec.canceled = true; 5572 mIntentSenderRecords.remove(rec.key); 5573 if (cleanActivity && rec.key.activity != null) { 5574 rec.key.activity.pendingResults.remove(rec.ref); 5575 } 5576 } 5577 5578 @Override 5579 public String getPackageForIntentSender(IIntentSender pendingResult) { 5580 if (!(pendingResult instanceof PendingIntentRecord)) { 5581 return null; 5582 } 5583 try { 5584 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5585 return res.key.packageName; 5586 } catch (ClassCastException e) { 5587 } 5588 return null; 5589 } 5590 5591 @Override 5592 public int getUidForIntentSender(IIntentSender sender) { 5593 if (sender instanceof PendingIntentRecord) { 5594 try { 5595 PendingIntentRecord res = (PendingIntentRecord)sender; 5596 return res.uid; 5597 } catch (ClassCastException e) { 5598 } 5599 } 5600 return -1; 5601 } 5602 5603 @Override 5604 public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) { 5605 if (!(pendingResult instanceof PendingIntentRecord)) { 5606 return false; 5607 } 5608 try { 5609 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5610 if (res.key.allIntents == null) { 5611 return false; 5612 } 5613 for (int i=0; i<res.key.allIntents.length; i++) { 5614 Intent intent = res.key.allIntents[i]; 5615 if (intent.getPackage() != null && intent.getComponent() != null) { 5616 return false; 5617 } 5618 } 5619 return true; 5620 } catch (ClassCastException e) { 5621 } 5622 return false; 5623 } 5624 5625 @Override 5626 public boolean isIntentSenderAnActivity(IIntentSender pendingResult) { 5627 if (!(pendingResult instanceof PendingIntentRecord)) { 5628 return false; 5629 } 5630 try { 5631 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5632 if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) { 5633 return true; 5634 } 5635 return false; 5636 } catch (ClassCastException e) { 5637 } 5638 return false; 5639 } 5640 5641 @Override 5642 public Intent getIntentForIntentSender(IIntentSender pendingResult) { 5643 if (!(pendingResult instanceof PendingIntentRecord)) { 5644 return null; 5645 } 5646 try { 5647 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5648 return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null; 5649 } catch (ClassCastException e) { 5650 } 5651 return null; 5652 } 5653 5654 @Override 5655 public String getTagForIntentSender(IIntentSender pendingResult, String prefix) { 5656 if (!(pendingResult instanceof PendingIntentRecord)) { 5657 return null; 5658 } 5659 try { 5660 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5661 Intent intent = res.key.requestIntent; 5662 if (intent != null) { 5663 if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null 5664 || res.lastTagPrefix.equals(prefix))) { 5665 return res.lastTag; 5666 } 5667 res.lastTagPrefix = prefix; 5668 StringBuilder sb = new StringBuilder(128); 5669 if (prefix != null) { 5670 sb.append(prefix); 5671 } 5672 if (intent.getAction() != null) { 5673 sb.append(intent.getAction()); 5674 } else if (intent.getComponent() != null) { 5675 intent.getComponent().appendShortString(sb); 5676 } else { 5677 sb.append("?"); 5678 } 5679 return res.lastTag = sb.toString(); 5680 } 5681 } catch (ClassCastException e) { 5682 } 5683 return null; 5684 } 5685 5686 @Override 5687 public void setProcessLimit(int max) { 5688 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 5689 "setProcessLimit()"); 5690 synchronized (this) { 5691 mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max; 5692 mProcessLimitOverride = max; 5693 } 5694 trimApplications(); 5695 } 5696 5697 @Override 5698 public int getProcessLimit() { 5699 synchronized (this) { 5700 return mProcessLimitOverride; 5701 } 5702 } 5703 5704 void foregroundTokenDied(ForegroundToken token) { 5705 synchronized (ActivityManagerService.this) { 5706 synchronized (mPidsSelfLocked) { 5707 ForegroundToken cur 5708 = mForegroundProcesses.get(token.pid); 5709 if (cur != token) { 5710 return; 5711 } 5712 mForegroundProcesses.remove(token.pid); 5713 ProcessRecord pr = mPidsSelfLocked.get(token.pid); 5714 if (pr == null) { 5715 return; 5716 } 5717 pr.forcingToForeground = null; 5718 updateProcessForegroundLocked(pr, false, false); 5719 } 5720 updateOomAdjLocked(); 5721 } 5722 } 5723 5724 @Override 5725 public void setProcessForeground(IBinder token, int pid, boolean isForeground) { 5726 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 5727 "setProcessForeground()"); 5728 synchronized(this) { 5729 boolean changed = false; 5730 5731 synchronized (mPidsSelfLocked) { 5732 ProcessRecord pr = mPidsSelfLocked.get(pid); 5733 if (pr == null && isForeground) { 5734 Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid); 5735 return; 5736 } 5737 ForegroundToken oldToken = mForegroundProcesses.get(pid); 5738 if (oldToken != null) { 5739 oldToken.token.unlinkToDeath(oldToken, 0); 5740 mForegroundProcesses.remove(pid); 5741 if (pr != null) { 5742 pr.forcingToForeground = null; 5743 } 5744 changed = true; 5745 } 5746 if (isForeground && token != null) { 5747 ForegroundToken newToken = new ForegroundToken() { 5748 @Override 5749 public void binderDied() { 5750 foregroundTokenDied(this); 5751 } 5752 }; 5753 newToken.pid = pid; 5754 newToken.token = token; 5755 try { 5756 token.linkToDeath(newToken, 0); 5757 mForegroundProcesses.put(pid, newToken); 5758 pr.forcingToForeground = token; 5759 changed = true; 5760 } catch (RemoteException e) { 5761 // If the process died while doing this, we will later 5762 // do the cleanup with the process death link. 5763 } 5764 } 5765 } 5766 5767 if (changed) { 5768 updateOomAdjLocked(); 5769 } 5770 } 5771 } 5772 5773 // ========================================================= 5774 // PERMISSIONS 5775 // ========================================================= 5776 5777 static class PermissionController extends IPermissionController.Stub { 5778 ActivityManagerService mActivityManagerService; 5779 PermissionController(ActivityManagerService activityManagerService) { 5780 mActivityManagerService = activityManagerService; 5781 } 5782 5783 @Override 5784 public boolean checkPermission(String permission, int pid, int uid) { 5785 return mActivityManagerService.checkPermission(permission, pid, 5786 uid) == PackageManager.PERMISSION_GRANTED; 5787 } 5788 } 5789 5790 class IntentFirewallInterface implements IntentFirewall.AMSInterface { 5791 @Override 5792 public int checkComponentPermission(String permission, int pid, int uid, 5793 int owningUid, boolean exported) { 5794 return ActivityManagerService.this.checkComponentPermission(permission, pid, uid, 5795 owningUid, exported); 5796 } 5797 5798 @Override 5799 public Object getAMSLock() { 5800 return ActivityManagerService.this; 5801 } 5802 } 5803 5804 /** 5805 * This can be called with or without the global lock held. 5806 */ 5807 int checkComponentPermission(String permission, int pid, int uid, 5808 int owningUid, boolean exported) { 5809 // We might be performing an operation on behalf of an indirect binder 5810 // invocation, e.g. via {@link #openContentUri}. Check and adjust the 5811 // client identity accordingly before proceeding. 5812 Identity tlsIdentity = sCallerIdentity.get(); 5813 if (tlsIdentity != null) { 5814 Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {" 5815 + tlsIdentity.pid + "," + tlsIdentity.uid + "}"); 5816 uid = tlsIdentity.uid; 5817 pid = tlsIdentity.pid; 5818 } 5819 5820 if (pid == MY_PID) { 5821 return PackageManager.PERMISSION_GRANTED; 5822 } 5823 5824 return ActivityManager.checkComponentPermission(permission, uid, 5825 owningUid, exported); 5826 } 5827 5828 /** 5829 * As the only public entry point for permissions checking, this method 5830 * can enforce the semantic that requesting a check on a null global 5831 * permission is automatically denied. (Internally a null permission 5832 * string is used when calling {@link #checkComponentPermission} in cases 5833 * when only uid-based security is needed.) 5834 * 5835 * This can be called with or without the global lock held. 5836 */ 5837 @Override 5838 public int checkPermission(String permission, int pid, int uid) { 5839 if (permission == null) { 5840 return PackageManager.PERMISSION_DENIED; 5841 } 5842 return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true); 5843 } 5844 5845 /** 5846 * Binder IPC calls go through the public entry point. 5847 * This can be called with or without the global lock held. 5848 */ 5849 int checkCallingPermission(String permission) { 5850 return checkPermission(permission, 5851 Binder.getCallingPid(), 5852 UserHandle.getAppId(Binder.getCallingUid())); 5853 } 5854 5855 /** 5856 * This can be called with or without the global lock held. 5857 */ 5858 void enforceCallingPermission(String permission, String func) { 5859 if (checkCallingPermission(permission) 5860 == PackageManager.PERMISSION_GRANTED) { 5861 return; 5862 } 5863 5864 String msg = "Permission Denial: " + func + " from pid=" 5865 + Binder.getCallingPid() 5866 + ", uid=" + Binder.getCallingUid() 5867 + " requires " + permission; 5868 Slog.w(TAG, msg); 5869 throw new SecurityException(msg); 5870 } 5871 5872 /** 5873 * Determine if UID is holding permissions required to access {@link Uri} in 5874 * the given {@link ProviderInfo}. Final permission checking is always done 5875 * in {@link ContentProvider}. 5876 */ 5877 private final boolean checkHoldingPermissionsLocked( 5878 IPackageManager pm, ProviderInfo pi, Uri uri, int uid, final int modeFlags) { 5879 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5880 "checkHoldingPermissionsLocked: uri=" + uri + " uid=" + uid); 5881 5882 if (pi.applicationInfo.uid == uid) { 5883 return true; 5884 } else if (!pi.exported) { 5885 return false; 5886 } 5887 5888 boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0; 5889 boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0; 5890 try { 5891 // check if target holds top-level <provider> permissions 5892 if (!readMet && pi.readPermission != null 5893 && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) { 5894 readMet = true; 5895 } 5896 if (!writeMet && pi.writePermission != null 5897 && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) { 5898 writeMet = true; 5899 } 5900 5901 // track if unprotected read/write is allowed; any denied 5902 // <path-permission> below removes this ability 5903 boolean allowDefaultRead = pi.readPermission == null; 5904 boolean allowDefaultWrite = pi.writePermission == null; 5905 5906 // check if target holds any <path-permission> that match uri 5907 final PathPermission[] pps = pi.pathPermissions; 5908 if (pps != null) { 5909 final String path = uri.getPath(); 5910 int i = pps.length; 5911 while (i > 0 && (!readMet || !writeMet)) { 5912 i--; 5913 PathPermission pp = pps[i]; 5914 if (pp.match(path)) { 5915 if (!readMet) { 5916 final String pprperm = pp.getReadPermission(); 5917 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for " 5918 + pprperm + " for " + pp.getPath() 5919 + ": match=" + pp.match(path) 5920 + " check=" + pm.checkUidPermission(pprperm, uid)); 5921 if (pprperm != null) { 5922 if (pm.checkUidPermission(pprperm, uid) == PERMISSION_GRANTED) { 5923 readMet = true; 5924 } else { 5925 allowDefaultRead = false; 5926 } 5927 } 5928 } 5929 if (!writeMet) { 5930 final String ppwperm = pp.getWritePermission(); 5931 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm " 5932 + ppwperm + " for " + pp.getPath() 5933 + ": match=" + pp.match(path) 5934 + " check=" + pm.checkUidPermission(ppwperm, uid)); 5935 if (ppwperm != null) { 5936 if (pm.checkUidPermission(ppwperm, uid) == PERMISSION_GRANTED) { 5937 writeMet = true; 5938 } else { 5939 allowDefaultWrite = false; 5940 } 5941 } 5942 } 5943 } 5944 } 5945 } 5946 5947 // grant unprotected <provider> read/write, if not blocked by 5948 // <path-permission> above 5949 if (allowDefaultRead) readMet = true; 5950 if (allowDefaultWrite) writeMet = true; 5951 5952 } catch (RemoteException e) { 5953 return false; 5954 } 5955 5956 return readMet && writeMet; 5957 } 5958 5959 private ProviderInfo getProviderInfoLocked(String authority, int userHandle) { 5960 ProviderInfo pi = null; 5961 ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle); 5962 if (cpr != null) { 5963 pi = cpr.info; 5964 } else { 5965 try { 5966 pi = AppGlobals.getPackageManager().resolveContentProvider( 5967 authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle); 5968 } catch (RemoteException ex) { 5969 } 5970 } 5971 return pi; 5972 } 5973 5974 private UriPermission findUriPermissionLocked(int targetUid, GrantUri uri) { 5975 final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid); 5976 if (targetUris != null) { 5977 return targetUris.get(uri); 5978 } 5979 return null; 5980 } 5981 5982 private UriPermission findOrCreateUriPermissionLocked(String sourcePkg, 5983 String targetPkg, int targetUid, GrantUri uri) { 5984 ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid); 5985 if (targetUris == null) { 5986 targetUris = Maps.newArrayMap(); 5987 mGrantedUriPermissions.put(targetUid, targetUris); 5988 } 5989 5990 UriPermission perm = targetUris.get(uri); 5991 if (perm == null) { 5992 perm = new UriPermission(sourcePkg, targetPkg, targetUid, uri); 5993 targetUris.put(uri, perm); 5994 } 5995 5996 return perm; 5997 } 5998 5999 private final boolean checkUriPermissionLocked(Uri uri, int uid, final int modeFlags) { 6000 final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0; 6001 final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE 6002 : UriPermission.STRENGTH_OWNED; 6003 6004 // Root gets to do everything. 6005 if (uid == 0) { 6006 return true; 6007 } 6008 6009 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid); 6010 if (perms == null) return false; 6011 6012 // First look for exact match 6013 final UriPermission exactPerm = perms.get(new GrantUri(uri, false)); 6014 if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) { 6015 return true; 6016 } 6017 6018 // No exact match, look for prefixes 6019 final int N = perms.size(); 6020 for (int i = 0; i < N; i++) { 6021 final UriPermission perm = perms.valueAt(i); 6022 if (perm.uri.prefix && uri.isPathPrefixMatch(perm.uri.uri) 6023 && perm.getStrength(modeFlags) >= minStrength) { 6024 return true; 6025 } 6026 } 6027 6028 return false; 6029 } 6030 6031 @Override 6032 public int checkUriPermission(Uri uri, int pid, int uid, final int modeFlags) { 6033 enforceNotIsolatedCaller("checkUriPermission"); 6034 6035 // Another redirected-binder-call permissions check as in 6036 // {@link checkComponentPermission}. 6037 Identity tlsIdentity = sCallerIdentity.get(); 6038 if (tlsIdentity != null) { 6039 uid = tlsIdentity.uid; 6040 pid = tlsIdentity.pid; 6041 } 6042 6043 // Our own process gets to do everything. 6044 if (pid == MY_PID) { 6045 return PackageManager.PERMISSION_GRANTED; 6046 } 6047 synchronized (this) { 6048 return checkUriPermissionLocked(uri, uid, modeFlags) 6049 ? PackageManager.PERMISSION_GRANTED 6050 : PackageManager.PERMISSION_DENIED; 6051 } 6052 } 6053 6054 /** 6055 * Check if the targetPkg can be granted permission to access uri by 6056 * the callingUid using the given modeFlags. Throws a security exception 6057 * if callingUid is not allowed to do this. Returns the uid of the target 6058 * if the URI permission grant should be performed; returns -1 if it is not 6059 * needed (for example targetPkg already has permission to access the URI). 6060 * If you already know the uid of the target, you can supply it in 6061 * lastTargetUid else set that to -1. 6062 */ 6063 int checkGrantUriPermissionLocked(int callingUid, String targetPkg, 6064 Uri uri, final int modeFlags, int lastTargetUid) { 6065 if (!Intent.isAccessUriMode(modeFlags)) { 6066 return -1; 6067 } 6068 6069 if (targetPkg != null) { 6070 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6071 "Checking grant " + targetPkg + " permission to " + uri); 6072 } 6073 6074 final IPackageManager pm = AppGlobals.getPackageManager(); 6075 6076 // If this is not a content: uri, we can't do anything with it. 6077 if (!ContentResolver.SCHEME_CONTENT.equals(uri.getScheme())) { 6078 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6079 "Can't grant URI permission for non-content URI: " + uri); 6080 return -1; 6081 } 6082 6083 final String authority = uri.getAuthority(); 6084 final ProviderInfo pi = getProviderInfoLocked(authority, UserHandle.getUserId(callingUid)); 6085 if (pi == null) { 6086 Slog.w(TAG, "No content provider found for permission check: " + uri.toSafeString()); 6087 return -1; 6088 } 6089 6090 int targetUid = lastTargetUid; 6091 if (targetUid < 0 && targetPkg != null) { 6092 try { 6093 targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid)); 6094 if (targetUid < 0) { 6095 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6096 "Can't grant URI permission no uid for: " + targetPkg); 6097 return -1; 6098 } 6099 } catch (RemoteException ex) { 6100 return -1; 6101 } 6102 } 6103 6104 if (targetUid >= 0) { 6105 // First... does the target actually need this permission? 6106 if (checkHoldingPermissionsLocked(pm, pi, uri, targetUid, modeFlags)) { 6107 // No need to grant the target this permission. 6108 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6109 "Target " + targetPkg + " already has full permission to " + uri); 6110 return -1; 6111 } 6112 } else { 6113 // First... there is no target package, so can anyone access it? 6114 boolean allowed = pi.exported; 6115 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) { 6116 if (pi.readPermission != null) { 6117 allowed = false; 6118 } 6119 } 6120 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) { 6121 if (pi.writePermission != null) { 6122 allowed = false; 6123 } 6124 } 6125 if (allowed) { 6126 return -1; 6127 } 6128 } 6129 6130 // Second... is the provider allowing granting of URI permissions? 6131 if (!pi.grantUriPermissions) { 6132 throw new SecurityException("Provider " + pi.packageName 6133 + "/" + pi.name 6134 + " does not allow granting of Uri permissions (uri " 6135 + uri + ")"); 6136 } 6137 if (pi.uriPermissionPatterns != null) { 6138 final int N = pi.uriPermissionPatterns.length; 6139 boolean allowed = false; 6140 for (int i=0; i<N; i++) { 6141 if (pi.uriPermissionPatterns[i] != null 6142 && pi.uriPermissionPatterns[i].match(uri.getPath())) { 6143 allowed = true; 6144 break; 6145 } 6146 } 6147 if (!allowed) { 6148 throw new SecurityException("Provider " + pi.packageName 6149 + "/" + pi.name 6150 + " does not allow granting of permission to path of Uri " 6151 + uri); 6152 } 6153 } 6154 6155 // Third... does the caller itself have permission to access 6156 // this uri? 6157 if (callingUid != Process.myUid()) { 6158 if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) { 6159 // Require they hold a strong enough Uri permission 6160 if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) { 6161 throw new SecurityException("Uid " + callingUid 6162 + " does not have permission to uri " + uri); 6163 } 6164 } 6165 } 6166 6167 return targetUid; 6168 } 6169 6170 @Override 6171 public int checkGrantUriPermission(int callingUid, String targetPkg, 6172 Uri uri, final int modeFlags) { 6173 enforceNotIsolatedCaller("checkGrantUriPermission"); 6174 synchronized(this) { 6175 return checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1); 6176 } 6177 } 6178 6179 void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, Uri uri, 6180 final int modeFlags, UriPermissionOwner owner) { 6181 if (!Intent.isAccessUriMode(modeFlags)) { 6182 return; 6183 } 6184 6185 // So here we are: the caller has the assumed permission 6186 // to the uri, and the target doesn't. Let's now give this to 6187 // the target. 6188 6189 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6190 "Granting " + targetPkg + "/" + targetUid + " permission to " + uri); 6191 6192 final String authority = uri.getAuthority(); 6193 final ProviderInfo pi = getProviderInfoLocked(authority, UserHandle.getUserId(targetUid)); 6194 if (pi == null) { 6195 Slog.w(TAG, "No content provider found for grant: " + uri.toSafeString()); 6196 return; 6197 } 6198 6199 final boolean prefix = (modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0; 6200 final UriPermission perm = findOrCreateUriPermissionLocked( 6201 pi.packageName, targetPkg, targetUid, new GrantUri(uri, prefix)); 6202 perm.grantModes(modeFlags, owner); 6203 } 6204 6205 void grantUriPermissionLocked(int callingUid, String targetPkg, Uri uri, 6206 final int modeFlags, UriPermissionOwner owner) { 6207 if (targetPkg == null) { 6208 throw new NullPointerException("targetPkg"); 6209 } 6210 6211 int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1); 6212 if (targetUid < 0) { 6213 return; 6214 } 6215 6216 grantUriPermissionUncheckedLocked(targetUid, targetPkg, uri, modeFlags, owner); 6217 } 6218 6219 static class NeededUriGrants extends ArrayList<Uri> { 6220 final String targetPkg; 6221 final int targetUid; 6222 final int flags; 6223 6224 NeededUriGrants(String targetPkg, int targetUid, int flags) { 6225 this.targetPkg = targetPkg; 6226 this.targetUid = targetUid; 6227 this.flags = flags; 6228 } 6229 } 6230 6231 /** 6232 * Like checkGrantUriPermissionLocked, but takes an Intent. 6233 */ 6234 NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid, 6235 String targetPkg, Intent intent, int mode, NeededUriGrants needed) { 6236 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6237 "Checking URI perm to data=" + (intent != null ? intent.getData() : null) 6238 + " clip=" + (intent != null ? intent.getClipData() : null) 6239 + " from " + intent + "; flags=0x" 6240 + Integer.toHexString(intent != null ? intent.getFlags() : 0)); 6241 6242 if (targetPkg == null) { 6243 throw new NullPointerException("targetPkg"); 6244 } 6245 6246 if (intent == null) { 6247 return null; 6248 } 6249 Uri data = intent.getData(); 6250 ClipData clip = intent.getClipData(); 6251 if (data == null && clip == null) { 6252 return null; 6253 } 6254 6255 if (data != null) { 6256 int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, data, 6257 mode, needed != null ? needed.targetUid : -1); 6258 if (targetUid > 0) { 6259 if (needed == null) { 6260 needed = new NeededUriGrants(targetPkg, targetUid, mode); 6261 } 6262 needed.add(data); 6263 } 6264 } 6265 if (clip != null) { 6266 for (int i=0; i<clip.getItemCount(); i++) { 6267 Uri uri = clip.getItemAt(i).getUri(); 6268 if (uri != null) { 6269 int targetUid = -1; 6270 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri, 6271 mode, needed != null ? needed.targetUid : -1); 6272 if (targetUid > 0) { 6273 if (needed == null) { 6274 needed = new NeededUriGrants(targetPkg, targetUid, mode); 6275 } 6276 needed.add(uri); 6277 } 6278 } else { 6279 Intent clipIntent = clip.getItemAt(i).getIntent(); 6280 if (clipIntent != null) { 6281 NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked( 6282 callingUid, targetPkg, clipIntent, mode, needed); 6283 if (newNeeded != null) { 6284 needed = newNeeded; 6285 } 6286 } 6287 } 6288 } 6289 } 6290 6291 return needed; 6292 } 6293 6294 /** 6295 * Like grantUriPermissionUncheckedLocked, but takes an Intent. 6296 */ 6297 void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed, 6298 UriPermissionOwner owner) { 6299 if (needed != null) { 6300 for (int i=0; i<needed.size(); i++) { 6301 grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg, 6302 needed.get(i), needed.flags, owner); 6303 } 6304 } 6305 } 6306 6307 void grantUriPermissionFromIntentLocked(int callingUid, 6308 String targetPkg, Intent intent, UriPermissionOwner owner) { 6309 NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg, 6310 intent, intent != null ? intent.getFlags() : 0, null); 6311 if (needed == null) { 6312 return; 6313 } 6314 6315 grantUriPermissionUncheckedFromIntentLocked(needed, owner); 6316 } 6317 6318 @Override 6319 public void grantUriPermission(IApplicationThread caller, String targetPkg, 6320 Uri uri, final int modeFlags) { 6321 enforceNotIsolatedCaller("grantUriPermission"); 6322 synchronized(this) { 6323 final ProcessRecord r = getRecordForAppLocked(caller); 6324 if (r == null) { 6325 throw new SecurityException("Unable to find app for caller " 6326 + caller 6327 + " when granting permission to uri " + uri); 6328 } 6329 if (targetPkg == null) { 6330 throw new IllegalArgumentException("null target"); 6331 } 6332 if (uri == null) { 6333 throw new IllegalArgumentException("null uri"); 6334 } 6335 6336 Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION 6337 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION 6338 | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION 6339 | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION); 6340 6341 grantUriPermissionLocked(r.uid, targetPkg, uri, modeFlags, null); 6342 } 6343 } 6344 6345 void removeUriPermissionIfNeededLocked(UriPermission perm) { 6346 if (perm.modeFlags == 0) { 6347 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get( 6348 perm.targetUid); 6349 if (perms != null) { 6350 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6351 "Removing " + perm.targetUid + " permission to " + perm.uri); 6352 6353 perms.remove(perm.uri); 6354 if (perms.isEmpty()) { 6355 mGrantedUriPermissions.remove(perm.targetUid); 6356 } 6357 } 6358 } 6359 } 6360 6361 private void revokeUriPermissionLocked(int callingUid, Uri uri, final int modeFlags) { 6362 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + uri); 6363 6364 final IPackageManager pm = AppGlobals.getPackageManager(); 6365 final String authority = uri.getAuthority(); 6366 final ProviderInfo pi = getProviderInfoLocked(authority, UserHandle.getUserId(callingUid)); 6367 if (pi == null) { 6368 Slog.w(TAG, "No content provider found for permission revoke: " + uri.toSafeString()); 6369 return; 6370 } 6371 6372 // Does the caller have this permission on the URI? 6373 if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) { 6374 // Right now, if you are not the original owner of the permission, 6375 // you are not allowed to revoke it. 6376 //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) { 6377 throw new SecurityException("Uid " + callingUid 6378 + " does not have permission to uri " + uri); 6379 //} 6380 } 6381 6382 boolean persistChanged = false; 6383 6384 // Go through all of the permissions and remove any that match. 6385 int N = mGrantedUriPermissions.size(); 6386 for (int i = 0; i < N; i++) { 6387 final int targetUid = mGrantedUriPermissions.keyAt(i); 6388 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 6389 6390 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) { 6391 final UriPermission perm = it.next(); 6392 if (perm.uri.uri.isPathPrefixMatch(uri)) { 6393 if (DEBUG_URI_PERMISSION) 6394 Slog.v(TAG, 6395 "Revoking " + perm.targetUid + " permission to " + perm.uri); 6396 persistChanged |= perm.revokeModes( 6397 modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION); 6398 if (perm.modeFlags == 0) { 6399 it.remove(); 6400 } 6401 } 6402 } 6403 6404 if (perms.isEmpty()) { 6405 mGrantedUriPermissions.remove(targetUid); 6406 N--; 6407 i--; 6408 } 6409 } 6410 6411 if (persistChanged) { 6412 schedulePersistUriGrants(); 6413 } 6414 } 6415 6416 @Override 6417 public void revokeUriPermission(IApplicationThread caller, Uri uri, 6418 final int modeFlags) { 6419 enforceNotIsolatedCaller("revokeUriPermission"); 6420 synchronized(this) { 6421 final ProcessRecord r = getRecordForAppLocked(caller); 6422 if (r == null) { 6423 throw new SecurityException("Unable to find app for caller " 6424 + caller 6425 + " when revoking permission to uri " + uri); 6426 } 6427 if (uri == null) { 6428 Slog.w(TAG, "revokeUriPermission: null uri"); 6429 return; 6430 } 6431 6432 if (!Intent.isAccessUriMode(modeFlags)) { 6433 return; 6434 } 6435 6436 final IPackageManager pm = AppGlobals.getPackageManager(); 6437 final String authority = uri.getAuthority(); 6438 final ProviderInfo pi = getProviderInfoLocked(authority, r.userId); 6439 if (pi == null) { 6440 Slog.w(TAG, "No content provider found for permission revoke: " 6441 + uri.toSafeString()); 6442 return; 6443 } 6444 6445 revokeUriPermissionLocked(r.uid, uri, modeFlags); 6446 } 6447 } 6448 6449 /** 6450 * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the 6451 * given package. 6452 * 6453 * @param packageName Package name to match, or {@code null} to apply to all 6454 * packages. 6455 * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply 6456 * to all users. 6457 * @param persistable If persistable grants should be removed. 6458 */ 6459 private void removeUriPermissionsForPackageLocked( 6460 String packageName, int userHandle, boolean persistable) { 6461 if (userHandle == UserHandle.USER_ALL && packageName == null) { 6462 throw new IllegalArgumentException("Must narrow by either package or user"); 6463 } 6464 6465 boolean persistChanged = false; 6466 6467 int N = mGrantedUriPermissions.size(); 6468 for (int i = 0; i < N; i++) { 6469 final int targetUid = mGrantedUriPermissions.keyAt(i); 6470 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 6471 6472 // Only inspect grants matching user 6473 if (userHandle == UserHandle.USER_ALL 6474 || userHandle == UserHandle.getUserId(targetUid)) { 6475 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) { 6476 final UriPermission perm = it.next(); 6477 6478 // Only inspect grants matching package 6479 if (packageName == null || perm.sourcePkg.equals(packageName) 6480 || perm.targetPkg.equals(packageName)) { 6481 persistChanged |= perm.revokeModes( 6482 persistable ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION); 6483 6484 // Only remove when no modes remain; any persisted grants 6485 // will keep this alive. 6486 if (perm.modeFlags == 0) { 6487 it.remove(); 6488 } 6489 } 6490 } 6491 6492 if (perms.isEmpty()) { 6493 mGrantedUriPermissions.remove(targetUid); 6494 N--; 6495 i--; 6496 } 6497 } 6498 } 6499 6500 if (persistChanged) { 6501 schedulePersistUriGrants(); 6502 } 6503 } 6504 6505 @Override 6506 public IBinder newUriPermissionOwner(String name) { 6507 enforceNotIsolatedCaller("newUriPermissionOwner"); 6508 synchronized(this) { 6509 UriPermissionOwner owner = new UriPermissionOwner(this, name); 6510 return owner.getExternalTokenLocked(); 6511 } 6512 } 6513 6514 @Override 6515 public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, 6516 Uri uri, final int modeFlags) { 6517 synchronized(this) { 6518 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 6519 if (owner == null) { 6520 throw new IllegalArgumentException("Unknown owner: " + token); 6521 } 6522 if (fromUid != Binder.getCallingUid()) { 6523 if (Binder.getCallingUid() != Process.myUid()) { 6524 // Only system code can grant URI permissions on behalf 6525 // of other users. 6526 throw new SecurityException("nice try"); 6527 } 6528 } 6529 if (targetPkg == null) { 6530 throw new IllegalArgumentException("null target"); 6531 } 6532 if (uri == null) { 6533 throw new IllegalArgumentException("null uri"); 6534 } 6535 6536 grantUriPermissionLocked(fromUid, targetPkg, uri, modeFlags, owner); 6537 } 6538 } 6539 6540 @Override 6541 public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode) { 6542 synchronized(this) { 6543 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 6544 if (owner == null) { 6545 throw new IllegalArgumentException("Unknown owner: " + token); 6546 } 6547 6548 if (uri == null) { 6549 owner.removeUriPermissionsLocked(mode); 6550 } else { 6551 owner.removeUriPermissionLocked(uri, mode); 6552 } 6553 } 6554 } 6555 6556 private void schedulePersistUriGrants() { 6557 if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) { 6558 mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG), 6559 10 * DateUtils.SECOND_IN_MILLIS); 6560 } 6561 } 6562 6563 private void writeGrantedUriPermissions() { 6564 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()"); 6565 6566 // Snapshot permissions so we can persist without lock 6567 ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList(); 6568 synchronized (this) { 6569 final int size = mGrantedUriPermissions.size(); 6570 for (int i = 0; i < size; i++) { 6571 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 6572 for (UriPermission perm : perms.values()) { 6573 if (perm.persistedModeFlags != 0) { 6574 persist.add(perm.snapshot()); 6575 } 6576 } 6577 } 6578 } 6579 6580 FileOutputStream fos = null; 6581 try { 6582 fos = mGrantFile.startWrite(); 6583 6584 XmlSerializer out = new FastXmlSerializer(); 6585 out.setOutput(fos, "utf-8"); 6586 out.startDocument(null, true); 6587 out.startTag(null, TAG_URI_GRANTS); 6588 for (UriPermission.Snapshot perm : persist) { 6589 out.startTag(null, TAG_URI_GRANT); 6590 writeIntAttribute(out, ATTR_USER_HANDLE, perm.userHandle); 6591 out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg); 6592 out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg); 6593 out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri)); 6594 writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix); 6595 writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags); 6596 writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime); 6597 out.endTag(null, TAG_URI_GRANT); 6598 } 6599 out.endTag(null, TAG_URI_GRANTS); 6600 out.endDocument(); 6601 6602 mGrantFile.finishWrite(fos); 6603 } catch (IOException e) { 6604 if (fos != null) { 6605 mGrantFile.failWrite(fos); 6606 } 6607 } 6608 } 6609 6610 private void readGrantedUriPermissionsLocked() { 6611 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()"); 6612 6613 final long now = System.currentTimeMillis(); 6614 6615 FileInputStream fis = null; 6616 try { 6617 fis = mGrantFile.openRead(); 6618 final XmlPullParser in = Xml.newPullParser(); 6619 in.setInput(fis, null); 6620 6621 int type; 6622 while ((type = in.next()) != END_DOCUMENT) { 6623 final String tag = in.getName(); 6624 if (type == START_TAG) { 6625 if (TAG_URI_GRANT.equals(tag)) { 6626 final int userHandle = readIntAttribute(in, ATTR_USER_HANDLE); 6627 final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG); 6628 final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG); 6629 final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI)); 6630 final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX); 6631 final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS); 6632 final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now); 6633 6634 // Sanity check that provider still belongs to source package 6635 final ProviderInfo pi = getProviderInfoLocked( 6636 uri.getAuthority(), userHandle); 6637 if (pi != null && sourcePkg.equals(pi.packageName)) { 6638 int targetUid = -1; 6639 try { 6640 targetUid = AppGlobals.getPackageManager() 6641 .getPackageUid(targetPkg, userHandle); 6642 } catch (RemoteException e) { 6643 } 6644 if (targetUid != -1) { 6645 final UriPermission perm = findOrCreateUriPermissionLocked( 6646 sourcePkg, targetPkg, targetUid, new GrantUri(uri, prefix)); 6647 perm.initPersistedModes(modeFlags, createdTime); 6648 } 6649 } else { 6650 Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg 6651 + " but instead found " + pi); 6652 } 6653 } 6654 } 6655 } 6656 } catch (FileNotFoundException e) { 6657 // Missing grants is okay 6658 } catch (IOException e) { 6659 Log.wtf(TAG, "Failed reading Uri grants", e); 6660 } catch (XmlPullParserException e) { 6661 Log.wtf(TAG, "Failed reading Uri grants", e); 6662 } finally { 6663 IoUtils.closeQuietly(fis); 6664 } 6665 } 6666 6667 @Override 6668 public void takePersistableUriPermission(Uri uri, final int modeFlags) { 6669 enforceNotIsolatedCaller("takePersistableUriPermission"); 6670 6671 Preconditions.checkFlagsArgument(modeFlags, 6672 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 6673 6674 synchronized (this) { 6675 final int callingUid = Binder.getCallingUid(); 6676 boolean persistChanged = false; 6677 6678 UriPermission exactPerm = findUriPermissionLocked(callingUid, new GrantUri(uri, false)); 6679 UriPermission prefixPerm = findUriPermissionLocked(callingUid, new GrantUri(uri, true)); 6680 6681 final boolean exactValid = (exactPerm != null) 6682 && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags); 6683 final boolean prefixValid = (prefixPerm != null) 6684 && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags); 6685 6686 if (!(exactValid || prefixValid)) { 6687 throw new SecurityException("No persistable permission grants found for UID " 6688 + callingUid + " and Uri " + uri.toSafeString()); 6689 } 6690 6691 if (exactValid) { 6692 persistChanged |= exactPerm.takePersistableModes(modeFlags); 6693 } 6694 if (prefixValid) { 6695 persistChanged |= prefixPerm.takePersistableModes(modeFlags); 6696 } 6697 6698 persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid); 6699 6700 if (persistChanged) { 6701 schedulePersistUriGrants(); 6702 } 6703 } 6704 } 6705 6706 @Override 6707 public void releasePersistableUriPermission(Uri uri, final int modeFlags) { 6708 enforceNotIsolatedCaller("releasePersistableUriPermission"); 6709 6710 Preconditions.checkFlagsArgument(modeFlags, 6711 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 6712 6713 synchronized (this) { 6714 final int callingUid = Binder.getCallingUid(); 6715 boolean persistChanged = false; 6716 6717 UriPermission exactPerm = findUriPermissionLocked(callingUid, new GrantUri(uri, false)); 6718 UriPermission prefixPerm = findUriPermissionLocked(callingUid, new GrantUri(uri, true)); 6719 if (exactPerm == null && prefixPerm == null) { 6720 throw new SecurityException("No permission grants found for UID " + callingUid 6721 + " and Uri " + uri.toSafeString()); 6722 } 6723 6724 if (exactPerm != null) { 6725 persistChanged |= exactPerm.releasePersistableModes(modeFlags); 6726 removeUriPermissionIfNeededLocked(exactPerm); 6727 } 6728 if (prefixPerm != null) { 6729 persistChanged |= prefixPerm.releasePersistableModes(modeFlags); 6730 removeUriPermissionIfNeededLocked(prefixPerm); 6731 } 6732 6733 if (persistChanged) { 6734 schedulePersistUriGrants(); 6735 } 6736 } 6737 } 6738 6739 /** 6740 * Prune any older {@link UriPermission} for the given UID until outstanding 6741 * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}. 6742 * 6743 * @return if any mutations occured that require persisting. 6744 */ 6745 private boolean maybePrunePersistedUriGrantsLocked(int uid) { 6746 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid); 6747 if (perms == null) return false; 6748 if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false; 6749 6750 final ArrayList<UriPermission> persisted = Lists.newArrayList(); 6751 for (UriPermission perm : perms.values()) { 6752 if (perm.persistedModeFlags != 0) { 6753 persisted.add(perm); 6754 } 6755 } 6756 6757 final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS; 6758 if (trimCount <= 0) return false; 6759 6760 Collections.sort(persisted, new UriPermission.PersistedTimeComparator()); 6761 for (int i = 0; i < trimCount; i++) { 6762 final UriPermission perm = persisted.get(i); 6763 6764 if (DEBUG_URI_PERMISSION) { 6765 Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime); 6766 } 6767 6768 perm.releasePersistableModes(~0); 6769 removeUriPermissionIfNeededLocked(perm); 6770 } 6771 6772 return true; 6773 } 6774 6775 @Override 6776 public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions( 6777 String packageName, boolean incoming) { 6778 enforceNotIsolatedCaller("getPersistedUriPermissions"); 6779 Preconditions.checkNotNull(packageName, "packageName"); 6780 6781 final int callingUid = Binder.getCallingUid(); 6782 final IPackageManager pm = AppGlobals.getPackageManager(); 6783 try { 6784 final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid)); 6785 if (packageUid != callingUid) { 6786 throw new SecurityException( 6787 "Package " + packageName + " does not belong to calling UID " + callingUid); 6788 } 6789 } catch (RemoteException e) { 6790 throw new SecurityException("Failed to verify package name ownership"); 6791 } 6792 6793 final ArrayList<android.content.UriPermission> result = Lists.newArrayList(); 6794 synchronized (this) { 6795 if (incoming) { 6796 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get( 6797 callingUid); 6798 if (perms == null) { 6799 Slog.w(TAG, "No permission grants found for " + packageName); 6800 } else { 6801 for (UriPermission perm : perms.values()) { 6802 if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) { 6803 result.add(perm.buildPersistedPublicApiObject()); 6804 } 6805 } 6806 } 6807 } else { 6808 final int size = mGrantedUriPermissions.size(); 6809 for (int i = 0; i < size; i++) { 6810 final ArrayMap<GrantUri, UriPermission> perms = 6811 mGrantedUriPermissions.valueAt(i); 6812 for (UriPermission perm : perms.values()) { 6813 if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) { 6814 result.add(perm.buildPersistedPublicApiObject()); 6815 } 6816 } 6817 } 6818 } 6819 } 6820 return new ParceledListSlice<android.content.UriPermission>(result); 6821 } 6822 6823 @Override 6824 public void showWaitingForDebugger(IApplicationThread who, boolean waiting) { 6825 synchronized (this) { 6826 ProcessRecord app = 6827 who != null ? getRecordForAppLocked(who) : null; 6828 if (app == null) return; 6829 6830 Message msg = Message.obtain(); 6831 msg.what = WAIT_FOR_DEBUGGER_MSG; 6832 msg.obj = app; 6833 msg.arg1 = waiting ? 1 : 0; 6834 mHandler.sendMessage(msg); 6835 } 6836 } 6837 6838 @Override 6839 public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) { 6840 final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ); 6841 final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ); 6842 outInfo.availMem = Process.getFreeMemory(); 6843 outInfo.totalMem = Process.getTotalMemory(); 6844 outInfo.threshold = homeAppMem; 6845 outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2)); 6846 outInfo.hiddenAppThreshold = cachedAppMem; 6847 outInfo.secondaryServerThreshold = mProcessList.getMemLevel( 6848 ProcessList.SERVICE_ADJ); 6849 outInfo.visibleAppThreshold = mProcessList.getMemLevel( 6850 ProcessList.VISIBLE_APP_ADJ); 6851 outInfo.foregroundAppThreshold = mProcessList.getMemLevel( 6852 ProcessList.FOREGROUND_APP_ADJ); 6853 } 6854 6855 // ========================================================= 6856 // TASK MANAGEMENT 6857 // ========================================================= 6858 6859 @Override 6860 public List<RunningTaskInfo> getTasks(int maxNum, int flags, 6861 IThumbnailReceiver receiver) { 6862 ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>(); 6863 6864 PendingThumbnailsRecord pending = new PendingThumbnailsRecord(receiver); 6865 ActivityRecord topRecord = null; 6866 6867 synchronized(this) { 6868 if (localLOGV) Slog.v( 6869 TAG, "getTasks: max=" + maxNum + ", flags=" + flags 6870 + ", receiver=" + receiver); 6871 6872 if (checkCallingPermission(android.Manifest.permission.GET_TASKS) 6873 != PackageManager.PERMISSION_GRANTED) { 6874 if (receiver != null) { 6875 // If the caller wants to wait for pending thumbnails, 6876 // it ain't gonna get them. 6877 try { 6878 receiver.finished(); 6879 } catch (RemoteException ex) { 6880 } 6881 } 6882 String msg = "Permission Denial: getTasks() from pid=" 6883 + Binder.getCallingPid() 6884 + ", uid=" + Binder.getCallingUid() 6885 + " requires " + android.Manifest.permission.GET_TASKS; 6886 Slog.w(TAG, msg); 6887 throw new SecurityException(msg); 6888 } 6889 6890 // TODO: Improve with MRU list from all ActivityStacks. 6891 topRecord = mStackSupervisor.getTasksLocked(maxNum, receiver, pending, list); 6892 6893 if (!pending.pendingRecords.isEmpty()) { 6894 mPendingThumbnails.add(pending); 6895 } 6896 } 6897 6898 if (localLOGV) Slog.v(TAG, "We have pending thumbnails: " + pending); 6899 6900 if (topRecord != null) { 6901 if (localLOGV) Slog.v(TAG, "Requesting top thumbnail"); 6902 try { 6903 IApplicationThread topThumbnail = topRecord.app.thread; 6904 topThumbnail.requestThumbnail(topRecord.appToken); 6905 } catch (Exception e) { 6906 Slog.w(TAG, "Exception thrown when requesting thumbnail", e); 6907 sendPendingThumbnail(null, topRecord.appToken, null, null, true); 6908 } 6909 } 6910 6911 if (pending.pendingRecords.isEmpty() && receiver != null) { 6912 // In this case all thumbnails were available and the client 6913 // is being asked to be told when the remaining ones come in... 6914 // which is unusually, since the top-most currently running 6915 // activity should never have a canned thumbnail! Oh well. 6916 try { 6917 receiver.finished(); 6918 } catch (RemoteException ex) { 6919 } 6920 } 6921 6922 return list; 6923 } 6924 6925 TaskRecord getMostRecentTask() { 6926 return mRecentTasks.get(0); 6927 } 6928 6929 @Override 6930 public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, 6931 int flags, int userId) { 6932 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 6933 false, true, "getRecentTasks", null); 6934 6935 synchronized (this) { 6936 enforceCallingPermission(android.Manifest.permission.GET_TASKS, 6937 "getRecentTasks()"); 6938 final boolean detailed = checkCallingPermission( 6939 android.Manifest.permission.GET_DETAILED_TASKS) 6940 == PackageManager.PERMISSION_GRANTED; 6941 6942 IPackageManager pm = AppGlobals.getPackageManager(); 6943 6944 final int N = mRecentTasks.size(); 6945 ArrayList<ActivityManager.RecentTaskInfo> res 6946 = new ArrayList<ActivityManager.RecentTaskInfo>( 6947 maxNum < N ? maxNum : N); 6948 6949 final Set<Integer> includedUsers; 6950 if ((flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0) { 6951 includedUsers = getProfileIdsLocked(userId); 6952 } else { 6953 includedUsers = new HashSet<Integer>(); 6954 } 6955 includedUsers.add(Integer.valueOf(userId)); 6956 for (int i=0; i<N && maxNum > 0; i++) { 6957 TaskRecord tr = mRecentTasks.get(i); 6958 // Only add calling user or related users recent tasks 6959 if (!includedUsers.contains(Integer.valueOf(tr.userId))) continue; 6960 6961 // Return the entry if desired by the caller. We always return 6962 // the first entry, because callers always expect this to be the 6963 // foreground app. We may filter others if the caller has 6964 // not supplied RECENT_WITH_EXCLUDED and there is some reason 6965 // we should exclude the entry. 6966 6967 if (i == 0 6968 || ((flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0) 6969 || (tr.intent == null) 6970 || ((tr.intent.getFlags() 6971 &Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0)) { 6972 ActivityManager.RecentTaskInfo rti 6973 = new ActivityManager.RecentTaskInfo(); 6974 rti.id = tr.numActivities > 0 ? tr.taskId : -1; 6975 rti.persistentId = tr.taskId; 6976 rti.baseIntent = new Intent( 6977 tr.intent != null ? tr.intent : tr.affinityIntent); 6978 if (!detailed) { 6979 rti.baseIntent.replaceExtras((Bundle)null); 6980 } 6981 rti.origActivity = tr.origActivity; 6982 rti.description = tr.lastDescription; 6983 rti.stackId = tr.stack.mStackId; 6984 rti.userId = tr.userId; 6985 6986 // Traverse upwards looking for any break between main task activities and 6987 // utility activities. 6988 final ArrayList<ActivityRecord> activities = tr.mActivities; 6989 int activityNdx; 6990 final int numActivities = activities.size(); 6991 for (activityNdx = Math.min(numActivities, 1); activityNdx < numActivities; 6992 ++activityNdx) { 6993 final ActivityRecord r = activities.get(activityNdx); 6994 if (r.intent != null && 6995 (r.intent.getFlags() & Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET) 6996 != 0) { 6997 break; 6998 } 6999 } 7000 // Traverse downwards starting below break looking for set label and icon. 7001 for (--activityNdx; activityNdx >= 0; --activityNdx) { 7002 final ActivityRecord r = activities.get(activityNdx); 7003 if (r.activityLabel != null || r.activityIcon != null) { 7004 rti.activityLabel = r.activityLabel; 7005 rti.activityIcon = r.activityIcon; 7006 break; 7007 } 7008 } 7009 7010 if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) { 7011 // Check whether this activity is currently available. 7012 try { 7013 if (rti.origActivity != null) { 7014 if (pm.getActivityInfo(rti.origActivity, 0, userId) 7015 == null) { 7016 continue; 7017 } 7018 } else if (rti.baseIntent != null) { 7019 if (pm.queryIntentActivities(rti.baseIntent, 7020 null, 0, userId) == null) { 7021 continue; 7022 } 7023 } 7024 } catch (RemoteException e) { 7025 // Will never happen. 7026 } 7027 } 7028 7029 res.add(rti); 7030 maxNum--; 7031 } 7032 } 7033 return res; 7034 } 7035 } 7036 7037 private TaskRecord recentTaskForIdLocked(int id) { 7038 final int N = mRecentTasks.size(); 7039 for (int i=0; i<N; i++) { 7040 TaskRecord tr = mRecentTasks.get(i); 7041 if (tr.taskId == id) { 7042 return tr; 7043 } 7044 } 7045 return null; 7046 } 7047 7048 @Override 7049 public ActivityManager.TaskThumbnails getTaskThumbnails(int id) { 7050 synchronized (this) { 7051 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER, 7052 "getTaskThumbnails()"); 7053 TaskRecord tr = recentTaskForIdLocked(id); 7054 if (tr != null) { 7055 return tr.getTaskThumbnailsLocked(); 7056 } 7057 } 7058 return null; 7059 } 7060 7061 @Override 7062 public Bitmap getTaskTopThumbnail(int id) { 7063 synchronized (this) { 7064 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER, 7065 "getTaskTopThumbnail()"); 7066 TaskRecord tr = recentTaskForIdLocked(id); 7067 if (tr != null) { 7068 return tr.getTaskTopThumbnailLocked(); 7069 } 7070 } 7071 return null; 7072 } 7073 7074 @Override 7075 public void setActivityLabelAndIcon(IBinder token, CharSequence activityLabel, 7076 Bitmap activityIcon) { 7077 synchronized (this) { 7078 ActivityRecord r = ActivityRecord.isInStackLocked(token); 7079 if (r != null) { 7080 r.activityLabel = activityLabel.toString(); 7081 r.activityIcon = activityIcon; 7082 } 7083 } 7084 } 7085 7086 @Override 7087 public boolean removeSubTask(int taskId, int subTaskIndex) { 7088 synchronized (this) { 7089 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, 7090 "removeSubTask()"); 7091 long ident = Binder.clearCallingIdentity(); 7092 try { 7093 TaskRecord tr = recentTaskForIdLocked(taskId); 7094 if (tr != null) { 7095 return tr.removeTaskActivitiesLocked(subTaskIndex, true) != null; 7096 } 7097 return false; 7098 } finally { 7099 Binder.restoreCallingIdentity(ident); 7100 } 7101 } 7102 } 7103 7104 private void killUnneededProcessLocked(ProcessRecord pr, String reason) { 7105 if (!pr.killedByAm) { 7106 Slog.i(TAG, "Killing " + pr.toShortString() + " (adj " + pr.setAdj + "): " + reason); 7107 EventLog.writeEvent(EventLogTags.AM_KILL, pr.userId, pr.pid, 7108 pr.processName, pr.setAdj, reason); 7109 pr.killedByAm = true; 7110 Process.killProcessQuiet(pr.pid); 7111 } 7112 } 7113 7114 private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) { 7115 tr.disposeThumbnail(); 7116 mRecentTasks.remove(tr); 7117 final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0; 7118 Intent baseIntent = new Intent( 7119 tr.intent != null ? tr.intent : tr.affinityIntent); 7120 ComponentName component = baseIntent.getComponent(); 7121 if (component == null) { 7122 Slog.w(TAG, "Now component for base intent of task: " + tr); 7123 return; 7124 } 7125 7126 // Find any running services associated with this app. 7127 mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent); 7128 7129 if (killProcesses) { 7130 // Find any running processes associated with this app. 7131 final String pkg = component.getPackageName(); 7132 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 7133 ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap(); 7134 for (int i=0; i<pmap.size(); i++) { 7135 SparseArray<ProcessRecord> uids = pmap.valueAt(i); 7136 for (int j=0; j<uids.size(); j++) { 7137 ProcessRecord proc = uids.valueAt(j); 7138 if (proc.userId != tr.userId) { 7139 continue; 7140 } 7141 if (!proc.pkgList.containsKey(pkg)) { 7142 continue; 7143 } 7144 procs.add(proc); 7145 } 7146 } 7147 7148 // Kill the running processes. 7149 for (int i=0; i<procs.size(); i++) { 7150 ProcessRecord pr = procs.get(i); 7151 if (pr == mHomeProcess) { 7152 // Don't kill the home process along with tasks from the same package. 7153 continue; 7154 } 7155 if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 7156 killUnneededProcessLocked(pr, "remove task"); 7157 } else { 7158 pr.waitingToKill = "remove task"; 7159 } 7160 } 7161 } 7162 } 7163 7164 /** 7165 * Removes the task with the specified task id. 7166 * 7167 * @param taskId Identifier of the task to be removed. 7168 * @param flags Additional operational flags. May be 0 or 7169 * {@link ActivityManager#REMOVE_TASK_KILL_PROCESS}. 7170 * @return Returns true if the given task was found and removed. 7171 */ 7172 private boolean removeTaskByIdLocked(int taskId, int flags) { 7173 TaskRecord tr = recentTaskForIdLocked(taskId); 7174 if (tr != null) { 7175 tr.removeTaskActivitiesLocked(-1, false); 7176 cleanUpRemovedTaskLocked(tr, flags); 7177 return true; 7178 } 7179 return false; 7180 } 7181 7182 @Override 7183 public boolean removeTask(int taskId, int flags) { 7184 synchronized (this) { 7185 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, 7186 "removeTask()"); 7187 long ident = Binder.clearCallingIdentity(); 7188 try { 7189 return removeTaskByIdLocked(taskId, flags); 7190 } finally { 7191 Binder.restoreCallingIdentity(ident); 7192 } 7193 } 7194 } 7195 7196 /** 7197 * TODO: Add mController hook 7198 */ 7199 @Override 7200 public void moveTaskToFront(int taskId, int flags, Bundle options) { 7201 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 7202 "moveTaskToFront()"); 7203 7204 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId); 7205 synchronized(this) { 7206 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 7207 Binder.getCallingUid(), "Task to front")) { 7208 ActivityOptions.abort(options); 7209 return; 7210 } 7211 final long origId = Binder.clearCallingIdentity(); 7212 try { 7213 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId); 7214 if (task == null) { 7215 return; 7216 } 7217 if (mStackSupervisor.isLockTaskModeViolation(task)) { 7218 Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode"); 7219 return; 7220 } 7221 mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options); 7222 } finally { 7223 Binder.restoreCallingIdentity(origId); 7224 } 7225 ActivityOptions.abort(options); 7226 } 7227 } 7228 7229 @Override 7230 public void moveTaskToBack(int taskId) { 7231 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 7232 "moveTaskToBack()"); 7233 7234 synchronized(this) { 7235 TaskRecord tr = recentTaskForIdLocked(taskId); 7236 if (tr != null) { 7237 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr); 7238 ActivityStack stack = tr.stack; 7239 if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) { 7240 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 7241 Binder.getCallingUid(), "Task to back")) { 7242 return; 7243 } 7244 } 7245 final long origId = Binder.clearCallingIdentity(); 7246 try { 7247 stack.moveTaskToBackLocked(taskId, null); 7248 } finally { 7249 Binder.restoreCallingIdentity(origId); 7250 } 7251 } 7252 } 7253 } 7254 7255 /** 7256 * Moves an activity, and all of the other activities within the same task, to the bottom 7257 * of the history stack. The activity's order within the task is unchanged. 7258 * 7259 * @param token A reference to the activity we wish to move 7260 * @param nonRoot If false then this only works if the activity is the root 7261 * of a task; if true it will work for any activity in a task. 7262 * @return Returns true if the move completed, false if not. 7263 */ 7264 @Override 7265 public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) { 7266 enforceNotIsolatedCaller("moveActivityTaskToBack"); 7267 synchronized(this) { 7268 final long origId = Binder.clearCallingIdentity(); 7269 int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot); 7270 if (taskId >= 0) { 7271 return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null); 7272 } 7273 Binder.restoreCallingIdentity(origId); 7274 } 7275 return false; 7276 } 7277 7278 @Override 7279 public void moveTaskBackwards(int task) { 7280 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 7281 "moveTaskBackwards()"); 7282 7283 synchronized(this) { 7284 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 7285 Binder.getCallingUid(), "Task backwards")) { 7286 return; 7287 } 7288 final long origId = Binder.clearCallingIdentity(); 7289 moveTaskBackwardsLocked(task); 7290 Binder.restoreCallingIdentity(origId); 7291 } 7292 } 7293 7294 private final void moveTaskBackwardsLocked(int task) { 7295 Slog.e(TAG, "moveTaskBackwards not yet implemented!"); 7296 } 7297 7298 @Override 7299 public IBinder getHomeActivityToken() throws RemoteException { 7300 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7301 "getHomeActivityToken()"); 7302 synchronized (this) { 7303 return mStackSupervisor.getHomeActivityToken(); 7304 } 7305 } 7306 7307 @Override 7308 public IActivityContainer createActivityContainer(IBinder parentActivityToken, 7309 IActivityContainerCallback callback) throws RemoteException { 7310 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7311 "createActivityContainer()"); 7312 synchronized (this) { 7313 if (parentActivityToken == null) { 7314 throw new IllegalArgumentException("parent token must not be null"); 7315 } 7316 ActivityRecord r = ActivityRecord.forToken(parentActivityToken); 7317 if (r == null) { 7318 return null; 7319 } 7320 if (callback == null) { 7321 throw new IllegalArgumentException("callback must not be null"); 7322 } 7323 return mStackSupervisor.createActivityContainer(r, callback); 7324 } 7325 } 7326 7327 @Override 7328 public void deleteActivityContainer(IActivityContainer container) throws RemoteException { 7329 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7330 "deleteActivityContainer()"); 7331 synchronized (this) { 7332 mStackSupervisor.deleteActivityContainer(container); 7333 } 7334 } 7335 7336 @Override 7337 public IActivityContainer getEnclosingActivityContainer(IBinder activityToken) 7338 throws RemoteException { 7339 synchronized (this) { 7340 ActivityStack stack = ActivityRecord.getStackLocked(activityToken); 7341 if (stack != null) { 7342 return stack.mActivityContainer; 7343 } 7344 return null; 7345 } 7346 } 7347 7348 @Override 7349 public void moveTaskToStack(int taskId, int stackId, boolean toTop) { 7350 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7351 "moveTaskToStack()"); 7352 if (stackId == HOME_STACK_ID) { 7353 Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack", 7354 new RuntimeException("here").fillInStackTrace()); 7355 } 7356 synchronized (this) { 7357 long ident = Binder.clearCallingIdentity(); 7358 try { 7359 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId=" 7360 + stackId + " toTop=" + toTop); 7361 mStackSupervisor.moveTaskToStack(taskId, stackId, toTop); 7362 } finally { 7363 Binder.restoreCallingIdentity(ident); 7364 } 7365 } 7366 } 7367 7368 @Override 7369 public void resizeStack(int stackBoxId, Rect bounds) { 7370 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7371 "resizeStackBox()"); 7372 long ident = Binder.clearCallingIdentity(); 7373 try { 7374 mWindowManager.resizeStack(stackBoxId, bounds); 7375 } finally { 7376 Binder.restoreCallingIdentity(ident); 7377 } 7378 } 7379 7380 @Override 7381 public List<StackInfo> getAllStackInfos() { 7382 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7383 "getAllStackInfos()"); 7384 long ident = Binder.clearCallingIdentity(); 7385 try { 7386 synchronized (this) { 7387 return mStackSupervisor.getAllStackInfosLocked(); 7388 } 7389 } finally { 7390 Binder.restoreCallingIdentity(ident); 7391 } 7392 } 7393 7394 @Override 7395 public StackInfo getStackInfo(int stackId) { 7396 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7397 "getStackInfo()"); 7398 long ident = Binder.clearCallingIdentity(); 7399 try { 7400 synchronized (this) { 7401 return mStackSupervisor.getStackInfoLocked(stackId); 7402 } 7403 } finally { 7404 Binder.restoreCallingIdentity(ident); 7405 } 7406 } 7407 7408 @Override 7409 public boolean isInHomeStack(int taskId) { 7410 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7411 "getStackInfo()"); 7412 long ident = Binder.clearCallingIdentity(); 7413 try { 7414 synchronized (this) { 7415 TaskRecord tr = recentTaskForIdLocked(taskId); 7416 if (tr != null) { 7417 return tr.stack.isHomeStack(); 7418 } 7419 } 7420 } finally { 7421 Binder.restoreCallingIdentity(ident); 7422 } 7423 return false; 7424 } 7425 7426 @Override 7427 public int getTaskForActivity(IBinder token, boolean onlyRoot) { 7428 synchronized(this) { 7429 return ActivityRecord.getTaskForActivityLocked(token, onlyRoot); 7430 } 7431 } 7432 7433 private boolean isLockTaskAuthorized(ComponentName name) { 7434// enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 7435// "startLockTaskMode()"); 7436// DevicePolicyManager dpm = (DevicePolicyManager) 7437// mContext.getSystemService(Context.DEVICE_POLICY_SERVICE); 7438// return dpm != null && dpm.isLockTaskPermitted(name); 7439 return true; 7440 } 7441 7442 private void startLockTaskMode(TaskRecord task) { 7443 if (!isLockTaskAuthorized(task.intent.getComponent())) { 7444 return; 7445 } 7446 long ident = Binder.clearCallingIdentity(); 7447 try { 7448 synchronized (this) { 7449 // Since we lost lock on task, make sure it is still there. 7450 task = mStackSupervisor.anyTaskForIdLocked(task.taskId); 7451 if (task != null) { 7452 mStackSupervisor.setLockTaskModeLocked(task); 7453 } 7454 } 7455 } finally { 7456 Binder.restoreCallingIdentity(ident); 7457 } 7458 } 7459 7460 @Override 7461 public void startLockTaskMode(int taskId) { 7462 long ident = Binder.clearCallingIdentity(); 7463 try { 7464 final TaskRecord task; 7465 synchronized (this) { 7466 task = mStackSupervisor.anyTaskForIdLocked(taskId); 7467 } 7468 if (task != null) { 7469 startLockTaskMode(task); 7470 } 7471 } finally { 7472 Binder.restoreCallingIdentity(ident); 7473 } 7474 } 7475 7476 @Override 7477 public void startLockTaskMode(IBinder token) { 7478 long ident = Binder.clearCallingIdentity(); 7479 try { 7480 final TaskRecord task; 7481 synchronized (this) { 7482 final ActivityRecord r = ActivityRecord.forToken(token); 7483 if (r == null) { 7484 return; 7485 } 7486 task = r.task; 7487 } 7488 if (task != null) { 7489 startLockTaskMode(task); 7490 } 7491 } finally { 7492 Binder.restoreCallingIdentity(ident); 7493 } 7494 } 7495 7496 @Override 7497 public void stopLockTaskMode() { 7498// enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 7499// "stopLockTaskMode()"); 7500 synchronized (this) { 7501 mStackSupervisor.setLockTaskModeLocked(null); 7502 } 7503 } 7504 7505 @Override 7506 public boolean isInLockTaskMode() { 7507 synchronized (this) { 7508 return mStackSupervisor.isInLockTaskMode(); 7509 } 7510 } 7511 7512 // ========================================================= 7513 // THUMBNAILS 7514 // ========================================================= 7515 7516 public void reportThumbnail(IBinder token, 7517 Bitmap thumbnail, CharSequence description) { 7518 //System.out.println("Report thumbnail for " + token + ": " + thumbnail); 7519 final long origId = Binder.clearCallingIdentity(); 7520 sendPendingThumbnail(null, token, thumbnail, description, true); 7521 Binder.restoreCallingIdentity(origId); 7522 } 7523 7524 final void sendPendingThumbnail(ActivityRecord r, IBinder token, 7525 Bitmap thumbnail, CharSequence description, boolean always) { 7526 TaskRecord task; 7527 ArrayList<PendingThumbnailsRecord> receivers = null; 7528 7529 //System.out.println("Send pending thumbnail: " + r); 7530 7531 synchronized(this) { 7532 if (r == null) { 7533 r = ActivityRecord.isInStackLocked(token); 7534 if (r == null) { 7535 return; 7536 } 7537 } 7538 if (thumbnail == null && r.thumbHolder != null) { 7539 thumbnail = r.thumbHolder.lastThumbnail; 7540 description = r.thumbHolder.lastDescription; 7541 } 7542 if (thumbnail == null && !always) { 7543 // If there is no thumbnail, and this entry is not actually 7544 // going away, then abort for now and pick up the next 7545 // thumbnail we get. 7546 return; 7547 } 7548 task = r.task; 7549 7550 int N = mPendingThumbnails.size(); 7551 int i=0; 7552 while (i<N) { 7553 PendingThumbnailsRecord pr = mPendingThumbnails.get(i); 7554 //System.out.println("Looking in " + pr.pendingRecords); 7555 if (pr.pendingRecords.remove(r)) { 7556 if (receivers == null) { 7557 receivers = new ArrayList<PendingThumbnailsRecord>(); 7558 } 7559 receivers.add(pr); 7560 if (pr.pendingRecords.size() == 0) { 7561 pr.finished = true; 7562 mPendingThumbnails.remove(i); 7563 N--; 7564 continue; 7565 } 7566 } 7567 i++; 7568 } 7569 } 7570 7571 if (receivers != null) { 7572 final int N = receivers.size(); 7573 for (int i=0; i<N; i++) { 7574 try { 7575 PendingThumbnailsRecord pr = receivers.get(i); 7576 pr.receiver.newThumbnail( 7577 task != null ? task.taskId : -1, thumbnail, description); 7578 if (pr.finished) { 7579 pr.receiver.finished(); 7580 } 7581 } catch (Exception e) { 7582 Slog.w(TAG, "Exception thrown when sending thumbnail", e); 7583 } 7584 } 7585 } 7586 } 7587 7588 // ========================================================= 7589 // CONTENT PROVIDERS 7590 // ========================================================= 7591 7592 private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) { 7593 List<ProviderInfo> providers = null; 7594 try { 7595 providers = AppGlobals.getPackageManager(). 7596 queryContentProviders(app.processName, app.uid, 7597 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS); 7598 } catch (RemoteException ex) { 7599 } 7600 if (DEBUG_MU) 7601 Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid); 7602 int userId = app.userId; 7603 if (providers != null) { 7604 int N = providers.size(); 7605 app.pubProviders.ensureCapacity(N + app.pubProviders.size()); 7606 for (int i=0; i<N; i++) { 7607 ProviderInfo cpi = 7608 (ProviderInfo)providers.get(i); 7609 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo, 7610 cpi.name, cpi.flags); 7611 if (singleton && UserHandle.getUserId(app.uid) != 0) { 7612 // This is a singleton provider, but a user besides the 7613 // default user is asking to initialize a process it runs 7614 // in... well, no, it doesn't actually run in this process, 7615 // it runs in the process of the default user. Get rid of it. 7616 providers.remove(i); 7617 N--; 7618 i--; 7619 continue; 7620 } 7621 7622 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 7623 ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId); 7624 if (cpr == null) { 7625 cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton); 7626 mProviderMap.putProviderByClass(comp, cpr); 7627 } 7628 if (DEBUG_MU) 7629 Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid); 7630 app.pubProviders.put(cpi.name, cpr); 7631 if (!cpi.multiprocess || !"android".equals(cpi.packageName)) { 7632 // Don't add this if it is a platform component that is marked 7633 // to run in multiple processes, because this is actually 7634 // part of the framework so doesn't make sense to track as a 7635 // separate apk in the process. 7636 app.addPackage(cpi.applicationInfo.packageName, mProcessStats); 7637 } 7638 ensurePackageDexOpt(cpi.applicationInfo.packageName); 7639 } 7640 } 7641 return providers; 7642 } 7643 7644 /** 7645 * Check if {@link ProcessRecord} has a possible chance at accessing the 7646 * given {@link ProviderInfo}. Final permission checking is always done 7647 * in {@link ContentProvider}. 7648 */ 7649 private final String checkContentProviderPermissionLocked( 7650 ProviderInfo cpi, ProcessRecord r) { 7651 final int callingPid = (r != null) ? r.pid : Binder.getCallingPid(); 7652 final int callingUid = (r != null) ? r.uid : Binder.getCallingUid(); 7653 if (checkComponentPermission(cpi.readPermission, callingPid, callingUid, 7654 cpi.applicationInfo.uid, cpi.exported) 7655 == PackageManager.PERMISSION_GRANTED) { 7656 return null; 7657 } 7658 if (checkComponentPermission(cpi.writePermission, callingPid, callingUid, 7659 cpi.applicationInfo.uid, cpi.exported) 7660 == PackageManager.PERMISSION_GRANTED) { 7661 return null; 7662 } 7663 7664 PathPermission[] pps = cpi.pathPermissions; 7665 if (pps != null) { 7666 int i = pps.length; 7667 while (i > 0) { 7668 i--; 7669 PathPermission pp = pps[i]; 7670 if (checkComponentPermission(pp.getReadPermission(), callingPid, callingUid, 7671 cpi.applicationInfo.uid, cpi.exported) 7672 == PackageManager.PERMISSION_GRANTED) { 7673 return null; 7674 } 7675 if (checkComponentPermission(pp.getWritePermission(), callingPid, callingUid, 7676 cpi.applicationInfo.uid, cpi.exported) 7677 == PackageManager.PERMISSION_GRANTED) { 7678 return null; 7679 } 7680 } 7681 } 7682 7683 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid); 7684 if (perms != null) { 7685 for (GrantUri uri : perms.keySet()) { 7686 if (uri.uri.getAuthority().equals(cpi.authority)) { 7687 return null; 7688 } 7689 } 7690 } 7691 7692 String msg; 7693 if (!cpi.exported) { 7694 msg = "Permission Denial: opening provider " + cpi.name 7695 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 7696 + ", uid=" + callingUid + ") that is not exported from uid " 7697 + cpi.applicationInfo.uid; 7698 } else { 7699 msg = "Permission Denial: opening provider " + cpi.name 7700 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 7701 + ", uid=" + callingUid + ") requires " 7702 + cpi.readPermission + " or " + cpi.writePermission; 7703 } 7704 Slog.w(TAG, msg); 7705 return msg; 7706 } 7707 7708 ContentProviderConnection incProviderCountLocked(ProcessRecord r, 7709 final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 7710 if (r != null) { 7711 for (int i=0; i<r.conProviders.size(); i++) { 7712 ContentProviderConnection conn = r.conProviders.get(i); 7713 if (conn.provider == cpr) { 7714 if (DEBUG_PROVIDER) Slog.v(TAG, 7715 "Adding provider requested by " 7716 + r.processName + " from process " 7717 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 7718 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 7719 if (stable) { 7720 conn.stableCount++; 7721 conn.numStableIncs++; 7722 } else { 7723 conn.unstableCount++; 7724 conn.numUnstableIncs++; 7725 } 7726 return conn; 7727 } 7728 } 7729 ContentProviderConnection conn = new ContentProviderConnection(cpr, r); 7730 if (stable) { 7731 conn.stableCount = 1; 7732 conn.numStableIncs = 1; 7733 } else { 7734 conn.unstableCount = 1; 7735 conn.numUnstableIncs = 1; 7736 } 7737 cpr.connections.add(conn); 7738 r.conProviders.add(conn); 7739 return conn; 7740 } 7741 cpr.addExternalProcessHandleLocked(externalProcessToken); 7742 return null; 7743 } 7744 7745 boolean decProviderCountLocked(ContentProviderConnection conn, 7746 ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 7747 if (conn != null) { 7748 cpr = conn.provider; 7749 if (DEBUG_PROVIDER) Slog.v(TAG, 7750 "Removing provider requested by " 7751 + conn.client.processName + " from process " 7752 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 7753 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 7754 if (stable) { 7755 conn.stableCount--; 7756 } else { 7757 conn.unstableCount--; 7758 } 7759 if (conn.stableCount == 0 && conn.unstableCount == 0) { 7760 cpr.connections.remove(conn); 7761 conn.client.conProviders.remove(conn); 7762 return true; 7763 } 7764 return false; 7765 } 7766 cpr.removeExternalProcessHandleLocked(externalProcessToken); 7767 return false; 7768 } 7769 7770 private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller, 7771 String name, IBinder token, boolean stable, int userId) { 7772 ContentProviderRecord cpr; 7773 ContentProviderConnection conn = null; 7774 ProviderInfo cpi = null; 7775 7776 synchronized(this) { 7777 ProcessRecord r = null; 7778 if (caller != null) { 7779 r = getRecordForAppLocked(caller); 7780 if (r == null) { 7781 throw new SecurityException( 7782 "Unable to find app for caller " + caller 7783 + " (pid=" + Binder.getCallingPid() 7784 + ") when getting content provider " + name); 7785 } 7786 } 7787 7788 // First check if this content provider has been published... 7789 cpr = mProviderMap.getProviderByName(name, userId); 7790 boolean providerRunning = cpr != null; 7791 if (providerRunning) { 7792 cpi = cpr.info; 7793 String msg; 7794 if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) { 7795 throw new SecurityException(msg); 7796 } 7797 7798 if (r != null && cpr.canRunHere(r)) { 7799 // This provider has been published or is in the process 7800 // of being published... but it is also allowed to run 7801 // in the caller's process, so don't make a connection 7802 // and just let the caller instantiate its own instance. 7803 ContentProviderHolder holder = cpr.newHolder(null); 7804 // don't give caller the provider object, it needs 7805 // to make its own. 7806 holder.provider = null; 7807 return holder; 7808 } 7809 7810 final long origId = Binder.clearCallingIdentity(); 7811 7812 // In this case the provider instance already exists, so we can 7813 // return it right away. 7814 conn = incProviderCountLocked(r, cpr, token, stable); 7815 if (conn != null && (conn.stableCount+conn.unstableCount) == 1) { 7816 if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 7817 // If this is a perceptible app accessing the provider, 7818 // make sure to count it as being accessed and thus 7819 // back up on the LRU list. This is good because 7820 // content providers are often expensive to start. 7821 updateLruProcessLocked(cpr.proc, false, null); 7822 } 7823 } 7824 7825 if (cpr.proc != null) { 7826 if (false) { 7827 if (cpr.name.flattenToShortString().equals( 7828 "com.android.providers.calendar/.CalendarProvider2")) { 7829 Slog.v(TAG, "****************** KILLING " 7830 + cpr.name.flattenToShortString()); 7831 Process.killProcess(cpr.proc.pid); 7832 } 7833 } 7834 boolean success = updateOomAdjLocked(cpr.proc); 7835 if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success); 7836 // NOTE: there is still a race here where a signal could be 7837 // pending on the process even though we managed to update its 7838 // adj level. Not sure what to do about this, but at least 7839 // the race is now smaller. 7840 if (!success) { 7841 // Uh oh... it looks like the provider's process 7842 // has been killed on us. We need to wait for a new 7843 // process to be started, and make sure its death 7844 // doesn't kill our process. 7845 Slog.i(TAG, 7846 "Existing provider " + cpr.name.flattenToShortString() 7847 + " is crashing; detaching " + r); 7848 boolean lastRef = decProviderCountLocked(conn, cpr, token, stable); 7849 appDiedLocked(cpr.proc, cpr.proc.pid, cpr.proc.thread); 7850 if (!lastRef) { 7851 // This wasn't the last ref our process had on 7852 // the provider... we have now been killed, bail. 7853 return null; 7854 } 7855 providerRunning = false; 7856 conn = null; 7857 } 7858 } 7859 7860 Binder.restoreCallingIdentity(origId); 7861 } 7862 7863 boolean singleton; 7864 if (!providerRunning) { 7865 try { 7866 cpi = AppGlobals.getPackageManager(). 7867 resolveContentProvider(name, 7868 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId); 7869 } catch (RemoteException ex) { 7870 } 7871 if (cpi == null) { 7872 return null; 7873 } 7874 singleton = isSingleton(cpi.processName, cpi.applicationInfo, 7875 cpi.name, cpi.flags); 7876 if (singleton) { 7877 userId = 0; 7878 } 7879 cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId); 7880 7881 String msg; 7882 if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) { 7883 throw new SecurityException(msg); 7884 } 7885 7886 if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate 7887 && !cpi.processName.equals("system")) { 7888 // If this content provider does not run in the system 7889 // process, and the system is not yet ready to run other 7890 // processes, then fail fast instead of hanging. 7891 throw new IllegalArgumentException( 7892 "Attempt to launch content provider before system ready"); 7893 } 7894 7895 // Make sure that the user who owns this provider is started. If not, 7896 // we don't want to allow it to run. 7897 if (mStartedUsers.get(userId) == null) { 7898 Slog.w(TAG, "Unable to launch app " 7899 + cpi.applicationInfo.packageName + "/" 7900 + cpi.applicationInfo.uid + " for provider " 7901 + name + ": user " + userId + " is stopped"); 7902 return null; 7903 } 7904 7905 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 7906 cpr = mProviderMap.getProviderByClass(comp, userId); 7907 final boolean firstClass = cpr == null; 7908 if (firstClass) { 7909 try { 7910 ApplicationInfo ai = 7911 AppGlobals.getPackageManager(). 7912 getApplicationInfo( 7913 cpi.applicationInfo.packageName, 7914 STOCK_PM_FLAGS, userId); 7915 if (ai == null) { 7916 Slog.w(TAG, "No package info for content provider " 7917 + cpi.name); 7918 return null; 7919 } 7920 ai = getAppInfoForUser(ai, userId); 7921 cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton); 7922 } catch (RemoteException ex) { 7923 // pm is in same process, this will never happen. 7924 } 7925 } 7926 7927 if (r != null && cpr.canRunHere(r)) { 7928 // If this is a multiprocess provider, then just return its 7929 // info and allow the caller to instantiate it. Only do 7930 // this if the provider is the same user as the caller's 7931 // process, or can run as root (so can be in any process). 7932 return cpr.newHolder(null); 7933 } 7934 7935 if (DEBUG_PROVIDER) { 7936 RuntimeException e = new RuntimeException("here"); 7937 Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null) 7938 + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e); 7939 } 7940 7941 // This is single process, and our app is now connecting to it. 7942 // See if we are already in the process of launching this 7943 // provider. 7944 final int N = mLaunchingProviders.size(); 7945 int i; 7946 for (i=0; i<N; i++) { 7947 if (mLaunchingProviders.get(i) == cpr) { 7948 break; 7949 } 7950 } 7951 7952 // If the provider is not already being launched, then get it 7953 // started. 7954 if (i >= N) { 7955 final long origId = Binder.clearCallingIdentity(); 7956 7957 try { 7958 // Content provider is now in use, its package can't be stopped. 7959 try { 7960 AppGlobals.getPackageManager().setPackageStoppedState( 7961 cpr.appInfo.packageName, false, userId); 7962 } catch (RemoteException e) { 7963 } catch (IllegalArgumentException e) { 7964 Slog.w(TAG, "Failed trying to unstop package " 7965 + cpr.appInfo.packageName + ": " + e); 7966 } 7967 7968 // Use existing process if already started 7969 ProcessRecord proc = getProcessRecordLocked( 7970 cpi.processName, cpr.appInfo.uid, false); 7971 if (proc != null && proc.thread != null) { 7972 if (DEBUG_PROVIDER) { 7973 Slog.d(TAG, "Installing in existing process " + proc); 7974 } 7975 proc.pubProviders.put(cpi.name, cpr); 7976 try { 7977 proc.thread.scheduleInstallProvider(cpi); 7978 } catch (RemoteException e) { 7979 } 7980 } else { 7981 proc = startProcessLocked(cpi.processName, 7982 cpr.appInfo, false, 0, "content provider", 7983 new ComponentName(cpi.applicationInfo.packageName, 7984 cpi.name), false, false, false); 7985 if (proc == null) { 7986 Slog.w(TAG, "Unable to launch app " 7987 + cpi.applicationInfo.packageName + "/" 7988 + cpi.applicationInfo.uid + " for provider " 7989 + name + ": process is bad"); 7990 return null; 7991 } 7992 } 7993 cpr.launchingApp = proc; 7994 mLaunchingProviders.add(cpr); 7995 } finally { 7996 Binder.restoreCallingIdentity(origId); 7997 } 7998 } 7999 8000 // Make sure the provider is published (the same provider class 8001 // may be published under multiple names). 8002 if (firstClass) { 8003 mProviderMap.putProviderByClass(comp, cpr); 8004 } 8005 8006 mProviderMap.putProviderByName(name, cpr); 8007 conn = incProviderCountLocked(r, cpr, token, stable); 8008 if (conn != null) { 8009 conn.waiting = true; 8010 } 8011 } 8012 } 8013 8014 // Wait for the provider to be published... 8015 synchronized (cpr) { 8016 while (cpr.provider == null) { 8017 if (cpr.launchingApp == null) { 8018 Slog.w(TAG, "Unable to launch app " 8019 + cpi.applicationInfo.packageName + "/" 8020 + cpi.applicationInfo.uid + " for provider " 8021 + name + ": launching app became null"); 8022 EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS, 8023 UserHandle.getUserId(cpi.applicationInfo.uid), 8024 cpi.applicationInfo.packageName, 8025 cpi.applicationInfo.uid, name); 8026 return null; 8027 } 8028 try { 8029 if (DEBUG_MU) { 8030 Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp=" 8031 + cpr.launchingApp); 8032 } 8033 if (conn != null) { 8034 conn.waiting = true; 8035 } 8036 cpr.wait(); 8037 } catch (InterruptedException ex) { 8038 } finally { 8039 if (conn != null) { 8040 conn.waiting = false; 8041 } 8042 } 8043 } 8044 } 8045 return cpr != null ? cpr.newHolder(conn) : null; 8046 } 8047 8048 public final ContentProviderHolder getContentProvider( 8049 IApplicationThread caller, String name, int userId, boolean stable) { 8050 enforceNotIsolatedCaller("getContentProvider"); 8051 if (caller == null) { 8052 String msg = "null IApplicationThread when getting content provider " 8053 + name; 8054 Slog.w(TAG, msg); 8055 throw new SecurityException(msg); 8056 } 8057 8058 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 8059 false, true, "getContentProvider", null); 8060 return getContentProviderImpl(caller, name, null, stable, userId); 8061 } 8062 8063 public ContentProviderHolder getContentProviderExternal( 8064 String name, int userId, IBinder token) { 8065 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 8066 "Do not have permission in call getContentProviderExternal()"); 8067 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 8068 false, true, "getContentProvider", null); 8069 return getContentProviderExternalUnchecked(name, token, userId); 8070 } 8071 8072 private ContentProviderHolder getContentProviderExternalUnchecked(String name, 8073 IBinder token, int userId) { 8074 return getContentProviderImpl(null, name, token, true, userId); 8075 } 8076 8077 /** 8078 * Drop a content provider from a ProcessRecord's bookkeeping 8079 */ 8080 public void removeContentProvider(IBinder connection, boolean stable) { 8081 enforceNotIsolatedCaller("removeContentProvider"); 8082 long ident = Binder.clearCallingIdentity(); 8083 try { 8084 synchronized (this) { 8085 ContentProviderConnection conn; 8086 try { 8087 conn = (ContentProviderConnection)connection; 8088 } catch (ClassCastException e) { 8089 String msg ="removeContentProvider: " + connection 8090 + " not a ContentProviderConnection"; 8091 Slog.w(TAG, msg); 8092 throw new IllegalArgumentException(msg); 8093 } 8094 if (conn == null) { 8095 throw new NullPointerException("connection is null"); 8096 } 8097 if (decProviderCountLocked(conn, null, null, stable)) { 8098 updateOomAdjLocked(); 8099 } 8100 } 8101 } finally { 8102 Binder.restoreCallingIdentity(ident); 8103 } 8104 } 8105 8106 public void removeContentProviderExternal(String name, IBinder token) { 8107 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 8108 "Do not have permission in call removeContentProviderExternal()"); 8109 removeContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId()); 8110 } 8111 8112 private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) { 8113 synchronized (this) { 8114 ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId); 8115 if(cpr == null) { 8116 //remove from mProvidersByClass 8117 if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list"); 8118 return; 8119 } 8120 8121 //update content provider record entry info 8122 ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name); 8123 ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId); 8124 if (localCpr.hasExternalProcessHandles()) { 8125 if (localCpr.removeExternalProcessHandleLocked(token)) { 8126 updateOomAdjLocked(); 8127 } else { 8128 Slog.e(TAG, "Attmpt to remove content provider " + localCpr 8129 + " with no external reference for token: " 8130 + token + "."); 8131 } 8132 } else { 8133 Slog.e(TAG, "Attmpt to remove content provider: " + localCpr 8134 + " with no external references."); 8135 } 8136 } 8137 } 8138 8139 public final void publishContentProviders(IApplicationThread caller, 8140 List<ContentProviderHolder> providers) { 8141 if (providers == null) { 8142 return; 8143 } 8144 8145 enforceNotIsolatedCaller("publishContentProviders"); 8146 synchronized (this) { 8147 final ProcessRecord r = getRecordForAppLocked(caller); 8148 if (DEBUG_MU) 8149 Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid); 8150 if (r == null) { 8151 throw new SecurityException( 8152 "Unable to find app for caller " + caller 8153 + " (pid=" + Binder.getCallingPid() 8154 + ") when publishing content providers"); 8155 } 8156 8157 final long origId = Binder.clearCallingIdentity(); 8158 8159 final int N = providers.size(); 8160 for (int i=0; i<N; i++) { 8161 ContentProviderHolder src = providers.get(i); 8162 if (src == null || src.info == null || src.provider == null) { 8163 continue; 8164 } 8165 ContentProviderRecord dst = r.pubProviders.get(src.info.name); 8166 if (DEBUG_MU) 8167 Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid); 8168 if (dst != null) { 8169 ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name); 8170 mProviderMap.putProviderByClass(comp, dst); 8171 String names[] = dst.info.authority.split(";"); 8172 for (int j = 0; j < names.length; j++) { 8173 mProviderMap.putProviderByName(names[j], dst); 8174 } 8175 8176 int NL = mLaunchingProviders.size(); 8177 int j; 8178 for (j=0; j<NL; j++) { 8179 if (mLaunchingProviders.get(j) == dst) { 8180 mLaunchingProviders.remove(j); 8181 j--; 8182 NL--; 8183 } 8184 } 8185 synchronized (dst) { 8186 dst.provider = src.provider; 8187 dst.proc = r; 8188 dst.notifyAll(); 8189 } 8190 updateOomAdjLocked(r); 8191 } 8192 } 8193 8194 Binder.restoreCallingIdentity(origId); 8195 } 8196 } 8197 8198 public boolean refContentProvider(IBinder connection, int stable, int unstable) { 8199 ContentProviderConnection conn; 8200 try { 8201 conn = (ContentProviderConnection)connection; 8202 } catch (ClassCastException e) { 8203 String msg ="refContentProvider: " + connection 8204 + " not a ContentProviderConnection"; 8205 Slog.w(TAG, msg); 8206 throw new IllegalArgumentException(msg); 8207 } 8208 if (conn == null) { 8209 throw new NullPointerException("connection is null"); 8210 } 8211 8212 synchronized (this) { 8213 if (stable > 0) { 8214 conn.numStableIncs += stable; 8215 } 8216 stable = conn.stableCount + stable; 8217 if (stable < 0) { 8218 throw new IllegalStateException("stableCount < 0: " + stable); 8219 } 8220 8221 if (unstable > 0) { 8222 conn.numUnstableIncs += unstable; 8223 } 8224 unstable = conn.unstableCount + unstable; 8225 if (unstable < 0) { 8226 throw new IllegalStateException("unstableCount < 0: " + unstable); 8227 } 8228 8229 if ((stable+unstable) <= 0) { 8230 throw new IllegalStateException("ref counts can't go to zero here: stable=" 8231 + stable + " unstable=" + unstable); 8232 } 8233 conn.stableCount = stable; 8234 conn.unstableCount = unstable; 8235 return !conn.dead; 8236 } 8237 } 8238 8239 public void unstableProviderDied(IBinder connection) { 8240 ContentProviderConnection conn; 8241 try { 8242 conn = (ContentProviderConnection)connection; 8243 } catch (ClassCastException e) { 8244 String msg ="refContentProvider: " + connection 8245 + " not a ContentProviderConnection"; 8246 Slog.w(TAG, msg); 8247 throw new IllegalArgumentException(msg); 8248 } 8249 if (conn == null) { 8250 throw new NullPointerException("connection is null"); 8251 } 8252 8253 // Safely retrieve the content provider associated with the connection. 8254 IContentProvider provider; 8255 synchronized (this) { 8256 provider = conn.provider.provider; 8257 } 8258 8259 if (provider == null) { 8260 // Um, yeah, we're way ahead of you. 8261 return; 8262 } 8263 8264 // Make sure the caller is being honest with us. 8265 if (provider.asBinder().pingBinder()) { 8266 // Er, no, still looks good to us. 8267 synchronized (this) { 8268 Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid() 8269 + " says " + conn + " died, but we don't agree"); 8270 return; 8271 } 8272 } 8273 8274 // Well look at that! It's dead! 8275 synchronized (this) { 8276 if (conn.provider.provider != provider) { 8277 // But something changed... good enough. 8278 return; 8279 } 8280 8281 ProcessRecord proc = conn.provider.proc; 8282 if (proc == null || proc.thread == null) { 8283 // Seems like the process is already cleaned up. 8284 return; 8285 } 8286 8287 // As far as we're concerned, this is just like receiving a 8288 // death notification... just a bit prematurely. 8289 Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid 8290 + ") early provider death"); 8291 final long ident = Binder.clearCallingIdentity(); 8292 try { 8293 appDiedLocked(proc, proc.pid, proc.thread); 8294 } finally { 8295 Binder.restoreCallingIdentity(ident); 8296 } 8297 } 8298 } 8299 8300 @Override 8301 public void appNotRespondingViaProvider(IBinder connection) { 8302 enforceCallingPermission( 8303 android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()"); 8304 8305 final ContentProviderConnection conn = (ContentProviderConnection) connection; 8306 if (conn == null) { 8307 Slog.w(TAG, "ContentProviderConnection is null"); 8308 return; 8309 } 8310 8311 final ProcessRecord host = conn.provider.proc; 8312 if (host == null) { 8313 Slog.w(TAG, "Failed to find hosting ProcessRecord"); 8314 return; 8315 } 8316 8317 final long token = Binder.clearCallingIdentity(); 8318 try { 8319 appNotResponding(host, null, null, false, "ContentProvider not responding"); 8320 } finally { 8321 Binder.restoreCallingIdentity(token); 8322 } 8323 } 8324 8325 public final void installSystemProviders() { 8326 List<ProviderInfo> providers; 8327 synchronized (this) { 8328 ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID); 8329 providers = generateApplicationProvidersLocked(app); 8330 if (providers != null) { 8331 for (int i=providers.size()-1; i>=0; i--) { 8332 ProviderInfo pi = (ProviderInfo)providers.get(i); 8333 if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) { 8334 Slog.w(TAG, "Not installing system proc provider " + pi.name 8335 + ": not system .apk"); 8336 providers.remove(i); 8337 } 8338 } 8339 } 8340 } 8341 if (providers != null) { 8342 mSystemThread.installSystemProviders(providers); 8343 } 8344 8345 mCoreSettingsObserver = new CoreSettingsObserver(this); 8346 8347 mUsageStatsService.monitorPackages(); 8348 } 8349 8350 /** 8351 * Allows app to retrieve the MIME type of a URI without having permission 8352 * to access its content provider. 8353 * 8354 * CTS tests for this functionality can be run with "runtest cts-appsecurity". 8355 * 8356 * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/ 8357 * src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java 8358 */ 8359 public String getProviderMimeType(Uri uri, int userId) { 8360 enforceNotIsolatedCaller("getProviderMimeType"); 8361 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 8362 userId, false, true, "getProviderMimeType", null); 8363 final String name = uri.getAuthority(); 8364 final long ident = Binder.clearCallingIdentity(); 8365 ContentProviderHolder holder = null; 8366 8367 try { 8368 holder = getContentProviderExternalUnchecked(name, null, userId); 8369 if (holder != null) { 8370 return holder.provider.getType(uri); 8371 } 8372 } catch (RemoteException e) { 8373 Log.w(TAG, "Content provider dead retrieving " + uri, e); 8374 return null; 8375 } finally { 8376 if (holder != null) { 8377 removeContentProviderExternalUnchecked(name, null, userId); 8378 } 8379 Binder.restoreCallingIdentity(ident); 8380 } 8381 8382 return null; 8383 } 8384 8385 // ========================================================= 8386 // GLOBAL MANAGEMENT 8387 // ========================================================= 8388 8389 final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess, 8390 boolean isolated) { 8391 String proc = customProcess != null ? customProcess : info.processName; 8392 BatteryStatsImpl.Uid.Proc ps = null; 8393 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 8394 int uid = info.uid; 8395 if (isolated) { 8396 int userId = UserHandle.getUserId(uid); 8397 int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1; 8398 while (true) { 8399 if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID 8400 || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) { 8401 mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID; 8402 } 8403 uid = UserHandle.getUid(userId, mNextIsolatedProcessUid); 8404 mNextIsolatedProcessUid++; 8405 if (mIsolatedProcesses.indexOfKey(uid) < 0) { 8406 // No process for this uid, use it. 8407 break; 8408 } 8409 stepsLeft--; 8410 if (stepsLeft <= 0) { 8411 return null; 8412 } 8413 } 8414 } 8415 return new ProcessRecord(stats, info, proc, uid); 8416 } 8417 8418 final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated) { 8419 ProcessRecord app; 8420 if (!isolated) { 8421 app = getProcessRecordLocked(info.processName, info.uid, true); 8422 } else { 8423 app = null; 8424 } 8425 8426 if (app == null) { 8427 app = newProcessRecordLocked(info, null, isolated); 8428 mProcessNames.put(info.processName, app.uid, app); 8429 if (isolated) { 8430 mIsolatedProcesses.put(app.uid, app); 8431 } 8432 updateLruProcessLocked(app, false, null); 8433 updateOomAdjLocked(); 8434 } 8435 8436 // This package really, really can not be stopped. 8437 try { 8438 AppGlobals.getPackageManager().setPackageStoppedState( 8439 info.packageName, false, UserHandle.getUserId(app.uid)); 8440 } catch (RemoteException e) { 8441 } catch (IllegalArgumentException e) { 8442 Slog.w(TAG, "Failed trying to unstop package " 8443 + info.packageName + ": " + e); 8444 } 8445 8446 if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) 8447 == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) { 8448 app.persistent = true; 8449 app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ; 8450 } 8451 if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) { 8452 mPersistentStartingProcesses.add(app); 8453 startProcessLocked(app, "added application", app.processName); 8454 } 8455 8456 return app; 8457 } 8458 8459 public void unhandledBack() { 8460 enforceCallingPermission(android.Manifest.permission.FORCE_BACK, 8461 "unhandledBack()"); 8462 8463 synchronized(this) { 8464 final long origId = Binder.clearCallingIdentity(); 8465 try { 8466 getFocusedStack().unhandledBackLocked(); 8467 } finally { 8468 Binder.restoreCallingIdentity(origId); 8469 } 8470 } 8471 } 8472 8473 public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException { 8474 enforceNotIsolatedCaller("openContentUri"); 8475 final int userId = UserHandle.getCallingUserId(); 8476 String name = uri.getAuthority(); 8477 ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId); 8478 ParcelFileDescriptor pfd = null; 8479 if (cph != null) { 8480 // We record the binder invoker's uid in thread-local storage before 8481 // going to the content provider to open the file. Later, in the code 8482 // that handles all permissions checks, we look for this uid and use 8483 // that rather than the Activity Manager's own uid. The effect is that 8484 // we do the check against the caller's permissions even though it looks 8485 // to the content provider like the Activity Manager itself is making 8486 // the request. 8487 sCallerIdentity.set(new Identity( 8488 Binder.getCallingPid(), Binder.getCallingUid())); 8489 try { 8490 pfd = cph.provider.openFile(null, uri, "r", null); 8491 } catch (FileNotFoundException e) { 8492 // do nothing; pfd will be returned null 8493 } finally { 8494 // Ensure that whatever happens, we clean up the identity state 8495 sCallerIdentity.remove(); 8496 } 8497 8498 // We've got the fd now, so we're done with the provider. 8499 removeContentProviderExternalUnchecked(name, null, userId); 8500 } else { 8501 Slog.d(TAG, "Failed to get provider for authority '" + name + "'"); 8502 } 8503 return pfd; 8504 } 8505 8506 // Actually is sleeping or shutting down or whatever else in the future 8507 // is an inactive state. 8508 public boolean isSleepingOrShuttingDown() { 8509 return mSleeping || mShuttingDown; 8510 } 8511 8512 void goingToSleep() { 8513 synchronized(this) { 8514 mWentToSleep = true; 8515 updateEventDispatchingLocked(); 8516 8517 if (!mSleeping) { 8518 mSleeping = true; 8519 mStackSupervisor.goingToSleepLocked(); 8520 8521 // Initialize the wake times of all processes. 8522 checkExcessivePowerUsageLocked(false); 8523 mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 8524 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 8525 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 8526 } 8527 } 8528 } 8529 8530 @Override 8531 public boolean shutdown(int timeout) { 8532 if (checkCallingPermission(android.Manifest.permission.SHUTDOWN) 8533 != PackageManager.PERMISSION_GRANTED) { 8534 throw new SecurityException("Requires permission " 8535 + android.Manifest.permission.SHUTDOWN); 8536 } 8537 8538 boolean timedout = false; 8539 8540 synchronized(this) { 8541 mShuttingDown = true; 8542 updateEventDispatchingLocked(); 8543 timedout = mStackSupervisor.shutdownLocked(timeout); 8544 } 8545 8546 mAppOpsService.shutdown(); 8547 mUsageStatsService.shutdown(); 8548 mBatteryStatsService.shutdown(); 8549 synchronized (this) { 8550 mProcessStats.shutdownLocked(); 8551 } 8552 8553 return timedout; 8554 } 8555 8556 public final void activitySlept(IBinder token) { 8557 if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token); 8558 8559 final long origId = Binder.clearCallingIdentity(); 8560 8561 synchronized (this) { 8562 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 8563 if (r != null) { 8564 mStackSupervisor.activitySleptLocked(r); 8565 } 8566 } 8567 8568 Binder.restoreCallingIdentity(origId); 8569 } 8570 8571 void logLockScreen(String msg) { 8572 if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg + 8573 " mLockScreenShown=" + mLockScreenShown + " mWentToSleep=" + 8574 mWentToSleep + " mSleeping=" + mSleeping + " mDismissKeyguardOnNextActivity=" + 8575 mStackSupervisor.mDismissKeyguardOnNextActivity); 8576 } 8577 8578 private void comeOutOfSleepIfNeededLocked() { 8579 if (!mWentToSleep && !mLockScreenShown) { 8580 if (mSleeping) { 8581 mSleeping = false; 8582 mStackSupervisor.comeOutOfSleepIfNeededLocked(); 8583 } 8584 } 8585 } 8586 8587 void wakingUp() { 8588 synchronized(this) { 8589 mWentToSleep = false; 8590 updateEventDispatchingLocked(); 8591 comeOutOfSleepIfNeededLocked(); 8592 } 8593 } 8594 8595 private void updateEventDispatchingLocked() { 8596 mWindowManager.setEventDispatching(mBooted && !mWentToSleep && !mShuttingDown); 8597 } 8598 8599 public void setLockScreenShown(boolean shown) { 8600 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER) 8601 != PackageManager.PERMISSION_GRANTED) { 8602 throw new SecurityException("Requires permission " 8603 + android.Manifest.permission.DEVICE_POWER); 8604 } 8605 8606 synchronized(this) { 8607 long ident = Binder.clearCallingIdentity(); 8608 try { 8609 if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown); 8610 mLockScreenShown = shown; 8611 comeOutOfSleepIfNeededLocked(); 8612 } finally { 8613 Binder.restoreCallingIdentity(ident); 8614 } 8615 } 8616 } 8617 8618 public void stopAppSwitches() { 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 mAppSwitchesAllowedTime = SystemClock.uptimeMillis() 8627 + APP_SWITCH_DELAY_TIME; 8628 mDidAppSwitch = false; 8629 mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 8630 Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 8631 mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME); 8632 } 8633 } 8634 8635 public void resumeAppSwitches() { 8636 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 8637 != PackageManager.PERMISSION_GRANTED) { 8638 throw new SecurityException("Requires permission " 8639 + android.Manifest.permission.STOP_APP_SWITCHES); 8640 } 8641 8642 synchronized(this) { 8643 // Note that we don't execute any pending app switches... we will 8644 // let those wait until either the timeout, or the next start 8645 // activity request. 8646 mAppSwitchesAllowedTime = 0; 8647 } 8648 } 8649 8650 boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid, 8651 String name) { 8652 if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) { 8653 return true; 8654 } 8655 8656 final int perm = checkComponentPermission( 8657 android.Manifest.permission.STOP_APP_SWITCHES, callingPid, 8658 callingUid, -1, true); 8659 if (perm == PackageManager.PERMISSION_GRANTED) { 8660 return true; 8661 } 8662 8663 Slog.w(TAG, name + " request from " + callingUid + " stopped"); 8664 return false; 8665 } 8666 8667 public void setDebugApp(String packageName, boolean waitForDebugger, 8668 boolean persistent) { 8669 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP, 8670 "setDebugApp()"); 8671 8672 long ident = Binder.clearCallingIdentity(); 8673 try { 8674 // Note that this is not really thread safe if there are multiple 8675 // callers into it at the same time, but that's not a situation we 8676 // care about. 8677 if (persistent) { 8678 final ContentResolver resolver = mContext.getContentResolver(); 8679 Settings.Global.putString( 8680 resolver, Settings.Global.DEBUG_APP, 8681 packageName); 8682 Settings.Global.putInt( 8683 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 8684 waitForDebugger ? 1 : 0); 8685 } 8686 8687 synchronized (this) { 8688 if (!persistent) { 8689 mOrigDebugApp = mDebugApp; 8690 mOrigWaitForDebugger = mWaitForDebugger; 8691 } 8692 mDebugApp = packageName; 8693 mWaitForDebugger = waitForDebugger; 8694 mDebugTransient = !persistent; 8695 if (packageName != null) { 8696 forceStopPackageLocked(packageName, -1, false, false, true, true, 8697 false, UserHandle.USER_ALL, "set debug app"); 8698 } 8699 } 8700 } finally { 8701 Binder.restoreCallingIdentity(ident); 8702 } 8703 } 8704 8705 void setOpenGlTraceApp(ApplicationInfo app, String processName) { 8706 synchronized (this) { 8707 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 8708 if (!isDebuggable) { 8709 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 8710 throw new SecurityException("Process not debuggable: " + app.packageName); 8711 } 8712 } 8713 8714 mOpenGlTraceApp = processName; 8715 } 8716 } 8717 8718 void setProfileApp(ApplicationInfo app, String processName, String profileFile, 8719 ParcelFileDescriptor profileFd, boolean autoStopProfiler) { 8720 synchronized (this) { 8721 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 8722 if (!isDebuggable) { 8723 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 8724 throw new SecurityException("Process not debuggable: " + app.packageName); 8725 } 8726 } 8727 mProfileApp = processName; 8728 mProfileFile = profileFile; 8729 if (mProfileFd != null) { 8730 try { 8731 mProfileFd.close(); 8732 } catch (IOException e) { 8733 } 8734 mProfileFd = null; 8735 } 8736 mProfileFd = profileFd; 8737 mProfileType = 0; 8738 mAutoStopProfiler = autoStopProfiler; 8739 } 8740 } 8741 8742 @Override 8743 public void setAlwaysFinish(boolean enabled) { 8744 enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH, 8745 "setAlwaysFinish()"); 8746 8747 Settings.Global.putInt( 8748 mContext.getContentResolver(), 8749 Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0); 8750 8751 synchronized (this) { 8752 mAlwaysFinishActivities = enabled; 8753 } 8754 } 8755 8756 @Override 8757 public void setActivityController(IActivityController controller) { 8758 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 8759 "setActivityController()"); 8760 synchronized (this) { 8761 mController = controller; 8762 Watchdog.getInstance().setActivityController(controller); 8763 } 8764 } 8765 8766 @Override 8767 public void setUserIsMonkey(boolean userIsMonkey) { 8768 synchronized (this) { 8769 synchronized (mPidsSelfLocked) { 8770 final int callingPid = Binder.getCallingPid(); 8771 ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid); 8772 if (precessRecord == null) { 8773 throw new SecurityException("Unknown process: " + callingPid); 8774 } 8775 if (precessRecord.instrumentationUiAutomationConnection == null) { 8776 throw new SecurityException("Only an instrumentation process " 8777 + "with a UiAutomation can call setUserIsMonkey"); 8778 } 8779 } 8780 mUserIsMonkey = userIsMonkey; 8781 } 8782 } 8783 8784 @Override 8785 public boolean isUserAMonkey() { 8786 synchronized (this) { 8787 // If there is a controller also implies the user is a monkey. 8788 return (mUserIsMonkey || mController != null); 8789 } 8790 } 8791 8792 public void requestBugReport() { 8793 enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport"); 8794 SystemProperties.set("ctl.start", "bugreport"); 8795 } 8796 8797 public static long getInputDispatchingTimeoutLocked(ActivityRecord r) { 8798 return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT; 8799 } 8800 8801 public static long getInputDispatchingTimeoutLocked(ProcessRecord r) { 8802 if (r != null && (r.instrumentationClass != null || r.usingWrapper)) { 8803 return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT; 8804 } 8805 return KEY_DISPATCHING_TIMEOUT; 8806 } 8807 8808 @Override 8809 public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) { 8810 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS) 8811 != PackageManager.PERMISSION_GRANTED) { 8812 throw new SecurityException("Requires permission " 8813 + android.Manifest.permission.FILTER_EVENTS); 8814 } 8815 ProcessRecord proc; 8816 long timeout; 8817 synchronized (this) { 8818 synchronized (mPidsSelfLocked) { 8819 proc = mPidsSelfLocked.get(pid); 8820 } 8821 timeout = getInputDispatchingTimeoutLocked(proc); 8822 } 8823 8824 if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) { 8825 return -1; 8826 } 8827 8828 return timeout; 8829 } 8830 8831 /** 8832 * Handle input dispatching timeouts. 8833 * Returns whether input dispatching should be aborted or not. 8834 */ 8835 public boolean inputDispatchingTimedOut(final ProcessRecord proc, 8836 final ActivityRecord activity, final ActivityRecord parent, 8837 final boolean aboveSystem, String reason) { 8838 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS) 8839 != PackageManager.PERMISSION_GRANTED) { 8840 throw new SecurityException("Requires permission " 8841 + android.Manifest.permission.FILTER_EVENTS); 8842 } 8843 8844 final String annotation; 8845 if (reason == null) { 8846 annotation = "Input dispatching timed out"; 8847 } else { 8848 annotation = "Input dispatching timed out (" + reason + ")"; 8849 } 8850 8851 if (proc != null) { 8852 synchronized (this) { 8853 if (proc.debugging) { 8854 return false; 8855 } 8856 8857 if (mDidDexOpt) { 8858 // Give more time since we were dexopting. 8859 mDidDexOpt = false; 8860 return false; 8861 } 8862 8863 if (proc.instrumentationClass != null) { 8864 Bundle info = new Bundle(); 8865 info.putString("shortMsg", "keyDispatchingTimedOut"); 8866 info.putString("longMsg", annotation); 8867 finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info); 8868 return true; 8869 } 8870 } 8871 mHandler.post(new Runnable() { 8872 @Override 8873 public void run() { 8874 appNotResponding(proc, activity, parent, aboveSystem, annotation); 8875 } 8876 }); 8877 } 8878 8879 return true; 8880 } 8881 8882 public Bundle getAssistContextExtras(int requestType) { 8883 enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO, 8884 "getAssistContextExtras()"); 8885 PendingAssistExtras pae; 8886 Bundle extras = new Bundle(); 8887 synchronized (this) { 8888 ActivityRecord activity = getFocusedStack().mResumedActivity; 8889 if (activity == null) { 8890 Slog.w(TAG, "getAssistContextExtras failed: no resumed activity"); 8891 return null; 8892 } 8893 extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName); 8894 if (activity.app == null || activity.app.thread == null) { 8895 Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity); 8896 return extras; 8897 } 8898 if (activity.app.pid == Binder.getCallingPid()) { 8899 Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity); 8900 return extras; 8901 } 8902 pae = new PendingAssistExtras(activity); 8903 try { 8904 activity.app.thread.requestAssistContextExtras(activity.appToken, pae, 8905 requestType); 8906 mPendingAssistExtras.add(pae); 8907 mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT); 8908 } catch (RemoteException e) { 8909 Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity); 8910 return extras; 8911 } 8912 } 8913 synchronized (pae) { 8914 while (!pae.haveResult) { 8915 try { 8916 pae.wait(); 8917 } catch (InterruptedException e) { 8918 } 8919 } 8920 if (pae.result != null) { 8921 extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result); 8922 } 8923 } 8924 synchronized (this) { 8925 mPendingAssistExtras.remove(pae); 8926 mHandler.removeCallbacks(pae); 8927 } 8928 return extras; 8929 } 8930 8931 public void reportAssistContextExtras(IBinder token, Bundle extras) { 8932 PendingAssistExtras pae = (PendingAssistExtras)token; 8933 synchronized (pae) { 8934 pae.result = extras; 8935 pae.haveResult = true; 8936 pae.notifyAll(); 8937 } 8938 } 8939 8940 public void registerProcessObserver(IProcessObserver observer) { 8941 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 8942 "registerProcessObserver()"); 8943 synchronized (this) { 8944 mProcessObservers.register(observer); 8945 } 8946 } 8947 8948 @Override 8949 public void unregisterProcessObserver(IProcessObserver observer) { 8950 synchronized (this) { 8951 mProcessObservers.unregister(observer); 8952 } 8953 } 8954 8955 @Override 8956 public boolean convertFromTranslucent(IBinder token) { 8957 final long origId = Binder.clearCallingIdentity(); 8958 try { 8959 synchronized (this) { 8960 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 8961 if (r == null) { 8962 return false; 8963 } 8964 if (r.changeWindowTranslucency(true)) { 8965 mWindowManager.setAppFullscreen(token, true); 8966 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 8967 return true; 8968 } 8969 return false; 8970 } 8971 } finally { 8972 Binder.restoreCallingIdentity(origId); 8973 } 8974 } 8975 8976 @Override 8977 public boolean convertToTranslucent(IBinder token) { 8978 final long origId = Binder.clearCallingIdentity(); 8979 try { 8980 synchronized (this) { 8981 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 8982 if (r == null) { 8983 return false; 8984 } 8985 if (r.changeWindowTranslucency(false)) { 8986 r.task.stack.convertToTranslucent(r); 8987 mWindowManager.setAppFullscreen(token, false); 8988 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 8989 return true; 8990 } 8991 return false; 8992 } 8993 } finally { 8994 Binder.restoreCallingIdentity(origId); 8995 } 8996 } 8997 8998 @Override 8999 public void setImmersive(IBinder token, boolean immersive) { 9000 synchronized(this) { 9001 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 9002 if (r == null) { 9003 throw new IllegalArgumentException(); 9004 } 9005 r.immersive = immersive; 9006 9007 // update associated state if we're frontmost 9008 if (r == mFocusedActivity) { 9009 if (DEBUG_IMMERSIVE) { 9010 Slog.d(TAG, "Frontmost changed immersion: "+ r); 9011 } 9012 applyUpdateLockStateLocked(r); 9013 } 9014 } 9015 } 9016 9017 @Override 9018 public boolean isImmersive(IBinder token) { 9019 synchronized (this) { 9020 ActivityRecord r = ActivityRecord.isInStackLocked(token); 9021 if (r == null) { 9022 throw new IllegalArgumentException(); 9023 } 9024 return r.immersive; 9025 } 9026 } 9027 9028 public boolean isTopActivityImmersive() { 9029 enforceNotIsolatedCaller("startActivity"); 9030 synchronized (this) { 9031 ActivityRecord r = getFocusedStack().topRunningActivityLocked(null); 9032 return (r != null) ? r.immersive : false; 9033 } 9034 } 9035 9036 public final void enterSafeMode() { 9037 synchronized(this) { 9038 // It only makes sense to do this before the system is ready 9039 // and started launching other packages. 9040 if (!mSystemReady) { 9041 try { 9042 AppGlobals.getPackageManager().enterSafeMode(); 9043 } catch (RemoteException e) { 9044 } 9045 } 9046 9047 mSafeMode = true; 9048 } 9049 } 9050 9051 public final void showSafeModeOverlay() { 9052 View v = LayoutInflater.from(mContext).inflate( 9053 com.android.internal.R.layout.safe_mode, null); 9054 WindowManager.LayoutParams lp = new WindowManager.LayoutParams(); 9055 lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY; 9056 lp.width = WindowManager.LayoutParams.WRAP_CONTENT; 9057 lp.height = WindowManager.LayoutParams.WRAP_CONTENT; 9058 lp.gravity = Gravity.BOTTOM | Gravity.START; 9059 lp.format = v.getBackground().getOpacity(); 9060 lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE 9061 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE; 9062 lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS; 9063 ((WindowManager)mContext.getSystemService( 9064 Context.WINDOW_SERVICE)).addView(v, lp); 9065 } 9066 9067 public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) { 9068 if (!(sender instanceof PendingIntentRecord)) { 9069 return; 9070 } 9071 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 9072 synchronized (stats) { 9073 if (mBatteryStatsService.isOnBattery()) { 9074 mBatteryStatsService.enforceCallingPermission(); 9075 PendingIntentRecord rec = (PendingIntentRecord)sender; 9076 int MY_UID = Binder.getCallingUid(); 9077 int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid; 9078 BatteryStatsImpl.Uid.Pkg pkg = 9079 stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid, 9080 sourcePkg != null ? sourcePkg : rec.key.packageName); 9081 pkg.incWakeupsLocked(); 9082 } 9083 } 9084 } 9085 9086 public boolean killPids(int[] pids, String pReason, boolean secure) { 9087 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 9088 throw new SecurityException("killPids only available to the system"); 9089 } 9090 String reason = (pReason == null) ? "Unknown" : pReason; 9091 // XXX Note: don't acquire main activity lock here, because the window 9092 // manager calls in with its locks held. 9093 9094 boolean killed = false; 9095 synchronized (mPidsSelfLocked) { 9096 int[] types = new int[pids.length]; 9097 int worstType = 0; 9098 for (int i=0; i<pids.length; i++) { 9099 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 9100 if (proc != null) { 9101 int type = proc.setAdj; 9102 types[i] = type; 9103 if (type > worstType) { 9104 worstType = type; 9105 } 9106 } 9107 } 9108 9109 // If the worst oom_adj is somewhere in the cached proc LRU range, 9110 // then constrain it so we will kill all cached procs. 9111 if (worstType < ProcessList.CACHED_APP_MAX_ADJ 9112 && worstType > ProcessList.CACHED_APP_MIN_ADJ) { 9113 worstType = ProcessList.CACHED_APP_MIN_ADJ; 9114 } 9115 9116 // If this is not a secure call, don't let it kill processes that 9117 // are important. 9118 if (!secure && worstType < ProcessList.SERVICE_ADJ) { 9119 worstType = ProcessList.SERVICE_ADJ; 9120 } 9121 9122 Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType); 9123 for (int i=0; i<pids.length; i++) { 9124 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 9125 if (proc == null) { 9126 continue; 9127 } 9128 int adj = proc.setAdj; 9129 if (adj >= worstType && !proc.killedByAm) { 9130 killUnneededProcessLocked(proc, reason); 9131 killed = true; 9132 } 9133 } 9134 } 9135 return killed; 9136 } 9137 9138 @Override 9139 public void killUid(int uid, String reason) { 9140 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 9141 throw new SecurityException("killUid only available to the system"); 9142 } 9143 synchronized (this) { 9144 killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid), 9145 ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false, 9146 reason != null ? reason : "kill uid"); 9147 } 9148 } 9149 9150 @Override 9151 public boolean killProcessesBelowForeground(String reason) { 9152 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 9153 throw new SecurityException("killProcessesBelowForeground() only available to system"); 9154 } 9155 9156 return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason); 9157 } 9158 9159 private boolean killProcessesBelowAdj(int belowAdj, String reason) { 9160 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 9161 throw new SecurityException("killProcessesBelowAdj() only available to system"); 9162 } 9163 9164 boolean killed = false; 9165 synchronized (mPidsSelfLocked) { 9166 final int size = mPidsSelfLocked.size(); 9167 for (int i = 0; i < size; i++) { 9168 final int pid = mPidsSelfLocked.keyAt(i); 9169 final ProcessRecord proc = mPidsSelfLocked.valueAt(i); 9170 if (proc == null) continue; 9171 9172 final int adj = proc.setAdj; 9173 if (adj > belowAdj && !proc.killedByAm) { 9174 killUnneededProcessLocked(proc, reason); 9175 killed = true; 9176 } 9177 } 9178 } 9179 return killed; 9180 } 9181 9182 @Override 9183 public void hang(final IBinder who, boolean allowRestart) { 9184 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 9185 != PackageManager.PERMISSION_GRANTED) { 9186 throw new SecurityException("Requires permission " 9187 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 9188 } 9189 9190 final IBinder.DeathRecipient death = new DeathRecipient() { 9191 @Override 9192 public void binderDied() { 9193 synchronized (this) { 9194 notifyAll(); 9195 } 9196 } 9197 }; 9198 9199 try { 9200 who.linkToDeath(death, 0); 9201 } catch (RemoteException e) { 9202 Slog.w(TAG, "hang: given caller IBinder is already dead."); 9203 return; 9204 } 9205 9206 synchronized (this) { 9207 Watchdog.getInstance().setAllowRestart(allowRestart); 9208 Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid()); 9209 synchronized (death) { 9210 while (who.isBinderAlive()) { 9211 try { 9212 death.wait(); 9213 } catch (InterruptedException e) { 9214 } 9215 } 9216 } 9217 Watchdog.getInstance().setAllowRestart(true); 9218 } 9219 } 9220 9221 @Override 9222 public void restart() { 9223 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 9224 != PackageManager.PERMISSION_GRANTED) { 9225 throw new SecurityException("Requires permission " 9226 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 9227 } 9228 9229 Log.i(TAG, "Sending shutdown broadcast..."); 9230 9231 BroadcastReceiver br = new BroadcastReceiver() { 9232 @Override public void onReceive(Context context, Intent intent) { 9233 // Now the broadcast is done, finish up the low-level shutdown. 9234 Log.i(TAG, "Shutting down activity manager..."); 9235 shutdown(10000); 9236 Log.i(TAG, "Shutdown complete, restarting!"); 9237 Process.killProcess(Process.myPid()); 9238 System.exit(10); 9239 } 9240 }; 9241 9242 // First send the high-level shut down broadcast. 9243 Intent intent = new Intent(Intent.ACTION_SHUTDOWN); 9244 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 9245 intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true); 9246 /* For now we are not doing a clean shutdown, because things seem to get unhappy. 9247 mContext.sendOrderedBroadcastAsUser(intent, 9248 UserHandle.ALL, null, br, mHandler, 0, null, null); 9249 */ 9250 br.onReceive(mContext, intent); 9251 } 9252 9253 private long getLowRamTimeSinceIdle(long now) { 9254 return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0); 9255 } 9256 9257 @Override 9258 public void performIdleMaintenance() { 9259 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 9260 != PackageManager.PERMISSION_GRANTED) { 9261 throw new SecurityException("Requires permission " 9262 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 9263 } 9264 9265 synchronized (this) { 9266 final long now = SystemClock.uptimeMillis(); 9267 final long timeSinceLastIdle = now - mLastIdleTime; 9268 final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now); 9269 mLastIdleTime = now; 9270 mLowRamTimeSinceLastIdle = 0; 9271 if (mLowRamStartTime != 0) { 9272 mLowRamStartTime = now; 9273 } 9274 9275 StringBuilder sb = new StringBuilder(128); 9276 sb.append("Idle maintenance over "); 9277 TimeUtils.formatDuration(timeSinceLastIdle, sb); 9278 sb.append(" low RAM for "); 9279 TimeUtils.formatDuration(lowRamSinceLastIdle, sb); 9280 Slog.i(TAG, sb.toString()); 9281 9282 // If at least 1/3 of our time since the last idle period has been spent 9283 // with RAM low, then we want to kill processes. 9284 boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3); 9285 9286 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 9287 ProcessRecord proc = mLruProcesses.get(i); 9288 if (proc.notCachedSinceIdle) { 9289 if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP 9290 && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) { 9291 if (doKilling && proc.initialIdlePss != 0 9292 && proc.lastPss > ((proc.initialIdlePss*3)/2)) { 9293 killUnneededProcessLocked(proc, "idle maint (pss " + proc.lastPss 9294 + " from " + proc.initialIdlePss + ")"); 9295 } 9296 } 9297 } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) { 9298 proc.notCachedSinceIdle = true; 9299 proc.initialIdlePss = 0; 9300 proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true, 9301 mSleeping, now); 9302 } 9303 } 9304 9305 mHandler.removeMessages(REQUEST_ALL_PSS_MSG); 9306 mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000); 9307 } 9308 } 9309 9310 private void retrieveSettings() { 9311 final ContentResolver resolver = mContext.getContentResolver(); 9312 String debugApp = Settings.Global.getString( 9313 resolver, Settings.Global.DEBUG_APP); 9314 boolean waitForDebugger = Settings.Global.getInt( 9315 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0; 9316 boolean alwaysFinishActivities = Settings.Global.getInt( 9317 resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0; 9318 boolean forceRtl = Settings.Global.getInt( 9319 resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0; 9320 // Transfer any global setting for forcing RTL layout, into a System Property 9321 SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0"); 9322 9323 Configuration configuration = new Configuration(); 9324 Settings.System.getConfiguration(resolver, configuration); 9325 if (forceRtl) { 9326 // This will take care of setting the correct layout direction flags 9327 configuration.setLayoutDirection(configuration.locale); 9328 } 9329 9330 synchronized (this) { 9331 mDebugApp = mOrigDebugApp = debugApp; 9332 mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger; 9333 mAlwaysFinishActivities = alwaysFinishActivities; 9334 // This happens before any activities are started, so we can 9335 // change mConfiguration in-place. 9336 updateConfigurationLocked(configuration, null, false, true); 9337 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration); 9338 } 9339 } 9340 9341 public boolean testIsSystemReady() { 9342 // no need to synchronize(this) just to read & return the value 9343 return mSystemReady; 9344 } 9345 9346 private static File getCalledPreBootReceiversFile() { 9347 File dataDir = Environment.getDataDirectory(); 9348 File systemDir = new File(dataDir, "system"); 9349 File fname = new File(systemDir, "called_pre_boots.dat"); 9350 return fname; 9351 } 9352 9353 static final int LAST_DONE_VERSION = 10000; 9354 9355 private static ArrayList<ComponentName> readLastDonePreBootReceivers() { 9356 ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>(); 9357 File file = getCalledPreBootReceiversFile(); 9358 FileInputStream fis = null; 9359 try { 9360 fis = new FileInputStream(file); 9361 DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048)); 9362 int fvers = dis.readInt(); 9363 if (fvers == LAST_DONE_VERSION) { 9364 String vers = dis.readUTF(); 9365 String codename = dis.readUTF(); 9366 String build = dis.readUTF(); 9367 if (android.os.Build.VERSION.RELEASE.equals(vers) 9368 && android.os.Build.VERSION.CODENAME.equals(codename) 9369 && android.os.Build.VERSION.INCREMENTAL.equals(build)) { 9370 int num = dis.readInt(); 9371 while (num > 0) { 9372 num--; 9373 String pkg = dis.readUTF(); 9374 String cls = dis.readUTF(); 9375 lastDoneReceivers.add(new ComponentName(pkg, cls)); 9376 } 9377 } 9378 } 9379 } catch (FileNotFoundException e) { 9380 } catch (IOException e) { 9381 Slog.w(TAG, "Failure reading last done pre-boot receivers", e); 9382 } finally { 9383 if (fis != null) { 9384 try { 9385 fis.close(); 9386 } catch (IOException e) { 9387 } 9388 } 9389 } 9390 return lastDoneReceivers; 9391 } 9392 9393 private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) { 9394 File file = getCalledPreBootReceiversFile(); 9395 FileOutputStream fos = null; 9396 DataOutputStream dos = null; 9397 try { 9398 Slog.i(TAG, "Writing new set of last done pre-boot receivers..."); 9399 fos = new FileOutputStream(file); 9400 dos = new DataOutputStream(new BufferedOutputStream(fos, 2048)); 9401 dos.writeInt(LAST_DONE_VERSION); 9402 dos.writeUTF(android.os.Build.VERSION.RELEASE); 9403 dos.writeUTF(android.os.Build.VERSION.CODENAME); 9404 dos.writeUTF(android.os.Build.VERSION.INCREMENTAL); 9405 dos.writeInt(list.size()); 9406 for (int i=0; i<list.size(); i++) { 9407 dos.writeUTF(list.get(i).getPackageName()); 9408 dos.writeUTF(list.get(i).getClassName()); 9409 } 9410 } catch (IOException e) { 9411 Slog.w(TAG, "Failure writing last done pre-boot receivers", e); 9412 file.delete(); 9413 } finally { 9414 FileUtils.sync(fos); 9415 if (dos != null) { 9416 try { 9417 dos.close(); 9418 } catch (IOException e) { 9419 // TODO Auto-generated catch block 9420 e.printStackTrace(); 9421 } 9422 } 9423 } 9424 } 9425 9426 public void systemReady(final Runnable goingCallback) { 9427 synchronized(this) { 9428 if (mSystemReady) { 9429 if (goingCallback != null) goingCallback.run(); 9430 return; 9431 } 9432 9433 // Check to see if there are any update receivers to run. 9434 if (!mDidUpdate) { 9435 if (mWaitingUpdate) { 9436 return; 9437 } 9438 Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED); 9439 List<ResolveInfo> ris = null; 9440 try { 9441 ris = AppGlobals.getPackageManager().queryIntentReceivers( 9442 intent, null, 0, 0); 9443 } catch (RemoteException e) { 9444 } 9445 if (ris != null) { 9446 for (int i=ris.size()-1; i>=0; i--) { 9447 if ((ris.get(i).activityInfo.applicationInfo.flags 9448 &ApplicationInfo.FLAG_SYSTEM) == 0) { 9449 ris.remove(i); 9450 } 9451 } 9452 intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE); 9453 9454 ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers(); 9455 9456 final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>(); 9457 for (int i=0; i<ris.size(); i++) { 9458 ActivityInfo ai = ris.get(i).activityInfo; 9459 ComponentName comp = new ComponentName(ai.packageName, ai.name); 9460 if (lastDoneReceivers.contains(comp)) { 9461 // We already did the pre boot receiver for this app with the current 9462 // platform version, so don't do it again... 9463 ris.remove(i); 9464 i--; 9465 // ...however, do keep it as one that has been done, so we don't 9466 // forget about it when rewriting the file of last done receivers. 9467 doneReceivers.add(comp); 9468 } 9469 } 9470 9471 final int[] users = getUsersLocked(); 9472 for (int i=0; i<ris.size(); i++) { 9473 ActivityInfo ai = ris.get(i).activityInfo; 9474 ComponentName comp = new ComponentName(ai.packageName, ai.name); 9475 doneReceivers.add(comp); 9476 intent.setComponent(comp); 9477 for (int j=0; j<users.length; j++) { 9478 IIntentReceiver finisher = null; 9479 if (i == ris.size()-1 && j == users.length-1) { 9480 finisher = new IIntentReceiver.Stub() { 9481 public void performReceive(Intent intent, int resultCode, 9482 String data, Bundle extras, boolean ordered, 9483 boolean sticky, int sendingUser) { 9484 // The raw IIntentReceiver interface is called 9485 // with the AM lock held, so redispatch to 9486 // execute our code without the lock. 9487 mHandler.post(new Runnable() { 9488 public void run() { 9489 synchronized (ActivityManagerService.this) { 9490 mDidUpdate = true; 9491 } 9492 writeLastDonePreBootReceivers(doneReceivers); 9493 showBootMessage(mContext.getText( 9494 R.string.android_upgrading_complete), 9495 false); 9496 systemReady(goingCallback); 9497 } 9498 }); 9499 } 9500 }; 9501 } 9502 Slog.i(TAG, "Sending system update to " + intent.getComponent() 9503 + " for user " + users[j]); 9504 broadcastIntentLocked(null, null, intent, null, finisher, 9505 0, null, null, null, AppOpsManager.OP_NONE, 9506 true, false, MY_PID, Process.SYSTEM_UID, 9507 users[j]); 9508 if (finisher != null) { 9509 mWaitingUpdate = true; 9510 } 9511 } 9512 } 9513 } 9514 if (mWaitingUpdate) { 9515 return; 9516 } 9517 mDidUpdate = true; 9518 } 9519 9520 mAppOpsService.systemReady(); 9521 mSystemReady = true; 9522 } 9523 9524 ArrayList<ProcessRecord> procsToKill = null; 9525 synchronized(mPidsSelfLocked) { 9526 for (int i=mPidsSelfLocked.size()-1; i>=0; i--) { 9527 ProcessRecord proc = mPidsSelfLocked.valueAt(i); 9528 if (!isAllowedWhileBooting(proc.info)){ 9529 if (procsToKill == null) { 9530 procsToKill = new ArrayList<ProcessRecord>(); 9531 } 9532 procsToKill.add(proc); 9533 } 9534 } 9535 } 9536 9537 synchronized(this) { 9538 if (procsToKill != null) { 9539 for (int i=procsToKill.size()-1; i>=0; i--) { 9540 ProcessRecord proc = procsToKill.get(i); 9541 Slog.i(TAG, "Removing system update proc: " + proc); 9542 removeProcessLocked(proc, true, false, "system update done"); 9543 } 9544 } 9545 9546 // Now that we have cleaned up any update processes, we 9547 // are ready to start launching real processes and know that 9548 // we won't trample on them any more. 9549 mProcessesReady = true; 9550 } 9551 9552 Slog.i(TAG, "System now ready"); 9553 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY, 9554 SystemClock.uptimeMillis()); 9555 9556 synchronized(this) { 9557 // Make sure we have no pre-ready processes sitting around. 9558 9559 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) { 9560 ResolveInfo ri = mContext.getPackageManager() 9561 .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST), 9562 STOCK_PM_FLAGS); 9563 CharSequence errorMsg = null; 9564 if (ri != null) { 9565 ActivityInfo ai = ri.activityInfo; 9566 ApplicationInfo app = ai.applicationInfo; 9567 if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) { 9568 mTopAction = Intent.ACTION_FACTORY_TEST; 9569 mTopData = null; 9570 mTopComponent = new ComponentName(app.packageName, 9571 ai.name); 9572 } else { 9573 errorMsg = mContext.getResources().getText( 9574 com.android.internal.R.string.factorytest_not_system); 9575 } 9576 } else { 9577 errorMsg = mContext.getResources().getText( 9578 com.android.internal.R.string.factorytest_no_action); 9579 } 9580 if (errorMsg != null) { 9581 mTopAction = null; 9582 mTopData = null; 9583 mTopComponent = null; 9584 Message msg = Message.obtain(); 9585 msg.what = SHOW_FACTORY_ERROR_MSG; 9586 msg.getData().putCharSequence("msg", errorMsg); 9587 mHandler.sendMessage(msg); 9588 } 9589 } 9590 } 9591 9592 retrieveSettings(); 9593 9594 synchronized (this) { 9595 readGrantedUriPermissionsLocked(); 9596 } 9597 9598 if (goingCallback != null) goingCallback.run(); 9599 9600 synchronized (this) { 9601 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 9602 try { 9603 List apps = AppGlobals.getPackageManager(). 9604 getPersistentApplications(STOCK_PM_FLAGS); 9605 if (apps != null) { 9606 int N = apps.size(); 9607 int i; 9608 for (i=0; i<N; i++) { 9609 ApplicationInfo info 9610 = (ApplicationInfo)apps.get(i); 9611 if (info != null && 9612 !info.packageName.equals("android")) { 9613 addAppLocked(info, false); 9614 } 9615 } 9616 } 9617 } catch (RemoteException ex) { 9618 // pm is in same process, this will never happen. 9619 } 9620 } 9621 9622 // Start up initial activity. 9623 mBooting = true; 9624 9625 try { 9626 if (AppGlobals.getPackageManager().hasSystemUidErrors()) { 9627 Message msg = Message.obtain(); 9628 msg.what = SHOW_UID_ERROR_MSG; 9629 mHandler.sendMessage(msg); 9630 } 9631 } catch (RemoteException e) { 9632 } 9633 9634 long ident = Binder.clearCallingIdentity(); 9635 try { 9636 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 9637 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 9638 | Intent.FLAG_RECEIVER_FOREGROUND); 9639 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); 9640 broadcastIntentLocked(null, null, intent, 9641 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 9642 false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId); 9643 intent = new Intent(Intent.ACTION_USER_STARTING); 9644 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 9645 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); 9646 broadcastIntentLocked(null, null, intent, 9647 null, new IIntentReceiver.Stub() { 9648 @Override 9649 public void performReceive(Intent intent, int resultCode, String data, 9650 Bundle extras, boolean ordered, boolean sticky, int sendingUser) 9651 throws RemoteException { 9652 } 9653 }, 0, null, null, 9654 android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 9655 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 9656 } finally { 9657 Binder.restoreCallingIdentity(ident); 9658 } 9659 mStackSupervisor.resumeTopActivitiesLocked(); 9660 sendUserSwitchBroadcastsLocked(-1, mCurrentUserId); 9661 } 9662 } 9663 9664 private boolean makeAppCrashingLocked(ProcessRecord app, 9665 String shortMsg, String longMsg, String stackTrace) { 9666 app.crashing = true; 9667 app.crashingReport = generateProcessError(app, 9668 ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace); 9669 startAppProblemLocked(app); 9670 app.stopFreezingAllLocked(); 9671 return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace); 9672 } 9673 9674 private void makeAppNotRespondingLocked(ProcessRecord app, 9675 String activity, String shortMsg, String longMsg) { 9676 app.notResponding = true; 9677 app.notRespondingReport = generateProcessError(app, 9678 ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING, 9679 activity, shortMsg, longMsg, null); 9680 startAppProblemLocked(app); 9681 app.stopFreezingAllLocked(); 9682 } 9683 9684 /** 9685 * Generate a process error record, suitable for attachment to a ProcessRecord. 9686 * 9687 * @param app The ProcessRecord in which the error occurred. 9688 * @param condition Crashing, Application Not Responding, etc. Values are defined in 9689 * ActivityManager.AppErrorStateInfo 9690 * @param activity The activity associated with the crash, if known. 9691 * @param shortMsg Short message describing the crash. 9692 * @param longMsg Long message describing the crash. 9693 * @param stackTrace Full crash stack trace, may be null. 9694 * 9695 * @return Returns a fully-formed AppErrorStateInfo record. 9696 */ 9697 private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app, 9698 int condition, String activity, String shortMsg, String longMsg, String stackTrace) { 9699 ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo(); 9700 9701 report.condition = condition; 9702 report.processName = app.processName; 9703 report.pid = app.pid; 9704 report.uid = app.info.uid; 9705 report.tag = activity; 9706 report.shortMsg = shortMsg; 9707 report.longMsg = longMsg; 9708 report.stackTrace = stackTrace; 9709 9710 return report; 9711 } 9712 9713 void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) { 9714 synchronized (this) { 9715 app.crashing = false; 9716 app.crashingReport = null; 9717 app.notResponding = false; 9718 app.notRespondingReport = null; 9719 if (app.anrDialog == fromDialog) { 9720 app.anrDialog = null; 9721 } 9722 if (app.waitDialog == fromDialog) { 9723 app.waitDialog = null; 9724 } 9725 if (app.pid > 0 && app.pid != MY_PID) { 9726 handleAppCrashLocked(app, null, null, null); 9727 killUnneededProcessLocked(app, "user request after error"); 9728 } 9729 } 9730 } 9731 9732 private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg, 9733 String stackTrace) { 9734 long now = SystemClock.uptimeMillis(); 9735 9736 Long crashTime; 9737 if (!app.isolated) { 9738 crashTime = mProcessCrashTimes.get(app.info.processName, app.uid); 9739 } else { 9740 crashTime = null; 9741 } 9742 if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) { 9743 // This process loses! 9744 Slog.w(TAG, "Process " + app.info.processName 9745 + " has crashed too many times: killing!"); 9746 EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH, 9747 app.userId, app.info.processName, app.uid); 9748 mStackSupervisor.handleAppCrashLocked(app); 9749 if (!app.persistent) { 9750 // We don't want to start this process again until the user 9751 // explicitly does so... but for persistent process, we really 9752 // need to keep it running. If a persistent process is actually 9753 // repeatedly crashing, then badness for everyone. 9754 EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid, 9755 app.info.processName); 9756 if (!app.isolated) { 9757 // XXX We don't have a way to mark isolated processes 9758 // as bad, since they don't have a peristent identity. 9759 mBadProcesses.put(app.info.processName, app.uid, 9760 new BadProcessInfo(now, shortMsg, longMsg, stackTrace)); 9761 mProcessCrashTimes.remove(app.info.processName, app.uid); 9762 } 9763 app.bad = true; 9764 app.removed = true; 9765 // Don't let services in this process be restarted and potentially 9766 // annoy the user repeatedly. Unless it is persistent, since those 9767 // processes run critical code. 9768 removeProcessLocked(app, false, false, "crash"); 9769 mStackSupervisor.resumeTopActivitiesLocked(); 9770 return false; 9771 } 9772 mStackSupervisor.resumeTopActivitiesLocked(); 9773 } else { 9774 mStackSupervisor.finishTopRunningActivityLocked(app); 9775 } 9776 9777 // Bump up the crash count of any services currently running in the proc. 9778 for (int i=app.services.size()-1; i>=0; i--) { 9779 // Any services running in the application need to be placed 9780 // back in the pending list. 9781 ServiceRecord sr = app.services.valueAt(i); 9782 sr.crashCount++; 9783 } 9784 9785 // If the crashing process is what we consider to be the "home process" and it has been 9786 // replaced by a third-party app, clear the package preferred activities from packages 9787 // with a home activity running in the process to prevent a repeatedly crashing app 9788 // from blocking the user to manually clear the list. 9789 final ArrayList<ActivityRecord> activities = app.activities; 9790 if (app == mHomeProcess && activities.size() > 0 9791 && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) { 9792 for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) { 9793 final ActivityRecord r = activities.get(activityNdx); 9794 if (r.isHomeActivity()) { 9795 Log.i(TAG, "Clearing package preferred activities from " + r.packageName); 9796 try { 9797 ActivityThread.getPackageManager() 9798 .clearPackagePreferredActivities(r.packageName); 9799 } catch (RemoteException c) { 9800 // pm is in same process, this will never happen. 9801 } 9802 } 9803 } 9804 } 9805 9806 if (!app.isolated) { 9807 // XXX Can't keep track of crash times for isolated processes, 9808 // because they don't have a perisistent identity. 9809 mProcessCrashTimes.put(app.info.processName, app.uid, now); 9810 } 9811 9812 return true; 9813 } 9814 9815 void startAppProblemLocked(ProcessRecord app) { 9816 if (app.userId == mCurrentUserId) { 9817 app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver( 9818 mContext, app.info.packageName, app.info.flags); 9819 } else { 9820 // If this app is not running under the current user, then we 9821 // can't give it a report button because that would require 9822 // launching the report UI under a different user. 9823 app.errorReportReceiver = null; 9824 } 9825 skipCurrentReceiverLocked(app); 9826 } 9827 9828 void skipCurrentReceiverLocked(ProcessRecord app) { 9829 for (BroadcastQueue queue : mBroadcastQueues) { 9830 queue.skipCurrentReceiverLocked(app); 9831 } 9832 } 9833 9834 /** 9835 * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes. 9836 * The application process will exit immediately after this call returns. 9837 * @param app object of the crashing app, null for the system server 9838 * @param crashInfo describing the exception 9839 */ 9840 public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) { 9841 ProcessRecord r = findAppProcess(app, "Crash"); 9842 final String processName = app == null ? "system_server" 9843 : (r == null ? "unknown" : r.processName); 9844 9845 handleApplicationCrashInner("crash", r, processName, crashInfo); 9846 } 9847 9848 /* Native crash reporting uses this inner version because it needs to be somewhat 9849 * decoupled from the AM-managed cleanup lifecycle 9850 */ 9851 void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName, 9852 ApplicationErrorReport.CrashInfo crashInfo) { 9853 EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(), 9854 UserHandle.getUserId(Binder.getCallingUid()), processName, 9855 r == null ? -1 : r.info.flags, 9856 crashInfo.exceptionClassName, 9857 crashInfo.exceptionMessage, 9858 crashInfo.throwFileName, 9859 crashInfo.throwLineNumber); 9860 9861 addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo); 9862 9863 crashApplication(r, crashInfo); 9864 } 9865 9866 public void handleApplicationStrictModeViolation( 9867 IBinder app, 9868 int violationMask, 9869 StrictMode.ViolationInfo info) { 9870 ProcessRecord r = findAppProcess(app, "StrictMode"); 9871 if (r == null) { 9872 return; 9873 } 9874 9875 if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) { 9876 Integer stackFingerprint = info.hashCode(); 9877 boolean logIt = true; 9878 synchronized (mAlreadyLoggedViolatedStacks) { 9879 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) { 9880 logIt = false; 9881 // TODO: sub-sample into EventLog for these, with 9882 // the info.durationMillis? Then we'd get 9883 // the relative pain numbers, without logging all 9884 // the stack traces repeatedly. We'd want to do 9885 // likewise in the client code, which also does 9886 // dup suppression, before the Binder call. 9887 } else { 9888 if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) { 9889 mAlreadyLoggedViolatedStacks.clear(); 9890 } 9891 mAlreadyLoggedViolatedStacks.add(stackFingerprint); 9892 } 9893 } 9894 if (logIt) { 9895 logStrictModeViolationToDropBox(r, info); 9896 } 9897 } 9898 9899 if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) { 9900 AppErrorResult result = new AppErrorResult(); 9901 synchronized (this) { 9902 final long origId = Binder.clearCallingIdentity(); 9903 9904 Message msg = Message.obtain(); 9905 msg.what = SHOW_STRICT_MODE_VIOLATION_MSG; 9906 HashMap<String, Object> data = new HashMap<String, Object>(); 9907 data.put("result", result); 9908 data.put("app", r); 9909 data.put("violationMask", violationMask); 9910 data.put("info", info); 9911 msg.obj = data; 9912 mHandler.sendMessage(msg); 9913 9914 Binder.restoreCallingIdentity(origId); 9915 } 9916 int res = result.get(); 9917 Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res); 9918 } 9919 } 9920 9921 // Depending on the policy in effect, there could be a bunch of 9922 // these in quick succession so we try to batch these together to 9923 // minimize disk writes, number of dropbox entries, and maximize 9924 // compression, by having more fewer, larger records. 9925 private void logStrictModeViolationToDropBox( 9926 ProcessRecord process, 9927 StrictMode.ViolationInfo info) { 9928 if (info == null) { 9929 return; 9930 } 9931 final boolean isSystemApp = process == null || 9932 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM | 9933 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0; 9934 final String processName = process == null ? "unknown" : process.processName; 9935 final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode"; 9936 final DropBoxManager dbox = (DropBoxManager) 9937 mContext.getSystemService(Context.DROPBOX_SERVICE); 9938 9939 // Exit early if the dropbox isn't configured to accept this report type. 9940 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 9941 9942 boolean bufferWasEmpty; 9943 boolean needsFlush; 9944 final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024); 9945 synchronized (sb) { 9946 bufferWasEmpty = sb.length() == 0; 9947 appendDropBoxProcessHeaders(process, processName, sb); 9948 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 9949 sb.append("System-App: ").append(isSystemApp).append("\n"); 9950 sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n"); 9951 if (info.violationNumThisLoop != 0) { 9952 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n"); 9953 } 9954 if (info.numAnimationsRunning != 0) { 9955 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n"); 9956 } 9957 if (info.broadcastIntentAction != null) { 9958 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n"); 9959 } 9960 if (info.durationMillis != -1) { 9961 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n"); 9962 } 9963 if (info.numInstances != -1) { 9964 sb.append("Instance-Count: ").append(info.numInstances).append("\n"); 9965 } 9966 if (info.tags != null) { 9967 for (String tag : info.tags) { 9968 sb.append("Span-Tag: ").append(tag).append("\n"); 9969 } 9970 } 9971 sb.append("\n"); 9972 if (info.crashInfo != null && info.crashInfo.stackTrace != null) { 9973 sb.append(info.crashInfo.stackTrace); 9974 } 9975 sb.append("\n"); 9976 9977 // Only buffer up to ~64k. Various logging bits truncate 9978 // things at 128k. 9979 needsFlush = (sb.length() > 64 * 1024); 9980 } 9981 9982 // Flush immediately if the buffer's grown too large, or this 9983 // is a non-system app. Non-system apps are isolated with a 9984 // different tag & policy and not batched. 9985 // 9986 // Batching is useful during internal testing with 9987 // StrictMode settings turned up high. Without batching, 9988 // thousands of separate files could be created on boot. 9989 if (!isSystemApp || needsFlush) { 9990 new Thread("Error dump: " + dropboxTag) { 9991 @Override 9992 public void run() { 9993 String report; 9994 synchronized (sb) { 9995 report = sb.toString(); 9996 sb.delete(0, sb.length()); 9997 sb.trimToSize(); 9998 } 9999 if (report.length() != 0) { 10000 dbox.addText(dropboxTag, report); 10001 } 10002 } 10003 }.start(); 10004 return; 10005 } 10006 10007 // System app batching: 10008 if (!bufferWasEmpty) { 10009 // An existing dropbox-writing thread is outstanding, so 10010 // we don't need to start it up. The existing thread will 10011 // catch the buffer appends we just did. 10012 return; 10013 } 10014 10015 // Worker thread to both batch writes and to avoid blocking the caller on I/O. 10016 // (After this point, we shouldn't access AMS internal data structures.) 10017 new Thread("Error dump: " + dropboxTag) { 10018 @Override 10019 public void run() { 10020 // 5 second sleep to let stacks arrive and be batched together 10021 try { 10022 Thread.sleep(5000); // 5 seconds 10023 } catch (InterruptedException e) {} 10024 10025 String errorReport; 10026 synchronized (mStrictModeBuffer) { 10027 errorReport = mStrictModeBuffer.toString(); 10028 if (errorReport.length() == 0) { 10029 return; 10030 } 10031 mStrictModeBuffer.delete(0, mStrictModeBuffer.length()); 10032 mStrictModeBuffer.trimToSize(); 10033 } 10034 dbox.addText(dropboxTag, errorReport); 10035 } 10036 }.start(); 10037 } 10038 10039 /** 10040 * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors. 10041 * @param app object of the crashing app, null for the system server 10042 * @param tag reported by the caller 10043 * @param crashInfo describing the context of the error 10044 * @return true if the process should exit immediately (WTF is fatal) 10045 */ 10046 public boolean handleApplicationWtf(IBinder app, String tag, 10047 ApplicationErrorReport.CrashInfo crashInfo) { 10048 ProcessRecord r = findAppProcess(app, "WTF"); 10049 final String processName = app == null ? "system_server" 10050 : (r == null ? "unknown" : r.processName); 10051 10052 EventLog.writeEvent(EventLogTags.AM_WTF, 10053 UserHandle.getUserId(Binder.getCallingUid()), Binder.getCallingPid(), 10054 processName, 10055 r == null ? -1 : r.info.flags, 10056 tag, crashInfo.exceptionMessage); 10057 10058 addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo); 10059 10060 if (r != null && r.pid != Process.myPid() && 10061 Settings.Global.getInt(mContext.getContentResolver(), 10062 Settings.Global.WTF_IS_FATAL, 0) != 0) { 10063 crashApplication(r, crashInfo); 10064 return true; 10065 } else { 10066 return false; 10067 } 10068 } 10069 10070 /** 10071 * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit}) 10072 * @return the corresponding {@link ProcessRecord} object, or null if none could be found 10073 */ 10074 private ProcessRecord findAppProcess(IBinder app, String reason) { 10075 if (app == null) { 10076 return null; 10077 } 10078 10079 synchronized (this) { 10080 final int NP = mProcessNames.getMap().size(); 10081 for (int ip=0; ip<NP; ip++) { 10082 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 10083 final int NA = apps.size(); 10084 for (int ia=0; ia<NA; ia++) { 10085 ProcessRecord p = apps.valueAt(ia); 10086 if (p.thread != null && p.thread.asBinder() == app) { 10087 return p; 10088 } 10089 } 10090 } 10091 10092 Slog.w(TAG, "Can't find mystery application for " + reason 10093 + " from pid=" + Binder.getCallingPid() 10094 + " uid=" + Binder.getCallingUid() + ": " + app); 10095 return null; 10096 } 10097 } 10098 10099 /** 10100 * Utility function for addErrorToDropBox and handleStrictModeViolation's logging 10101 * to append various headers to the dropbox log text. 10102 */ 10103 private void appendDropBoxProcessHeaders(ProcessRecord process, String processName, 10104 StringBuilder sb) { 10105 // Watchdog thread ends up invoking this function (with 10106 // a null ProcessRecord) to add the stack file to dropbox. 10107 // Do not acquire a lock on this (am) in such cases, as it 10108 // could cause a potential deadlock, if and when watchdog 10109 // is invoked due to unavailability of lock on am and it 10110 // would prevent watchdog from killing system_server. 10111 if (process == null) { 10112 sb.append("Process: ").append(processName).append("\n"); 10113 return; 10114 } 10115 // Note: ProcessRecord 'process' is guarded by the service 10116 // instance. (notably process.pkgList, which could otherwise change 10117 // concurrently during execution of this method) 10118 synchronized (this) { 10119 sb.append("Process: ").append(processName).append("\n"); 10120 int flags = process.info.flags; 10121 IPackageManager pm = AppGlobals.getPackageManager(); 10122 sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n"); 10123 for (int ip=0; ip<process.pkgList.size(); ip++) { 10124 String pkg = process.pkgList.keyAt(ip); 10125 sb.append("Package: ").append(pkg); 10126 try { 10127 PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId()); 10128 if (pi != null) { 10129 sb.append(" v").append(pi.versionCode); 10130 if (pi.versionName != null) { 10131 sb.append(" (").append(pi.versionName).append(")"); 10132 } 10133 } 10134 } catch (RemoteException e) { 10135 Slog.e(TAG, "Error getting package info: " + pkg, e); 10136 } 10137 sb.append("\n"); 10138 } 10139 } 10140 } 10141 10142 private static String processClass(ProcessRecord process) { 10143 if (process == null || process.pid == MY_PID) { 10144 return "system_server"; 10145 } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) { 10146 return "system_app"; 10147 } else { 10148 return "data_app"; 10149 } 10150 } 10151 10152 /** 10153 * Write a description of an error (crash, WTF, ANR) to the drop box. 10154 * @param eventType to include in the drop box tag ("crash", "wtf", etc.) 10155 * @param process which caused the error, null means the system server 10156 * @param activity which triggered the error, null if unknown 10157 * @param parent activity related to the error, null if unknown 10158 * @param subject line related to the error, null if absent 10159 * @param report in long form describing the error, null if absent 10160 * @param logFile to include in the report, null if none 10161 * @param crashInfo giving an application stack trace, null if absent 10162 */ 10163 public void addErrorToDropBox(String eventType, 10164 ProcessRecord process, String processName, ActivityRecord activity, 10165 ActivityRecord parent, String subject, 10166 final String report, final File logFile, 10167 final ApplicationErrorReport.CrashInfo crashInfo) { 10168 // NOTE -- this must never acquire the ActivityManagerService lock, 10169 // otherwise the watchdog may be prevented from resetting the system. 10170 10171 final String dropboxTag = processClass(process) + "_" + eventType; 10172 final DropBoxManager dbox = (DropBoxManager) 10173 mContext.getSystemService(Context.DROPBOX_SERVICE); 10174 10175 // Exit early if the dropbox isn't configured to accept this report type. 10176 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 10177 10178 final StringBuilder sb = new StringBuilder(1024); 10179 appendDropBoxProcessHeaders(process, processName, sb); 10180 if (activity != null) { 10181 sb.append("Activity: ").append(activity.shortComponentName).append("\n"); 10182 } 10183 if (parent != null && parent.app != null && parent.app.pid != process.pid) { 10184 sb.append("Parent-Process: ").append(parent.app.processName).append("\n"); 10185 } 10186 if (parent != null && parent != activity) { 10187 sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n"); 10188 } 10189 if (subject != null) { 10190 sb.append("Subject: ").append(subject).append("\n"); 10191 } 10192 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 10193 if (Debug.isDebuggerConnected()) { 10194 sb.append("Debugger: Connected\n"); 10195 } 10196 sb.append("\n"); 10197 10198 // Do the rest in a worker thread to avoid blocking the caller on I/O 10199 // (After this point, we shouldn't access AMS internal data structures.) 10200 Thread worker = new Thread("Error dump: " + dropboxTag) { 10201 @Override 10202 public void run() { 10203 if (report != null) { 10204 sb.append(report); 10205 } 10206 if (logFile != null) { 10207 try { 10208 sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE, 10209 "\n\n[[TRUNCATED]]")); 10210 } catch (IOException e) { 10211 Slog.e(TAG, "Error reading " + logFile, e); 10212 } 10213 } 10214 if (crashInfo != null && crashInfo.stackTrace != null) { 10215 sb.append(crashInfo.stackTrace); 10216 } 10217 10218 String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag; 10219 int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0); 10220 if (lines > 0) { 10221 sb.append("\n"); 10222 10223 // Merge several logcat streams, and take the last N lines 10224 InputStreamReader input = null; 10225 try { 10226 java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat", 10227 "-v", "time", "-b", "events", "-b", "system", "-b", "main", 10228 "-t", String.valueOf(lines)).redirectErrorStream(true).start(); 10229 10230 try { logcat.getOutputStream().close(); } catch (IOException e) {} 10231 try { logcat.getErrorStream().close(); } catch (IOException e) {} 10232 input = new InputStreamReader(logcat.getInputStream()); 10233 10234 int num; 10235 char[] buf = new char[8192]; 10236 while ((num = input.read(buf)) > 0) sb.append(buf, 0, num); 10237 } catch (IOException e) { 10238 Slog.e(TAG, "Error running logcat", e); 10239 } finally { 10240 if (input != null) try { input.close(); } catch (IOException e) {} 10241 } 10242 } 10243 10244 dbox.addText(dropboxTag, sb.toString()); 10245 } 10246 }; 10247 10248 if (process == null) { 10249 // If process is null, we are being called from some internal code 10250 // and may be about to die -- run this synchronously. 10251 worker.run(); 10252 } else { 10253 worker.start(); 10254 } 10255 } 10256 10257 /** 10258 * Bring up the "unexpected error" dialog box for a crashing app. 10259 * Deal with edge cases (intercepts from instrumented applications, 10260 * ActivityController, error intent receivers, that sort of thing). 10261 * @param r the application crashing 10262 * @param crashInfo describing the failure 10263 */ 10264 private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) { 10265 long timeMillis = System.currentTimeMillis(); 10266 String shortMsg = crashInfo.exceptionClassName; 10267 String longMsg = crashInfo.exceptionMessage; 10268 String stackTrace = crashInfo.stackTrace; 10269 if (shortMsg != null && longMsg != null) { 10270 longMsg = shortMsg + ": " + longMsg; 10271 } else if (shortMsg != null) { 10272 longMsg = shortMsg; 10273 } 10274 10275 AppErrorResult result = new AppErrorResult(); 10276 synchronized (this) { 10277 if (mController != null) { 10278 try { 10279 String name = r != null ? r.processName : null; 10280 int pid = r != null ? r.pid : Binder.getCallingPid(); 10281 if (!mController.appCrashed(name, pid, 10282 shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) { 10283 Slog.w(TAG, "Force-killing crashed app " + name 10284 + " at watcher's request"); 10285 Process.killProcess(pid); 10286 return; 10287 } 10288 } catch (RemoteException e) { 10289 mController = null; 10290 Watchdog.getInstance().setActivityController(null); 10291 } 10292 } 10293 10294 final long origId = Binder.clearCallingIdentity(); 10295 10296 // If this process is running instrumentation, finish it. 10297 if (r != null && r.instrumentationClass != null) { 10298 Slog.w(TAG, "Error in app " + r.processName 10299 + " running instrumentation " + r.instrumentationClass + ":"); 10300 if (shortMsg != null) Slog.w(TAG, " " + shortMsg); 10301 if (longMsg != null) Slog.w(TAG, " " + longMsg); 10302 Bundle info = new Bundle(); 10303 info.putString("shortMsg", shortMsg); 10304 info.putString("longMsg", longMsg); 10305 finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info); 10306 Binder.restoreCallingIdentity(origId); 10307 return; 10308 } 10309 10310 // If we can't identify the process or it's already exceeded its crash quota, 10311 // quit right away without showing a crash dialog. 10312 if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) { 10313 Binder.restoreCallingIdentity(origId); 10314 return; 10315 } 10316 10317 Message msg = Message.obtain(); 10318 msg.what = SHOW_ERROR_MSG; 10319 HashMap data = new HashMap(); 10320 data.put("result", result); 10321 data.put("app", r); 10322 msg.obj = data; 10323 mHandler.sendMessage(msg); 10324 10325 Binder.restoreCallingIdentity(origId); 10326 } 10327 10328 int res = result.get(); 10329 10330 Intent appErrorIntent = null; 10331 synchronized (this) { 10332 if (r != null && !r.isolated) { 10333 // XXX Can't keep track of crash time for isolated processes, 10334 // since they don't have a persistent identity. 10335 mProcessCrashTimes.put(r.info.processName, r.uid, 10336 SystemClock.uptimeMillis()); 10337 } 10338 if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) { 10339 appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo); 10340 } 10341 } 10342 10343 if (appErrorIntent != null) { 10344 try { 10345 mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId)); 10346 } catch (ActivityNotFoundException e) { 10347 Slog.w(TAG, "bug report receiver dissappeared", e); 10348 } 10349 } 10350 } 10351 10352 Intent createAppErrorIntentLocked(ProcessRecord r, 10353 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 10354 ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo); 10355 if (report == null) { 10356 return null; 10357 } 10358 Intent result = new Intent(Intent.ACTION_APP_ERROR); 10359 result.setComponent(r.errorReportReceiver); 10360 result.putExtra(Intent.EXTRA_BUG_REPORT, report); 10361 result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 10362 return result; 10363 } 10364 10365 private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r, 10366 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 10367 if (r.errorReportReceiver == null) { 10368 return null; 10369 } 10370 10371 if (!r.crashing && !r.notResponding && !r.forceCrashReport) { 10372 return null; 10373 } 10374 10375 ApplicationErrorReport report = new ApplicationErrorReport(); 10376 report.packageName = r.info.packageName; 10377 report.installerPackageName = r.errorReportReceiver.getPackageName(); 10378 report.processName = r.processName; 10379 report.time = timeMillis; 10380 report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0; 10381 10382 if (r.crashing || r.forceCrashReport) { 10383 report.type = ApplicationErrorReport.TYPE_CRASH; 10384 report.crashInfo = crashInfo; 10385 } else if (r.notResponding) { 10386 report.type = ApplicationErrorReport.TYPE_ANR; 10387 report.anrInfo = new ApplicationErrorReport.AnrInfo(); 10388 10389 report.anrInfo.activity = r.notRespondingReport.tag; 10390 report.anrInfo.cause = r.notRespondingReport.shortMsg; 10391 report.anrInfo.info = r.notRespondingReport.longMsg; 10392 } 10393 10394 return report; 10395 } 10396 10397 public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() { 10398 enforceNotIsolatedCaller("getProcessesInErrorState"); 10399 // assume our apps are happy - lazy create the list 10400 List<ActivityManager.ProcessErrorStateInfo> errList = null; 10401 10402 final boolean allUsers = ActivityManager.checkUidPermission( 10403 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 10404 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 10405 int userId = UserHandle.getUserId(Binder.getCallingUid()); 10406 10407 synchronized (this) { 10408 10409 // iterate across all processes 10410 for (int i=mLruProcesses.size()-1; i>=0; i--) { 10411 ProcessRecord app = mLruProcesses.get(i); 10412 if (!allUsers && app.userId != userId) { 10413 continue; 10414 } 10415 if ((app.thread != null) && (app.crashing || app.notResponding)) { 10416 // This one's in trouble, so we'll generate a report for it 10417 // crashes are higher priority (in case there's a crash *and* an anr) 10418 ActivityManager.ProcessErrorStateInfo report = null; 10419 if (app.crashing) { 10420 report = app.crashingReport; 10421 } else if (app.notResponding) { 10422 report = app.notRespondingReport; 10423 } 10424 10425 if (report != null) { 10426 if (errList == null) { 10427 errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1); 10428 } 10429 errList.add(report); 10430 } else { 10431 Slog.w(TAG, "Missing app error report, app = " + app.processName + 10432 " crashing = " + app.crashing + 10433 " notResponding = " + app.notResponding); 10434 } 10435 } 10436 } 10437 } 10438 10439 return errList; 10440 } 10441 10442 static int oomAdjToImportance(int adj, ActivityManager.RunningAppProcessInfo currApp) { 10443 if (adj >= ProcessList.CACHED_APP_MIN_ADJ) { 10444 if (currApp != null) { 10445 currApp.lru = adj - ProcessList.CACHED_APP_MIN_ADJ + 1; 10446 } 10447 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 10448 } else if (adj >= ProcessList.SERVICE_B_ADJ) { 10449 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 10450 } else if (adj >= ProcessList.HOME_APP_ADJ) { 10451 if (currApp != null) { 10452 currApp.lru = 0; 10453 } 10454 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 10455 } else if (adj >= ProcessList.SERVICE_ADJ) { 10456 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 10457 } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 10458 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE; 10459 } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) { 10460 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE; 10461 } else if (adj >= ProcessList.VISIBLE_APP_ADJ) { 10462 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE; 10463 } else { 10464 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND; 10465 } 10466 } 10467 10468 private void fillInProcMemInfo(ProcessRecord app, 10469 ActivityManager.RunningAppProcessInfo outInfo) { 10470 outInfo.pid = app.pid; 10471 outInfo.uid = app.info.uid; 10472 if (mHeavyWeightProcess == app) { 10473 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE; 10474 } 10475 if (app.persistent) { 10476 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT; 10477 } 10478 if (app.activities.size() > 0) { 10479 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES; 10480 } 10481 outInfo.lastTrimLevel = app.trimMemoryLevel; 10482 int adj = app.curAdj; 10483 outInfo.importance = oomAdjToImportance(adj, outInfo); 10484 outInfo.importanceReasonCode = app.adjTypeCode; 10485 } 10486 10487 public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() { 10488 enforceNotIsolatedCaller("getRunningAppProcesses"); 10489 // Lazy instantiation of list 10490 List<ActivityManager.RunningAppProcessInfo> runList = null; 10491 final boolean allUsers = ActivityManager.checkUidPermission( 10492 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 10493 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 10494 int userId = UserHandle.getUserId(Binder.getCallingUid()); 10495 synchronized (this) { 10496 // Iterate across all processes 10497 for (int i=mLruProcesses.size()-1; i>=0; i--) { 10498 ProcessRecord app = mLruProcesses.get(i); 10499 if (!allUsers && app.userId != userId) { 10500 continue; 10501 } 10502 if ((app.thread != null) && (!app.crashing && !app.notResponding)) { 10503 // Generate process state info for running application 10504 ActivityManager.RunningAppProcessInfo currApp = 10505 new ActivityManager.RunningAppProcessInfo(app.processName, 10506 app.pid, app.getPackageList()); 10507 fillInProcMemInfo(app, currApp); 10508 if (app.adjSource instanceof ProcessRecord) { 10509 currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid; 10510 currApp.importanceReasonImportance = oomAdjToImportance( 10511 app.adjSourceOom, null); 10512 } else if (app.adjSource instanceof ActivityRecord) { 10513 ActivityRecord r = (ActivityRecord)app.adjSource; 10514 if (r.app != null) currApp.importanceReasonPid = r.app.pid; 10515 } 10516 if (app.adjTarget instanceof ComponentName) { 10517 currApp.importanceReasonComponent = (ComponentName)app.adjTarget; 10518 } 10519 //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance 10520 // + " lru=" + currApp.lru); 10521 if (runList == null) { 10522 runList = new ArrayList<ActivityManager.RunningAppProcessInfo>(); 10523 } 10524 runList.add(currApp); 10525 } 10526 } 10527 } 10528 return runList; 10529 } 10530 10531 public List<ApplicationInfo> getRunningExternalApplications() { 10532 enforceNotIsolatedCaller("getRunningExternalApplications"); 10533 List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses(); 10534 List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>(); 10535 if (runningApps != null && runningApps.size() > 0) { 10536 Set<String> extList = new HashSet<String>(); 10537 for (ActivityManager.RunningAppProcessInfo app : runningApps) { 10538 if (app.pkgList != null) { 10539 for (String pkg : app.pkgList) { 10540 extList.add(pkg); 10541 } 10542 } 10543 } 10544 IPackageManager pm = AppGlobals.getPackageManager(); 10545 for (String pkg : extList) { 10546 try { 10547 ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId()); 10548 if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) { 10549 retList.add(info); 10550 } 10551 } catch (RemoteException e) { 10552 } 10553 } 10554 } 10555 return retList; 10556 } 10557 10558 @Override 10559 public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) { 10560 enforceNotIsolatedCaller("getMyMemoryState"); 10561 synchronized (this) { 10562 ProcessRecord proc; 10563 synchronized (mPidsSelfLocked) { 10564 proc = mPidsSelfLocked.get(Binder.getCallingPid()); 10565 } 10566 fillInProcMemInfo(proc, outInfo); 10567 } 10568 } 10569 10570 @Override 10571 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 10572 if (checkCallingPermission(android.Manifest.permission.DUMP) 10573 != PackageManager.PERMISSION_GRANTED) { 10574 pw.println("Permission Denial: can't dump ActivityManager from from pid=" 10575 + Binder.getCallingPid() 10576 + ", uid=" + Binder.getCallingUid() 10577 + " without permission " 10578 + android.Manifest.permission.DUMP); 10579 return; 10580 } 10581 10582 boolean dumpAll = false; 10583 boolean dumpClient = false; 10584 String dumpPackage = null; 10585 10586 int opti = 0; 10587 while (opti < args.length) { 10588 String opt = args[opti]; 10589 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 10590 break; 10591 } 10592 opti++; 10593 if ("-a".equals(opt)) { 10594 dumpAll = true; 10595 } else if ("-c".equals(opt)) { 10596 dumpClient = true; 10597 } else if ("-h".equals(opt)) { 10598 pw.println("Activity manager dump options:"); 10599 pw.println(" [-a] [-c] [-h] [cmd] ..."); 10600 pw.println(" cmd may be one of:"); 10601 pw.println(" a[ctivities]: activity stack state"); 10602 pw.println(" b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state"); 10603 pw.println(" i[ntents] [PACKAGE_NAME]: pending intent state"); 10604 pw.println(" p[rocesses] [PACKAGE_NAME]: process state"); 10605 pw.println(" o[om]: out of memory management"); 10606 pw.println(" prov[iders] [COMP_SPEC ...]: content provider state"); 10607 pw.println(" provider [COMP_SPEC]: provider client-side state"); 10608 pw.println(" s[ervices] [COMP_SPEC ...]: service state"); 10609 pw.println(" service [COMP_SPEC]: service client-side state"); 10610 pw.println(" package [PACKAGE_NAME]: all state related to given package"); 10611 pw.println(" all: dump all activities"); 10612 pw.println(" top: dump the top activity"); 10613 pw.println(" cmd may also be a COMP_SPEC to dump activities."); 10614 pw.println(" COMP_SPEC may be a component name (com.foo/.myApp),"); 10615 pw.println(" a partial substring in a component name, a"); 10616 pw.println(" hex object identifier."); 10617 pw.println(" -a: include all available server state."); 10618 pw.println(" -c: include client state."); 10619 return; 10620 } else { 10621 pw.println("Unknown argument: " + opt + "; use -h for help"); 10622 } 10623 } 10624 10625 long origId = Binder.clearCallingIdentity(); 10626 boolean more = false; 10627 // Is the caller requesting to dump a particular piece of data? 10628 if (opti < args.length) { 10629 String cmd = args[opti]; 10630 opti++; 10631 if ("activities".equals(cmd) || "a".equals(cmd)) { 10632 synchronized (this) { 10633 dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null); 10634 } 10635 } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) { 10636 String[] newArgs; 10637 String name; 10638 if (opti >= args.length) { 10639 name = null; 10640 newArgs = EMPTY_STRING_ARRAY; 10641 } else { 10642 name = args[opti]; 10643 opti++; 10644 newArgs = new String[args.length - opti]; 10645 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 10646 args.length - opti); 10647 } 10648 synchronized (this) { 10649 dumpBroadcastsLocked(fd, pw, args, opti, true, name); 10650 } 10651 } else if ("intents".equals(cmd) || "i".equals(cmd)) { 10652 String[] newArgs; 10653 String name; 10654 if (opti >= args.length) { 10655 name = null; 10656 newArgs = EMPTY_STRING_ARRAY; 10657 } else { 10658 name = args[opti]; 10659 opti++; 10660 newArgs = new String[args.length - opti]; 10661 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 10662 args.length - opti); 10663 } 10664 synchronized (this) { 10665 dumpPendingIntentsLocked(fd, pw, args, opti, true, name); 10666 } 10667 } else if ("processes".equals(cmd) || "p".equals(cmd)) { 10668 String[] newArgs; 10669 String name; 10670 if (opti >= args.length) { 10671 name = null; 10672 newArgs = EMPTY_STRING_ARRAY; 10673 } else { 10674 name = args[opti]; 10675 opti++; 10676 newArgs = new String[args.length - opti]; 10677 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 10678 args.length - opti); 10679 } 10680 synchronized (this) { 10681 dumpProcessesLocked(fd, pw, args, opti, true, name); 10682 } 10683 } else if ("oom".equals(cmd) || "o".equals(cmd)) { 10684 synchronized (this) { 10685 dumpOomLocked(fd, pw, args, opti, true); 10686 } 10687 } else if ("provider".equals(cmd)) { 10688 String[] newArgs; 10689 String name; 10690 if (opti >= args.length) { 10691 name = null; 10692 newArgs = EMPTY_STRING_ARRAY; 10693 } else { 10694 name = args[opti]; 10695 opti++; 10696 newArgs = new String[args.length - opti]; 10697 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti); 10698 } 10699 if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) { 10700 pw.println("No providers match: " + name); 10701 pw.println("Use -h for help."); 10702 } 10703 } else if ("providers".equals(cmd) || "prov".equals(cmd)) { 10704 synchronized (this) { 10705 dumpProvidersLocked(fd, pw, args, opti, true, null); 10706 } 10707 } else if ("service".equals(cmd)) { 10708 String[] newArgs; 10709 String name; 10710 if (opti >= args.length) { 10711 name = null; 10712 newArgs = EMPTY_STRING_ARRAY; 10713 } else { 10714 name = args[opti]; 10715 opti++; 10716 newArgs = new String[args.length - opti]; 10717 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 10718 args.length - opti); 10719 } 10720 if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) { 10721 pw.println("No services match: " + name); 10722 pw.println("Use -h for help."); 10723 } 10724 } else if ("package".equals(cmd)) { 10725 String[] newArgs; 10726 if (opti >= args.length) { 10727 pw.println("package: no package name specified"); 10728 pw.println("Use -h for help."); 10729 } else { 10730 dumpPackage = args[opti]; 10731 opti++; 10732 newArgs = new String[args.length - opti]; 10733 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 10734 args.length - opti); 10735 args = newArgs; 10736 opti = 0; 10737 more = true; 10738 } 10739 } else if ("services".equals(cmd) || "s".equals(cmd)) { 10740 synchronized (this) { 10741 mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null); 10742 } 10743 } else { 10744 // Dumping a single activity? 10745 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) { 10746 pw.println("Bad activity command, or no activities match: " + cmd); 10747 pw.println("Use -h for help."); 10748 } 10749 } 10750 if (!more) { 10751 Binder.restoreCallingIdentity(origId); 10752 return; 10753 } 10754 } 10755 10756 // No piece of data specified, dump everything. 10757 synchronized (this) { 10758 dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 10759 pw.println(); 10760 if (dumpAll) { 10761 pw.println("-------------------------------------------------------------------------------"); 10762 } 10763 dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 10764 pw.println(); 10765 if (dumpAll) { 10766 pw.println("-------------------------------------------------------------------------------"); 10767 } 10768 dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage); 10769 pw.println(); 10770 if (dumpAll) { 10771 pw.println("-------------------------------------------------------------------------------"); 10772 } 10773 mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 10774 pw.println(); 10775 if (dumpAll) { 10776 pw.println("-------------------------------------------------------------------------------"); 10777 } 10778 dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 10779 pw.println(); 10780 if (dumpAll) { 10781 pw.println("-------------------------------------------------------------------------------"); 10782 } 10783 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage); 10784 } 10785 Binder.restoreCallingIdentity(origId); 10786 } 10787 10788 void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 10789 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) { 10790 pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)"); 10791 10792 boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient, 10793 dumpPackage); 10794 boolean needSep = printedAnything; 10795 10796 boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity, 10797 dumpPackage, needSep, " mFocusedActivity: "); 10798 if (printed) { 10799 printedAnything = true; 10800 needSep = false; 10801 } 10802 10803 if (dumpPackage == null) { 10804 if (needSep) { 10805 pw.println(); 10806 } 10807 needSep = true; 10808 printedAnything = true; 10809 mStackSupervisor.dump(pw, " "); 10810 } 10811 10812 if (mRecentTasks.size() > 0) { 10813 boolean printedHeader = false; 10814 10815 final int N = mRecentTasks.size(); 10816 for (int i=0; i<N; i++) { 10817 TaskRecord tr = mRecentTasks.get(i); 10818 if (dumpPackage != null) { 10819 if (tr.realActivity == null || 10820 !dumpPackage.equals(tr.realActivity)) { 10821 continue; 10822 } 10823 } 10824 if (!printedHeader) { 10825 if (needSep) { 10826 pw.println(); 10827 } 10828 pw.println(" Recent tasks:"); 10829 printedHeader = true; 10830 printedAnything = true; 10831 } 10832 pw.print(" * Recent #"); pw.print(i); pw.print(": "); 10833 pw.println(tr); 10834 if (dumpAll) { 10835 mRecentTasks.get(i).dump(pw, " "); 10836 } 10837 } 10838 } 10839 10840 if (!printedAnything) { 10841 pw.println(" (nothing)"); 10842 } 10843 } 10844 10845 void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 10846 int opti, boolean dumpAll, String dumpPackage) { 10847 boolean needSep = false; 10848 boolean printedAnything = false; 10849 int numPers = 0; 10850 10851 pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)"); 10852 10853 if (dumpAll) { 10854 final int NP = mProcessNames.getMap().size(); 10855 for (int ip=0; ip<NP; ip++) { 10856 SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip); 10857 final int NA = procs.size(); 10858 for (int ia=0; ia<NA; ia++) { 10859 ProcessRecord r = procs.valueAt(ia); 10860 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 10861 continue; 10862 } 10863 if (!needSep) { 10864 pw.println(" All known processes:"); 10865 needSep = true; 10866 printedAnything = true; 10867 } 10868 pw.print(r.persistent ? " *PERS*" : " *APP*"); 10869 pw.print(" UID "); pw.print(procs.keyAt(ia)); 10870 pw.print(" "); pw.println(r); 10871 r.dump(pw, " "); 10872 if (r.persistent) { 10873 numPers++; 10874 } 10875 } 10876 } 10877 } 10878 10879 if (mIsolatedProcesses.size() > 0) { 10880 boolean printed = false; 10881 for (int i=0; i<mIsolatedProcesses.size(); i++) { 10882 ProcessRecord r = mIsolatedProcesses.valueAt(i); 10883 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 10884 continue; 10885 } 10886 if (!printed) { 10887 if (needSep) { 10888 pw.println(); 10889 } 10890 pw.println(" Isolated process list (sorted by uid):"); 10891 printedAnything = true; 10892 printed = true; 10893 needSep = true; 10894 } 10895 pw.println(String.format("%sIsolated #%2d: %s", 10896 " ", i, r.toString())); 10897 } 10898 } 10899 10900 if (mLruProcesses.size() > 0) { 10901 if (needSep) { 10902 pw.println(); 10903 } 10904 pw.print(" Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size()); 10905 pw.print(" total, non-act at "); 10906 pw.print(mLruProcesses.size()-mLruProcessActivityStart); 10907 pw.print(", non-svc at "); 10908 pw.print(mLruProcesses.size()-mLruProcessServiceStart); 10909 pw.println("):"); 10910 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", false, dumpPackage); 10911 needSep = true; 10912 printedAnything = true; 10913 } 10914 10915 if (dumpAll || dumpPackage != null) { 10916 synchronized (mPidsSelfLocked) { 10917 boolean printed = false; 10918 for (int i=0; i<mPidsSelfLocked.size(); i++) { 10919 ProcessRecord r = mPidsSelfLocked.valueAt(i); 10920 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 10921 continue; 10922 } 10923 if (!printed) { 10924 if (needSep) pw.println(); 10925 needSep = true; 10926 pw.println(" PID mappings:"); 10927 printed = true; 10928 printedAnything = true; 10929 } 10930 pw.print(" PID #"); pw.print(mPidsSelfLocked.keyAt(i)); 10931 pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i)); 10932 } 10933 } 10934 } 10935 10936 if (mForegroundProcesses.size() > 0) { 10937 synchronized (mPidsSelfLocked) { 10938 boolean printed = false; 10939 for (int i=0; i<mForegroundProcesses.size(); i++) { 10940 ProcessRecord r = mPidsSelfLocked.get( 10941 mForegroundProcesses.valueAt(i).pid); 10942 if (dumpPackage != null && (r == null 10943 || !r.pkgList.containsKey(dumpPackage))) { 10944 continue; 10945 } 10946 if (!printed) { 10947 if (needSep) pw.println(); 10948 needSep = true; 10949 pw.println(" Foreground Processes:"); 10950 printed = true; 10951 printedAnything = true; 10952 } 10953 pw.print(" PID #"); pw.print(mForegroundProcesses.keyAt(i)); 10954 pw.print(": "); pw.println(mForegroundProcesses.valueAt(i)); 10955 } 10956 } 10957 } 10958 10959 if (mPersistentStartingProcesses.size() > 0) { 10960 if (needSep) pw.println(); 10961 needSep = true; 10962 printedAnything = true; 10963 pw.println(" Persisent processes that are starting:"); 10964 dumpProcessList(pw, this, mPersistentStartingProcesses, " ", 10965 "Starting Norm", "Restarting PERS", dumpPackage); 10966 } 10967 10968 if (mRemovedProcesses.size() > 0) { 10969 if (needSep) pw.println(); 10970 needSep = true; 10971 printedAnything = true; 10972 pw.println(" Processes that are being removed:"); 10973 dumpProcessList(pw, this, mRemovedProcesses, " ", 10974 "Removed Norm", "Removed PERS", dumpPackage); 10975 } 10976 10977 if (mProcessesOnHold.size() > 0) { 10978 if (needSep) pw.println(); 10979 needSep = true; 10980 printedAnything = true; 10981 pw.println(" Processes that are on old until the system is ready:"); 10982 dumpProcessList(pw, this, mProcessesOnHold, " ", 10983 "OnHold Norm", "OnHold PERS", dumpPackage); 10984 } 10985 10986 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage); 10987 10988 if (mProcessCrashTimes.getMap().size() > 0) { 10989 boolean printed = false; 10990 long now = SystemClock.uptimeMillis(); 10991 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap(); 10992 final int NP = pmap.size(); 10993 for (int ip=0; ip<NP; ip++) { 10994 String pname = pmap.keyAt(ip); 10995 SparseArray<Long> uids = pmap.valueAt(ip); 10996 final int N = uids.size(); 10997 for (int i=0; i<N; i++) { 10998 int puid = uids.keyAt(i); 10999 ProcessRecord r = mProcessNames.get(pname, puid); 11000 if (dumpPackage != null && (r == null 11001 || !r.pkgList.containsKey(dumpPackage))) { 11002 continue; 11003 } 11004 if (!printed) { 11005 if (needSep) pw.println(); 11006 needSep = true; 11007 pw.println(" Time since processes crashed:"); 11008 printed = true; 11009 printedAnything = true; 11010 } 11011 pw.print(" Process "); pw.print(pname); 11012 pw.print(" uid "); pw.print(puid); 11013 pw.print(": last crashed "); 11014 TimeUtils.formatDuration(now-uids.valueAt(i), pw); 11015 pw.println(" ago"); 11016 } 11017 } 11018 } 11019 11020 if (mBadProcesses.getMap().size() > 0) { 11021 boolean printed = false; 11022 final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap(); 11023 final int NP = pmap.size(); 11024 for (int ip=0; ip<NP; ip++) { 11025 String pname = pmap.keyAt(ip); 11026 SparseArray<BadProcessInfo> uids = pmap.valueAt(ip); 11027 final int N = uids.size(); 11028 for (int i=0; i<N; i++) { 11029 int puid = uids.keyAt(i); 11030 ProcessRecord r = mProcessNames.get(pname, puid); 11031 if (dumpPackage != null && (r == null 11032 || !r.pkgList.containsKey(dumpPackage))) { 11033 continue; 11034 } 11035 if (!printed) { 11036 if (needSep) pw.println(); 11037 needSep = true; 11038 pw.println(" Bad processes:"); 11039 printedAnything = true; 11040 } 11041 BadProcessInfo info = uids.valueAt(i); 11042 pw.print(" Bad process "); pw.print(pname); 11043 pw.print(" uid "); pw.print(puid); 11044 pw.print(": crashed at time "); pw.println(info.time); 11045 if (info.shortMsg != null) { 11046 pw.print(" Short msg: "); pw.println(info.shortMsg); 11047 } 11048 if (info.longMsg != null) { 11049 pw.print(" Long msg: "); pw.println(info.longMsg); 11050 } 11051 if (info.stack != null) { 11052 pw.println(" Stack:"); 11053 int lastPos = 0; 11054 for (int pos=0; pos<info.stack.length(); pos++) { 11055 if (info.stack.charAt(pos) == '\n') { 11056 pw.print(" "); 11057 pw.write(info.stack, lastPos, pos-lastPos); 11058 pw.println(); 11059 lastPos = pos+1; 11060 } 11061 } 11062 if (lastPos < info.stack.length()) { 11063 pw.print(" "); 11064 pw.write(info.stack, lastPos, info.stack.length()-lastPos); 11065 pw.println(); 11066 } 11067 } 11068 } 11069 } 11070 } 11071 11072 if (dumpPackage == null) { 11073 pw.println(); 11074 needSep = false; 11075 pw.println(" mStartedUsers:"); 11076 for (int i=0; i<mStartedUsers.size(); i++) { 11077 UserStartedState uss = mStartedUsers.valueAt(i); 11078 pw.print(" User #"); pw.print(uss.mHandle.getIdentifier()); 11079 pw.print(": "); uss.dump("", pw); 11080 } 11081 pw.print(" mStartedUserArray: ["); 11082 for (int i=0; i<mStartedUserArray.length; i++) { 11083 if (i > 0) pw.print(", "); 11084 pw.print(mStartedUserArray[i]); 11085 } 11086 pw.println("]"); 11087 pw.print(" mUserLru: ["); 11088 for (int i=0; i<mUserLru.size(); i++) { 11089 if (i > 0) pw.print(", "); 11090 pw.print(mUserLru.get(i)); 11091 } 11092 pw.println("]"); 11093 if (dumpAll) { 11094 pw.print(" mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray)); 11095 } 11096 } 11097 if (mHomeProcess != null && (dumpPackage == null 11098 || mHomeProcess.pkgList.containsKey(dumpPackage))) { 11099 if (needSep) { 11100 pw.println(); 11101 needSep = false; 11102 } 11103 pw.println(" mHomeProcess: " + mHomeProcess); 11104 } 11105 if (mPreviousProcess != null && (dumpPackage == null 11106 || mPreviousProcess.pkgList.containsKey(dumpPackage))) { 11107 if (needSep) { 11108 pw.println(); 11109 needSep = false; 11110 } 11111 pw.println(" mPreviousProcess: " + mPreviousProcess); 11112 } 11113 if (dumpAll) { 11114 StringBuilder sb = new StringBuilder(128); 11115 sb.append(" mPreviousProcessVisibleTime: "); 11116 TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb); 11117 pw.println(sb); 11118 } 11119 if (mHeavyWeightProcess != null && (dumpPackage == null 11120 || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) { 11121 if (needSep) { 11122 pw.println(); 11123 needSep = false; 11124 } 11125 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 11126 } 11127 if (dumpPackage == null) { 11128 pw.println(" mConfiguration: " + mConfiguration); 11129 } 11130 if (dumpAll) { 11131 pw.println(" mConfigWillChange: " + getFocusedStack().mConfigWillChange); 11132 if (mCompatModePackages.getPackages().size() > 0) { 11133 boolean printed = false; 11134 for (Map.Entry<String, Integer> entry 11135 : mCompatModePackages.getPackages().entrySet()) { 11136 String pkg = entry.getKey(); 11137 int mode = entry.getValue(); 11138 if (dumpPackage != null && !dumpPackage.equals(pkg)) { 11139 continue; 11140 } 11141 if (!printed) { 11142 pw.println(" mScreenCompatPackages:"); 11143 printed = true; 11144 } 11145 pw.print(" "); pw.print(pkg); pw.print(": "); 11146 pw.print(mode); pw.println(); 11147 } 11148 } 11149 } 11150 if (dumpPackage == null) { 11151 if (mSleeping || mWentToSleep || mLockScreenShown) { 11152 pw.println(" mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep 11153 + " mLockScreenShown " + mLockScreenShown); 11154 } 11155 if (mShuttingDown) { 11156 pw.println(" mShuttingDown=" + mShuttingDown); 11157 } 11158 } 11159 if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient 11160 || mOrigWaitForDebugger) { 11161 if (dumpPackage == null || dumpPackage.equals(mDebugApp) 11162 || dumpPackage.equals(mOrigDebugApp)) { 11163 if (needSep) { 11164 pw.println(); 11165 needSep = false; 11166 } 11167 pw.println(" mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp 11168 + " mDebugTransient=" + mDebugTransient 11169 + " mOrigWaitForDebugger=" + mOrigWaitForDebugger); 11170 } 11171 } 11172 if (mOpenGlTraceApp != null) { 11173 if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) { 11174 if (needSep) { 11175 pw.println(); 11176 needSep = false; 11177 } 11178 pw.println(" mOpenGlTraceApp=" + mOpenGlTraceApp); 11179 } 11180 } 11181 if (mProfileApp != null || mProfileProc != null || mProfileFile != null 11182 || mProfileFd != null) { 11183 if (dumpPackage == null || dumpPackage.equals(mProfileApp)) { 11184 if (needSep) { 11185 pw.println(); 11186 needSep = false; 11187 } 11188 pw.println(" mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc); 11189 pw.println(" mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd); 11190 pw.println(" mProfileType=" + mProfileType + " mAutoStopProfiler=" 11191 + mAutoStopProfiler); 11192 } 11193 } 11194 if (dumpPackage == null) { 11195 if (mAlwaysFinishActivities || mController != null) { 11196 pw.println(" mAlwaysFinishActivities=" + mAlwaysFinishActivities 11197 + " mController=" + mController); 11198 } 11199 if (dumpAll) { 11200 pw.println(" Total persistent processes: " + numPers); 11201 pw.println(" mProcessesReady=" + mProcessesReady 11202 + " mSystemReady=" + mSystemReady); 11203 pw.println(" mBooting=" + mBooting 11204 + " mBooted=" + mBooted 11205 + " mFactoryTest=" + mFactoryTest); 11206 pw.print(" mLastPowerCheckRealtime="); 11207 TimeUtils.formatDuration(mLastPowerCheckRealtime, pw); 11208 pw.println(""); 11209 pw.print(" mLastPowerCheckUptime="); 11210 TimeUtils.formatDuration(mLastPowerCheckUptime, pw); 11211 pw.println(""); 11212 pw.println(" mGoingToSleep=" + mStackSupervisor.mGoingToSleep); 11213 pw.println(" mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity); 11214 pw.println(" mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq); 11215 pw.println(" mNumNonCachedProcs=" + mNumNonCachedProcs 11216 + " (" + mLruProcesses.size() + " total)" 11217 + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs 11218 + " mNumServiceProcs=" + mNumServiceProcs 11219 + " mNewNumServiceProcs=" + mNewNumServiceProcs); 11220 pw.println(" mAllowLowerMemLevel=" + mAllowLowerMemLevel 11221 + " mLastMemoryLevel" + mLastMemoryLevel 11222 + " mLastNumProcesses" + mLastNumProcesses); 11223 long now = SystemClock.uptimeMillis(); 11224 pw.print(" mLastIdleTime="); 11225 TimeUtils.formatDuration(now, mLastIdleTime, pw); 11226 pw.print(" mLowRamSinceLastIdle="); 11227 TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw); 11228 pw.println(); 11229 } 11230 } 11231 11232 if (!printedAnything) { 11233 pw.println(" (nothing)"); 11234 } 11235 } 11236 11237 boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args, 11238 int opti, boolean needSep, boolean dumpAll, String dumpPackage) { 11239 if (mProcessesToGc.size() > 0) { 11240 boolean printed = false; 11241 long now = SystemClock.uptimeMillis(); 11242 for (int i=0; i<mProcessesToGc.size(); i++) { 11243 ProcessRecord proc = mProcessesToGc.get(i); 11244 if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) { 11245 continue; 11246 } 11247 if (!printed) { 11248 if (needSep) pw.println(); 11249 needSep = true; 11250 pw.println(" Processes that are waiting to GC:"); 11251 printed = true; 11252 } 11253 pw.print(" Process "); pw.println(proc); 11254 pw.print(" lowMem="); pw.print(proc.reportLowMemory); 11255 pw.print(", last gced="); 11256 pw.print(now-proc.lastRequestedGc); 11257 pw.print(" ms ago, last lowMem="); 11258 pw.print(now-proc.lastLowMemory); 11259 pw.println(" ms ago"); 11260 11261 } 11262 } 11263 return needSep; 11264 } 11265 11266 void printOomLevel(PrintWriter pw, String name, int adj) { 11267 pw.print(" "); 11268 if (adj >= 0) { 11269 pw.print(' '); 11270 if (adj < 10) pw.print(' '); 11271 } else { 11272 if (adj > -10) pw.print(' '); 11273 } 11274 pw.print(adj); 11275 pw.print(": "); 11276 pw.print(name); 11277 pw.print(" ("); 11278 pw.print(mProcessList.getMemLevel(adj)/1024); 11279 pw.println(" kB)"); 11280 } 11281 11282 boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args, 11283 int opti, boolean dumpAll) { 11284 boolean needSep = false; 11285 11286 if (mLruProcesses.size() > 0) { 11287 if (needSep) pw.println(); 11288 needSep = true; 11289 pw.println(" OOM levels:"); 11290 printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ); 11291 printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ); 11292 printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ); 11293 printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ); 11294 printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ); 11295 printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ); 11296 printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ); 11297 printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ); 11298 printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ); 11299 printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ); 11300 printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ); 11301 printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ); 11302 printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ); 11303 11304 if (needSep) pw.println(); 11305 pw.print(" Process OOM control ("); pw.print(mLruProcesses.size()); 11306 pw.print(" total, non-act at "); 11307 pw.print(mLruProcesses.size()-mLruProcessActivityStart); 11308 pw.print(", non-svc at "); 11309 pw.print(mLruProcesses.size()-mLruProcessServiceStart); 11310 pw.println("):"); 11311 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", true, null); 11312 needSep = true; 11313 } 11314 11315 dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null); 11316 11317 pw.println(); 11318 pw.println(" mHomeProcess: " + mHomeProcess); 11319 pw.println(" mPreviousProcess: " + mPreviousProcess); 11320 if (mHeavyWeightProcess != null) { 11321 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 11322 } 11323 11324 return true; 11325 } 11326 11327 /** 11328 * There are three ways to call this: 11329 * - no provider specified: dump all the providers 11330 * - a flattened component name that matched an existing provider was specified as the 11331 * first arg: dump that one provider 11332 * - the first arg isn't the flattened component name of an existing provider: 11333 * dump all providers whose component contains the first arg as a substring 11334 */ 11335 protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args, 11336 int opti, boolean dumpAll) { 11337 return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll); 11338 } 11339 11340 static class ItemMatcher { 11341 ArrayList<ComponentName> components; 11342 ArrayList<String> strings; 11343 ArrayList<Integer> objects; 11344 boolean all; 11345 11346 ItemMatcher() { 11347 all = true; 11348 } 11349 11350 void build(String name) { 11351 ComponentName componentName = ComponentName.unflattenFromString(name); 11352 if (componentName != null) { 11353 if (components == null) { 11354 components = new ArrayList<ComponentName>(); 11355 } 11356 components.add(componentName); 11357 all = false; 11358 } else { 11359 int objectId = 0; 11360 // Not a '/' separated full component name; maybe an object ID? 11361 try { 11362 objectId = Integer.parseInt(name, 16); 11363 if (objects == null) { 11364 objects = new ArrayList<Integer>(); 11365 } 11366 objects.add(objectId); 11367 all = false; 11368 } catch (RuntimeException e) { 11369 // Not an integer; just do string match. 11370 if (strings == null) { 11371 strings = new ArrayList<String>(); 11372 } 11373 strings.add(name); 11374 all = false; 11375 } 11376 } 11377 } 11378 11379 int build(String[] args, int opti) { 11380 for (; opti<args.length; opti++) { 11381 String name = args[opti]; 11382 if ("--".equals(name)) { 11383 return opti+1; 11384 } 11385 build(name); 11386 } 11387 return opti; 11388 } 11389 11390 boolean match(Object object, ComponentName comp) { 11391 if (all) { 11392 return true; 11393 } 11394 if (components != null) { 11395 for (int i=0; i<components.size(); i++) { 11396 if (components.get(i).equals(comp)) { 11397 return true; 11398 } 11399 } 11400 } 11401 if (objects != null) { 11402 for (int i=0; i<objects.size(); i++) { 11403 if (System.identityHashCode(object) == objects.get(i)) { 11404 return true; 11405 } 11406 } 11407 } 11408 if (strings != null) { 11409 String flat = comp.flattenToString(); 11410 for (int i=0; i<strings.size(); i++) { 11411 if (flat.contains(strings.get(i))) { 11412 return true; 11413 } 11414 } 11415 } 11416 return false; 11417 } 11418 } 11419 11420 /** 11421 * There are three things that cmd can be: 11422 * - a flattened component name that matches an existing activity 11423 * - the cmd arg isn't the flattened component name of an existing activity: 11424 * dump all activity whose component contains the cmd as a substring 11425 * - A hex number of the ActivityRecord object instance. 11426 */ 11427 protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args, 11428 int opti, boolean dumpAll) { 11429 ArrayList<ActivityRecord> activities; 11430 11431 synchronized (this) { 11432 activities = mStackSupervisor.getDumpActivitiesLocked(name); 11433 } 11434 11435 if (activities.size() <= 0) { 11436 return false; 11437 } 11438 11439 String[] newArgs = new String[args.length - opti]; 11440 System.arraycopy(args, opti, newArgs, 0, args.length - opti); 11441 11442 TaskRecord lastTask = null; 11443 boolean needSep = false; 11444 for (int i=activities.size()-1; i>=0; i--) { 11445 ActivityRecord r = activities.get(i); 11446 if (needSep) { 11447 pw.println(); 11448 } 11449 needSep = true; 11450 synchronized (this) { 11451 if (lastTask != r.task) { 11452 lastTask = r.task; 11453 pw.print("TASK "); pw.print(lastTask.affinity); 11454 pw.print(" id="); pw.println(lastTask.taskId); 11455 if (dumpAll) { 11456 lastTask.dump(pw, " "); 11457 } 11458 } 11459 } 11460 dumpActivity(" ", fd, pw, activities.get(i), newArgs, dumpAll); 11461 } 11462 return true; 11463 } 11464 11465 /** 11466 * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if 11467 * there is a thread associated with the activity. 11468 */ 11469 private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw, 11470 final ActivityRecord r, String[] args, boolean dumpAll) { 11471 String innerPrefix = prefix + " "; 11472 synchronized (this) { 11473 pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName); 11474 pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r))); 11475 pw.print(" pid="); 11476 if (r.app != null) pw.println(r.app.pid); 11477 else pw.println("(not running)"); 11478 if (dumpAll) { 11479 r.dump(pw, innerPrefix); 11480 } 11481 } 11482 if (r.app != null && r.app.thread != null) { 11483 // flush anything that is already in the PrintWriter since the thread is going 11484 // to write to the file descriptor directly 11485 pw.flush(); 11486 try { 11487 TransferPipe tp = new TransferPipe(); 11488 try { 11489 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(), 11490 r.appToken, innerPrefix, args); 11491 tp.go(fd); 11492 } finally { 11493 tp.kill(); 11494 } 11495 } catch (IOException e) { 11496 pw.println(innerPrefix + "Failure while dumping the activity: " + e); 11497 } catch (RemoteException e) { 11498 pw.println(innerPrefix + "Got a RemoteException while dumping the activity"); 11499 } 11500 } 11501 } 11502 11503 void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 11504 int opti, boolean dumpAll, String dumpPackage) { 11505 boolean needSep = false; 11506 boolean onlyHistory = false; 11507 boolean printedAnything = false; 11508 11509 if ("history".equals(dumpPackage)) { 11510 if (opti < args.length && "-s".equals(args[opti])) { 11511 dumpAll = false; 11512 } 11513 onlyHistory = true; 11514 dumpPackage = null; 11515 } 11516 11517 pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)"); 11518 if (!onlyHistory && dumpAll) { 11519 if (mRegisteredReceivers.size() > 0) { 11520 boolean printed = false; 11521 Iterator it = mRegisteredReceivers.values().iterator(); 11522 while (it.hasNext()) { 11523 ReceiverList r = (ReceiverList)it.next(); 11524 if (dumpPackage != null && (r.app == null || 11525 !dumpPackage.equals(r.app.info.packageName))) { 11526 continue; 11527 } 11528 if (!printed) { 11529 pw.println(" Registered Receivers:"); 11530 needSep = true; 11531 printed = true; 11532 printedAnything = true; 11533 } 11534 pw.print(" * "); pw.println(r); 11535 r.dump(pw, " "); 11536 } 11537 } 11538 11539 if (mReceiverResolver.dump(pw, needSep ? 11540 "\n Receiver Resolver Table:" : " Receiver Resolver Table:", 11541 " ", dumpPackage, false)) { 11542 needSep = true; 11543 printedAnything = true; 11544 } 11545 } 11546 11547 for (BroadcastQueue q : mBroadcastQueues) { 11548 needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep); 11549 printedAnything |= needSep; 11550 } 11551 11552 needSep = true; 11553 11554 if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) { 11555 for (int user=0; user<mStickyBroadcasts.size(); user++) { 11556 if (needSep) { 11557 pw.println(); 11558 } 11559 needSep = true; 11560 printedAnything = true; 11561 pw.print(" Sticky broadcasts for user "); 11562 pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":"); 11563 StringBuilder sb = new StringBuilder(128); 11564 for (Map.Entry<String, ArrayList<Intent>> ent 11565 : mStickyBroadcasts.valueAt(user).entrySet()) { 11566 pw.print(" * Sticky action "); pw.print(ent.getKey()); 11567 if (dumpAll) { 11568 pw.println(":"); 11569 ArrayList<Intent> intents = ent.getValue(); 11570 final int N = intents.size(); 11571 for (int i=0; i<N; i++) { 11572 sb.setLength(0); 11573 sb.append(" Intent: "); 11574 intents.get(i).toShortString(sb, false, true, false, false); 11575 pw.println(sb.toString()); 11576 Bundle bundle = intents.get(i).getExtras(); 11577 if (bundle != null) { 11578 pw.print(" "); 11579 pw.println(bundle.toString()); 11580 } 11581 } 11582 } else { 11583 pw.println(""); 11584 } 11585 } 11586 } 11587 } 11588 11589 if (!onlyHistory && dumpAll) { 11590 pw.println(); 11591 for (BroadcastQueue queue : mBroadcastQueues) { 11592 pw.println(" mBroadcastsScheduled [" + queue.mQueueName + "]=" 11593 + queue.mBroadcastsScheduled); 11594 } 11595 pw.println(" mHandler:"); 11596 mHandler.dump(new PrintWriterPrinter(pw), " "); 11597 needSep = true; 11598 printedAnything = true; 11599 } 11600 11601 if (!printedAnything) { 11602 pw.println(" (nothing)"); 11603 } 11604 } 11605 11606 void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args, 11607 int opti, boolean dumpAll, String dumpPackage) { 11608 boolean needSep; 11609 boolean printedAnything = false; 11610 11611 ItemMatcher matcher = new ItemMatcher(); 11612 matcher.build(args, opti); 11613 11614 pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)"); 11615 11616 needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage); 11617 printedAnything |= needSep; 11618 11619 if (mLaunchingProviders.size() > 0) { 11620 boolean printed = false; 11621 for (int i=mLaunchingProviders.size()-1; i>=0; i--) { 11622 ContentProviderRecord r = mLaunchingProviders.get(i); 11623 if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) { 11624 continue; 11625 } 11626 if (!printed) { 11627 if (needSep) pw.println(); 11628 needSep = true; 11629 pw.println(" Launching content providers:"); 11630 printed = true; 11631 printedAnything = true; 11632 } 11633 pw.print(" Launching #"); pw.print(i); pw.print(": "); 11634 pw.println(r); 11635 } 11636 } 11637 11638 if (mGrantedUriPermissions.size() > 0) { 11639 boolean printed = false; 11640 int dumpUid = -2; 11641 if (dumpPackage != null) { 11642 try { 11643 dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0); 11644 } catch (NameNotFoundException e) { 11645 dumpUid = -1; 11646 } 11647 } 11648 for (int i=0; i<mGrantedUriPermissions.size(); i++) { 11649 int uid = mGrantedUriPermissions.keyAt(i); 11650 if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) { 11651 continue; 11652 } 11653 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 11654 if (!printed) { 11655 if (needSep) pw.println(); 11656 needSep = true; 11657 pw.println(" Granted Uri Permissions:"); 11658 printed = true; 11659 printedAnything = true; 11660 } 11661 pw.print(" * UID "); pw.print(uid); pw.println(" holds:"); 11662 for (UriPermission perm : perms.values()) { 11663 pw.print(" "); pw.println(perm); 11664 if (dumpAll) { 11665 perm.dump(pw, " "); 11666 } 11667 } 11668 } 11669 } 11670 11671 if (!printedAnything) { 11672 pw.println(" (nothing)"); 11673 } 11674 } 11675 11676 void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 11677 int opti, boolean dumpAll, String dumpPackage) { 11678 boolean printed = false; 11679 11680 pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)"); 11681 11682 if (mIntentSenderRecords.size() > 0) { 11683 Iterator<WeakReference<PendingIntentRecord>> it 11684 = mIntentSenderRecords.values().iterator(); 11685 while (it.hasNext()) { 11686 WeakReference<PendingIntentRecord> ref = it.next(); 11687 PendingIntentRecord rec = ref != null ? ref.get(): null; 11688 if (dumpPackage != null && (rec == null 11689 || !dumpPackage.equals(rec.key.packageName))) { 11690 continue; 11691 } 11692 printed = true; 11693 if (rec != null) { 11694 pw.print(" * "); pw.println(rec); 11695 if (dumpAll) { 11696 rec.dump(pw, " "); 11697 } 11698 } else { 11699 pw.print(" * "); pw.println(ref); 11700 } 11701 } 11702 } 11703 11704 if (!printed) { 11705 pw.println(" (nothing)"); 11706 } 11707 } 11708 11709 private static final int dumpProcessList(PrintWriter pw, 11710 ActivityManagerService service, List list, 11711 String prefix, String normalLabel, String persistentLabel, 11712 String dumpPackage) { 11713 int numPers = 0; 11714 final int N = list.size()-1; 11715 for (int i=N; i>=0; i--) { 11716 ProcessRecord r = (ProcessRecord)list.get(i); 11717 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 11718 continue; 11719 } 11720 pw.println(String.format("%s%s #%2d: %s", 11721 prefix, (r.persistent ? persistentLabel : normalLabel), 11722 i, r.toString())); 11723 if (r.persistent) { 11724 numPers++; 11725 } 11726 } 11727 return numPers; 11728 } 11729 11730 private static final boolean dumpProcessOomList(PrintWriter pw, 11731 ActivityManagerService service, List<ProcessRecord> origList, 11732 String prefix, String normalLabel, String persistentLabel, 11733 boolean inclDetails, String dumpPackage) { 11734 11735 ArrayList<Pair<ProcessRecord, Integer>> list 11736 = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size()); 11737 for (int i=0; i<origList.size(); i++) { 11738 ProcessRecord r = origList.get(i); 11739 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 11740 continue; 11741 } 11742 list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i)); 11743 } 11744 11745 if (list.size() <= 0) { 11746 return false; 11747 } 11748 11749 Comparator<Pair<ProcessRecord, Integer>> comparator 11750 = new Comparator<Pair<ProcessRecord, Integer>>() { 11751 @Override 11752 public int compare(Pair<ProcessRecord, Integer> object1, 11753 Pair<ProcessRecord, Integer> object2) { 11754 if (object1.first.setAdj != object2.first.setAdj) { 11755 return object1.first.setAdj > object2.first.setAdj ? -1 : 1; 11756 } 11757 if (object1.second.intValue() != object2.second.intValue()) { 11758 return object1.second.intValue() > object2.second.intValue() ? -1 : 1; 11759 } 11760 return 0; 11761 } 11762 }; 11763 11764 Collections.sort(list, comparator); 11765 11766 final long curRealtime = SystemClock.elapsedRealtime(); 11767 final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime; 11768 final long curUptime = SystemClock.uptimeMillis(); 11769 final long uptimeSince = curUptime - service.mLastPowerCheckUptime; 11770 11771 for (int i=list.size()-1; i>=0; i--) { 11772 ProcessRecord r = list.get(i).first; 11773 String oomAdj = ProcessList.makeOomAdjString(r.setAdj); 11774 char schedGroup; 11775 switch (r.setSchedGroup) { 11776 case Process.THREAD_GROUP_BG_NONINTERACTIVE: 11777 schedGroup = 'B'; 11778 break; 11779 case Process.THREAD_GROUP_DEFAULT: 11780 schedGroup = 'F'; 11781 break; 11782 default: 11783 schedGroup = '?'; 11784 break; 11785 } 11786 char foreground; 11787 if (r.foregroundActivities) { 11788 foreground = 'A'; 11789 } else if (r.foregroundServices) { 11790 foreground = 'S'; 11791 } else { 11792 foreground = ' '; 11793 } 11794 String procState = ProcessList.makeProcStateString(r.curProcState); 11795 pw.print(prefix); 11796 pw.print(r.persistent ? persistentLabel : normalLabel); 11797 pw.print(" #"); 11798 int num = (origList.size()-1)-list.get(i).second; 11799 if (num < 10) pw.print(' '); 11800 pw.print(num); 11801 pw.print(": "); 11802 pw.print(oomAdj); 11803 pw.print(' '); 11804 pw.print(schedGroup); 11805 pw.print('/'); 11806 pw.print(foreground); 11807 pw.print('/'); 11808 pw.print(procState); 11809 pw.print(" trm:"); 11810 if (r.trimMemoryLevel < 10) pw.print(' '); 11811 pw.print(r.trimMemoryLevel); 11812 pw.print(' '); 11813 pw.print(r.toShortString()); 11814 pw.print(" ("); 11815 pw.print(r.adjType); 11816 pw.println(')'); 11817 if (r.adjSource != null || r.adjTarget != null) { 11818 pw.print(prefix); 11819 pw.print(" "); 11820 if (r.adjTarget instanceof ComponentName) { 11821 pw.print(((ComponentName)r.adjTarget).flattenToShortString()); 11822 } else if (r.adjTarget != null) { 11823 pw.print(r.adjTarget.toString()); 11824 } else { 11825 pw.print("{null}"); 11826 } 11827 pw.print("<="); 11828 if (r.adjSource instanceof ProcessRecord) { 11829 pw.print("Proc{"); 11830 pw.print(((ProcessRecord)r.adjSource).toShortString()); 11831 pw.println("}"); 11832 } else if (r.adjSource != null) { 11833 pw.println(r.adjSource.toString()); 11834 } else { 11835 pw.println("{null}"); 11836 } 11837 } 11838 if (inclDetails) { 11839 pw.print(prefix); 11840 pw.print(" "); 11841 pw.print("oom: max="); pw.print(r.maxAdj); 11842 pw.print(" curRaw="); pw.print(r.curRawAdj); 11843 pw.print(" setRaw="); pw.print(r.setRawAdj); 11844 pw.print(" cur="); pw.print(r.curAdj); 11845 pw.print(" set="); pw.println(r.setAdj); 11846 pw.print(prefix); 11847 pw.print(" "); 11848 pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState)); 11849 pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState)); 11850 pw.print(" lastPss="); pw.print(r.lastPss); 11851 pw.print(" lastCachedPss="); pw.println(r.lastCachedPss); 11852 pw.print(prefix); 11853 pw.print(" "); 11854 pw.print("keeping="); pw.print(r.keeping); 11855 pw.print(" cached="); pw.print(r.cached); 11856 pw.print(" empty="); pw.print(r.empty); 11857 pw.print(" hasAboveClient="); pw.println(r.hasAboveClient); 11858 11859 if (!r.keeping) { 11860 if (r.lastWakeTime != 0) { 11861 long wtime; 11862 BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics(); 11863 synchronized (stats) { 11864 wtime = stats.getProcessWakeTime(r.info.uid, 11865 r.pid, curRealtime); 11866 } 11867 long timeUsed = wtime - r.lastWakeTime; 11868 pw.print(prefix); 11869 pw.print(" "); 11870 pw.print("keep awake over "); 11871 TimeUtils.formatDuration(realtimeSince, pw); 11872 pw.print(" used "); 11873 TimeUtils.formatDuration(timeUsed, pw); 11874 pw.print(" ("); 11875 pw.print((timeUsed*100)/realtimeSince); 11876 pw.println("%)"); 11877 } 11878 if (r.lastCpuTime != 0) { 11879 long timeUsed = r.curCpuTime - r.lastCpuTime; 11880 pw.print(prefix); 11881 pw.print(" "); 11882 pw.print("run cpu over "); 11883 TimeUtils.formatDuration(uptimeSince, pw); 11884 pw.print(" used "); 11885 TimeUtils.formatDuration(timeUsed, pw); 11886 pw.print(" ("); 11887 pw.print((timeUsed*100)/uptimeSince); 11888 pw.println("%)"); 11889 } 11890 } 11891 } 11892 } 11893 return true; 11894 } 11895 11896 ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) { 11897 ArrayList<ProcessRecord> procs; 11898 synchronized (this) { 11899 if (args != null && args.length > start 11900 && args[start].charAt(0) != '-') { 11901 procs = new ArrayList<ProcessRecord>(); 11902 int pid = -1; 11903 try { 11904 pid = Integer.parseInt(args[start]); 11905 } catch (NumberFormatException e) { 11906 } 11907 for (int i=mLruProcesses.size()-1; i>=0; i--) { 11908 ProcessRecord proc = mLruProcesses.get(i); 11909 if (proc.pid == pid) { 11910 procs.add(proc); 11911 } else if (proc.processName.equals(args[start])) { 11912 procs.add(proc); 11913 } 11914 } 11915 if (procs.size() <= 0) { 11916 return null; 11917 } 11918 } else { 11919 procs = new ArrayList<ProcessRecord>(mLruProcesses); 11920 } 11921 } 11922 return procs; 11923 } 11924 11925 final void dumpGraphicsHardwareUsage(FileDescriptor fd, 11926 PrintWriter pw, String[] args) { 11927 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args); 11928 if (procs == null) { 11929 pw.println("No process found for: " + args[0]); 11930 return; 11931 } 11932 11933 long uptime = SystemClock.uptimeMillis(); 11934 long realtime = SystemClock.elapsedRealtime(); 11935 pw.println("Applications Graphics Acceleration Info:"); 11936 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 11937 11938 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 11939 ProcessRecord r = procs.get(i); 11940 if (r.thread != null) { 11941 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **"); 11942 pw.flush(); 11943 try { 11944 TransferPipe tp = new TransferPipe(); 11945 try { 11946 r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args); 11947 tp.go(fd); 11948 } finally { 11949 tp.kill(); 11950 } 11951 } catch (IOException e) { 11952 pw.println("Failure while dumping the app: " + r); 11953 pw.flush(); 11954 } catch (RemoteException e) { 11955 pw.println("Got a RemoteException while dumping the app " + r); 11956 pw.flush(); 11957 } 11958 } 11959 } 11960 } 11961 11962 final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) { 11963 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args); 11964 if (procs == null) { 11965 pw.println("No process found for: " + args[0]); 11966 return; 11967 } 11968 11969 pw.println("Applications Database Info:"); 11970 11971 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 11972 ProcessRecord r = procs.get(i); 11973 if (r.thread != null) { 11974 pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **"); 11975 pw.flush(); 11976 try { 11977 TransferPipe tp = new TransferPipe(); 11978 try { 11979 r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args); 11980 tp.go(fd); 11981 } finally { 11982 tp.kill(); 11983 } 11984 } catch (IOException e) { 11985 pw.println("Failure while dumping the app: " + r); 11986 pw.flush(); 11987 } catch (RemoteException e) { 11988 pw.println("Got a RemoteException while dumping the app " + r); 11989 pw.flush(); 11990 } 11991 } 11992 } 11993 } 11994 11995 final static class MemItem { 11996 final boolean isProc; 11997 final String label; 11998 final String shortLabel; 11999 final long pss; 12000 final int id; 12001 final boolean hasActivities; 12002 ArrayList<MemItem> subitems; 12003 12004 public MemItem(String _label, String _shortLabel, long _pss, int _id, 12005 boolean _hasActivities) { 12006 isProc = true; 12007 label = _label; 12008 shortLabel = _shortLabel; 12009 pss = _pss; 12010 id = _id; 12011 hasActivities = _hasActivities; 12012 } 12013 12014 public MemItem(String _label, String _shortLabel, long _pss, int _id) { 12015 isProc = false; 12016 label = _label; 12017 shortLabel = _shortLabel; 12018 pss = _pss; 12019 id = _id; 12020 hasActivities = false; 12021 } 12022 } 12023 12024 static final void dumpMemItems(PrintWriter pw, String prefix, String tag, 12025 ArrayList<MemItem> items, boolean sort, boolean isCompact) { 12026 if (sort && !isCompact) { 12027 Collections.sort(items, new Comparator<MemItem>() { 12028 @Override 12029 public int compare(MemItem lhs, MemItem rhs) { 12030 if (lhs.pss < rhs.pss) { 12031 return 1; 12032 } else if (lhs.pss > rhs.pss) { 12033 return -1; 12034 } 12035 return 0; 12036 } 12037 }); 12038 } 12039 12040 for (int i=0; i<items.size(); i++) { 12041 MemItem mi = items.get(i); 12042 if (!isCompact) { 12043 pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label); 12044 } else if (mi.isProc) { 12045 pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel); 12046 pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss); 12047 pw.println(mi.hasActivities ? ",a" : ",e"); 12048 } else { 12049 pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(","); 12050 pw.println(mi.pss); 12051 } 12052 if (mi.subitems != null) { 12053 dumpMemItems(pw, prefix + " ", mi.shortLabel, mi.subitems, 12054 true, isCompact); 12055 } 12056 } 12057 } 12058 12059 // These are in KB. 12060 static final long[] DUMP_MEM_BUCKETS = new long[] { 12061 5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024, 12062 120*1024, 160*1024, 200*1024, 12063 250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024, 12064 1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024 12065 }; 12066 12067 static final void appendMemBucket(StringBuilder out, long memKB, String label, 12068 boolean stackLike) { 12069 int start = label.lastIndexOf('.'); 12070 if (start >= 0) start++; 12071 else start = 0; 12072 int end = label.length(); 12073 for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) { 12074 if (DUMP_MEM_BUCKETS[i] >= memKB) { 12075 long bucket = DUMP_MEM_BUCKETS[i]/1024; 12076 out.append(bucket); 12077 out.append(stackLike ? "MB." : "MB "); 12078 out.append(label, start, end); 12079 return; 12080 } 12081 } 12082 out.append(memKB/1024); 12083 out.append(stackLike ? "MB." : "MB "); 12084 out.append(label, start, end); 12085 } 12086 12087 static final int[] DUMP_MEM_OOM_ADJ = new int[] { 12088 ProcessList.NATIVE_ADJ, 12089 ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ, 12090 ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ, 12091 ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ, 12092 ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ, 12093 ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ 12094 }; 12095 static final String[] DUMP_MEM_OOM_LABEL = new String[] { 12096 "Native", 12097 "System", "Persistent", "Foreground", 12098 "Visible", "Perceptible", 12099 "Heavy Weight", "Backup", 12100 "A Services", "Home", 12101 "Previous", "B Services", "Cached" 12102 }; 12103 static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] { 12104 "native", 12105 "sys", "pers", "fore", 12106 "vis", "percept", 12107 "heavy", "backup", 12108 "servicea", "home", 12109 "prev", "serviceb", "cached" 12110 }; 12111 12112 private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime, 12113 long realtime, boolean isCheckinRequest, boolean isCompact) { 12114 if (isCheckinRequest || isCompact) { 12115 // short checkin version 12116 pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime); 12117 } else { 12118 pw.println("Applications Memory Usage (kB):"); 12119 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 12120 } 12121 } 12122 12123 final void dumpApplicationMemoryUsage(FileDescriptor fd, 12124 PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) { 12125 boolean dumpDetails = false; 12126 boolean dumpFullDetails = false; 12127 boolean dumpDalvik = false; 12128 boolean oomOnly = false; 12129 boolean isCompact = false; 12130 boolean localOnly = false; 12131 12132 int opti = 0; 12133 while (opti < args.length) { 12134 String opt = args[opti]; 12135 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 12136 break; 12137 } 12138 opti++; 12139 if ("-a".equals(opt)) { 12140 dumpDetails = true; 12141 dumpFullDetails = true; 12142 dumpDalvik = true; 12143 } else if ("-d".equals(opt)) { 12144 dumpDalvik = true; 12145 } else if ("-c".equals(opt)) { 12146 isCompact = true; 12147 } else if ("--oom".equals(opt)) { 12148 oomOnly = true; 12149 } else if ("--local".equals(opt)) { 12150 localOnly = true; 12151 } else if ("-h".equals(opt)) { 12152 pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]"); 12153 pw.println(" -a: include all available information for each process."); 12154 pw.println(" -d: include dalvik details when dumping process details."); 12155 pw.println(" -c: dump in a compact machine-parseable representation."); 12156 pw.println(" --oom: only show processes organized by oom adj."); 12157 pw.println(" --local: only collect details locally, don't call process."); 12158 pw.println("If [process] is specified it can be the name or "); 12159 pw.println("pid of a specific process to dump."); 12160 return; 12161 } else { 12162 pw.println("Unknown argument: " + opt + "; use -h for help"); 12163 } 12164 } 12165 12166 final boolean isCheckinRequest = scanArgs(args, "--checkin"); 12167 long uptime = SystemClock.uptimeMillis(); 12168 long realtime = SystemClock.elapsedRealtime(); 12169 final long[] tmpLong = new long[1]; 12170 12171 ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args); 12172 if (procs == null) { 12173 // No Java processes. Maybe they want to print a native process. 12174 if (args != null && args.length > opti 12175 && args[opti].charAt(0) != '-') { 12176 ArrayList<ProcessCpuTracker.Stats> nativeProcs 12177 = new ArrayList<ProcessCpuTracker.Stats>(); 12178 updateCpuStatsNow(); 12179 int findPid = -1; 12180 try { 12181 findPid = Integer.parseInt(args[opti]); 12182 } catch (NumberFormatException e) { 12183 } 12184 synchronized (mProcessCpuThread) { 12185 final int N = mProcessCpuTracker.countStats(); 12186 for (int i=0; i<N; i++) { 12187 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 12188 if (st.pid == findPid || (st.baseName != null 12189 && st.baseName.equals(args[opti]))) { 12190 nativeProcs.add(st); 12191 } 12192 } 12193 } 12194 if (nativeProcs.size() > 0) { 12195 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, 12196 isCompact); 12197 Debug.MemoryInfo mi = null; 12198 for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) { 12199 final ProcessCpuTracker.Stats r = nativeProcs.get(i); 12200 final int pid = r.pid; 12201 if (!isCheckinRequest && dumpDetails) { 12202 pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **"); 12203 } 12204 if (mi == null) { 12205 mi = new Debug.MemoryInfo(); 12206 } 12207 if (dumpDetails || (!brief && !oomOnly)) { 12208 Debug.getMemoryInfo(pid, mi); 12209 } else { 12210 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong); 12211 mi.dalvikPrivateDirty = (int)tmpLong[0]; 12212 } 12213 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails, 12214 dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0); 12215 if (isCheckinRequest) { 12216 pw.println(); 12217 } 12218 } 12219 return; 12220 } 12221 } 12222 pw.println("No process found for: " + args[opti]); 12223 return; 12224 } 12225 12226 if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest)) { 12227 dumpDetails = true; 12228 } 12229 12230 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact); 12231 12232 String[] innerArgs = new String[args.length-opti]; 12233 System.arraycopy(args, opti, innerArgs, 0, args.length-opti); 12234 12235 ArrayList<MemItem> procMems = new ArrayList<MemItem>(); 12236 final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>(); 12237 long nativePss=0, dalvikPss=0, otherPss=0; 12238 long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS]; 12239 12240 long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length]; 12241 ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[]) 12242 new ArrayList[DUMP_MEM_OOM_LABEL.length]; 12243 12244 long totalPss = 0; 12245 long cachedPss = 0; 12246 12247 Debug.MemoryInfo mi = null; 12248 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 12249 final ProcessRecord r = procs.get(i); 12250 final IApplicationThread thread; 12251 final int pid; 12252 final int oomAdj; 12253 final boolean hasActivities; 12254 synchronized (this) { 12255 thread = r.thread; 12256 pid = r.pid; 12257 oomAdj = r.getSetAdjWithServices(); 12258 hasActivities = r.activities.size() > 0; 12259 } 12260 if (thread != null) { 12261 if (!isCheckinRequest && dumpDetails) { 12262 pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **"); 12263 } 12264 if (mi == null) { 12265 mi = new Debug.MemoryInfo(); 12266 } 12267 if (dumpDetails || (!brief && !oomOnly)) { 12268 Debug.getMemoryInfo(pid, mi); 12269 } else { 12270 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong); 12271 mi.dalvikPrivateDirty = (int)tmpLong[0]; 12272 } 12273 if (dumpDetails) { 12274 if (localOnly) { 12275 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails, 12276 dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0); 12277 if (isCheckinRequest) { 12278 pw.println(); 12279 } 12280 } else { 12281 try { 12282 pw.flush(); 12283 thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails, 12284 dumpDalvik, innerArgs); 12285 } catch (RemoteException e) { 12286 if (!isCheckinRequest) { 12287 pw.println("Got RemoteException!"); 12288 pw.flush(); 12289 } 12290 } 12291 } 12292 } 12293 12294 final long myTotalPss = mi.getTotalPss(); 12295 final long myTotalUss = mi.getTotalUss(); 12296 12297 synchronized (this) { 12298 if (r.thread != null && oomAdj == r.getSetAdjWithServices()) { 12299 // Record this for posterity if the process has been stable. 12300 r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList); 12301 } 12302 } 12303 12304 if (!isCheckinRequest && mi != null) { 12305 totalPss += myTotalPss; 12306 MemItem pssItem = new MemItem(r.processName + " (pid " + pid + 12307 (hasActivities ? " / activities)" : ")"), 12308 r.processName, myTotalPss, pid, hasActivities); 12309 procMems.add(pssItem); 12310 procMemsMap.put(pid, pssItem); 12311 12312 nativePss += mi.nativePss; 12313 dalvikPss += mi.dalvikPss; 12314 otherPss += mi.otherPss; 12315 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 12316 long mem = mi.getOtherPss(j); 12317 miscPss[j] += mem; 12318 otherPss -= mem; 12319 } 12320 12321 if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 12322 cachedPss += myTotalPss; 12323 } 12324 12325 for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) { 12326 if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex] 12327 || oomIndex == (oomPss.length-1)) { 12328 oomPss[oomIndex] += myTotalPss; 12329 if (oomProcs[oomIndex] == null) { 12330 oomProcs[oomIndex] = new ArrayList<MemItem>(); 12331 } 12332 oomProcs[oomIndex].add(pssItem); 12333 break; 12334 } 12335 } 12336 } 12337 } 12338 } 12339 12340 if (!isCheckinRequest && procs.size() > 1) { 12341 // If we are showing aggregations, also look for native processes to 12342 // include so that our aggregations are more accurate. 12343 updateCpuStatsNow(); 12344 synchronized (mProcessCpuThread) { 12345 final int N = mProcessCpuTracker.countStats(); 12346 for (int i=0; i<N; i++) { 12347 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 12348 if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) { 12349 if (mi == null) { 12350 mi = new Debug.MemoryInfo(); 12351 } 12352 if (!brief && !oomOnly) { 12353 Debug.getMemoryInfo(st.pid, mi); 12354 } else { 12355 mi.nativePss = (int)Debug.getPss(st.pid, tmpLong); 12356 mi.nativePrivateDirty = (int)tmpLong[0]; 12357 } 12358 12359 final long myTotalPss = mi.getTotalPss(); 12360 totalPss += myTotalPss; 12361 12362 MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")", 12363 st.name, myTotalPss, st.pid, false); 12364 procMems.add(pssItem); 12365 12366 nativePss += mi.nativePss; 12367 dalvikPss += mi.dalvikPss; 12368 otherPss += mi.otherPss; 12369 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 12370 long mem = mi.getOtherPss(j); 12371 miscPss[j] += mem; 12372 otherPss -= mem; 12373 } 12374 oomPss[0] += myTotalPss; 12375 if (oomProcs[0] == null) { 12376 oomProcs[0] = new ArrayList<MemItem>(); 12377 } 12378 oomProcs[0].add(pssItem); 12379 } 12380 } 12381 } 12382 12383 ArrayList<MemItem> catMems = new ArrayList<MemItem>(); 12384 12385 catMems.add(new MemItem("Native", "Native", nativePss, -1)); 12386 catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2)); 12387 catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3)); 12388 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 12389 String label = Debug.MemoryInfo.getOtherLabel(j); 12390 catMems.add(new MemItem(label, label, miscPss[j], j)); 12391 } 12392 12393 ArrayList<MemItem> oomMems = new ArrayList<MemItem>(); 12394 for (int j=0; j<oomPss.length; j++) { 12395 if (oomPss[j] != 0) { 12396 String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j] 12397 : DUMP_MEM_OOM_LABEL[j]; 12398 MemItem item = new MemItem(label, label, oomPss[j], 12399 DUMP_MEM_OOM_ADJ[j]); 12400 item.subitems = oomProcs[j]; 12401 oomMems.add(item); 12402 } 12403 } 12404 12405 if (!brief && !oomOnly && !isCompact) { 12406 pw.println(); 12407 pw.println("Total PSS by process:"); 12408 dumpMemItems(pw, " ", "proc", procMems, true, isCompact); 12409 pw.println(); 12410 } 12411 if (!isCompact) { 12412 pw.println("Total PSS by OOM adjustment:"); 12413 } 12414 dumpMemItems(pw, " ", "oom", oomMems, false, isCompact); 12415 if (!brief && !oomOnly) { 12416 PrintWriter out = categoryPw != null ? categoryPw : pw; 12417 if (!isCompact) { 12418 out.println(); 12419 out.println("Total PSS by category:"); 12420 } 12421 dumpMemItems(out, " ", "cat", catMems, true, isCompact); 12422 } 12423 if (!isCompact) { 12424 pw.println(); 12425 } 12426 MemInfoReader memInfo = new MemInfoReader(); 12427 memInfo.readMemInfo(); 12428 if (!brief) { 12429 if (!isCompact) { 12430 pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb()); 12431 pw.print(" kB (status "); 12432 switch (mLastMemoryLevel) { 12433 case ProcessStats.ADJ_MEM_FACTOR_NORMAL: 12434 pw.println("normal)"); 12435 break; 12436 case ProcessStats.ADJ_MEM_FACTOR_MODERATE: 12437 pw.println("moderate)"); 12438 break; 12439 case ProcessStats.ADJ_MEM_FACTOR_LOW: 12440 pw.println("low)"); 12441 break; 12442 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL: 12443 pw.println("critical)"); 12444 break; 12445 default: 12446 pw.print(mLastMemoryLevel); 12447 pw.println(")"); 12448 break; 12449 } 12450 pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb() 12451 + memInfo.getFreeSizeKb()); pw.print(" kB ("); 12452 pw.print(cachedPss); pw.print(" cached pss + "); 12453 pw.print(memInfo.getCachedSizeKb()); pw.print(" cached + "); 12454 pw.print(memInfo.getFreeSizeKb()); pw.println(" free)"); 12455 } else { 12456 pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(","); 12457 pw.print(cachedPss + memInfo.getCachedSizeKb() 12458 + memInfo.getFreeSizeKb()); pw.print(","); 12459 pw.println(totalPss - cachedPss); 12460 } 12461 } 12462 if (!isCompact) { 12463 pw.print(" Used RAM: "); pw.print(totalPss - cachedPss 12464 + memInfo.getBuffersSizeKb() + memInfo.getShmemSizeKb() 12465 + memInfo.getSlabSizeKb()); pw.print(" kB ("); 12466 pw.print(totalPss - cachedPss); pw.print(" used pss + "); 12467 pw.print(memInfo.getBuffersSizeKb()); pw.print(" buffers + "); 12468 pw.print(memInfo.getShmemSizeKb()); pw.print(" shmem + "); 12469 pw.print(memInfo.getSlabSizeKb()); pw.println(" slab)"); 12470 pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb() 12471 - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb() 12472 - memInfo.getBuffersSizeKb() - memInfo.getShmemSizeKb() 12473 - memInfo.getSlabSizeKb()); pw.println(" kB"); 12474 } 12475 if (!brief) { 12476 if (memInfo.getZramTotalSizeKb() != 0) { 12477 if (!isCompact) { 12478 pw.print(" ZRAM: "); pw.print(memInfo.getZramTotalSizeKb()); 12479 pw.print(" kB physical used for "); 12480 pw.print(memInfo.getSwapTotalSizeKb() 12481 - memInfo.getSwapFreeSizeKb()); 12482 pw.print(" kB in swap ("); 12483 pw.print(memInfo.getSwapTotalSizeKb()); 12484 pw.println(" kB total swap)"); 12485 } else { 12486 pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(","); 12487 pw.print(memInfo.getSwapTotalSizeKb()); pw.print(","); 12488 pw.println(memInfo.getSwapFreeSizeKb()); 12489 } 12490 } 12491 final int[] SINGLE_LONG_FORMAT = new int[] { 12492 Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG 12493 }; 12494 long[] longOut = new long[1]; 12495 Process.readProcFile("/sys/kernel/mm/ksm/pages_shared", 12496 SINGLE_LONG_FORMAT, null, longOut, null); 12497 long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024; 12498 longOut[0] = 0; 12499 Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing", 12500 SINGLE_LONG_FORMAT, null, longOut, null); 12501 long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024; 12502 longOut[0] = 0; 12503 Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared", 12504 SINGLE_LONG_FORMAT, null, longOut, null); 12505 long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024; 12506 longOut[0] = 0; 12507 Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile", 12508 SINGLE_LONG_FORMAT, null, longOut, null); 12509 long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024; 12510 if (!isCompact) { 12511 if (sharing != 0 || shared != 0 || unshared != 0 || voltile != 0) { 12512 pw.print(" KSM: "); pw.print(sharing); 12513 pw.print(" kB saved from shared "); 12514 pw.print(shared); pw.println(" kB"); 12515 pw.print(" "); pw.print(unshared); pw.print(" kB unshared; "); 12516 pw.print(voltile); pw.println(" kB volatile"); 12517 } 12518 pw.print(" Tuning: "); 12519 pw.print(ActivityManager.staticGetMemoryClass()); 12520 pw.print(" (large "); 12521 pw.print(ActivityManager.staticGetLargeMemoryClass()); 12522 pw.print("), oom "); 12523 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024); 12524 pw.print(" kB"); 12525 pw.print(", restore limit "); 12526 pw.print(mProcessList.getCachedRestoreThresholdKb()); 12527 pw.print(" kB"); 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 } else { 12536 pw.print("ksm,"); pw.print(sharing); pw.print(","); 12537 pw.print(shared); pw.print(","); pw.print(unshared); pw.print(","); 12538 pw.println(voltile); 12539 pw.print("tuning,"); 12540 pw.print(ActivityManager.staticGetMemoryClass()); 12541 pw.print(','); 12542 pw.print(ActivityManager.staticGetLargeMemoryClass()); 12543 pw.print(','); 12544 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024); 12545 if (ActivityManager.isLowRamDeviceStatic()) { 12546 pw.print(",low-ram"); 12547 } 12548 if (ActivityManager.isHighEndGfx()) { 12549 pw.print(",high-end-gfx"); 12550 } 12551 pw.println(); 12552 } 12553 } 12554 } 12555 } 12556 12557 /** 12558 * Searches array of arguments for the specified string 12559 * @param args array of argument strings 12560 * @param value value to search for 12561 * @return true if the value is contained in the array 12562 */ 12563 private static boolean scanArgs(String[] args, String value) { 12564 if (args != null) { 12565 for (String arg : args) { 12566 if (value.equals(arg)) { 12567 return true; 12568 } 12569 } 12570 } 12571 return false; 12572 } 12573 12574 private final boolean removeDyingProviderLocked(ProcessRecord proc, 12575 ContentProviderRecord cpr, boolean always) { 12576 final boolean inLaunching = mLaunchingProviders.contains(cpr); 12577 12578 if (!inLaunching || always) { 12579 synchronized (cpr) { 12580 cpr.launchingApp = null; 12581 cpr.notifyAll(); 12582 } 12583 mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid)); 12584 String names[] = cpr.info.authority.split(";"); 12585 for (int j = 0; j < names.length; j++) { 12586 mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid)); 12587 } 12588 } 12589 12590 for (int i=0; i<cpr.connections.size(); i++) { 12591 ContentProviderConnection conn = cpr.connections.get(i); 12592 if (conn.waiting) { 12593 // If this connection is waiting for the provider, then we don't 12594 // need to mess with its process unless we are always removing 12595 // or for some reason the provider is not currently launching. 12596 if (inLaunching && !always) { 12597 continue; 12598 } 12599 } 12600 ProcessRecord capp = conn.client; 12601 conn.dead = true; 12602 if (conn.stableCount > 0) { 12603 if (!capp.persistent && capp.thread != null 12604 && capp.pid != 0 12605 && capp.pid != MY_PID) { 12606 killUnneededProcessLocked(capp, "depends on provider " 12607 + cpr.name.flattenToShortString() 12608 + " in dying proc " + (proc != null ? proc.processName : "??")); 12609 } 12610 } else if (capp.thread != null && conn.provider.provider != null) { 12611 try { 12612 capp.thread.unstableProviderDied(conn.provider.provider.asBinder()); 12613 } catch (RemoteException e) { 12614 } 12615 // In the protocol here, we don't expect the client to correctly 12616 // clean up this connection, we'll just remove it. 12617 cpr.connections.remove(i); 12618 conn.client.conProviders.remove(conn); 12619 } 12620 } 12621 12622 if (inLaunching && always) { 12623 mLaunchingProviders.remove(cpr); 12624 } 12625 return inLaunching; 12626 } 12627 12628 /** 12629 * Main code for cleaning up a process when it has gone away. This is 12630 * called both as a result of the process dying, or directly when stopping 12631 * a process when running in single process mode. 12632 */ 12633 private final void cleanUpApplicationRecordLocked(ProcessRecord app, 12634 boolean restarting, boolean allowRestart, int index) { 12635 if (index >= 0) { 12636 removeLruProcessLocked(app); 12637 ProcessList.remove(app.pid); 12638 } 12639 12640 mProcessesToGc.remove(app); 12641 mPendingPssProcesses.remove(app); 12642 12643 // Dismiss any open dialogs. 12644 if (app.crashDialog != null && !app.forceCrashReport) { 12645 app.crashDialog.dismiss(); 12646 app.crashDialog = null; 12647 } 12648 if (app.anrDialog != null) { 12649 app.anrDialog.dismiss(); 12650 app.anrDialog = null; 12651 } 12652 if (app.waitDialog != null) { 12653 app.waitDialog.dismiss(); 12654 app.waitDialog = null; 12655 } 12656 12657 app.crashing = false; 12658 app.notResponding = false; 12659 12660 app.resetPackageList(mProcessStats); 12661 app.unlinkDeathRecipient(); 12662 app.makeInactive(mProcessStats); 12663 app.forcingToForeground = null; 12664 updateProcessForegroundLocked(app, false, false); 12665 app.foregroundActivities = false; 12666 app.hasShownUi = false; 12667 app.treatLikeActivity = false; 12668 app.hasAboveClient = false; 12669 app.hasClientActivities = false; 12670 12671 mServices.killServicesLocked(app, allowRestart); 12672 12673 boolean restart = false; 12674 12675 // Remove published content providers. 12676 for (int i=app.pubProviders.size()-1; i>=0; i--) { 12677 ContentProviderRecord cpr = app.pubProviders.valueAt(i); 12678 final boolean always = app.bad || !allowRestart; 12679 if (removeDyingProviderLocked(app, cpr, always) || always) { 12680 // We left the provider in the launching list, need to 12681 // restart it. 12682 restart = true; 12683 } 12684 12685 cpr.provider = null; 12686 cpr.proc = null; 12687 } 12688 app.pubProviders.clear(); 12689 12690 // Take care of any launching providers waiting for this process. 12691 if (checkAppInLaunchingProvidersLocked(app, false)) { 12692 restart = true; 12693 } 12694 12695 // Unregister from connected content providers. 12696 if (!app.conProviders.isEmpty()) { 12697 for (int i=0; i<app.conProviders.size(); i++) { 12698 ContentProviderConnection conn = app.conProviders.get(i); 12699 conn.provider.connections.remove(conn); 12700 } 12701 app.conProviders.clear(); 12702 } 12703 12704 // At this point there may be remaining entries in mLaunchingProviders 12705 // where we were the only one waiting, so they are no longer of use. 12706 // Look for these and clean up if found. 12707 // XXX Commented out for now. Trying to figure out a way to reproduce 12708 // the actual situation to identify what is actually going on. 12709 if (false) { 12710 for (int i=0; i<mLaunchingProviders.size(); i++) { 12711 ContentProviderRecord cpr = (ContentProviderRecord) 12712 mLaunchingProviders.get(i); 12713 if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) { 12714 synchronized (cpr) { 12715 cpr.launchingApp = null; 12716 cpr.notifyAll(); 12717 } 12718 } 12719 } 12720 } 12721 12722 skipCurrentReceiverLocked(app); 12723 12724 // Unregister any receivers. 12725 for (int i=app.receivers.size()-1; i>=0; i--) { 12726 removeReceiverLocked(app.receivers.valueAt(i)); 12727 } 12728 app.receivers.clear(); 12729 12730 // If the app is undergoing backup, tell the backup manager about it 12731 if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) { 12732 if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App " 12733 + mBackupTarget.appInfo + " died during backup"); 12734 try { 12735 IBackupManager bm = IBackupManager.Stub.asInterface( 12736 ServiceManager.getService(Context.BACKUP_SERVICE)); 12737 bm.agentDisconnected(app.info.packageName); 12738 } catch (RemoteException e) { 12739 // can't happen; backup manager is local 12740 } 12741 } 12742 12743 for (int i = mPendingProcessChanges.size()-1; i>=0; i--) { 12744 ProcessChangeItem item = mPendingProcessChanges.get(i); 12745 if (item.pid == app.pid) { 12746 mPendingProcessChanges.remove(i); 12747 mAvailProcessChanges.add(item); 12748 } 12749 } 12750 mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget(); 12751 12752 // If the caller is restarting this app, then leave it in its 12753 // current lists and let the caller take care of it. 12754 if (restarting) { 12755 return; 12756 } 12757 12758 if (!app.persistent || app.isolated) { 12759 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, 12760 "Removing non-persistent process during cleanup: " + app); 12761 mProcessNames.remove(app.processName, app.uid); 12762 mIsolatedProcesses.remove(app.uid); 12763 if (mHeavyWeightProcess == app) { 12764 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 12765 mHeavyWeightProcess.userId, 0)); 12766 mHeavyWeightProcess = null; 12767 } 12768 } else if (!app.removed) { 12769 // This app is persistent, so we need to keep its record around. 12770 // If it is not already on the pending app list, add it there 12771 // and start a new process for it. 12772 if (mPersistentStartingProcesses.indexOf(app) < 0) { 12773 mPersistentStartingProcesses.add(app); 12774 restart = true; 12775 } 12776 } 12777 if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG, 12778 "Clean-up removing on hold: " + app); 12779 mProcessesOnHold.remove(app); 12780 12781 if (app == mHomeProcess) { 12782 mHomeProcess = null; 12783 } 12784 if (app == mPreviousProcess) { 12785 mPreviousProcess = null; 12786 } 12787 12788 if (restart && !app.isolated) { 12789 // We have components that still need to be running in the 12790 // process, so re-launch it. 12791 mProcessNames.put(app.processName, app.uid, app); 12792 startProcessLocked(app, "restart", app.processName); 12793 } else if (app.pid > 0 && app.pid != MY_PID) { 12794 // Goodbye! 12795 boolean removed; 12796 synchronized (mPidsSelfLocked) { 12797 mPidsSelfLocked.remove(app.pid); 12798 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 12799 } 12800 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH, 12801 app.processName, app.info.uid); 12802 if (app.isolated) { 12803 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 12804 } 12805 app.setPid(0); 12806 } 12807 } 12808 12809 boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) { 12810 // Look through the content providers we are waiting to have launched, 12811 // and if any run in this process then either schedule a restart of 12812 // the process or kill the client waiting for it if this process has 12813 // gone bad. 12814 int NL = mLaunchingProviders.size(); 12815 boolean restart = false; 12816 for (int i=0; i<NL; i++) { 12817 ContentProviderRecord cpr = mLaunchingProviders.get(i); 12818 if (cpr.launchingApp == app) { 12819 if (!alwaysBad && !app.bad) { 12820 restart = true; 12821 } else { 12822 removeDyingProviderLocked(app, cpr, true); 12823 // cpr should have been removed from mLaunchingProviders 12824 NL = mLaunchingProviders.size(); 12825 i--; 12826 } 12827 } 12828 } 12829 return restart; 12830 } 12831 12832 // ========================================================= 12833 // SERVICES 12834 // ========================================================= 12835 12836 public List<ActivityManager.RunningServiceInfo> getServices(int maxNum, 12837 int flags) { 12838 enforceNotIsolatedCaller("getServices"); 12839 synchronized (this) { 12840 return mServices.getRunningServiceInfoLocked(maxNum, flags); 12841 } 12842 } 12843 12844 public PendingIntent getRunningServiceControlPanel(ComponentName name) { 12845 enforceNotIsolatedCaller("getRunningServiceControlPanel"); 12846 synchronized (this) { 12847 return mServices.getRunningServiceControlPanelLocked(name); 12848 } 12849 } 12850 12851 public ComponentName startService(IApplicationThread caller, Intent service, 12852 String resolvedType, int userId) { 12853 enforceNotIsolatedCaller("startService"); 12854 // Refuse possible leaked file descriptors 12855 if (service != null && service.hasFileDescriptors() == true) { 12856 throw new IllegalArgumentException("File descriptors passed in Intent"); 12857 } 12858 12859 if (DEBUG_SERVICE) 12860 Slog.v(TAG, "startService: " + service + " type=" + resolvedType); 12861 synchronized(this) { 12862 final int callingPid = Binder.getCallingPid(); 12863 final int callingUid = Binder.getCallingUid(); 12864 final long origId = Binder.clearCallingIdentity(); 12865 ComponentName res = mServices.startServiceLocked(caller, service, 12866 resolvedType, callingPid, callingUid, userId); 12867 Binder.restoreCallingIdentity(origId); 12868 return res; 12869 } 12870 } 12871 12872 ComponentName startServiceInPackage(int uid, 12873 Intent service, String resolvedType, int userId) { 12874 synchronized(this) { 12875 if (DEBUG_SERVICE) 12876 Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType); 12877 final long origId = Binder.clearCallingIdentity(); 12878 ComponentName res = mServices.startServiceLocked(null, service, 12879 resolvedType, -1, uid, userId); 12880 Binder.restoreCallingIdentity(origId); 12881 return res; 12882 } 12883 } 12884 12885 public int stopService(IApplicationThread caller, Intent service, 12886 String resolvedType, int userId) { 12887 enforceNotIsolatedCaller("stopService"); 12888 // Refuse possible leaked file descriptors 12889 if (service != null && service.hasFileDescriptors() == true) { 12890 throw new IllegalArgumentException("File descriptors passed in Intent"); 12891 } 12892 12893 synchronized(this) { 12894 return mServices.stopServiceLocked(caller, service, resolvedType, userId); 12895 } 12896 } 12897 12898 public IBinder peekService(Intent service, String resolvedType) { 12899 enforceNotIsolatedCaller("peekService"); 12900 // Refuse possible leaked file descriptors 12901 if (service != null && service.hasFileDescriptors() == true) { 12902 throw new IllegalArgumentException("File descriptors passed in Intent"); 12903 } 12904 synchronized(this) { 12905 return mServices.peekServiceLocked(service, resolvedType); 12906 } 12907 } 12908 12909 public boolean stopServiceToken(ComponentName className, IBinder token, 12910 int startId) { 12911 synchronized(this) { 12912 return mServices.stopServiceTokenLocked(className, token, startId); 12913 } 12914 } 12915 12916 public void setServiceForeground(ComponentName className, IBinder token, 12917 int id, Notification notification, boolean removeNotification) { 12918 synchronized(this) { 12919 mServices.setServiceForegroundLocked(className, token, id, notification, 12920 removeNotification); 12921 } 12922 } 12923 12924 public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll, 12925 boolean requireFull, String name, String callerPackage) { 12926 final int callingUserId = UserHandle.getUserId(callingUid); 12927 if (callingUserId != userId) { 12928 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 12929 if ((requireFull || checkComponentPermission( 12930 android.Manifest.permission.INTERACT_ACROSS_USERS, 12931 callingPid, callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) 12932 && checkComponentPermission( 12933 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 12934 callingPid, callingUid, -1, true) 12935 != PackageManager.PERMISSION_GRANTED) { 12936 if (userId == UserHandle.USER_CURRENT_OR_SELF) { 12937 // In this case, they would like to just execute as their 12938 // owner user instead of failing. 12939 userId = callingUserId; 12940 } else { 12941 StringBuilder builder = new StringBuilder(128); 12942 builder.append("Permission Denial: "); 12943 builder.append(name); 12944 if (callerPackage != null) { 12945 builder.append(" from "); 12946 builder.append(callerPackage); 12947 } 12948 builder.append(" asks to run as user "); 12949 builder.append(userId); 12950 builder.append(" but is calling from user "); 12951 builder.append(UserHandle.getUserId(callingUid)); 12952 builder.append("; this requires "); 12953 builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL); 12954 if (!requireFull) { 12955 builder.append(" or "); 12956 builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS); 12957 } 12958 String msg = builder.toString(); 12959 Slog.w(TAG, msg); 12960 throw new SecurityException(msg); 12961 } 12962 } 12963 } 12964 if (userId == UserHandle.USER_CURRENT 12965 || userId == UserHandle.USER_CURRENT_OR_SELF) { 12966 // Note that we may be accessing this outside of a lock... 12967 // shouldn't be a big deal, if this is being called outside 12968 // of a locked context there is intrinsically a race with 12969 // the value the caller will receive and someone else changing it. 12970 userId = mCurrentUserId; 12971 } 12972 if (!allowAll && userId < 0) { 12973 throw new IllegalArgumentException( 12974 "Call does not support special user #" + userId); 12975 } 12976 } 12977 return userId; 12978 } 12979 12980 boolean isSingleton(String componentProcessName, ApplicationInfo aInfo, 12981 String className, int flags) { 12982 boolean result = false; 12983 if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) { 12984 if ((flags&ServiceInfo.FLAG_SINGLE_USER) != 0) { 12985 if (ActivityManager.checkUidPermission( 12986 android.Manifest.permission.INTERACT_ACROSS_USERS, 12987 aInfo.uid) != PackageManager.PERMISSION_GRANTED) { 12988 ComponentName comp = new ComponentName(aInfo.packageName, className); 12989 String msg = "Permission Denial: Component " + comp.flattenToShortString() 12990 + " requests FLAG_SINGLE_USER, but app does not hold " 12991 + android.Manifest.permission.INTERACT_ACROSS_USERS; 12992 Slog.w(TAG, msg); 12993 throw new SecurityException(msg); 12994 } 12995 result = true; 12996 } 12997 } else if (componentProcessName == aInfo.packageName) { 12998 result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0; 12999 } else if ("system".equals(componentProcessName)) { 13000 result = true; 13001 } 13002 if (DEBUG_MU) { 13003 Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo 13004 + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result); 13005 } 13006 return result; 13007 } 13008 13009 public int bindService(IApplicationThread caller, IBinder token, 13010 Intent service, String resolvedType, 13011 IServiceConnection connection, int flags, int userId) { 13012 enforceNotIsolatedCaller("bindService"); 13013 // Refuse possible leaked file descriptors 13014 if (service != null && service.hasFileDescriptors() == true) { 13015 throw new IllegalArgumentException("File descriptors passed in Intent"); 13016 } 13017 13018 synchronized(this) { 13019 return mServices.bindServiceLocked(caller, token, service, resolvedType, 13020 connection, flags, userId); 13021 } 13022 } 13023 13024 public boolean unbindService(IServiceConnection connection) { 13025 synchronized (this) { 13026 return mServices.unbindServiceLocked(connection); 13027 } 13028 } 13029 13030 public void publishService(IBinder token, Intent intent, IBinder service) { 13031 // Refuse possible leaked file descriptors 13032 if (intent != null && intent.hasFileDescriptors() == true) { 13033 throw new IllegalArgumentException("File descriptors passed in Intent"); 13034 } 13035 13036 synchronized(this) { 13037 if (!(token instanceof ServiceRecord)) { 13038 throw new IllegalArgumentException("Invalid service token"); 13039 } 13040 mServices.publishServiceLocked((ServiceRecord)token, intent, service); 13041 } 13042 } 13043 13044 public void unbindFinished(IBinder token, Intent intent, boolean doRebind) { 13045 // Refuse possible leaked file descriptors 13046 if (intent != null && intent.hasFileDescriptors() == true) { 13047 throw new IllegalArgumentException("File descriptors passed in Intent"); 13048 } 13049 13050 synchronized(this) { 13051 mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind); 13052 } 13053 } 13054 13055 public void serviceDoneExecuting(IBinder token, int type, int startId, int res) { 13056 synchronized(this) { 13057 if (!(token instanceof ServiceRecord)) { 13058 throw new IllegalArgumentException("Invalid service token"); 13059 } 13060 mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res); 13061 } 13062 } 13063 13064 // ========================================================= 13065 // BACKUP AND RESTORE 13066 // ========================================================= 13067 13068 // Cause the target app to be launched if necessary and its backup agent 13069 // instantiated. The backup agent will invoke backupAgentCreated() on the 13070 // activity manager to announce its creation. 13071 public boolean bindBackupAgent(ApplicationInfo app, int backupMode) { 13072 if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode); 13073 enforceCallingPermission("android.permission.BACKUP", "bindBackupAgent"); 13074 13075 synchronized(this) { 13076 // !!! TODO: currently no check here that we're already bound 13077 BatteryStatsImpl.Uid.Pkg.Serv ss = null; 13078 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 13079 synchronized (stats) { 13080 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name); 13081 } 13082 13083 // Backup agent is now in use, its package can't be stopped. 13084 try { 13085 AppGlobals.getPackageManager().setPackageStoppedState( 13086 app.packageName, false, UserHandle.getUserId(app.uid)); 13087 } catch (RemoteException e) { 13088 } catch (IllegalArgumentException e) { 13089 Slog.w(TAG, "Failed trying to unstop package " 13090 + app.packageName + ": " + e); 13091 } 13092 13093 BackupRecord r = new BackupRecord(ss, app, backupMode); 13094 ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL) 13095 ? new ComponentName(app.packageName, app.backupAgentName) 13096 : new ComponentName("android", "FullBackupAgent"); 13097 // startProcessLocked() returns existing proc's record if it's already running 13098 ProcessRecord proc = startProcessLocked(app.processName, app, 13099 false, 0, "backup", hostingName, false, false, false); 13100 if (proc == null) { 13101 Slog.e(TAG, "Unable to start backup agent process " + r); 13102 return false; 13103 } 13104 13105 r.app = proc; 13106 mBackupTarget = r; 13107 mBackupAppName = app.packageName; 13108 13109 // Try not to kill the process during backup 13110 updateOomAdjLocked(proc); 13111 13112 // If the process is already attached, schedule the creation of the backup agent now. 13113 // If it is not yet live, this will be done when it attaches to the framework. 13114 if (proc.thread != null) { 13115 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc); 13116 try { 13117 proc.thread.scheduleCreateBackupAgent(app, 13118 compatibilityInfoForPackageLocked(app), backupMode); 13119 } catch (RemoteException e) { 13120 // Will time out on the backup manager side 13121 } 13122 } else { 13123 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach"); 13124 } 13125 // Invariants: at this point, the target app process exists and the application 13126 // is either already running or in the process of coming up. mBackupTarget and 13127 // mBackupAppName describe the app, so that when it binds back to the AM we 13128 // know that it's scheduled for a backup-agent operation. 13129 } 13130 13131 return true; 13132 } 13133 13134 @Override 13135 public void clearPendingBackup() { 13136 if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup"); 13137 enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup"); 13138 13139 synchronized (this) { 13140 mBackupTarget = null; 13141 mBackupAppName = null; 13142 } 13143 } 13144 13145 // A backup agent has just come up 13146 public void backupAgentCreated(String agentPackageName, IBinder agent) { 13147 if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName 13148 + " = " + agent); 13149 13150 synchronized(this) { 13151 if (!agentPackageName.equals(mBackupAppName)) { 13152 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!"); 13153 return; 13154 } 13155 } 13156 13157 long oldIdent = Binder.clearCallingIdentity(); 13158 try { 13159 IBackupManager bm = IBackupManager.Stub.asInterface( 13160 ServiceManager.getService(Context.BACKUP_SERVICE)); 13161 bm.agentConnected(agentPackageName, agent); 13162 } catch (RemoteException e) { 13163 // can't happen; the backup manager service is local 13164 } catch (Exception e) { 13165 Slog.w(TAG, "Exception trying to deliver BackupAgent binding: "); 13166 e.printStackTrace(); 13167 } finally { 13168 Binder.restoreCallingIdentity(oldIdent); 13169 } 13170 } 13171 13172 // done with this agent 13173 public void unbindBackupAgent(ApplicationInfo appInfo) { 13174 if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo); 13175 if (appInfo == null) { 13176 Slog.w(TAG, "unbind backup agent for null app"); 13177 return; 13178 } 13179 13180 synchronized(this) { 13181 try { 13182 if (mBackupAppName == null) { 13183 Slog.w(TAG, "Unbinding backup agent with no active backup"); 13184 return; 13185 } 13186 13187 if (!mBackupAppName.equals(appInfo.packageName)) { 13188 Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target"); 13189 return; 13190 } 13191 13192 // Not backing this app up any more; reset its OOM adjustment 13193 final ProcessRecord proc = mBackupTarget.app; 13194 updateOomAdjLocked(proc); 13195 13196 // If the app crashed during backup, 'thread' will be null here 13197 if (proc.thread != null) { 13198 try { 13199 proc.thread.scheduleDestroyBackupAgent(appInfo, 13200 compatibilityInfoForPackageLocked(appInfo)); 13201 } catch (Exception e) { 13202 Slog.e(TAG, "Exception when unbinding backup agent:"); 13203 e.printStackTrace(); 13204 } 13205 } 13206 } finally { 13207 mBackupTarget = null; 13208 mBackupAppName = null; 13209 } 13210 } 13211 } 13212 // ========================================================= 13213 // BROADCASTS 13214 // ========================================================= 13215 13216 private final List getStickiesLocked(String action, IntentFilter filter, 13217 List cur, int userId) { 13218 final ContentResolver resolver = mContext.getContentResolver(); 13219 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 13220 if (stickies == null) { 13221 return cur; 13222 } 13223 final ArrayList<Intent> list = stickies.get(action); 13224 if (list == null) { 13225 return cur; 13226 } 13227 int N = list.size(); 13228 for (int i=0; i<N; i++) { 13229 Intent intent = list.get(i); 13230 if (filter.match(resolver, intent, true, TAG) >= 0) { 13231 if (cur == null) { 13232 cur = new ArrayList<Intent>(); 13233 } 13234 cur.add(intent); 13235 } 13236 } 13237 return cur; 13238 } 13239 13240 boolean isPendingBroadcastProcessLocked(int pid) { 13241 return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid) 13242 || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid); 13243 } 13244 13245 void skipPendingBroadcastLocked(int pid) { 13246 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 13247 for (BroadcastQueue queue : mBroadcastQueues) { 13248 queue.skipPendingBroadcastLocked(pid); 13249 } 13250 } 13251 13252 // The app just attached; send any pending broadcasts that it should receive 13253 boolean sendPendingBroadcastsLocked(ProcessRecord app) { 13254 boolean didSomething = false; 13255 for (BroadcastQueue queue : mBroadcastQueues) { 13256 didSomething |= queue.sendPendingBroadcastsLocked(app); 13257 } 13258 return didSomething; 13259 } 13260 13261 public Intent registerReceiver(IApplicationThread caller, String callerPackage, 13262 IIntentReceiver receiver, IntentFilter filter, String permission, int userId) { 13263 enforceNotIsolatedCaller("registerReceiver"); 13264 int callingUid; 13265 int callingPid; 13266 synchronized(this) { 13267 ProcessRecord callerApp = null; 13268 if (caller != null) { 13269 callerApp = getRecordForAppLocked(caller); 13270 if (callerApp == null) { 13271 throw new SecurityException( 13272 "Unable to find app for caller " + caller 13273 + " (pid=" + Binder.getCallingPid() 13274 + ") when registering receiver " + receiver); 13275 } 13276 if (callerApp.info.uid != Process.SYSTEM_UID && 13277 !callerApp.pkgList.containsKey(callerPackage) && 13278 !"android".equals(callerPackage)) { 13279 throw new SecurityException("Given caller package " + callerPackage 13280 + " is not running in process " + callerApp); 13281 } 13282 callingUid = callerApp.info.uid; 13283 callingPid = callerApp.pid; 13284 } else { 13285 callerPackage = null; 13286 callingUid = Binder.getCallingUid(); 13287 callingPid = Binder.getCallingPid(); 13288 } 13289 13290 userId = this.handleIncomingUser(callingPid, callingUid, userId, 13291 true, true, "registerReceiver", callerPackage); 13292 13293 List allSticky = null; 13294 13295 // Look for any matching sticky broadcasts... 13296 Iterator actions = filter.actionsIterator(); 13297 if (actions != null) { 13298 while (actions.hasNext()) { 13299 String action = (String)actions.next(); 13300 allSticky = getStickiesLocked(action, filter, allSticky, 13301 UserHandle.USER_ALL); 13302 allSticky = getStickiesLocked(action, filter, allSticky, 13303 UserHandle.getUserId(callingUid)); 13304 } 13305 } else { 13306 allSticky = getStickiesLocked(null, filter, allSticky, 13307 UserHandle.USER_ALL); 13308 allSticky = getStickiesLocked(null, filter, allSticky, 13309 UserHandle.getUserId(callingUid)); 13310 } 13311 13312 // The first sticky in the list is returned directly back to 13313 // the client. 13314 Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null; 13315 13316 if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter 13317 + ": " + sticky); 13318 13319 if (receiver == null) { 13320 return sticky; 13321 } 13322 13323 ReceiverList rl 13324 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder()); 13325 if (rl == null) { 13326 rl = new ReceiverList(this, callerApp, callingPid, callingUid, 13327 userId, receiver); 13328 if (rl.app != null) { 13329 rl.app.receivers.add(rl); 13330 } else { 13331 try { 13332 receiver.asBinder().linkToDeath(rl, 0); 13333 } catch (RemoteException e) { 13334 return sticky; 13335 } 13336 rl.linkedToDeath = true; 13337 } 13338 mRegisteredReceivers.put(receiver.asBinder(), rl); 13339 } else if (rl.uid != callingUid) { 13340 throw new IllegalArgumentException( 13341 "Receiver requested to register for uid " + callingUid 13342 + " was previously registered for uid " + rl.uid); 13343 } else if (rl.pid != callingPid) { 13344 throw new IllegalArgumentException( 13345 "Receiver requested to register for pid " + callingPid 13346 + " was previously registered for pid " + rl.pid); 13347 } else if (rl.userId != userId) { 13348 throw new IllegalArgumentException( 13349 "Receiver requested to register for user " + userId 13350 + " was previously registered for user " + rl.userId); 13351 } 13352 BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage, 13353 permission, callingUid, userId); 13354 rl.add(bf); 13355 if (!bf.debugCheck()) { 13356 Slog.w(TAG, "==> For Dynamic broadast"); 13357 } 13358 mReceiverResolver.addFilter(bf); 13359 13360 // Enqueue broadcasts for all existing stickies that match 13361 // this filter. 13362 if (allSticky != null) { 13363 ArrayList receivers = new ArrayList(); 13364 receivers.add(bf); 13365 13366 int N = allSticky.size(); 13367 for (int i=0; i<N; i++) { 13368 Intent intent = (Intent)allSticky.get(i); 13369 BroadcastQueue queue = broadcastQueueForIntent(intent); 13370 BroadcastRecord r = new BroadcastRecord(queue, intent, null, 13371 null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0, 13372 null, null, false, true, true, -1); 13373 queue.enqueueParallelBroadcastLocked(r); 13374 queue.scheduleBroadcastsLocked(); 13375 } 13376 } 13377 13378 return sticky; 13379 } 13380 } 13381 13382 public void unregisterReceiver(IIntentReceiver receiver) { 13383 if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver); 13384 13385 final long origId = Binder.clearCallingIdentity(); 13386 try { 13387 boolean doTrim = false; 13388 13389 synchronized(this) { 13390 ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder()); 13391 if (rl != null) { 13392 if (rl.curBroadcast != null) { 13393 BroadcastRecord r = rl.curBroadcast; 13394 final boolean doNext = finishReceiverLocked( 13395 receiver.asBinder(), r.resultCode, r.resultData, 13396 r.resultExtras, r.resultAbort); 13397 if (doNext) { 13398 doTrim = true; 13399 r.queue.processNextBroadcast(false); 13400 } 13401 } 13402 13403 if (rl.app != null) { 13404 rl.app.receivers.remove(rl); 13405 } 13406 removeReceiverLocked(rl); 13407 if (rl.linkedToDeath) { 13408 rl.linkedToDeath = false; 13409 rl.receiver.asBinder().unlinkToDeath(rl, 0); 13410 } 13411 } 13412 } 13413 13414 // If we actually concluded any broadcasts, we might now be able 13415 // to trim the recipients' apps from our working set 13416 if (doTrim) { 13417 trimApplications(); 13418 return; 13419 } 13420 13421 } finally { 13422 Binder.restoreCallingIdentity(origId); 13423 } 13424 } 13425 13426 void removeReceiverLocked(ReceiverList rl) { 13427 mRegisteredReceivers.remove(rl.receiver.asBinder()); 13428 int N = rl.size(); 13429 for (int i=0; i<N; i++) { 13430 mReceiverResolver.removeFilter(rl.get(i)); 13431 } 13432 } 13433 13434 private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) { 13435 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 13436 ProcessRecord r = mLruProcesses.get(i); 13437 if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) { 13438 try { 13439 r.thread.dispatchPackageBroadcast(cmd, packages); 13440 } catch (RemoteException ex) { 13441 } 13442 } 13443 } 13444 } 13445 13446 private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType, 13447 int[] users) { 13448 List<ResolveInfo> receivers = null; 13449 try { 13450 HashSet<ComponentName> singleUserReceivers = null; 13451 boolean scannedFirstReceivers = false; 13452 for (int user : users) { 13453 List<ResolveInfo> newReceivers = AppGlobals.getPackageManager() 13454 .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user); 13455 if (user != 0 && newReceivers != null) { 13456 // If this is not the primary user, we need to check for 13457 // any receivers that should be filtered out. 13458 for (int i=0; i<newReceivers.size(); i++) { 13459 ResolveInfo ri = newReceivers.get(i); 13460 if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) { 13461 newReceivers.remove(i); 13462 i--; 13463 } 13464 } 13465 } 13466 if (newReceivers != null && newReceivers.size() == 0) { 13467 newReceivers = null; 13468 } 13469 if (receivers == null) { 13470 receivers = newReceivers; 13471 } else if (newReceivers != null) { 13472 // We need to concatenate the additional receivers 13473 // found with what we have do far. This would be easy, 13474 // but we also need to de-dup any receivers that are 13475 // singleUser. 13476 if (!scannedFirstReceivers) { 13477 // Collect any single user receivers we had already retrieved. 13478 scannedFirstReceivers = true; 13479 for (int i=0; i<receivers.size(); i++) { 13480 ResolveInfo ri = receivers.get(i); 13481 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 13482 ComponentName cn = new ComponentName( 13483 ri.activityInfo.packageName, ri.activityInfo.name); 13484 if (singleUserReceivers == null) { 13485 singleUserReceivers = new HashSet<ComponentName>(); 13486 } 13487 singleUserReceivers.add(cn); 13488 } 13489 } 13490 } 13491 // Add the new results to the existing results, tracking 13492 // and de-dupping single user receivers. 13493 for (int i=0; i<newReceivers.size(); i++) { 13494 ResolveInfo ri = newReceivers.get(i); 13495 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 13496 ComponentName cn = new ComponentName( 13497 ri.activityInfo.packageName, ri.activityInfo.name); 13498 if (singleUserReceivers == null) { 13499 singleUserReceivers = new HashSet<ComponentName>(); 13500 } 13501 if (!singleUserReceivers.contains(cn)) { 13502 singleUserReceivers.add(cn); 13503 receivers.add(ri); 13504 } 13505 } else { 13506 receivers.add(ri); 13507 } 13508 } 13509 } 13510 } 13511 } catch (RemoteException ex) { 13512 // pm is in same process, this will never happen. 13513 } 13514 return receivers; 13515 } 13516 13517 private final int broadcastIntentLocked(ProcessRecord callerApp, 13518 String callerPackage, Intent intent, String resolvedType, 13519 IIntentReceiver resultTo, int resultCode, String resultData, 13520 Bundle map, String requiredPermission, int appOp, 13521 boolean ordered, boolean sticky, int callingPid, int callingUid, 13522 int userId) { 13523 intent = new Intent(intent); 13524 13525 // By default broadcasts do not go to stopped apps. 13526 intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES); 13527 13528 if (DEBUG_BROADCAST_LIGHT) Slog.v( 13529 TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent 13530 + " ordered=" + ordered + " userid=" + userId); 13531 if ((resultTo != null) && !ordered) { 13532 Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!"); 13533 } 13534 13535 userId = handleIncomingUser(callingPid, callingUid, userId, 13536 true, false, "broadcast", callerPackage); 13537 13538 // Make sure that the user who is receiving this broadcast is started. 13539 // If not, we will just skip it. 13540 if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) { 13541 if (callingUid != Process.SYSTEM_UID || (intent.getFlags() 13542 & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) { 13543 Slog.w(TAG, "Skipping broadcast of " + intent 13544 + ": user " + userId + " is stopped"); 13545 return ActivityManager.BROADCAST_SUCCESS; 13546 } 13547 } 13548 13549 /* 13550 * Prevent non-system code (defined here to be non-persistent 13551 * processes) from sending protected broadcasts. 13552 */ 13553 int callingAppId = UserHandle.getAppId(callingUid); 13554 if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID 13555 || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID || 13556 callingUid == 0) { 13557 // Always okay. 13558 } else if (callerApp == null || !callerApp.persistent) { 13559 try { 13560 if (AppGlobals.getPackageManager().isProtectedBroadcast( 13561 intent.getAction())) { 13562 String msg = "Permission Denial: not allowed to send broadcast " 13563 + intent.getAction() + " from pid=" 13564 + callingPid + ", uid=" + callingUid; 13565 Slog.w(TAG, msg); 13566 throw new SecurityException(msg); 13567 } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) { 13568 // Special case for compatibility: we don't want apps to send this, 13569 // but historically it has not been protected and apps may be using it 13570 // to poke their own app widget. So, instead of making it protected, 13571 // just limit it to the caller. 13572 if (callerApp == null) { 13573 String msg = "Permission Denial: not allowed to send broadcast " 13574 + intent.getAction() + " from unknown caller."; 13575 Slog.w(TAG, msg); 13576 throw new SecurityException(msg); 13577 } else if (intent.getComponent() != null) { 13578 // They are good enough to send to an explicit component... verify 13579 // it is being sent to the calling app. 13580 if (!intent.getComponent().getPackageName().equals( 13581 callerApp.info.packageName)) { 13582 String msg = "Permission Denial: not allowed to send broadcast " 13583 + intent.getAction() + " to " 13584 + intent.getComponent().getPackageName() + " from " 13585 + callerApp.info.packageName; 13586 Slog.w(TAG, msg); 13587 throw new SecurityException(msg); 13588 } 13589 } else { 13590 // Limit broadcast to their own package. 13591 intent.setPackage(callerApp.info.packageName); 13592 } 13593 } 13594 } catch (RemoteException e) { 13595 Slog.w(TAG, "Remote exception", e); 13596 return ActivityManager.BROADCAST_SUCCESS; 13597 } 13598 } 13599 13600 // Handle special intents: if this broadcast is from the package 13601 // manager about a package being removed, we need to remove all of 13602 // its activities from the history stack. 13603 final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals( 13604 intent.getAction()); 13605 if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction()) 13606 || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction()) 13607 || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction()) 13608 || uidRemoved) { 13609 if (checkComponentPermission( 13610 android.Manifest.permission.BROADCAST_PACKAGE_REMOVED, 13611 callingPid, callingUid, -1, true) 13612 == PackageManager.PERMISSION_GRANTED) { 13613 if (uidRemoved) { 13614 final Bundle intentExtras = intent.getExtras(); 13615 final int uid = intentExtras != null 13616 ? intentExtras.getInt(Intent.EXTRA_UID) : -1; 13617 if (uid >= 0) { 13618 BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics(); 13619 synchronized (bs) { 13620 bs.removeUidStatsLocked(uid); 13621 } 13622 mAppOpsService.uidRemoved(uid); 13623 } 13624 } else { 13625 // If resources are unavailable just force stop all 13626 // those packages and flush the attribute cache as well. 13627 if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) { 13628 String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 13629 if (list != null && (list.length > 0)) { 13630 for (String pkg : list) { 13631 forceStopPackageLocked(pkg, -1, false, true, true, false, false, userId, 13632 "storage unmount"); 13633 } 13634 sendPackageBroadcastLocked( 13635 IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId); 13636 } 13637 } else { 13638 Uri data = intent.getData(); 13639 String ssp; 13640 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 13641 boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals( 13642 intent.getAction()); 13643 boolean fullUninstall = removed && 13644 !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false); 13645 if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) { 13646 forceStopPackageLocked(ssp, UserHandle.getAppId( 13647 intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true, 13648 false, fullUninstall, userId, 13649 removed ? "pkg removed" : "pkg changed"); 13650 } 13651 if (removed) { 13652 sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED, 13653 new String[] {ssp}, userId); 13654 if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) { 13655 mAppOpsService.packageRemoved( 13656 intent.getIntExtra(Intent.EXTRA_UID, -1), ssp); 13657 13658 // Remove all permissions granted from/to this package 13659 removeUriPermissionsForPackageLocked(ssp, userId, true); 13660 } 13661 } 13662 } 13663 } 13664 } 13665 } else { 13666 String msg = "Permission Denial: " + intent.getAction() 13667 + " broadcast from " + callerPackage + " (pid=" + callingPid 13668 + ", uid=" + callingUid + ")" 13669 + " requires " 13670 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED; 13671 Slog.w(TAG, msg); 13672 throw new SecurityException(msg); 13673 } 13674 13675 // Special case for adding a package: by default turn on compatibility 13676 // mode. 13677 } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) { 13678 Uri data = intent.getData(); 13679 String ssp; 13680 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 13681 mCompatModePackages.handlePackageAddedLocked(ssp, 13682 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)); 13683 } 13684 } 13685 13686 /* 13687 * If this is the time zone changed action, queue up a message that will reset the timezone 13688 * of all currently running processes. This message will get queued up before the broadcast 13689 * happens. 13690 */ 13691 if (Intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) { 13692 mHandler.sendEmptyMessage(UPDATE_TIME_ZONE); 13693 } 13694 13695 /* 13696 * If the user set the time, let all running processes know. 13697 */ 13698 if (Intent.ACTION_TIME_CHANGED.equals(intent.getAction())) { 13699 final int is24Hour = intent.getBooleanExtra( 13700 Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1 : 0; 13701 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0)); 13702 } 13703 13704 if (Intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) { 13705 mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG); 13706 } 13707 13708 if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) { 13709 ProxyProperties proxy = intent.getParcelableExtra("proxy"); 13710 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy)); 13711 } 13712 13713 // Add to the sticky list if requested. 13714 if (sticky) { 13715 if (checkPermission(android.Manifest.permission.BROADCAST_STICKY, 13716 callingPid, callingUid) 13717 != PackageManager.PERMISSION_GRANTED) { 13718 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid=" 13719 + callingPid + ", uid=" + callingUid 13720 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 13721 Slog.w(TAG, msg); 13722 throw new SecurityException(msg); 13723 } 13724 if (requiredPermission != null) { 13725 Slog.w(TAG, "Can't broadcast sticky intent " + intent 13726 + " and enforce permission " + requiredPermission); 13727 return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION; 13728 } 13729 if (intent.getComponent() != null) { 13730 throw new SecurityException( 13731 "Sticky broadcasts can't target a specific component"); 13732 } 13733 // We use userId directly here, since the "all" target is maintained 13734 // as a separate set of sticky broadcasts. 13735 if (userId != UserHandle.USER_ALL) { 13736 // But first, if this is not a broadcast to all users, then 13737 // make sure it doesn't conflict with an existing broadcast to 13738 // all users. 13739 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get( 13740 UserHandle.USER_ALL); 13741 if (stickies != null) { 13742 ArrayList<Intent> list = stickies.get(intent.getAction()); 13743 if (list != null) { 13744 int N = list.size(); 13745 int i; 13746 for (i=0; i<N; i++) { 13747 if (intent.filterEquals(list.get(i))) { 13748 throw new IllegalArgumentException( 13749 "Sticky broadcast " + intent + " for user " 13750 + userId + " conflicts with existing global broadcast"); 13751 } 13752 } 13753 } 13754 } 13755 } 13756 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 13757 if (stickies == null) { 13758 stickies = new ArrayMap<String, ArrayList<Intent>>(); 13759 mStickyBroadcasts.put(userId, stickies); 13760 } 13761 ArrayList<Intent> list = stickies.get(intent.getAction()); 13762 if (list == null) { 13763 list = new ArrayList<Intent>(); 13764 stickies.put(intent.getAction(), list); 13765 } 13766 int N = list.size(); 13767 int i; 13768 for (i=0; i<N; i++) { 13769 if (intent.filterEquals(list.get(i))) { 13770 // This sticky already exists, replace it. 13771 list.set(i, new Intent(intent)); 13772 break; 13773 } 13774 } 13775 if (i >= N) { 13776 list.add(new Intent(intent)); 13777 } 13778 } 13779 13780 int[] users; 13781 if (userId == UserHandle.USER_ALL) { 13782 // Caller wants broadcast to go to all started users. 13783 users = mStartedUserArray; 13784 } else { 13785 // Caller wants broadcast to go to one specific user. 13786 users = new int[] {userId}; 13787 } 13788 13789 // Figure out who all will receive this broadcast. 13790 List receivers = null; 13791 List<BroadcastFilter> registeredReceivers = null; 13792 // Need to resolve the intent to interested receivers... 13793 if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) 13794 == 0) { 13795 receivers = collectReceiverComponents(intent, resolvedType, users); 13796 } 13797 if (intent.getComponent() == null) { 13798 registeredReceivers = mReceiverResolver.queryIntent(intent, 13799 resolvedType, false, userId); 13800 } 13801 13802 final boolean replacePending = 13803 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0; 13804 13805 if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction() 13806 + " replacePending=" + replacePending); 13807 13808 int NR = registeredReceivers != null ? registeredReceivers.size() : 0; 13809 if (!ordered && NR > 0) { 13810 // If we are not serializing this broadcast, then send the 13811 // registered receivers separately so they don't wait for the 13812 // components to be launched. 13813 final BroadcastQueue queue = broadcastQueueForIntent(intent); 13814 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 13815 callerPackage, callingPid, callingUid, resolvedType, requiredPermission, 13816 appOp, registeredReceivers, resultTo, resultCode, resultData, map, 13817 ordered, sticky, false, userId); 13818 if (DEBUG_BROADCAST) Slog.v( 13819 TAG, "Enqueueing parallel broadcast " + r); 13820 final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r); 13821 if (!replaced) { 13822 queue.enqueueParallelBroadcastLocked(r); 13823 queue.scheduleBroadcastsLocked(); 13824 } 13825 registeredReceivers = null; 13826 NR = 0; 13827 } 13828 13829 // Merge into one list. 13830 int ir = 0; 13831 if (receivers != null) { 13832 // A special case for PACKAGE_ADDED: do not allow the package 13833 // being added to see this broadcast. This prevents them from 13834 // using this as a back door to get run as soon as they are 13835 // installed. Maybe in the future we want to have a special install 13836 // broadcast or such for apps, but we'd like to deliberately make 13837 // this decision. 13838 String skipPackages[] = null; 13839 if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction()) 13840 || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction()) 13841 || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) { 13842 Uri data = intent.getData(); 13843 if (data != null) { 13844 String pkgName = data.getSchemeSpecificPart(); 13845 if (pkgName != null) { 13846 skipPackages = new String[] { pkgName }; 13847 } 13848 } 13849 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) { 13850 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 13851 } 13852 if (skipPackages != null && (skipPackages.length > 0)) { 13853 for (String skipPackage : skipPackages) { 13854 if (skipPackage != null) { 13855 int NT = receivers.size(); 13856 for (int it=0; it<NT; it++) { 13857 ResolveInfo curt = (ResolveInfo)receivers.get(it); 13858 if (curt.activityInfo.packageName.equals(skipPackage)) { 13859 receivers.remove(it); 13860 it--; 13861 NT--; 13862 } 13863 } 13864 } 13865 } 13866 } 13867 13868 int NT = receivers != null ? receivers.size() : 0; 13869 int it = 0; 13870 ResolveInfo curt = null; 13871 BroadcastFilter curr = null; 13872 while (it < NT && ir < NR) { 13873 if (curt == null) { 13874 curt = (ResolveInfo)receivers.get(it); 13875 } 13876 if (curr == null) { 13877 curr = registeredReceivers.get(ir); 13878 } 13879 if (curr.getPriority() >= curt.priority) { 13880 // Insert this broadcast record into the final list. 13881 receivers.add(it, curr); 13882 ir++; 13883 curr = null; 13884 it++; 13885 NT++; 13886 } else { 13887 // Skip to the next ResolveInfo in the final list. 13888 it++; 13889 curt = null; 13890 } 13891 } 13892 } 13893 while (ir < NR) { 13894 if (receivers == null) { 13895 receivers = new ArrayList(); 13896 } 13897 receivers.add(registeredReceivers.get(ir)); 13898 ir++; 13899 } 13900 13901 if ((receivers != null && receivers.size() > 0) 13902 || resultTo != null) { 13903 BroadcastQueue queue = broadcastQueueForIntent(intent); 13904 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 13905 callerPackage, callingPid, callingUid, resolvedType, 13906 requiredPermission, appOp, receivers, resultTo, resultCode, 13907 resultData, map, ordered, sticky, false, userId); 13908 if (DEBUG_BROADCAST) Slog.v( 13909 TAG, "Enqueueing ordered broadcast " + r 13910 + ": prev had " + queue.mOrderedBroadcasts.size()); 13911 if (DEBUG_BROADCAST) { 13912 int seq = r.intent.getIntExtra("seq", -1); 13913 Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq); 13914 } 13915 boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r); 13916 if (!replaced) { 13917 queue.enqueueOrderedBroadcastLocked(r); 13918 queue.scheduleBroadcastsLocked(); 13919 } 13920 } 13921 13922 return ActivityManager.BROADCAST_SUCCESS; 13923 } 13924 13925 final Intent verifyBroadcastLocked(Intent intent) { 13926 // Refuse possible leaked file descriptors 13927 if (intent != null && intent.hasFileDescriptors() == true) { 13928 throw new IllegalArgumentException("File descriptors passed in Intent"); 13929 } 13930 13931 int flags = intent.getFlags(); 13932 13933 if (!mProcessesReady) { 13934 // if the caller really truly claims to know what they're doing, go 13935 // ahead and allow the broadcast without launching any receivers 13936 if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) { 13937 intent = new Intent(intent); 13938 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 13939 } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) { 13940 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent 13941 + " before boot completion"); 13942 throw new IllegalStateException("Cannot broadcast before boot completed"); 13943 } 13944 } 13945 13946 if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 13947 throw new IllegalArgumentException( 13948 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 13949 } 13950 13951 return intent; 13952 } 13953 13954 public final int broadcastIntent(IApplicationThread caller, 13955 Intent intent, String resolvedType, IIntentReceiver resultTo, 13956 int resultCode, String resultData, Bundle map, 13957 String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) { 13958 enforceNotIsolatedCaller("broadcastIntent"); 13959 synchronized(this) { 13960 intent = verifyBroadcastLocked(intent); 13961 13962 final ProcessRecord callerApp = getRecordForAppLocked(caller); 13963 final int callingPid = Binder.getCallingPid(); 13964 final int callingUid = Binder.getCallingUid(); 13965 final long origId = Binder.clearCallingIdentity(); 13966 int res = broadcastIntentLocked(callerApp, 13967 callerApp != null ? callerApp.info.packageName : null, 13968 intent, resolvedType, resultTo, 13969 resultCode, resultData, map, requiredPermission, appOp, serialized, sticky, 13970 callingPid, callingUid, userId); 13971 Binder.restoreCallingIdentity(origId); 13972 return res; 13973 } 13974 } 13975 13976 int broadcastIntentInPackage(String packageName, int uid, 13977 Intent intent, String resolvedType, IIntentReceiver resultTo, 13978 int resultCode, String resultData, Bundle map, 13979 String requiredPermission, boolean serialized, boolean sticky, int userId) { 13980 synchronized(this) { 13981 intent = verifyBroadcastLocked(intent); 13982 13983 final long origId = Binder.clearCallingIdentity(); 13984 int res = broadcastIntentLocked(null, packageName, intent, resolvedType, 13985 resultTo, resultCode, resultData, map, requiredPermission, 13986 AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId); 13987 Binder.restoreCallingIdentity(origId); 13988 return res; 13989 } 13990 } 13991 13992 public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) { 13993 // Refuse possible leaked file descriptors 13994 if (intent != null && intent.hasFileDescriptors() == true) { 13995 throw new IllegalArgumentException("File descriptors passed in Intent"); 13996 } 13997 13998 userId = handleIncomingUser(Binder.getCallingPid(), 13999 Binder.getCallingUid(), userId, true, false, "removeStickyBroadcast", null); 14000 14001 synchronized(this) { 14002 if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY) 14003 != PackageManager.PERMISSION_GRANTED) { 14004 String msg = "Permission Denial: unbroadcastIntent() from pid=" 14005 + Binder.getCallingPid() 14006 + ", uid=" + Binder.getCallingUid() 14007 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 14008 Slog.w(TAG, msg); 14009 throw new SecurityException(msg); 14010 } 14011 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 14012 if (stickies != null) { 14013 ArrayList<Intent> list = stickies.get(intent.getAction()); 14014 if (list != null) { 14015 int N = list.size(); 14016 int i; 14017 for (i=0; i<N; i++) { 14018 if (intent.filterEquals(list.get(i))) { 14019 list.remove(i); 14020 break; 14021 } 14022 } 14023 if (list.size() <= 0) { 14024 stickies.remove(intent.getAction()); 14025 } 14026 } 14027 if (stickies.size() <= 0) { 14028 mStickyBroadcasts.remove(userId); 14029 } 14030 } 14031 } 14032 } 14033 14034 private final boolean finishReceiverLocked(IBinder receiver, int resultCode, 14035 String resultData, Bundle resultExtras, boolean resultAbort) { 14036 final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver); 14037 if (r == null) { 14038 Slog.w(TAG, "finishReceiver called but not found on queue"); 14039 return false; 14040 } 14041 14042 return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false); 14043 } 14044 14045 void backgroundServicesFinishedLocked(int userId) { 14046 for (BroadcastQueue queue : mBroadcastQueues) { 14047 queue.backgroundServicesFinishedLocked(userId); 14048 } 14049 } 14050 14051 public void finishReceiver(IBinder who, int resultCode, String resultData, 14052 Bundle resultExtras, boolean resultAbort) { 14053 if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who); 14054 14055 // Refuse possible leaked file descriptors 14056 if (resultExtras != null && resultExtras.hasFileDescriptors()) { 14057 throw new IllegalArgumentException("File descriptors passed in Bundle"); 14058 } 14059 14060 final long origId = Binder.clearCallingIdentity(); 14061 try { 14062 boolean doNext = false; 14063 BroadcastRecord r; 14064 14065 synchronized(this) { 14066 r = broadcastRecordForReceiverLocked(who); 14067 if (r != null) { 14068 doNext = r.queue.finishReceiverLocked(r, resultCode, 14069 resultData, resultExtras, resultAbort, true); 14070 } 14071 } 14072 14073 if (doNext) { 14074 r.queue.processNextBroadcast(false); 14075 } 14076 trimApplications(); 14077 } finally { 14078 Binder.restoreCallingIdentity(origId); 14079 } 14080 } 14081 14082 // ========================================================= 14083 // INSTRUMENTATION 14084 // ========================================================= 14085 14086 public boolean startInstrumentation(ComponentName className, 14087 String profileFile, int flags, Bundle arguments, 14088 IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection, 14089 int userId) { 14090 enforceNotIsolatedCaller("startInstrumentation"); 14091 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 14092 userId, false, true, "startInstrumentation", null); 14093 // Refuse possible leaked file descriptors 14094 if (arguments != null && arguments.hasFileDescriptors()) { 14095 throw new IllegalArgumentException("File descriptors passed in Bundle"); 14096 } 14097 14098 synchronized(this) { 14099 InstrumentationInfo ii = null; 14100 ApplicationInfo ai = null; 14101 try { 14102 ii = mContext.getPackageManager().getInstrumentationInfo( 14103 className, STOCK_PM_FLAGS); 14104 ai = AppGlobals.getPackageManager().getApplicationInfo( 14105 ii.targetPackage, STOCK_PM_FLAGS, userId); 14106 } catch (PackageManager.NameNotFoundException e) { 14107 } catch (RemoteException e) { 14108 } 14109 if (ii == null) { 14110 reportStartInstrumentationFailure(watcher, className, 14111 "Unable to find instrumentation info for: " + className); 14112 return false; 14113 } 14114 if (ai == null) { 14115 reportStartInstrumentationFailure(watcher, className, 14116 "Unable to find instrumentation target package: " + ii.targetPackage); 14117 return false; 14118 } 14119 14120 int match = mContext.getPackageManager().checkSignatures( 14121 ii.targetPackage, ii.packageName); 14122 if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) { 14123 String msg = "Permission Denial: starting instrumentation " 14124 + className + " from pid=" 14125 + Binder.getCallingPid() 14126 + ", uid=" + Binder.getCallingPid() 14127 + " not allowed because package " + ii.packageName 14128 + " does not have a signature matching the target " 14129 + ii.targetPackage; 14130 reportStartInstrumentationFailure(watcher, className, msg); 14131 throw new SecurityException(msg); 14132 } 14133 14134 final long origId = Binder.clearCallingIdentity(); 14135 // Instrumentation can kill and relaunch even persistent processes 14136 forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId, 14137 "start instr"); 14138 ProcessRecord app = addAppLocked(ai, false); 14139 app.instrumentationClass = className; 14140 app.instrumentationInfo = ai; 14141 app.instrumentationProfileFile = profileFile; 14142 app.instrumentationArguments = arguments; 14143 app.instrumentationWatcher = watcher; 14144 app.instrumentationUiAutomationConnection = uiAutomationConnection; 14145 app.instrumentationResultClass = className; 14146 Binder.restoreCallingIdentity(origId); 14147 } 14148 14149 return true; 14150 } 14151 14152 /** 14153 * Report errors that occur while attempting to start Instrumentation. Always writes the 14154 * error to the logs, but if somebody is watching, send the report there too. This enables 14155 * the "am" command to report errors with more information. 14156 * 14157 * @param watcher The IInstrumentationWatcher. Null if there isn't one. 14158 * @param cn The component name of the instrumentation. 14159 * @param report The error report. 14160 */ 14161 private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher, 14162 ComponentName cn, String report) { 14163 Slog.w(TAG, report); 14164 try { 14165 if (watcher != null) { 14166 Bundle results = new Bundle(); 14167 results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService"); 14168 results.putString("Error", report); 14169 watcher.instrumentationStatus(cn, -1, results); 14170 } 14171 } catch (RemoteException e) { 14172 Slog.w(TAG, e); 14173 } 14174 } 14175 14176 void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) { 14177 if (app.instrumentationWatcher != null) { 14178 try { 14179 // NOTE: IInstrumentationWatcher *must* be oneway here 14180 app.instrumentationWatcher.instrumentationFinished( 14181 app.instrumentationClass, 14182 resultCode, 14183 results); 14184 } catch (RemoteException e) { 14185 } 14186 } 14187 if (app.instrumentationUiAutomationConnection != null) { 14188 try { 14189 app.instrumentationUiAutomationConnection.shutdown(); 14190 } catch (RemoteException re) { 14191 /* ignore */ 14192 } 14193 // Only a UiAutomation can set this flag and now that 14194 // it is finished we make sure it is reset to its default. 14195 mUserIsMonkey = false; 14196 } 14197 app.instrumentationWatcher = null; 14198 app.instrumentationUiAutomationConnection = null; 14199 app.instrumentationClass = null; 14200 app.instrumentationInfo = null; 14201 app.instrumentationProfileFile = null; 14202 app.instrumentationArguments = null; 14203 14204 forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId, 14205 "finished inst"); 14206 } 14207 14208 public void finishInstrumentation(IApplicationThread target, 14209 int resultCode, Bundle results) { 14210 int userId = UserHandle.getCallingUserId(); 14211 // Refuse possible leaked file descriptors 14212 if (results != null && results.hasFileDescriptors()) { 14213 throw new IllegalArgumentException("File descriptors passed in Intent"); 14214 } 14215 14216 synchronized(this) { 14217 ProcessRecord app = getRecordForAppLocked(target); 14218 if (app == null) { 14219 Slog.w(TAG, "finishInstrumentation: no app for " + target); 14220 return; 14221 } 14222 final long origId = Binder.clearCallingIdentity(); 14223 finishInstrumentationLocked(app, resultCode, results); 14224 Binder.restoreCallingIdentity(origId); 14225 } 14226 } 14227 14228 // ========================================================= 14229 // CONFIGURATION 14230 // ========================================================= 14231 14232 public ConfigurationInfo getDeviceConfigurationInfo() { 14233 ConfigurationInfo config = new ConfigurationInfo(); 14234 synchronized (this) { 14235 config.reqTouchScreen = mConfiguration.touchscreen; 14236 config.reqKeyboardType = mConfiguration.keyboard; 14237 config.reqNavigation = mConfiguration.navigation; 14238 if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD 14239 || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) { 14240 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV; 14241 } 14242 if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED 14243 && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) { 14244 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD; 14245 } 14246 config.reqGlEsVersion = GL_ES_VERSION; 14247 } 14248 return config; 14249 } 14250 14251 ActivityStack getFocusedStack() { 14252 return mStackSupervisor.getFocusedStack(); 14253 } 14254 14255 public Configuration getConfiguration() { 14256 Configuration ci; 14257 synchronized(this) { 14258 ci = new Configuration(mConfiguration); 14259 } 14260 return ci; 14261 } 14262 14263 public void updatePersistentConfiguration(Configuration values) { 14264 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 14265 "updateConfiguration()"); 14266 enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS, 14267 "updateConfiguration()"); 14268 if (values == null) { 14269 throw new NullPointerException("Configuration must not be null"); 14270 } 14271 14272 synchronized(this) { 14273 final long origId = Binder.clearCallingIdentity(); 14274 updateConfigurationLocked(values, null, true, false); 14275 Binder.restoreCallingIdentity(origId); 14276 } 14277 } 14278 14279 public void updateConfiguration(Configuration values) { 14280 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 14281 "updateConfiguration()"); 14282 14283 synchronized(this) { 14284 if (values == null && mWindowManager != null) { 14285 // sentinel: fetch the current configuration from the window manager 14286 values = mWindowManager.computeNewConfiguration(); 14287 } 14288 14289 if (mWindowManager != null) { 14290 mProcessList.applyDisplaySize(mWindowManager); 14291 } 14292 14293 final long origId = Binder.clearCallingIdentity(); 14294 if (values != null) { 14295 Settings.System.clearConfiguration(values); 14296 } 14297 updateConfigurationLocked(values, null, false, false); 14298 Binder.restoreCallingIdentity(origId); 14299 } 14300 } 14301 14302 /** 14303 * Do either or both things: (1) change the current configuration, and (2) 14304 * make sure the given activity is running with the (now) current 14305 * configuration. Returns true if the activity has been left running, or 14306 * false if <var>starting</var> is being destroyed to match the new 14307 * configuration. 14308 * @param persistent TODO 14309 */ 14310 boolean updateConfigurationLocked(Configuration values, 14311 ActivityRecord starting, boolean persistent, boolean initLocale) { 14312 int changes = 0; 14313 14314 if (values != null) { 14315 Configuration newConfig = new Configuration(mConfiguration); 14316 changes = newConfig.updateFrom(values); 14317 if (changes != 0) { 14318 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) { 14319 Slog.i(TAG, "Updating configuration to: " + values); 14320 } 14321 14322 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes); 14323 14324 if (values.locale != null && !initLocale) { 14325 saveLocaleLocked(values.locale, 14326 !values.locale.equals(mConfiguration.locale), 14327 values.userSetLocale); 14328 } 14329 14330 mConfigurationSeq++; 14331 if (mConfigurationSeq <= 0) { 14332 mConfigurationSeq = 1; 14333 } 14334 newConfig.seq = mConfigurationSeq; 14335 mConfiguration = newConfig; 14336 Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig); 14337 14338 final Configuration configCopy = new Configuration(mConfiguration); 14339 14340 // TODO: If our config changes, should we auto dismiss any currently 14341 // showing dialogs? 14342 mShowDialogs = shouldShowDialogs(newConfig); 14343 14344 AttributeCache ac = AttributeCache.instance(); 14345 if (ac != null) { 14346 ac.updateConfiguration(configCopy); 14347 } 14348 14349 // Make sure all resources in our process are updated 14350 // right now, so that anyone who is going to retrieve 14351 // resource values after we return will be sure to get 14352 // the new ones. This is especially important during 14353 // boot, where the first config change needs to guarantee 14354 // all resources have that config before following boot 14355 // code is executed. 14356 mSystemThread.applyConfigurationToResources(configCopy); 14357 14358 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) { 14359 Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG); 14360 msg.obj = new Configuration(configCopy); 14361 mHandler.sendMessage(msg); 14362 } 14363 14364 for (int i=mLruProcesses.size()-1; i>=0; i--) { 14365 ProcessRecord app = mLruProcesses.get(i); 14366 try { 14367 if (app.thread != null) { 14368 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc " 14369 + app.processName + " new config " + mConfiguration); 14370 app.thread.scheduleConfigurationChanged(configCopy); 14371 } 14372 } catch (Exception e) { 14373 } 14374 } 14375 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED); 14376 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 14377 | Intent.FLAG_RECEIVER_REPLACE_PENDING 14378 | Intent.FLAG_RECEIVER_FOREGROUND); 14379 broadcastIntentLocked(null, null, intent, null, null, 0, null, null, 14380 null, AppOpsManager.OP_NONE, false, false, MY_PID, 14381 Process.SYSTEM_UID, UserHandle.USER_ALL); 14382 if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) { 14383 intent = new Intent(Intent.ACTION_LOCALE_CHANGED); 14384 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 14385 broadcastIntentLocked(null, null, intent, 14386 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 14387 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 14388 } 14389 } 14390 } 14391 14392 boolean kept = true; 14393 final ActivityStack mainStack = mStackSupervisor.getFocusedStack(); 14394 // mainStack is null during startup. 14395 if (mainStack != null) { 14396 if (changes != 0 && starting == null) { 14397 // If the configuration changed, and the caller is not already 14398 // in the process of starting an activity, then find the top 14399 // activity to check if its configuration needs to change. 14400 starting = mainStack.topRunningActivityLocked(null); 14401 } 14402 14403 if (starting != null) { 14404 kept = mainStack.ensureActivityConfigurationLocked(starting, changes); 14405 // And we need to make sure at this point that all other activities 14406 // are made visible with the correct configuration. 14407 mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes); 14408 } 14409 } 14410 14411 if (values != null && mWindowManager != null) { 14412 mWindowManager.setNewConfiguration(mConfiguration); 14413 } 14414 14415 return kept; 14416 } 14417 14418 /** 14419 * Decide based on the configuration whether we should shouw the ANR, 14420 * crash, etc dialogs. The idea is that if there is no affordnace to 14421 * press the on-screen buttons, we shouldn't show the dialog. 14422 * 14423 * A thought: SystemUI might also want to get told about this, the Power 14424 * dialog / global actions also might want different behaviors. 14425 */ 14426 private static final boolean shouldShowDialogs(Configuration config) { 14427 return !(config.keyboard == Configuration.KEYBOARD_NOKEYS 14428 && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH); 14429 } 14430 14431 /** 14432 * Save the locale. You must be inside a synchronized (this) block. 14433 */ 14434 private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) { 14435 if(isDiff) { 14436 SystemProperties.set("user.language", l.getLanguage()); 14437 SystemProperties.set("user.region", l.getCountry()); 14438 } 14439 14440 if(isPersist) { 14441 SystemProperties.set("persist.sys.language", l.getLanguage()); 14442 SystemProperties.set("persist.sys.country", l.getCountry()); 14443 SystemProperties.set("persist.sys.localevar", l.getVariant()); 14444 } 14445 } 14446 14447 @Override 14448 public boolean targetTaskAffinityMatchesActivity(IBinder token, String destAffinity) { 14449 ActivityRecord srec = ActivityRecord.forToken(token); 14450 return srec != null && srec.task.affinity != null && 14451 srec.task.affinity.equals(destAffinity); 14452 } 14453 14454 public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode, 14455 Intent resultData) { 14456 14457 synchronized (this) { 14458 final ActivityStack stack = ActivityRecord.getStackLocked(token); 14459 if (stack != null) { 14460 return stack.navigateUpToLocked(token, destIntent, resultCode, resultData); 14461 } 14462 return false; 14463 } 14464 } 14465 14466 public int getLaunchedFromUid(IBinder activityToken) { 14467 ActivityRecord srec = ActivityRecord.forToken(activityToken); 14468 if (srec == null) { 14469 return -1; 14470 } 14471 return srec.launchedFromUid; 14472 } 14473 14474 public String getLaunchedFromPackage(IBinder activityToken) { 14475 ActivityRecord srec = ActivityRecord.forToken(activityToken); 14476 if (srec == null) { 14477 return null; 14478 } 14479 return srec.launchedFromPackage; 14480 } 14481 14482 // ========================================================= 14483 // LIFETIME MANAGEMENT 14484 // ========================================================= 14485 14486 // Returns which broadcast queue the app is the current [or imminent] receiver 14487 // on, or 'null' if the app is not an active broadcast recipient. 14488 private BroadcastQueue isReceivingBroadcast(ProcessRecord app) { 14489 BroadcastRecord r = app.curReceiver; 14490 if (r != null) { 14491 return r.queue; 14492 } 14493 14494 // It's not the current receiver, but it might be starting up to become one 14495 synchronized (this) { 14496 for (BroadcastQueue queue : mBroadcastQueues) { 14497 r = queue.mPendingBroadcast; 14498 if (r != null && r.curApp == app) { 14499 // found it; report which queue it's in 14500 return queue; 14501 } 14502 } 14503 } 14504 14505 return null; 14506 } 14507 14508 private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP, 14509 boolean doingAll, long now) { 14510 if (mAdjSeq == app.adjSeq) { 14511 // This adjustment has already been computed. 14512 return app.curRawAdj; 14513 } 14514 14515 if (app.thread == null) { 14516 app.adjSeq = mAdjSeq; 14517 app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 14518 app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 14519 return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ); 14520 } 14521 14522 app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN; 14523 app.adjSource = null; 14524 app.adjTarget = null; 14525 app.empty = false; 14526 app.cached = false; 14527 14528 final int activitiesSize = app.activities.size(); 14529 14530 if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) { 14531 // The max adjustment doesn't allow this app to be anything 14532 // below foreground, so it is not worth doing work for it. 14533 app.adjType = "fixed"; 14534 app.adjSeq = mAdjSeq; 14535 app.curRawAdj = app.maxAdj; 14536 app.foregroundActivities = false; 14537 app.keeping = true; 14538 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT; 14539 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT; 14540 // System process can do UI, and when they do we want to have 14541 // them trim their memory after the user leaves the UI. To 14542 // facilitate this, here we need to determine whether or not it 14543 // is currently showing UI. 14544 app.systemNoUi = true; 14545 if (app == TOP_APP) { 14546 app.systemNoUi = false; 14547 } else if (activitiesSize > 0) { 14548 for (int j = 0; j < activitiesSize; j++) { 14549 final ActivityRecord r = app.activities.get(j); 14550 if (r.visible) { 14551 app.systemNoUi = false; 14552 } 14553 } 14554 } 14555 if (!app.systemNoUi) { 14556 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI; 14557 } 14558 return (app.curAdj=app.maxAdj); 14559 } 14560 14561 app.keeping = false; 14562 app.systemNoUi = false; 14563 14564 // Determine the importance of the process, starting with most 14565 // important to least, and assign an appropriate OOM adjustment. 14566 int adj; 14567 int schedGroup; 14568 int procState; 14569 boolean foregroundActivities = false; 14570 boolean interesting = false; 14571 BroadcastQueue queue; 14572 if (app == TOP_APP) { 14573 // The last app on the list is the foreground app. 14574 adj = ProcessList.FOREGROUND_APP_ADJ; 14575 schedGroup = Process.THREAD_GROUP_DEFAULT; 14576 app.adjType = "top-activity"; 14577 foregroundActivities = true; 14578 interesting = true; 14579 procState = ActivityManager.PROCESS_STATE_TOP; 14580 } else if (app.instrumentationClass != null) { 14581 // Don't want to kill running instrumentation. 14582 adj = ProcessList.FOREGROUND_APP_ADJ; 14583 schedGroup = Process.THREAD_GROUP_DEFAULT; 14584 app.adjType = "instrumentation"; 14585 interesting = true; 14586 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14587 } else if ((queue = isReceivingBroadcast(app)) != null) { 14588 // An app that is currently receiving a broadcast also 14589 // counts as being in the foreground for OOM killer purposes. 14590 // It's placed in a sched group based on the nature of the 14591 // broadcast as reflected by which queue it's active in. 14592 adj = ProcessList.FOREGROUND_APP_ADJ; 14593 schedGroup = (queue == mFgBroadcastQueue) 14594 ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 14595 app.adjType = "broadcast"; 14596 procState = ActivityManager.PROCESS_STATE_RECEIVER; 14597 } else if (app.executingServices.size() > 0) { 14598 // An app that is currently executing a service callback also 14599 // counts as being in the foreground. 14600 adj = ProcessList.FOREGROUND_APP_ADJ; 14601 schedGroup = app.execServicesFg ? 14602 Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 14603 app.adjType = "exec-service"; 14604 procState = ActivityManager.PROCESS_STATE_SERVICE; 14605 //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app); 14606 } else { 14607 // As far as we know the process is empty. We may change our mind later. 14608 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 14609 // At this point we don't actually know the adjustment. Use the cached adj 14610 // value that the caller wants us to. 14611 adj = cachedAdj; 14612 procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 14613 app.cached = true; 14614 app.empty = true; 14615 app.adjType = "cch-empty"; 14616 } 14617 14618 // Examine all activities if not already foreground. 14619 if (!foregroundActivities && activitiesSize > 0) { 14620 for (int j = 0; j < activitiesSize; j++) { 14621 final ActivityRecord r = app.activities.get(j); 14622 if (r.app != app) { 14623 Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc " 14624 + app + "?!?"); 14625 continue; 14626 } 14627 if (r.visible) { 14628 // App has a visible activity; only upgrade adjustment. 14629 if (adj > ProcessList.VISIBLE_APP_ADJ) { 14630 adj = ProcessList.VISIBLE_APP_ADJ; 14631 app.adjType = "visible"; 14632 } 14633 if (procState > ActivityManager.PROCESS_STATE_TOP) { 14634 procState = ActivityManager.PROCESS_STATE_TOP; 14635 } 14636 schedGroup = Process.THREAD_GROUP_DEFAULT; 14637 app.cached = false; 14638 app.empty = false; 14639 foregroundActivities = true; 14640 break; 14641 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) { 14642 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14643 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 14644 app.adjType = "pausing"; 14645 } 14646 if (procState > ActivityManager.PROCESS_STATE_TOP) { 14647 procState = ActivityManager.PROCESS_STATE_TOP; 14648 } 14649 schedGroup = Process.THREAD_GROUP_DEFAULT; 14650 app.cached = false; 14651 app.empty = false; 14652 foregroundActivities = true; 14653 } else if (r.state == ActivityState.STOPPING) { 14654 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14655 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 14656 app.adjType = "stopping"; 14657 } 14658 // For the process state, we will at this point consider the 14659 // process to be cached. It will be cached either as an activity 14660 // or empty depending on whether the activity is finishing. We do 14661 // this so that we can treat the process as cached for purposes of 14662 // memory trimming (determing current memory level, trim command to 14663 // send to process) since there can be an arbitrary number of stopping 14664 // processes and they should soon all go into the cached state. 14665 if (!r.finishing) { 14666 if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 14667 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 14668 } 14669 } 14670 app.cached = false; 14671 app.empty = false; 14672 foregroundActivities = true; 14673 } else { 14674 if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 14675 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 14676 app.adjType = "cch-act"; 14677 } 14678 } 14679 } 14680 } 14681 14682 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14683 if (app.foregroundServices) { 14684 // The user is aware of this app, so make it visible. 14685 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 14686 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14687 app.cached = false; 14688 app.adjType = "fg-service"; 14689 schedGroup = Process.THREAD_GROUP_DEFAULT; 14690 } else if (app.forcingToForeground != null) { 14691 // The user is aware of this app, so make it visible. 14692 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 14693 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14694 app.cached = false; 14695 app.adjType = "force-fg"; 14696 app.adjSource = app.forcingToForeground; 14697 schedGroup = Process.THREAD_GROUP_DEFAULT; 14698 } 14699 } 14700 14701 if (app.foregroundServices) { 14702 interesting = true; 14703 } 14704 14705 if (app == mHeavyWeightProcess) { 14706 if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) { 14707 // We don't want to kill the current heavy-weight process. 14708 adj = ProcessList.HEAVY_WEIGHT_APP_ADJ; 14709 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 14710 app.cached = false; 14711 app.adjType = "heavy"; 14712 } 14713 if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) { 14714 procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT; 14715 } 14716 } 14717 14718 if (app == mHomeProcess) { 14719 if (adj > ProcessList.HOME_APP_ADJ) { 14720 // This process is hosting what we currently consider to be the 14721 // home app, so we don't want to let it go into the background. 14722 adj = ProcessList.HOME_APP_ADJ; 14723 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 14724 app.cached = false; 14725 app.adjType = "home"; 14726 } 14727 if (procState > ActivityManager.PROCESS_STATE_HOME) { 14728 procState = ActivityManager.PROCESS_STATE_HOME; 14729 } 14730 } 14731 14732 if (app == mPreviousProcess && app.activities.size() > 0) { 14733 if (adj > ProcessList.PREVIOUS_APP_ADJ) { 14734 // This was the previous process that showed UI to the user. 14735 // We want to try to keep it around more aggressively, to give 14736 // a good experience around switching between two apps. 14737 adj = ProcessList.PREVIOUS_APP_ADJ; 14738 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 14739 app.cached = false; 14740 app.adjType = "previous"; 14741 } 14742 if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) { 14743 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY; 14744 } 14745 } 14746 14747 if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj 14748 + " reason=" + app.adjType); 14749 14750 // By default, we use the computed adjustment. It may be changed if 14751 // there are applications dependent on our services or providers, but 14752 // this gives us a baseline and makes sure we don't get into an 14753 // infinite recursion. 14754 app.adjSeq = mAdjSeq; 14755 app.curRawAdj = adj; 14756 app.hasStartedServices = false; 14757 14758 if (mBackupTarget != null && app == mBackupTarget.app) { 14759 // If possible we want to avoid killing apps while they're being backed up 14760 if (adj > ProcessList.BACKUP_APP_ADJ) { 14761 if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app); 14762 adj = ProcessList.BACKUP_APP_ADJ; 14763 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) { 14764 procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND; 14765 } 14766 app.adjType = "backup"; 14767 app.cached = false; 14768 } 14769 if (procState > ActivityManager.PROCESS_STATE_BACKUP) { 14770 procState = ActivityManager.PROCESS_STATE_BACKUP; 14771 } 14772 } 14773 14774 boolean mayBeTop = false; 14775 14776 for (int is = app.services.size()-1; 14777 is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 14778 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 14779 || procState > ActivityManager.PROCESS_STATE_TOP); 14780 is--) { 14781 ServiceRecord s = app.services.valueAt(is); 14782 if (s.startRequested) { 14783 app.hasStartedServices = true; 14784 if (procState > ActivityManager.PROCESS_STATE_SERVICE) { 14785 procState = ActivityManager.PROCESS_STATE_SERVICE; 14786 } 14787 if (app.hasShownUi && app != mHomeProcess) { 14788 // If this process has shown some UI, let it immediately 14789 // go to the LRU list because it may be pretty heavy with 14790 // UI stuff. We'll tag it with a label just to help 14791 // debug and understand what is going on. 14792 if (adj > ProcessList.SERVICE_ADJ) { 14793 app.adjType = "cch-started-ui-services"; 14794 } 14795 } else { 14796 if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) { 14797 // This service has seen some activity within 14798 // recent memory, so we will keep its process ahead 14799 // of the background processes. 14800 if (adj > ProcessList.SERVICE_ADJ) { 14801 adj = ProcessList.SERVICE_ADJ; 14802 app.adjType = "started-services"; 14803 app.cached = false; 14804 } 14805 } 14806 // If we have let the service slide into the background 14807 // state, still have some text describing what it is doing 14808 // even though the service no longer has an impact. 14809 if (adj > ProcessList.SERVICE_ADJ) { 14810 app.adjType = "cch-started-services"; 14811 } 14812 } 14813 // Don't kill this process because it is doing work; it 14814 // has said it is doing work. 14815 app.keeping = true; 14816 } 14817 for (int conni = s.connections.size()-1; 14818 conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 14819 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 14820 || procState > ActivityManager.PROCESS_STATE_TOP); 14821 conni--) { 14822 ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni); 14823 for (int i = 0; 14824 i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ 14825 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 14826 || procState > ActivityManager.PROCESS_STATE_TOP); 14827 i++) { 14828 // XXX should compute this based on the max of 14829 // all connected clients. 14830 ConnectionRecord cr = clist.get(i); 14831 if (cr.binding.client == app) { 14832 // Binding to ourself is not interesting. 14833 continue; 14834 } 14835 if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) { 14836 ProcessRecord client = cr.binding.client; 14837 int clientAdj = computeOomAdjLocked(client, cachedAdj, 14838 TOP_APP, doingAll, now); 14839 int clientProcState = client.curProcState; 14840 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 14841 // If the other app is cached for any reason, for purposes here 14842 // we are going to consider it empty. The specific cached state 14843 // doesn't propagate except under certain conditions. 14844 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 14845 } 14846 String adjType = null; 14847 if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) { 14848 // Not doing bind OOM management, so treat 14849 // this guy more like a started service. 14850 if (app.hasShownUi && app != mHomeProcess) { 14851 // If this process has shown some UI, let it immediately 14852 // go to the LRU list because it may be pretty heavy with 14853 // UI stuff. We'll tag it with a label just to help 14854 // debug and understand what is going on. 14855 if (adj > clientAdj) { 14856 adjType = "cch-bound-ui-services"; 14857 } 14858 app.cached = false; 14859 clientAdj = adj; 14860 clientProcState = procState; 14861 } else { 14862 if (now >= (s.lastActivity 14863 + ActiveServices.MAX_SERVICE_INACTIVITY)) { 14864 // This service has not seen activity within 14865 // recent memory, so allow it to drop to the 14866 // LRU list if there is no other reason to keep 14867 // it around. We'll also tag it with a label just 14868 // to help debug and undertand what is going on. 14869 if (adj > clientAdj) { 14870 adjType = "cch-bound-services"; 14871 } 14872 clientAdj = adj; 14873 } 14874 } 14875 } 14876 if (adj > clientAdj) { 14877 // If this process has recently shown UI, and 14878 // the process that is binding to it is less 14879 // important than being visible, then we don't 14880 // care about the binding as much as we care 14881 // about letting this process get into the LRU 14882 // list to be killed and restarted if needed for 14883 // memory. 14884 if (app.hasShownUi && app != mHomeProcess 14885 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14886 adjType = "cch-bound-ui-services"; 14887 } else { 14888 if ((cr.flags&(Context.BIND_ABOVE_CLIENT 14889 |Context.BIND_IMPORTANT)) != 0) { 14890 adj = clientAdj; 14891 } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0 14892 && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ 14893 && adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14894 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 14895 } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) { 14896 adj = clientAdj; 14897 } else { 14898 if (adj > ProcessList.VISIBLE_APP_ADJ) { 14899 adj = ProcessList.VISIBLE_APP_ADJ; 14900 } 14901 } 14902 if (!client.cached) { 14903 app.cached = false; 14904 } 14905 if (client.keeping) { 14906 app.keeping = true; 14907 } 14908 adjType = "service"; 14909 } 14910 } 14911 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 14912 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 14913 schedGroup = Process.THREAD_GROUP_DEFAULT; 14914 } 14915 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) { 14916 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) { 14917 // Special handling of clients who are in the top state. 14918 // We *may* want to consider this process to be in the 14919 // top state as well, but only if there is not another 14920 // reason for it to be running. Being on the top is a 14921 // special state, meaning you are specifically running 14922 // for the current top app. If the process is already 14923 // running in the background for some other reason, it 14924 // is more important to continue considering it to be 14925 // in the background state. 14926 mayBeTop = true; 14927 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 14928 } else { 14929 // Special handling for above-top states (persistent 14930 // processes). These should not bring the current process 14931 // into the top state, since they are not on top. Instead 14932 // give them the best state after that. 14933 clientProcState = 14934 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14935 } 14936 } 14937 } else { 14938 if (clientProcState < 14939 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) { 14940 clientProcState = 14941 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND; 14942 } 14943 } 14944 if (procState > clientProcState) { 14945 procState = clientProcState; 14946 } 14947 if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 14948 && (cr.flags&Context.BIND_SHOWING_UI) != 0) { 14949 app.pendingUiClean = true; 14950 } 14951 if (adjType != null) { 14952 app.adjType = adjType; 14953 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 14954 .REASON_SERVICE_IN_USE; 14955 app.adjSource = cr.binding.client; 14956 app.adjSourceOom = clientAdj; 14957 app.adjTarget = s.name; 14958 } 14959 } 14960 if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) { 14961 app.treatLikeActivity = true; 14962 } 14963 final ActivityRecord a = cr.activity; 14964 if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) { 14965 if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ && 14966 (a.visible || a.state == ActivityState.RESUMED 14967 || a.state == ActivityState.PAUSING)) { 14968 adj = ProcessList.FOREGROUND_APP_ADJ; 14969 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 14970 schedGroup = Process.THREAD_GROUP_DEFAULT; 14971 } 14972 app.cached = false; 14973 app.adjType = "service"; 14974 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 14975 .REASON_SERVICE_IN_USE; 14976 app.adjSource = a; 14977 app.adjSourceOom = adj; 14978 app.adjTarget = s.name; 14979 } 14980 } 14981 } 14982 } 14983 } 14984 14985 for (int provi = app.pubProviders.size()-1; 14986 provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 14987 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 14988 || procState > ActivityManager.PROCESS_STATE_TOP); 14989 provi--) { 14990 ContentProviderRecord cpr = app.pubProviders.valueAt(provi); 14991 for (int i = cpr.connections.size()-1; 14992 i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 14993 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 14994 || procState > ActivityManager.PROCESS_STATE_TOP); 14995 i--) { 14996 ContentProviderConnection conn = cpr.connections.get(i); 14997 ProcessRecord client = conn.client; 14998 if (client == app) { 14999 // Being our own client is not interesting. 15000 continue; 15001 } 15002 int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now); 15003 int clientProcState = client.curProcState; 15004 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 15005 // If the other app is cached for any reason, for purposes here 15006 // we are going to consider it empty. 15007 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 15008 } 15009 if (adj > clientAdj) { 15010 if (app.hasShownUi && app != mHomeProcess 15011 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 15012 app.adjType = "cch-ui-provider"; 15013 } else { 15014 adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ 15015 ? clientAdj : ProcessList.FOREGROUND_APP_ADJ; 15016 app.adjType = "provider"; 15017 } 15018 app.cached &= client.cached; 15019 app.keeping |= client.keeping; 15020 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 15021 .REASON_PROVIDER_IN_USE; 15022 app.adjSource = client; 15023 app.adjSourceOom = clientAdj; 15024 app.adjTarget = cpr.name; 15025 } 15026 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) { 15027 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) { 15028 // Special handling of clients who are in the top state. 15029 // We *may* want to consider this process to be in the 15030 // top state as well, but only if there is not another 15031 // reason for it to be running. Being on the top is a 15032 // special state, meaning you are specifically running 15033 // for the current top app. If the process is already 15034 // running in the background for some other reason, it 15035 // is more important to continue considering it to be 15036 // in the background state. 15037 mayBeTop = true; 15038 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 15039 } else { 15040 // Special handling for above-top states (persistent 15041 // processes). These should not bring the current process 15042 // into the top state, since they are not on top. Instead 15043 // give them the best state after that. 15044 clientProcState = 15045 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 15046 } 15047 } 15048 if (procState > clientProcState) { 15049 procState = clientProcState; 15050 } 15051 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 15052 schedGroup = Process.THREAD_GROUP_DEFAULT; 15053 } 15054 } 15055 // If the provider has external (non-framework) process 15056 // dependencies, ensure that its adjustment is at least 15057 // FOREGROUND_APP_ADJ. 15058 if (cpr.hasExternalProcessHandles()) { 15059 if (adj > ProcessList.FOREGROUND_APP_ADJ) { 15060 adj = ProcessList.FOREGROUND_APP_ADJ; 15061 schedGroup = Process.THREAD_GROUP_DEFAULT; 15062 app.cached = false; 15063 app.keeping = true; 15064 app.adjType = "provider"; 15065 app.adjTarget = cpr.name; 15066 } 15067 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) { 15068 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 15069 } 15070 } 15071 } 15072 15073 if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) { 15074 // A client of one of our services or providers is in the top state. We 15075 // *may* want to be in the top state, but not if we are already running in 15076 // the background for some other reason. For the decision here, we are going 15077 // to pick out a few specific states that we want to remain in when a client 15078 // is top (states that tend to be longer-term) and otherwise allow it to go 15079 // to the top state. 15080 switch (procState) { 15081 case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND: 15082 case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND: 15083 case ActivityManager.PROCESS_STATE_SERVICE: 15084 // These all are longer-term states, so pull them up to the top 15085 // of the background states, but not all the way to the top state. 15086 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 15087 break; 15088 default: 15089 // Otherwise, top is a better choice, so take it. 15090 procState = ActivityManager.PROCESS_STATE_TOP; 15091 break; 15092 } 15093 } 15094 15095 if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) { 15096 if (app.hasClientActivities) { 15097 // This is a cached process, but with client activities. Mark it so. 15098 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT; 15099 app.adjType = "cch-client-act"; 15100 } else if (app.treatLikeActivity) { 15101 // This is a cached process, but somebody wants us to treat it like it has 15102 // an activity, okay! 15103 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 15104 app.adjType = "cch-as-act"; 15105 } 15106 } 15107 15108 if (adj == ProcessList.SERVICE_ADJ) { 15109 if (doingAll) { 15110 app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3); 15111 mNewNumServiceProcs++; 15112 //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb); 15113 if (!app.serviceb) { 15114 // This service isn't far enough down on the LRU list to 15115 // normally be a B service, but if we are low on RAM and it 15116 // is large we want to force it down since we would prefer to 15117 // keep launcher over it. 15118 if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL 15119 && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) { 15120 app.serviceHighRam = true; 15121 app.serviceb = true; 15122 //Slog.i(TAG, "ADJ " + app + " high ram!"); 15123 } else { 15124 mNewNumAServiceProcs++; 15125 //Slog.i(TAG, "ADJ " + app + " not high ram!"); 15126 } 15127 } else { 15128 app.serviceHighRam = false; 15129 } 15130 } 15131 if (app.serviceb) { 15132 adj = ProcessList.SERVICE_B_ADJ; 15133 } 15134 } 15135 15136 app.curRawAdj = adj; 15137 15138 //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid + 15139 // " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj); 15140 if (adj > app.maxAdj) { 15141 adj = app.maxAdj; 15142 if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 15143 schedGroup = Process.THREAD_GROUP_DEFAULT; 15144 } 15145 } 15146 if (adj < ProcessList.CACHED_APP_MIN_ADJ) { 15147 app.keeping = true; 15148 } 15149 15150 // Do final modification to adj. Everything we do between here and applying 15151 // the final setAdj must be done in this function, because we will also use 15152 // it when computing the final cached adj later. Note that we don't need to 15153 // worry about this for max adj above, since max adj will always be used to 15154 // keep it out of the cached vaues. 15155 adj = app.modifyRawOomAdj(adj); 15156 15157 app.curProcState = procState; 15158 15159 int importance = app.memImportance; 15160 if (importance == 0 || adj != app.curAdj || schedGroup != app.curSchedGroup) { 15161 app.curAdj = adj; 15162 app.curSchedGroup = schedGroup; 15163 if (!interesting) { 15164 // For this reporting, if there is not something explicitly 15165 // interesting in this process then we will push it to the 15166 // background importance. 15167 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 15168 } else if (adj >= ProcessList.CACHED_APP_MIN_ADJ) { 15169 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 15170 } else if (adj >= ProcessList.SERVICE_B_ADJ) { 15171 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 15172 } else if (adj >= ProcessList.HOME_APP_ADJ) { 15173 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 15174 } else if (adj >= ProcessList.SERVICE_ADJ) { 15175 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 15176 } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 15177 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE; 15178 } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) { 15179 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE; 15180 } else if (adj >= ProcessList.VISIBLE_APP_ADJ) { 15181 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE; 15182 } else if (adj >= ProcessList.FOREGROUND_APP_ADJ) { 15183 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND; 15184 } else { 15185 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERSISTENT; 15186 } 15187 } 15188 15189 int changes = importance != app.memImportance ? ProcessChangeItem.CHANGE_IMPORTANCE : 0; 15190 if (foregroundActivities != app.foregroundActivities) { 15191 changes |= ProcessChangeItem.CHANGE_ACTIVITIES; 15192 } 15193 if (changes != 0) { 15194 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes); 15195 app.memImportance = importance; 15196 app.foregroundActivities = foregroundActivities; 15197 int i = mPendingProcessChanges.size()-1; 15198 ProcessChangeItem item = null; 15199 while (i >= 0) { 15200 item = mPendingProcessChanges.get(i); 15201 if (item.pid == app.pid) { 15202 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item); 15203 break; 15204 } 15205 i--; 15206 } 15207 if (i < 0) { 15208 // No existing item in pending changes; need a new one. 15209 final int NA = mAvailProcessChanges.size(); 15210 if (NA > 0) { 15211 item = mAvailProcessChanges.remove(NA-1); 15212 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item); 15213 } else { 15214 item = new ProcessChangeItem(); 15215 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item); 15216 } 15217 item.changes = 0; 15218 item.pid = app.pid; 15219 item.uid = app.info.uid; 15220 if (mPendingProcessChanges.size() == 0) { 15221 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, 15222 "*** Enqueueing dispatch processes changed!"); 15223 mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget(); 15224 } 15225 mPendingProcessChanges.add(item); 15226 } 15227 item.changes |= changes; 15228 item.importance = importance; 15229 item.foregroundActivities = foregroundActivities; 15230 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item " 15231 + Integer.toHexString(System.identityHashCode(item)) 15232 + " " + app.toShortString() + ": changes=" + item.changes 15233 + " importance=" + item.importance 15234 + " foreground=" + item.foregroundActivities 15235 + " type=" + app.adjType + " source=" + app.adjSource 15236 + " target=" + app.adjTarget); 15237 } 15238 15239 return app.curRawAdj; 15240 } 15241 15242 /** 15243 * Schedule PSS collection of a process. 15244 */ 15245 void requestPssLocked(ProcessRecord proc, int procState) { 15246 if (mPendingPssProcesses.contains(proc)) { 15247 return; 15248 } 15249 if (mPendingPssProcesses.size() == 0) { 15250 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG); 15251 } 15252 if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc); 15253 proc.pssProcState = procState; 15254 mPendingPssProcesses.add(proc); 15255 } 15256 15257 /** 15258 * Schedule PSS collection of all processes. 15259 */ 15260 void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) { 15261 if (!always) { 15262 if (now < (mLastFullPssTime + 15263 (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) { 15264 return; 15265 } 15266 } 15267 if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs! memLowered=" + memLowered); 15268 mLastFullPssTime = now; 15269 mPendingPssProcesses.ensureCapacity(mLruProcesses.size()); 15270 mPendingPssProcesses.clear(); 15271 for (int i=mLruProcesses.size()-1; i>=0; i--) { 15272 ProcessRecord app = mLruProcesses.get(i); 15273 if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) { 15274 app.pssProcState = app.setProcState; 15275 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true, 15276 mSleeping, now); 15277 mPendingPssProcesses.add(app); 15278 } 15279 } 15280 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG); 15281 } 15282 15283 /** 15284 * Ask a given process to GC right now. 15285 */ 15286 final void performAppGcLocked(ProcessRecord app) { 15287 try { 15288 app.lastRequestedGc = SystemClock.uptimeMillis(); 15289 if (app.thread != null) { 15290 if (app.reportLowMemory) { 15291 app.reportLowMemory = false; 15292 app.thread.scheduleLowMemory(); 15293 } else { 15294 app.thread.processInBackground(); 15295 } 15296 } 15297 } catch (Exception e) { 15298 // whatever. 15299 } 15300 } 15301 15302 /** 15303 * Returns true if things are idle enough to perform GCs. 15304 */ 15305 private final boolean canGcNowLocked() { 15306 boolean processingBroadcasts = false; 15307 for (BroadcastQueue q : mBroadcastQueues) { 15308 if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) { 15309 processingBroadcasts = true; 15310 } 15311 } 15312 return !processingBroadcasts 15313 && (mSleeping || mStackSupervisor.allResumedActivitiesIdle()); 15314 } 15315 15316 /** 15317 * Perform GCs on all processes that are waiting for it, but only 15318 * if things are idle. 15319 */ 15320 final void performAppGcsLocked() { 15321 final int N = mProcessesToGc.size(); 15322 if (N <= 0) { 15323 return; 15324 } 15325 if (canGcNowLocked()) { 15326 while (mProcessesToGc.size() > 0) { 15327 ProcessRecord proc = mProcessesToGc.remove(0); 15328 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) { 15329 if ((proc.lastRequestedGc+GC_MIN_INTERVAL) 15330 <= SystemClock.uptimeMillis()) { 15331 // To avoid spamming the system, we will GC processes one 15332 // at a time, waiting a few seconds between each. 15333 performAppGcLocked(proc); 15334 scheduleAppGcsLocked(); 15335 return; 15336 } else { 15337 // It hasn't been long enough since we last GCed this 15338 // process... put it in the list to wait for its time. 15339 addProcessToGcListLocked(proc); 15340 break; 15341 } 15342 } 15343 } 15344 15345 scheduleAppGcsLocked(); 15346 } 15347 } 15348 15349 /** 15350 * If all looks good, perform GCs on all processes waiting for them. 15351 */ 15352 final void performAppGcsIfAppropriateLocked() { 15353 if (canGcNowLocked()) { 15354 performAppGcsLocked(); 15355 return; 15356 } 15357 // Still not idle, wait some more. 15358 scheduleAppGcsLocked(); 15359 } 15360 15361 /** 15362 * Schedule the execution of all pending app GCs. 15363 */ 15364 final void scheduleAppGcsLocked() { 15365 mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG); 15366 15367 if (mProcessesToGc.size() > 0) { 15368 // Schedule a GC for the time to the next process. 15369 ProcessRecord proc = mProcessesToGc.get(0); 15370 Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG); 15371 15372 long when = proc.lastRequestedGc + GC_MIN_INTERVAL; 15373 long now = SystemClock.uptimeMillis(); 15374 if (when < (now+GC_TIMEOUT)) { 15375 when = now + GC_TIMEOUT; 15376 } 15377 mHandler.sendMessageAtTime(msg, when); 15378 } 15379 } 15380 15381 /** 15382 * Add a process to the array of processes waiting to be GCed. Keeps the 15383 * list in sorted order by the last GC time. The process can't already be 15384 * on the list. 15385 */ 15386 final void addProcessToGcListLocked(ProcessRecord proc) { 15387 boolean added = false; 15388 for (int i=mProcessesToGc.size()-1; i>=0; i--) { 15389 if (mProcessesToGc.get(i).lastRequestedGc < 15390 proc.lastRequestedGc) { 15391 added = true; 15392 mProcessesToGc.add(i+1, proc); 15393 break; 15394 } 15395 } 15396 if (!added) { 15397 mProcessesToGc.add(0, proc); 15398 } 15399 } 15400 15401 /** 15402 * Set up to ask a process to GC itself. This will either do it 15403 * immediately, or put it on the list of processes to gc the next 15404 * time things are idle. 15405 */ 15406 final void scheduleAppGcLocked(ProcessRecord app) { 15407 long now = SystemClock.uptimeMillis(); 15408 if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) { 15409 return; 15410 } 15411 if (!mProcessesToGc.contains(app)) { 15412 addProcessToGcListLocked(app); 15413 scheduleAppGcsLocked(); 15414 } 15415 } 15416 15417 final void checkExcessivePowerUsageLocked(boolean doKills) { 15418 updateCpuStatsNow(); 15419 15420 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 15421 boolean doWakeKills = doKills; 15422 boolean doCpuKills = doKills; 15423 if (mLastPowerCheckRealtime == 0) { 15424 doWakeKills = false; 15425 } 15426 if (mLastPowerCheckUptime == 0) { 15427 doCpuKills = false; 15428 } 15429 if (stats.isScreenOn()) { 15430 doWakeKills = false; 15431 } 15432 final long curRealtime = SystemClock.elapsedRealtime(); 15433 final long realtimeSince = curRealtime - mLastPowerCheckRealtime; 15434 final long curUptime = SystemClock.uptimeMillis(); 15435 final long uptimeSince = curUptime - mLastPowerCheckUptime; 15436 mLastPowerCheckRealtime = curRealtime; 15437 mLastPowerCheckUptime = curUptime; 15438 if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) { 15439 doWakeKills = false; 15440 } 15441 if (uptimeSince < CPU_MIN_CHECK_DURATION) { 15442 doCpuKills = false; 15443 } 15444 int i = mLruProcesses.size(); 15445 while (i > 0) { 15446 i--; 15447 ProcessRecord app = mLruProcesses.get(i); 15448 if (!app.keeping) { 15449 long wtime; 15450 synchronized (stats) { 15451 wtime = stats.getProcessWakeTime(app.info.uid, 15452 app.pid, curRealtime); 15453 } 15454 long wtimeUsed = wtime - app.lastWakeTime; 15455 long cputimeUsed = app.curCpuTime - app.lastCpuTime; 15456 if (DEBUG_POWER) { 15457 StringBuilder sb = new StringBuilder(128); 15458 sb.append("Wake for "); 15459 app.toShortString(sb); 15460 sb.append(": over "); 15461 TimeUtils.formatDuration(realtimeSince, sb); 15462 sb.append(" used "); 15463 TimeUtils.formatDuration(wtimeUsed, sb); 15464 sb.append(" ("); 15465 sb.append((wtimeUsed*100)/realtimeSince); 15466 sb.append("%)"); 15467 Slog.i(TAG, sb.toString()); 15468 sb.setLength(0); 15469 sb.append("CPU for "); 15470 app.toShortString(sb); 15471 sb.append(": over "); 15472 TimeUtils.formatDuration(uptimeSince, sb); 15473 sb.append(" used "); 15474 TimeUtils.formatDuration(cputimeUsed, sb); 15475 sb.append(" ("); 15476 sb.append((cputimeUsed*100)/uptimeSince); 15477 sb.append("%)"); 15478 Slog.i(TAG, sb.toString()); 15479 } 15480 // If a process has held a wake lock for more 15481 // than 50% of the time during this period, 15482 // that sounds bad. Kill! 15483 if (doWakeKills && realtimeSince > 0 15484 && ((wtimeUsed*100)/realtimeSince) >= 50) { 15485 synchronized (stats) { 15486 stats.reportExcessiveWakeLocked(app.info.uid, app.processName, 15487 realtimeSince, wtimeUsed); 15488 } 15489 killUnneededProcessLocked(app, "excessive wake held " + wtimeUsed 15490 + " during " + realtimeSince); 15491 app.baseProcessTracker.reportExcessiveWake(app.pkgList); 15492 } else if (doCpuKills && uptimeSince > 0 15493 && ((cputimeUsed*100)/uptimeSince) >= 50) { 15494 synchronized (stats) { 15495 stats.reportExcessiveCpuLocked(app.info.uid, app.processName, 15496 uptimeSince, cputimeUsed); 15497 } 15498 killUnneededProcessLocked(app, "excessive cpu " + cputimeUsed 15499 + " during " + uptimeSince); 15500 app.baseProcessTracker.reportExcessiveCpu(app.pkgList); 15501 } else { 15502 app.lastWakeTime = wtime; 15503 app.lastCpuTime = app.curCpuTime; 15504 } 15505 } 15506 } 15507 } 15508 15509 private final boolean applyOomAdjLocked(ProcessRecord app, boolean wasKeeping, 15510 ProcessRecord TOP_APP, boolean doingAll, boolean reportingProcessState, long now) { 15511 boolean success = true; 15512 15513 if (app.curRawAdj != app.setRawAdj) { 15514 if (wasKeeping && !app.keeping) { 15515 // This app is no longer something we want to keep. Note 15516 // its current wake lock time to later know to kill it if 15517 // it is not behaving well. 15518 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 15519 synchronized (stats) { 15520 app.lastWakeTime = stats.getProcessWakeTime(app.info.uid, 15521 app.pid, SystemClock.elapsedRealtime()); 15522 } 15523 app.lastCpuTime = app.curCpuTime; 15524 } 15525 15526 app.setRawAdj = app.curRawAdj; 15527 } 15528 15529 if (app.curAdj != app.setAdj) { 15530 ProcessList.setOomAdj(app.pid, app.curAdj); 15531 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v( 15532 TAG, "Set " + app.pid + " " + app.processName + 15533 " adj " + app.curAdj + ": " + app.adjType); 15534 app.setAdj = app.curAdj; 15535 } 15536 15537 if (app.setSchedGroup != app.curSchedGroup) { 15538 app.setSchedGroup = app.curSchedGroup; 15539 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 15540 "Setting process group of " + app.processName 15541 + " to " + app.curSchedGroup); 15542 if (app.waitingToKill != null && 15543 app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 15544 killUnneededProcessLocked(app, app.waitingToKill); 15545 success = false; 15546 } else { 15547 if (true) { 15548 long oldId = Binder.clearCallingIdentity(); 15549 try { 15550 Process.setProcessGroup(app.pid, app.curSchedGroup); 15551 } catch (Exception e) { 15552 Slog.w(TAG, "Failed setting process group of " + app.pid 15553 + " to " + app.curSchedGroup); 15554 e.printStackTrace(); 15555 } finally { 15556 Binder.restoreCallingIdentity(oldId); 15557 } 15558 } else { 15559 if (app.thread != null) { 15560 try { 15561 app.thread.setSchedulingGroup(app.curSchedGroup); 15562 } catch (RemoteException e) { 15563 } 15564 } 15565 } 15566 Process.setSwappiness(app.pid, 15567 app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE); 15568 } 15569 } 15570 if (app.repProcState != app.curProcState) { 15571 app.repProcState = app.curProcState; 15572 if (!reportingProcessState && app.thread != null) { 15573 try { 15574 if (false) { 15575 //RuntimeException h = new RuntimeException("here"); 15576 Slog.i(TAG, "Sending new process state " + app.repProcState 15577 + " to " + app /*, h*/); 15578 } 15579 app.thread.setProcessState(app.repProcState); 15580 } catch (RemoteException e) { 15581 } 15582 } 15583 } 15584 if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState, 15585 app.setProcState)) { 15586 app.lastStateTime = now; 15587 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true, 15588 mSleeping, now); 15589 if (DEBUG_PSS) Slog.d(TAG, "Process state change from " 15590 + ProcessList.makeProcStateString(app.setProcState) + " to " 15591 + ProcessList.makeProcStateString(app.curProcState) + " next pss in " 15592 + (app.nextPssTime-now) + ": " + app); 15593 } else { 15594 if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL) 15595 && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) { 15596 requestPssLocked(app, app.setProcState); 15597 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false, 15598 mSleeping, now); 15599 } else if (false && DEBUG_PSS) { 15600 Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now)); 15601 } 15602 } 15603 if (app.setProcState != app.curProcState) { 15604 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 15605 "Proc state change of " + app.processName 15606 + " to " + app.curProcState); 15607 app.setProcState = app.curProcState; 15608 if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) { 15609 app.notCachedSinceIdle = false; 15610 } 15611 if (!doingAll) { 15612 setProcessTrackerState(app, mProcessStats.getMemFactorLocked(), now); 15613 } else { 15614 app.procStateChanged = true; 15615 } 15616 } 15617 return success; 15618 } 15619 15620 private final void setProcessTrackerState(ProcessRecord proc, int memFactor, long now) { 15621 if (proc.thread != null && proc.baseProcessTracker != null) { 15622 proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList); 15623 } 15624 } 15625 15626 private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj, 15627 ProcessRecord TOP_APP, boolean doingAll, boolean reportingProcessState, long now) { 15628 if (app.thread == null) { 15629 return false; 15630 } 15631 15632 final boolean wasKeeping = app.keeping; 15633 15634 computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now); 15635 15636 return applyOomAdjLocked(app, wasKeeping, TOP_APP, doingAll, 15637 reportingProcessState, now); 15638 } 15639 15640 final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground, 15641 boolean oomAdj) { 15642 if (isForeground != proc.foregroundServices) { 15643 proc.foregroundServices = isForeground; 15644 ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName, 15645 proc.info.uid); 15646 if (isForeground) { 15647 if (curProcs == null) { 15648 curProcs = new ArrayList<ProcessRecord>(); 15649 mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs); 15650 } 15651 if (!curProcs.contains(proc)) { 15652 curProcs.add(proc); 15653 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START, 15654 proc.info.packageName, proc.info.uid); 15655 } 15656 } else { 15657 if (curProcs != null) { 15658 if (curProcs.remove(proc)) { 15659 mBatteryStatsService.noteEvent( 15660 BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH, 15661 proc.info.packageName, proc.info.uid); 15662 if (curProcs.size() <= 0) { 15663 mForegroundPackages.remove(proc.info.packageName, proc.info.uid); 15664 } 15665 } 15666 } 15667 } 15668 if (oomAdj) { 15669 updateOomAdjLocked(); 15670 } 15671 } 15672 } 15673 15674 private final ActivityRecord resumedAppLocked() { 15675 ActivityRecord act = mStackSupervisor.resumedAppLocked(); 15676 String pkg; 15677 int uid; 15678 if (act != null && !act.sleeping) { 15679 pkg = act.packageName; 15680 uid = act.info.applicationInfo.uid; 15681 } else { 15682 pkg = null; 15683 uid = -1; 15684 } 15685 // Has the UID or resumed package name changed? 15686 if (uid != mCurResumedUid || (pkg != mCurResumedPackage 15687 && (pkg == null || !pkg.equals(mCurResumedPackage)))) { 15688 if (mCurResumedPackage != null) { 15689 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH, 15690 mCurResumedPackage, mCurResumedUid); 15691 } 15692 mCurResumedPackage = pkg; 15693 mCurResumedUid = uid; 15694 if (mCurResumedPackage != null) { 15695 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START, 15696 mCurResumedPackage, mCurResumedUid); 15697 } 15698 } 15699 return act; 15700 } 15701 15702 final boolean updateOomAdjLocked(ProcessRecord app) { 15703 return updateOomAdjLocked(app, false); 15704 } 15705 15706 final boolean updateOomAdjLocked(ProcessRecord app, boolean doingProcessState) { 15707 final ActivityRecord TOP_ACT = resumedAppLocked(); 15708 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 15709 final boolean wasCached = app.cached; 15710 15711 mAdjSeq++; 15712 15713 // This is the desired cached adjusment we want to tell it to use. 15714 // If our app is currently cached, we know it, and that is it. Otherwise, 15715 // we don't know it yet, and it needs to now be cached we will then 15716 // need to do a complete oom adj. 15717 final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ 15718 ? app.curRawAdj : ProcessList.UNKNOWN_ADJ; 15719 boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false, doingProcessState, 15720 SystemClock.uptimeMillis()); 15721 if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) { 15722 // Changed to/from cached state, so apps after it in the LRU 15723 // list may also be changed. 15724 updateOomAdjLocked(); 15725 } 15726 return success; 15727 } 15728 15729 final void updateOomAdjLocked() { 15730 final ActivityRecord TOP_ACT = resumedAppLocked(); 15731 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 15732 final long now = SystemClock.uptimeMillis(); 15733 final long oldTime = now - ProcessList.MAX_EMPTY_TIME; 15734 final int N = mLruProcesses.size(); 15735 15736 if (false) { 15737 RuntimeException e = new RuntimeException(); 15738 e.fillInStackTrace(); 15739 Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e); 15740 } 15741 15742 mAdjSeq++; 15743 mNewNumServiceProcs = 0; 15744 mNewNumAServiceProcs = 0; 15745 15746 final int emptyProcessLimit; 15747 final int cachedProcessLimit; 15748 if (mProcessLimit <= 0) { 15749 emptyProcessLimit = cachedProcessLimit = 0; 15750 } else if (mProcessLimit == 1) { 15751 emptyProcessLimit = 1; 15752 cachedProcessLimit = 0; 15753 } else { 15754 emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit); 15755 cachedProcessLimit = mProcessLimit - emptyProcessLimit; 15756 } 15757 15758 // Let's determine how many processes we have running vs. 15759 // how many slots we have for background processes; we may want 15760 // to put multiple processes in a slot of there are enough of 15761 // them. 15762 int numSlots = (ProcessList.CACHED_APP_MAX_ADJ 15763 - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2; 15764 int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs; 15765 if (numEmptyProcs > cachedProcessLimit) { 15766 // If there are more empty processes than our limit on cached 15767 // processes, then use the cached process limit for the factor. 15768 // This ensures that the really old empty processes get pushed 15769 // down to the bottom, so if we are running low on memory we will 15770 // have a better chance at keeping around more cached processes 15771 // instead of a gazillion empty processes. 15772 numEmptyProcs = cachedProcessLimit; 15773 } 15774 int emptyFactor = numEmptyProcs/numSlots; 15775 if (emptyFactor < 1) emptyFactor = 1; 15776 int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots; 15777 if (cachedFactor < 1) cachedFactor = 1; 15778 int stepCached = 0; 15779 int stepEmpty = 0; 15780 int numCached = 0; 15781 int numEmpty = 0; 15782 int numTrimming = 0; 15783 15784 mNumNonCachedProcs = 0; 15785 mNumCachedHiddenProcs = 0; 15786 15787 // First update the OOM adjustment for each of the 15788 // application processes based on their current state. 15789 int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ; 15790 int nextCachedAdj = curCachedAdj+1; 15791 int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ; 15792 int nextEmptyAdj = curEmptyAdj+2; 15793 for (int i=N-1; i>=0; i--) { 15794 ProcessRecord app = mLruProcesses.get(i); 15795 if (!app.killedByAm && app.thread != null) { 15796 app.procStateChanged = false; 15797 final boolean wasKeeping = app.keeping; 15798 computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now); 15799 15800 // If we haven't yet assigned the final cached adj 15801 // to the process, do that now. 15802 if (app.curAdj >= ProcessList.UNKNOWN_ADJ) { 15803 switch (app.curProcState) { 15804 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY: 15805 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: 15806 // This process is a cached process holding activities... 15807 // assign it the next cached value for that type, and then 15808 // step that cached level. 15809 app.curRawAdj = curCachedAdj; 15810 app.curAdj = app.modifyRawOomAdj(curCachedAdj); 15811 if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i 15812 + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj 15813 + ")"); 15814 if (curCachedAdj != nextCachedAdj) { 15815 stepCached++; 15816 if (stepCached >= cachedFactor) { 15817 stepCached = 0; 15818 curCachedAdj = nextCachedAdj; 15819 nextCachedAdj += 2; 15820 if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) { 15821 nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ; 15822 } 15823 } 15824 } 15825 break; 15826 default: 15827 // For everything else, assign next empty cached process 15828 // level and bump that up. Note that this means that 15829 // long-running services that have dropped down to the 15830 // cached level will be treated as empty (since their process 15831 // state is still as a service), which is what we want. 15832 app.curRawAdj = curEmptyAdj; 15833 app.curAdj = app.modifyRawOomAdj(curEmptyAdj); 15834 if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i 15835 + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj 15836 + ")"); 15837 if (curEmptyAdj != nextEmptyAdj) { 15838 stepEmpty++; 15839 if (stepEmpty >= emptyFactor) { 15840 stepEmpty = 0; 15841 curEmptyAdj = nextEmptyAdj; 15842 nextEmptyAdj += 2; 15843 if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) { 15844 nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ; 15845 } 15846 } 15847 } 15848 break; 15849 } 15850 } 15851 15852 applyOomAdjLocked(app, wasKeeping, TOP_APP, true, false, now); 15853 15854 // Count the number of process types. 15855 switch (app.curProcState) { 15856 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY: 15857 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: 15858 mNumCachedHiddenProcs++; 15859 numCached++; 15860 if (numCached > cachedProcessLimit) { 15861 killUnneededProcessLocked(app, "cached #" + numCached); 15862 } 15863 break; 15864 case ActivityManager.PROCESS_STATE_CACHED_EMPTY: 15865 if (numEmpty > ProcessList.TRIM_EMPTY_APPS 15866 && app.lastActivityTime < oldTime) { 15867 killUnneededProcessLocked(app, "empty for " 15868 + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime) 15869 / 1000) + "s"); 15870 } else { 15871 numEmpty++; 15872 if (numEmpty > emptyProcessLimit) { 15873 killUnneededProcessLocked(app, "empty #" + numEmpty); 15874 } 15875 } 15876 break; 15877 default: 15878 mNumNonCachedProcs++; 15879 break; 15880 } 15881 15882 if (app.isolated && app.services.size() <= 0) { 15883 // If this is an isolated process, and there are no 15884 // services running in it, then the process is no longer 15885 // needed. We agressively kill these because we can by 15886 // definition not re-use the same process again, and it is 15887 // good to avoid having whatever code was running in them 15888 // left sitting around after no longer needed. 15889 killUnneededProcessLocked(app, "isolated not needed"); 15890 } 15891 15892 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME 15893 && !app.killedByAm) { 15894 numTrimming++; 15895 } 15896 } 15897 } 15898 15899 mNumServiceProcs = mNewNumServiceProcs; 15900 15901 // Now determine the memory trimming level of background processes. 15902 // Unfortunately we need to start at the back of the list to do this 15903 // properly. We only do this if the number of background apps we 15904 // are managing to keep around is less than half the maximum we desire; 15905 // if we are keeping a good number around, we'll let them use whatever 15906 // memory they want. 15907 final int numCachedAndEmpty = numCached + numEmpty; 15908 int memFactor; 15909 if (numCached <= ProcessList.TRIM_CACHED_APPS 15910 && numEmpty <= ProcessList.TRIM_EMPTY_APPS) { 15911 if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) { 15912 memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL; 15913 } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) { 15914 memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW; 15915 } else { 15916 memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE; 15917 } 15918 } else { 15919 memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL; 15920 } 15921 // We always allow the memory level to go up (better). We only allow it to go 15922 // down if we are in a state where that is allowed, *and* the total number of processes 15923 // has gone down since last time. 15924 if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel 15925 + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size() 15926 + " last=" + mLastNumProcesses); 15927 if (memFactor > mLastMemoryLevel) { 15928 if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) { 15929 memFactor = mLastMemoryLevel; 15930 if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!"); 15931 } 15932 } 15933 mLastMemoryLevel = memFactor; 15934 mLastNumProcesses = mLruProcesses.size(); 15935 boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !mSleeping, now); 15936 final int trackerMemFactor = mProcessStats.getMemFactorLocked(); 15937 if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) { 15938 if (mLowRamStartTime == 0) { 15939 mLowRamStartTime = now; 15940 } 15941 int step = 0; 15942 int fgTrimLevel; 15943 switch (memFactor) { 15944 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL: 15945 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL; 15946 break; 15947 case ProcessStats.ADJ_MEM_FACTOR_LOW: 15948 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW; 15949 break; 15950 default: 15951 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE; 15952 break; 15953 } 15954 int factor = numTrimming/3; 15955 int minFactor = 2; 15956 if (mHomeProcess != null) minFactor++; 15957 if (mPreviousProcess != null) minFactor++; 15958 if (factor < minFactor) factor = minFactor; 15959 int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE; 15960 for (int i=N-1; i>=0; i--) { 15961 ProcessRecord app = mLruProcesses.get(i); 15962 if (allChanged || app.procStateChanged) { 15963 setProcessTrackerState(app, trackerMemFactor, now); 15964 app.procStateChanged = false; 15965 } 15966 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME 15967 && !app.killedByAm) { 15968 if (app.trimMemoryLevel < curLevel && app.thread != null) { 15969 try { 15970 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 15971 "Trimming memory of " + app.processName 15972 + " to " + curLevel); 15973 app.thread.scheduleTrimMemory(curLevel); 15974 } catch (RemoteException e) { 15975 } 15976 if (false) { 15977 // For now we won't do this; our memory trimming seems 15978 // to be good enough at this point that destroying 15979 // activities causes more harm than good. 15980 if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE 15981 && app != mHomeProcess && app != mPreviousProcess) { 15982 // Need to do this on its own message because the stack may not 15983 // be in a consistent state at this point. 15984 // For these apps we will also finish their activities 15985 // to help them free memory. 15986 mStackSupervisor.scheduleDestroyAllActivities(app, "trim"); 15987 } 15988 } 15989 } 15990 app.trimMemoryLevel = curLevel; 15991 step++; 15992 if (step >= factor) { 15993 step = 0; 15994 switch (curLevel) { 15995 case ComponentCallbacks2.TRIM_MEMORY_COMPLETE: 15996 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE; 15997 break; 15998 case ComponentCallbacks2.TRIM_MEMORY_MODERATE: 15999 curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 16000 break; 16001 } 16002 } 16003 } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) { 16004 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND 16005 && app.thread != null) { 16006 try { 16007 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 16008 "Trimming memory of heavy-weight " + app.processName 16009 + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 16010 app.thread.scheduleTrimMemory( 16011 ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 16012 } catch (RemoteException e) { 16013 } 16014 } 16015 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 16016 } else { 16017 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 16018 || app.systemNoUi) && app.pendingUiClean) { 16019 // If this application is now in the background and it 16020 // had done UI, then give it the special trim level to 16021 // have it free UI resources. 16022 final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN; 16023 if (app.trimMemoryLevel < level && app.thread != null) { 16024 try { 16025 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 16026 "Trimming memory of bg-ui " + app.processName 16027 + " to " + level); 16028 app.thread.scheduleTrimMemory(level); 16029 } catch (RemoteException e) { 16030 } 16031 } 16032 app.pendingUiClean = false; 16033 } 16034 if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) { 16035 try { 16036 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 16037 "Trimming memory of fg " + app.processName 16038 + " to " + fgTrimLevel); 16039 app.thread.scheduleTrimMemory(fgTrimLevel); 16040 } catch (RemoteException e) { 16041 } 16042 } 16043 app.trimMemoryLevel = fgTrimLevel; 16044 } 16045 } 16046 } else { 16047 if (mLowRamStartTime != 0) { 16048 mLowRamTimeSinceLastIdle += now - mLowRamStartTime; 16049 mLowRamStartTime = 0; 16050 } 16051 for (int i=N-1; i>=0; i--) { 16052 ProcessRecord app = mLruProcesses.get(i); 16053 if (allChanged || app.procStateChanged) { 16054 setProcessTrackerState(app, trackerMemFactor, now); 16055 app.procStateChanged = false; 16056 } 16057 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 16058 || app.systemNoUi) && app.pendingUiClean) { 16059 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN 16060 && app.thread != null) { 16061 try { 16062 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 16063 "Trimming memory of ui hidden " + app.processName 16064 + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 16065 app.thread.scheduleTrimMemory( 16066 ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 16067 } catch (RemoteException e) { 16068 } 16069 } 16070 app.pendingUiClean = false; 16071 } 16072 app.trimMemoryLevel = 0; 16073 } 16074 } 16075 16076 if (mAlwaysFinishActivities) { 16077 // Need to do this on its own message because the stack may not 16078 // be in a consistent state at this point. 16079 mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish"); 16080 } 16081 16082 if (allChanged) { 16083 requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered()); 16084 } 16085 16086 if (mProcessStats.shouldWriteNowLocked(now)) { 16087 mHandler.post(new Runnable() { 16088 @Override public void run() { 16089 synchronized (ActivityManagerService.this) { 16090 mProcessStats.writeStateAsyncLocked(); 16091 } 16092 } 16093 }); 16094 } 16095 16096 if (DEBUG_OOM_ADJ) { 16097 Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms"); 16098 } 16099 } 16100 16101 final void trimApplications() { 16102 synchronized (this) { 16103 int i; 16104 16105 // First remove any unused application processes whose package 16106 // has been removed. 16107 for (i=mRemovedProcesses.size()-1; i>=0; i--) { 16108 final ProcessRecord app = mRemovedProcesses.get(i); 16109 if (app.activities.size() == 0 16110 && app.curReceiver == null && app.services.size() == 0) { 16111 Slog.i( 16112 TAG, "Exiting empty application process " 16113 + app.processName + " (" 16114 + (app.thread != null ? app.thread.asBinder() : null) 16115 + ")\n"); 16116 if (app.pid > 0 && app.pid != MY_PID) { 16117 EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid, 16118 app.processName, app.setAdj, "empty"); 16119 app.killedByAm = true; 16120 Process.killProcessQuiet(app.pid); 16121 } else { 16122 try { 16123 app.thread.scheduleExit(); 16124 } catch (Exception e) { 16125 // Ignore exceptions. 16126 } 16127 } 16128 cleanUpApplicationRecordLocked(app, false, true, -1); 16129 mRemovedProcesses.remove(i); 16130 16131 if (app.persistent) { 16132 if (app.persistent) { 16133 addAppLocked(app.info, false); 16134 } 16135 } 16136 } 16137 } 16138 16139 // Now update the oom adj for all processes. 16140 updateOomAdjLocked(); 16141 } 16142 } 16143 16144 /** This method sends the specified signal to each of the persistent apps */ 16145 public void signalPersistentProcesses(int sig) throws RemoteException { 16146 if (sig != Process.SIGNAL_USR1) { 16147 throw new SecurityException("Only SIGNAL_USR1 is allowed"); 16148 } 16149 16150 synchronized (this) { 16151 if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES) 16152 != PackageManager.PERMISSION_GRANTED) { 16153 throw new SecurityException("Requires permission " 16154 + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES); 16155 } 16156 16157 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 16158 ProcessRecord r = mLruProcesses.get(i); 16159 if (r.thread != null && r.persistent) { 16160 Process.sendSignal(r.pid, sig); 16161 } 16162 } 16163 } 16164 } 16165 16166 private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) { 16167 if (proc == null || proc == mProfileProc) { 16168 proc = mProfileProc; 16169 path = mProfileFile; 16170 profileType = mProfileType; 16171 clearProfilerLocked(); 16172 } 16173 if (proc == null) { 16174 return; 16175 } 16176 try { 16177 proc.thread.profilerControl(false, path, null, profileType); 16178 } catch (RemoteException e) { 16179 throw new IllegalStateException("Process disappeared"); 16180 } 16181 } 16182 16183 private void clearProfilerLocked() { 16184 if (mProfileFd != null) { 16185 try { 16186 mProfileFd.close(); 16187 } catch (IOException e) { 16188 } 16189 } 16190 mProfileApp = null; 16191 mProfileProc = null; 16192 mProfileFile = null; 16193 mProfileType = 0; 16194 mAutoStopProfiler = false; 16195 } 16196 16197 public boolean profileControl(String process, int userId, boolean start, 16198 String path, ParcelFileDescriptor fd, int profileType) throws RemoteException { 16199 16200 try { 16201 synchronized (this) { 16202 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 16203 // its own permission. 16204 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 16205 != PackageManager.PERMISSION_GRANTED) { 16206 throw new SecurityException("Requires permission " 16207 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 16208 } 16209 16210 if (start && fd == null) { 16211 throw new IllegalArgumentException("null fd"); 16212 } 16213 16214 ProcessRecord proc = null; 16215 if (process != null) { 16216 proc = findProcessLocked(process, userId, "profileControl"); 16217 } 16218 16219 if (start && (proc == null || proc.thread == null)) { 16220 throw new IllegalArgumentException("Unknown process: " + process); 16221 } 16222 16223 if (start) { 16224 stopProfilerLocked(null, null, 0); 16225 setProfileApp(proc.info, proc.processName, path, fd, false); 16226 mProfileProc = proc; 16227 mProfileType = profileType; 16228 try { 16229 fd = fd.dup(); 16230 } catch (IOException e) { 16231 fd = null; 16232 } 16233 proc.thread.profilerControl(start, path, fd, profileType); 16234 fd = null; 16235 mProfileFd = null; 16236 } else { 16237 stopProfilerLocked(proc, path, profileType); 16238 if (fd != null) { 16239 try { 16240 fd.close(); 16241 } catch (IOException e) { 16242 } 16243 } 16244 } 16245 16246 return true; 16247 } 16248 } catch (RemoteException e) { 16249 throw new IllegalStateException("Process disappeared"); 16250 } finally { 16251 if (fd != null) { 16252 try { 16253 fd.close(); 16254 } catch (IOException e) { 16255 } 16256 } 16257 } 16258 } 16259 16260 private ProcessRecord findProcessLocked(String process, int userId, String callName) { 16261 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 16262 userId, true, true, callName, null); 16263 ProcessRecord proc = null; 16264 try { 16265 int pid = Integer.parseInt(process); 16266 synchronized (mPidsSelfLocked) { 16267 proc = mPidsSelfLocked.get(pid); 16268 } 16269 } catch (NumberFormatException e) { 16270 } 16271 16272 if (proc == null) { 16273 ArrayMap<String, SparseArray<ProcessRecord>> all 16274 = mProcessNames.getMap(); 16275 SparseArray<ProcessRecord> procs = all.get(process); 16276 if (procs != null && procs.size() > 0) { 16277 proc = procs.valueAt(0); 16278 if (userId != UserHandle.USER_ALL && proc.userId != userId) { 16279 for (int i=1; i<procs.size(); i++) { 16280 ProcessRecord thisProc = procs.valueAt(i); 16281 if (thisProc.userId == userId) { 16282 proc = thisProc; 16283 break; 16284 } 16285 } 16286 } 16287 } 16288 } 16289 16290 return proc; 16291 } 16292 16293 public boolean dumpHeap(String process, int userId, boolean managed, 16294 String path, ParcelFileDescriptor fd) throws RemoteException { 16295 16296 try { 16297 synchronized (this) { 16298 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 16299 // its own permission (same as profileControl). 16300 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 16301 != PackageManager.PERMISSION_GRANTED) { 16302 throw new SecurityException("Requires permission " 16303 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 16304 } 16305 16306 if (fd == null) { 16307 throw new IllegalArgumentException("null fd"); 16308 } 16309 16310 ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap"); 16311 if (proc == null || proc.thread == null) { 16312 throw new IllegalArgumentException("Unknown process: " + process); 16313 } 16314 16315 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 16316 if (!isDebuggable) { 16317 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 16318 throw new SecurityException("Process not debuggable: " + proc); 16319 } 16320 } 16321 16322 proc.thread.dumpHeap(managed, path, fd); 16323 fd = null; 16324 return true; 16325 } 16326 } catch (RemoteException e) { 16327 throw new IllegalStateException("Process disappeared"); 16328 } finally { 16329 if (fd != null) { 16330 try { 16331 fd.close(); 16332 } catch (IOException e) { 16333 } 16334 } 16335 } 16336 } 16337 16338 /** In this method we try to acquire our lock to make sure that we have not deadlocked */ 16339 public void monitor() { 16340 synchronized (this) { } 16341 } 16342 16343 void onCoreSettingsChange(Bundle settings) { 16344 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 16345 ProcessRecord processRecord = mLruProcesses.get(i); 16346 try { 16347 if (processRecord.thread != null) { 16348 processRecord.thread.setCoreSettings(settings); 16349 } 16350 } catch (RemoteException re) { 16351 /* ignore */ 16352 } 16353 } 16354 } 16355 16356 // Multi-user methods 16357 16358 /** 16359 * Start user, if its not already running, but don't bring it to foreground. 16360 */ 16361 @Override 16362 public boolean startUserInBackground(final int userId) { 16363 return startUser(userId, /* foreground */ false); 16364 } 16365 16366 /** 16367 * Refreshes the list of users related to the current user when either a 16368 * user switch happens or when a new related user is started in the 16369 * background. 16370 */ 16371 private void updateCurrentProfileIdsLocked() { 16372 final List<UserInfo> profiles = getUserManagerLocked().getProfiles( 16373 mCurrentUserId, false /* enabledOnly */); 16374 int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null 16375 for (int i = 0; i < currentProfileIds.length; i++) { 16376 currentProfileIds[i] = profiles.get(i).id; 16377 } 16378 mCurrentProfileIds = currentProfileIds; 16379 } 16380 16381 private Set getProfileIdsLocked(int userId) { 16382 Set userIds = new HashSet<Integer>(); 16383 final List<UserInfo> profiles = getUserManagerLocked().getProfiles( 16384 userId, false /* enabledOnly */); 16385 for (UserInfo user : profiles) { 16386 userIds.add(Integer.valueOf(user.id)); 16387 } 16388 return userIds; 16389 } 16390 16391 @Override 16392 public boolean switchUser(final int userId) { 16393 return startUser(userId, /* foregound */ true); 16394 } 16395 16396 private boolean startUser(final int userId, boolean foreground) { 16397 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 16398 != PackageManager.PERMISSION_GRANTED) { 16399 String msg = "Permission Denial: switchUser() from pid=" 16400 + Binder.getCallingPid() 16401 + ", uid=" + Binder.getCallingUid() 16402 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 16403 Slog.w(TAG, msg); 16404 throw new SecurityException(msg); 16405 } 16406 16407 if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground); 16408 16409 final long ident = Binder.clearCallingIdentity(); 16410 try { 16411 synchronized (this) { 16412 final int oldUserId = mCurrentUserId; 16413 if (oldUserId == userId) { 16414 return true; 16415 } 16416 16417 mStackSupervisor.setLockTaskModeLocked(null); 16418 16419 final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId); 16420 if (userInfo == null) { 16421 Slog.w(TAG, "No user info for user #" + userId); 16422 return false; 16423 } 16424 16425 if (foreground) { 16426 mWindowManager.startFreezingScreen(R.anim.screen_user_exit, 16427 R.anim.screen_user_enter); 16428 } 16429 16430 boolean needStart = false; 16431 16432 // If the user we are switching to is not currently started, then 16433 // we need to start it now. 16434 if (mStartedUsers.get(userId) == null) { 16435 mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false)); 16436 updateStartedUserArrayLocked(); 16437 needStart = true; 16438 } 16439 16440 final Integer userIdInt = Integer.valueOf(userId); 16441 mUserLru.remove(userIdInt); 16442 mUserLru.add(userIdInt); 16443 16444 if (foreground) { 16445 mCurrentUserId = userId; 16446 updateCurrentProfileIdsLocked(); 16447 mWindowManager.setCurrentUser(userId, mCurrentProfileIds); 16448 // Once the internal notion of the active user has switched, we lock the device 16449 // with the option to show the user switcher on the keyguard. 16450 mWindowManager.lockNow(null); 16451 } else { 16452 final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId); 16453 updateCurrentProfileIdsLocked(); 16454 mWindowManager.setCurrentProfileIds(mCurrentProfileIds); 16455 mUserLru.remove(currentUserIdInt); 16456 mUserLru.add(currentUserIdInt); 16457 } 16458 16459 final UserStartedState uss = mStartedUsers.get(userId); 16460 16461 // Make sure user is in the started state. If it is currently 16462 // stopping, we need to knock that off. 16463 if (uss.mState == UserStartedState.STATE_STOPPING) { 16464 // If we are stopping, we haven't sent ACTION_SHUTDOWN, 16465 // so we can just fairly silently bring the user back from 16466 // the almost-dead. 16467 uss.mState = UserStartedState.STATE_RUNNING; 16468 updateStartedUserArrayLocked(); 16469 needStart = true; 16470 } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) { 16471 // This means ACTION_SHUTDOWN has been sent, so we will 16472 // need to treat this as a new boot of the user. 16473 uss.mState = UserStartedState.STATE_BOOTING; 16474 updateStartedUserArrayLocked(); 16475 needStart = true; 16476 } 16477 16478 if (foreground) { 16479 mHandler.removeMessages(REPORT_USER_SWITCH_MSG); 16480 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 16481 mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG, 16482 oldUserId, userId, uss)); 16483 mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG, 16484 oldUserId, userId, uss), USER_SWITCH_TIMEOUT); 16485 } 16486 16487 if (needStart) { 16488 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 16489 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16490 | Intent.FLAG_RECEIVER_FOREGROUND); 16491 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 16492 broadcastIntentLocked(null, null, intent, 16493 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 16494 false, false, MY_PID, Process.SYSTEM_UID, userId); 16495 } 16496 16497 if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) { 16498 if (userId != 0) { 16499 Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE); 16500 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 16501 broadcastIntentLocked(null, null, intent, null, 16502 new IIntentReceiver.Stub() { 16503 public void performReceive(Intent intent, int resultCode, 16504 String data, Bundle extras, boolean ordered, 16505 boolean sticky, int sendingUser) { 16506 userInitialized(uss, userId); 16507 } 16508 }, 0, null, null, null, AppOpsManager.OP_NONE, 16509 true, false, MY_PID, Process.SYSTEM_UID, 16510 userId); 16511 uss.initializing = true; 16512 } else { 16513 getUserManagerLocked().makeInitialized(userInfo.id); 16514 } 16515 } 16516 16517 if (foreground) { 16518 boolean homeInFront = mStackSupervisor.switchUserLocked(userId, uss); 16519 if (homeInFront) { 16520 startHomeActivityLocked(userId); 16521 } else { 16522 mStackSupervisor.resumeTopActivitiesLocked(); 16523 } 16524 EventLogTags.writeAmSwitchUser(userId); 16525 getUserManagerLocked().userForeground(userId); 16526 sendUserSwitchBroadcastsLocked(oldUserId, userId); 16527 } 16528 16529 if (needStart) { 16530 Intent intent = new Intent(Intent.ACTION_USER_STARTING); 16531 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 16532 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 16533 broadcastIntentLocked(null, null, intent, 16534 null, new IIntentReceiver.Stub() { 16535 @Override 16536 public void performReceive(Intent intent, int resultCode, String data, 16537 Bundle extras, boolean ordered, boolean sticky, int sendingUser) 16538 throws RemoteException { 16539 } 16540 }, 0, null, null, 16541 android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 16542 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 16543 } 16544 } 16545 } finally { 16546 Binder.restoreCallingIdentity(ident); 16547 } 16548 16549 return true; 16550 } 16551 16552 void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) { 16553 long ident = Binder.clearCallingIdentity(); 16554 try { 16555 Intent intent; 16556 if (oldUserId >= 0) { 16557 intent = new Intent(Intent.ACTION_USER_BACKGROUND); 16558 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16559 | Intent.FLAG_RECEIVER_FOREGROUND); 16560 intent.putExtra(Intent.EXTRA_USER_HANDLE, oldUserId); 16561 broadcastIntentLocked(null, null, intent, 16562 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 16563 false, false, MY_PID, Process.SYSTEM_UID, oldUserId); 16564 } 16565 if (newUserId >= 0) { 16566 intent = new Intent(Intent.ACTION_USER_FOREGROUND); 16567 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16568 | Intent.FLAG_RECEIVER_FOREGROUND); 16569 intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId); 16570 broadcastIntentLocked(null, null, intent, 16571 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 16572 false, false, MY_PID, Process.SYSTEM_UID, newUserId); 16573 intent = new Intent(Intent.ACTION_USER_SWITCHED); 16574 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16575 | Intent.FLAG_RECEIVER_FOREGROUND); 16576 intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId); 16577 broadcastIntentLocked(null, null, intent, 16578 null, null, 0, null, null, 16579 android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE, 16580 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 16581 } 16582 } finally { 16583 Binder.restoreCallingIdentity(ident); 16584 } 16585 } 16586 16587 void dispatchUserSwitch(final UserStartedState uss, final int oldUserId, 16588 final int newUserId) { 16589 final int N = mUserSwitchObservers.beginBroadcast(); 16590 if (N > 0) { 16591 final IRemoteCallback callback = new IRemoteCallback.Stub() { 16592 int mCount = 0; 16593 @Override 16594 public void sendResult(Bundle data) throws RemoteException { 16595 synchronized (ActivityManagerService.this) { 16596 if (mCurUserSwitchCallback == this) { 16597 mCount++; 16598 if (mCount == N) { 16599 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 16600 } 16601 } 16602 } 16603 } 16604 }; 16605 synchronized (this) { 16606 uss.switching = true; 16607 mCurUserSwitchCallback = callback; 16608 } 16609 for (int i=0; i<N; i++) { 16610 try { 16611 mUserSwitchObservers.getBroadcastItem(i).onUserSwitching( 16612 newUserId, callback); 16613 } catch (RemoteException e) { 16614 } 16615 } 16616 } else { 16617 synchronized (this) { 16618 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 16619 } 16620 } 16621 mUserSwitchObservers.finishBroadcast(); 16622 } 16623 16624 void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 16625 synchronized (this) { 16626 Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId); 16627 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 16628 } 16629 } 16630 16631 void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) { 16632 mCurUserSwitchCallback = null; 16633 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 16634 mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG, 16635 oldUserId, newUserId, uss)); 16636 } 16637 16638 void userInitialized(UserStartedState uss, int newUserId) { 16639 completeSwitchAndInitalize(uss, newUserId, true, false); 16640 } 16641 16642 void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 16643 completeSwitchAndInitalize(uss, newUserId, false, true); 16644 } 16645 16646 void completeSwitchAndInitalize(UserStartedState uss, int newUserId, 16647 boolean clearInitializing, boolean clearSwitching) { 16648 boolean unfrozen = false; 16649 synchronized (this) { 16650 if (clearInitializing) { 16651 uss.initializing = false; 16652 getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier()); 16653 } 16654 if (clearSwitching) { 16655 uss.switching = false; 16656 } 16657 if (!uss.switching && !uss.initializing) { 16658 mWindowManager.stopFreezingScreen(); 16659 unfrozen = true; 16660 } 16661 } 16662 if (unfrozen) { 16663 final int N = mUserSwitchObservers.beginBroadcast(); 16664 for (int i=0; i<N; i++) { 16665 try { 16666 mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId); 16667 } catch (RemoteException e) { 16668 } 16669 } 16670 mUserSwitchObservers.finishBroadcast(); 16671 } 16672 } 16673 16674 void scheduleStartProfilesLocked() { 16675 if (!mHandler.hasMessages(START_PROFILES_MSG)) { 16676 mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG), 16677 DateUtils.SECOND_IN_MILLIS); 16678 } 16679 } 16680 16681 void startProfilesLocked() { 16682 if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked"); 16683 List<UserInfo> profiles = getUserManagerLocked().getProfiles( 16684 mCurrentUserId, false /* enabledOnly */); 16685 List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size()); 16686 for (UserInfo user : profiles) { 16687 if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED 16688 && user.id != mCurrentUserId) { 16689 toStart.add(user); 16690 } 16691 } 16692 final int n = toStart.size(); 16693 int i = 0; 16694 for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) { 16695 startUserInBackground(toStart.get(i).id); 16696 } 16697 if (i < n) { 16698 Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS"); 16699 } 16700 } 16701 16702 void finishUserSwitch(UserStartedState uss) { 16703 synchronized (this) { 16704 if (uss.mState == UserStartedState.STATE_BOOTING 16705 && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) { 16706 uss.mState = UserStartedState.STATE_RUNNING; 16707 final int userId = uss.mHandle.getIdentifier(); 16708 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 16709 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 16710 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT); 16711 broadcastIntentLocked(null, null, intent, 16712 null, null, 0, null, null, 16713 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE, 16714 true, false, MY_PID, Process.SYSTEM_UID, userId); 16715 } 16716 16717 startProfilesLocked(); 16718 16719 int num = mUserLru.size(); 16720 int i = 0; 16721 while (num > MAX_RUNNING_USERS && i < mUserLru.size()) { 16722 Integer oldUserId = mUserLru.get(i); 16723 UserStartedState oldUss = mStartedUsers.get(oldUserId); 16724 if (oldUss == null) { 16725 // Shouldn't happen, but be sane if it does. 16726 mUserLru.remove(i); 16727 num--; 16728 continue; 16729 } 16730 if (oldUss.mState == UserStartedState.STATE_STOPPING 16731 || oldUss.mState == UserStartedState.STATE_SHUTDOWN) { 16732 // This user is already stopping, doesn't count. 16733 num--; 16734 i++; 16735 continue; 16736 } 16737 if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) { 16738 // Owner and current can't be stopped, but count as running. 16739 i++; 16740 continue; 16741 } 16742 // This is a user to be stopped. 16743 stopUserLocked(oldUserId, null); 16744 num--; 16745 i++; 16746 } 16747 } 16748 } 16749 16750 @Override 16751 public int stopUser(final int userId, final IStopUserCallback callback) { 16752 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 16753 != PackageManager.PERMISSION_GRANTED) { 16754 String msg = "Permission Denial: switchUser() from pid=" 16755 + Binder.getCallingPid() 16756 + ", uid=" + Binder.getCallingUid() 16757 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 16758 Slog.w(TAG, msg); 16759 throw new SecurityException(msg); 16760 } 16761 if (userId <= 0) { 16762 throw new IllegalArgumentException("Can't stop primary user " + userId); 16763 } 16764 synchronized (this) { 16765 return stopUserLocked(userId, callback); 16766 } 16767 } 16768 16769 private int stopUserLocked(final int userId, final IStopUserCallback callback) { 16770 if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId); 16771 if (mCurrentUserId == userId) { 16772 return ActivityManager.USER_OP_IS_CURRENT; 16773 } 16774 16775 final UserStartedState uss = mStartedUsers.get(userId); 16776 if (uss == null) { 16777 // User is not started, nothing to do... but we do need to 16778 // callback if requested. 16779 if (callback != null) { 16780 mHandler.post(new Runnable() { 16781 @Override 16782 public void run() { 16783 try { 16784 callback.userStopped(userId); 16785 } catch (RemoteException e) { 16786 } 16787 } 16788 }); 16789 } 16790 return ActivityManager.USER_OP_SUCCESS; 16791 } 16792 16793 if (callback != null) { 16794 uss.mStopCallbacks.add(callback); 16795 } 16796 16797 if (uss.mState != UserStartedState.STATE_STOPPING 16798 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 16799 uss.mState = UserStartedState.STATE_STOPPING; 16800 updateStartedUserArrayLocked(); 16801 16802 long ident = Binder.clearCallingIdentity(); 16803 try { 16804 // We are going to broadcast ACTION_USER_STOPPING and then 16805 // once that is done send a final ACTION_SHUTDOWN and then 16806 // stop the user. 16807 final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING); 16808 stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 16809 stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 16810 stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true); 16811 final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN); 16812 // This is the result receiver for the final shutdown broadcast. 16813 final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() { 16814 @Override 16815 public void performReceive(Intent intent, int resultCode, String data, 16816 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 16817 finishUserStop(uss); 16818 } 16819 }; 16820 // This is the result receiver for the initial stopping broadcast. 16821 final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() { 16822 @Override 16823 public void performReceive(Intent intent, int resultCode, String data, 16824 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 16825 // On to the next. 16826 synchronized (ActivityManagerService.this) { 16827 if (uss.mState != UserStartedState.STATE_STOPPING) { 16828 // Whoops, we are being started back up. Abort, abort! 16829 return; 16830 } 16831 uss.mState = UserStartedState.STATE_SHUTDOWN; 16832 } 16833 broadcastIntentLocked(null, null, shutdownIntent, 16834 null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE, 16835 true, false, MY_PID, Process.SYSTEM_UID, userId); 16836 } 16837 }; 16838 // Kick things off. 16839 broadcastIntentLocked(null, null, stoppingIntent, 16840 null, stoppingReceiver, 0, null, null, 16841 android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 16842 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 16843 } finally { 16844 Binder.restoreCallingIdentity(ident); 16845 } 16846 } 16847 16848 return ActivityManager.USER_OP_SUCCESS; 16849 } 16850 16851 void finishUserStop(UserStartedState uss) { 16852 final int userId = uss.mHandle.getIdentifier(); 16853 boolean stopped; 16854 ArrayList<IStopUserCallback> callbacks; 16855 synchronized (this) { 16856 callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks); 16857 if (mStartedUsers.get(userId) != uss) { 16858 stopped = false; 16859 } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) { 16860 stopped = false; 16861 } else { 16862 stopped = true; 16863 // User can no longer run. 16864 mStartedUsers.remove(userId); 16865 mUserLru.remove(Integer.valueOf(userId)); 16866 updateStartedUserArrayLocked(); 16867 16868 // Clean up all state and processes associated with the user. 16869 // Kill all the processes for the user. 16870 forceStopUserLocked(userId, "finish user"); 16871 } 16872 } 16873 16874 for (int i=0; i<callbacks.size(); i++) { 16875 try { 16876 if (stopped) callbacks.get(i).userStopped(userId); 16877 else callbacks.get(i).userStopAborted(userId); 16878 } catch (RemoteException e) { 16879 } 16880 } 16881 16882 mStackSupervisor.removeUserLocked(userId); 16883 } 16884 16885 @Override 16886 public UserInfo getCurrentUser() { 16887 if ((checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) 16888 != PackageManager.PERMISSION_GRANTED) && ( 16889 checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 16890 != PackageManager.PERMISSION_GRANTED)) { 16891 String msg = "Permission Denial: getCurrentUser() 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 getUserManagerLocked().getUserInfo(mCurrentUserId); 16900 } 16901 } 16902 16903 int getCurrentUserIdLocked() { 16904 return mCurrentUserId; 16905 } 16906 16907 @Override 16908 public boolean isUserRunning(int userId, boolean orStopped) { 16909 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) 16910 != PackageManager.PERMISSION_GRANTED) { 16911 String msg = "Permission Denial: isUserRunning() from pid=" 16912 + Binder.getCallingPid() 16913 + ", uid=" + Binder.getCallingUid() 16914 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS; 16915 Slog.w(TAG, msg); 16916 throw new SecurityException(msg); 16917 } 16918 synchronized (this) { 16919 return isUserRunningLocked(userId, orStopped); 16920 } 16921 } 16922 16923 boolean isUserRunningLocked(int userId, boolean orStopped) { 16924 UserStartedState state = mStartedUsers.get(userId); 16925 if (state == null) { 16926 return false; 16927 } 16928 if (orStopped) { 16929 return true; 16930 } 16931 return state.mState != UserStartedState.STATE_STOPPING 16932 && state.mState != UserStartedState.STATE_SHUTDOWN; 16933 } 16934 16935 @Override 16936 public int[] getRunningUserIds() { 16937 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) 16938 != PackageManager.PERMISSION_GRANTED) { 16939 String msg = "Permission Denial: isUserRunning() from pid=" 16940 + Binder.getCallingPid() 16941 + ", uid=" + Binder.getCallingUid() 16942 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS; 16943 Slog.w(TAG, msg); 16944 throw new SecurityException(msg); 16945 } 16946 synchronized (this) { 16947 return mStartedUserArray; 16948 } 16949 } 16950 16951 private void updateStartedUserArrayLocked() { 16952 int num = 0; 16953 for (int i=0; i<mStartedUsers.size(); i++) { 16954 UserStartedState uss = mStartedUsers.valueAt(i); 16955 // This list does not include stopping users. 16956 if (uss.mState != UserStartedState.STATE_STOPPING 16957 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 16958 num++; 16959 } 16960 } 16961 mStartedUserArray = new int[num]; 16962 num = 0; 16963 for (int i=0; i<mStartedUsers.size(); i++) { 16964 UserStartedState uss = mStartedUsers.valueAt(i); 16965 if (uss.mState != UserStartedState.STATE_STOPPING 16966 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 16967 mStartedUserArray[num] = mStartedUsers.keyAt(i); 16968 num++; 16969 } 16970 } 16971 } 16972 16973 @Override 16974 public void registerUserSwitchObserver(IUserSwitchObserver observer) { 16975 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 16976 != PackageManager.PERMISSION_GRANTED) { 16977 String msg = "Permission Denial: registerUserSwitchObserver() from pid=" 16978 + Binder.getCallingPid() 16979 + ", uid=" + Binder.getCallingUid() 16980 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 16981 Slog.w(TAG, msg); 16982 throw new SecurityException(msg); 16983 } 16984 16985 mUserSwitchObservers.register(observer); 16986 } 16987 16988 @Override 16989 public void unregisterUserSwitchObserver(IUserSwitchObserver observer) { 16990 mUserSwitchObservers.unregister(observer); 16991 } 16992 16993 private boolean userExists(int userId) { 16994 if (userId == 0) { 16995 return true; 16996 } 16997 UserManagerService ums = getUserManagerLocked(); 16998 return ums != null ? (ums.getUserInfo(userId) != null) : false; 16999 } 17000 17001 int[] getUsersLocked() { 17002 UserManagerService ums = getUserManagerLocked(); 17003 return ums != null ? ums.getUserIds() : new int[] { 0 }; 17004 } 17005 17006 UserManagerService getUserManagerLocked() { 17007 if (mUserManager == null) { 17008 IBinder b = ServiceManager.getService(Context.USER_SERVICE); 17009 mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b); 17010 } 17011 return mUserManager; 17012 } 17013 17014 private int applyUserId(int uid, int userId) { 17015 return UserHandle.getUid(userId, uid); 17016 } 17017 17018 ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) { 17019 if (info == null) return null; 17020 ApplicationInfo newInfo = new ApplicationInfo(info); 17021 newInfo.uid = applyUserId(info.uid, userId); 17022 newInfo.dataDir = USER_DATA_DIR + userId + "/" 17023 + info.packageName; 17024 return newInfo; 17025 } 17026 17027 ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) { 17028 if (aInfo == null 17029 || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) { 17030 return aInfo; 17031 } 17032 17033 ActivityInfo info = new ActivityInfo(aInfo); 17034 info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId); 17035 return info; 17036 } 17037 17038 private final class LocalService extends ActivityManagerInternal { 17039 @Override 17040 public void goingToSleep() { 17041 ActivityManagerService.this.goingToSleep(); 17042 } 17043 17044 @Override 17045 public void wakingUp() { 17046 ActivityManagerService.this.wakingUp(); 17047 } 17048 } 17049} 17050